Repository: hathach/tinyusb Branch: master Commit: 8a9f44bdd267 Files: 2411 Total size: 17.4 MB Directory structure: gitextract_0tofuoxf/ ├── .circleci/ │ ├── config.yml │ └── config2.yml ├── .clang-format ├── .codespellrc ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── feature_request.yml │ ├── actions/ │ │ ├── get_deps/ │ │ │ └── action.yml │ │ └── setup_toolchain/ │ │ ├── action.yml │ │ ├── download/ │ │ │ └── action.yml │ │ ├── espressif/ │ │ │ └── action.yml │ │ └── toolchain.json │ ├── membrowse_pr_message.j2 │ └── workflows/ │ ├── build.yml │ ├── build_util.yml │ ├── ci_set_matrix.py │ ├── cifuzz.yml │ ├── claude-code-review.yml │ ├── claude.yml │ ├── labeler.yml │ ├── membrowse-comment.yml │ ├── membrowse-onboard.yml │ ├── metrics_comment.yml │ ├── pre-commit.yml │ ├── static_analysis.yml │ └── trigger.yml ├── .gitignore ├── .idea/ │ ├── .gitignore │ ├── cmake.xml │ ├── debugServers/ │ │ ├── AT32F423VCT7.xml │ │ ├── ST_LINK.xml │ │ ├── at32f403acgu7.xml │ │ ├── esp32s2.xml │ │ ├── lpc1769.xml │ │ ├── lpc55s69.xml │ │ ├── max32690.xml │ │ ├── mcxa153.xml │ │ ├── nrf52833.xml │ │ ├── nrf5340.xml │ │ ├── ra6m1.xml │ │ ├── ra6m5.xml │ │ ├── rp2040.xml │ │ ├── rp2350.xml │ │ ├── rt1011.xml │ │ ├── rt1060.xml │ │ ├── rt1064.xml │ │ ├── rt1170.xml │ │ ├── s3.xml │ │ ├── sam21.xml │ │ ├── sam51.xml │ │ ├── stm32f072.xml │ │ ├── stm32f303.xml │ │ ├── stm32f411.xml │ │ ├── stm32f769.xml │ │ ├── stm32h563.xml │ │ ├── stm32h743.xml │ │ ├── stm32l053.xml │ │ └── wch_riscv.xml │ ├── runConfigurations/ │ │ ├── k64f.xml │ │ ├── kl25.xml │ │ ├── lpc1857.xml │ │ ├── lpc4088.xml │ │ ├── lpc54628.xml │ │ ├── lpc55s69.xml │ │ ├── mcx947.xml │ │ ├── nrf52840.xml │ │ ├── nrf5340.xml │ │ ├── ra2a1.xml │ │ ├── ra4m1.xml │ │ ├── ra6m1.xml │ │ ├── ra6m5.xml │ │ ├── rp2040.xml │ │ ├── rt1010.xml │ │ ├── rt1060.xml │ │ ├── samd21g18.xml │ │ ├── samd51j19.xml │ │ ├── stlink.xml │ │ ├── stm32g474.xml │ │ ├── stm32h563.xml │ │ ├── stm32h743.xml │ │ ├── stm32u5a5.xml │ │ └── uno_r4.xml │ └── vcs.xml ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── AGENTS.md ├── CODE_OF_CONDUCT.rst ├── CONTRIBUTORS.rst ├── LICENSE ├── README.rst ├── SConscript ├── docs/ │ ├── _static/ │ │ └── custom.css │ ├── conf.py │ ├── faq.rst │ ├── getting_started.rst │ ├── index.rst │ ├── info/ │ │ ├── changelog.rst │ │ ├── code_of_conduct.rst │ │ ├── contributors.rst │ │ └── index.rst │ ├── integration.rst │ ├── porting.rst │ ├── reference/ │ │ ├── architecture.rst │ │ ├── boards.rst │ │ ├── concurrency.rst │ │ ├── dependencies.rst │ │ ├── glossary.rst │ │ ├── index.rst │ │ └── usb_concepts.rst │ ├── requirements.txt │ └── troubleshooting.rst ├── examples/ │ ├── CMakeLists.txt │ ├── CMakePresets.json │ ├── build_system/ │ │ ├── cmake/ │ │ │ ├── cpu/ │ │ │ │ ├── arm1176jzf-s.cmake │ │ │ │ ├── arm926ej-s.cmake │ │ │ │ ├── cortex-a53.cmake │ │ │ │ ├── cortex-a72.cmake │ │ │ │ ├── cortex-m0.cmake │ │ │ │ ├── cortex-m0plus.cmake │ │ │ │ ├── cortex-m23.cmake │ │ │ │ ├── cortex-m3.cmake │ │ │ │ ├── cortex-m33-nodsp-nofp.cmake │ │ │ │ ├── cortex-m33-nodsp.cmake │ │ │ │ ├── cortex-m33.cmake │ │ │ │ ├── cortex-m4-nofpu.cmake │ │ │ │ ├── cortex-m4.cmake │ │ │ │ ├── cortex-m55.cmake │ │ │ │ ├── cortex-m7-fpsp.cmake │ │ │ │ ├── cortex-m7.cmake │ │ │ │ ├── cortex-m85.cmake │ │ │ │ ├── ft32.cmake │ │ │ │ ├── msp430.cmake │ │ │ │ ├── rv32i-ilp32.cmake │ │ │ │ ├── rv32imac-ilp32.cmake │ │ │ │ ├── rx610.cmake │ │ │ │ └── rx64m.cmake │ │ │ └── toolchain/ │ │ │ ├── aarch64_gcc.cmake │ │ │ ├── arm_clang.cmake │ │ │ ├── arm_gcc.cmake │ │ │ ├── arm_iar.cmake │ │ │ ├── common.cmake │ │ │ ├── cstat_sel_checks.txt │ │ │ ├── ft32_gcc.cmake │ │ │ ├── msp430_gcc.cmake │ │ │ ├── riscv_gcc.cmake │ │ │ └── rx_gcc.cmake │ │ └── make/ │ │ ├── cpu/ │ │ │ ├── arm1176jzf-s.mk │ │ │ ├── arm926ej-s.mk │ │ │ ├── cortex-a53.mk │ │ │ ├── cortex-a72.mk │ │ │ ├── cortex-m0.mk │ │ │ ├── cortex-m0plus.mk │ │ │ ├── cortex-m23.mk │ │ │ ├── cortex-m3.mk │ │ │ ├── cortex-m33-nodsp-nofp.mk │ │ │ ├── cortex-m33.mk │ │ │ ├── cortex-m4-nofpu.mk │ │ │ ├── cortex-m4.mk │ │ │ ├── cortex-m55.mk │ │ │ ├── cortex-m7-fpsp.mk │ │ │ ├── cortex-m7.mk │ │ │ ├── cortex-m85.mk │ │ │ ├── msp430.mk │ │ │ ├── rv32i-ilp32.mk │ │ │ └── rv32imac-ilp32.mk │ │ └── toolchain/ │ │ ├── arm_clang.mk │ │ ├── arm_gcc.mk │ │ ├── arm_iar.mk │ │ ├── clang_rules.mk │ │ ├── gcc_common.mk │ │ ├── gcc_rules.mk │ │ ├── iar_rules.mk │ │ └── riscv_gcc.mk │ ├── device/ │ │ ├── 99-tinyusb.rules │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── audio_4_channel_mic/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── plot_audio_samples.py │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── audio_4_channel_mic_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── sdkconfig.defaults │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── plot_audio_samples.py │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── audio_test/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── plot_audio_samples.py │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── audio_test_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── sdkconfig.defaults │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── plot_audio_samples.py │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── audio_test_multi_rate/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── plot_audio_samples.py │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── board_test/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── sdkconfig.defaults │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ └── tusb_config.h │ │ ├── cdc_dual_ports/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── cdc_msc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── prj.conf │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── msc_disk.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── cdc_msc_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── sdkconfig.defaults │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── msc_disk.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── cdc_uac2/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── cdc_app.c │ │ │ ├── common.h │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── uac2_app.c │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── dfu/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── dfu_runtime/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── dynamic_configuration/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── msc_disk.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── hid_boot_interface/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── hid_composite/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── hid_composite_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── sdkconfig.defaults │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── hid_generic_inout/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── boards.js │ │ │ ├── hid_test.js │ │ │ ├── hid_test.py │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── hid_multiple_interface/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── midi_test/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── midi_test_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── msc_dual_lun/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── prj.conf │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── msc_disk_dual.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── mtp/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── prj.conf │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── mtp_fs_example.c │ │ │ ├── tinyusb_logo_png.h │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── net_lwip_webserver/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── arch/ │ │ │ │ ├── bpstruct.h │ │ │ │ ├── cc.h │ │ │ │ └── epstruct.h │ │ │ ├── lwipopts.h │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── printer_to_cdc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── uac2_headset/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── uac2_speaker_fb/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── audio_debug.py │ │ │ ├── common_types.h │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── usbtmc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ ├── src/ │ │ │ │ ├── main.c │ │ │ │ ├── main.h │ │ │ │ ├── tusb_config.h │ │ │ │ ├── usb_descriptors.c │ │ │ │ ├── usbtmc_app.c │ │ │ │ └── usbtmc_app.h │ │ │ └── visaQuery.py │ │ ├── video_capture/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── images.h │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ ├── video_capture_2ch/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── images.h │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ └── webusb_serial/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── Makefile │ │ ├── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ ├── usb_descriptors.c │ │ │ └── usb_descriptors.h │ │ └── website/ │ │ ├── application.js │ │ ├── divider.js │ │ ├── index.html │ │ ├── serial.js │ │ └── style.css │ ├── dual/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── dynamic_switch/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── only.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ ├── host_hid_to_device_cdc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.c │ │ └── host_info_to_device_cdc/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── Makefile │ │ ├── only.txt │ │ └── src/ │ │ ├── CMakeLists.txt │ │ ├── main.c │ │ ├── tusb_config.h │ │ └── usb_descriptors.c │ ├── host/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── bare_api/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ └── tusb_config.h │ │ ├── cdc_msc_hid/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── app.h │ │ │ ├── cdc_app.c │ │ │ ├── hid_app.c │ │ │ ├── main.c │ │ │ ├── msc_app.c │ │ │ └── tusb_config.h │ │ ├── cdc_msc_hid_freertos/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── app.h │ │ │ ├── cdc_app.c │ │ │ ├── hid_app.c │ │ │ ├── main.c │ │ │ ├── msc_app.c │ │ │ └── tusb_config.h │ │ ├── device_info/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── main.c │ │ │ └── tusb_config.h │ │ ├── hid_controller/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── app.h │ │ │ ├── hid_app.c │ │ │ ├── main.c │ │ │ └── tusb_config.h │ │ ├── midi_rx/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CMakePresets.json │ │ │ ├── Makefile │ │ │ ├── only.txt │ │ │ ├── skip.txt │ │ │ └── src/ │ │ │ ├── main.c │ │ │ └── tusb_config.h │ │ └── msc_file_explorer/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── Makefile │ │ ├── only.txt │ │ ├── skip.txt │ │ └── src/ │ │ ├── main.c │ │ ├── msc_app.c │ │ ├── msc_app.h │ │ └── tusb_config.h │ ├── typec/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ └── power_delivery/ │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── Makefile │ │ ├── only.txt │ │ └── src/ │ │ ├── main.c │ │ └── tusb_config.h │ └── west.yml ├── hw/ │ ├── bsp/ │ │ ├── BoardPresets.json │ │ ├── ansi_escape.h │ │ ├── at32f402_405/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f402_405_clock.c │ │ │ ├── at32f402_405_clock.h │ │ │ ├── at32f402_405_conf.h │ │ │ ├── at32f402_405_int.c │ │ │ ├── at32f402_405_int.h │ │ │ ├── boards/ │ │ │ │ ├── at_start_f402/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── at_start_f405/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f403a_407/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f403a_407_clock.c │ │ │ ├── at32f403a_407_clock.h │ │ │ ├── at32f403a_407_conf.h │ │ │ ├── at32f403a_407_int.c │ │ │ ├── at32f403a_407_int.h │ │ │ ├── boards/ │ │ │ │ ├── at32f403a_weact_blackpill/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── at_start_f403a/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── at_start_f407/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f413/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f413_clock.c │ │ │ ├── at32f413_clock.h │ │ │ ├── at32f413_conf.h │ │ │ ├── at32f413_int.c │ │ │ ├── at32f413_int.h │ │ │ ├── boards/ │ │ │ │ └── at_start_f413/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f415/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f415_clock.c │ │ │ ├── at32f415_clock.h │ │ │ ├── at32f415_conf.h │ │ │ ├── at32f415_int.c │ │ │ ├── at32f415_int.h │ │ │ ├── boards/ │ │ │ │ └── at_start_f415/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f423/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f423_clock.c │ │ │ ├── at32f423_clock.h │ │ │ ├── at32f423_conf.h │ │ │ ├── at32f423_int.c │ │ │ ├── at32f423_int.h │ │ │ ├── boards/ │ │ │ │ └── at_start_f423/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f425/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f425_clock.c │ │ │ ├── at32f425_clock.h │ │ │ ├── at32f425_conf.h │ │ │ ├── at32f425_int.c │ │ │ ├── at32f425_int.h │ │ │ ├── boards/ │ │ │ │ └── at_start_f425/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f435_437/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f435_437_clock.c │ │ │ ├── at32f435_437_clock.h │ │ │ ├── at32f435_437_conf.h │ │ │ ├── at32f435_437_int.c │ │ │ ├── at32f435_437_int.h │ │ │ ├── boards/ │ │ │ │ ├── at_start_f435/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── at_start_f437/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── at32f45x/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── at32f45x_clock.c │ │ │ ├── at32f45x_clock.h │ │ │ ├── at32f45x_conf.h │ │ │ ├── at32f45x_int.c │ │ │ ├── at32f45x_int.h │ │ │ ├── boards/ │ │ │ │ ├── at_start_f455/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── at_start_f456/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── at_start_f457/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── board.c │ │ ├── board_api.h │ │ ├── broadcom_32bit/ │ │ │ ├── boards/ │ │ │ │ └── raspberrypi_zero/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── broadcom_64bit/ │ │ │ ├── boards/ │ │ │ │ ├── raspberrypi_cm4/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── raspberrypi_zero2/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── ch32f20x/ │ │ │ ├── boards/ │ │ │ │ └── ch32f205r-r0/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── ch32f205.ld │ │ │ ├── ch32f20x_conf.h │ │ │ ├── ch32f20x_it.c │ │ │ ├── ch32f20x_it.h │ │ │ ├── core_cm3.h │ │ │ ├── debug_uart.c │ │ │ ├── debug_uart.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── startup_gcc_ch32f20x_d8c.s │ │ │ ├── system_ch32f20x.c │ │ │ └── system_ch32f20x.h │ │ ├── ch32v10x/ │ │ │ ├── boards/ │ │ │ │ └── ch32v103r_r1_1v0/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── ch32v10x_conf.h │ │ │ ├── ch32v10x_it.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ └── ch32v10x.ld │ │ │ ├── system_ch32v10x.c │ │ │ ├── system_ch32v10x.h │ │ │ └── wch-riscv.cfg │ │ ├── ch32v20x/ │ │ │ ├── boards/ │ │ │ │ ├── ch32v203c_r0_1v0/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── ch32v203g_r0_1v0/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── nanoch32v203/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── ch32v20x_conf.h │ │ │ ├── ch32v20x_it.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ └── ch32v20x.ld │ │ │ ├── system_ch32v20x.c │ │ │ ├── system_ch32v20x.h │ │ │ └── wch-riscv.cfg │ │ ├── ch32v30x/ │ │ │ ├── boards/ │ │ │ │ ├── ch32v307v_r1_1v0/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── nanoch32v305/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── ch32v30x_conf.h │ │ │ ├── ch32v30x_it.c │ │ │ ├── ch32v30x_it.h │ │ │ ├── debug_uart.c │ │ │ ├── debug_uart.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ └── ch32v30x.ld │ │ │ ├── system_ch32v30x.c │ │ │ ├── system_ch32v30x.h │ │ │ └── wch-riscv.cfg │ │ ├── cxd56/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── spresense/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── da1469x/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── da14695_dk_usb/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── syscfg/ │ │ │ │ │ └── syscfg.h │ │ │ │ └── da1469x_dk_pro/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── syscfg/ │ │ │ │ └── syscfg.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── gcc_startup_da1469x.S │ │ │ ├── linker/ │ │ │ │ └── da1469x.ld │ │ │ └── product_header.dump │ │ ├── efm32/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── sltb009a/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── espressif/ │ │ │ ├── boards/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── adafruit_feather_esp32_v2/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_feather_esp32c6/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_feather_esp32s2/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_feather_esp32s3/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_magtag_29gray/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_metro_esp32s2/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_addax_1/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_c3_devkitc/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_c6_devkitc/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_kaluga_1/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_p4_function_ev/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── sdkconfig.defaults │ │ │ │ ├── espressif_s2_devkitc/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_s3_devkitc/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_s3_devkitm/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── espressif_saola_1/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ └── family.c │ │ │ ├── components/ │ │ │ │ ├── led_strip/ │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── README.md │ │ │ │ │ ├── api.md │ │ │ │ │ ├── examples/ │ │ │ │ │ │ └── led_strip_rmt_ws2812/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ └── main/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── idf_component.yml │ │ │ │ │ │ └── led_strip_rmt_ws2812_main.c │ │ │ │ │ ├── idf_component.yml │ │ │ │ │ ├── include/ │ │ │ │ │ │ ├── led_strip.h │ │ │ │ │ │ ├── led_strip_rmt.h │ │ │ │ │ │ ├── led_strip_spi.h │ │ │ │ │ │ └── led_strip_types.h │ │ │ │ │ ├── interface/ │ │ │ │ │ │ └── led_strip_interface.h │ │ │ │ │ └── src/ │ │ │ │ │ ├── led_strip_api.c │ │ │ │ │ ├── led_strip_rmt_dev.c │ │ │ │ │ ├── led_strip_rmt_dev_idf4.c │ │ │ │ │ ├── led_strip_rmt_encoder.c │ │ │ │ │ ├── led_strip_rmt_encoder.h │ │ │ │ │ └── led_strip_spi_dev.c │ │ │ │ └── tinyusb_src/ │ │ │ │ └── CMakeLists.txt │ │ │ └── family.cmake │ │ ├── f1c100s/ │ │ │ ├── README.md │ │ │ ├── boards/ │ │ │ │ └── f1c100s/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── family_rules.mk │ │ ├── family_support.cmake │ │ ├── family_support.mk │ │ ├── fomu/ │ │ │ ├── boards/ │ │ │ │ └── fomu/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── crt0-vexriscv.S │ │ │ ├── dfu.py │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── fomu.ld │ │ │ ├── include/ │ │ │ │ ├── csr.h │ │ │ │ ├── hw/ │ │ │ │ │ └── common.h │ │ │ │ └── irq.h │ │ │ ├── output_format.ld │ │ │ └── regions.ld │ │ ├── ft9xx/ │ │ │ ├── boards/ │ │ │ │ └── mm900evxb/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── gd32vf103/ │ │ │ ├── boards/ │ │ │ │ └── sipeed_longan_nano/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── system_gd32vf103.c │ │ ├── hpmicro/ │ │ │ ├── boards/ │ │ │ │ └── hpm6750evk2/ │ │ │ │ ├── board.c │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── pinmux.c │ │ │ │ └── pinmux.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── imxrt/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── metro_m7_1011/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1010_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1010_flexspi_nor_config.h │ │ │ │ │ ├── metro_m7_1011.ld │ │ │ │ │ ├── metro_m7_1011.mex │ │ │ │ │ └── ozone/ │ │ │ │ │ └── metro_m7_1011.jdebug │ │ │ │ ├── mimxrt1010_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1010_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1010_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1010_evk.mex │ │ │ │ ├── mimxrt1015_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1015_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1015_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1015_evk.mex │ │ │ │ ├── mimxrt1020_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1020_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1020_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1020_evk.mex │ │ │ │ ├── mimxrt1024_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1024_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1024_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1024_evk.mex │ │ │ │ ├── mimxrt1050_evkb/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkbimxrt1050_flexspi_nor_config.c │ │ │ │ │ ├── evkbimxrt1050_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1050_evkb.mex │ │ │ │ ├── mimxrt1060_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1060_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1060_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1060_evk.mex │ │ │ │ ├── mimxrt1064_evk/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkmimxrt1064_flexspi_nor_config.c │ │ │ │ │ ├── evkmimxrt1064_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1064_evk.mex │ │ │ │ ├── mimxrt1170_evkb/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── evkbmimxrt1170_flexspi_nor_config.c │ │ │ │ │ ├── evkbmimxrt1170_flexspi_nor_config.h │ │ │ │ │ └── mimxrt1170_evkb.mex │ │ │ │ ├── teensy_40/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── teensy40.mex │ │ │ │ │ ├── teensy40_flexspi_nor_config.c │ │ │ │ │ └── teensy40_flexspi_nor_config.h │ │ │ │ └── teensy_41/ │ │ │ │ ├── board/ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── teensy41.mex │ │ │ │ ├── teensy41_flexspi_nor_config.c │ │ │ │ └── teensy41_flexspi_nor_config.h │ │ │ ├── debug.jlinkscript │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── kinetis_k/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── frdm_k64f/ │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── frdm_k64f.mex │ │ │ │ └── teensy_35/ │ │ │ │ ├── board/ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── teensy_35.mex │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── kinetis_k32l/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── frdm_k32l2a4s/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── clock_config.c │ │ │ │ │ └── clock_config.h │ │ │ │ ├── frdm_k32l2b/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── clock_config.c │ │ │ │ │ └── clock_config.h │ │ │ │ └── kuiic/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── clock_config.c │ │ │ │ ├── clock_config.h │ │ │ │ └── kuiic.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── kinetis_kl/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── frdm_kl25z/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── clock_config.c │ │ │ │ └── clock_config.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── gcc/ │ │ │ ├── MKL25Z128xxx4_flash.ld │ │ │ └── startup_MKL25Z4.S │ │ ├── lpc11/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── lpcxpresso11u37/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── lpc11u37.ld │ │ │ │ └── lpcxpresso11u68/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── lpc11u68.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc13/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── lpcxpresso1347/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── lpc1347.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc15/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── lpcxpresso1549/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── lpc1549.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc17/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── lpcxpresso1769/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── lpc1769.ld │ │ │ │ └── mbed1768/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── lpc1768.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc18/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── lpcxpresso18s37/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── lpc1837.ld │ │ │ │ └── mcb1800/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── lpc1857.ld │ │ │ │ └── ozone/ │ │ │ │ └── lpc1857.jdebug │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc40/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── ea4088_quickstart/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── lpc4088.ld │ │ │ │ └── ozone/ │ │ │ │ └── ea4088_quickstart.jdebug │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc43/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── ea4357/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── lpc4357.ld │ │ │ │ │ ├── pca9532.c │ │ │ │ │ └── pca9532.h │ │ │ │ └── lpcxpresso43s67/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── lpc4367.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc51/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── lpcxpresso51u68/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── lpc54/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── lpcxpresso54114/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── lpcxpresso54608/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── lpcxpresso54628/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── iar/ │ │ │ ├── LPC54608_flash.icf │ │ │ ├── LPC54628_flash.icf │ │ │ ├── startup_LPC54608.s │ │ │ └── startup_LPC54628.s │ │ ├── lpc55/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── double_m33_express/ │ │ │ │ │ ├── LPC55S69_cm33_core0_uf2.ld │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── peripherals.c │ │ │ │ │ │ ├── peripherals.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── double_m33_express.mex │ │ │ │ ├── lpcxpresso55s28/ │ │ │ │ │ ├── LPCXpresso55S28.mex │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── peripherals.c │ │ │ │ │ │ ├── peripherals.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── lpcxpresso55s69/ │ │ │ │ │ ├── LPCXpresso55S69.mex │ │ │ │ │ ├── board/ │ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ │ ├── clock_config.h │ │ │ │ │ │ ├── peripherals.c │ │ │ │ │ │ ├── peripherals.h │ │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ │ └── pin_mux.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── mcu_link/ │ │ │ │ ├── board/ │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── peripherals.c │ │ │ │ │ ├── peripherals.h │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── mcu_link.mex │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── maxim/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── README.md │ │ │ ├── boards/ │ │ │ │ ├── apard32690/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32650evkit/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32650fthr/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32651evkit/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32666evkit/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32666fthr/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── max32690evkit/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── max78002evkit/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── linker/ │ │ │ ├── max32650.ld │ │ │ ├── max32651.ld │ │ │ ├── max32665.ld │ │ │ ├── max32690.ld │ │ │ └── max78002.ld │ │ ├── mcx/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── frdm_mcxa153/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── frdm_mcxa153.mex │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ ├── frdm_mcxa156/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ ├── frdm_mcxn947/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── clock_config.c │ │ │ │ │ ├── clock_config.h │ │ │ │ │ ├── pin_mux.c │ │ │ │ │ └── pin_mux.h │ │ │ │ └── mcxn947brk/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── clock_config.c │ │ │ │ ├── clock_config.h │ │ │ │ ├── pin_mux.c │ │ │ │ └── pin_mux.h │ │ │ ├── debug.jlinkscript │ │ │ ├── drivers/ │ │ │ │ └── spc/ │ │ │ │ ├── fsl_spc.c │ │ │ │ └── fsl_spc.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── mm32/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── mm32f327x_mb39/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── flash.ld │ │ │ │ └── mm32f327x_pitaya_lite/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── msp430/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── msp_exp430f5529lp/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── msp432e4/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── msp_exp432e401y/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── nrf/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── adafruit_clue/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── arduino_nano33_ble/ │ │ │ │ │ ├── arduino_nano33_ble.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── circuitplayground_bluefruit/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── feather_nrf52840_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── feather_nrf52840_sense/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── itsybitsy_nrf52840/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── nrf52833dk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── nrf52840dk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── ozone/ │ │ │ │ │ └── nrf52840.jdebug │ │ │ │ ├── nrf52840dongle/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── nrf52840dongle.ld │ │ │ │ ├── nrf5340dk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── ozone/ │ │ │ │ │ └── nrf5340.jdebug │ │ │ │ └── nrf54h20dk/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ ├── nrf52833_xxaa.ld │ │ │ │ ├── nrf52840_s140_v6.ld │ │ │ │ ├── nrf52840_xxaa.ld │ │ │ │ ├── nrf5340_xxaa_application.ld │ │ │ │ └── nrf54h20_xxaa_application.ld │ │ │ └── nrfx_config/ │ │ │ ├── nrfx_config.h │ │ │ ├── nrfx_config_common.h │ │ │ ├── nrfx_config_ext.h │ │ │ ├── nrfx_glue.h │ │ │ └── nrfx_log.h │ │ ├── nuc100_120/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── nutiny_sdk_nuc120/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── nuc120_flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── nuc121_125/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── nutiny_sdk_nuc121/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── nuc121_flash.ld │ │ │ │ └── nutiny_sdk_nuc125/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── nuc125_flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── nuc126/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── nutiny_nuc126v/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── nuc126_flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── nuc505/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── nutiny_sdk_nuc505/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── nuc505_flashtoram.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── pic32mz/ │ │ │ ├── boards/ │ │ │ │ ├── olimex_emz64/ │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── olimex_emz64.c │ │ │ │ └── olimex_hmz144/ │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── olimex_hmz144.c │ │ │ ├── family.c │ │ │ └── family.mk │ │ ├── ra/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── board_cfg.h │ │ │ ├── boards/ │ │ │ │ ├── portenta_c33/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra2a1_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra4m1_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra4m3_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra6m1_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra6m5_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ozone/ │ │ │ │ │ │ └── ra6m5.jdebug │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ ├── ra8m1_ek/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ozone/ │ │ │ │ │ │ ├── Renesas_RA8_TracePins.pex │ │ │ │ │ │ └── ra8m1.jdebug │ │ │ │ │ ├── ra_cfg/ │ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ │ ├── ra_gen/ │ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ │ ├── common_data.c │ │ │ │ │ │ ├── common_data.h │ │ │ │ │ │ └── pin_data.c │ │ │ │ │ ├── script/ │ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ │ └── memory_regions.ld │ │ │ │ │ └── smart_configurator/ │ │ │ │ │ └── configuration.xml │ │ │ │ └── uno_r4/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── ra_cfg/ │ │ │ │ │ └── fsp_cfg/ │ │ │ │ │ ├── bsp/ │ │ │ │ │ │ ├── bsp_cfg.h │ │ │ │ │ │ ├── bsp_mcu_device_cfg.h │ │ │ │ │ │ ├── bsp_mcu_device_pn_cfg.h │ │ │ │ │ │ ├── bsp_mcu_family_cfg.h │ │ │ │ │ │ └── bsp_pin_cfg.h │ │ │ │ │ └── r_ioport_cfg.h │ │ │ │ ├── ra_gen/ │ │ │ │ │ ├── bsp_clock_cfg.h │ │ │ │ │ ├── common_data.c │ │ │ │ │ ├── common_data.h │ │ │ │ │ └── pin_data.c │ │ │ │ ├── script/ │ │ │ │ │ ├── fsp.ld │ │ │ │ │ └── memory_regions.ld │ │ │ │ └── smart_configurator/ │ │ │ │ └── configuration.xml │ │ │ ├── debug.jlinkscript │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── vector_data.h │ │ ├── rp2040/ │ │ │ ├── boards/ │ │ │ │ ├── adafruit_feather_rp2040_usb_host/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_fruit_jam/ │ │ │ │ │ ├── adafruit_fruit_jam.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── adafruit_metro_rp2350/ │ │ │ │ │ ├── adafruit_metro_rp2350.h │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── feather_rp2040_max3421/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── pico_sdk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── raspberry_pi_pico/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ ├── raspberry_pi_pico2/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ └── board.h │ │ │ │ └── raspberry_pi_pico_w/ │ │ │ │ ├── board.cmake │ │ │ │ └── board.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── pico_sdk_import.cmake │ │ │ ├── rp2040-openocd.cfg │ │ │ └── rp2350-openocd.cfg │ │ ├── rw61x/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── frdm_rw612/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── clock_config.c │ │ │ │ ├── clock_config.h │ │ │ │ ├── pin_mux.c │ │ │ │ └── pin_mux.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── rx/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── gr_citrus/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── gr_citrus.c │ │ │ │ │ └── r5f5631fd.ld │ │ │ │ └── rx65n_target/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── r5f565ne.ld │ │ │ │ └── rx65n_target.c │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── samd11/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── cynthion_d11/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── cynthion_d11.ld │ │ │ │ └── samd11_xplained/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── samd11d14am_flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── samd2x_l2x/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── atsamd21_xpro/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── samd21j18a_flash.ld │ │ │ │ ├── atsaml21_xpro/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── saml21j18b_flash.ld │ │ │ │ ├── circuitplayground_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── circuitplayground_express.ld │ │ │ │ ├── curiosity_nano/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── samd21g17a_flash.ld │ │ │ │ ├── cynthion_d21/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── samd21g18a_flash.ld │ │ │ │ ├── feather_m0_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── feather_m0_express.ld │ │ │ │ ├── itsybitsy_m0/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── itsybitsy_m0.ld │ │ │ │ ├── metro_m0_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── metro_m0_express.ld │ │ │ │ ├── qtpy/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── qtpy.ld │ │ │ │ ├── saml22_feather/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── saml22_feather.ld │ │ │ │ ├── seeeduino_xiao/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── seeeduino_xiao.ld │ │ │ │ ├── sensorwatch_m0/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── sensorwatch_m0.ld │ │ │ │ ├── sparkfun_samd21_mini_usb/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── sparkfun_samd21_mini_usb.ld │ │ │ │ └── trinket_m0/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── trinket_m0.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── samd5x_e5x/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── d5035_01/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── same51j19a_flash.ld │ │ │ │ ├── feather_m4_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── feather_m4_express.ld │ │ │ │ ├── itsybitsy_m4/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── itsybitsy_m4.ld │ │ │ │ ├── metro_m4_express/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── metro_m4_express.ld │ │ │ │ ├── pybadge/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── pybadge.ld │ │ │ │ ├── pyportal/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── pyportal.ld │ │ │ │ └── same54_xplained/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── same54p20a_flash.ld │ │ │ │ └── same54p20a_sram.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── same7x/ │ │ │ ├── boards/ │ │ │ │ ├── same70_qmtech/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── hpl_pmc_config.h │ │ │ │ │ ├── hpl_usart_config.h │ │ │ │ │ ├── hpl_xdmac_config.h │ │ │ │ │ └── peripheral_clk_config.h │ │ │ │ └── same70_xplained/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ ├── hpl_pmc_config.h │ │ │ │ ├── hpl_usart_config.h │ │ │ │ ├── hpl_xdmac_config.h │ │ │ │ └── peripheral_clk_config.h │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── samg/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── samg55_xplained/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── samg55j19_flash.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── hpl_usart_config.h │ │ │ └── peripheral_clk_config.h │ │ ├── stm32c0/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32c071nucleo/ │ │ │ │ ├── STM32C071RBTx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── stm32c071xx_flash.icf │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32c0xx_hal_conf.h │ │ ├── stm32f0/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32f070rbnucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── stm32F070rbtx_flash.ld │ │ │ │ ├── stm32f072disco/ │ │ │ │ │ ├── STM32F072RBTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32f072eval/ │ │ │ │ ├── STM32F072VBTx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f0xx_hal_conf.h │ │ ├── stm32f1/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32f103_bluepill/ │ │ │ │ │ ├── STM32F103X8_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── stm32f103x8_flash.icf │ │ │ │ ├── stm32f103_mini_2/ │ │ │ │ │ ├── STM32F103XC_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── stm32f103xc_flash.icf │ │ │ │ └── stm32f103ze_iar/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f1xx_hal_conf.h │ │ ├── stm32f2/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32f207nucleo/ │ │ │ │ ├── STM32F207ZGTx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f2xx_hal_conf.h │ │ ├── stm32f3/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32f303disco/ │ │ │ │ ├── STM32F303VCTx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f3xx_hal_conf.h │ │ ├── stm32f4/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── feather_stm32f405/ │ │ │ │ │ ├── STM32F405RGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── pyboardv11/ │ │ │ │ │ ├── STM32F405RGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f401blackpill/ │ │ │ │ │ ├── STM32F401VCTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f407blackvet/ │ │ │ │ │ ├── STM32F407VETx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f407disco/ │ │ │ │ │ ├── STM32F407VGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f411blackpill/ │ │ │ │ │ ├── STM32F411CEUx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f411disco/ │ │ │ │ │ ├── STM32F411VETx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f412disco/ │ │ │ │ │ ├── STM32F412ZGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f412nucleo/ │ │ │ │ │ ├── STM32F412ZGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32f439nucleo/ │ │ │ │ ├── STM32F439ZITX_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f4xx_hal_conf.h │ │ ├── stm32f7/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stlinkv3mini/ │ │ │ │ │ ├── STM32F723xE_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f723disco/ │ │ │ │ │ ├── STM32F723xE_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f746disco/ │ │ │ │ │ ├── STM32F746ZGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f746nucleo/ │ │ │ │ │ ├── STM32F746ZGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32f767nucleo/ │ │ │ │ │ ├── STM32F767ZITx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32f769disco/ │ │ │ │ ├── STM32F769ZITx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32f7xx_hal_conf.h │ │ ├── stm32g0/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32g0b1nucleo/ │ │ │ │ ├── STM32G0B1RETx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32g0xx_hal_conf.h │ │ ├── stm32g4/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── b_g474e_dpow1/ │ │ │ │ │ ├── STM32G474RETx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── cubemx/ │ │ │ │ │ └── b_g474e_dpow1.ioc │ │ │ │ ├── stm32g474nucleo/ │ │ │ │ │ ├── STM32G474RETx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32g491nucleo/ │ │ │ │ ├── STM32G491RETX_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32g4xx_hal_conf.h │ │ ├── stm32h5/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32h503nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32h563nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── cubemx/ │ │ │ │ │ └── stm32h563nucleo.ioc │ │ │ │ └── stm32h573i_dk/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ ├── STM32H503xx_FLASH.ld │ │ │ │ ├── STM32H523xx_FLASH.ld │ │ │ │ ├── STM32H533xx_FLASH.ld │ │ │ │ ├── STM32H562xx_FLASH.ld │ │ │ │ ├── STM32H563xx_FLASH.ld │ │ │ │ ├── STM32H573xx_FLASH.ld │ │ │ │ ├── stm32h503xx_flash.icf │ │ │ │ ├── stm32h523xx_flash.icf │ │ │ │ ├── stm32h562xx_flash.icf │ │ │ │ ├── stm32h563xx_flash.icf │ │ │ │ └── stm32h573xx_flash.icf │ │ │ └── stm32h5xx_hal_conf.h │ │ ├── stm32h7/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── daisyseed/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── stm32h750ibkx_flash.ld │ │ │ │ │ └── stm32h750ibkx_ram.ld │ │ │ │ ├── stm32h723nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32h743eval/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── cubemx/ │ │ │ │ │ │ └── stm32h743eval.ioc │ │ │ │ │ └── ozone/ │ │ │ │ │ └── stm32h743.jdebug │ │ │ │ ├── stm32h743nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── cubemx/ │ │ │ │ │ └── stm32h743nucleo.ioc │ │ │ │ ├── stm32h745disco/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32h747disco/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32h750_weact/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── stm32h750xx_flash_CM7.ld │ │ │ │ ├── stm32h750bdk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ └── stm32h750xx_flash_CM7.ld │ │ │ │ └── waveshare_openh743i/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ ├── stm32h723xx_flash.ld │ │ │ │ ├── stm32h743xx_flash.ld │ │ │ │ ├── stm32h745xx_flash_CM7.ld │ │ │ │ └── stm32h747xx_flash_CM7.ld │ │ │ └── stm32h7xx_hal_conf.h │ │ ├── stm32h7rs/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32h7s3nucleo/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ └── stm32h7s3xx_flash.ld │ │ │ └── stm32h7rsxx_hal_conf.h │ │ ├── stm32l0/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32l052dap52/ │ │ │ │ │ ├── STM32L052K8Ux_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32l0538disco/ │ │ │ │ ├── STM32L053C8Tx_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32l0xx_hal_conf.h │ │ ├── stm32l4/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32l412nucleo/ │ │ │ │ │ ├── STM32L412KBUx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32l476disco/ │ │ │ │ │ ├── STM32L476VGTx_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32l496nucleo/ │ │ │ │ │ ├── STM32L496ZGTX_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32l4p5nucleo/ │ │ │ │ │ ├── STM32L4P5ZGTX_FLASH.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32l4r5nucleo/ │ │ │ │ ├── STM32L4RXxI_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32l4xx_hal_conf.h │ │ ├── stm32n6/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32n6570dk/ │ │ │ │ │ ├── STM32N657XX_AXISRAM2_fsbl.ld │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32n657nucleo/ │ │ │ │ ├── STM32N657XX_AXISRAM2_fsbl.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── partition_stm32n657xx.h │ │ │ ├── setup_iar.mac │ │ │ ├── stm32n6.jdebug │ │ │ └── stm32n6xx_hal_conf.h │ │ ├── stm32u0/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── stm32u083cdk/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32u083nucleo/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── cubemx/ │ │ │ │ └── cubemx.ioc │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ ├── STM32U083xx_FLASH.ld │ │ │ │ └── stm32u083xx_flash.icf │ │ │ └── stm32u0xx_hal_conf.h │ │ ├── stm32u5/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── b_u585i_iot2a/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32u545nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32u575eval/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ ├── stm32u575nucleo/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── stm32u5a5nucleo/ │ │ │ │ ├── STM32U5A5ZJTXQ_FLASH.ld │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── cubemx/ │ │ │ │ └── stm32u5a5nucleo.ioc │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ ├── STM32U535xx_FLASH.ld │ │ │ │ ├── STM32U545xx_FLASH.ld │ │ │ │ ├── STM32U575xx_FLASH.ld │ │ │ │ ├── STM32U585xx_FLASH.ld │ │ │ │ ├── STM32U595xx_FLASH.ld │ │ │ │ ├── STM32U599xx_FLASH.ld │ │ │ │ ├── STM32U5A9xx_FLASH.ld │ │ │ │ ├── STM32U5F7xx_FLASH.ld │ │ │ │ ├── STM32U5F9xx_FLASH.ld │ │ │ │ ├── STM32U5G7xx_FLASH.ld │ │ │ │ └── STM32U5G9xx_FLASH.ld │ │ │ └── stm32u5xx_hal_conf.h │ │ ├── stm32wb/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32wb55nucleo/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── stm32wb55xx_flash_cm4.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ └── stm32wbxx_hal_conf.h │ │ ├── stm32wba/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ └── stm32wba_nucleo/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ ├── family.mk │ │ │ ├── linker/ │ │ │ │ └── STM32WBA65xx_FLASH_ns.ld │ │ │ └── stm32wbaxx_hal_conf.h │ │ ├── tm4c/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── ek_tm4c123gxl/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ ├── board.mk │ │ │ │ │ ├── ek_tm4c123gxl.ccxml │ │ │ │ │ └── tm4c123.ld │ │ │ │ └── ek_tm4c1294xl/ │ │ │ │ ├── TM4C1294NC.icf │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ ├── board.mk │ │ │ │ └── tm4c1294nc.ld │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ ├── xmc4000/ │ │ │ ├── FreeRTOSConfig/ │ │ │ │ └── FreeRTOSConfig.h │ │ │ ├── boards/ │ │ │ │ ├── xmc4500_relax/ │ │ │ │ │ ├── board.cmake │ │ │ │ │ ├── board.h │ │ │ │ │ └── board.mk │ │ │ │ └── xmc4700_relax/ │ │ │ │ ├── board.cmake │ │ │ │ ├── board.h │ │ │ │ └── board.mk │ │ │ ├── family.c │ │ │ ├── family.cmake │ │ │ └── family.mk │ │ └── zephyr_board_aliases.cmake │ └── mcu/ │ ├── bridgetek/ │ │ └── ft9xx/ │ │ ├── Readme.md │ │ └── scripts/ │ │ ├── crt0.S │ │ └── ldscript.ld │ ├── dialog/ │ │ ├── README.md │ │ └── da1469x/ │ │ ├── SDK_10.0.8.105/ │ │ │ └── sdk/ │ │ │ └── bsp/ │ │ │ ├── arm_license.txt │ │ │ └── include/ │ │ │ ├── DA1469xAB.h │ │ │ ├── cmsis_compiler.h │ │ │ ├── cmsis_gcc.h │ │ │ ├── cmsis_version.h │ │ │ ├── core_cm0.h │ │ │ ├── core_cm33.h │ │ │ ├── mpu_armv8.h │ │ │ ├── system_ARMCM0.h │ │ │ └── system_DA1469x.h │ │ ├── da1469x.ld │ │ ├── include/ │ │ │ ├── hal/ │ │ │ │ └── hal_gpio.h │ │ │ └── mcu/ │ │ │ ├── da1469x_clock.h │ │ │ ├── da1469x_hal.h │ │ │ └── mcu.h │ │ └── src/ │ │ ├── da1469x_clock.c │ │ ├── hal_gpio.c │ │ ├── hal_system.c │ │ ├── hal_system_start.c │ │ └── system_da1469x.c │ ├── nordic/ │ │ └── nrf5x/ │ │ └── s140_nrf52_6.1.1_API/ │ │ └── include/ │ │ ├── ble.h │ │ ├── ble_err.h │ │ ├── ble_gap.h │ │ ├── ble_gatt.h │ │ ├── ble_gattc.h │ │ ├── ble_gatts.h │ │ ├── ble_hci.h │ │ ├── ble_l2cap.h │ │ ├── ble_ranges.h │ │ ├── ble_types.h │ │ ├── nrf52/ │ │ │ └── nrf_mbr.h │ │ ├── nrf_error.h │ │ ├── nrf_error_sdm.h │ │ ├── nrf_error_soc.h │ │ ├── nrf_nvic.h │ │ ├── nrf_sdm.h │ │ ├── nrf_soc.h │ │ └── nrf_svc.h │ └── sony/ │ └── cxd56/ │ ├── mkspk/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── clefia.c │ │ ├── clefia.h │ │ ├── elf32.h │ │ ├── mkspk.c │ │ └── mkspk.h │ └── tools/ │ ├── flash_writer.py │ └── xmodem.py ├── lib/ │ ├── SEGGER_RTT/ │ │ ├── Config/ │ │ │ └── SEGGER_RTT_Conf.h │ │ ├── LICENSE.md │ │ ├── README.md │ │ └── RTT/ │ │ ├── SEGGER_RTT.c │ │ ├── SEGGER_RTT.h │ │ ├── SEGGER_RTT_ASM_ARMv7M.S │ │ └── SEGGER_RTT_printf.c │ ├── embedded-cli/ │ │ └── embedded_cli.h │ ├── fatfs/ │ │ ├── LICENSE.txt │ │ └── source/ │ │ ├── 00history.txt │ │ ├── 00readme.txt │ │ ├── diskio.c │ │ ├── diskio.h │ │ ├── ff.c │ │ ├── ff.h │ │ ├── ffconf.h │ │ ├── ffsystem.c │ │ └── ffunicode.c │ ├── networking/ │ │ ├── dhserver.c │ │ ├── dhserver.h │ │ ├── dnserver.c │ │ ├── dnserver.h │ │ ├── ndis.h │ │ ├── rndis_protocol.h │ │ └── rndis_reports.c │ └── rt-thread/ │ ├── SConscript │ ├── port/ │ │ └── msc_device_port.c │ ├── tusb_config.h │ └── tusb_rt_thread_port.c ├── library.json ├── pkg.yml ├── repository.yml ├── sonar-project.properties ├── src/ │ ├── CMakeLists.txt │ ├── class/ │ │ ├── audio/ │ │ │ ├── audio.h │ │ │ ├── audio_device.c │ │ │ └── audio_device.h │ │ ├── bth/ │ │ │ ├── bth_device.c │ │ │ └── bth_device.h │ │ ├── cdc/ │ │ │ ├── cdc.h │ │ │ ├── cdc_device.c │ │ │ ├── cdc_device.h │ │ │ ├── cdc_host.c │ │ │ ├── cdc_host.h │ │ │ ├── cdc_rndis.h │ │ │ └── serial/ │ │ │ ├── ch34x.h │ │ │ ├── cp210x.h │ │ │ ├── ftdi_sio.h │ │ │ └── pl2303.h │ │ ├── dfu/ │ │ │ ├── dfu.h │ │ │ ├── dfu_device.c │ │ │ ├── dfu_device.h │ │ │ ├── dfu_rt_device.c │ │ │ └── dfu_rt_device.h │ │ ├── hid/ │ │ │ ├── hid.h │ │ │ ├── hid_device.c │ │ │ ├── hid_device.h │ │ │ ├── hid_host.c │ │ │ └── hid_host.h │ │ ├── midi/ │ │ │ ├── README_midi_host.md │ │ │ ├── midi.h │ │ │ ├── midi_device.c │ │ │ ├── midi_device.h │ │ │ ├── midi_host.c │ │ │ └── midi_host.h │ │ ├── msc/ │ │ │ ├── msc.h │ │ │ ├── msc_device.c │ │ │ ├── msc_device.h │ │ │ ├── msc_host.c │ │ │ └── msc_host.h │ │ ├── mtp/ │ │ │ ├── mtp.h │ │ │ ├── mtp_device.c │ │ │ └── mtp_device.h │ │ ├── net/ │ │ │ ├── ecm_rndis_device.c │ │ │ ├── ncm.h │ │ │ ├── ncm_device.c │ │ │ └── net_device.h │ │ ├── printer/ │ │ │ ├── printer.h │ │ │ ├── printer_device.c │ │ │ └── printer_device.h │ │ ├── usbtmc/ │ │ │ ├── usbtmc.h │ │ │ ├── usbtmc_device.c │ │ │ └── usbtmc_device.h │ │ ├── vendor/ │ │ │ ├── vendor_device.c │ │ │ ├── vendor_device.h │ │ │ ├── vendor_host.c │ │ │ └── vendor_host.h │ │ └── video/ │ │ ├── video.h │ │ ├── video_device.c │ │ └── video_device.h │ ├── common/ │ │ ├── tusb_common.h │ │ ├── tusb_compiler.h │ │ ├── tusb_debug.h │ │ ├── tusb_fifo.c │ │ ├── tusb_fifo.h │ │ ├── tusb_mcu.h │ │ ├── tusb_private.h │ │ ├── tusb_types.h │ │ └── tusb_verify.h │ ├── device/ │ │ ├── dcd.h │ │ ├── usbd.c │ │ ├── usbd.h │ │ ├── usbd_control.c │ │ └── usbd_pvt.h │ ├── host/ │ │ ├── hcd.h │ │ ├── hub.c │ │ ├── hub.h │ │ ├── usbh.c │ │ ├── usbh.h │ │ └── usbh_pvt.h │ ├── osal/ │ │ ├── osal.h │ │ ├── osal_freertos.h │ │ ├── osal_mynewt.h │ │ ├── osal_none.h │ │ ├── osal_pico.h │ │ ├── osal_rtthread.h │ │ ├── osal_rtx4.h │ │ ├── osal_threadx.h │ │ └── osal_zephyr.h │ ├── portable/ │ │ ├── analog/ │ │ │ └── max3421/ │ │ │ ├── hcd_max3421.c │ │ │ └── hcd_max3421.h │ │ ├── bridgetek/ │ │ │ └── ft9xx/ │ │ │ └── dcd_ft9xx.c │ │ ├── chipidea/ │ │ │ ├── ci_fs/ │ │ │ │ ├── ci_fs_kinetis.h │ │ │ │ ├── ci_fs_mcx.h │ │ │ │ ├── ci_fs_type.h │ │ │ │ └── dcd_ci_fs.c │ │ │ └── ci_hs/ │ │ │ ├── ci_hs_hpm.h │ │ │ ├── ci_hs_imxrt.h │ │ │ ├── ci_hs_lpc18_43.h │ │ │ ├── ci_hs_mcx.h │ │ │ ├── ci_hs_rw61x.h │ │ │ ├── ci_hs_type.h │ │ │ ├── dcd_ci_hs.c │ │ │ └── hcd_ci_hs.c │ │ ├── dialog/ │ │ │ └── da146xx/ │ │ │ └── dcd_da146xx.c │ │ ├── ehci/ │ │ │ ├── ehci.c │ │ │ ├── ehci.h │ │ │ └── ehci_api.h │ │ ├── mentor/ │ │ │ └── musb/ │ │ │ ├── dcd_musb.c │ │ │ ├── hcd_musb.c │ │ │ ├── musb_max32.h │ │ │ ├── musb_ti.h │ │ │ └── musb_type.h │ │ ├── microchip/ │ │ │ ├── pic/ │ │ │ │ ├── README.md │ │ │ │ └── dcd_pic.c │ │ │ ├── pic32mz/ │ │ │ │ ├── dcd_pic32mz.c │ │ │ │ └── usbhs_registers.h │ │ │ ├── samd/ │ │ │ │ ├── dcd_samd.c │ │ │ │ └── hcd_samd.c │ │ │ ├── samg/ │ │ │ │ └── dcd_samg.c │ │ │ └── samx7x/ │ │ │ ├── dcd_samx7x.c │ │ │ └── samx7x_common.h │ │ ├── mindmotion/ │ │ │ └── mm32/ │ │ │ └── dcd_mm32f327x_otg.c │ │ ├── nordic/ │ │ │ └── nrf5x/ │ │ │ └── dcd_nrf5x.c │ │ ├── nuvoton/ │ │ │ ├── nuc120/ │ │ │ │ └── dcd_nuc120.c │ │ │ ├── nuc121/ │ │ │ │ └── dcd_nuc121.c │ │ │ └── nuc505/ │ │ │ └── dcd_nuc505.c │ │ ├── nxp/ │ │ │ ├── khci/ │ │ │ │ ├── dcd_khci.c │ │ │ │ └── hcd_khci.c │ │ │ ├── lpc17_40/ │ │ │ │ ├── dcd_lpc17_40.c │ │ │ │ └── dcd_lpc17_40.h │ │ │ ├── lpc_ip3511/ │ │ │ │ └── dcd_lpc_ip3511.c │ │ │ └── lpc_ip3516/ │ │ │ ├── hcd_lpc_ip3516.c │ │ │ └── hcd_lpc_ip3516.h │ │ ├── ohci/ │ │ │ ├── ohci.c │ │ │ ├── ohci.h │ │ │ └── ohci_nxp.h │ │ ├── raspberrypi/ │ │ │ ├── pio_usb/ │ │ │ │ ├── dcd_pio_usb.c │ │ │ │ └── hcd_pio_usb.c │ │ │ └── rp2040/ │ │ │ ├── dcd_rp2040.c │ │ │ ├── hcd_rp2040.c │ │ │ ├── rp2040_usb.c │ │ │ └── rp2040_usb.h │ │ ├── renesas/ │ │ │ └── rusb2/ │ │ │ ├── dcd_rusb2.c │ │ │ ├── hcd_rusb2.c │ │ │ ├── rusb2_common.c │ │ │ ├── rusb2_common.h │ │ │ ├── rusb2_ra.h │ │ │ ├── rusb2_rx.h │ │ │ └── rusb2_type.h │ │ ├── sony/ │ │ │ └── cxd56/ │ │ │ └── dcd_cxd56.c │ │ ├── st/ │ │ │ ├── stm32_fsdev/ │ │ │ │ ├── dcd_stm32_fsdev.c │ │ │ │ ├── fsdev_at32.h │ │ │ │ ├── fsdev_ch32.h │ │ │ │ ├── fsdev_common.c │ │ │ │ ├── fsdev_common.h │ │ │ │ ├── fsdev_stm32.h │ │ │ │ └── hcd_stm32_fsdev.c │ │ │ └── typec/ │ │ │ └── typec_stm32.c │ │ ├── sunxi/ │ │ │ ├── dcd_sunxi_musb.c │ │ │ └── musb_def.h │ │ ├── synopsys/ │ │ │ └── dwc2/ │ │ │ ├── dcd_dwc2.c │ │ │ ├── dwc2_at32.h │ │ │ ├── dwc2_bcm.h │ │ │ ├── dwc2_common.c │ │ │ ├── dwc2_common.h │ │ │ ├── dwc2_efm32.h │ │ │ ├── dwc2_esp32.h │ │ │ ├── dwc2_gd32.h │ │ │ ├── dwc2_info.md │ │ │ ├── dwc2_info.py │ │ │ ├── dwc2_nrf.h │ │ │ ├── dwc2_stm32.h │ │ │ ├── dwc2_type.h │ │ │ ├── dwc2_xmc.h │ │ │ └── hcd_dwc2.c │ │ ├── template/ │ │ │ ├── dcd_template.c │ │ │ └── hcd_template.c │ │ ├── ti/ │ │ │ └── msp430x5xx/ │ │ │ └── dcd_msp430x5xx.c │ │ ├── valentyusb/ │ │ │ └── eptri/ │ │ │ ├── dcd_eptri.c │ │ │ └── dcd_eptri.h │ │ └── wch/ │ │ ├── ch32_usbfs_reg.h │ │ ├── ch32_usbhs_reg.h │ │ ├── dcd_ch32_usbfs.c │ │ ├── dcd_ch32_usbhs.c │ │ └── hcd_ch32_usbfs.c │ ├── tinyusb.mk │ ├── tusb.c │ ├── tusb.h │ ├── tusb_option.h │ └── typec/ │ ├── pd_types.h │ ├── tcd.h │ ├── usbc.c │ └── usbc.h ├── test/ │ ├── fuzz/ │ │ ├── dcd_fuzz.cc │ │ ├── device/ │ │ │ ├── cdc/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Makefile │ │ │ │ └── src/ │ │ │ │ ├── fuzz.cc │ │ │ │ ├── tusb_config.h │ │ │ │ └── usb_descriptors.cc │ │ │ ├── msc/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Makefile │ │ │ │ └── src/ │ │ │ │ ├── fuzz.cc │ │ │ │ ├── tusb_config.h │ │ │ │ └── usb_descriptors.cc │ │ │ └── net/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ └── src/ │ │ │ ├── arch/ │ │ │ │ └── cc.h │ │ │ ├── fuzz.cc │ │ │ ├── lwipopts.h │ │ │ ├── tusb_config.h │ │ │ └── usb_descriptors.cc │ │ ├── dicts/ │ │ │ └── cdc.dict │ │ ├── fuzz.cc │ │ ├── fuzz.h │ │ ├── fuzz_private.h │ │ ├── make.mk │ │ ├── msc_fuzz.cc │ │ ├── net_fuzz.cc │ │ ├── rules.mk │ │ └── usbd_fuzz.cc │ ├── hil/ │ │ ├── hfp.json │ │ ├── hil_ci_set_matrix.py │ │ ├── hil_test.py │ │ ├── pymtp.py │ │ ├── requirements.txt │ │ └── tinyusb.json │ └── unit-test/ │ ├── CMakeLists.txt │ ├── ceedling │ ├── project.yml │ └── test/ │ ├── device/ │ │ ├── msc/ │ │ │ └── test_msc_device.c │ │ └── usbd/ │ │ └── test_usbd.c │ ├── support/ │ │ └── tusb_config.h │ ├── test_common_func.c │ └── test_fifo.c ├── tools/ │ ├── build.py │ ├── build_utils.py │ ├── codespell/ │ │ ├── exclude-file.txt │ │ └── ignore-words.txt │ ├── file2carray.py │ ├── gen_doc.py │ ├── gen_presets.py │ ├── get_deps.py │ ├── iar_gen.py │ ├── iar_template.ipcf │ ├── make_release.py │ ├── metrics.py │ ├── mksunxi.py │ ├── pcapng_to_corpus.py │ └── usb_drivers/ │ └── tinyusb_win_usbser.inf └── version.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/config.yml ================================================ version: 2.1 setup: true orbs: continuation: circleci/continuation@1 jobs: set-matrix: executor: continuation/default docker: - image: cimg/base:current resource_class: large steps: - checkout - run: name: Set matrix command: | MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) echo "MATRIX_JSON=$MATRIX_JSON" BUILDSYSTEM_LIST=( "cmake" "make" ) TOOLCHAIN_LIST=( "aarch64-gcc" "arm-clang" "arm-gcc" "esp-idf" "ft9xx-gcc" "msp430-gcc" "riscv-gcc" ) # only build IAR if not forked PR, since IAR token is not shared if [ -z $CIRCLE_PR_USERNAME ]; then TOOLCHAIN_LIST+=("arm-iar") fi gen_build_entry() { local build_system="$1" local toolchain="$2" local family="$3" local build_args="" if [[ "$toolchain" == "arm-iar" || "$build_system" == "make" ]]; then build_args="--one-random" fi if [[ "$toolchain" == "esp-idf" ]]; then echo " - build-vm:" >> .circleci/config2.yml else echo " - build:" >> .circleci/config2.yml fi echo " matrix:" >> .circleci/config2.yml echo " alias: build-${build_system}-${toolchain}" >> .circleci/config2.yml echo " parameters:" >> .circleci/config2.yml echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml echo " family: $family" >> .circleci/config2.yml echo " resource_class: ['large']" >> .circleci/config2.yml echo " build-args: ['$build_args']" >> .circleci/config2.yml } # Collect all build aliases for code-metrics requires (cmake only, exclude esp-idf) BUILD_ALIASES=() for build_system in "${BUILDSYSTEM_LIST[@]}"; do for toolchain in "${TOOLCHAIN_LIST[@]}"; do # make does not support these toolchains if [ "$build_system" == "make" ] && { [ "$toolchain" == "arm-clang" ] || [ "$toolchain" == "arm-iar" ] || [ "$toolchain" == "esp-idf" ]; }; then continue fi FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") echo "FAMILY_${toolchain}=$FAMILY" gen_build_entry "$build_system" "$toolchain" "$FAMILY" # Only add cmake builds: excluding esp-idf or build_args="--one-random" to metrics requirements if [ "$build_system" == "cmake" ] && [ "$toolchain" != "esp-idf" ] && [ "$toolchain" != "arm-iar" ]; then BUILD_ALIASES+=("build-${build_system}-${toolchain}") fi done done # Add code-metrics job that requires all build jobs echo " - code-metrics:" >> .circleci/config2.yml echo " requires:" >> .circleci/config2.yml for alias in "${BUILD_ALIASES[@]}"; do echo " - $alias" >> .circleci/config2.yml done - continuation/continue: configuration_path: .circleci/config2.yml workflows: set-matrix: jobs: - set-matrix ================================================ FILE: .circleci/config2.yml ================================================ version: 2.1 commands: setup-toolchain: parameters: toolchain: type: string steps: - run: name: Set toolchain url and key command: | toolchain_url=$(jq -r '."<< parameters.toolchain >>"' .github/actions/setup_toolchain/toolchain.json) # only cache if not a github link if [[ $toolchain_url != "https://github.com"* ]]; then echo "<< parameters.toolchain >>-$toolchain_url" > toolchain_key fi echo "export toolchain_url=$toolchain_url" >> $BASH_ENV - restore_cache: name: Restore Toolchain Cache key: deps-{{ checksum "toolchain_key" }} paths: - ~/cache/<< parameters.toolchain >> - run: name: Install Toolchain command: | # download if folder does not exist (not cached) if [ ! -d ~/cache/<< parameters.toolchain >> ]; then mkdir -p ~/cache/<< parameters.toolchain >> if [[ << parameters.toolchain >> == rx-gcc ]]; then wget --progress=dot:giga $toolchain_url -O toolchain.run chmod +x toolchain.run ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb elif [[ << parameters.toolchain >> == arm-iar ]]; then wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/toolchain.deb else wget --progress=dot:giga $toolchain_url -O toolchain.tar.gz tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz fi fi # Add toolchain to PATH if [[ << parameters.toolchain >> == arm-iar ]]; then # Install IAR since we only cache deb file sudo dpkg -i ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb sudo dpkg --ignore-depends=libusb-1.0-0 -i ~/cache/<< parameters.toolchain >>/toolchain.deb echo "export PATH=$PATH:/opt/iar/cxarm/arm/bin" >> $BASH_ENV elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then sudo apt install -y ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb echo "export PATH=$PATH:/opt/ft32/bin" >> $BASH_ENV else echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV fi - save_cache: name: Save Toolchain Cache key: deps-{{ checksum "toolchain_key" }} paths: - ~/cache/<< parameters.toolchain >> build: parameters: build-system: type: string toolchain: type: string family: type: string build-args: type: string default: "" steps: - checkout - run: name: Get Dependencies command: | python tools/get_deps.py << parameters.family >> # Install ninja if cmake build system if [ << parameters.build-system >> == "cmake" ]; then NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip wget $NINJA_URL -O ninja-linux.zip unzip ninja-linux.zip -d ~/bin fi # rx-gcc is 32-bit binary if [[ << parameters.toolchain >> == rx-gcc ]]; then sudo dpkg --add-architecture i386 sudo apt update sudo apt install libc6:i386 libstdc++6:i386 zlib1g:i386 fi # Install Pico SDK if [ << parameters.family >> == "rp2040" ]; then git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV fi - when: condition: not: equal: [esp-idf, << parameters.toolchain >>] steps: - setup-toolchain: toolchain: << parameters.toolchain >> - run: name: Build no_output_timeout: 20m command: | if [ << parameters.toolchain >> == esp-idf ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:v5.5.3 python tools/build.py << parameters.build-args >> --target all << parameters.family >> else # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then TOOLCHAIN_OPTION="--toolchain clang" elif [ << parameters.toolchain >> == arm-iar ]; then TOOLCHAIN_OPTION="--toolchain iar" iccarm --version elif [ << parameters.toolchain >> == arm-gcc ]; then TOOLCHAIN_OPTION="--toolchain gcc" fi # circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large) # Required for IAR, also prevent crashed/killed by docker BUILD_PY_ARGS="-s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> --target all" if [ << parameters.build-system >> == "cmake" ]; then BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics" fi python tools/build.py $BUILD_PY_ARGS << parameters.family >> fi # Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random) - when: condition: and: - equal: [ cmake, << parameters.build-system >> ] - not: equal: [ esp-idf, << parameters.toolchain >> ] - not: equal: [ arm-iar, << parameters.toolchain >> ] steps: - run: name: Collect Metrics command: | # Create unique directory per toolchain to avoid workspace conflicts METRICS_DIR="/tmp/metrics/<< parameters.toolchain >>" mkdir -p "${METRICS_DIR}" # Copy all metrics.json files for f in cmake-build/cmake-build-*/metrics.json; do if [ -f "$f" ]; then BOARD_DIR=$(dirname "$f" | xargs basename) cp "$f" "${METRICS_DIR}/${BOARD_DIR}.json" fi done - persist_to_workspace: root: /tmp paths: - metrics/<< parameters.toolchain >> jobs: # Build using docker build: parameters: resource_class: type: string default: large build-system: type: string toolchain: type: string family: type: string build-args: type: string default: "" docker: - image: cimg/base:current working_directory: ~/project/tinyusb resource_class: << parameters.resource_class >> steps: - build: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> build-args: << parameters.build-args >> # Build using VM build-vm: parameters: resource_class: type: string default: large build-system: type: string toolchain: type: string family: type: string build-args: type: string default: "" machine: image: ubuntu-2404:current working_directory: ~/project/tinyusb resource_class: << parameters.resource_class >> steps: - build: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> build-args: << parameters.build-args >> # Aggregate code metrics from all builds code-metrics: docker: - image: cimg/python:3.12 resource_class: large steps: - checkout - attach_workspace: at: /tmp - run: name: Aggregate Code Metrics command: | python tools/get_deps.py # Combine all metrics files from all toolchain subdirectories ls -R /tmp/metrics if ls /tmp/metrics/*/*.json 1> /dev/null 2>&1; then python tools/metrics.py combine -j -m -f tinyusb/src /tmp/metrics/*/*.json else echo "No metrics files found" exit 1 fi - store_artifacts: path: metrics.json destination: metrics.json # Compare with base master metrics on PR branches - when: condition: not: equal: [ master, << pipeline.git.branch >> ] steps: - run: name: Download Base Branch Metrics command: | # Download metrics.json artifact from the latest successful build on master branch mkdir -p base-metrics # Use CircleCI API to get the latest artifact curl -s -L "https://dl.circleci.com/api/v2/project/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/latest/artifacts?branch=master&filter=successful" \ -H "Circle-Token: ${CIRCLE_TOKEN:-}" | \ jq -r '.items[] | select(.path == "metrics.json") | .url' | \ head -1 | xargs -I {} curl -s -L -o base-metrics/metrics.json {} || true - run: name: Compare with Base Branch command: | if [ -f base-metrics/metrics.json ]; then python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json cat metrics_compare.md else echo "No base metrics found, skipping comparison" cp metrics.md metrics_compare.md fi - store_artifacts: path: metrics_compare.md destination: metrics_compare.md workflows: build: jobs: # The jobs below are populated dynamically by config.yml set-matrix job # Example entries that will be generated: # - build: # matrix: # alias: build-cmake-arm-gcc # parameters: # toolchain: [ 'arm-gcc' ] # build-system: [ 'cmake' ] # family: [ 'nrf' ] # resource_class: ['large'] # - code-metrics: # requires: # - build-cmake-arm-gcc ================================================ FILE: .clang-format ================================================ --- Language: Cpp BasedOnStyle: LLVM AlignAfterOpenBracket: Align AlignConsecutiveAssignments: Enabled: true AcrossEmptyLines: false AcrossComments: false AlignConsecutiveBitFields: Enabled: true AcrossEmptyLines: false AcrossComments: false AlignConsecutiveDeclarations: Enabled: true AcrossEmptyLines: false AcrossComments: false AlignConsecutiveMacros: Enabled: true AcrossEmptyLines: true AcrossComments: false AlignConsecutiveShortCaseStatements: Enabled: true AcrossEmptyLines: true AcrossComments: true AlignCaseColons: false AlignEscapedNewlines: LeftWithLastLine AlignOperands: true AlignTrailingComments: Kind: Always OverEmptyLines: 2 AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: Empty AllowShortCaseExpressionOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false AllowShortEnumsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: false AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterStruct: false AfterUnion: false AfterExternBlock: false BeforeCatch: true BeforeElse: false BeforeLambdaBody: false BeforeWhile: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BracedInitializerIndentWidth: 2 BreakBeforeBinaryOperators: None BreakConstructorInitializers: AfterColon BreakConstructorInitializersBeforeComma: false ContinuationIndentWidth: 2 ColumnLimit: 120 ConstructorInitializerAllOnOneLineOrOnePerLine: false Cpp11BracedListStyle: true IncludeBlocks: Preserve IncludeCategories: - Regex: '^<.*' Priority: 1 - Regex: '^".*' Priority: 2 - Regex: '.*' Priority: 3 IncludeIsMainRegex: '([-_](test|unittest))?$' IndentPPDirectives: BeforeHash InsertBraces: true IndentCaseLabels: true InsertNewlineAtEOF: true MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: All PenaltyBreakBeforeFirstCallParameter: 1000000 PenaltyBreakOpenParenthesis: 1000000 PPIndentWidth: 2 QualifierAlignment: Custom QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type'] SpaceAfterTemplateKeyword: false SpaceBeforeRangeBasedForLoopColon: false SpaceInEmptyParentheses: false SpacesInAngles: false SpacesInConditionalStatement: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false SortIncludes: false TabWidth: 2 ... ================================================ FILE: .codespellrc ================================================ # See: https://github.com/codespell-project/codespell#using-a-config-file [codespell] # In the event of a false positive, add the problematic word, in all lowercase, to 'ignore-words.txt' (one word per line). # Or copy & paste the whole problematic line to 'exclude-file.txt' ignore-words = tools/codespell/ignore-words.txt exclude-file = tools/codespell/exclude-file.txt check-filenames = check-hidden = count = skip = *.rb,.cproject,.git,./lib,./examples/*/*/_build,./examples/*/*/ses,./examples/*/*/ozone,./hw/mcu,./tests_obsolete ================================================ FILE: .gitattributes ================================================ # Set the default behavior, in case people don't have core.autocrlf set. * text=auto *.c text *.cpp text *.h text *.icf text *.js text *.json text *.ld text *.md text *.mk text *.py text *.rst text *.s text *.txt text *.xml text *.yml text Makefile text # Windows-only Visual Studio things *.sln text eol=crlf *.csproj text eol=crlf ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Bug Report description: Report a problem with TinyUSB labels: 'Bug 🐞' body: - type: markdown attributes: value: | Thanks for taking the time to fill out this bug report! It's okay to leave some blank if it doesn't apply to your problem. - type: dropdown attributes: label: Operating System options: - Linux - MacOS - RaspberryPi OS - Windows 7 - Windows 10 - Windows 11 - Others validations: required: true - type: input attributes: label: Commit SHA placeholder: e.g 3a042b37da28d0ba1e5593eb1068ca5645d77b56 or version bundled by esp-idf or pico-sdk validations: required: true - type: input attributes: label: Board placeholder: e.g Adafruit Feather nRF52840 Express validations: required: true - type: textarea attributes: label: Firmware placeholder: | e.g examples/device/cdc_msc. If it is custom firmware, it is preferably compiled like one in example folder and reviewable for people to comment on. The easiest way is - Fork this repo, checkout a new branch - Add your-own-example based on stock one - Push and post it here. validations: required: true - type: textarea attributes: label: What happened ? placeholder: A clear and concise description of what the bug is. validations: required: true - type: textarea attributes: label: How to reproduce ? placeholder: | Exact steps in chronological order, details should be specific e.g if you use a command/script to test with, please post it as well. 1. Go to '...' 2. Click on '....' 3. See error validations: required: true - type: textarea attributes: label: Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2) placeholder: | Attach your debug log txt file here, where the issue occurred, best with comments to explain the actual events. Note1: Please DO NOT paste your lengthy log contents here since it hurts the readability. Note2: To enable logging, add `LOG=2` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=2` in your tusb_config.h. More information can be found at [example's readme](https://github.com/hathach/tinyusb/blob/master/docs/getting_started.md) validations: required: true - type: textarea attributes: label: Screenshots description: If applicable, add screenshots to help explain your problem. validations: required: false - type: checkboxes attributes: label: I have checked existing issues, discussion and documentation description: You agree to check all the resources above before opening a new issue. options: - label: I confirm I have checked existing issues, discussion and documentation. required: true ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: TinyUSB Discussion url: https://github.com/hathach/tinyusb/discussions about: If you have other questions or need help, post it here. - name: TinyUSB Docs url: https://docs.tinyusb.org/ about: Online documentation ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: Feature Request description: Suggest an idea for this project labels: 'Feature 💡' body: - type: markdown attributes: value: | Thanks for taking the time to fill out this request! It's okay to leave some blank if it doesn't apply to your request. - type: input attributes: label: Related area description: Please briefly explain the area of your Feature Request. placeholder: eg. new port support, device stack, class driver ... validations: required: true - type: input attributes: label: Hardware specification description: Please provide if your proposal depends on specific Hardware. placeholder: eg. rp2040, samd51 ... validations: required: true - type: textarea attributes: label: Is your feature request related to a problem? description: Please provide a clear and concise description of what the problem is. Add relevant issue link. placeholder: ex. I'm facing the issue/missing function... validations: required: true - type: textarea attributes: label: Describe the solution you'd like description: Please provide a clear and concise description of what you want to happen. placeholder: ex. When using this function... validations: required: true - type: checkboxes attributes: label: I have checked existing issues, dicussion and documentation description: You agree to check all the resources above before opening a new issue. options: - label: I confirm I have checked existing issues, dicussion and documentation. required: true ================================================ FILE: .github/actions/get_deps/action.yml ================================================ name: Get dependencies inputs: arg: description: 'Arguments to get_deps.py' required: true runs: using: "composite" steps: - name: Checkout pico-sdk for rp2040 if: >- contains(inputs.arg, 'rp2040') || contains(inputs.arg, 'rp2350') || contains(inputs.arg, 'raspberry_pi_pico') || contains(inputs.arg, 'adafruit_fruit_jam') uses: actions/checkout@v6 with: repository: raspberrypi/pico-sdk ref: master path: pico-sdk - name: Linux dependencies if: runner.os == 'Linux' run: | NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip wget $NINJA_URL -O ninja-linux.zip unzip ninja-linux.zip -d ninja-bin pip install membrowse echo >> $GITHUB_PATH "${{ github.workspace }}/ninja-bin" shell: bash - name: Get Dependencies env: ARG: ${{ inputs.arg }} run: | python3 tools/get_deps.py ${ARG} echo "PICO_SDK_PATH=${{ github.workspace }}/pico-sdk" >> $GITHUB_ENV shell: bash ================================================ FILE: .github/actions/setup_toolchain/action.yml ================================================ name: Setup Toolchain inputs: toolchain: description: 'Toolchain name' required: true outputs: build_option: description: 'Build option for the toolchain e.g --toolchain clang' value: ${{ steps.set-toolchain-option.outputs.build_option }} runs: using: "composite" steps: - name: Pull ESP-IDF docker if: inputs.toolchain == 'esp-idf' uses: ./.github/actions/setup_toolchain/espressif with: toolchain: ${{ inputs.toolchain }} - name: Get Toolchain URL if: inputs.toolchain != 'esp-idf' id: set-toolchain-url env: TOOLCHAIN: ${{ inputs.toolchain }} run: | TOOLCHAIN_URL=$(jq -r --arg tc "$TOOLCHAIN" '.[$tc]' .github/actions/setup_toolchain/toolchain.json) echo "toolchain_url=$TOOLCHAIN_URL" echo "toolchain_url=$TOOLCHAIN_URL" >> $GITHUB_OUTPUT shell: bash - name: Download Toolchain if: inputs.toolchain != 'esp-idf' uses: ./.github/actions/setup_toolchain/download with: toolchain: ${{ inputs.toolchain }} toolchain_url: ${{ steps.set-toolchain-url.outputs.toolchain_url }} - name: Set toolchain option id: set-toolchain-option env: TOOLCHAIN: ${{ inputs.toolchain }} run: | BUILD_OPTION="" if [[ "$TOOLCHAIN" == *"clang"* ]]; then BUILD_OPTION="--toolchain clang" elif [[ "$TOOLCHAIN" == "arm-iar" ]]; then BUILD_OPTION="--toolchain iar" fi echo "build_option=$BUILD_OPTION" echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT shell: bash ================================================ FILE: .github/actions/setup_toolchain/download/action.yml ================================================ name: Download Toolchain inputs: toolchain: description: 'Toolchain name' required: true toolchain_url: description: 'Toolchain URL' required: true runs: using: "composite" steps: - name: Cache Toolchain if: ${{ !startsWith(inputs.toolchain_url, 'https://github.com') }} uses: actions/cache@v5 id: cache-toolchain-download with: path: ~/cache/${{ inputs.toolchain }} key: ${{ runner.os }}-${{ inputs.toolchain }}-${{ inputs.toolchain_url }} - name: Install Toolchain if: steps.cache-toolchain-download.outputs.cache-hit != 'true' env: TOOLCHAIN: ${{ inputs.toolchain }} TOOLCHAIN_URL: ${{ inputs.toolchain_url }} run: | mkdir -p ~/cache/${TOOLCHAIN} FILE_EXT="${TOOLCHAIN_URL##*.}" if [[ ${TOOLCHAIN} == rx-gcc ]]; then wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.run chmod +x toolchain.run ./toolchain.run -p ~/cache/${TOOLCHAIN}/gnurx -y elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb elif [[ ${TOOLCHAIN} == arm-iar ]]; then wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/cxarm.deb elif [[ ${FILE_EXT} == zip ]]; then curl -L "$TOOLCHAIN_URL" -o toolchain.zip unzip -q toolchain.zip -d ~/cache/${TOOLCHAIN} ~/cache/${TOOLCHAIN}/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin/arm-none-eabi-gcc.exe --version elif [[ ${FILE_EXT} == gz ]]; then wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.tar.gz tar -C ~/cache/${TOOLCHAIN} -xaf toolchain.tar.gz else echo "Unsupported toolchain file extension: ${FILE_EXT}" exit 1 fi shell: bash - name: Setup Toolchain env: TOOLCHAIN: ${{ inputs.toolchain }} run: | if [[ ${TOOLCHAIN} == arm-iar ]]; then sudo dpkg -i ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb sudo apt install -y ~/cache/${TOOLCHAIN}/cxarm.deb TOOLCHAIN_PATH="/opt/iar/cxarm/arm/bin" elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then sudo apt install -y ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb TOOLCHAIN_PATH="/opt/ft32/bin" else # Find the single toolchain bin directory TOOLCHAIN_BIN_DIRS=(~/cache/${TOOLCHAIN}/*/bin) if [[ ${#TOOLCHAIN_BIN_DIRS[@]} -ne 1 ]]; then echo "Error: Expected exactly one toolchain bin directory, found ${#TOOLCHAIN_BIN_DIRS[@]}" exit 1 fi TOOLCHAIN_PATH="${TOOLCHAIN_BIN_DIRS[0]}" fi # Convert to native path for Windows compatibility if [[ "$RUNNER_OS" == "Windows" ]]; then TOOLCHAIN_PATH=$(cygpath -w "$TOOLCHAIN_PATH") fi echo "$TOOLCHAIN_PATH" >> $GITHUB_PATH shell: bash ================================================ FILE: .github/actions/setup_toolchain/espressif/action.yml ================================================ name: Setup ESP-IDF Toolchain inputs: toolchain: description: 'Toolchain name' required: true toolchain_version: description: 'Toolchain version' required: false default: 'v5.5.3' runs: using: "composite" steps: - name: Set DOCKER_ESP_IDF env: TOOLCHAIN: ${{ inputs.toolchain }} run: | DOCKER_ESP_IDF=$HOME/cache/${TOOLCHAIN}/docker_image.tar echo "DOCKER_ESP_IDF=$DOCKER_ESP_IDF" >> $GITHUB_ENV shell: bash - name: Cache Docker Image uses: actions/cache@v5 id: cache-toolchain-espressif with: path: ${{ env.DOCKER_ESP_IDF }} key: ${{ inputs.toolchain }}-${{ inputs.toolchain_version }} - name: Pull and Save Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true' env: TOOLCHAIN_VERSION: ${{ inputs.toolchain_version }} run: | docker pull espressif/idf:${TOOLCHAIN_VERSION} mkdir -p $(dirname $DOCKER_ESP_IDF) docker save -o $DOCKER_ESP_IDF espressif/idf:${TOOLCHAIN_VERSION} du -sh $DOCKER_ESP_IDF shell: bash - name: Load Docker Image if: steps.cache-toolchain-espressif.outputs.cache-hit == 'true' run: | du -sh $DOCKER_ESP_IDF docker load --input $DOCKER_ESP_IDF shell: bash - name: Tag Local Image env: TOOLCHAIN_VERSION: ${{ inputs.toolchain_version }} run: | docker tag espressif/idf:${TOOLCHAIN_VERSION} espressif/idf:tinyusb docker images shell: bash ================================================ FILE: .github/actions/setup_toolchain/toolchain.json ================================================ { "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-19.1.1/LLVM-ET-Arm-19.1.1-Linux-x86_64.tar.xz", "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz", "ft9xx-gcc": "https://github.com/Bridgetek/ft32-toolchain-linux/releases/download/v2.7.6/ft9xxtoolchain_2.7.6_amd64.deb", "arm-gcc-macos-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-darwin-arm64.tar.gz", "arm-gcc-windows-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-win32-x64.zip", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", "rx-gcc": "https://github.com/hathach/rx_device/releases/download/0.0.1/gcc-8.3.0.202411-GNURX-ELF.run", "arm-iar": "https://netstorage.iar.com/FileStore/STANDARD/001/003/723/cxarm-9.70.1.deb" } ================================================ FILE: .github/membrowse_pr_message.j2 ================================================ {#- Top 10 targets with biggest memory changes + project dashboard link -#} {% set section_columns = ['.text', '.rodata', '.data', '.bss'] -%} {#- --- Compute per-target total absolute delta and collect changed targets --- -#} {% set changed = [] -%} {% for target in targets -%} {% if target.has_changes -%} {% set ns = namespace(total_delta=0, total_current=0) -%} {% for region in target.regions -%} {% set ns.total_delta = ns.total_delta + region.delta -%} {% set ns.total_current = ns.total_current + region.used_size -%} {% endfor -%} {% set total_old = ns.total_current - ns.total_delta -%} {% set pct = (ns.total_delta / total_old * 100) if total_old > 0 else 0 -%} {% set abs_pct = (ns.total_delta | abs) if total_old == 0 else (pct | abs) -%} {% set _ = changed.append({'target': target, 'total_current': ns.total_current, 'total_old': total_old, 'total_delta': ns.total_delta, 'pct': pct, 'abs_pct': abs_pct}) -%} {% endif -%} {% endfor -%} {#- --- Sort by absolute percentage change descending and take top 10 --- -#} {% set sorted_changed = changed | sort(attribute='abs_pct', reverse=true) -%} {% set top10 = sorted_changed[:10] -%} {#- --- Render --- -#} {% if top10 %} ### Top {{ top10 | length }} targets by memory change (%) (out of {{ targets | length }} targets) {% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %} | target | .text | .rodata | .data | .bss | total | % diff | |--------|-------|---------|-------|------|-------|--------| {% for info in top10 -%} {% set target = info.target -%} {% set section_map = {} -%} {% for section in target.sections -%} {% set _ = section_map.update({section.name: section}) -%} {% endfor -%} | {% if target.comparison_url %}[{{ target.name }}]({{ target.comparison_url }}){% else %}{{ target.name }}{% endif %} | {%- for col in section_columns %} {% if col in section_map %}{{ "{:,}".format(section_map[col].old.size) }} → {{ "{:,}".format(section_map[col].size) }} ({{ section_map[col].delta_str }}){% else %}—{% endif %} |{% endfor %} {{ "{:,}".format(info.total_old) }} → {{ "{:,}".format(info.total_current) }} ({% if info.total_delta >= 0 %}+{{ "{:,}".format(info.total_delta) }}{% else %}{{ "{:,}".format(info.total_delta) }}{% endif %}) | {% if info.total_old > 0 %}{% if info.pct >= 0 %}+{% endif %}{{ "%.1f" | format(info.pct) }}%{% else %}N/A{% endif %} | {% endfor %} {% else %} No memory changes detected across {{ targets | length }} target{{ 's' if targets | length != 1 else '' }}.{% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %} {% endif -%} ================================================ FILE: .github/workflows/build.yml ================================================ name: Build on: workflow_dispatch: push: branches: [master] pull_request: release: types: [ published ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: HIL_JSON: test/hil/tinyusb.json jobs: # Check if the code changes and we need to run ci build # Cannot use paths filter in the on-event since we want this workflow to run even when there are no code changes, to register the commit chain check-paths: runs-on: ubuntu-latest permissions: contents: read pull-requests: read outputs: code_changed: ${{ steps.filter.outputs.code }} steps: - uses: actions/checkout@v6 with: fetch-depth: 2 # Needed for push commit comparison - uses: dorny/paths-filter@v4 id: filter with: filters: | code: - 'src/**' - 'examples/**' - 'lib/**' - 'hw/**' - 'test/hil/**' - 'tools/build.py' - 'tools/get_deps.py' - '.github/actions/**' - '.github/workflows/build.yml' - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' set-matrix: runs-on: ubuntu-latest outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} hil_json: ${{ steps.set-matrix-json.outputs.hil_matrix }} steps: - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Generate matrix json id: set-matrix-json run: | # build matrix MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)/ echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT # hil matrix HIL_MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py ${{ env.HIL_JSON }}) echo "hil_matrix=$HIL_MATRIX_JSON" echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT # ------------------------------------------------------------------------------ # CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR # Note: # For Make and IAR build: will be done on CircleCI only (one random per family as well) # ------------------------------------------------------------------------------ cmake: needs: [ check-paths, set-matrix ] uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: toolchain: - 'aarch64-gcc' #- 'arm-clang' - 'arm-gcc' #- 'esp-idf' - 'ft9xx-gcc' - 'msp430-gcc' - 'riscv-gcc' with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} build-options: '--one-first' upload-metrics: true upload-artifacts: false upload-membrowse: true code-changed: ${{ needs.check-paths.outputs.code_changed == 'true' }} secrets: inherit code-metrics: needs: [ check-paths, cmake ] if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest permissions: pull-requests: write contents: write steps: - name: Checkout TinyUSB uses: actions/checkout@v6 with: fetch-tags: ${{ github.event_name == 'release' }} - name: Download Artifacts uses: actions/download-artifact@v5 with: pattern: metrics-* path: cmake-build merge-multiple: true - name: Aggregate Code Metrics run: | python tools/get_deps.py python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json - name: Upload Metrics Artifact if: github.event_name == 'push' || github.event_name == 'release' uses: actions/upload-artifact@v7 with: name: metrics-tinyusb path: metrics.json - name: Download Base Branch Metrics if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' uses: dawidd6/action-download-artifact@v11 with: workflow: build.yml workflow_conclusion: '' branch: ${{ github.base_ref }} name: metrics-tinyusb path: base-metrics continue-on-error: true - name: Download Previous Release Asset if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | PREV_TAG=$(git tag --sort=-creatordate | head -n 2 | tail -n 1) echo "Previous Release: $PREV_TAG" echo "PREV_TAG=$PREV_TAG" >> $GITHUB_ENV mkdir -p base-metrics gh release download $PREV_TAG -p metrics.json -D base-metrics || echo "No metrics.json found in $PREV_TAG release" - name: Compare with Base Branch if: github.event_name != 'push' run: | if [ -f base-metrics/metrics.json ]; then python tools/metrics.py compare -m -f tinyusb/src base-metrics/metrics.json metrics.json cat metrics_compare.md else echo "No base metrics found, skipping comparison" cp metrics.md metrics_compare.md fi - name: Upload Release Assets if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | CURR_TAG=${{ github.event.release.tag_name }} COMPARE_FILE="metrics_compare_${CURR_TAG}-${PREV_TAG}.md" mv metrics_compare.md $COMPARE_FILE gh release upload $CURR_TAG metrics.json $COMPARE_FILE - name: Save PR number if: github.event_name == 'pull_request' run: echo ${{ github.event.number }} > pr_number.txt - name: Upload Metrics Comment Artifact if: github.event_name == 'pull_request' uses: actions/upload-artifact@v7 with: name: metrics-comment path: | metrics_compare.md metrics.json pr_number.txt - name: Post Code Metrics as PR Comment if: (github.event_name == 'workflow_dispatch') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) uses: marocchino/sticky-pull-request-comment@v2 with: header: code-metrics path: metrics_compare.md # --------------------------------------- # Build Make/CMake on Windows/MacOS # --------------------------------------- build-os: needs: [ check-paths ] if: needs.check-paths.outputs.code_changed == 'true' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: os: [ windows-latest, macos-latest ] build-system: [ 'make', 'cmake' ] with: os: ${{ matrix.os }} build-system: ${{ matrix.build-system }} toolchain: 'arm-gcc-${{ matrix.os }}' build-args: '["stm32h7rs"]' build-options: '--one-random' # --------------------------------------- # Zephyr # --------------------------------------- zephyr: needs: [ check-paths ] # skip zephyr build due to failed build, fix later if: false #if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest steps: - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Setup Zephyr project uses: zephyrproject-rtos/action-zephyr-setup@v1 with: app-path: examples toolchains: arm-zephyr-eabi - name: Build run: | west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr # --------------------------------------- # Hardware in the loop (HIL) # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR # --------------------------------------- hil-build: needs: [ check-paths, set-matrix ] if: needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: toolchain: - 'arm-gcc' - 'esp-idf' with: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} upload-artifacts: true # --------------------------------------- # Hardware in the loop (HIL) # self-hosted on local VM, for attached hardware checkout HIL_JSON # --------------------------------------- hil-tinyusb: needs: hil-build runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] steps: - name: Get Skip Boards from previous run if: github.run_attempt != '1' run: | if [ -f "${{ env.HIL_JSON }}.skip" ]; then SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") else SKIP_BOARDS="" fi echo "SKIP_BOARDS=$SKIP_BOARDS" echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV - name: Clean workspace run: | echo "Cleaning up for the first run" rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Download Artifacts uses: actions/download-artifact@v5 with: pattern: binaries-* path: cmake-build merge-multiple: true - name: Test on actual hardware run: | python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS || \ (if [ -f "${{ env.HIL_JSON }}.skip" ]; then SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") echo "Re-running with SKIP_BOARDS=$SKIP_BOARDS" python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS else exit 1 fi) # --------------------------------------- # Hardware in the loop (HIL) # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json # Since IAR Token secret is not passed to forked PR, only build non-forked PR # --------------------------------------- hil-hfp: needs: [ check-paths ] if: | needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) runs-on: [ self-hosted, Linux, X64, hifiphile ] env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} steps: - name: Clean workspace run: | echo "Cleaning up previous run" rm -rf "${{ github.workspace }}"3 mkdir -p "${{ github.workspace }}" - name: Toolchain version run: | iccarm --version - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Get build boards run: | MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json) BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")') echo "BUILD_ARGS=$BUILD_ARGS" echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV - name: Get Dependencies run: python3 tools/get_deps.py $BUILD_ARGS - name: Build run: python3 tools/build.py --toolchain iar $BUILD_ARGS - name: Test on actual hardware (hardware in the loop) run: python3 test/hil/hil_test.py hfp.json ================================================ FILE: .github/workflows/build_util.yml ================================================ name: Reusable build util on: workflow_call: inputs: os: required: false type: string default: 'ubuntu-latest' build-system: required: true type: string toolchain: required: true type: string build-args: required: true type: string build-options: required: false default: '' type: string upload-artifacts: required: false default: false type: boolean upload-metrics: required: false default: false type: boolean upload-membrowse: required: false default: false type: boolean code-changed: required: false default: true type: boolean jobs: family: runs-on: ${{ inputs.os }} strategy: fail-fast: false matrix: arg: ${{ fromJSON(inputs.build-args) }} steps: - name: Checkout TinyUSB uses: actions/checkout@v6 with: fetch-depth: ${{ !inputs.upload-membrowse && 1 || 0 }} - name: Setup Toolchain id: setup-toolchain uses: ./.github/actions/setup_toolchain with: toolchain: ${{ inputs.toolchain }} - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: ${{ matrix.arg }} - name: Build if: ${{ inputs.code-changed }} env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} else BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} --target all" if [ "${{ inputs.upload-metrics }}" = "true" ]; then BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics" fi python tools/build.py $BUILD_PY_ARGS ${{ matrix.arg }} fi shell: bash - name: Membrowse Upload if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true continue-on-error: true env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | # if code-changed is false --> there is no elf -> membrowse target upload with --identical flag BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }} shell: bash - name: Upload Artifacts for Metrics if: inputs.upload-metrics == true && inputs.code-changed == true uses: actions/upload-artifact@v7 with: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - name: Upload Artifacts for Hardware Testing if: inputs.upload-artifacts == true && inputs.code-changed == true uses: actions/upload-artifact@v7 with: name: binaries-${{ matrix.arg }} path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin cmake-build/cmake-build-*/*/*/*.bin cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin cmake-build/cmake-build-*/*/*/config.env cmake-build/cmake-build-*/*/*/flash_args cmake-build/hw/mcu/**/*.ld ================================================ FILE: .github/workflows/ci_set_matrix.py ================================================ #!/usr/bin/env python3 import json # toolchain, url toolchain_list = [ "aarch64-gcc", "arm-clang", "arm-iar", "arm-gcc", "esp-idf", "ft9xx-gcc", "msp430-gcc", "riscv-gcc", "rx-gcc" ] # family: [supported toolchain] family_list = { "at32f402_405": ["arm-gcc"], "at32f403a_407": ["arm-gcc"], "at32f413": ["arm-gcc"], "at32f415": ["arm-gcc"], "at32f423": ["arm-gcc"], "at32f425": ["arm-gcc"], "at32f435_437": ["arm-gcc"], "at32f45x": ["arm-gcc"], "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32f20x": ["arm-gcc"], "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], "da1469x": ["arm-gcc"], "fomu": ["riscv-gcc"], "ft9xx": ["ft9xx-gcc"], "gd32vf103": ["riscv-gcc"], "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k": ["arm-gcc"], "kinetis_k32l": ["arm-gcc"], "kinetis_kl": ["arm-gcc"], "lpc11": ["arm-gcc", "arm-clang"], "lpc13": ["arm-gcc", "arm-clang"], "lpc15": ["arm-gcc", "arm-clang"], "lpc17": ["arm-gcc", "arm-clang"], "lpc18": ["arm-gcc", "arm-clang"], "lpc40": ["arm-gcc", "arm-clang"], "lpc43": ["arm-gcc", "arm-clang"], "lpc51": ["arm-gcc", "arm-clang"], "lpc54": ["arm-gcc", "arm-clang"], "lpc55": ["arm-gcc", "arm-clang"], "maxim": ["arm-gcc"], "mcx": ["arm-gcc"], "mm32": ["arm-gcc"], "msp430": ["msp430-gcc"], "msp432e4": ["arm-gcc"], "nrf": ["arm-gcc", "arm-clang"], "nuc100_120": ["arm-gcc"], "nuc121_125": ["arm-gcc"], "nuc126": ["arm-gcc"], "nuc505": ["arm-gcc"], "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], "rw61x": ["arm-gcc"], "rx": ["rx-gcc"], "samd11": ["arm-gcc", "arm-clang"], "samd2x_l2x": ["arm-gcc", "arm-clang"], "samd5x_e5x": ["arm-gcc", "arm-clang"], "samg": ["arm-gcc", "arm-clang"], "stm32c0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f1": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f2": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], "stm32l0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], "stm32u0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], "stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], "tm4c": ["arm-gcc"], "xmc4000": ["arm-gcc"], # S3, P4 will be built by hil test # "-bespressif_s3_devkitm": ["esp-idf"], # "-bespressif_p4_function_ev": ["esp-idf"], } def set_matrix_json(): matrix = {} for toolchain in toolchain_list: filtered_families = [family for family, supported_toolchain in family_list.items() if toolchain in supported_toolchain] matrix[toolchain] = filtered_families print(json.dumps(matrix)) if __name__ == '__main__': set_matrix_json() ================================================ FILE: .github/workflows/cifuzz.yml ================================================ name: CIFuzz on: workflow_dispatch: pull_request: branches: - master paths: - '**.c' - '**.cc' - '**.cpp' - '**.cxx' - '**.h' jobs: Fuzzing: runs-on: ubuntu-latest steps: - name: Build Fuzzers id: build uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master with: oss-fuzz-project-name: 'tinyusb' language: c++ - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: oss-fuzz-project-name: 'tinyusb' language: c++ fuzz-seconds: 400 - name: Upload Crash uses: actions/upload-artifact@v7 if: failure() && steps.build.outcome == 'success' with: name: artifacts path: ./out/artifacts ================================================ FILE: .github/workflows/claude-code-review.yml ================================================ name: Claude Code Review on: pull_request_target: types: [opened, synchronize, ready_for_review, reopened] jobs: claude-review: if: false runs-on: ubuntu-latest permissions: contents: read pull-requests: write issues: read id-token: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 1 - name: Run Claude Code Review id: claude-review uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://code.claude.com/docs/en/cli-reference for available options ================================================ FILE: .github/workflows/claude.yml ================================================ name: Claude Code on: issue_comment: types: [created] pull_request_review_comment: types: [created] issues: types: [opened, assigned] pull_request_review: types: [submitted] jobs: claude: if: | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 1 - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. # prompt: 'Update the pull request description to include a summary of changes.' # Optional: Add claude_args to customize behavior and configuration # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://code.claude.com/docs/en/cli-reference for available options # claude_args: '--allowed-tools Bash(gh pr:*)' ================================================ FILE: .github/workflows/labeler.yml ================================================ name: Labeler on: issues: types: [opened] pull_request_target: types: [opened] jobs: label-priority: runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: - name: Label New Issue or PR uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | let label = ''; let username = ''; let issueOrPrNumber = 0; if (context.eventName === 'issues') { username = context.payload.issue.user.login; issueOrPrNumber = context.payload.issue.number; } else if (context.eventName === 'pull_request_target') { username = context.payload.pull_request.user.login; issueOrPrNumber = context.payload.pull_request.number; } // Check if an Adafruit member try { const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ org: 'adafruit', username: username }); if (adafruitResponse.status === 204) { console.log('Adafruit Member'); label = 'Prio Urgent'; } } catch (error) { console.log('Not an Adafruit member'); } // Check if a contributor if (label == '') { try { const collaboratorResponse = await github.rest.repos.checkCollaborator({ owner: context.repo.owner, repo: context.repo.repo, username: username }); if (collaboratorResponse.status === 204) { console.log('Contributor'); label = 'Prio Higher'; } } catch (error) { console.log('Not a contributor'); } } if (label !== '') { await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueOrPrNumber, labels: [label] }); } ================================================ FILE: .github/workflows/membrowse-comment.yml ================================================ name: Membrowse Comment on: workflow_run: workflows: ["Build"] types: - completed jobs: post-comment: runs-on: ubuntu-latest # Run the comment job even if some of the builds fail if: > github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion != 'cancelled' permissions: contents: read actions: read pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v6 - name: Post Membrowse PR comment if: ${{ env.MEMBROWSE_API_KEY != '' }} uses: membrowse/membrowse-action/comment-action@v1 with: api_key: ${{ secrets.MEMBROWSE_API_KEY }} commit: ${{ github.event.workflow_run.head_sha }} comment_template: .github/membrowse_pr_message.j2 env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/membrowse-onboard.yml ================================================ name: Onboard to Membrowse on: workflow_dispatch: inputs: num_commits: description: 'Number of commits to process' required: true default: '10' type: string jobs: load-targets: runs-on: ubuntu-22.04 outputs: targets: ${{ steps.load.outputs.targets }} toolchains: ${{ steps.load.outputs.toolchains }} steps: - name: Checkout repository uses: actions/checkout@v6 - name: Load target matrix id: load run: | echo "targets=$(jq -c '.targets' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT echo "toolchains=$(jq -c '.toolchains' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT onboard: needs: load-targets runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: include: ${{ fromJson(needs.load-targets.outputs.targets) }} steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install packages run: | ${{ fromJson(needs.load-targets.outputs.toolchains)[matrix.toolchain].setup_cmd }} && python3 tools/get_deps.py ${{ matrix.get_deps || matrix.port }} - name: Setup ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ matrix.port }}-${{ matrix.board }} - name: Run Membrowse Onboard Action uses: membrowse/membrowse-action/onboard-action@v1 with: target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} num_commits: ${{ github.event.inputs.num_commits }} build_script: python3 tools/build.py -s cmake -b ${{ matrix.board }} elf: cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf ld: ${{ matrix.ld }} linker_vars: ${{ matrix.linker_vars || '' }} api_key: ${{ secrets.MEMBROWSE_API_KEY }} api_url: ${{ vars.MEMBROWSE_API_URL }} ================================================ FILE: .github/workflows/metrics_comment.yml ================================================ name: Metrics Comment on: workflow_run: workflows: ["Build"] types: - completed jobs: post-comment: runs-on: ubuntu-latest if: > github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' permissions: actions: read pull-requests: write steps: - name: Download Artifacts uses: actions/download-artifact@v5 with: run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} name: metrics-comment - name: Read PR Number id: pr_number run: | if [ -f pr_number.txt ]; then echo "number=$(cat pr_number.txt)" >> $GITHUB_OUTPUT fi - name: Post Code Metrics as PR Comment if: steps.pr_number.outputs.number != '' uses: marocchino/sticky-pull-request-comment@v2 with: header: code-metrics path: metrics_compare.md number: ${{ steps.pr_number.outputs.number }} ================================================ FILE: .github/workflows/pre-commit.yml ================================================ name: pre-commit on: workflow_dispatch: push: pull_request: branches: [ master ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: pre-commit: runs-on: ubuntu-latest steps: - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.0' - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Get Dependencies run: | gem install ceedling #cd test/unit-test #ceedling test:all - name: Run pre-commit uses: pre-commit/action@v3.0.1 - name: Build Fuzzer run: | sudo apt install libc++-dev libc++abi-dev clang --version export CC=clang export CXX=clang++ fuzz_harness=$(ls -d test/fuzz/device/*/) for h in $fuzz_harness do make -C $h get-deps make -C $h all done ================================================ FILE: .github/workflows/static_analysis.yml ================================================ name: Static Analysis on: workflow_dispatch: push: branches: [ master ] paths: - 'src/**' - 'examples/**' - 'hw/bsp/**' - '.github/workflows/static_analysis.yml' pull_request: branches: [ master ] paths: - 'src/**' - 'examples/**' - 'hw/bsp/**' - '.github/workflows/static_analysis.yml' permissions: actions: read contents: read security-events: write # pull-requests: write # checks: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: CodeQL: runs-on: ubuntu-latest strategy: fail-fast: false matrix: board: - 'metro_m4_express' steps: - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: -b${{ matrix.board }} - name: Setup Toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' - name: Initialize CodeQL uses: github/codeql-action/init@v4 with: languages: 'c-cpp' queries: security-and-quality - name: Build run: | mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 with: category: CodeQL upload: false id: analyze - name: Filter SARIF report uses: advanced-security/filter-sarif@v1 with: patterns: | -hw/mcu/** -lib/** input: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif output: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: sarif_file: ${{ steps.analyze.outputs.sarif-output }} category: CodeQL - name: Upload artifact uses: actions/upload-artifact@v7 with: name: codeql-${{ matrix.board }} path: ${{ steps.analyze.outputs.sarif-output }} PVS-Studio: # Only run on non-forked PR since secrets token is required if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest strategy: fail-fast: false matrix: board: - 'raspberry_pi_pico' steps: - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: -b${{ matrix.board }} - name: Setup Toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' - name: Install Tools run: | wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add - sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list sudo apt update sudo apt install pvs-studio pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} pvs-studio-analyzer --version - name: Analyze run: | mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build pvs-studio-analyzer analyze -f build/compile_commands.json -R .PVS-Studio/.pvsconfig -j4 --security-related-issues --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser -e lib/ -e hw/mcu/ -e */iar/cxarm/ -e pico-sdk/ plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: sarif_file: pvs-studio-${{ matrix.board }}.sarif category: PVS-Studio - name: Upload artifact uses: actions/upload-artifact@v7 with: name: pvs-studio-${{ matrix.board }} path: pvs-studio-${{ matrix.board }}.sarif SonarQube: # Only run on non-forked PR since secrets token is required if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory strategy: fail-fast: false matrix: board: - 'stm32h743eval' steps: - name: Checkout TinyUSB uses: actions/checkout@v6 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: -b${{ matrix.board }} - name: Setup Toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-gcc' - name: Install Build Wrapper uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 - name: Run Build Wrapper run: | cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@v6 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options args: > --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json IAR-CStat: # Only run on non-forked PR since secrets token is required #if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false if: false runs-on: ubuntu-latest strategy: fail-fast: false matrix: board: - 'b_g474e_dpow1' steps: - name: Checkout TinyUSB uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: -b${{ matrix.board }} - name: Setup Toolchain uses: ./.github/actions/setup_toolchain with: toolchain: 'arm-iar' - name: Install CMake 4.2 run: | # IAR CSTAT requires CMake >= 4.1 wget -q https://github.com/Kitware/CMake/releases/download/v4.2.0-rc1/cmake-4.2.0-rc1-linux-x86_64.tar.gz tar -xzf cmake-4.2.0-rc1-linux-x86_64.tar.gz echo "${{ github.workspace }}/cmake-4.2.0-rc1-linux-x86_64/bin" >> $GITHUB_PATH - name: Build and run IAR C-STAT Analysis env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | # CMake run post build to generate C-STAT SARIF report cmake --version mkdir -p build cmake examples/device/cdc_msc -B build -G Ninja -DBOARD=${{ matrix.board }} -DTOOLCHAIN=iar -DIAR_CSTAT=1 -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build # Merge sarif files for codeql upload npm i -g @microsoft/sarif-multitool npx @microsoft/sarif-multitool merge --merge-runs --output-file iar-cstat-${{ matrix.board }}.sarif build/cstat_sarif/*.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: sarif_file: iar-cstat-${{ matrix.board }}.sarif category: IAR-CStat - name: Upload artifact uses: actions/upload-artifact@v7 with: name: iar-cstat-${{ matrix.board }} path: iar-cstat-${{ matrix.board }}.sarif ================================================ FILE: .github/workflows/trigger.yml ================================================ name: Trigger Repos on: workflow_dispatch: push: branches: master release: types: - created jobs: trigger-mynewt: if: github.repository == 'hathach/tinyusb' runs-on: ubuntu-latest steps: - name: Trigger mynewt-tinyusb-example shell: bash run: | curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" --data '{"event_type": "rebuild"}' https://api.github.com/repos/hathach/mynewt-tinyusb-example/dispatches mirror-tinyusb-src: if: github.repository == 'hathach/tinyusb' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v6 - name: Push to tinyusb_src run: | # clone tinyusb_src with PAT git config --global user.email "thach@tinyusb.org" git config --global user.name "hathach" git clone --depth 1 --single-branch --branch main "https://${{ secrets.API_TOKEN_GITHUB }}@github.com/hathach/tinyusb_src.git" tinyusb_src # Remove all files rm -rf tinyusb_src/* # Copy src and other files cp -r src tinyusb_src/ cp LICENSE tinyusb_src/ cd tinyusb_src # Commit if there is changes if [ -n "$(git status --porcelain)" ]; then git add . git commit --message "Update from https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" git push fi - name: Create tinyusb_src Release if: ${{ github.event_name == 'release' }} run: | # Push tag cd tinyusb_src git tag ${{ github.event.release.tag_name }} git push origin ${{ github.event.release.tag_name }} # Send POST reqwuest to release https://docs.github.com/en/rest/reference/repos#create-a-release bb="For release note, please checkout https://github.com/hathach/tinyusb/releases/tag/${{ github.event.release.tag_name }}" curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "$bb", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases ================================================ FILE: .gitignore ================================================ html latex *.a *.d *.o *.P *.axf *.bin *.elf *.env *.ind *.log *.map *.obj *.jlink *.emSession *.ninja* *.eww *.ewp *.ewt *.ewd *.hex .venv/ cmake_install.cmake CMakeCache.txt settings/ .settings/ .vscode/ .gdb_history /examples/*/*/build* test_old/ tests_obsolete/ _build/ build/ /examples/*/*/ses /examples/*/*/ozone /examples/obsolete hw/bsp/**/cubemx/*/ .mxproject # coverity intermediate files cov-int # cppcheck build directories *-build-dir /_bin/ __pycache__ cmake-build/ cmake-build-* sdkconfig .PVS-Studio .vscode/ CMakeFiles Debug RelWithDebInfo Release BrowseInfo .cmake_build README_processed.rst ================================================ FILE: .idea/.gitignore ================================================ # Default ignored files /shelf/ /workspace.xml # Datasource local storage ignored files /dataSources/ /dataSources.local.xml # Editor-based HTTP Client requests /httpRequests/ # GitHub Copilot persisted chat sessions /copilot/chatSessions ================================================ FILE: .idea/cmake.xml ================================================ ================================================ FILE: .idea/debugServers/AT32F423VCT7.xml ================================================ ================================================ FILE: .idea/debugServers/ST_LINK.xml ================================================ ================================================ FILE: .idea/debugServers/at32f403acgu7.xml ================================================ ================================================ FILE: .idea/debugServers/esp32s2.xml ================================================ $USER_HOME$/.espressif/tools/xtensa-esp-elf-gdb/14.2_20240403/xtensa-esp-elf-gdb/bin/xtensa-esp32s2-elf-gdb ================================================ FILE: .idea/debugServers/lpc1769.xml ================================================ ================================================ FILE: .idea/debugServers/lpc55s69.xml ================================================ ================================================ FILE: .idea/debugServers/max32690.xml ================================================ ================================================ FILE: .idea/debugServers/mcxa153.xml ================================================ ================================================ FILE: .idea/debugServers/nrf52833.xml ================================================ ================================================ FILE: .idea/debugServers/nrf5340.xml ================================================ ================================================ FILE: .idea/debugServers/ra6m1.xml ================================================ ================================================ FILE: .idea/debugServers/ra6m5.xml ================================================ ================================================ FILE: .idea/debugServers/rp2040.xml ================================================ ================================================ FILE: .idea/debugServers/rp2350.xml ================================================ ================================================ FILE: .idea/debugServers/rt1011.xml ================================================ ================================================ FILE: .idea/debugServers/rt1060.xml ================================================ ================================================ FILE: .idea/debugServers/rt1064.xml ================================================ ================================================ FILE: .idea/debugServers/rt1170.xml ================================================ ================================================ FILE: .idea/debugServers/s3.xml ================================================ ================================================ FILE: .idea/debugServers/sam21.xml ================================================ ================================================ FILE: .idea/debugServers/sam51.xml ================================================ ================================================ FILE: .idea/debugServers/stm32f072.xml ================================================ ================================================ FILE: .idea/debugServers/stm32f303.xml ================================================ ================================================ FILE: .idea/debugServers/stm32f411.xml ================================================ ================================================ FILE: .idea/debugServers/stm32f769.xml ================================================ ================================================ FILE: .idea/debugServers/stm32h563.xml ================================================ ================================================ FILE: .idea/debugServers/stm32h743.xml ================================================ ================================================ FILE: .idea/debugServers/stm32l053.xml ================================================ ================================================ FILE: .idea/debugServers/wch_riscv.xml ================================================ ================================================ FILE: .idea/runConfigurations/k64f.xml ================================================ ================================================ FILE: .idea/runConfigurations/kl25.xml ================================================ ================================================ FILE: .idea/runConfigurations/lpc1857.xml ================================================ ================================================ FILE: .idea/runConfigurations/lpc4088.xml ================================================ ================================================ FILE: .idea/runConfigurations/lpc54628.xml ================================================ ================================================ FILE: .idea/runConfigurations/lpc55s69.xml ================================================ ================================================ FILE: .idea/runConfigurations/mcx947.xml ================================================ ================================================ FILE: .idea/runConfigurations/nrf52840.xml ================================================ ================================================ FILE: .idea/runConfigurations/nrf5340.xml ================================================ ================================================ FILE: .idea/runConfigurations/ra2a1.xml ================================================ ================================================ FILE: .idea/runConfigurations/ra4m1.xml ================================================ ================================================ FILE: .idea/runConfigurations/ra6m1.xml ================================================ ================================================ FILE: .idea/runConfigurations/ra6m5.xml ================================================ ================================================ FILE: .idea/runConfigurations/rp2040.xml ================================================ ================================================ FILE: .idea/runConfigurations/rt1010.xml ================================================ ================================================ FILE: .idea/runConfigurations/rt1060.xml ================================================ ================================================ FILE: .idea/runConfigurations/samd21g18.xml ================================================ ================================================ FILE: .idea/runConfigurations/samd51j19.xml ================================================ ================================================ FILE: .idea/runConfigurations/stlink.xml ================================================ ================================================ FILE: .idea/runConfigurations/stm32g474.xml ================================================ ================================================ FILE: .idea/runConfigurations/stm32h563.xml ================================================ ================================================ FILE: .idea/runConfigurations/stm32h743.xml ================================================ ================================================ FILE: .idea/runConfigurations/stm32u5a5.xml ================================================ ================================================ FILE: .idea/runConfigurations/uno_r4.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: .pre-commit-config.yaml ================================================ # SPDX-FileCopyrightText: 2020 Diego Elio Pettenò # # SPDX-License-Identifier: Unlicense repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-yaml - id: trailing-whitespace exclude: | (?x)^( hw/bsp/mcx/sdk/ ) - id: end-of-file-fixer exclude: | (?x)^( .idea/| hw/bsp/mcx/sdk/| docs/contributing/code_of_conduct.rst| docs/info/contributors.rst ) - id: forbid-submodules - repo: https://github.com/codespell-project/codespell rev: v2.2.4 hooks: - id: codespell args: [-w] exclude: | (?x)^( lib/| hw/bsp/mcx/sdk/ ) - repo: local hooks: - id: unit-test name: unit-test files: ^(src/|test/unit-test/) entry: sh -c "cd test/unit-test && ceedling test:all" pass_filenames: false types_or: [c, header] language: system # - id: build-fuzzer # name: build-fuzzer # files: ^(src/|test/fuzz/) # language: system # types_or: [c, header] # entry: | # bash -c 'export CC=clang # export CXX=clang++ # fuzz_harness=$(ls -d test/fuzz/device/*/) # for h in $fuzz_harness # do # make -C $h get-deps # make -C $h all # done' ================================================ FILE: .readthedocs.yaml ================================================ # .readthedocs.yaml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details version: 2 # Set the version of Python and other tools you might need build: os: ubuntu-22.04 tools: python: "3.11" # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py # Optionally declare the Python requirements required to build your docs python: install: - requirements: docs/requirements.txt submodules: include: [] recursive: false ================================================ FILE: AGENTS.md ================================================ # TinyUSB Agent Instructions TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. ## Shared Ground Rules - Keep TinyUSB memory-safe: avoid dynamic allocation, defer ISR work to task context, and follow C99 with two-space indentation/no tabs. - Match file organization: core stack under `src`, MCU/BSP support in `hw/{mcu,bsp}`, examples under `examples/{device,host,dual}`, docs in `docs`, tests under `test/{unit-test,fuzz,hil}`. - Use descriptive snake_case for helpers, reserve `tud_`/`tuh_` for public APIs, `TU_` for macros, and keep headers self-contained with `#if CFG_TUSB_MCU` guards where needed. - Prefer `.clang-format` for C/C++ formatting, run `pre-commit run --all-files` before submitting, and document board/HIL coverage when applicable. - Commit in imperative mood, keep changes scoped, and supply PRs with linked issues plus test/build evidence. ## Bootstrap and Build Setup - Install ARM GCC toolchain: `sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi` - Fetch core dependencies: `python3 tools/get_deps.py` -- takes <1 second. NEVER CANCEL. - For specific board families: `python3 tools/get_deps.py FAMILY_NAME` (e.g., rp2040, stm32f4), or `python3 tools/get_deps.py -b BOARD_NAME` - Dependencies are cached in `lib/` and `hw/mcu/` directories - For **Espressif** boards, initialize the ESP-IDF environment before any build/flash/monitor command: `. $HOME/code/esp-idf/export.sh` ## Build Examples Choose ONE of these approaches: **Option 1: Individual Example with CMake and Ninja (RECOMMENDED)** ```bash cd examples/device/cdc_msc mkdir -p build && cd build cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. cmake --build . ``` -- takes 1-2 seconds. NEVER CANCEL. Set timeout to 5+ minutes. **Option 2: All Examples for a Board** different folder than Option 1 ```bash cd examples/ mkdir -p build && cd build cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. cmake --build . ``` -- takes 15-20 seconds, may have some objcopy failures that are non-critical. NEVER CANCEL. Set timeout to 30+ minutes. **Option 3: Individual Example with Make** ```bash cd examples/device/cdc_msc make BOARD=raspberry_pi_pico all ``` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 5+ minutes. **Option 4: Espressif Example with ESP-IDF** Only ESP-IDF-enabled examples are supported for Espressif boards. Use FreeRTOS examples such as `examples/device/cdc_msc_freertos` that contain `idf_component_register()` support. ```bash . $HOME/code/esp-idf/export.sh cd examples/device/cdc_msc_freertos idf.py -DBOARD=espressif_s3_devkitc build ``` Use `-DBOARD=...` with any supported board under `hw/bsp/espressif/boards/`. NEVER CANCEL. Set timeout to 10+ minutes. ## Build Options - **Debug build**: - CMake: `-DCMAKE_BUILD_TYPE=Debug` - Make: `DEBUG=1` - **With logging**: - CMake: `-DLOG=2` - Make: `LOG=2` - **With RTT logger**: - CMake: `-DLOG=2 -DLOGGER=rtt` - Make: `LOG=2 LOGGER=rtt` - **RootHub port selection**: - CMake: `-DRHPORT_DEVICE=1` - Make: `RHPORT_DEVICE=1` - **Port speed**: - CMake: `-DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` - Make: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` ## Flashing and Deployment - **Flash with JLink**: - CMake: `ninja cdc_msc-jlink` - Make: `make BOARD=raspberry_pi_pico flash-jlink` - **Flash with OpenOCD**: - CMake: `ninja cdc_msc-openocd` - Make: `make BOARD=raspberry_pi_pico flash-openocd` - **Generate UF2**: - CMake: `ninja cdc_msc-uf2` - Make: `make BOARD=raspberry_pi_pico all uf2` - **List all targets** (CMake/Ninja): `ninja -t targets` - **Espressif flash**: - Run `. $HOME/code/esp-idf/export.sh` - `cd examples/device/cdc_msc_freertos` - `idf.py -DBOARD=espressif_s3_devkitc flash` - **Espressif serial monitor / chip log output**: - Run `. $HOME/code/esp-idf/export.sh` - `cd examples/device/cdc_msc_freertos` - `idf.py -DBOARD=espressif_s3_devkitc monitor` ## GDB Debugging Look up the board's `JLINK_DEVICE` and `OPENOCD_OPTION` from `hw/bsp/*/boards/*/board.cmake` (or `board.mk`). ### JLinkGDBServer **Terminal 1 – start the GDB server:** ```bash JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 \ -port 2331 -swoport 2332 -telnetport 2333 -nogui ``` **Terminal 2 – connect GDB:** ```bash arm-none-eabi-gdb /tmp/build/firmware.elf (gdb) target remote :2331 (gdb) monitor reset halt (gdb) load (gdb) continue ``` To break on entry instead of running immediately: ```bash (gdb) monitor reset halt (gdb) load (gdb) break main (gdb) continue ``` ### OpenOCD **Terminal 1 – start the GDB server:** ```bash openocd -f interface/stlink.cfg -f target/stm32h7x.cfg # or with J-Link probe: openocd -f interface/jlink.cfg -f target/stm32h7x.cfg ``` For **rp2040/rp2350** with a CMSIS-DAP probe (e.g. Picoprobe, debugprobe): ```bash openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" # or for rp2350: openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" ``` For boards that define `OPENOCD_OPTION` in `board.cmake`, use those options directly: ```bash openocd $(cat hw/bsp/FAMILY/boards/BOARD/board.cmake | grep OPENOCD_OPTION | ...) ``` **Terminal 2 – connect GDB (OpenOCD default port is 3333):** ```bash arm-none-eabi-gdb /tmp/build/firmware.elf (gdb) target remote :3333 (gdb) monitor reset halt (gdb) load (gdb) continue ``` ### RTT Logging with JLinkGDBServer - Build with RTT logging enabled (example): `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt all` - Flash with J-Link: `cd examples/device/cdc_msc && make BOARD=stm32h743eval LOG=2 LOGGER=rtt flash-jlink` - Launch GDB server with RTT port (keep this running in terminal 1): `JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -RTTTelnetPort 19021 -nogui` - Read RTT output (terminal 2): `JLinkRTTClient` - Capture RTT to file (optional): `JLinkRTTClient | tee rtt.log` - For non-interactive capture: `timeout 20s JLinkRTTClient > rtt.log` ## Unit Testing - Install Ceedling: `sudo gem install ceedling` - Run all unit tests: `cd test/unit-test && ceedling` or `cd test/unit-test && ceedling test:all` -- takes 4 seconds. NEVER CANCEL. Set timeout to 10+ minutes. - Run specific test: `cd test/unit-test && ceedling test:test_fifo` - Tests use Unity framework with CMock for mocking ## Hardware-in-the-Loop (HIL) Testing - `-B examples` means `examples` is the parent folder that contains multi-board build outputs such as `examples/cmake-build-BOARD_NAME/...` - Select config file before running HIL tests: - if GitHub Actions self-hosted runner service is running, use `tinyusb.json` - otherwise use `local.json` - example: `HIL_CONFIG=$( (systemctl list-units --type=service --state=running 2>/dev/null; systemctl --user list-units --type=service --state=running 2>/dev/null) | grep -q 'actions\.runner' && echo tinyusb.json || echo local.json )` - Run tests on actual hardware, one of following ways: - test a specific board `python test/hil/hil_test.py -b BOARD_NAME -B examples $HIL_CONFIG` - test all boards in config `python test/hil/hil_test.py -B examples $HIL_CONFIG` - In case of error, enabled verbose mode with `-v` flag for detailed logs. Also try to observe script output, and try to modify hil_test.py (temporarily) to add more debug prints to pinpoint the issue. - Requires pre-built (all) examples for target boards (see Build Examples section 2) take 2-5 minutes. NEVER CANCEL. Set timeout to 20+ minutes. ## Documentation - Install requirements: `pip install -r docs/requirements.txt` - Build docs: `cd docs && sphinx-build -b html . _build` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 10+ minutes. ## Code Size Metrics Generate and compare code size metrics to evaluate the impact of changes. This is the most common workflow when making code changes — use it to verify size impact before committing. **Quick single-board metrics (preferred for iterative development):** ```bash rm -rf cmake-build python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json ``` This builds all examples for one board and produces `metrics.json` + `metrics.md`. Takes ~30 seconds. NEVER CANCEL. Set timeout to 10+ minutes. **Comparing with master (before/after workflow):** 1. On master: build and save baseline ```bash rm -rf cmake-build python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json mv metrics.json metrics_master.json ``` 2. Switch to your branch: rebuild ```bash rm -rf cmake-build python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json ``` 3. Compare: `python3 tools/metrics.py compare -m -f tinyusb/src metrics_master.json metrics.json` Produces `metrics_compare.md` showing size differences. **Full CI metrics (all arm-gcc families, for thorough validation):** ```bash rm -rf cmake-build FAMILIES=$(python3 .github/workflows/ci_set_matrix.py | python3 -c "import sys,json; d=json.load(sys.stdin); print(' '.join(d.get('arm-gcc',[])))") python3 tools/build.py --one-first --target all --target tinyusb_metrics $FAMILIES python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json ``` Builds the first board of each family. Takes 2-4 minutes. NEVER CANCEL. Set timeout to 10+ minutes. ## Code Quality and Validation - Format code: `clang-format -i path/to/file.c` (uses `.clang-format` config) - Check spelling: `pip install codespell && codespell` (uses `.codespellrc` config) - Pre-commit hooks validate unit tests and code quality automatically ## Static Analysis with PVS-Studio - **Analyze whole project**: ```bash pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser ``` - **Analyze specific source files**: ```bash pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S path/to/file.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser ``` - **Multiple specific files**: ```bash pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S src/file1.c -S src/file2.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser ``` - Requires `compile_commands.json` in the build directory (generated by CMake with `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`) - Use `-f` option to specify path to `compile_commands.json` - Use `-R .PVS-Studio/.pvsconfig` to specify rule configuration file - Use `-j12` for parallel analysis with 12 threads - `--dump-files` saves preprocessed files for debugging - `--misra-c-version 2023` enables MISRA C:2023 checks - `--misra-cpp-version 2008` enables MISRA C++:2008 checks - `--use-old-parser` uses legacy parser for compatibility - Analysis takes ~10-30 seconds depending on project size. Set timeout to 5+ minutes. - View results: `plog-converter -a GA:1,2 -t errorfile pvs-report.log` or open in PVS-Studio GUI ## Validation Checklist ### ALWAYS Run These After Making Changes 1. **Pre-commit validation** (RECOMMENDED): `pre-commit run --all-files` - Install pre-commit: `pip install pre-commit && pre-commit install` - Runs all quality checks, unit tests, spell checking, and formatting - Takes 10-15 seconds. NEVER CANCEL. Set timeout to 15+ minutes. 2. **Build validation**: Build at least one board with all example that exercises your changes, see Build Examples section (option 2) 3. Run unit tests relevant to touched modules; add fuzz/HIL coverage when modifying parsers or protocol state machines. ### Manual Testing Scenarios - **Device examples**: Cannot be fully tested without real hardware, but must build successfully - **Unit tests**: Exercise core stack functionality - ALL tests must pass - **Build system**: Must be able to build examples for multiple board families ### Board Selection for Testing - **STM32F4**: `stm32f407disco` - no external SDK required, good for testing - **RP2040**: `raspberry_pi_pico` - requires Pico SDK, commonly used - **Other families**: Check `hw/bsp/FAMILY/boards/` for available boards ## Release Instructions **DO NOT commit files automatically - only modify files and let the maintainer review before committing.** 1. Bump the release version variable at the top of `tools/make_release.py`. 2. Execute `python3 tools/make_release.py` to refresh: - `src/tusb_option.h` (version defines) - `repository.yml` (version mapping) - `library.json` (PlatformIO version) - `sonar-project.properties` (SonarQube version) - `docs/reference/boards.rst` (generated board documentation) - `hw/bsp/BoardPresets.json` (CMake presets) 3. Generate release notes for `docs/info/changelog.rst`: - Get commit list: `git log ..HEAD --oneline` - **Visit GitHub PRs** for merged pull requests to understand context and gather details - Use GitHub tools to search/read PRs: `github-mcp-server-list_pull_requests`, `github-mcp-server-pull_request_read` - Extract key changes, API modifications, bug fixes, and new features from PR descriptions - Add new changelog entry following the existing format: - Version heading with equals underline (e.g., `0.20.0` followed by `======`) - Release date in italics (e.g., `*November 19, 2024*`) - Major sections: General, API Changes, Controller Driver (DCD & HCD), Device Stack, Host Stack, Testing - Use bullet lists with descriptive categorization - Reference function names, config macros, and file paths using RST inline code (double backticks) - Include meaningful descriptions, not just commit messages 4. **Validation before commit**: - Run unit tests: `cd test/unit-test && ceedling test:all` - Build at least one example: `cd examples/device/cdc_msc && make BOARD=stm32f407disco all` - Verify changed files look correct: `git diff --stat` 5. **Leave files unstaged** for maintainer to review, modify if needed, and commit with message: `Bump version to X.Y.Z` 6. **After maintainer commits**: Create annotated tag with `git tag -a vX.Y.Z -m "Release X.Y.Z"` 7. Push commit and tag: `git push origin && git push origin vX.Y.Z` 8. Create GitHub release from the tag with changelog content ## Repository Structure Quick Reference ``` ├── src/ # Core TinyUSB stack │ ├── class/ # USB device classes (CDC, HID, MSC, Audio, etc.) │ ├── portable/ # MCU-specific drivers (organized by vendor) │ ├── device/ # USB device stack core │ ├── host/ # USB host stack core │ └── common/ # Shared utilities (FIFO, etc.) ├── examples/ # Example applications │ ├── device/ # Device examples (cdc_msc, hid_generic, etc.) │ ├── host/ # Host examples │ └── dual/ # Dual-role examples ├── hw/bsp/ # Board Support Packages │ └── FAMILY/boards/ # Board-specific configurations ├── test/unit-test/ # Unit tests using Ceedling ├── tools/ # Build and utility scripts └── docs/ # Sphinx documentation ``` #### Build Time Reference - **Dependency fetch**: <1 second - **Single example build**: 1-3 seconds - **Unit tests**: ~4 seconds - **Documentation build**: ~2.5 seconds - **Full board examples**: 15-20 seconds - **Toolchain installation**: 2-5 minutes (one-time) #### Key Files to Know - `tools/get_deps.py`: Manages dependencies for MCU families - `tools/build.py`: Builds multiple examples, supports make/cmake - `src/tusb.h`: Main TinyUSB header file - `src/tusb_config.h`: Configuration template - `examples/device/cdc_msc/`: Most commonly used example for testing - `test/unit-test/project.yml`: Ceedling test configuration #### MCU Reference Manuals and Datasheets - Look in `$HOME/Documents/Calibre Library` for all MCU reference manuals, datasheets and board schematics. #### Debugging Build Issues - **Missing compiler**: Install `gcc-arm-none-eabi` package - **Missing dependencies**: Run `python3 tools/get_deps.py FAMILY` - **Board not found**: Check `hw/bsp/FAMILY/boards/` for valid board names - **objcopy errors**: Often non-critical in full builds, try individual example builds #### Working with USB Device Classes - **CDC (Serial)**: `src/class/cdc/` - Virtual serial port - **HID**: `src/class/hid/` - Human Interface Device (keyboard, mouse, etc.) - **MSC**: `src/class/msc/` - Mass Storage Class (USB drive) - **Audio**: `src/class/audio/` - USB Audio Class - Each class has device (`*_device.c`) and host (`*_host.c`) implementations #### MCU Family Support - **STM32**: Largest support (F0, F1, F2, F3, F4, F7, G0, G4, H7, L4, U5, etc.) - **Raspberry Pi**: RP2040, RP2350 with PIO-USB host support - **NXP**: iMXRT, Kinetis, LPC families - **Microchip**: SAM D/E/G/L families - Check `hw/bsp/` for complete list and `docs/reference/boards.rst` for details ### Code Style Guidelines #### General Coding Standards - Use C99 standard - Memory-safe: no dynamic allocation - Thread-safe: defer all interrupt events to non-ISR task functions - 2-space indentation, no tabs - Use snake_case for variables/functions - Use UPPER_CASE for macros and constants - Follow existing variable naming patterns in files you're modifying - Include proper header comments with MIT license - Add descriptive comments for non-obvious functions #### Best Practices - When including headers, group in order: C stdlib, tusb common, drivers, classes - Always check return values from functions that can fail - Use TU_ASSERT() for error checking with return statements - Follow the existing code patterns in the files you're modifying Remember: TinyUSB is designed for embedded systems - builds are fast, tests are focused, and the codebase is optimized for resource-constrained environments. ================================================ FILE: CODE_OF_CONDUCT.rst ================================================ *************** Code of Conduct *************** Our Pledge ---------- In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. Our Standards ------------- Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting Our Responsibilities -------------------- Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Scope ----- This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. Enforcement ----------- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at thach@tinyusb.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Attribution ----------- This Code of Conduct is adapted from the `Contributor Covenant `__, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: CONTRIBUTORS.rst ================================================ ************ Contributors ************ Special thanks to all the people who spent their precious time and effort to help this project so far. list contributors and their awesome work for the stack: Notable contributors ==================== (sorted alphabetically) `Adafruit Team `__ ----------------------------------------------- - Main supporter and sponsor for hardware boards and kits - Discussion and suggestion for feature and improvement - Design the project logo `Gordon McNab `__ --------------------------------------------- - Add new DCD port for Bridgetek FT90x and FT93x `Ha Thach `__ ----------------------------------------- - *Author and maintainer* - Most features development `Heiko Kuester `__ -------------------------------------------- - Add CH34x and PL2303 support (CDC host) - Improve FTDI and CP210x support (CDC host) `Hristo Gochkov `__ ------------------------------------------------- - Improve ESP32s2 DCD `Jacob Berg Potter `__ ------------------------------------------------ - Add new class driver for network CDC-NCM `Jan Dümpelmann `__ ----------------------------------------------- - Improve transfer performance for Synopsys DCD for STM32 MCUs `Jeff Epler `__ ------------------------------------------ - Improve MIDI class driver `Jerzy Kasenberg `__ ----------------------------------------------- - Add new DCD port for Dialog DA1469x - Add new DCD port for PIC32MZ - Add new class driver for Bluetooth HCI - Add ISO transfer for STM32 Synopsys, Nordic nRF, Dialog DA1469x - Improve Audio driver and add uac2\_headset example - Improve STM32 Synopsys DCD with various PRs `J McCarthy `__ -------------------------------------------------- - Add new DFU 1.1 class driver - Add new example for dfu `Kamil Tomaszewski `__ ---------------------------------------------------- - Add new DCD port for Sony CXD56 (spresnese board) `Kay Sievers `__ ----------------------------------------------- - Improve MIDI driver with packet API `Koji KITAYAMA `__ ----------------------------------------------- - Add new DCD and HCD port for NXP Kinetis KL25 - Add new DCD and HCD port for Renesas RX family (RX600, RX700 ..) with GR-CITRUS, RX65n target board - Add new DCD and HCD port for Mentor musb with MSP432E4 - Add new class driver for USB Video Class (UVC 1.5) `Nathan Conrad `__ --------------------------------------------- - Add new DCD port for STM32 fsdev Fullspeed device for STM32 L0, F0, F1, F3 etc ... - Add new class driver for USB Test and Measurement Class (USBTMC) - Various improvement e.g Zero-length packet, Lint setup - Board support for STM32F070RB Nucleo, STM32F303 Discovery `Peter Lawrence `__ ------------------------------------------------ - Add new DCD port for Nuvoton NUC 120, 121, 125, 126, 505 - Add new class driver for network RNDIS, CDC-ECM - Enhance CDC-NCM network driver to compatible with RNDIS/ECM - Add *net\_lwip\_webserver* example for demonstration of usbnet with lwip - Board support for NuTiny NUC120, NUC121s, NUC125s, NUC126V, NUC505 - Improve multiple cdc interfaces API & add cdc\_dual\_ports example `Rafael Silva `__ ---------------------------------------------- - Port DCD Synopsys to support Silabs EFM32GG12 with SLTB009A board - Rewrite documentation in rst and setup for readthedocs - Generalize Renesas driver and support RA family with EK-RA4M3 board `Raspberry Pi Team `__ ------------------------------------------------------ - Add new DCD port for Raspberry Pi RP2040 - Add new HCD port for Raspberry Pi RP2040 `Reinhard Panhuber `__ ------------------------------------------------ - Add new class driver for USB Audio Class 2.0 (UAC2) - Rework tu\_fifo with unmasked pointer, add DMA support, and constant address support - Add new DCD/USBD edpt\_xfer\_fifo() API for optimizing endpoint transfer - Add and greatly improve Isochronous transfer - Add new audio examples: audio\_test and audio\_4\_channel\_mic `Scott Shawcroft `__ ------------------------------------------------ - Add new DCD port for SAMD21 and SAMD51 - Add new class driver for Musical Instrument Digital Interface (MIDI) - Improve USBD control transfer, MSC, CDC class driver - Board support for Metro M0 & M4 express - Write the excellent porting.md documentation - Add initial Makefile `Sean Cross `__ ---------------------------------------- - Add new DCD port for ValentyUSB eptri (fomu board) `Sylvain "tnt" Munaut `__ ----------------------------------------------------- - Add new class driver for DFU Runtime `Tian Yunhao `__ ------------------------------------------- - Add new DCD port for Allwinner F1C100S/F1C200S - Add support for osal_rtx4 `Timon Skerutsch `__ ---------------------------------------------- - Add hid\_test.js script and extensive test for bi-directional raw HID `Tod E. Kurt `__ ------------------------------------------- - Add hid\_test.js script and extensive test for bi-directional raw HID `Uwe Bonnes `__ --------------------------------------------- - Improve STM32 Synopsys highspeed DCD `William D. Jones `__ ------------------------------------------------ - Add new DCD port for Synopsys DesignWare for STM32 L4, F2, F4, F7, H7 etc ... - Add new DCD port for TI MSP430 - Board support for STM32F407 Discovery, STM32H743 Nucleo, pyboard v1.1, msp\_exp430f5529lp etc ... `Zixun Li `__ ------------------------------------------- - Add new DCD port for Microchip SAMx7x - Add IAR compiler support - Improve UAC2, CDC, DFU class driver - Improve stm32_fsdev, chipidea_ci_hs, lpc_ip3511 DCD - Host IAR Build CI & hardware in the loop (HITL) test `Full contributors list `__ ============================================================================ ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2012-2026, hathach (tinyusb.org) 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. ================================================ FILE: README.rst ================================================ TinyUSB ======= |Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |Membrowse| |License| Sponsors -------- TinyUSB is funded by: Adafruit. Purchasing products from them helps to support this project. .. figure:: docs/assets/adafruit_logo.svg :alt: Adafruit Logo :align: left :target: https://www.adafruit.com .. raw:: html
Overview -------- .. figure:: docs/assets/logo.svg :alt: TinyUSB :align: left .. raw:: html
TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems. It’s designed for memory safety (no dynamic allocation) and thread safety (all interrupts deferred to non-ISR task functions). The stack emphasizes portability, small footprint, and real-time performance across 50+ MCU families. Key Features ------------ * **Thread-safe:** USB interrupts deferred to task context * **Memory-safe:** No dynamic allocation, all buffers static * **Portable:** Supports 50+ MCU families * **Comprehensive:** Includes CDC, HID, MSC, Audio, and Host support * **RTOS-friendly:** Works with bare metal, FreeRTOS, RT-Thread, and Mynewt .. figure:: docs/assets/stack.svg :width: 500px :align: left :alt: stackup .. raw:: html
:: . ├── docs # Documentation ├── examples # Examples with make and cmake build system ├── hw │ ├── bsp # Supported boards source files │ └── mcu # Low level mcu core & peripheral drivers ├── lib # Sources from 3rd party such as FreeRTOS, FatFs ... ├── src # All sources files for TinyUSB stack itself. ├── test # Tests: unit test, fuzzing, hardware test └── tools # Files used internally Getting started --------------- See the `online documentation `_ for information about using TinyUSB and how it is implemented. Check out `Getting Started`_ guide for adding TinyUSB to your project or building the examples. If you are new to TinyUSB, we recommend starting with the ``cdc_msc`` example. There is a handful of `Supported Boards`_ that should work out of the box. We use `GitHub Discussions `_ as our forum. It is a great place to ask questions and advice from the community or to discuss your TinyUSB-based projects. For bugs and feature requests, please `raise an issue `_ and follow the templates there. See `Porting`_ guide for adding support for new MCUs and boards. Device Stack ------------ Supports multiple device configurations by dynamically changing USB descriptors, low power functions such like suspend, resume, and remote wakeup. The following device classes are supported: - Audio Class 1.0/2.0 (UAC1/UAC2) - Bluetooth Host Controller Interface (BTH HCI) - Communication Device Class (CDC) - Device Firmware Update (DFU): DFU mode (WIP) and Runtime - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Printer class - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) - Media Transfer Protocol (MTP/PTP) - Network with RNDIS, Ethernet Control Model (ECM), Network Control Model (NCM) - Test and Measurement Class (USBTMC) - Video class 1.5 (UVC): work in progress - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - `WebUSB `__ with vendor-specific class If you have a special requirement, ``usbd_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 `_ Host Stack ---------- - Communication Device Class: CDC-ACM - Vendor serial over USB: FTDI, CP210x, CH34x, PL2303 - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) - Musical Instrument Digital Interface (MIDI) - Hub with multiple-level support Similar to the Device Stack, if you have a special requirement, ``usbh_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack. Power Delivery Stack -------------------- - Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP) - Super early stage, only for testing purpose - Only support STM32 G4 OS Abstraction layer -------------------- TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box. - **No OS** - **FreeRTOS** - `RT-Thread `_: `repo `_ - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ Supported CPUs -------------- +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Manufacturer | Family | Device | Host | Highspeed | Driver | Note | +==============+=============================+========+======+===========+========================+====================+ | Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | | | MAX78002 | | | | | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | 512 USB RAM | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | F415, F435_437, F423, | ✔ | ✔ | | dwc2 | | | | F425, F45x | | | | | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Bridgetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Espressif | S2, S3, H4 | ✔ | ✔ | ✖ | dwc2 | | | ESP32 +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | P4 | ✔ | ✔ | ✔ | dwc2 | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | HPMicro | HPM6750 | ✔ | ✔ | ✔ | ci_hs, ehci | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | D51, E5x | ✔ | | ✖ | samd | | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | G55 | ✔ | | ✖ | samg | 1-dir ep | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | | +-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | | PIC | 24 | ✔ | | | pic | ci_fs variant | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | dsPIC33 | ✔ | | | pic | ci_fs variant | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | 32mz | ✔ | | | pic32mz | musb variant | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | MindMotion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | NUC121/NUC125, NUC126 | ✔ | ✖ | ✖ | nuc121 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | NUC505 | ✔ | | ✔ | nuc505 | | +--------------+---------+-------------------+--------+------+-----------+------------------------+--------------------+ | NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | | | +---------+-------------------+--------+------+-----------+------------------------+--------------------+ | | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | | +---------+-------------------+--------+------+-----------+------------------------+--------------------+ | | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | NRND, read errata | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | | +---------+-------------------+--------+------+-----------+------------------------+--------------------+ | | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | | | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | A15 | ✔ | | | ci_fs | | | +---------+-------------------+--------+------+-----------+------------------------+--------------------+ | | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | | +-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | | | +-----------------------+--------+------+-----------+------------------------+--------------------+ | | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | ST STM32 | F0, F3, L0, L1, L5, WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | 512 USB RAM | | | +------------------------+--------+------+-----------+------------------------+--------------------+ | | | 105, 107 | ✔ | ✔ | ✖ | dwc2 | | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | | | +------------------------+--------+------+-----------+------------------------+--------------------+ | | | 4x5, 4x6, 4+ | ✔ | ✔ | ✖ | dwc2 | | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | N6 | ✔ | ✔ | ✔ | dwc2 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | U0 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | U5 | 535, 545 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | | | +------------------------+--------+------+-----------+------------------------+--------------------+ | | | 575, 585 | ✔ | ✔ | ✖ | dwc2 | | | | +------------------------+--------+------+-----------+------------------------+--------------------+ | | | 59x,5Ax,5Fx,5Gx | ✔ | ✔ | ✔ | dwc2 | | +--------------+----+------------------------+--------+------+-----------+------------------------+--------------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | MSP432E4, TM4C123 | ✔ | | ✖ | musb | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | WCH | CH32F20x | ✔ | | ✔ | ch32_usbhs | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | CH32V20x | ✔ | | ✖ | stm32_fsdev/ch32_usbfs | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | CH32V305, CH32V307 | ✔ | | ✔ | ch32_usbfs/hs | | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ Table Legend ^^^^^^^^^^^^ ========= ========================= ✔ Supported ⚠ Partial support ✖ Not supported by hardware \[empty\] Unknown ========= ========================= Development Tools ----------------- The following tools are provided freely to support the development of the TinyUSB project: - `IAR Build Tools (CX) `_ Professional IDE and compiler for embedded development. - `JetBrains CLion `_ Cross-platform IDE for C and C++ development. - `PVS-Studio `_ static analyzer for C, C++, C#, and Java code. .. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/build.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions/workflows/build.yml .. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg :target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master .. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest :target: https://docs.tinyusb.org/en/latest/?badge=latest .. |Static Analysis| image:: https://github.com/hathach/tinyusb/actions/workflows/static_analysis.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions/workflows/static_analysis.yml .. |Fuzzing Status| image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/tinyusb.svg :target: https://oss-fuzz-build-logs.storage.googleapis.com/index.html#tinyusb .. |Membrowse| image:: https://membrowse.com/badge.svg :target: https://membrowse.com/public/hathach/tinyusb .. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg :target: https://opensource.org/licenses/MIT .. _Changelog: docs/info/changelog.rst .. _Contributors: CONTRIBUTORS.rst .. _Getting Started: docs/getting_started.rst .. _Supported Boards: docs/reference/boards.rst .. _Dependencies: docs/reference/dependencies.rst .. _Concurrency: docs/reference/concurrency.rst .. _Code of Conduct: CODE_OF_CONDUCT.rst .. _Porting: docs/porting.rst ================================================ FILE: SConscript ================================================ # RT-Thread building script for bridge import os from building import * objs = [] cwd = GetCurrentDir() objs = objs + SConscript(cwd + '/lib/rt-thread/SConscript') Return('objs') ================================================ FILE: docs/_static/custom.css ================================================ .clear-both { clear: both; } ================================================ FILE: docs/conf.py ================================================ #!/usr/bin/env python3 # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html import re from pathlib import Path # -- Path setup -------------------------------------------------------------- # -- Project information ----------------------------------------------------- project = 'TinyUSB' copyright = '2025, Ha Thach' author = 'Ha Thach' # -- General configuration --------------------------------------------------- extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx_autodoc_typehints', ] templates_path = ['_templates'] exclude_patterns = ['_build'] # -- Options for HTML output ------------------------------------------------- html_theme = 'furo' html_title = 'TinyUSB' html_logo = 'assets/logo.svg' html_favicon = 'assets/logo.svg' html_theme_options = { 'sidebar_hide_name': True, } html_static_path = ['_static'] html_css_files = ['custom.css'] todo_include_todos = True # pre-process path in README.rst def preprocess_readme(): """Modify figure paths in README.rst for Sphinx builds.""" src = Path(__file__).parent.parent / "README.rst" tgt = Path(__file__).parent.parent / "README_processed.rst" if src.exists(): content = src.read_text(encoding='utf-8') content = re.sub(r"docs/", r"", content) content = re.sub(r"\.rst\b", r".html", content) if not content.endswith("\n"): content += "\n" tgt.write_text(content, encoding='utf-8') preprocess_readme() ================================================ FILE: docs/faq.rst ================================================ ************************** Frequently Asked Questions ************************** General Questions ================= **Q: What microcontrollers does TinyUSB support?** TinyUSB supports 50+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. **Q: Can I use TinyUSB in commercial projects?** Yes, TinyUSB is released under the MIT license, allowing commercial use with minimal restrictions. **Q: Does TinyUSB require an RTOS?** No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, ThreadX, and Mynewt. **Q: How much memory does TinyUSB use?** Typical usage: 8-20KB flash, 1-4KB RAM depending on enabled classes and configuration. The stack uses static allocation only. Build and Setup ================ **Q: Why do I get "arm-none-eabi-gcc: command not found"?** Install the ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` on Ubuntu/Debian, or download from ARM's website for other platforms. **Q: Build fails with "Board 'X' not found"** Check available boards: ``ls hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` to list all supported boards. **Q: What are the dependencies and how do I get them?** Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., stm32f4, rp2040). This downloads MCU-specific drivers and libraries. **Q: Can I use my own build system instead of Make/CMake?** Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`getting_started` for details. **Q: Error: "tusb_config.h: No such file or directory"** This is a very common issue. You need to create ``tusb_config.h`` in your project and ensure it's in your include path. The file must define ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS`` at minimum. Copy from ``examples/device/*/tusb_config.h`` as a starting point. **Q: RP2040 + pico-sdk ignores my tusb_config.h settings** The pico-sdk build system can override ``tusb_config.h`` settings. The ``CFG_TUSB_OS`` setting is often ignored because pico-sdk sets it to ``OPT_OS_PICO`` internally. Use pico-sdk specific configuration methods or modify the CMake configuration. **Q: "multiple definition of dcd_..." errors with STM32** This happens when multiple USB drivers are included. Ensure you're only including the correct portable driver for your STM32 family. Check that ``CFG_TUSB_MCU`` is set correctly and you don't have conflicting source files. Device Development ================== **Q: My USB device isn't recognized by the host** Common causes: - Invalid USB descriptors - validate with ``LOG=2`` build - ``tud_task()`` not called regularly in main loop - Incorrect ``tusb_config.h`` settings - USB cable doesn't support data (charging-only cable) **Q: Windows shows "Device Descriptor Request Failed"** This typically indicates: - Malformed device descriptor - USB timing issues (check crystal/clock configuration) - Power supply problems during enumeration - Conflicting devices on the same USB hub **Q: How do I implement a custom USB class?** Use the vendor class interface (``CFG_TUD_VENDOR``) or implement a custom class driver. See ``src/class/vendor/`` for examples. **Q: Can I have multiple configurations or interfaces?** Yes, TinyUSB supports multiple configurations and composite devices. Modify the descriptors in ``usb_descriptors.c`` accordingly. **Q: How do I change Vendor ID/Product ID?** Edit the device descriptor in ``usb_descriptors.c``. For production, obtain your own VID from USB-IF or use one from your silicon vendor. **Q: Device works alone but fails when connected through USB hub** This is a known issue where some devices interfere with each other when connected to the same hub. Try: - Using different USB hubs - Connecting devices to separate USB ports - Checking for power supply issues with the hub Host Development ================ **Q: Why doesn't my host application detect any devices?** Check: - Power supply - host mode requires more power than device mode - USB connector type - use USB-A for host applications - Board supports host mode on the selected port - Enable logging with ``LOG=2`` to see enumeration details **Q: Can I connect multiple devices simultaneously?** Yes, through a USB hub. TinyUSB supports multi-level hubs and multiple device connections. **Q: Does TinyUSB support USB 3.0?** No, TinyUSB currently supports USB 2.0 and earlier. USB 3.0 devices typically work in USB 2.0 compatibility mode. Configuration and Features ========================== **Q: How do I enable/disable specific USB classes?** Edit ``tusb_config.h`` and set the corresponding ``CFG_TUD_*`` or ``CFG_TUH_*`` macros to 1 (enable) or 0 (disable). **Q: Can I use both device and host modes simultaneously?** Yes, with dual-role/OTG capable hardware. See ``examples/dual/`` for implementation examples. **Q: How do I optimize for code size?** - Disable unused classes in ``tusb_config.h`` - Use ``CFG_TUSB_DEBUG = 0`` for release builds - Compile with ``-Os`` optimization - Consider using only required endpoints/interfaces **Q: Does TinyUSB support low power/suspend modes?** Yes, TinyUSB handles USB suspend/resume. Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for custom power management. **Q: What CFG_TUSB_MCU should I use for x86/PC platforms?** For PC/motherboard applications, there's no standard MCU option. You may need to use a generic option or modify TinyUSB for your specific use case. Consider using libusb or other PC-specific USB libraries instead. **Q: RP2040 FreeRTOS configuration issues** The RP2040 pico-sdk has specific requirements for FreeRTOS integration. The ``CFG_TUSB_OS`` setting may be overridden by the SDK. Use pico-sdk specific configuration methods and ensure proper task stack sizes for the USB task. Debugging and Troubleshooting ============================= **Q: How do I debug USB communication issues?** 1. Enable logging: build with ``LOG=2`` 2. Use ``LOGGER=rtt`` or ``LOGGER=swo`` for high-speed logging 3. Use USB protocol analyzers for detailed traffic analysis 4. Check with different host systems (Windows/Linux/macOS) **Q: My application crashes or hard faults** Common causes: - Stack overflow - increase stack size in linker script - Incorrect interrupt configuration - Buffer overruns in USB callbacks - Build with ``DEBUG=1`` and use a debugger **Q: Performance is poor or USB transfers are slow** - Ensure ``tud_task()``/``tuh_task()`` called frequently (< 1ms intervals) - Use DMA for USB transfers if supported by your MCU - Optimize endpoint buffer sizes - Consider using high-speed USB if available **Q: Some USB devices don't work with my host application** - Not all devices follow USB standards perfectly - Some may need device-specific handling - Composite devices may have partial support - Check device descriptors and implement custom drivers if needed **Q: ESP32-S3 USB host/device issues** ESP32-S3 has specific USB implementation challenges: - Ensure proper USB pin configuration - Check power supply requirements for host mode - Some features may be limited compared to other MCUs - Use ESP32-S3 specific examples and documentation ================================================ FILE: docs/getting_started.rst ================================================ *************** Getting Started *************** This guide will get you up and running with TinyUSB quickly with working examples. Project Structure ==================== TinyUSB separates example applications from board-specific hardware configurations: * **Example applications**: Located in `examples/ `_ directories * **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts * **Build system**: Located in `examples/build_system/ `_ which supports both Make and CMake. Though some MCU families such as espressif or rp2040 only support cmake For example, stm32h743eval is located in `hw/bsp/stm32h7/boards/stm32h743eval `_ where ``FAMILY=stm32h7`` and ``BOARD=stm32h743eval``. When you build with ``BOARD=stm32h743eval``, the build system automatically finds the corresponding BSP using the FAMILY. For guidance on integrating TinyUSB into your own firmware (configuration, descriptors, initialization, and callback workflow), see :doc:`integration`. Quick Start Examples ==================== The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. We'll assume you are using the **STM32H743 Eval board** (BOARD=stm32h743eval) under the **stm32h7** family. For other boards, see ``Board Support Packages`` below. Get the Code ------------ .. code-block:: bash $ git clone https://github.com/hathach/tinyusb tinyusb $ cd tinyusb $ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7 .. note:: Some MCU families require additional SDKs, please follow their instructions to install and set it up * **rp2040**: Requires `pico-sdk `_ * **Espressif (esp32)**: Requires `esp-idf `_. Only a few examples support the ESP-IDF build system. Look for ones with `src/CMakeLists.txt` that contain `idf_component_register()`, such as `cdc_msc_freertos`. Simple Device Example --------------------- The `cdc_msc `_ example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). **What it does:** * Appears as a serial port that echoes back any text you send * Appears as a small USB drive with a README.TXT file * Blinks an LED to show activity **Build and run with CMake:** .. code-block:: bash $ cd examples/device/cdc_msc $ cmake -DBOARD=stm32h743eval -B build # add "-G Ninja" to use Ninja build $ cmake --build build # cmake --build build --target cdc_msc-jlink .. tip:: Flashed/Debugger can be selected with --target ``-jlink``, ``-stlink`` or ``-openocd`` depending on your board. Use ``--target help`` to list all supported targets. **Build and run with Make:** .. code-block:: bash $ cd examples/device/cdc_msc $ make BOARD=stm32h743eval all $ make BOARD=stm32h743eval flash-jlink .. tip:: Flashed/Debugger can be selected with target ``flash-jlink``, ``flash-stlink`` or ``flash-openocd`` depending on your board. Connect the device to your computer and you'll see both a new serial port and a small USB drive appear. Simple Host Example ------------------- The `cdc_msc_hid `_ example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. **What it does:** * Detects and enumerates connected USB devices * Communicates with CDC devices (like USB-to-serial adapters) * Reads from MSC devices (like USB drives) * Receives input from HID devices (like keyboards and mice) **Build and run with CMake:** .. code-block:: bash $ cd examples/host/cdc_msc_hid $ cmake -DBOARD=stm32h743eval -B build $ cmake --build build **Build and run with Make:** .. code-block:: bash $ cd examples/host/cdc_msc_hid $ make BOARD=stm32h743eval all $ make BOARD=stm32h743eval flash-jlink Connect USB devices to see enumeration messages and device-specific interactions in the serial output. Additional Build Options ------------------------ Debug and Logging ^^^^^^^^^^^^^^^^^ TinyUSB built-in logging can be enabled by setting `CFG_TUSB_DEBUG` which is done by passing ``LOG=level``. The higher the level, the more verbose the logging. In addition to traditional hw uart as default, logging with debugger such as `Segger RTT `_ (10x faster) is also supported with `LOGGER=rtt` option. .. code-block:: bash $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 # logging level 2 with uart $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 -DLOGGER=rtt # logging level 2 with RTT .. code-block:: bash $ make BOARD=stm32h743eval LOG=2 all # logging level 2 with uart $ make BOARD=stm32h743eval LOG=2 LOGGER=rtt all # logging level 2 with RTT RootHub Port Selection ^^^^^^^^^^^^^^^^^^^^^^ Some boards support multiple usb controllers (roothub ports), by default one rh port is used as device, another as host in ``board.mk/board.cmake``. This can be overridden with option ``RHPORT_DEVICE=n`` or ``RHPORT_HOST=n`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: .. code-block:: bash $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE=1 # select roothub port 1 as device .. code-block:: bash $ make BOARD=stm32h743eval RHPORT_DEVICE=1 all # select roothub port 1 as device RootHub Port Speed ^^^^^^^^^^^^^^^^^^ A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force operating speed .. code-block:: bash $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. code-block:: bash $ make BOARD=stm32h743eval RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all IAR Embedded Workbench ---------------------- For IAR users, project connection files are available. Import `tools/iar_template.ipcf `_ or use native CMake support (IAR 9.50.1+). See `tools/iar_gen.py `_ for automated project generation. Common Issues and Solutions --------------------------- **Build Errors** * **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` * **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` * **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board or ``python tools/get_deps.py -b BOARD`` **Runtime Issues** * **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings * **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors * **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation **Linux Permissions** Some examples require udev permissions to access USB devices: .. code-block:: bash $ cp `examples/device/99-tinyusb.rules `_ /etc/udev/rules.d/ $ sudo udevadm control --reload-rules && sudo udevadm trigger Next Steps ========== * Check :doc:`integration` for integrating TinyUSB into your own firmware * Check :doc:`reference/boards` for board-specific information * Explore more examples in `examples/device/ `_ and `examples/host/ `_ directories * Read :doc:`reference/usb_concepts` to understand USB fundamentals ================================================ FILE: docs/index.rst ================================================ .. include:: ../README_processed.rst .. toctree:: :maxdepth: 2 :caption: Information getting_started integration porting reference/index faq troubleshooting .. toctree:: :maxdepth: 1 :caption: Project Info info/index .. toctree:: :caption: External Links :hidden: Source Code Issue Tracker Discussions ================================================ FILE: docs/info/changelog.rst ================================================ ********* Changelog ********* 0.20.0 ====== *November 19, 2025* General ------- - New MCUs and Boards: - Add STM32U3 device support (adjusted from STM32U0) - Add nRF54H20 support with initial board configuration - Rename board names: pca10056→nrf52840dk, pca10059→nrf52840dongle, pca10095→nrf5340dk - Improve CMake: Move startup and linker files from board target to executable. Enhance target warning flags and fix various build warnings - Code Quality and Static Analysis: - Add PVS-Studio static analysis to CI - Add SonarQube scan support - Add IAR C-Stat analysis capability - Add ``.clang-format`` for consistent code formatting - Fix numerous alerts and warnings found by static analysis tools - Documentation: - Improve Getting Started documentation structure and flow - Add naming conventions and buffer handling documentation Controller Driver (DCD & HCD) ----------------------------- - DWC2 - Fix incorrect handling of Zero-Length Packets (ZLP) in the DWC2 driver when receiving data (OUT transfers) - Improve EP0 multi-packet logic - Support EP0 with max packet size = 8 - For IN endpoint, write initial packet directly to FIFO and only use TXFE interrupt for subsequent packets - Fix ISO with bInterval > 2 using incomplete IN interrupt handling. - Fix compile issues when enabling both host and device - Clear pending suspend interrupt after USB reset (enum end) - Improve host closing endpoint and channel handling when device is unplugged - FSDEV (STM32) - Fix AT32 USB interrupt remapping in ``dcd_int_enable()`` - OHCI - Add initial LPC55 OHCI support - Improve data cache support Device Stack ------------ - USBD Core - Support configurable EP0 buffer size CFG_TUD_ENDPOINT0_BUFSIZE - Make dcd_edpt_iso_alloc/activate as default API for ISO endpoint - Audio - Add UAC1 support - Implement RX FIFO threshold adjustment with `tud_audio_get/set_ep_in_fifo_threshold()` - CDC - Migrate to endpoint stream API - HID - Fix HID stylus descriptor - MIDI - Migrate to endpoint stream API - Add ``tud_midi_n_packet_write_n()`` and ``tud_midi_n_packet_read_n()`` - MTP - Fix incorrect MTP xact_len calculation - Video - Add bufferless operation callback for dynamic frame generation with tud_video_prepare_payload_cb() Host Stack ---------- No changes 0.19.0 ====== General ------- - New MCUs and Boards: - Add ESP32-H4, ESP32-C5, ESP32-C61 support - Add STM32U0, STM32WBA, STM32N6 - Add AT32F405, AT32F403A, AT32F415, AT32F423 support - Add CH32V305 support and CH32V20x USB host support - Add MCXA156 SDK 2.16 support and FRDM-MCXA156 board API Changes ----------- - Core APIs - Add weak callbacks with new syntax for better compiler compatibility - Add ``tusb_deinit()`` to cleanup stack - Add time functions: ``tusb_time_millis_api()`` and ``tusb_time_delay_ms_api()`` - Add ``osal_critical`` APIs for critical section handling - Introduce ``xfer_isr()`` callback for ISO transfer optimization in device classes - Device APIs - CDC: Add notification support ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - MSC: Add ``tud_msc_inquiry2_cb()`` with bufsize parameter, update ``tud_msc_async_io_done()`` with ``in_isr`` parameter - Audio: Add ``tud_audio_n_mounted()`` and various FIFO access functions - MTP: Add ``tud_mtp_mounted()``, ``tud_mtp_data_send()``, ``tud_mtp_data_receive()``, ``tud_mtp_response_send()``, ``tud_mtp_event_send()`` - Host APIs - Core: Add ``tuh_edpt_close()``, ``tuh_address_set()``, ``tuh_descriptor_get_device_local()``, ``tuh_descriptor_get_string_langid()``, ``tuh_connected()``, ``tuh_bus_info_get()`` - Add enumeration callbacks: ``tuh_enum_descriptor_device_cb()``, ``tuh_enum_descriptor_configuration_cb()`` - CDC: Add ``tuh_cdc_get_control_line_state_local()``, ``tuh_cdc_get/set_dtr/rts()``, ``tuh_cdc_connect/disconnect()`` and sync versions of all control APIs - MIDI: Add ``tuh_midi_itf_get_info()``, ``tuh_midi_packet_read_n()``, ``tuh_midi_packet_write_n()``, ``tuh_midi_read_available()``, ``tuh_midi_write_flush()``, ``tuh_midi_descriptor_cb()`` Controller Driver (DCD & HCD) ----------------------------- - DWC2 - Support DWC2 v4.30a with improved reset procedure - Fix core reset: wait for AHB idle before reset - Add STM32 DWC2 data cache support with proper alignment - Host improvements: - Fix disconnect detection and SOF flag handling - Fix HFIR timing off-by-one error - Retry IN token immediately for bInterval=1 - Proper attach debouncing (200ms) - Fix all retry intervals - Resume OUT transfer when PING ACKed - Fix enumeration racing conditions - Refactor bitfields for better code generation - FSDEV (STM32) - Fix AT32 compile issues after single-buffered endpoint changes - Add configurable single-buffered isochronous endpoints - Fix STM32H7 recurrent suspend ISR - Fix STM32L4 GPIOD clock enable for variants without GPIOD - Fix STM32 PHYC PLL stability wait - Improve PMA size handling for STM32U0 - EHCI - Fix removed QHD getting reused - Fix NXP USBPHY disconnection detection - Chipidea/NXP - Fix race condition with spinlock - Improve iMXRT support: fix build, disable BOARD_ConfigMPU, fix attach debouncing on port1 highspeed - Fix iMXRT1064 and add to HIL test pool - MAX3421E - Use spinlock for thread safety instead of atomic flag - Implement ``hcd_edpt_close()`` - RP2040 - Fix audio ISO transfer: reset state before notifying stack - Fix CMake RTOS cache variable - Abort transfer if active in ``iso_activate()`` - SAMD - Add host controller driver support Device Stack ------------ - USBD Core - Introduce ``xfer_isr()`` callback for interrupt-time transfer handling - Add ``usbd_edpt_xfer_fifo()`` stub - Revert endpoint busy/claim status if ``xfer_isr()`` defers to ``xfer_cb()`` - Audio - Major simplification of UAC driver and alt settings management - Move ISO transfers into ``xfer_isr()`` for better performance - Remove FIFO mutex (single producer/consumer optimization) - Add implicit feedback support for data IN endpoints - Fix alignment issues - Update buffer macros with cache line size alignment - CDC - Add notification support: ``CFG_TUD_CDC_NOTIFY``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - Reduce default bInterval from 16ms to 1ms for better responsiveness - Rename ``tud_cdc_configure_fifo()`` to ``tud_cdc_configure()`` and add ``tx_overwritable_if_not_connected`` option - Fix web serial robustness with major overhaul and logic cleanup - HID - Add Usage Page and Table for Power Devices (0x84 - 0x85) - Fix HID descriptor parser variable size and 4-byte item handling - Add consumer page configurations - MIDI - Fix MIDI interface descriptor handling after audio streaming interface - Skip RX data with all zeroes - MSC - Add async I/O support for MSC using ``tud_msc_async_io_done()`` - Add ``tud_msc_inquiry2_cb()`` with bufsize for full inquiry response - MTP - Add new Media Transfer Protocol (MTP) device class driver - Support MTP operations: GetDeviceInfo, SendObjectInfo, SendObject - Add MTP event support with ``tud_mtp_event_send()`` - Implement filesystem example with callbacks - Add hardware-in-the-loop testing support - NCM - Add USB NCM link state control support - Fix DHCP offer/ACK destination - USBTMC - Add vendor-specific message support - Vendor - Fix vendor device reset and open issues - Fix descriptor parsing for ``CFG_TUD_VENDOR > 1`` - Fix vendor FIFO argument calculation Host Stack ---------- - USBH Core - Major enumeration improvements: - Fix enumeration racing conditions - Add proper attach debouncing with hub/rootport handling (200ms delay) - Reduce ``ENUM_DEBOUNCING_DELAY_MS`` to 200ms - Always get language ID, manufacturer, product, and serial strings during enumeration - Always get first 2 bytes of string descriptor to determine length (prevents buffer overflow) - Support devices with multiple configurations - Add ``tuh_enum_descriptor_device_cb()`` and ``tuh_enum_descriptor_configuration_cb()`` callbacks - Add ``tuh_descriptor_get_string_langid()`` API - Hub improvements: - Check status before getting first device descriptor - Properly handle port status and change detection - Queue status endpoint for detach/remove events - Fix hub status change endpoint handling - Fix endpoint management: - ``hcd_edpt_open()`` returns false if endpoint already opened - Add ``hcd_edpt_close()`` implementation - Abort pending transfers on close - Add roothub debouncing flag to ignore attach/remove during debouncing - Move address setting and bus info management to separate structures - Force removed devices in same bus info before setting address - CDC Serial Host - Major refactor to generalize CDC serial drivers (FTDI, CP210x, CH34x, PL2303, ACM) - Add explicit ``sync()`` API with ``TU_API_SYNC()`` returning ``tusb_xfer_result_t`` - Rename ``tuh_cdc_get_local_line_coding()`` to ``tuh_cdc_get_line_coding_local()`` - Add ``tuh_cdc_get_control_line_state_local()`` - Implement ``tuh_cdc_get/set_dtr/rts()`` as inline functions - MIDI Host - Major API changes: - Rename ``tuh_midi_stream_flush()`` to ``tuh_midi_write_flush()`` - Add ``tuh_midi_packet_read_n()`` and ``tuh_midi_packet_write_n()`` - Add ``CFG_TUH_MIDI_STREAM_API`` to opt out of stream API - Change API to use index instead of device address (supports multiple MIDI per device) - Rename ``tuh_midi_get_num_rx/tx_cables()`` to ``tuh_midi_get_rx/tx_cable_count()`` - Add ``tuh_midi_descriptor_cb()`` and ``tuh_midi_itf_get_info()`` - MSC Host - Continue async I/O improvements - HID Host - Fix version string to actually show version 0.18.0 ====== General ------- - New MCUs: - Add esp32p4 OTG highspeed support - Add stm32 u0, c0, h7rs - Better support dcache, make sure all usb-transferred buffer are cache line aligned and occupy full cache line - Build ARM IAR with CircleCI - Improve HIL with `dual/host_info_to_device_cdc`` optional for pico/pico2, enable dwc2 dma test API Changes ----------- - Change signature of ``tusb_init(rhport, tusb_rhport_init_t*)``, ``tusb_init(void)`` is now deprecated but still available for backward compatibility - Add new ``tusb_int_handler(rhport, in_isr)`` - Add time-related APIs: ``tusb_time_millis_api()`` and ``tusb_time_delay_ms_api()`` for non-RTOS, required for some ports/configuration - New configuration macros: - ``CFG_TUD/TUH_MEM_DCACHE_ENABLE`` enable data cache sync for endpoint buffer - ``CFG_TUD/TUH_MEM_DCACHE_LINE_SIZE`` set cache line size - ``CFG_TUD/TUH_DWC2_SLAVE_ENABLE`` enable dwc2 slave mode - ``CFG_TUD/TUH_DWC2_DMA_ENABLE`` enable dwc2 dma mode Controller Driver (DCD & HCD) ----------------------------- - DWC2 - Add DMA support for both device and host controller - Add host driver support including: full/high speed, control/bulk/interrupt (CBI) transfer, split CBI i.e FS/LS attached via highspeed hub, hub support - RP2: implement ``dcd_edpt_iso_alloc()`` and ``dcd_edpt_iso_activate()`` for isochronous endpoint - iMXRT1170 support M4 core Device Stack ------------ - Vendor Fix class reset - NCM fix recursions in ``tud_network_recv_renew()`` - Audio fix align issue of ``_audiod_fct.alt_setting`` - UVC support format frame based - Change ``dcd_dcache_()`` return type from void to bool - HID add Usage Table for Physical Input Device Page (0x0F) Host Stack ---------- - Fix an duplicated attach issue which cause USBH Defer Attach until current enumeration complete message 0.17.0 ====== General ------- - Improved CI: build both cmake and make. Make use of CircleCI for part of build process to speed up CI - Add CodeQL Workflow for Code Security Analysis - Add Clang compiler support - Add default implementation for weak callbacks functions for better Keil compatibility - Upgrade hardware-in-the-loop (HIL) testing with more boards and examples: including dual stack example Controller Driver (DCD & HCD) ----------------------------- - Chipidea - Support MCXA - DWC2 - Fix tickless issue with stm32f7: disable ULPI clock during sleep when using internal phy - Fix SOF interrupt handling - Fix fifo level half/empty issue - Add DWC2 Test Mode support. - for esp32 force disconnect/connect using USB_WRAP otg pad override - FSDEV - Rewrite and Generalize driver to support non-stm32 mcu such as wch - Simplify PMA, HW FIFO access and bit manipulation for different access scheme 1x16, 2x16 and 32 bit - Add support for ch32 usbd e.g ch32v203 - Add support for STM32G4 and STM32U5 microcontrollers. - Fix h5 (32-bit) errata 2.15.1: Buffer description table update completes after CTR interrupt triggers - ISO EP buffer allocation improvements, implement ``dcd_edpt_close_all()`` - Fix ch32v203 race condition and stability issue with - fix ch32v203 seems to unconditionally accept ZLP on EP0 OUT. - fix v203 race condition between rx bufsize and RX_STAT which cause PMAOVR, occurs with WRITE10 - correctly handle setup prepare at ``dcd_edpt0_status_complete()``, which fixes the race condition with windows where we could miss setup packet (setup bit set, but count = 0) - MAX3421E - Add support for rp2040, esp32 (c3, c6, h2, etc..) - Add ``hcd_deinit()`` for max3421 - Retry NAK handling next frame to reduce CPU and SPI bus usage - add ``cpuctl`` and ``pinctl`` to ``tuh_configure()`` option for max3421 - Implement hcd abort transfer for Max3421 - Properly Handle NAK Response in MAX3421E driver: correctly switch and skip writing to 2 FIFOs when NAK received. Otherwise, the driver may hang in certain conditions. - MSP430: support non-bus-powered - MUSB - Add support for Analoog devices: max32650, max32666, max32690, max3278002 - nRF - Fix ``dcd_edpt_open()`` for iso endpoint - Handle ISOOUT CRC errors - Add compile support with old nordic sdk - Fix a few race conditions - OHCI - Allow more than 16 devices - RP2040 - Correctly abort control transfer when new setup arrived. Due to RP2040-E2 only able to fix B2 or later - Implement hcd abort transfer for rp2040 - Add support for rp2350 - RUSB2 - Support ra2a1 pipe number scheme - WCH CH32 - Added support for USB OTG/FS and FSDev Driver. Update CH32V307 to allow manual select FS or HS driver. - Fixed various bugs in CH32v307 usbhs driver: endpoint handling and data transfer management. Device Stack ------------ - Add ``tud_deinit()`` and ``class driver deinit()`` to deinitialize TinyUSB device stack. - Add support for generic SOF callback. - Add set address recovery time 2ms per USB spec. - Audio - Add audio_test_freertos & audio_4_channel_mic_freertos - Improved support for Audio Class 2.0 (UAC2) with various bug fixes. - Add feedback by fifo counting. - Bluetooth HCI - Issue ZLP on ACL IN ep when transfer is multiple of endpoint max packet size - CDC - Add ``tud_cdc_configure_fifo()`` to make RX/TX buffer persistent (not clear when disconnected) - Add missing capability bit for CDC ACM serial break support - Enhanced CDC class with better handling of large data transmissions. - Add missing capability bit for CDC ACM serial break support - HID - Added missing key codes for keypad - Added HID Lighting and Illumination functionality - Fixed issues in the HID class for more reliable device enumeration. - Support HID Mouse with absolute positioning - Use separate buffer for control SET_REPORT, fix conflict with interrupt endpoint out - MSC: Added support for SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL - Net - Rewrite of NCM device driver to improve throughput - removed obsolete ``tud_network_link_state_cb()`` - USBTMC Added notification support - Vendor - Migrate to new endpoint stream API, support non-buffered TX/RX - Add ZLP for ``write()`` when needed - Video - Enhance UVC descriptors and example - Video Added support for USB Video Class (UVC) with MJPEG. - Fix multiple interfaces, add an example of 2ch video capture. - Fix race for ``tud_video_n_streaming()`` check Host Stack ---------- - Added ``tuh_deinit()`` to de-initialize TinyUSB host stack. - Added support for new USB mass storage class APIs. - Improved error handling and retry mechanisms for unstable devices. - CDC Serial - Add support for ch34x - Allow to overwrite ``CFG_TUH_CDC_FTDI/CP210X/CH32X_VID_PID_LIST`` - Enhanced stability of CDC-ACM devices during enumeration. - HID - Add ``tuh_hid_receive_abort()`` - Add ``tuh_hid_get_report()`` - Hub - Prevent status request to invalid ep_num - Fix double status xfer - unroll hub removal 0.16.0 ====== - New controller driver: MAX3421e (usb host shield), rusb2 (Renesas USB2.0), ChipIdea fullspeed - New MCUs: MCXn9, nRF5340, STM32: G0, G4, L5, U575, U5A5, RA6m5, CH32F20x - Add initial TypeC PowerDelivery support with STM32G4 - Remove submodules and use python script to manage repo dependencies #1947 - Add CMake support for most families and boards, move build file from tools/ to examples/build_system - Add ETM trace support with JTrace for nrf52840, nrf5340, mcb1857, stm32h743eval, ra6m5 - [osal] Make it possible to override the ``osal_task_delay()`` in osal_none - Add CDC+UAC2 composite device example - Enhance Hardware-in-the-loop (HIL) testing with more boards: rp2040, stm32l412nucleo, stm32f746disco, lpcxpresso43s67 Controller Driver (DCD & HCD) ----------------------------- - Add new ISO endpoint API: ``dcd_edpt_iso_alloc()`` and ``dcd_edpt_iso_activate()`` - Remove legacy driver st/synopsys - EHCI - [iMXRT] Add dache clean/invalidate when memory is in cacheable memory - Fix portsc write issue which cause problem with enumeration - Fix an issue when doing port reset write to portsc - Fix port change detect is not recognized when power on with attached device - Fix xfer failed with disconnected device as stalled - Fix error on EHCI causes xfer error in non-queued qhd which cause memory fault - Un-roll recursive hub removal with usbh queue - Fix issue when removing queue head - Implement ``hcd_edpt_abort_xfer()`` - use standard USB complete interrupt instead of custom chipidea async/period interrupt to be more compatible with other ehci implementation - refactor usb complete & error isr processing, merge, update. Fix EHCI QHD reuses QTD on wrong endpoint - Improve bus reset, fix ``send_setup()`` not carried out if halted previously - Fix clear qhd halted bit if not caused by STALL protocol to allow for next transfer - ChipIdea Highspeed - Fix control transfer issue when previous status and new setup complete in the same isr frame - [imxrt] Add dcache support for cache region - ChipIdea Fullspeed - Generalize ChipIdea Fullspeed driver for mcxn9 (port 0), kinetis - nrf - Fix DMA race condition with ISO OUT transfer #1946 - Add support for nRF5340 with pca10095 board - Renesas rusb2 - Generalize rusb2 driver for ra, rx mcus - rework both dcd and hcd for better multiple ports support - Add support for board with HS USB port: ra6m5 port1 - rp2040 - [dcd] Make writes to SIE_CTRL aware of concurrent access - [hcd] add ``hcd_frame_number()``, ``hcd_edpt_abort_xfer()`` for pio-usb host - stm32 fsdev: - Add STM32L5 support - Implement ``dcd_edpt_iso_alloc()`` and ``dcd_edpt_iso_activate()`` - OHCI - Allows configurable root hub ports, handles SMM mode (Ref OHCI spec 5.1.1.3.3) and Bios mode (Ref OHCI spec 5.1.1.3.4) - Fix FrameIntervalToggle must be toggled after we write the FrameInterval (Ref OHCI Spec 7.3.1) - Wait PowerOnToPowerGoodTime after we enable power of the RH ports (Ref OHCI Spec 7.4.1) - Generate port interrupts for devices already connected during init. - Fix issue when removing queue head - Disable MIE during IRQ processing and clear HccaDoneHead on completion as per OCHI Spec Page 80 Device Stack ------------ - Add optional hooks ``tud_event_hook_cb()`` - Audio (UAC2) - Fix feedback EP buffer alignment. - Fix encoding, update example - Improve IN transfer - Bluetooth - Add historical EP compatibility for Bluetooth HCI - CDC - Fix line_coding alignment - Fix typo in cdc line coding enum - MIDI - Fix ``stream_write()`` always writes system messages to cable 0 - Fix incorrect NOTE_ON, NOTE_OFF definitions - USBTMC: Fix tmc488 bit order - Vendor: fix ``read()``/``write()`` race condition - Video (UVC) - Add the capability for video class to handle a bulk endpoint in the streaming interface. Host Stack ---------- - USBH - Add new APIs: ``tuh_interface_set()``, ``tuh_task_event_ready()``, ``tuh_edpt_abort_xfer()``, ``tuh_rhport_reset_bus()``, ``tuh_rhport_is_active()`` - Fix issue when device generate multiple attach/detach/attach when plugging in - Prefer application callback over built-in driver on transfer complete event - Correct ``hcd_edpt_clear_stall()`` API signature - Separate bus reset delay and contact debouncing delay in enumeration - Support ``usbh_app_driver_get_cb()`` for application drivers - Fix usbh enumeration removal race condition - Add optional hooks ``tuh_event_hook_cb()`` - CDC - Breaking: change ``tuh_cdc_itf_get_info()`` to use tuh_itf_info_t instead of tuh_cdc_info_t - Fix cdc host enumeration issue when device does not support line request - Add support for vendor usb2uart serial: ftdi, cp210x, ch9102f - Improve sync control API e.g ``tuh_cdc_set_control_line_state()``, ``tuh_cdc_set_line_coding()`` - HID - Add new APIs ``tuh_hid_send_report()``, ``tuh_hid_itf_get_info()``, ``tuh_hid_receive_ready()``, ``tuh_hid_send_ready()``, ``tuh_hid_set_default_protocol()`` - Change meaning of CFG_TUH_HID to total number of HID interfaces supported. Previously ``CFG_TUH_HID`` is max number of interfaces per device which is rather limited and consume more resources than needed. - HUB - Fix handling of empty "status change" interrupt - Fix issue with hub status_change is not aligned - MSC - Fix bug in ``tuh_msc_ready()`` - Fix host msc get maxlun not using aligned section memory 0.15.0 ====== - Add codespell to detect typo - Add support for fuzzing and bagde for oss-fuzz - [osal] - Allow the use of non-static allocation for FreeRTOS - Fix FreeRTOS wrong task switch in some cases - Fix tu_fifo memory overflown when repeatedly write to overwritable fifo (accumulated more than 2 depths) - Better support for IAR (ARM) with ci build check for stm32 mcus. - Fix Windows build for some mingw gnu make situations Controller Driver (DCD & HCD) ----------------------------- - Add new port support (WIP) for WCH CH32V307 USB Highspeed - Add new port support (WIP) for PIC32MM/MX & PIC24 - [nRF] - Fix endpoint internal state when closed - Fix reception of large ISO packets - [rp2040] - [dcd] Implement workaround for Errata 15. This enable SOF when bulk-in endpoint is in use and reduce its bandwidth to only 80% - [hcd] Fix shared irq slots filling up when ``hcd_init()`` is called multiple times - [hcd] Support host bulk endpoint using hw "interrupt" endpoint. Note speed limit is 64KB/s - [samd][dcd] Add support for ISO endpoint - [dwc2][dcd] Add support for stm32u5xx - [esp32sx] Fix Isochronous transfers only transmitted on even frame - [lpc_ip3511][dcd] Add isochronous support and fix endpoint accidental write - [ft90x] Improve and enhance support for FT9xx MCU, tested with more examples Device Stack ------------ - [Video] - Add support for MJPEG - Fix probe on macOS - [MIDI] - Support port name strings - fix MS Header wTotalLength computation - [HID] - Add FIDO descriptor template - change length in ``tud_hid_report_complete_cb()`` from ``uint8_t`` to ``uint16_t`` - [CDC] - Fix autoflush for FIFO < MPS - Fix tx fifo memory overflown when DTR is not set and ``tud_cdc_write()`` is called repeatedly with large enough data - [USBTMC] Fix packet size with highspeed Host Stack ---------- - Retry a few times with transfers in enumeration since device can be unstable when starting up - [MSC] Rework host masstorage API. Add new ``host/msc_file_explorer`` example - [CDC] - Add support for host cdc - Fix host cdc with device without IAD e.g Arduino Due 0.14.0 ====== - Improve compiler support for CCRX and IAR - Add timeout to ``osal_queue_receive()`` - Add ``tud_task_ext(timeout, in_isr)`` as generic version of ``tud_task()``. Same as ``tuh_task_ext()``, ``tuh_task()`` - Enable more warnings ``-Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls -Wconversion`` - Add new examples - ``host/bare_api`` to demonstrate generic (app-level) enumeration and endpoint transfer - ``dual/host_hid_to_device_cdc`` to run both device and host stack concurrently, get HID report from host and print out to device CDC. This example only work with multiple-controller MCUs and rp2040 with the help of pio-usb as added controller. Controller Driver (DCD & HCD) ----------------------------- - Enhance rhports management to better support dual roles - ``CFG_TUD_ENABLED``/``CFG_TUH_ENABLED``, ``CFG_TUD_MAX_SPEED``/``CFG_TUH_MAX_SPEED`` can be used to replace ``CFG_TUSB_RHPORT0_MODE``/``CFG_TUSB_RHPORT1_MODE`` - ``tud_init(rphort)``, ``tuh_init(rhport)`` can be used to init stack on specified roothub port (controller) instead of ``tusb_init(void)`` - Add dcd/hcd port specific defines ``TUP_`` (stand for tinyusb port-specific) - [dwc2] - Update to support stm32 h72x, h73x with only 1 otg controller - Fix overwrite with grstctl when disable endpoint - [EHCI] Fix an issue with EHCI driver - [msp430] Fix for possible bug in msp430-elf-gcc 9.3.0 - [nrf5x] Fix DMA access race condition using atomic function - [pic32] Fix PIC32 santiy - [rp2040] - Add PICO-PIO-USB as controller (device/host) support for rp2040 - Use shared IRQ handlers, so user can also hook the USB IRQ - Fix resumed signal not reported to device stack - [stm32fsdev] Add support for stm32wb55 Device Stack ------------ - [Audio] Add support for feedback endpoint computation - New API ``tud_audio_feedback_params_cb()``, ``tud_audio_feedback_interval_isr()``. - Supported computation method are: frequency with fixed/float or power of 2. Feedback with fifo count is not yet supported. - Fix nitfs (should be 3) in ``TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR`` - Fix typo in ``audiod_rx_done_cb()`` - [DFU] Fix coexistence with other interfaces BTH, RNDIS - [MSC] Fix inquiry response additional length field - [Venndor] Improve write performance Host Stack ---------- - Add new API ``tuh_configure(rhport, cfg_id, cfg_param)`` for dynamnic port specific behavior configuration - [HID] Open OUT endpoint if available - [Hub] hub clear port and device interrupts - [USBH] Major improvement - Rework usbh control transfer with complete callback. New API ``tuh_control_xfer()`` though still only carry 1 usbh (no queueing) at a time. - Add generic endpoint transfer with ``tuh_edpt_open()``, ``tuh_edpt_xfer()``. Require ``CFG_TUH_API_EDPT_XFER=1`` - Support app-level enumeration with new APIs - ``tuh_descriptor_get()``, ``tuh_descriptor_get_device()``, ``tuh_descriptor_get_configuration()``, ``tuh_descriptor_get_hid_report()`` - ``tuh_descriptor_get_string()``, ``tuh_descriptor_get_manufacturer_string()``, ``tuh_descriptor_get_product_string()``, ``tuh_descriptor_get_serial_string()`` - Also add ``_sync()`` as sync/blocking version for above APIs 0.13.0 ====== - [tu_fifo] Fix locked mutex when full, and return type in ``peek_n()`` Controller Driver (DCD & HCD) ----------------------------- - [DWC2] Generalize synopsys dwc2 with synopsys/dwc2 which support both FS and HS phy (UTMI and ULPI) for various MCUs. - Broadcom 28/27xx on raspberrypi SBC - Silicon Labs EFM32 - Espressif ESP32 Sx - GigaDevice GD32 - ST STM32 - Infineon XMC - [KL25] Add new HCD for NXP KL25 - [MUSB] Add new DCD and HCD for Mentor musb with TI MSP432E4 - [F1C100s] Add new DCD for Allwinner F1C100s family - [PIC32MZ] Add new DCD for PIC32MZ - [nRF] Fix/Enhance various race condition with: EASY DMA, request HFXO, EPOUT - [ChipIdea] rename Transdimension to more popular ChipIdea Highspeed, - [RP2040] various update/fix for hcd/dcd - [FT9XX] new DCD port for Bridgetek FT90x and FT93x devices - [DA1469X] Fix resume - [OHCI] Fix device array out of bound Note: legacy drivers such as st/synopsys, nxp/transdimension are still present in this release but won't receive more update and could be removed in the future. Device Stack ------------ - [Audio] Support disabling feedback format correction (16.16 <-> 10.14 format) - [MSC] Add ``tud_msc_request_sense_cb()`` callback, change most default sense error to medium not present (0x02, 0x3A, 0x00) - [Video] Fix video_capture example fails enumeration when 8FPS Host Stack ---------- No notable changes 0.12.0 ====== - add ``CFG_TUSB_OS_INC_PATH`` for os include path Device Controller Driver (DCD) ------------------------------ - Getting device stack to pass USB Compliance Verification test (chapter9, HID, MSC). Ports are tested: nRF, SAMD 21/51, rp2040, stm32f4, Renesas RX, iMXRT, ESP32-S2/3, Kinetic KL25/32, DA146xx - Added ``dcd_edpt_close_all()`` for switching configuration - [Transdimension] Support ``dcd_edpt_xfer_fifo()`` with auto wrap over if fifo buffer is 4K aligned and size is multiple of 4K. - [DA146xx] Improve vbus, reset, suspend, resume detection, and remote wakeup. Device Stack ------------ - Add new network driver Network Control Model (CDC-NCM), update ``net_lwip_webserver`` to work with NCM (need re-configure example) - Add new USB Video Class UVC 1.5 driver and video_capture example (work in progress) - Fix potential buffer overflow for HID, bluetooth drivers Host Controller Driver (HCD) ---------------------------- No notable changes Host Stack ---------- No notable changes 0.11.0 (2021-08-29) =================== - Add host/hid_controller example: only worked/tested with Sony PS4 DualShock controller - Add device/hid_boot_interface example - Add support for Renesas CCRX toolchain for RX mcu Device Controller Driver (DCD) ------------------------------ - Add new DCD port for SAMx7x (E70, S70, V70, V71) - Add new mcu K32L2Bxx - Add new mcu GD32VF103 - Add new mcu STM32l151 - Add new mcu SAML21 - Add new mcu RX65n RX72n - Fix NUC120/121/126 USBRAM can only be accessed in byte manner. Also improve set_address & disable sof - Add Suspend/Resume handling for Renesas RX family. - Fix DA1469x no VBUS startup Synopsys ^^^^^^^^ - Fix Synopsys set address bug which could cause re-enumeration failed - Fix ``dcd_synopsys`` driver integer overflow in HS mode (issue #968) nRF5x ^^^^^ - Add nRF5x suspend, resume and remote wakeup - Fix nRF5x race condition with ``TASKS_EP0RCVOUT`` RP2040 ^^^^^^ - Add RP2040 suspend & resume support - Implement double buffer for both host and device (#891). However device EPOUT is still single buffered due to techinical issue with short packet Device Stack ------------ USBD ^^^^ - Better support big endian mcu - Add ``tuh_inited()`` and ``tud_inited()``, will separate ``tusb_init/inited()`` to ``tud/tuh_init/inited()`` - Add ``dcd_attr.h`` for defining common controller attribute such as max endpoints Bluetooth ^^^^^^^^^ - Fix stridx error in descriptor template DFU ^^^ - Enhance DFU implementation to support multiple alternate interface and better support ``bwPollTimeout`` - Rename ``CFG_TUD_DFU_MODE`` to simply ``CFG_TUD_DFU`` HID ^^^ - Fix newline usage keyboard (ENTER 0x28) - Better support Hid Get/Set report - Change max gamepad support from 16 to 32 buttons MIDI ^^^^ - Fix midi available - Fix midi data - Fix an issue when calling midi API when not enumerated yet UAC2 ^^^^ - Fix bug and enhance of UAC2 Vendor ^^^^^^ - Fix vendor fifo deadlock in certain case - Add ``tud_vendor_n_read_flush()`` Host Controller Driver (HCD) ---------------------------- RP2040 ^^^^^^ - Implement double buffered to fix E4 errata and boost performance - Lots of rp2040 update and enhancement Host Stack ---------- - Major update and rework most of host stack, still needs more improvement - Lots of improvement and update in parsing configuration and control - Rework and major update to HID driver. Will default to enable boot interface if available - Separate ``CFG_TUH_DEVICE_MAX`` and ``CFG_TUH_HUB`` for better management and reduce SRAM usage 0.10.1 (2021-06-03) =================== - rework rp2040 examples and CMake build, allow better integration with pico-sdk Host Controller Driver (HCD) ---------------------------- - Fix rp2040 host driver: incorrect PID with low speed device with max packet size of 8 bytes - Improve hub driver - Remove obsolete ``hcd_pipe_queue_xfer()``/``hcd_pipe_xfer()`` - Use ``hcd_frame_number()`` instead of micro frame - Fix OHCI endpoint address and ``xferred_bytes`` in xfer complete event 0.10.0 (2021-05-28) =================== - Rework tu_fifo_t with separated mutex for read and write, better support DMA with read/write buffer info. And constant address mode - Improve audio_test example and add audio_4_channel_mic example - Add new dfu example - Remove pico-sdk from submodule Device Controller Driver (DCD) ------------------------------ - Add new DCD port for Silabs EFM32GG12 with board Thunderboard Kit (SLTB009A) - Add new DCD port Renesas RX63N, board GR-CITRUS - Add new (optional) endpoint API dcd_edpt_xfer_fifo - Fix build with nRF5340 - Fix build with lpc15 and lpc54 - Fix build with lpc177x_8x - STM32 Synopsys: greatly improve Isochronous transfer with ``edpt_xfer_fifo()`` API - Support LPC55 port1 highspeed - Add support for Espressif esp32s3 - nRF: fix race condition that could cause drop packet of Bulk OUT transfer USB Device Driver (USBD) ------------------------ - Add new (optional) endpoint ADPI ``usbd_edpt_xfer_fifo()`` Device Class Driver ------------------- CDC - [Breaking] ``tud_cdc_peek()``, ``tud_vendor_peek()`` no longer support random offset and dropped position parameter. DFU - Add new DFU 1.1 class driver (WIP) HID - Fix keyboard report descriptor template - Add more hid keys constant from 0x6B to 0xA4 - [Breaking] rename API - ``HID_PROTOCOL_NONE/KEYBOARD/MOUSE`` to ``HID_ITF_PROTOCOL_NONE/KEYBOARD/MOUSE`` - ``tud_hid_boot_mode()`` to ``tud_hid_get_protocol()`` - ``tud_hid_boot_mode_cb()`` to ``tud_hid_set_protocol_cb()`` MIDI - Fix MIDI buffer overflow issue - [Breaking] rename API - Rename ``tud_midi_read()`` to ``tud_midi_stream_read()`` - Rename ``tud_midi_write()`` to ``tud_midi_stream_write()`` - Rename ``tud_midi_receive()`` to ``tud_midi_packet_read()`` - Rename ``tud_midi_send()`` to ``tud_midi_packet_write()`` Host Controller Driver (HCD) ---------------------------- - No noticeable changes USB Host Driver (USBH) ---------------------- - No noticeable changes Host Class Driver ----------------- - HID: Rework host hid driver, basically everything changes 0.9.0 (2021-03-12) ================== Device Stack ------------ Device Controller Driver (DCD) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RP2040 - Fix endpoint buffer reallocation overrun problem - Fix osal_pico queue overflow in initialization - Fix Isochronous endpoint buffer size in transfer - Optimize hardware endpoint struct to reduce RAM usage - Fix enum walkaround forever check for SE0 when pull up is disabled Sony CXD56 - Pass the correct speed on Spresense - Fix setup processed flag NXP Transdimention - Update dcd_init() to reset controller to device mode USB Device Driver (USBD) ^^^^^^^^^^^^^^^^^^^^^^^^ - Fix issue with status zlp (``tud_control_status()``) is returned by class driver with SET/CLEAR_FEATURE for endpoint. - Correct endpoint size check for fullspeed bulk, can be 8, 16, 32, 64 - Ack SET_INTERFACE even if it is not implemented by class driver. Device Class Driver ^^^^^^^^^^^^^^^^^^^ DFU Runtime - rename ``dfu_rt()`` to ``dfu_runtime()`` for easy reading CDC - Add ``tud_cdc_send_break_cb()`` to support break request - Improve CDC receive, minor behavior changes: when ``tud_cdc_rx_wanted_cb()`` is invoked wanted_char may not be the last byte in the fifo HID - [Breaking] Add itf argument to hid API to support multiple instances, follow API has signature changes - ``tud_hid_descriptor_report_cb()`` - ``tud_hid_get_report_cb()`` - ``tud_hid_set_report_cb()`` - ``tud_hid_boot_mode_cb()`` - ``tud_hid_set_idle_cb()`` - Add report complete callback ``tud_hid_report_complete_cb()`` API - Add DPad/Hat support for HID Gamepad - ``TUD_HID_REPORT_DESC_GAMEPAD()`` now support 16 buttons, 2 joysticks, 1 hat/dpad - Add ``hid_gamepad_report_t`` along with ``GAMEPAD_BUTTON_`` and ``GAMEPAD_HAT_`` enum - Add Gamepad to ``hid_composite`` / ``hid_composite_freertos`` example MIDI - Fix dropping MIDI sysex message when fifo is full - Fix typo in ``tud_midi_write24()``, make example less ambiguous for cable and channel - Fix incorrect endpoint descriptor length, MIDI v1 use Audio v1 which has 9-byte endpoint descriptor (instead of 7) Host Stack ---------- Host Controller Driver (HCD) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add rhport to ``hcd_init()`` - Improve EHCI/OHCI driver abstraction - Move echi/ohci files to portable/ - Rename ``hcd_lpc18_43`` to ``hcd_transdimension`` - Sub hcd API with ``hcd_ehci_init()``, ``hcd_ehci_register_addr()`` - Update NXP transdimension ``hcd_init()`` to reset controller to host mode - Ported hcd to rt10xx USB Host Driver (USBH) ^^^^^^^^^^^^^^^^^^^^^^ - No noticeable changes to usbh Host Class Driver ^^^^^^^^^^^^^^^^^ MSC - Rename ``tuh_msc_scsi_inquiry()`` to ``tuh_msc_inquiry()`` - Rename ``tuh_msc_mounted_cb()``/``tuh_msc_unmounted_cb()`` to ``tuh_msc_mount_cb()``/``tuh_msc_unmount_cb()`` to match device stack naming - Change ``tuh_msc_is_busy()`` to ``tuh_msc_ready()`` - Add read10 and write10 function: ``tuh_msc_read10()``, ``tuh_msc_write10()`` - Read_Capacity is invoked as part of enumeration process - Add ``tuh_msc_get_block_count()``, ``tuh_msc_get_block_size()`` - Add ``CFG_TUH_MSC_MAXLUN`` (default to 4) to hold lun capacities Others ------ - Add basic support for rt-thread OS - Change zero bitfield length to more explicit padding - Build example now fetch required submodules on the fly while running ``make`` without prior submodule init for mcu drivers - Update pico-sdk to v1.1.0 **New Boards** - Microchip SAM E54 Xplained Pro - LPCXpresso 55s28 - LPCXpresso 18s37 0.8.0 (2021-02-05) ================== Device Controller Driver ------------------------ - Added new device support for Raspberry Pi RP2040 - Added new device support for NXP Kinetis KL25ZXX - Use ``dcd_event_bus_reset()`` with link speed to replace bus_signal - ESP32-S2: - Add bus suspend and wakeup support - SAMD21: - Fix (walkaround) samd21 setup_packet overflow by USB DMA - STM32 Synopsys: - Rework USB FIFO allocation scheme and allow RX FIFO size reduction - Sony CXD56 - Update Update Spresense SDK to 2.0.2 - Fix dcd issues with setup packets - Correct EP number for cdc_msc example USB Device ---------- **USBD** - Rework usbd control transfer to have additional stage parameter for setup, data, status - Fix ``tusb_init()`` return true instead of ``TUSB_ERROR_NONE`` - Added new API ``tud_connected()`` that return true after device got out of bus reset and received the very first setup packet **Class Driver** - CDC - Allow to transmit data, even if the host does not support control line states i.e set DTR - HID - change default ``CFG_TUD_HID_EP_BUFSIZE`` from 16 to 64 - MIDI - Fix midi sysex sending bug - MSC - Invoke only scsi complete callback after status transaction is complete. - Fix ``scsi_mode_sense6_t`` padding, which cause IAR compiler internal error. - USBTMC - Change interrupt endpoint example size to 8 instead of 2 for better compatibility with mcu **Example** - Support make from windows ``cmd.exe`` - Add HID Consumer Control (media keys) to ``hid_composite`` & ``hid_composite_freertos`` examples USB Host -------- No noticeable changes to host stack New Boards ---------- - NXP/Freescale Freedom FRDM-KL25Z - Feather Double M33 express - Raspberry Pi Pico - Adafruit Feather RP2040 - Adafruit Itsy Bitsy RP2040 - Adafruit QT RP2040 - Adfruit Feather ESP32-S2 - Adafruit Magtag 29" Eink - Adafruit Metro ESP32-S2 - Adafruit PyBadge - Adafruit PyPortal - Great Scott Gadgets' LUNA D11 & D21 0.7.0 (2020-11-08) ================== Device Controller Driver ------------------------ - Added new support for Espressif ESP32-S2 - Added new support for Dialog DA1469x - Enhance STM32 Synopsys - Support bus events disconnection/suspend/resume/wakeup - Improve transfer performance with optimizing xfer and fifo size - Support Highspeed port (OTG_HS) with both internal and external PHY - Support multiple usb ports with rhport=1 is highspeed on selected MCUs e.g H743, F23. It is possible to have OTG_HS to run on Fullspeed PHY (e.g lacking external PHY) - Add ISO transfer, fix odd/even frame - Fix FIFO flush during stall - Implement ``dcd_edpt_close()`` API - Support F105, F107 - Enhance STM32 fsdev - Improve dcd fifo allocation - Fix ISTR race condition - Support remap USB IRQ on supported MCUs - Implement ``dcd_edpt_close()`` API - Enhance NUC 505: enhance set configure behavior - Enhance SAMD - Fix race condition with setup packet - Add SAMD11 option ``OPT_MCU_SAMD11`` - Add SAME5x option ``OPT_MCU_SAME5X`` - Fix SAMG control data toggle and stall race condition - Enhance nRF - Fix hanged when ``tud_task()`` is called within critical section (disabled interrupt) - Fix disconnect bus event not submitted - Implement ISO transfer and ``dcd_edpt_close()`` USB Device ---------- **USBD** - Add new class driver for **Bluetooth HCI** class driver with example can be found in [mynewt-tinyusb-example](https://github.com/hathach/mynewt-tinyusb-example) since it needs mynewt OS to run with. - Fix USBD endpoint usage racing condition with ``usbd_edpt_claim()``/``usbd_edpt_release()`` - Added ``tud_task_event_ready()`` and ``osal_queue_empty()``. This API is needed to check before enter low power mode with WFI/WFE - Rename USB IRQ Handler to ``dcd_int_handler()``. Application must define IRQ handler in which it calls this API. - Add ``dcd_connect()`` and ``dcd_disconnect()`` to enable/disable internal pullup on D+/D- on supported MCUs. - Add ``usbd_edpt_open()`` - Remove ``dcd_set_config()`` - Add ``OPT_OS_CUMSTOM`` as hook for application to overwrite and/or add their own OS implementation - Support SET_INTERFACE, GET_INTERFACE request - Add Logging for debug with optional uart/rtt/swo printf retarget or ``CFG_TUSB_DEBUG_PRINTF`` hook - Add IAR compiler support - Support multiple configuration descriptors. ``TUD_CONFIG_DESCRIPTOR()`` template has extra config_num as 1st argument - Improve USB Highspeed support with actual link speed detection with ``dcd_event_bus_reset()`` - Enhance class driver management - ``usbd_driver_open()`` add max length argument, and return length of interface (0 for not supported). Return value is used for finding appropriate driver - Add application implemented class driver via ``usbd_app_driver_get_cb()`` - IAD is handled to assign driver id - Added ``tud_descriptor_device_qualifier_cb()`` callback - Optimize ``tu_fifo`` bulk write/read transfer - Forward non-std control request to class driver - Let application handle Microsoft OS 1.0 Descriptors (the 0xEE index string) - Fix OSAL FreeRTOS yield from ISR **Class Drivers** - USBNET: remove ACM-EEM due to lack of support from host - USBTMC: fix descriptors when INT EP is disabled - CDC: - Send zero length packet for end of data when needed - Add ``tud_cdc_tx_complete_cb()`` callback - Change ``tud_cdc_n_write_flush()`` return number of bytes forced to transfer, and flush when writing enough data to fifo - MIDI: - Add packet interface - Add multiple jack descriptors - Fix MIDI driver for sysex - DFU Runtime: fix response to SET_INTERFACE and DFU_GETSTATUS request - Rename some configure macro to make it clear that those are used directly for endpoint transfer - ``CFG_TUD_HID_BUFSIZE`` to ``CFG_TUD_HID_EP_BUFSIZE`` - ``CFG_TUD_CDC_EPSIZE`` to ``CFG_TUD_CDC_EP_BUFSIZE`` - ``CFG_TUD_MSC_BUFSIZE`` to ``CFG_TUD_MSC_EP_BUFSIZE`` - ``CFG_TUD_MIDI_EPSIZE`` to ``CFG_TUD_MIDI_EP_BUFSIZE`` - HID: - Fix gamepad template descriptor - Add multiple HID interface API - Add extra comma to HID_REPORT_ID USB Host -------- - Rework USB host stack (still work in progress) - Fix compile error with pipehandle - Rework usbh control and enumeration as non-blocking - Improve Hub, MSC, HID host driver Examples -------- - Add new ``hid_composite_freertos`` - Add new ``dynamic_configuration`` to demonstrate how to switch configuration descriptors - Add new ``hid_multiple_interface`` - Enhance ``net_lwip_webserver`` example - Add multiple configuration: RNDIS for Windows, CDC-ECM for macOS (Linux will work with both) - Update lwip to STABLE-2_1_2_RELEASE for ``net_lwip_webserver`` - Added new Audio example: ``audio_test`` ``uac2_headsest`` New Boards ---------- - Espressif ESP32-S2: saola_1, kaluga_1 - STM32: F746 Nucleo, H743 Eval, H743 Nucleo, F723 discovery, stlink v3 mini, STM32L4r5 Nucleo - Dialog DA1469x dk pro and dk usb - Microchip: Great Scoot Gadgets' LUNA, samd11_xplained, D5035-01, atsamd21 xplained pro - nRF: ItsyBitsy nRF52840 0.6.0 (2020-03-30) ================== Added **CONTRIBUTORS.md** to give proper credit for contributors to the stack. Special thanks to `Nathan Conrad `__ , `Peter Lawrence `__ , `William D. Jones `__ and `Sean Cross `__ and others for spending their precious time to add lots of features and ports for this release. Added ----- **MCU** - Added support for Microchip SAMG55 - Added support for Nordic nRF52833 - Added support for Nuvoton: NUC120, NUC121/NUC125, NUC126, NUC505 - Added support for NXP LPC: 51Uxx, 54xxx, 55xx - Added support for NXP iMXRT: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064 - Added support for Sony CXD56 (Spresense) - Added support for STM32: L0, F0, F1, F2, F3, F4, F7, H7 - Added support for TI MSP430 - Added support for ValentyUSB's eptri **Class Driver** - Added DFU Runtime class driver - Added Network class driver with RNDIS, CDC-ECM, CDC-EEM (work in progress) - Added USBTMC class driver - Added WebUSB class driver using vendor-specific class - Added multiple instances support for CDC and MIDI - Added a handful of unit test with Ceedling. - Added LOG support for debugging with CFG_TUSB_DEBUG - Added ``tud_descriptor_bos_cb()`` for BOS descriptor (required for USB 2.1) - Added ``dcd_edpt0_status_complete()`` as optional API for DCD **Examples** Following examples are added: - ``board_test`` - ``cdc_dual_ports`` - ``dfu_rt`` - ``hid_composite`` - ``net_lwip_webserver`` - ``usbtmc`` - ``webusb_serial`` Changed ------- - Changed ``tud_descriptor_string_cb()`` to have additional Language ID argument - Merged ``hal_nrf5x.c`` into ``dcd_nrf5x.c`` - Merged ``dcd_samd21.c`` and ``dcd_samd51.c`` into ``dcd_samd.c`` - Generalized ``dcd_stm32f4.c`` to ``dcd_synopsys.c`` - Changed ``cdc_msc_hid`` to ``cdc_msc`` (drop hid) due to limited endpoints number of some MCUs - Improved DCD SAMD stability, fix missing setup packet occasionally - Improved ``usbd/usbd_control`` with proper handling of zero-length packet (ZLP) - Improved STM32 DCD FSDev - Improved STM32 DCD Synopsys - Migrated CI from Travis to Github Action - Updated nrfx submodule to 2.1.0 - Fixed mynewt osal queue definition - Fixed ``cdc_msc_freertos`` example build for all MCUs 0.5.0 (2019-06) =============== First release, device stack works great, host stack works but still need improvement. - Special thanks to @adafruit team, especially @tannewt to help out immensely to rework device stack: simplify osal & control transfer, adding SAMD21/SAMD51 ports, writing porting docs, adding MIDI class support etc... - Thanks to @cr1901 for adding STM32F4 port. - Thanks to @PTS93 and @todbot for HID raw API ================================================ FILE: docs/info/code_of_conduct.rst ================================================ .. include:: ../../CODE_OF_CONDUCT.rst ================================================ FILE: docs/info/contributors.rst ================================================ .. include:: ../../CONTRIBUTORS.rst ================================================ FILE: docs/info/index.rst ================================================ **** Info **** Index ===== .. toctree:: :maxdepth: 2 changelog contributors code_of_conduct ================================================ FILE: docs/integration.rst ================================================ ******************* Integrating TinyUSB ******************* Once you've seen TinyUSB working in the examples, use this guide to wire the stack into your own firmware. Integration Steps ================= 1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb``. 2. **Add source files**: Add every ``.c`` file from ``tinyusb/src/`` to your project build system. .. note:: Only supported dcd/hcd drivers for your CPU sources under ``tinyusb/src/portable/vendor/usbip/`` are needed. Add 3. **Configure TinyUSB**: Create ``tusb_config.h`` with macros such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS``, and class enable flags. Start from any example's ``tusb_config.h`` and tweak. 4. **Configure include paths**: Add ``your_project/tinyusb/src`` (and the folder holding ``tusb_config.h``) to your include paths. 5. **Implement USB descriptors**: For device stack, implement the ``tud_descriptor_*_cb()`` callbacks (device) or host descriptor helpers that match your product. 6. **Initialize TinyUSB**: Call ``tusb_init()`` once the clocks/peripherals are ready. Pass ``tusb_rhport_init_t`` if you need per-port settings. 7. **Handle interrupts**: From the USB ISR call ``tusb_int_handler(rhport, true)`` so the stack can process events. 8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) regularly from the main loop, RTOS task. 9. **Implement class callbacks**: Provide the callbacks for the classes you enabled (e.g., ``tud_cdc_rx_cb()``, ``tuh_msc_mount_cb()``). Minimal Example =============== .. code-block:: c #include "tusb.h" int main(void) { board_init(); // Your board initialization // Init device stack on roothub port 0 for highspeed device tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_HIGH }; tusb_init(0, &dev_init); // init host stack on roothub port 1 for fullspeed host tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_FULL }; tusb_init(1, &host_init); while (1) { tud_task(); // device task tuh_task(); // host task app_task(); // Your application logic } } void USB0_IRQHandler(void) { // forward interrupt port 0 to TinyUSB stack tusb_int_handler(0, true); } void USB1_IRQHandler(void) { // forward interrupt port 1 to TinyUSB stack tusb_int_handler(1, true); } .. note:: Unlike many libraries, TinyUSB callbacks don't need to be registered. Implement functions with the prescribed names (for example ``tud_cdc_rx_cb()``) and the stack will invoke them automatically. .. note:: Naming follows ``tud_*`` for device APIs and ``tuh_*`` for host APIs. Refer to :doc:`reference/glossary` for a summary of the prefixes and callback naming rules. STM32CubeIDE Integration ======================== To integrate TinyUSB device stack with STM32CubeIDE 1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode 2. Enable the USB global interrupt in NVIC Settings 3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c 4. Call ``tud_task()`` in your main loop 5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` .. code-block:: c void OTG_FS_IRQHandler(void) { tud_int_handler(0); } 6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files .. tip:: STM32CubeIDE generated code conflicts with TinyUSB. Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. ================================================ FILE: docs/porting.rst ================================================ ******* Porting ******* TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for data transactions on different endpoints. Porting is the process of adding low-level support for the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support for the microcontroller to other projects, especially those already using TinyUSB such as CircuitPython. Below are instructions on how to get the cdc_msc device example running on a new microcontroller. Doing so includes adding the common code necessary for other uses while minimizing other extra code. Whenever you see a phrase or word in ``<>`` it should be replaced. Register defs ------------- The first step to adding support is including the register definitions and startup code for the microcontroller in TinyUSB. We write the TinyUSB implementation against these structs instead of higher level functions to keep the code small and to prevent function name collisions in linking of larger projects. For ARM microcontrollers this is the CMSIS definitions. They should be placed in the ``hw/mcu//`` directory. Once this is done, create a directory in ``hw/bsp/`` for the specific board you are using to test the code (duplicating an existing board's directory is the best way to get started). The board should be a readily available development board so that others can also test. Build ----- Now that those directories are in place, we can start our iteration process to get the example building successfully. To build, run from the root of TinyUSB: .. code-block:: bash make -C examples/device/cdc_msc BOARD= Unless you've read ahead, this will fail miserably. Now, lets get it to fail less by updating the files in the board directory. The code in the board's directory is responsible for setting up the microcontroller's clocks and pins so that USB works. TinyUSB itself only operates on the USB peripheral. The board directory also includes information what files are needed to build the example. One of the first things to change is the ``-DCFG_TUSB_MCU`` C flag in the ``board.mk`` file. This is used to tell TinyUSB what platform is being built. So, add an entry to ``src/tusb_option.h`` and update the ``CFLAGS`` to match. Update ``board.mk``'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from ``src/portable`` into ``src/portable//`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. Implementation -------------- At this point you should get an error due to an implementation issue and hopefully the build is setup for the new MCU. You will still need to modify the ``board.mk`` to include specific ``CFLAGS``, the linker script, linker flags, source files, include directories. All file paths are relative to the top of the TinyUSB repo. Board Support (BSP) ^^^^^^^^^^^^^^^^^^^ The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. Its responsible for getting the MCU started and the USB peripheral clocked. It also optionally provides LED definitions that are used to blink an LED to show that the code is running. It is located in ``hw/bsp//board_.c``. ``board_init()`` ~~~~~~~~~~~~~~~~ ``board_init()`` is responsible for starting the MCU, setting up the USB clock and USB pins. It is also responsible for initializing LED pins. One useful clock debugging technique is to set up a PWM output at a known value such as 500hz based on the USB clock so that you can verify it is correct with a logic probe or oscilloscope. Setup your USB in a crystal-less mode when available. That makes the code easier to port across boards. ``board_led_write()`` ~~~~~~~~~~~~~~~~~~~~~ Feel free to skip this until you want to verify your demo code is running. To implement, set the pin corresponding to the led to output a value that lights the LED when ``state`` is true. OS Abstraction Layer (OSAL) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The OS Abstraction Layer is responsible for providing basic data structures for TinyUSB that may allow for concurrency when used with an RTOS. Without an RTOS it simply handles concurrency issues between the main code and interrupts. The code is almost entirely agnostic of MCU and lives in ``src/osal``. In RTOS configurations, ``tud_task()``/``tuh_task()`` blocks behind a synchronization structure when the event queue is empty, so that the scheduler may give the CPU to a different task. To take advantage of the library's capability to yield the CPU when there are no actionable USB device events, ensure that the ``CFG_TUSB_OS`` symbol is defined, e.g ``OPT_OS_FREERTOS`` enables the FreeRTOS scheduler to schedule other threads than that which calls ``tud_task()``/``tuh_task()``. Device API ^^^^^^^^^^ After the USB device is setup, the USB device code works by processing events on the main thread (by calling ``tud_task()``). These events are queued by the USB interrupt handler. So, there are three parts to the device low-level API: device setup, endpoint setup and interrupt processing. All of the code for the low-level device API is in ``src/portable///dcd_.c``. Device Setup ~~~~~~~~~~~~ ``dcd_init()`` """""""""""""" Initializes the USB peripheral for device mode and enables it. This function should enable internal D+/D- pull-up for enumeration. ``dcd_int_enable()`` / ``dcd_int_disable()`` """""""""""""""""""""""""""""""""""""""""""" Enables or disables the USB device interrupt(s). May be used to prevent concurrency issues when mutating data structures shared between main code and the interrupt handler. ``dcd_int_handler()`` """"""""""""""""""""" Processes all the hardware generated events e.g Bus reset, new data packet from host etc ... It will be called by application in the MCU USB interrupt handler. ``dcd_set_address()`` """"""""""""""""""""" Called when the device is given a new bus address. If your peripheral automatically changes address during enumeration (like the nrf52) you may leave this empty and also no queue an event for the corresponding SETUP packet. ``dcd_remote_wakeup()`` """"""""""""""""""""""" Called to remote wake up host when suspended (e.g hid keyboard) ``dcd_connect()`` / ``dcd_disconnect()`` """""""""""""""""""""""""""""""""""""""" Connect or disconnect the data-line pull-up resistor. Define only if MCU has an internal pull-up. (BSP may define for MCU without internal pull-up.) Special events ~~~~~~~~~~~~~~ You must let TinyUSB know when certain events occur so that it can continue its work. There are a few methods you can call to queue events for TinyUSB to process. ``dcd_event_bus_signal()`` """""""""""""""""""""""""" There are a number of events that your peripheral may communicate about the state of the bus. Here is an overview of what they are. Events in **BOLD** must be provided for TinyUSB to work. * **DCD_EVENT_RESET** - Triggered when the host resets the bus causing the peripheral to reset. Do any other internal reset you need from the interrupt handler such as resetting the control endpoint. * DCD_EVENT_SOF - Signals the start of a new USB frame. Calls to this look like: .. code-block:: c dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); The first ``0`` is the USB peripheral number. Statically saying ``0`` is common for single USB device MCUs. The ``true`` indicates the call is from an interrupt handler and will always be the case when porting in this way. ``dcd_setup_received()`` """""""""""""""""""""""" SETUP packets are a special type of transaction that can occur at any time on the control endpoint, numbered ``0``. Since they are unique, most peripherals have special handling for them. Their data is always 8 bytes in length as well. Calls to this look like: .. code-block:: c dcd_event_setup_received(0, setup, true); As before with ``dcd_event_bus_signal()`` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. Endpoints ~~~~~~~~~ Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below. Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides ``tu_edpt_number()`` and ``tu_edpt_dir()`` to unpack this data from the address. Here is a snippet that does it. .. code-block:: c uint8_t epnum = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); ``dcd_edpt_open()`` """"""""""""""""""" Opening an endpoint is done for all non-control endpoints once the host picks a configuration that the device should use. At this point, the endpoint should be enabled in the peripheral and configured to match the endpoint descriptor. Pay special attention to the direction of the endpoint you can get from the helper methods above. It will likely change what registers you are setting. Also make sure to enable endpoint specific interrupts. ``dcd_edpt_close()`` """""""""""""""""""" .. warning:: This function is deprecated, ISO transfer should implement dcd_edpt_iso_alloc() and dcd_edpt_iso_activate() instead. Close an endpoint. his function is used for implementing alternate settings. After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. ``dcd_edpt_iso_alloc() / dcd_edpt_iso_activate()`` """""""""""""""""""""""""""""""""""""""""""""""""" dcd_edpt_iso_alloc() is used to allocate largest buffer (for all alternative interfaces) for ISO endpoints when device is enumerated. This allows DCD to allocate necessary resources for ISO endpoints in the future. dcd_edpt_iso_activate() is used to activate or deactivate ISO endpoint when alternate setting is set with active max packet size. ``dcd_edpt_xfer()`` """"""""""""""""""" ``dcd_edpt_xfer()`` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint number and direction which usually determines where to write the buffer info. The buffer and its length are usually written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a register or setting a counter register to 0 for OUT or length for IN.) The transmit buffer alignment is determined by ``CFG_TUSB_MEM_ALIGN``. One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track some state for yourself and queue up an intermediate USB packet from the interrupt handler. Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete()`` function is called. The ``dcd_edpt_xfer()`` function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, then it must be explicitly sent by the stack calling ``dcd_edpt_xfer()``, by calling ``dcd_edpt_xfer()`` a second time with len=0. For control transfers, this is automatically done in ``usbd_control.c``. At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new ``dcd_edpt_xfer()`` will not be called again on the same endpoint address until the driver calls ``dcd_xfer_complete()`` (except in cases of USB resets). ``dcd_xfer_complete()`` """"""""""""""""""""""" Once a transfer completes you must call ``dcd_xfer_complete()`` from the USB interrupt handler to let TinyUSB know that a transaction has completed. Here is a sample call: .. code-block:: c dcd_event_xfer_complete(0, ep_addr, xfer->actual_len, XFER_RESULT_SUCCESS, true); The arguments are: * the USB peripheral number * the endpoint address * the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer()``) * the result of the transfer. Failure isn't handled yet. * ``true`` to note the call is from an interrupt handler. ``dcd_edpt_stall()`` / ``dcd_edpt_clear_stall()`` """"""""""""""""""""""""""""""""""""""""""""""""" Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints. Woohoo! ------- At this point you should have everything working! 🙂 Of course, you may not write perfect code. Here are some tips and tricks for debugging. Use `WireShark `_ or `a Beagle `_ to sniff the USB traffic. When things aren't working its likely very early in the USB enumeration process. Figuring out where can help clue in where the issue is. For example: * If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly. * If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? 🙂) * If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task()`` may not be called.) If that's OK, the ``dcd_xfer_complete()`` may not be setting up the next transaction correctly. ================================================ FILE: docs/reference/architecture.rst ================================================ ************ Architecture ************ This document explains TinyUSB's internal architecture, design principles, and how different components work together. Design Principles ================= Memory Safety ------------- TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. Thread Safety ------------- TinyUSB achieves thread safety through a deferred interrupt model: - **ISR deferral**: USB interrupts are captured and deferred to task context - **Single-threaded processing**: All USB protocol handling occurs in task context - **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` - **RTOS integration**: Proper semaphore/mutex usage for shared resources Portability ----------- The stack is designed to work across diverse microcontroller families: - **Hardware abstraction**: MCU-specific code isolated in portable drivers - **OS abstraction**: RTOS dependencies isolated in OSAL layer - **Modular design**: Features can be enabled/disabled at compile time - **Standard compliance**: Strict adherence to USB specifications Core Architecture ================= Layer Structure --------------- TinyUSB follows a layered architecture from hardware to application: .. figure:: ../assets/stack.svg :width: 500px :align: left :alt: stackup .. raw:: html
Component Overview ------------------ - **Application Layer**: Your main application code that uses TinyUSB APIs. - **Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. - **Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. - **OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. - **Device/Host Controller Driver**: drivers that interface with MCU USB peripherals. Several MCUs may share a common driver. Device Stack Architecture ========================= This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). Core Components --------------- **Device Controller Driver (DCD)**: - MCU-specific USB device peripheral driver - Handles endpoint configuration and data transfers - Abstracts hardware differences between MCU families - Located in ``src/portable/VENDOR/USBIP/`` **USB Device Core (USBD)**: - Implements USB device state machine - Handles standard USB requests (Chapter 9) - Manages device configuration and enumeration - Located in ``src/device/`` **Class Drivers**: - Implement USB class specifications - Handle class-specific requests and data transfer - Provide application APIs - Located in ``src/class/*/`` Data Flow --------- **Control Transfers (Setup Requests)**: .. code-block:: none USB Bus → DCD → USBD Core → Class Driver → Application ↓ Standard requests handled in core ↓ Class-specific requests → Class Driver **Data Transfers**: .. code-block:: none Application → Class Driver → USBD Core → DCD → USB Bus USB Bus → DCD → USBD Core → Class Driver → Application Event Processing ---------------- TinyUSB uses a deferred interrupt model for thread safety: 1. **Interrupt Occurs**: USB hardware generates interrupt 2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing 3. **Event Queuing**: Events queued for later processing 4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events 5. **Callback Execution**: Application callbacks executed in task context .. code-block:: none USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application Host Stack Architecture ======================= This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. Core Components --------------- **Host Controller Driver (HCD)**: - MCU-specific USB host peripheral driver - Manages USB pipes and data transfers - Handles host controller hardware - Located in ``src/portable/VENDOR/FAMILY/`` **USB Host Core (USBH)**: - Implements USB host functionality - Manages device enumeration and configuration - Handles pipe management and scheduling - Located in ``src/host/`` **Hub Driver**: - Manages USB hub devices - Handles port management and device detection - Supports multi-level hub topologies - Located in ``src/host/`` Device Enumeration ------------------ The host stack follows USB enumeration process: 1. **Device Detection**: Hub or root hub detects device connection 2. **Reset and Address**: Reset device, assign unique address 3. **Descriptor Retrieval**: Get device, configuration, and class descriptors 4. **Driver Matching**: Find appropriate class driver for device 5. **Configuration**: Configure device and start communication 6. **Class Operation**: Normal class-specific communication .. code-block:: none Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate Class Architecture ================== Common Class Structure ---------------------- All USB classes follow a similar architecture: **Device Classes**: - ``*_device.c``: Device-side implementation - ``*_device.h``: Device API definitions - Implement class-specific descriptors - Handle class requests and data transfer **Host Classes**: - ``*_host.c``: Host-side implementation - ``*_host.h``: Host API definitions - Manage connected devices of this class - Provide application interface Class Driver Interface ---------------------- See ``usbd.c``. **Required Functions**: - ``init()``: Initialize class driver - ``reset()``: Reset class state - ``open()``: Configure class endpoints - ``control_xfer_cb()``: Handle control requests - ``xfer_cb()``: Handle data transfer completion **Optional Functions**: - ``close()``: Clean up class resources - ``deinit()``: Deinitialize class driver - ``sof()``: Start-of-frame processing - ``xfer_isr()``: Called from USB ISR context on transfer completion. Data will get queued for ``xfer_cb()`` only if this returns ``false``. Descriptor Management --------------------- Each class is responsible for: - **Interface Descriptors**: Define class type and endpoints - **Class-Specific Descriptors**: Additional class requirements - **Endpoint Descriptors**: Define data transfer characteristics Memory Management ================= Static Allocation Model ----------------------- TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. Buffer Management ----------------- **Endpoint Buffers**: - Allocated per endpoint at compile time - Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros - Used for USB data transfers **FIFO Buffers**: - Ring buffers for streaming data - Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros - Separate read/write pointers Threading Model =============== Task-Based Design ----------------- TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. RTOS Integration ---------------- **Bare Metal**: - Application calls ``tud_task()`` in main loop - No threading primitives needed - Simplest integration method **FreeRTOS**: - USB task runs at high priority - Semaphores used for synchronization - Queue for inter-task communication **Other RTOS**: - Similar patterns with RTOS-specific primitives - OSAL layer abstracts RTOS differences Interrupt Handling ------------------ **Interrupt Service Routine**: - Minimal processing in ISR - Event capture and queuing only - Quick return to avoid blocking **Deferred Processing**: - All complex processing in task context - Thread-safe access to data structures - Application callbacks in known context Memory Usage Patterns --------------------- **Flash Memory**: - Core stack: 8-15KB depending on features - Each class: 1-4KB additional - Portable driver: 2-8KB depending on MCU **RAM Usage**: - Core stack: 1-2KB - Endpoint buffers: User configurable - Class buffers: Depends on configuration ================================================ FILE: docs/reference/boards.rst ================================================ **************** Supported Boards **************** The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. It is responsible for getting the MCU started and the USB peripheral clocked with minimal of on-board devices - One LED : for status - One Button : to get input from user - One UART : needed for logging with LOGGER=uart, maybe required for host/dual examples Following boards are supported Analog Devices -------------- ============= ================ ======== ================================================================================================================= ====== Board Name Family URL Note ============= ================ ======== ================================================================================================================= ====== apard32690 APARD32690-SL maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html max32650evkit MAX32650 EVKIT maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650-evkit.html max32650fthr MAX32650 Feather maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650fthr.html max32651evkit MAX32651 EVKIT maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32651-evkit.html max32666evkit MAX32666 EVKIT maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666evkit.html max32666fthr MAX32666 Feather maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666fthr.html max32690evkit MAX32690 EVKIT maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32690evkit.html max78002evkit MAX78002 EVKIT maxim https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78002evkit.html ============= ================ ======== ================================================================================================================= ====== Artery ------ ========================= ============================= ============= ==================================================== ====== Board Name Family URL Note ========================= ============================= ============= ==================================================== ====== at_start_f402 AT-START-F402 at32f402_405 https://www.arterychip.com/en/product/AT32F402.jsp at_start_f405 AT-START-F405 at32f402_405 https://www.arterychip.com/en/product/AT32F405.jsp at32f403a_weact_blackpill WeAct BlackPill AT32F403ACGU7 at32f403a_407 https://github.com/WeActStudio/WeActStudio.BlackPill at_start_f403a AT-START-F403a at32f403a_407 https://www.arterychip.com/en/product/AT32F403.jsp at_start_f407 AT-START-F407 at32f403a_407 https://www.arterychip.com/en/product/AT32F407.jsp at_start_f413 AT-START-F413 at32f413 https://www.arterychip.com/en/product/AT32F413.jsp at_start_f415 AT-START-F415 at32f415 https://www.arterychip.com/en/product/AT32F415.jsp at_start_f423 AT-START-F423 at32f423 https://www.arterychip.com/en/product/AT32F423.jsp at_start_f425 AT-START-F425 at32f425 https://www.arterychip.com/en/product/AT32F425.jsp at_start_f435 AT-START-F435 at32f435_437 https://www.arterychip.com/en/product/AT32F435.jsp at_start_f437 AT-START-F437 at32f435_437 https://www.arterychip.com/en/product/AT32F437.jsp at_start_f455 AT-START-F455 at32f45x https://www.arterychip.com/en/product/AT32F455.jsp at_start_f456 AT-START-F456 at32f45x https://www.arterychip.com/en/product/AT32F456.jsp at_start_f457 AT-START-F457 at32f45x https://www.arterychip.com/en/product/AT32F457.jsp ========================= ============================= ============= ==================================================== ====== Bridgetek --------- ========= ========= ======== ===================================== ====== Board Name Family URL Note ========= ========= ======== ===================================== ====== mm900evxb MM900EVxB ft9xx https://brtchip.com/product/mm900ev1b ========= ========= ======== ===================================== ====== Espressif --------- ========================= ============================== ========= ======================================================================================================== ====== Board Name Family URL Note ========================= ============================== ========= ======================================================================================================== ====== adafruit_feather_esp32_v2 Adafruit Feather ESP32 v2 espressif https://www.adafruit.com/product/5400 adafruit_feather_esp32c6 Adafruit Feather EPS32-C6 espressif https://www.adafruit.com/product/5933 adafruit_feather_esp32s2 Adafruit Feather ESP32S2 espressif https://www.adafruit.com/product/5000 adafruit_feather_esp32s3 Adafruit Feather ESP32S3 espressif https://www.adafruit.com/product/5323 adafruit_magtag_29gray Adafruit MagTag 2.9" Grayscale espressif https://www.adafruit.com/product/4800 adafruit_metro_esp32s2 Adafruit Metro ESP32-S2 espressif https://www.adafruit.com/product/4775 espressif_addax_1 Espresif Addax-1 espressif n/a espressif_c3_devkitc Espresif C3 DevKitC espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c3/esp32-c3-devkitc-02/index.html espressif_c6_devkitc Espresif C6 DevKitC espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html espressif_kaluga_1 Espresif Kaluga 1 espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-kaluga-1/index.html espressif_p4_function_ev Espresif P4 Function EV espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html espressif_s2_devkitc Espresif S2 DevKitC espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-devkitc-1/index.html espressif_s3_devkitc Espresif S3 DevKitC espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitc-1/index.html espressif_s3_devkitm Espresif S3 DevKitM espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitm-1/index.html espressif_saola_1 Espresif S2 Saola 1 espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-saola-1/index.html ========================= ============================== ========= ======================================================================================================== ====== GigaDevice ---------- ================== ================== ========= ============================= ====== Board Name Family URL Note ================== ================== ========= ============================= ====== sipeed_longan_nano Sipeed Longan Nano gd32vf103 https://longan.sipeed.com/en/ ================== ================== ========= ============================= ====== HPMicro ------- =========== =========== ======== ========================================================================== ====== Board Name Family URL Note =========== =========== ======== ========================================================================== ====== hpm6750evk2 HPM6750EVK2 hpmicro https://hpm-sdk.readthedocs.io/en/v1.6.0/boards/hpm6750evk2/README_en.html =========== =========== ======== ========================================================================== ====== Infineon -------- ============= ================= ======== ============================================================================= ====== Board Name Family URL Note ============= ================= ======== ============================================================================= ====== xmc4500_relax XMC4500 relax kit xmc4000 https://www.infineon.com/cms/en/product/evaluation-boards/kit_xmc45_relax_v1/ xmc4700_relax XMC4700 relax kit xmc4000 https://www.infineon.com/cms/en/product/evaluation-boards/kit_xmc47_relax_v1/ ============= ================= ======== ============================================================================= ====== Microchip --------- ========================= =================================== ========== ================================================================================= ====== Board Name Family URL Note ========================= =================================== ========== ================================================================================= ====== olimex_emz64 Olimex PIC32-EMZ64 pic32mz https://www.olimex.com/Products/PIC/Development/PIC32-EMZ64/open-source-hardware olimex_hmz144 Olimex PIC32-HMZ144 pic32mz https://www.olimex.com/Products/PIC/Development/PIC32-HMZ144/open-source-hardware cynthion_d11 Great Scott Gadgets Cynthion samd11 https://greatscottgadgets.com/cynthion/ samd11_xplained SAMD11 Xplained Pro samd11 https://www.microchip.com/en-us/development-tool/ATSAMD11-XPRO atsamd21_xpro SAMD21 Xplained Pro samd2x_l2x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMD21-XPRO atsaml21_xpro SAML21 Xplained Pro samd2x_l2x https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b circuitplayground_express Adafruit Circuit Playground Express samd2x_l2x https://www.adafruit.com/product/3333 curiosity_nano SAMD21 Curiosty Nano samd2x_l2x https://www.microchip.com/en-us/development-tool/dm320119 cynthion_d21 Great Scott Gadgets Cynthion samd2x_l2x https://greatscottgadgets.com/cynthion/ feather_m0_express Adafruit Feather M0 Express samd2x_l2x https://www.adafruit.com/product/3403 itsybitsy_m0 Adafruit ItsyBitsy M0 samd2x_l2x https://www.adafruit.com/product/3727 metro_m0_express Adafruit Metro M0 Express samd2x_l2x https://www.adafruit.com/product/3505 qtpy Adafruit QT Py samd2x_l2x https://www.adafruit.com/product/4600 saml22_feather SAML22 Feather samd2x_l2x https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather seeeduino_xiao Seeeduino XIAO samd2x_l2x https://wiki.seeedstudio.com/Seeeduino-XIAO/ sensorwatch_m0 SensorWatch samd2x_l2x https://github.com/joeycastillo/Sensor-Watch sparkfun_samd21_mini_usb SparkFun SAMD21 Mini samd2x_l2x https://www.sparkfun.com/products/13664 trinket_m0 Adafruit Trinket M0 samd2x_l2x https://www.adafruit.com/product/3500 d5035_01 D5035-01 samd5x_e5x https://github.com/RudolphRiedel/USB_CAN-FD feather_m4_express Adafruit Feather M4 Express samd5x_e5x https://www.adafruit.com/product/3857 itsybitsy_m4 Adafruit ItsyBitsy M4 samd5x_e5x https://www.adafruit.com/product/3800 metro_m4_express Adafruit Metro M4 Express samd5x_e5x https://www.adafruit.com/product/3382 pybadge Adafruit PyBadge samd5x_e5x https://www.adafruit.com/product/4200 pyportal Adafruit PyPortal samd5x_e5x https://www.adafruit.com/product/4116 same54_xplained SAME54 Xplained Pro samd5x_e5x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAME54-XPRO same70_qmtech SAME70 QMTech same7x https://www.aliexpress.com/item/1005003173783268.html same70_xplained SAME70 Xplained same7x https://www.microchip.com/en-us/development-tool/atsame70-xpld samg55_xplained SAMG55 Xplained Pro samg https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMG55-XPRO ========================= =================================== ========== ================================================================================= ====== MindMotion ---------- ===================== ====================================== ======== =============================================================================================== ====== Board Name Family URL Note ===================== ====================================== ======== =============================================================================================== ====== mm32f327x_mb39 MM32F3273G9P MB-039 mm32 https://www.mindmotion.com.cn/support/development_tools/evaluation_boards/evboard/mm32f3273g9p/ mm32f327x_pitaya_lite DshanMCU Pitaya Lite with MM32F3273G8P mm32 https://gitee.com/weidongshan/DshanMCU-Pitaya-c ===================== ====================================== ======== =============================================================================================== ====== NXP --- ================== ========================================= ============ ========================================================================================================================================================================= ====== Board Name Family URL Note ================== ========================================= ============ ========================================================================================================================================================================= ====== metro_m7_1011 Adafruit Metro M7 1011 imxrt https://www.adafruit.com/product/5600 mimxrt1010_evk i.MX RT1010 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1010-evaluation-kit:MIMXRT1010-EVK mimxrt1015_evk i.MX RT1015 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1015-EVK mimxrt1020_evk i.MX RT1020 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1020-EVK mimxrt1024_evk i.MX RT1024 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1024-evaluation-kit:MIMXRT1024-EVK mimxrt1050_evkb i.MX RT1050 Evaluation Kit revB imxrt https://www.nxp.com/part/IMXRT1050-EVKB mimxrt1060_evk i.MX RT1060 Evaluation Kit revB imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1060-EVKB mimxrt1064_evk i.MX RT1064 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1064-EVK mimxrt1170_evkb i.MX RT1070 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1170-evaluation-kit:MIMXRT1170-EVKB teensy_40 Teensy 4.0 imxrt https://www.pjrc.com/store/teensy40.html teensy_41 Teensy 4.1 imxrt https://www.pjrc.com/store/teensy41.html frdm_k64f Freedom K64F kinetis_k https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F teensy_35 Teensy 3.5 kinetis_k https://www.pjrc.com/store/teensy35.html frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S frdm_k32l2b Freedom K32L2B3 kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 kuiic Kuiic kinetis_k32l https://github.com/nxf58843/kuiic frdm_kl25z fomu kinetis_kl https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z lpcxpresso11u37 LPCXpresso11U37 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13074 lpcxpresso11u68 LPCXpresso11U68 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 lpcxpresso1347 LPCXpresso1347 lpc13 https://www.nxp.com/products/no-longer-manufactured/lpcxpresso-board-for-lpc1347:OM13045 lpcxpresso1549 LPCXpresso1549 lpc15 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13056 lpcxpresso1769 LPCXpresso1769 lpc17 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13000 mbed1768 mbed 1768 lpc17 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1700-arm-cortex-m3/arm-mbed-lpc1768-board:OM11043 lpcxpresso18s37 LPCXpresso18s37 lpc18 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso18s37-development-board:OM13076 mcb1800 Keil MCB1800 lpc18 https://www.keil.com/arm/mcb1800/ ea4088_quickstart Embedded Artists LPC4088 QuickStart Board lpc40 https://www.embeddedartists.com/products/lpc4088-quickstart-board/ ea4357 Embedded Artists LPC4357 Development Kit lpc43 https://www.embeddedartists.com/products/lpc4357-developers-kit/ lpcxpresso43s67 LPCXpresso43S67 lpc43 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso43s67-development-board:OM13084 lpcxpresso51u68 LPCXpresso51u68 lpc51 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpcxpresso51u68-for-the-lpc51u68-mcus:OM40005 lpcxpresso54114 LPCXpresso54114 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54114-board:OM13089 lpcxpresso54608 LPCXpresso54608 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-development-board-for-lpc5460x-mcus:OM13092 lpcxpresso54628 LPCXpresso54628 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54628-development-board:OM13098 double_m33_express Double M33 Express lpc55 https://www.crowdsupply.com/steiert-solutions/double-m33-express lpcxpresso55s28 LPCXpresso55s28 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s28-development-board:LPC55S28-EVK lpcxpresso55s69 LPCXpresso55s69 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s69-development-board:LPC55S69-EVK mcu_link MCU Link lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcu-link-debug-probe:MCU-LINK frdm_mcxa153 Freedom MCXA153 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA153 frdm_mcxa156 Freedom MCXA156 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA156 frdm_mcxn947 Freedom MCXN947 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXN947 mcxn947brk MCXN947 Breakout mcx n/a frdm_rw612 FRDM-RW612 rw61x https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-RW612 ================== ========================================= ============ ========================================================================================================================================================================= ====== Nordic Semiconductor -------------------- =========================== ===================================== ======== ============================================================================== ====== Board Name Family URL Note =========================== ===================================== ======== ============================================================================== ====== adafruit_clue Adafruit CLUE nrf https://www.adafruit.com/product/4500 arduino_nano33_ble Arduino Nano 33 BLE nrf https://store.arduino.cc/arduino-nano-33-ble circuitplayground_bluefruit Adafruit Circuit Playground Bluefruit nrf https://www.adafruit.com/product/4333 feather_nrf52840_express Adafruit Feather nRF52840 Express nrf https://www.adafruit.com/product/4062 feather_nrf52840_sense Adafruit Feather nRF52840 Sense nrf https://www.adafruit.com/product/4516 itsybitsy_nrf52840 Adafruit ItsyBitsy nRF52840 Express nrf https://www.adafruit.com/product/4481 nrf52833dk Nordic nRF52833 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK nrf52840dk Nordic nRF52840DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK nrf52840dongle Nordic nRF52840 Dongle nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle nrf5340dk Nordic nRF5340 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK nrf54h20dk Nordic nRF54H20 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK =========================== ===================================== ======== ============================================================================== ====== Raspberry Pi ------------ ================================ ============================================ ============== ========================================================== ====== Board Name Family URL Note ================================ ============================================ ============== ========================================================== ====== raspberrypi_zero Raspberry Pi Zero broadcom_32bit https://www.raspberrypi.org/products/raspberry-pi-zero/ raspberrypi_cm4 Raspberry CM4 broadcom_64bit https://www.raspberrypi.org/products/compute-module-4 raspberrypi_zero2 Raspberry Zero2 broadcom_64bit https://www.raspberrypi.org/products/raspberry-pi-zero-2-w adafruit_feather_rp2040_usb_host Adafruit Feather RP2040 with USB Type A Host rp2040 https://www.adafruit.com/product/5723 adafruit_fruit_jam Adafruit Fruit Jam - Mini RP2350 rp2040 https://www.adafruit.com/product/6200 adafruit_metro_rp2350 Adafruit Metro RP2350 rp2040 https://www.adafruit.com/product/6003 raspberry_pi_pico Pico rp2040 https://www.raspberrypi.com/products/raspberry-pi-pico/ raspberry_pi_pico2 Pico2 rp2040 https://www.raspberrypi.com/products/raspberry-pi-pico-2/ raspberry_pi_pico_w Pico rp2040 https://www.raspberrypi.com/products/raspberry-pi-pico/ ================================ ============================================ ============== ========================================================== ====== Renesas ------- ============== =========================== ======== ================================================================================================================================================================ ====== Board Name Family URL Note ============== =========================== ======== ================================================================================================================================================================ ====== da14695_dk_usb DA14695-00HQDEVKT-U da1469x https://www.renesas.com/en/products/wireless-connectivity/bluetooth-low-energy/da14695-00hqdevkt-u-smartbond-da14695-bluetooth-low-energy-52-usb-development-kit da1469x_dk_pro DA1469x Development Kit Pro da1469x https://lpccs-docs.renesas.com/um-b-090-da1469x_getting_started/DA1469x_The_hardware/DA1469x_The_hardware.html portenta_c33 Arduino Portenta C33 ra https://www.arduino.cc/pro/hardware-product-portenta-c33/ ra2a1_ek RA2A1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra2a1-evaluation-kit-ra2a1-mcu-group ra4m1_ek RA4M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m1-evaluation-kit-ra4m1-mcu-group ra4m3_ek RA4M3 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m3-evaluation-kit-ra4m3-mcu-group ra6m1_ek RA6M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m1-evaluation-kit-ra6m1-mcu-group ra6m5_ek RA6M5 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m5-evaluation-kit-ra6m5-mcu-group ra8m1_ek RA8M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra8m1-evaluation-kit-ra8m1-mcu-group uno_r4 Arduino UNO R4 ra https://store-usa.arduino.cc/pages/uno-r4 ============== =========================== ======== ================================================================================================================================================================ ====== STMicroelectronics ------------------ =================== ================================= ========= ================================================================= ====== Board Name Family URL Note =================== ================================= ========= ================================================================= ====== stm32c071nucleo STM32C071 Nucleo stm32c0 https://www.st.com/en/evaluation-tools/nucleo-g071rb.html stm32f070rbnucleo STM32 F070 Nucleo stm32f0 https://www.st.com/en/evaluation-tools/nucleo-f070rb.html stm32f072disco STM32 F072 Discovery stm32f0 https://www.st.com/en/evaluation-tools/32f072bdiscovery.html stm32f072eval STM32 F072 Eval stm32f0 https://www.st.com/en/evaluation-tools/stm32072b-eval.html stm32f103_bluepill STM32 F103 Bluepill stm32f1 https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill stm32f103_mini_2 STM32 F103 Mini v2 stm32f1 https://stm32-base.org/boards/STM32F103RCT6-STM32-Mini-V2.0 stm32f103ze_iar IAR STM32 F103ze starter kit stm32f1 n/a stm32f207nucleo STM32 F207 Nucleo stm32f2 https://www.st.com/en/evaluation-tools/nucleo-f207zg.html stm32f303disco STM32 F303 Discovery stm32f3 https://www.st.com/en/evaluation-tools/stm32f3discovery.html feather_stm32f405 Adafruit Feather STM32F405 stm32f4 https://www.adafruit.com/product/4382 pyboardv11 Pyboard v1.1 stm32f4 https://www.adafruit.com/product/2390 stm32f401blackpill STM32 F401 Blackpill stm32f4 https://stm32-base.org/boards/STM32F401CCU6-WeAct-Black-Pill-V1.2 stm32f407blackvet STM32 F407 Blackvet stm32f4 https://stm32-base.org/boards/STM32F407VET6-STM32-F4VE-V2.0 stm32f407disco STM32 F407 Discovery stm32f4 https://www.st.com/en/evaluation-tools/stm32f4discovery.html stm32f411blackpill STM32 F411 Blackpill stm32f4 https://stm32-base.org/boards/STM32F411CEU6-WeAct-Black-Pill-V2.0 stm32f411disco STM32 F411 Discovery stm32f4 https://www.st.com/en/evaluation-tools/32f411ediscovery.html stm32f412disco STM32 F412 Discovery stm32f4 https://www.st.com/en/evaluation-tools/32f412gdiscovery.html stm32f412nucleo STM32 F412 Nucleo stm32f4 https://www.st.com/en/evaluation-tools/nucleo-f412zg.html stm32f439nucleo STM32 F439 Nucleo stm32f4 https://www.st.com/en/evaluation-tools/nucleo-f439zi.html stlinkv3mini Stlink-v3 mini stm32f7 https://www.st.com/en/development-tools/stlink-v3mini.html stm32f723disco STM32 F723 Discovery stm32f7 https://www.st.com/en/evaluation-tools/32f723ediscovery.html stm32f746disco STM32 F746 Discovery stm32f7 https://www.st.com/en/evaluation-tools/32f746gdiscovery.html stm32f746nucleo STM32 F746 Nucleo stm32f7 https://www.st.com/en/evaluation-tools/nucleo-f746zg.html stm32f767nucleo STM32 F767 Nucleo stm32f7 https://www.st.com/en/evaluation-tools/nucleo-f767zi.html stm32f769disco STM32 F769 Discovery stm32f7 https://www.st.com/en/evaluation-tools/32f769idiscovery.html stm32g0b1nucleo STM32 G0B1 Nucleo stm32g0 https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html b_g474e_dpow1 STM32 B-G474E-DPOW1 Discovery kit stm32g4 https://www.st.com/en/evaluation-tools/b-g474e-dpow1.html stm32g474nucleo STM32 G474 Nucleo stm32g4 https://www.st.com/en/evaluation-tools/nucleo-g474re.html stm32g491nucleo STM32 G491 Nucleo stm32g4 https://www.st.com/en/evaluation-tools/nucleo-g491re.html stm32h503nucleo STM32 H503 Nucleo stm32h5 https://www.st.com/en/evaluation-tools/nucleo-h503rb.html stm32h563nucleo STM32 H563 Nucleo stm32h5 https://www.st.com/en/evaluation-tools/nucleo-h563zi.html stm32h573i_dk STM32 H573i Discovery stm32h5 https://www.st.com/en/evaluation-tools/stm32h573i-dk.html daisyseed Daisy Seed stm32h7 https://electro-smith.com/products/daisy-seed stm32h723nucleo STM32 H723 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h723zg.html stm32h743eval STM32 H743 Eval stm32h7 https://www.st.com/en/evaluation-tools/stm32h743i-eval.html stm32h743nucleo STM32 H743 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h743zi.html stm32h745disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html stm32h747disco STM32 H747 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h747i-disco.html stm32h750_weact STM32 H750 WeAct stm32h7 https://www.adafruit.com/product/5032 stm32h750bdk STM32 H750b Discovery Kit stm32h7 https://www.st.com/en/evaluation-tools/stm32h750b-dk.html waveshare_openh743i Waveshare Open H743i stm32h7 https://www.waveshare.com/openh743i-c-standard.htm stm32h7s3nucleo STM32 H7S3L8 Nucleo stm32h7rs https://www.st.com/en/evaluation-tools/nucleo-h7s3l8.html stm32l052dap52 STM32 L052 DAP stm32l0 n/a stm32l0538disco STM32 L0538 Discovery stm32l0 https://www.st.com/en/evaluation-tools/32l0538discovery.html stm32l412nucleo STM32 L412 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l412kb.html stm32l476disco STM32 L476 Disco stm32l4 https://www.st.com/en/evaluation-tools/32l476gdiscovery.html stm32l496nucleo STM32 L496 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l496ZG-P.html stm32l4p5nucleo STM32 L4P5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html stm32l4r5nucleo STM32 L4R5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html stm32n6570dk STM32 N6570-DK stm32n6 https://www.st.com/en/evaluation-tools/stm32n6570-dk.html stm32n657nucleo STM32 N657X0-Q Nucleo stm32n6 https://www.st.com/en/evaluation-tools/nucleo-n657x0-q.html stm32u083cdk STM32U083C-DK Discovery Kit stm32u0 https://www.st.com/en/evaluation-tools/stm32u083c-dk.html b_u585i_iot2a STM32 B-U585i IOT2A Discovery kit stm32u5 https://www.st.com/en/evaluation-tools/b-u585i-iot02a.html stm32u545nucleo STM32 U545 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u545re-q.html stm32u575eval STM32 U575 Eval stm32u5 https://www.st.com/en/evaluation-tools/stm32u575i-ev.html stm32u575nucleo STM32 U575 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u575zi-q.html stm32u5a5nucleo STM32 U5a5 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u5a5zj-q.html stm32wb55nucleo STM32 P-NUCLEO-WB55 stm32wb https://www.st.com/en/evaluation-tools/p-nucleo-wb55.html stm32wba_nucleo STM32 NUCLEO-WBA65RI stm32wba https://www.st.com/en/evaluation-tools/nucleo-wba65ri.html =================== ================================= ========= ================================================================= ====== Sunxi ----- ======= ================= ======== ========================================= ====== Board Name Family URL Note ======= ================= ======== ========================================= ====== f1c100s Lctech Pi F1C200s f1c100s https://linux-sunxi.org/Lctech_Pi_F1C200s ======= ================= ======== ========================================= ====== Texas Instruments ----------------- ================= ===================== ======== ========================================= ====== Board Name Family URL Note ================= ===================== ======== ========================================= ====== msp_exp430f5529lp MSP430F5529 LaunchPad msp430 https://www.ti.com/tool/MSP-EXP430F5529LP msp_exp432e401y MSP432E401Y LaunchPad msp432e4 https://www.ti.com/tool/MSP-EXP432E401Y ek_tm4c123gxl TM4C123G LaunchPad tm4c https://www.ti.com/tool/EK-TM4C123GXL ek_tm4c1294xl TM4C1294 LaunchPad tm4c https://www.ti.com/tool/EK-TM4C1294XL ================= ===================== ======== ========================================= ====== Tomu ---- ======= ====== ======== ========================= ====== Board Name Family URL Note ======= ====== ======== ========================= ====== fomu fomu fomu https://tomu.im/fomu.html ======= ====== ======== ========================= ====== WCH --- ================ ================ ======== ===================================================================== ====== Board Name Family URL Note ================ ================ ======== ===================================================================== ====== ch32f205r-r0 CH32F205r-r0 ch32f20x https://github.com/openwch/ch32f20x ch32v103r_r1_1v0 CH32V103R-R1-1v1 ch32v10x https://github.com/openwch/ch32v103/tree/main/SCHPCB/CH32V103R-R1-1v1 ch32v203c_r0_1v0 CH32V203C-R0-1v0 ch32v20x https://github.com/openwch/ch32v20x/tree/main/SCHPCB/CH32V203C-R0 ch32v203g_r0_1v0 CH32V203G-R0-1v0 ch32v20x https://github.com/openwch/ch32v20x/tree/main/SCHPCB/CH32V203C-R0 nanoch32v203 nanoCH32V203 ch32v20x https://github.com/wuxx/nanoCH32V203 ch32v307v_r1_1v0 CH32V307V-R1-1v0 ch32v30x https://github.com/openwch/ch32v307/tree/main/SCHPCB/CH32V307V-R1-1v0 nanoch32v305 nanoCH32V305 ch32v30x https://github.com/wuxx/nanoCH32V305 ================ ================ ======== ===================================================================== ====== ================================================ FILE: docs/reference/concurrency.rst ================================================ *********** Concurrency *********** The TinyUSB library is designed to operate on single-core MCUs with multi-threaded applications in mind. Interaction with interrupts is especially important to pay attention to. It is compatible with optionally using an RTOS. General ------- When writing code, keep in mind that the OS (if using an RTOS) may swap out your code at any time. Also, your code can be preempted by an interrupt at any time. Application Code ---------------- The USB core does not execute application callbacks while in an interrupt context. Calls to application code are from within the USB core task context. Note that the application core will call class drivers from within its own task. Class Drivers ------------- Class driver code should never be called from an interrupt context by the USB core, though the application is allowed to call class driver functions from interrupts. USB core functions may be called simultaneously by multiple tasks. Use care that proper locking is used to guard the USBD core functions from this case. Class drivers are allowed to call ``usbd_*`` functions, but not ``dcd_*`` functions. USB Core -------- All functions that may be called from an (USB core) interrupt context have a ``bool in_isr`` parameter to remind the implementer that special care must be taken. Interrupt handlers must not directly call class driver code, they must pass a message to the USB core's task. ``usbd_*`` functions may be called from interrupts without any notice. They may also be called simultaneously by multiple tasks. Device Drivers -------------- Much of the processing of the USB stack is done in an interrupt context, and care must be taken in order to ensure variables are handled in the appropriate ways by the compiler and optimizer. In particular: * Ensure that all memory-mapped registers (including packet memory) are marked as volatile. GCC's optimizer will even combine memory accesses (like two 16-bit to be a 32-bit) if you don't mark the pointers as volatile. On some architectures, this can use macros like _I , _O , or _IO. * All defined global variables are marked as ``static``. ================================================ FILE: docs/reference/dependencies.rst ================================================ ************ Dependencies ************ MCU low-level peripheral drivers and external libraries for building TinyUSB examples ======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by ======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 hw/mcu/artery/at32f403a_407 https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git f2cb360c3d28fada76b374308b8c4c61d37a090b at32f403a_407 hw/mcu/artery/at32f413 https://github.com/ArteryTek/AT32F413_Firmware_Library.git f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450 at32f413 hw/mcu/artery/at32f415 https://github.com/ArteryTek/AT32F415_Firmware_Library.git 716f545aa1290ff144ccf023a8e797b951e1bc8e at32f415 hw/mcu/artery/at32f423 https://github.com/ArteryTek/AT32F423_Firmware_Library.git 2afa7f12852e57a9e8aab3a892c641e1a8635a18 at32f423 hw/mcu/artery/at32f425 https://github.com/ArteryTek/AT32F425_Firmware_Library.git 620233e1357d5c1b7e2bde6b9dd5196822b91817 at32f425 hw/mcu/artery/at32f435_437 https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git 25439cc6650a8ae0345934e8707a5f38c7ae41f8 at32f435_437 hw/mcu/artery/at32f45x https://github.com/ArteryTek/AT32F45x_Firmware_Library.git 3d4a1b38be8ebac292e2350ca53bc4bfa4430233 at32f45x hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 03f74eac84645178fdde7f2e5ca9acdcb7bd9dcd ft9xx hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 hw/mcu/hpmicro/hpm_sdk https://github.com/hpmicro/hpm_sdk 8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff hpmicro hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 hw/mcu/nxp/mcux-devices-kinetis https://github.com/nxp-mcuxpresso/mcux-devices-kinetis 98a155e666c54f396e528ec3131f27a5d5b71f76 kinetis_k32l hw/mcu/nxp/mcux-devices-lpc https://github.com/nxp-mcuxpresso/mcux-devices-lpc 8096b783ec09d0d1c8629025a5f9d8e7df26e520 lpc51 lpc55 hw/mcu/nxp/mcux-devices-mcx https://github.com/nxp-mcuxpresso/mcux-devices-mcx ada1c97c761123ec0c179bb9bb9f744bf9a11475 mcx hw/mcu/nxp/mcux-devices-rt https://github.com/nxp-mcuxpresso/mcux-devices-rt dba2b523c9df61f3330bd186242f8210a8e47c45 imxrt hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_kl lpc54 rw61x hw/mcu/nxp/mcuxsdk-core https://github.com/nxp-mcuxpresso/mcuxsdk-core 0c5c6b16deb211110e06bde896cdff59ab213e16 imxrt kinetis_k32l lpc51 lpc55 mcx hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git edcc97d684b6f716728a60d7a6fea049d9870bd6 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc efm32 hw/mcu/sony/cxd56/spresense-exported-sdk https://github.com/sonydevworld/spresense-exported-sdk.git 2ec2a1538362696118dc3fdf56f33dacaf8f4067 spresense hw/mcu/st/cmsis-device-u0 https://github.com/STMicroelectronics/cmsis-device-u0.git e3a627c6a5bc4eb2388e1885a95cc155e1672253 stm32u0 hw/mcu/st/cmsis-device-wba https://github.com/STMicroelectronics/cmsis-device-wba.git 647d8522e5fd15049e9a1cc30ed19d85e5911eaf stm32wba hw/mcu/st/cmsis_device_c0 https://github.com/STMicroelectronics/cmsis_device_c0.git 517611273f835ffe95318947647bc1408f69120d stm32c0 hw/mcu/st/cmsis_device_f0 https://github.com/STMicroelectronics/cmsis_device_f0.git cbb5da5d48b4b5f2efacdc2f033be30f9d29889f stm32f0 hw/mcu/st/cmsis_device_f1 https://github.com/STMicroelectronics/cmsis_device_f1.git c8e9a4a4f16b6d2cb2a2083cbe5161025280fb22 stm32f1 hw/mcu/st/cmsis_device_f2 https://github.com/STMicroelectronics/cmsis_device_f2.git 49321f1e4d2bd3e65687b37f2652a28ea7983674 stm32f2 hw/mcu/st/cmsis_device_f3 https://github.com/STMicroelectronics/cmsis_device_f3.git 5558e64e3675a1e1fcb1c71f468c7c407c1b1134 stm32f3 hw/mcu/st/cmsis_device_f4 https://github.com/STMicroelectronics/cmsis_device_f4.git 3c77349ce04c8af401454cc51f85ea9a50e34fc1 stm32f4 hw/mcu/st/cmsis_device_f7 https://github.com/STMicroelectronics/cmsis_device_f7.git 2352e888e821aa0f4fe549bd5ea81d29c67a3222 stm32f7 hw/mcu/st/cmsis_device_g0 https://github.com/STMicroelectronics/cmsis_device_g0.git f484fe852535f913a02ee79787eafa74dd7f9488 stm32g0 hw/mcu/st/cmsis_device_g4 https://github.com/STMicroelectronics/cmsis_device_g4.git 7c39c32593b03764aaa57531588b8bf7cdd443a5 stm32g4 hw/mcu/st/cmsis_device_h5 https://github.com/STMicroelectronics/cmsis_device_h5.git 5273b8f134ba65f5b8174c4141b711b5c0d295b2 stm32h5 hw/mcu/st/cmsis_device_h7 https://github.com/STMicroelectronics/cmsis_device_h7.git 45b818cab6ee2806e3a27c80e330957223424392 stm32h7 hw/mcu/st/cmsis_device_h7rs https://github.com/STMicroelectronics/cmsis_device_h7rs.git 57ea11f70ebf1850e1048989d665c9070f0bb863 stm32h7rs hw/mcu/st/cmsis_device_l0 https://github.com/STMicroelectronics/cmsis_device_l0.git 7b7ae8cd71437331e1d7824f157d00c7bb4a5044 stm32l0 hw/mcu/st/cmsis_device_l1 https://github.com/STMicroelectronics/cmsis_device_l1.git a23ade4ccf14012085fedf862e33a536ab7ed8be stm32l1 hw/mcu/st/cmsis_device_l4 https://github.com/STMicroelectronics/cmsis_device_l4.git a2530753e86dd326a75467d28feb92e2ba7d0df2 stm32l4 hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/cmsis_device_l5.git 7d9a51481f0e6c376e62c3c849e6caf652c66482 stm32l5 hw/mcu/st/cmsis_device_n6 https://github.com/STMicroelectronics/cmsis-device-n6.git 7bcdc944fbf7cf5928d3c1d14054ca13261d33ec stm32n6 hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 6e67187dec98035893692ab2923914cb5f4e0117 stm32u5 hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git cda2cb9fc4a5232ab18efece0bb06b0b60910083 stm32wb hw/mcu/st/stm32-mfxstm32l152 https://github.com/STMicroelectronics/stm32-mfxstm32l152.git 7f4389efee9c6a655b55e5df3fceef5586b35f9b stm32h7 hw/mcu/st/stm32-tcpp0203 https://github.com/STMicroelectronics/stm32-tcpp0203.git 9918655bff176ac3046ccf378b5c7bbbc6a38d15 stm32h5 stm32h7rs stm32n6 hw/mcu/st/stm32c0xx_hal_driver https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git c283b143bef6bdaacf64240ee6f15eb61dad6125 stm32c0 hw/mcu/st/stm32f0xx_hal_driver https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git 94399697cb5eeaf8511b81b7f50dc62f0a5a3f6c stm32f0 hw/mcu/st/stm32f1xx_hal_driver https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git 18074e3e5ecad0b380a5cf5a9131fe4b5ed1b2b7 stm32f1 hw/mcu/st/stm32f2xx_hal_driver https://github.com/STMicroelectronics/stm32f2xx_hal_driver.git ae7b47fe41cf75ccaf65cbf8ee8749b18ba0e0f3 stm32f2 hw/mcu/st/stm32f3xx_hal_driver https://github.com/STMicroelectronics/stm32f3xx_hal_driver.git e098c8c8ce6f426bcee7db3a37c0932ea881eb0b stm32f3 hw/mcu/st/stm32f4xx_hal_driver https://github.com/STMicroelectronics/stm32f4xx_hal_driver.git b6f0ed3829f3829eb358a2e7417d80bba1a42db7 stm32f4 hw/mcu/st/stm32f7xx_hal_driver https://github.com/STMicroelectronics/stm32f7xx_hal_driver.git e1446fa12ffda80ea1016faf349e45b2047fff12 stm32f7 hw/mcu/st/stm32g0xx_hal_driver https://github.com/STMicroelectronics/stm32g0xx_hal_driver.git a248a9e484d58943b46c68f6c49b4b276778bd59 stm32g0 hw/mcu/st/stm32g4xx_hal_driver https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git 10138a41749ea62d53ecab65b2bc2a950acc04d2 stm32g4 hw/mcu/st/stm32h5xx_hal_driver https://github.com/STMicroelectronics/stm32h5xx_hal_driver.git 3c84eaa6000ab620be01afbcfba2735389afe09b stm32h5 hw/mcu/st/stm32h7rsxx_hal_driver https://github.com/STMicroelectronics/stm32h7rsxx-hal-driver.git 9e83b95ae0f70faa067eddce2da617d180937f9b stm32h7rs hw/mcu/st/stm32h7xx_hal_driver https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git dbfb749f229e1aa89e50b54229ca87766e180d2d stm32h7 hw/mcu/st/stm32l0xx_hal_driver https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git 65da4cd8a10ad859ec8d9cd71f3f6c50735bd473 stm32l0 hw/mcu/st/stm32l1xx_hal_driver https://github.com/STMicroelectronics/stm32l1xx_hal_driver.git 54f0b7568ce2acb33d090c70c897ee32229c1d32 stm32l1 hw/mcu/st/stm32l4xx_hal_driver https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git 3e039bbf62f54bbd834d578185521cff80596efe stm32l4 hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git 3340b9a597bcf75cc173345a90a74aa2a4a37510 stm32l5 hw/mcu/st/stm32n6xx_hal_driver https://github.com/STMicroelectronics/stm32n6xx-hal-driver.git bc6c41f8f67d61b47af26695d0bf67762a000666 stm32n6 hw/mcu/st/stm32u0xx_hal_driver https://github.com/STMicroelectronics/stm32u0xx-hal-driver.git cbfb5ac654256445237fd32b3587ac6a238d24f1 stm32u0 hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2c5e2568fbdb1900a13ca3b2901fdd302cac3444 stm32u5 hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb hw/mcu/ti https://github.com/hathach/ti_driver.git 083944907e7d08fcb1f614b47598ce45935b8da1 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 lib/threadx https://github.com/eclipse-threadx/threadx.git 4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae all tools/linkermap https://github.com/hathach/linkermap.git 8e1f440fa15c567aceb5aa0d14f6d18c329cc67f all tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all ======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== ================================================ FILE: docs/reference/glossary.rst ================================================ ******** Glossary ******** .. glossary:: BSP Board Support Package. A collection of board-specific code that provides hardware abstraction for a particular development board, including pin mappings, clock settings, linker scripts, and hardware initialization routines. Located in ``hw/bsp/FAMILY/boards/BOARD_NAME``. Bulk Transfer USB transfer type used for large amounts of data that doesn't require guaranteed timing. Used by mass storage devices and CDC class. CDC Communications Device Class. USB class for devices that communicate serial data, creating virtual serial ports. Control Transfer USB transfer type used for device configuration and control. All USB devices must support control transfers on endpoint 0. DCD Device Controller Driver. The hardware abstraction layer for USB device controllers in TinyUSB. See also HCD. Descriptor Data structures that describe USB device capabilities, configuration, and interfaces to the host. Device Class USB specification defining how devices of a particular type (e.g., storage, audio, HID) communicate with hosts. DFU Device Firmware Update. USB class that allows firmware updates over USB. Endpoint Communication channel between host and device. Each endpoint has a direction (IN/OUT) and transfer type. Enumeration Process where USB host discovers and configures a newly connected device. HCD Host Controller Driver. The hardware abstraction layer for USB host controllers in TinyUSB. See also DCD. HID Human Interface Device. USB class for input devices like keyboards, mice, and game controllers. High Speed USB 2.0 speed mode operating at 480 Mbps. Full Speed USB speed mode operating at 12 Mbps, supported by USB 1.1 and 2.0. Low Speed USB speed mode operating at 1.5 Mbps, typically used by simple input devices. Interrupt Transfer USB transfer type for small, time-sensitive data with guaranteed maximum latency. Isochronous Transfer USB transfer type for time-critical data like audio/video with guaranteed bandwidth but no error correction. MSC Mass Storage Class. USB class for storage devices like USB drives. OSAL Operating System Abstraction Layer. TinyUSB component that abstracts RTOS differences. OTG On-The-Go. USB specification allowing devices to act as both host and device. Pipe Host-side communication channel to a device endpoint. Root Hub The USB hub built into the host controller, where devices connect directly. Stall USB protocol mechanism where an endpoint responds with a STALL handshake to indicate an error condition or unsupported request. Used for error handling, not flow control. Super Speed USB 3.0 speed mode operating at 5 Gbps. Not supported by TinyUSB. tud TinyUSB Device. Function prefix for all device stack APIs (e.g., ``tud_task()``, ``tud_cdc_write()``). tuh TinyUSB Host. Function prefix for all host stack APIs (e.g., ``tuh_task()``, ``tuh_cdc_receive()``). UAC USB Audio Class. USB class for audio devices. UVC USB Video Class. USB class for video devices like cameras. VID Vendor Identifier. 16-bit number assigned by USB-IF to identify device manufacturers. PID Product Identifier. 16-bit number assigned by vendor to identify specific products. USB-IF USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. ================================================ FILE: docs/reference/index.rst ================================================ ********* Reference ********* Complete reference documentation for TinyUSB APIs, configuration, and supported hardware. .. toctree:: :maxdepth: 2 architecture usb_concepts boards dependencies concurrency glossary ================================================ FILE: docs/reference/usb_concepts.rst ================================================ ************ USB Concepts ************ This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. TinyUSB API Naming Conventions =============================== TinyUSB uses consistent function prefixes to organize its API: * **tusb_**: Core stack functions (initialization, interrupt handling) * **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) * **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) * **tu_**: Internal utility functions (generally not used by applications) This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. USB Protocol Basics ==================== Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. Host and Device Roles ---------------------- **USB Host**: The controlling side of a USB connection (typically a computer). The host: - Initiates all communication - Provides power to devices - Manages the USB bus - Enumerates and configures devices **TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. **USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: - Respond to host requests - Cannot initiate communication - Receive power from the host - Must be enumerated by the host before use **TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. **OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. USB Transfers ============= Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. USB defines four transfer types, each intended for different use cases: Control Transfers ----------------- Used for device configuration and control commands. **Characteristics**: - Bidirectional (uses both IN and OUT) - Guaranteed delivery with error detection - Limited data size (8-64 bytes per packet) - All devices must support control transfers on endpoint 0 **Usage**: Device enumeration, configuration changes, class-specific commands **TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). Bulk Transfers -------------- Used for large amounts of data that don't require guaranteed timing. **Characteristics**: - Unidirectional (separate IN and OUT endpoints) - Guaranteed delivery with error detection - Large packet sizes (up to 512 bytes for High Speed) - Uses available bandwidth when no other transfers are active **Usage**: File transfers, large data communication, CDC serial data **TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. Interrupt Transfers ------------------- Used for small, time-sensitive data with guaranteed maximum latency. **Characteristics**: - Unidirectional (separate IN and OUT endpoints) - Guaranteed delivery with error detection - Small packet sizes (up to 64 bytes for Full Speed) - Regular polling interval (1ms to 255ms) **Usage**: Keyboard/mouse input, sensor data, status updates **TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. Isochronous Transfers --------------------- Used for time-critical streaming data. **Characteristics**: - Unidirectional (separate IN and OUT endpoints) - No error correction (speed over reliability) - Guaranteed bandwidth - Real-time delivery **Usage**: Audio, video streaming **TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. Endpoints and Addressing ========================= Endpoint Basics --------------- **Endpoint**: A communication channel between host and device. - Each endpoint has a number (0-15) and direction - Endpoint 0 is reserved for control transfers - Other endpoints are assigned by device class requirements **TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. **Direction**: - **OUT**: Host to device (host sends data out) - **IN**: Device to host (host reads data in) - Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). **Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) Endpoint Configuration ---------------------- Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. **TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. Error Handling and Flow Control ------------------------------- **Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. **Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. **TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. USB Device States ================= A USB device progresses through several states: 1. **Attached**: Device is physically connected 2. **Powered**: Device receives power from host 3. **Default**: Device responds to address 0 4. **Address**: Device has been assigned a unique address 5. **Configured**: Device is ready for normal operation 6. **Suspended**: Device is in low-power state **TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. Device Enumeration Process ========================== When a device is connected, the host follows this process: 1. **Detection**: Host detects device connection 2. **Reset**: Host resets the device 3. **Descriptor Requests**: Host requests device descriptors 4. **Address Assignment**: Host assigns unique address to device 5. **Configuration**: Host selects and configures device 6. **Class Loading**: Host loads appropriate drivers 7. **Normal Operation**: Device is ready for use **TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. USB Descriptors =============== Descriptors are data structures that describe device capabilities: Device Descriptor ----------------- Describes the device (VID, PID, USB version, etc.) Configuration Descriptor ------------------------ Describes device configuration (power requirements, interfaces, etc.) Interface Descriptor -------------------- Describes a functional interface (class, endpoints, etc.) Endpoint Descriptor ------------------- Describes endpoint characteristics (type, direction, size, etc.) String Descriptors ------------------ Human-readable strings (manufacturer, product name, etc.) **TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: - ``tud_descriptor_device_cb()`` - Device descriptor - ``tud_descriptor_configuration_cb()`` - Configuration descriptor - ``tud_descriptor_string_cb()`` - String descriptors The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. USB Classes =========== USB classes define standardized protocols for device types: **Class Code**: Identifies the device type in descriptors **Class Driver**: Software that implements the class protocol **Class Requests**: Standardized commands for the class **Common TinyUSB-Supported Classes**: - **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` - **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` - **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` - **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` - **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` - **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` - **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` .. note:: **Vendor Class Buffer Configuration**: Unlike other USB classes, the vendor class supports setting buffer sizes to 0 in ``tusb_config.h`` (``CFG_TUD_VENDOR_RX_BUFSIZE = 0``) to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. See ``examples/device/*/tusb_config.h`` for configuration examples. USB Speeds ========== USB supports multiple speed modes: **Low Speed (1.5 Mbps)**: - Simple devices (mice, keyboards) - Limited endpoint types and sizes **Full Speed (12 Mbps)**: - Most common for embedded devices - All transfer types supported - Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) **High Speed (480 Mbps)**: - High-performance devices - Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) - Requires more complex hardware **Super Speed (5 Gbps)**: - USB 3.0 and later - Not supported by TinyUSB **TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. USB Controller Abstraction =========================== USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. Controller Fundamentals ----------------------- **What Controllers Do**: - Handle USB signaling and protocol timing - Manage endpoint buffers and data transfers - Generate interrupts for USB events - Implement USB electrical specifications **Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. Controller Architecture Types ----------------------------- Different MCU vendors implement USB controllers with varying architectures. To list a few common patterns: **FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): - Shared or dedicated FIFOs for endpoint data - Software manages FIFO allocation and data flow - Common in higher-end MCUs with flexible configurations **Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): - Fixed packet memory areas for each endpoint - Hardware automatically handles packet placement - Simpler programming model, common in smaller MCUs **Descriptor-Based Controllers** (e.g., NXP EHCI-style): - Use descriptor chains to describe transfers - Hardware processes transfer descriptors independently - More complex but can handle larger transfers autonomously TinyUSB Controller Abstraction ------------------------------ TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. **Portable Interface** (``src/device/usbd.h``): - Standardized function signatures for all controllers - Common endpoint and transfer management APIs - Unified interrupt and event handling **Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): - Implement the DCD interface for specific hardware - Handle vendor-specific register layouts and behaviors - Manage controller-specific quirks and workarounds **Common DCD Functions**: - ``dcd_init()`` - Initialize controller hardware - ``dcd_edpt_open()`` - Configure endpoint with type and size - ``dcd_edpt_xfer()`` - Start data transfer on endpoint - ``dcd_int_handler()`` - Process USB interrupts - ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection Host Controller Driver (HCD) ----------------------------- TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. **Portable Interface** (``src/host/usbh.h``): - Standardized interface for all host controllers - Common device enumeration and pipe management - Unified transfer scheduling and completion handling **Common HCD Functions**: - ``hcd_init()`` - Initialize host controller hardware - ``hcd_port_connect_status()`` - Check device connection status - ``hcd_port_reset()`` - Reset connected device - ``hcd_edpt_open()`` - Open communication pipe to device endpoint - ``hcd_edpt_xfer()`` - Transfer data to/from connected device **Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. TinyUSB Event System & Thread Safety ==================================== Deferred Interrupt Processing ----------------------------- **Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. **Event Flow**: 1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) 2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue 3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events 4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks **Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. Controller Event Flow --------------------- **Typical USB Event Processing**: 1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) 2. **Interrupt Generation**: Controller generates interrupt to CPU 3. **ISR Processing**: ``dcd_int_handler()`` reads controller status 4. **Event Queuing**: Events are queued for later processing (thread safety) 5. **Task Processing**: ``tud_task()`` processes queued events 6. **Class Notification**: Appropriate class drivers handle the event 7. **Application Callback**: User code responds to the event USB Class Driver Architecture ============================== TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. Class Driver Pattern --------------------- **Standardized Entry Points**: Each class driver implements these core functions: - ``*_init()`` - Initialize class driver state and buffers - ``*_reset()`` - Reset to initial state on USB bus reset - ``*_open()`` - Parse and configure interfaces during enumeration - ``*_control_xfer_cb()`` - Handle class-specific control requests - ``*_xfer_cb()`` - Handle transfer completion callbacks **Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: .. code-block:: c // Single instance (default instance 0) tud_cdc_write(data, len); // Multiple instances tud_cdc_n_write(0, data, len); // Instance 0 tud_cdc_n_write(1, data, len); // Instance 1 **Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. Class Driver Types ------------------- TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. **Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. Power Management ================ USB provides power to devices: **Bus-Powered**: Device draws power from USB bus (up to 500mA) **Self-Powered**: Device has its own power source **Suspend/Resume**: Devices must enter low-power mode when bus is idle **TinyUSB Power Management**: - Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management - Configure power requirements in device descriptor (``bMaxPower`` field) - Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) - Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` Next Steps ========== - Start with :doc:`../getting_started` for basic setup - Review ``examples/device/*/tusb_config.h`` for configuration examples - Explore examples in ``examples/device/`` and ``examples/host/`` directories ================================================ FILE: docs/requirements.txt ================================================ sphinx>=5.0 furo>=2020.12.30.b24 sphinx-autodoc-typehints>=1.10 jinja2>=3.0.3 ================================================ FILE: docs/troubleshooting.rst ================================================ *************** Troubleshooting *************** This guide helps you diagnose and fix common issues when developing with TinyUSB. Build Issues ============ Toolchain Problems ------------------ **"arm-none-eabi-gcc: command not found"** The ARM GCC toolchain is not installed or not in PATH. *Solution*: .. code-block:: bash # Ubuntu/Debian $ sudo apt-get update && sudo apt-get install gcc-arm-none-eabi # macOS with Homebrew $ brew install --cask gcc-arm-embedded # Windows: Download from ARM website and add to PATH **"make: command not found" or CMake errors** Build tools are missing. *Solution*: .. code-block:: bash # Ubuntu/Debian $ sudo apt-get install build-essential cmake # macOS $ xcode-select --install $ brew install cmake Dependency Issues ----------------- **"No rule to make target" or missing header files** Dependencies for your MCU family are not downloaded. *Solution*: .. code-block:: bash # Download dependencies for specific board or family $ python tools/get_deps.py -b stm32h743eval # Replace with your board $ python tools/get_deps.py stm32f4 # Replace with your family # Or from example directory cd examples/device/cdc_msc make BOARD=your_board get-deps **Board Not Found** Invalid board name in build command. *Diagnosis*: .. code-block:: bash # List available boards for a family ls hw/bsp/stm32f4/boards/ *Solution*: Use exact board name from the listing. Runtime Issues ============== Device Mode Problems -------------------- **Device not recognized by host** The most common issue - host doesn't see your USB device. *Diagnosis steps*: 1. Check USB cable (must support data, not just power) 2. Enable logging: build with ``LOG=2`` 3. Use different USB ports/hosts 4. Check device manager (Windows) or ``dmesg`` (Linux) *Common causes and solutions*: - **Invalid descriptors**: Review ``usb_descriptors.c`` carefully - **``tud_task()`` not called**: Ensure regular calls in main loop (< 1ms interval) - **Wrong USB configuration**: Check ``tusb_config.h`` settings - **Hardware issues**: Verify USB pins, crystal/clock configuration **Enumeration starts but fails** Device is detected but configuration fails. *Diagnosis*: .. code-block:: bash # Build with logging enabled make BOARD=your_board LOG=2 all *Look for*: - Setup request handling errors - Endpoint configuration problems - String descriptor issues *Solutions*: - Implement all required descriptors - Check endpoint sizes match descriptors - Ensure control endpoint (EP0) handling is correct **Data transfer issues** Device enumerates but data doesn't transfer correctly. *Common causes*: - Buffer overruns in class callbacks - Incorrect endpoint usage (IN vs OUT) - Flow control issues in CDC class *Solutions*: - Check buffer sizes in callbacks - Verify endpoint directions in descriptors - Implement proper flow control Host Mode Problems ------------------ **No devices detected** Host application doesn't see connected devices. *Hardware checks*: - Power supply adequate for host mode - USB-A connector for host (not micro-USB) - Board supports host mode on selected port *Software checks*: - ``tuh_task()`` called regularly - Host stack enabled in ``tusb_config.h`` - Correct root hub port configuration **Device enumeration fails** Devices connect but enumeration fails. *Diagnosis*: .. code-block:: bash # Enable host logging make BOARD=your_board LOG=2 RHPORT_HOST=1 all *Common issues*: - Power supply insufficient during enumeration - Timing issues with slow devices - USB hub compatibility problems **Class driver issues** Device enumerates but class-specific communication fails. *Troubleshooting*: - Check device descriptors match expected class - Verify interface/endpoint assignments - Some devices need device-specific handling Performance Issues ================== Slow Transfer Speeds -------------------- **Symptoms**: Lower than expected USB transfer rates *Causes and solutions*: Improve **task scheduling** by calling ``tud_task()``/``tuh_task()`` more frequently to ensure timely USB event processing. Consider increasing **endpoint buffer sizes** for bulk transfers to reduce the frequency of small transfers. Enable **DMA usage** for USB transfers if your hardware supports it to offload CPU processing. Finally, use **High Speed** (480 Mbps) instead of Full Speed (12 Mbps) when possible to achieve better throughput. High CPU Usage -------------- **Symptoms**: MCU spending too much time in USB handling *Solutions*: - Use efficient logging (RTT/SWO instead of UART) - Reduce log level in production builds - Optimize descriptor parsing - Use DMA for data transfers Hardware-Specific Issues ======================== STM32 Issues ------------ **Clock configuration problems**: - USB requires precise 48MHz clock - HSE crystal must be configured correctly - PLL settings affect USB timing **Pin configuration**: - USB pins need specific alternate function settings - VBUS sensing configuration - ID pin for OTG applications RP2040 Issues ------------- **PIO-USB for host mode**: - Requires specific pin assignments - CPU overclocking may be needed for reliable operation - Timing-sensitive - avoid long interrupt disable periods ESP32 Issues ------------ **USB peripheral differences**: - ESP32-S2/S3/P4 have different USB capabilities - DMA configuration varies between models Advanced Debugging ================== Using USB Analyzers ------------------- For complex issues, hardware USB analyzers provide detailed protocol traces: - **Wireshark** with USBPcap (Windows) or usbmon (Linux) - **Hardware analyzers**: Total Phase Beagle, LeCroy USB analyzers - **Logic analyzers**: For timing analysis of USB signals Debugging with GDB ------------------ Debugging with traditional debuggers is limited due to the real time nature of USB. However, especially for diagnosis of crashes, it can still be useful. .. code-block:: bash # Build with debug info make BOARD=your_board DEBUG=1 all # Use with debugger arm-none-eabi-gdb build/your_app.elf *Useful breakpoints*: - ``dcd_int_handler()`` - USB interrupt entry - ``tud_task()`` - Main device task - Class-specific callbacks Custom Logging -------------- For production debugging, implement custom logging: .. code-block:: c // In tusb_config.h #define CFG_TUSB_DEBUG_PRINTF my_printf // Your implementation void my_printf(const char* format, ...) { // Send to RTT, SWO, or custom interface } Getting Help ============ When reporting issues: 1. **Minimal reproducible example**: Simplify to bare minimum 2. **Build information**: Board, toolchain version, build flags 3. **Logs**: Include output with ``LOG=2`` enabled 4. **Hardware details**: Board revision, USB connections, power supply 5. **Host environment**: OS version, USB port type **Resources**: - GitHub Discussions: https://github.com/hathach/tinyusb/discussions - Issue Tracker: https://github.com/hathach/tinyusb/issues - Documentation: https://docs.tinyusb.org ================================================ FILE: examples/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../hw/bsp/family_support.cmake) project(tinyusb_examples C CXX ASM) set(EXAMPLES_LIST device dual host typec ) set(MAPJSON_PATTERNS "") foreach (example ${EXAMPLES_LIST}) add_subdirectory(${example}) list(APPEND MAPJSON_PATTERNS "${CMAKE_BINARY_DIR}/${example}/*/*.map.json") endforeach () # Post-build: run metrics.py on all map.json files find_package(Python3 REQUIRED COMPONENTS Interpreter) add_custom_target(tinyusb_metrics COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/metrics.py combine -f tinyusb/src -j -o ${CMAKE_BINARY_DIR}/metrics ${MAPJSON_PATTERNS} COMMENT "Generating average code size metrics" VERBATIM ) #add_custom_command(TARGET tinyusb_metrics POST_BUILD # COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/metrics.py compare ${TOP}/cmake-build/cmake-build-${BOARD}/metrics.json ${CMAKE_BINARY_DIR}/metrics.json # COMMENT "Generating average code size metrics" # VERBATIM # ) ================================================ FILE: examples/CMakePresets.json ================================================ { "version": 6, "include": [ "../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/build_system/cmake/cpu/arm1176jzf-s.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=arm1176jzf-s -ffreestanding ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=arm1176jzf-s -mfpu=none -mfloat-abi=soft -ffreestanding ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") endif () ================================================ FILE: examples/build_system/cmake/cpu/arm926ej-s.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=arm926ej-s -ffreestanding ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=arm926ej-s -mfpu=none -mfloat-abi=soft -ffreestanding ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-a53.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=cortex-a53 ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-a53 ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-a72.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=cortex-a72 ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-a72 ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m0.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m0 -mfloat-abi=soft ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m0 ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m0plus.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m0plus -mfloat-abi=soft ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m0plus ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m23.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m23 -mfloat-abi=soft ) set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m23 ) set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m23 ) set(FREERTOS_PORT IAR_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m3.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m3 ) set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m3 ) set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m3 ) set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m33+nodsp -mfloat-abi=soft ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") message(FATAL_ERROR "Clang is not supported for this target") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m33+nodsp ) set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m33+nodsp -mfloat-abi=hard -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m33+nodsp -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m33+nodsp --fpu VFPv5-SP ) set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m33.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m33 --fpu VFPv5-SP ) set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m4-nofpu.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m4 -mfloat-abi=soft ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") endif () elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m4 ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") endif () elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m4 --fpu none ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "") endif () endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m4.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") endif () elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") endif () elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m4 --fpu VFPv4_sp ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "") endif () endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m55.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m55 -mfloat-abi=hard -mfpu=fpv5-d16 -mcmse ) set(FREERTOS_PORT GCC_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m55 -mfpu=fpv5-d16 -mcmse ) set(FREERTOS_PORT GCC_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m55 --fpu VFPv5_D16 --cmse ) set(FREERTOS_PORT IAR_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m7 --fpu VFPv5_sp ) set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m7.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m7 -mfpu=fpv5-d16 ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m7 --fpu VFPv5_D16 ) set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/cortex-m85.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mthumb -mcpu=cortex-m85 -mfloat-abi=hard -mfpu=fpv5-d16 ) set(FREERTOS_PORT GCC_ARM_CM85_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m85 -mfpu=fpv5-d16 ) set(FREERTOS_PORT GCC_ARM_CM85_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m85 --fpu VFPv5_D16 ) set(FREERTOS_PORT IAR_ARM_CM85_NTZ_NONSECURE CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/ft32.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -fvar-tracking -fvar-tracking-assignments ) elseif (TOOLCHAIN STREQUAL "clang") message(FATAL_ERROR "Clang is not supported for this target") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR is not supported for this target") endif () ================================================ FILE: examples/build_system/cmake/cpu/msp430.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") message(FATAL_ERROR "Clang is not supported for this target") elseif (TOOLCHAIN STREQUAL "iar") set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/rv32i-ilp32.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/rv32imac-ilp32.cmake ================================================ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") message(FATAL_ERROR "IAR not supported") set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") endif () ================================================ FILE: examples/build_system/cmake/cpu/rx610.cmake ================================================ if (NOT DEFINED TOOLCHAIN OR TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=rx610 -misa=v1 -mlittle-endian-data -fshort-enums ) set(FREERTOS_PORT GCC_RX600 CACHE INTERNAL "") else () message(FATAL_ERROR "Toolchain ${TOOLCHAIN} is not supported for RX") endif () ================================================ FILE: examples/build_system/cmake/cpu/rx64m.cmake ================================================ if (NOT DEFINED TOOLCHAIN OR TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=rx64m -misa=v2 -mlittle-endian-data -fshort-enums ) set(FREERTOS_PORT GCC_RX600 CACHE INTERNAL "") else () message(FATAL_ERROR "Toolchain ${TOOLCHAIN} is not supported for RX") endif () ================================================ FILE: examples/build_system/cmake/toolchain/aarch64_gcc.cmake ================================================ if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "aarch64-none-elf-gcc") endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "aarch64-none-elf-g++") endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE aarch64-none-elf-size) find_program(CMAKE_OBJCOPY aarch64-none-elf-objcopy) find_program(CMAKE_OBJDUMP aarch64-none-elf-objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/cmake/toolchain/arm_clang.cmake ================================================ if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "clang") endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "clang++") endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE llvm-size) find_program(CMAKE_OBJCOPY llvm-objcopy) find_program(CMAKE_OBJDUMP llvm-objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/cmake/toolchain/arm_gcc.cmake ================================================ if (RTOS STREQUAL zephyr) return() endif () if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "arm-none-eabi-gcc") endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "arm-none-eabi-g++") endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE arm-none-eabi-size) find_program(CMAKE_OBJCOPY arm-none-eabi-objcopy) find_program(CMAKE_OBJDUMP arm-none-eabi-objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/cmake/toolchain/arm_iar.cmake ================================================ if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "iccarm") endif() if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "iccarm") endif() if (NOT DEFINED CMAKE_ASM_COMPILER) set(CMAKE_ASM_COMPILER "iasmarm") endif() find_program(CMAKE_SIZE size) find_program(CMAKE_OBJCOPY ielftool) find_program(CMAKE_OBJDUMP iefdumparm) find_program(CMAKE_IAR_CSTAT icstat) find_program(CMAKE_IAR_CHECKS ichecks) find_program(CMAKE_IAR_REPORT ireport) if (IAR_CSTAT) cmake_minimum_required(VERSION 4.1) set(CMAKE_C_ICSTAT ${CMAKE_IAR_CSTAT} --checks=${CMAKE_CURRENT_LIST_DIR}/cstat_sel_checks.txt --db=${CMAKE_BINARY_DIR}/cstat.db --sarif_dir=${CMAKE_BINARY_DIR}/cstat_sarif --exclude=${TOP}/hw/mcu --exclude=${TOP}/lib ) endif () include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) ================================================ FILE: examples/build_system/cmake/toolchain/common.cmake ================================================ include(CMakePrintHelpers) # ---------------------------------------------------------------------------- # Common # ---------------------------------------------------------------------------- set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_CPU}) set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) # Look for includes and libraries only in the target system prefix. set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # pass TOOLCHAIN_CPU to set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR CMAKE_SYSTEM_CPU) include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_CPU}.cmake) # ---------------------------------------------------------------------------- # Compile flags # ---------------------------------------------------------------------------- set(TOOLCHAIN_C_FLAGS) set(TOOLCHAIN_ASM_FLAGS) set(TOOLCHAIN_EXE_LINKER_FLAGS) if (TOOLCHAIN STREQUAL "gcc" OR TOOLCHAIN STREQUAL "clang") list(APPEND TOOLCHAIN_COMMON_FLAGS -fdata-sections -ffunction-sections # -fsingle-precision-constant # not supported by clang -fno-strict-aliasing -g # include debug info for bloaty ) set(TOOLCHAIN_EXE_LINKER_FLAGS "-Wl,--print-memory-usage -Wl,--gc-sections -Wl,--cref") if (TOOLCHAIN STREQUAL clang) set(TOOLCHAIN_ASM_FLAGS "-x assembler-with-cpp") endif () elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_C_FLAGS --debug) set(TOOLCHAIN_EXE_LINKER_FLAGS --diag_suppress=Li065) endif () # join the toolchain flags into a single string list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) set(CMAKE_C_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_C_FLAGS}") set(CMAKE_CXX_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_C_FLAGS}") set(CMAKE_ASM_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_ASM_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS_INIT ${TOOLCHAIN_EXE_LINKER_FLAGS}) ================================================ FILE: examples/build_system/cmake/toolchain/cstat_sel_checks.txt ================================================ # IAR C-STAT Checks Manifest Handler V2.7.5.562 # MISRAC2012-Dir-4.3 MISRAC2012-Dir-4.7_c MISRAC2012-Dir-4.10 MISRAC2012-Dir-4.11_a MISRAC2012-Dir-4.11_b MISRAC2012-Dir-4.11_c MISRAC2012-Dir-4.11_d MISRAC2012-Dir-4.11_e MISRAC2012-Dir-4.11_f MISRAC2012-Dir-4.11_g MISRAC2012-Dir-4.11_h MISRAC2012-Dir-4.11_i MISRAC2012-Dir-4.12 MISRAC2012-Dir-4.14_a MISRAC2012-Dir-4.14_b MISRAC2012-Dir-4.14_c MISRAC2012-Dir-4.14_d MISRAC2012-Dir-4.14_e MISRAC2012-Dir-4.14_f MISRAC2012-Dir-4.14_g MISRAC2012-Dir-4.14_h MISRAC2012-Dir-4.14_i MISRAC2012-Dir-4.14_j MISRAC2012-Dir-4.14_l MISRAC2012-Dir-4.14_m MISRAC2012-Dir-4.15 MISRAC2012-Rule-1.3_a MISRAC2012-Rule-1.3_b MISRAC2012-Rule-1.3_c MISRAC2012-Rule-1.3_d MISRAC2012-Rule-1.3_e MISRAC2012-Rule-1.3_f MISRAC2012-Rule-1.3_g MISRAC2012-Rule-1.3_h MISRAC2012-Rule-1.3_i MISRAC2012-Rule-1.3_j MISRAC2012-Rule-1.3_k MISRAC2012-Rule-1.3_l MISRAC2012-Rule-1.3_m MISRAC2012-Rule-1.3_n MISRAC2012-Rule-1.3_o MISRAC2012-Rule-1.3_p MISRAC2012-Rule-1.3_q MISRAC2012-Rule-1.3_r MISRAC2012-Rule-1.3_s MISRAC2012-Rule-1.3_t MISRAC2012-Rule-1.3_u MISRAC2012-Rule-1.3_v MISRAC2012-Rule-1.4 MISRAC2012-Rule-1.5_b MISRAC2012-Rule-1.5_c MISRAC2012-Rule-1.5_d MISRAC2012-Rule-1.5_e MISRAC2012-Rule-1.5_f MISRAC2012-Rule-1.5_g MISRAC2012-Rule-2.1_a MISRAC2012-Rule-2.1_b MISRAC2012-Rule-2.2_a MISRAC2012-Rule-2.2_b MISRAC2012-Rule-2.2_c MISRAC2012-Rule-3.1 MISRAC2012-Rule-3.2 MISRAC2012-Rule-5.1 MISRAC2012-Rule-5.2_c89 MISRAC2012-Rule-5.2_c99 MISRAC2012-Rule-5.3_c89 MISRAC2012-Rule-5.3_c99 MISRAC2012-Rule-5.4_c89 MISRAC2012-Rule-5.4_c99 MISRAC2012-Rule-5.5_c89 MISRAC2012-Rule-5.5_c99 MISRAC2012-Rule-5.6 MISRAC2012-Rule-5.7 MISRAC2012-Rule-5.8 MISRAC2012-Rule-6.1 MISRAC2012-Rule-6.2 MISRAC2012-Rule-6.3 MISRAC2012-Rule-7.1 MISRAC2012-Rule-7.2 MISRAC2012-Rule-7.3 MISRAC2012-Rule-7.4_a MISRAC2012-Rule-7.4_b MISRAC2012-Rule-7.5 MISRAC2012-Rule-7.6 MISRAC2012-Rule-8.1 MISRAC2012-Rule-8.2_a MISRAC2012-Rule-8.2_b MISRAC2012-Rule-8.3 MISRAC2012-Rule-8.4 MISRAC2012-Rule-8.5_a MISRAC2012-Rule-8.5_b MISRAC2012-Rule-8.10 MISRAC2012-Rule-8.12 MISRAC2012-Rule-8.14 MISRAC2012-Rule-8.15 MISRAC2012-Rule-9.1_a MISRAC2012-Rule-9.1_b MISRAC2012-Rule-9.1_d MISRAC2012-Rule-9.1_e MISRAC2012-Rule-9.2 MISRAC2012-Rule-9.3 MISRAC2012-Rule-9.4 MISRAC2012-Rule-9.5_a MISRAC2012-Rule-9.5_b MISRAC2012-Rule-9.6 MISRAC2012-Rule-9.7 MISRAC2012-Rule-10.1_R2 MISRAC2012-Rule-10.1_R3 MISRAC2012-Rule-10.1_R4 MISRAC2012-Rule-10.1_R5 MISRAC2012-Rule-10.1_R6 MISRAC2012-Rule-10.1_R7 MISRAC2012-Rule-10.1_R8 MISRAC2012-Rule-10.1_R10 MISRAC2012-Rule-10.2 MISRAC2012-Rule-10.3 MISRAC2012-Rule-10.4_a MISRAC2012-Rule-10.4_b MISRAC2012-Rule-10.6 MISRAC2012-Rule-10.7 MISRAC2012-Rule-10.8 MISRAC2012-Rule-11.1 MISRAC2012-Rule-11.2 MISRAC2012-Rule-11.3 MISRAC2012-Rule-11.6 MISRAC2012-Rule-11.7 MISRAC2012-Rule-11.8 MISRAC2012-Rule-11.9 MISRAC2012-Rule-11.10 MISRAC2012-Rule-12.2 MISRAC2012-Rule-12.5 MISRAC2012-Rule-12.6 MISRAC2012-Rule-13.1 MISRAC2012-Rule-13.2_a MISRAC2012-Rule-13.2_b MISRAC2012-Rule-13.2_c MISRAC2012-Rule-13.5 MISRAC2012-Rule-13.6 MISRAC2012-Rule-14.1_a MISRAC2012-Rule-14.1_b MISRAC2012-Rule-14.2 MISRAC2012-Rule-14.3_a MISRAC2012-Rule-14.3_b MISRAC2012-Rule-14.4_a MISRAC2012-Rule-14.4_b MISRAC2012-Rule-14.4_c MISRAC2012-Rule-14.4_d MISRAC2012-Rule-15.2 MISRAC2012-Rule-15.3 MISRAC2012-Rule-15.6_a MISRAC2012-Rule-15.6_b MISRAC2012-Rule-15.6_c MISRAC2012-Rule-15.6_d MISRAC2012-Rule-15.6_e MISRAC2012-Rule-15.7 MISRAC2012-Rule-16.1 MISRAC2012-Rule-16.2 MISRAC2012-Rule-16.3 MISRAC2012-Rule-16.4 MISRAC2012-Rule-16.5 MISRAC2012-Rule-16.6 MISRAC2012-Rule-16.7 MISRAC2012-Rule-17.1 MISRAC2012-Rule-17.2_a MISRAC2012-Rule-17.2_b MISRAC2012-Rule-17.3 MISRAC2012-Rule-17.4 MISRAC2012-Rule-17.5 MISRAC2012-Rule-17.6 MISRAC2012-Rule-17.7 MISRAC2012-Rule-17.13 MISRAC2012-Rule-18.1_a MISRAC2012-Rule-18.1_b MISRAC2012-Rule-18.1_c MISRAC2012-Rule-18.1_d MISRAC2012-Rule-18.2 MISRAC2012-Rule-18.3 MISRAC2012-Rule-18.4 MISRAC2012-Rule-18.6_a MISRAC2012-Rule-18.6_b MISRAC2012-Rule-18.6_c MISRAC2012-Rule-18.6_d MISRAC2012-Rule-18.7 MISRAC2012-Rule-18.8 MISRAC2012-Rule-18.9 MISRAC2012-Rule-18.10 MISRAC2012-Rule-19.1 MISRAC2012-Rule-20.2 MISRAC2012-Rule-20.4_c89 MISRAC2012-Rule-20.4_c99 MISRAC2012-Rule-20.6_a MISRAC2012-Rule-20.6_b MISRAC2012-Rule-20.7 MISRAC2012-Rule-21.1 MISRAC2012-Rule-21.2 MISRAC2012-Rule-21.3 MISRAC2012-Rule-21.4 MISRAC2012-Rule-21.5 MISRAC2012-Rule-21.6 MISRAC2012-Rule-21.7 MISRAC2012-Rule-21.8 MISRAC2012-Rule-21.9 MISRAC2012-Rule-21.10 MISRAC2012-Rule-21.12_a MISRAC2012-Rule-21.12_b MISRAC2012-Rule-21.12_c MISRAC2012-Rule-21.13 MISRAC2012-Rule-21.14 MISRAC2012-Rule-21.15 MISRAC2012-Rule-21.16 MISRAC2012-Rule-21.17_a MISRAC2012-Rule-21.17_b MISRAC2012-Rule-21.17_c MISRAC2012-Rule-21.17_d MISRAC2012-Rule-21.17_e MISRAC2012-Rule-21.17_f MISRAC2012-Rule-21.18_a MISRAC2012-Rule-21.18_b MISRAC2012-Rule-21.19_a MISRAC2012-Rule-21.19_b MISRAC2012-Rule-21.20 MISRAC2012-Rule-21.21 MISRAC2012-Rule-21.22 MISRAC2012-Rule-21.23 MISRAC2012-Rule-21.24 MISRAC2012-Rule-21.25 MISRAC2012-Rule-22.1_a MISRAC2012-Rule-22.1_b MISRAC2012-Rule-22.2_a MISRAC2012-Rule-22.2_b MISRAC2012-Rule-22.2_c MISRAC2012-Rule-22.3 MISRAC2012-Rule-22.4 MISRAC2012-Rule-22.5_a MISRAC2012-Rule-22.5_b MISRAC2012-Rule-22.6 MISRAC2012-Rule-22.7_a MISRAC2012-Rule-22.7_b MISRAC2012-Rule-22.8 MISRAC2012-Rule-22.9 MISRAC2012-Rule-22.10 MISRAC2012-Rule-23.2 MISRAC2012-Rule-23.4 MISRAC2012-Rule-23.6 MISRAC2012-Rule-23.8 ================================================ FILE: examples/build_system/cmake/toolchain/ft32_gcc.cmake ================================================ if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "ft32-elf-gcc") endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "ft32-elf-g++") endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE ft32-elf-size) find_program(CMAKE_OBJCOPY ft32-elf-objcopy) find_program(CMAKE_OBJDUMP ft32-elf-objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/cmake/toolchain/msp430_gcc.cmake ================================================ if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "msp430-elf-gcc") endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER "msp430-elf-g++") endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE msp430-elf-size) find_program(CMAKE_OBJCOPY msp430-elf-objcopy) find_program(CMAKE_OBJDUMP msp430-elf-objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) ================================================ FILE: examples/build_system/cmake/toolchain/riscv_gcc.cmake ================================================ # default Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack if (NOT DEFINED CROSS_COMPILE) set(CROSS_COMPILE "riscv-none-elf-") endif () if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE ${CROSS_COMPILE}size) find_program(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy) find_program(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/cmake/toolchain/rx_gcc.cmake ================================================ # Cross Compiler for RX if (NOT DEFINED CROSS_COMPILE) set(CROSS_COMPILE "rx-elf-") endif () if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) find_program(CMAKE_SIZE ${CROSS_COMPILE}size) find_program(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy) find_program(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump) include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) if (IS_IN_TRY_COMPILE) set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") cmake_print_variables(CMAKE_C_LINK_FLAGS) endif () ================================================ FILE: examples/build_system/make/cpu/arm1176jzf-s.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mcpu=arm1176jzf-s \ else ifeq ($(TOOLCHAIN),iar) #CFLAGS += --cpu cortex-a53 #ASFLAGS += --cpu cortex-a53 endif ================================================ FILE: examples/build_system/make/cpu/arm926ej-s.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mcpu=arm926ej-s \ else ifeq ($(TOOLCHAIN),iar) #CFLAGS += --cpu cortex-a53 #ASFLAGS += --cpu cortex-a53 endif ================================================ FILE: examples/build_system/make/cpu/cortex-a53.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mcpu=cortex-a53 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-a53 \ ASFLAGS += \ --cpu cortex-a53 \ endif ================================================ FILE: examples/build_system/make/cpu/cortex-a72.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mcpu=cortex-a72 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-a72 \ ASFLAGS += \ --cpu cortex-a72 \ endif ================================================ FILE: examples/build_system/make/cpu/cortex-m0.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m0 \ -mfloat-abi=soft \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m0 \ else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0 ASFLAGS += --cpu cortex-m0 else $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM0 ================================================ FILE: examples/build_system/make/cpu/cortex-m0plus.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m0plus \ -mfloat-abi=soft \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m0plus \ else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0+ ASFLAGS += --cpu cortex-m0+ else $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM0 ================================================ FILE: examples/build_system/make/cpu/cortex-m23.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m23 \ -mfloat-abi=soft \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m23 \ else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m23 ASFLAGS += --cpu cortex-m23 else $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM23 ================================================ FILE: examples/build_system/make/cpu/cortex-m3.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m3 \ -mfloat-abi=soft \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m3 \ else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m3 ASFLAGS += --cpu cortex-m3 else $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM3 ================================================ FILE: examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m33+nodsp \ -mfloat-abi=soft \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m33 \ -mfpu=softvp \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m33+nodsp \ ASFLAGS += \ --cpu cortex-m33+nodsp \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure ================================================ FILE: examples/build_system/make/cpu/cortex-m33.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m33 \ -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m33 \ -mfpu=fpv5-sp-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ ASFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure ================================================ FILE: examples/build_system/make/cpu/cortex-m4-nofpu.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m4 \ -mfloat-abi=soft else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m4 else ifeq ($(TOOLCHAIN),iar) CFLAGS += --cpu cortex-m4 --fpu none ASFLAGS += --cpu cortex-m4 --fpu none else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM3 ================================================ FILE: examples/build_system/make/cpu/cortex-m4.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m4 \ -mfpu=fpv4-sp-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += --cpu cortex-m4 --fpu VFPv4-SP ASFLAGS += --cpu cortex-m4 --fpu VFPv4-SP else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM4F ================================================ FILE: examples/build_system/make/cpu/cortex-m55.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m55 \ -mfloat-abi=hard \ -mfpu=fpv5-d16 \ -mcmse else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m55 \ -mfpu=fpv5-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m55 \ --fpu VFPv5_D16 \ ASFLAGS += \ --cpu cortex-m55 \ --fpu VFPv5_D16 \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM55_NTZ/non_secure ================================================ FILE: examples/build_system/make/cpu/cortex-m7-fpsp.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m7 \ -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m7 \ -mfpu=fpv5-sp-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m7 \ --fpu VFPv5_sp \ ASFLAGS += \ --cpu cortex-m7 \ --fpu VFPv5_sp \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 ================================================ FILE: examples/build_system/make/cpu/cortex-m7.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m7 \ -mfloat-abi=hard \ -mfpu=fpv5-d16 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m7 \ -mfpu=fpv5-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m7 \ --fpu VFPv5_D16 \ ASFLAGS += \ --cpu cortex-m7 \ --fpu VFPv5_D16 \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 ================================================ FILE: examples/build_system/make/cpu/cortex-m85.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -mthumb \ -mcpu=cortex-m85 \ -mfloat-abi=hard \ -mfpu=fpv5-d16 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ --target=arm-none-eabi \ -mcpu=cortex-m85 \ -mfpu=fpv5-d16 \ else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m85 \ --fpu VFPv5_D16 \ ASFLAGS += \ --cpu cortex-m85 \ --fpu VFPv5_D16 \ else $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM85_NTZ/non_secure ================================================ FILE: examples/build_system/make/cpu/msp430.mk ================================================ ifeq ($(TOOLCHAIN),gcc) # nothing to add else ifeq ($(TOOLCHAIN),clang) # nothing to add else ifeq ($(TOOLCHAIN),iar) # nothing to add else $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/GCC_MSP430F449 ================================================ FILE: examples/build_system/make/cpu/rv32i-ilp32.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -march=rv32i_zicsr \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ -march=rv32i_zicsr \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),iar) $(error not support) endif # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V ================================================ FILE: examples/build_system/make/cpu/rv32imac-ilp32.mk ================================================ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ -march=rv32imac_zicsr_zifencei \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),clang) CFLAGS += \ -march=rv32imac_zicsr_zifencei \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),iar) $(error not support) endif # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V ================================================ FILE: examples/build_system/make/toolchain/arm_clang.mk ================================================ CC = clang CXX = clang++ AS = $(CC) -x assembler-with-cpp LD = $(CC) GDB = $(CROSS_COMPILE)gdb OBJCOPY = llvm-objcopy SIZE = llvm-size include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk ================================================ FILE: examples/build_system/make/toolchain/arm_gcc.mk ================================================ # makefile for arm gcc toolchain # Can be set by family, default to ARM GCC CROSS_COMPILE ?= arm-none-eabi- CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ AS = $(CC) -x assembler-with-cpp LD = $(CC) GDB = $(CROSS_COMPILE)gdb OBJCOPY = $(CROSS_COMPILE)objcopy SIZE = $(CROSS_COMPILE)size CFLAGS += \ -fsingle-precision-constant \ LIBS += -lgcc -lm -lnosys include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk ================================================ FILE: examples/build_system/make/toolchain/arm_iar.mk ================================================ # makefile for arm iar toolchain CC = iccarm AS = iasmarm LD = ilinkarm OBJCOPY = ielftool --silent SIZE = size # Enable extension mode (gcc compatible) CFLAGS += -e --debug --silent # silent mode ASFLAGS += -S $(addprefix -I,$(INC)) ================================================ FILE: examples/build_system/make/toolchain/clang_rules.mk ================================================ include ${TOP}/examples/build_system/make/toolchain/gcc_rules.mk ================================================ FILE: examples/build_system/make/toolchain/gcc_common.mk ================================================ # --------------------------------------- # Compiler Flags # --------------------------------------- CFLAGS += \ -MD \ -ggdb \ -fdata-sections \ -ffunction-sections \ -fno-strict-aliasing \ -Wall \ -Wextra \ -Werror \ -Wfatal-errors \ -Wdouble-promotion \ -Wstrict-prototypes \ -Wstrict-overflow \ -Werror-implicit-function-declaration \ -Wfloat-equal \ -Wundef \ -Wshadow \ -Wwrite-strings \ -Wsign-compare \ -Wmissing-format-attribute \ -Wunreachable-code \ -Wcast-align \ -Wcast-function-type \ -Wcast-qual \ -Wnull-dereference \ -Wuninitialized \ -Wunused \ -Wreturn-type \ -Wredundant-decls \ CFLAGS_CLANG += \ -Wno-error=unknown-warning-option # -Wmissing-prototypes \ # conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion # -Wconversion # Size Optimization as default CFLAGS_OPTIMIZED ?= -Os # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -O0 NO_LTO = 1 else CFLAGS += $(CFLAGS_OPTIMIZED) endif # --------------------------------------- # Linker Flags # --------------------------------------- LDFLAGS += \ -Wl,-Map=$@.map \ -Wl,--cref \ -Wl,-gc-sections \ # renesas rx does not support --print-memory-usage flags ifneq ($(FAMILY),rx) LDFLAGS += -Wl,--print-memory-usage endif ifeq ($(TOOLCHAIN),gcc) CC_VERSION := $(shell $(CC) -dumpversion) CC_VERSION_MAJOR = $(firstword $(subst ., ,$(CC_VERSION))) # from version 12 ifeq ($(strip $(if $(CMDEXE),\ $(shell if $(CC_VERSION_MAJOR) geq 12 (echo 1) else (echo 0)),\ $(shell expr $(CC_VERSION_MAJOR) \>= 12))), 1) LDFLAGS += -Wl,--no-warn-rwx-segment endif endif ================================================ FILE: examples/build_system/make/toolchain/gcc_rules.mk ================================================ SRC_S += $(SRC_S_GCC) # Assembly files can be name with upper case .S, convert it to .s SRC_S := $(SRC_S:.S=.s) # Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 # assembly file should be placed first in linking order # '_asm' suffix is added to object of assembly file OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=_asm.o)) OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) CFLAGS += $(CFLAGS_GCC) -MD # LTO makes it difficult to analyze map file for optimizing size purpose # We will run this option in ci ifeq ($(NO_LTO),1) CFLAGS := $(filter-out -flto,$(CFLAGS)) endif ifneq ($(CFLAGS_SKIP),) CFLAGS := $(filter-out $(CFLAGS_SKIP),$(CFLAGS)) endif ifeq ($(TOOLCHAIN),clang) CFLAGS += $(CFLAGS_CLANG) LDFLAGS += $(CFLAGS) $(LDFLAGS_CLANG) else LDFLAGS += $(CFLAGS) $(LDFLAGS_GCC) endif # TODO should be removed after all examples are updated ifdef LD_FILE LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE) endif ifdef LD_FILE_GCC LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE_GCC) endif ASFLAGS += $(CFLAGS) # libc ifneq ($(BOARD), spresense) LIBS += -lc endif # --------------------------------------- # Rules # --------------------------------------- # Compile .c file $(BUILD)/obj/%.o: %.c @echo CC $(notdir $@) @$(CC) $(CFLAGS) -c -o $@ $< # ASM sources lower case .s $(BUILD)/obj/%_asm.o: %.s @echo AS $(notdir $@) @$(AS) $(ASFLAGS) -c -o $@ $< # ASM sources upper case .S $(BUILD)/obj/%_asm.o: %.S @echo AS $(notdir $@) @$(AS) $(ASFLAGS) -c -o $@ $< OBJCOPY_BIN_OPTION ?= $(BUILD)/$(PROJECT).bin: $(BUILD)/$(PROJECT).elf @echo CREATE $@ $(OBJCOPY) -O binary $(OBJCOPY_BIN_OPTION) $^ $@ $(BUILD)/$(PROJECT).hex: $(BUILD)/$(PROJECT).elf @echo CREATE $@ @$(OBJCOPY) -O ihex $^ $@ $(BUILD)/$(PROJECT).elf: $(OBJ) @echo LINK $@ @$(LD) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group ================================================ FILE: examples/build_system/make/toolchain/iar_rules.mk ================================================ SRC_S += $(SRC_S_IAR) # Assembly files can be name with upper case .S, convert it to .s SRC_S := $(SRC_S:.S=.s) # Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 # assembly file should be placed first in linking order # '_asm' suffix is added to object of assembly file OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=_asm.o)) OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) # Linker script LDFLAGS += --config $(TOP)/$(LD_FILE_IAR) # --------------------------------------- # Rules # --------------------------------------- # Compile .c file $(BUILD)/obj/%.o: %.c @echo CC $(notdir $@) @$(CC) $(CFLAGS) -c -o $@ $< # ASM sources lower case .s $(BUILD)/obj/%_asm.o: %.s @echo AS $(notdir $@) @$(AS) $(ASFLAGS) -c -o $@ $< # ASM sources upper case .S $(BUILD)/obj/%_asm.o: %.S @echo AS $(notdir $@) @$(AS) $(ASFLAGS) -c -o $@ $< $(BUILD)/$(PROJECT).bin: $(BUILD)/$(PROJECT).elf @echo CREATE $@ @$(OBJCOPY) --bin $^ $@ $(BUILD)/$(PROJECT).hex: $(BUILD)/$(PROJECT).elf @echo CREATE $@ @$(OBJCOPY) --ihex $^ $@ $(BUILD)/$(PROJECT).elf: $(OBJ) @echo LINK $@ @$(LD) -o $@ $(LDFLAGS) $^ ================================================ FILE: examples/build_system/make/toolchain/riscv_gcc.mk ================================================ # makefile for arm gcc toolchain # Can be set by family, default to ARM GCC CROSS_COMPILE ?= riscv-none-elf- CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ AS = $(CC) -x assembler-with-cpp LD = $(CC) GDB = $(CROSS_COMPILE)gdb OBJCOPY = $(CROSS_COMPILE)objcopy SIZE = $(CROSS_COMPILE)size CFLAGS += \ -fsingle-precision-constant \ LIBS += -lgcc -lm -lnosys include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk ================================================ FILE: examples/device/99-tinyusb.rules ================================================ # Copy this file to the location of your distribution's udev rules, for example on Ubuntu: # sudo cp 99-tinyusb.rules /etc/udev/rules.d/ # Then reload udev configuration by executing: # sudo udevadm control --reload-rules # sudo udevadm trigger # Check SUBSYSTEM SUBSYSTEMS=="hidraw", KERNEL=="hidraw*", MODE="0666", GROUP="dialout" # Rule applies to all TinyUSB example ATTRS{idVendor}=="cafe", MODE="0666", GROUP="dialout" # Rule to blacklist TinyUSB example from being manipulated by ModemManager. SUBSYSTEMS=="usb", ATTRS{idVendor}=="cafe", ENV{ID_MM_DEVICE_IGNORE}="1" # Xplained Pro SamG55 Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="0666", GROUP="users", ENV{ID_MM_DEVICE_IGNORE}="1" SUBSYSTEMS=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="0666", GROUP="users", ENV{ID_MM_DEVICE_IGNORE}="1" # TI Stellaris/Tiva-C Launchpad ICDI SUBSYSTEM=="usb", ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666" ================================================ FILE: examples/device/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake) project(tinyusb_device_examples C CXX ASM) family_initialize_project(tinyusb_device_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY set(EXAMPLE_LIST audio_4_channel_mic audio_4_channel_mic_freertos audio_test audio_test_freertos audio_test_multi_rate board_test cdc_dual_ports cdc_msc cdc_msc_freertos cdc_uac2 dfu dfu_runtime dynamic_configuration hid_boot_interface hid_composite hid_composite_freertos hid_generic_inout hid_multiple_interface midi_test midi_test_freertos msc_dual_lun mtp net_lwip_webserver printer_to_cdc uac2_headset uac2_speaker_fb usbtmc video_capture video_capture_2ch webusb_serial ) foreach (example ${EXAMPLE_LIST}) family_add_subdirectory(${example}) endforeach () ================================================ FILE: examples/device/CMakePresets.json ================================================ { "version": 6, "include": [ "../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_4_channel_mic/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(audio_4_channel_mic C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Add libm for GCC if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_libraries(${PROJECT_NAME} PUBLIC m) endif() # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/audio_4_channel_mic/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_4_channel_mic/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c \ src/usb_descriptors.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/audio_4_channel_mic/skip.txt ================================================ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:broadcom_64bit family:espressif ================================================ FILE: examples/device/audio_4_channel_mic/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber * * 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. * */ /* plot_audio_samples.py requires following modules: * $ sudo apt install libportaudio * $ pip3 install sounddevice matplotlib * * Then run * $ python3 plot_audio_samples.py */ #include #include #include #include #include "bsp/board_api.h" #include "tusb.h" #include "tusb_config.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ #define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t clkValid; // Range states audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000]; void led_blinking_task(void); void audio_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // Init values sampFreq = AUDIO_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; // Generate dummy data uint16_t *p_buff = i2s_dummy_buffer; uint16_t dataVal = 0; for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE / 1000; cnt++) { // CH0 saw wave *p_buff++ = dataVal; // CH1 inverted saw wave *p_buff++ = 3200 + AUDIO_SAMPLE_RATE / 1000 - dataVal; dataVal += 32; // CH3 square wave *p_buff++ = cnt < (AUDIO_SAMPLE_RATE / 1000 / 2) ? 3400 : 5000; // CH4 sinus wave float t = 2 * 3.1415f * cnt / (AUDIO_SAMPLE_RATE / 1000); *p_buff++ = (uint16_t) ((int16_t) (sinf(t) * 750) + 6000); } while (1) { tud_task();// tinyusb device task led_blinking_task(); audio_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio receive callback, one frame is received every 1ms. // We assume that the audio data is read from an I2S buffer. // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } start_ms = curr_ms; tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific set request received for an interface bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); (void) itf; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; // return tud_control_xfer(rhport, p_request, &tmp, 1); return false;// Yet not implemented } // Invoked when audio class specific get request received for an interface bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); } break; // Unknown/Unsupported control selector default: TU_BREAKPOINT(); return false; } } // Feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB ret.subrange[0].bMax = 90; // +90 dB ret.subrange[0].bRes = 1; // 1 dB steps return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == 4) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); // Buffered control transfer is needed for IN flow control to work return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } TU_LOG2(" Unsupported entity: %d\r\n", entityID); return false;// Yet not implemented } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } ================================================ FILE: examples/device/audio_4_channel_mic/src/plot_audio_samples.py ================================================ #!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np import platform if __name__ == '__main__': # If you got "ValueError: No input device matching", that is because your PC name example device # differently from tested list below. Uncomment the next line to see full list and try to pick correct one # print(sd.query_devices()) fs = 48000 # Sample rate duration = 1 # Duration of recording if platform.system() == 'Windows': # WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows) device = 'Microphone (MicNode_4_Ch), Windows WASAPI' elif platform.system() == 'Darwin': device = 'MicNode_4_Ch' else: device ='default' myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=4, dtype='int16', device=device) print('Waiting...') sd.wait() # Wait until recording is finished print('Done!') time = np.arange(0, duration, 1 / fs) # time vector # strip starting zero plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode 4 Channel') plt.legend(['CH-1', 'CH-2', 'CH-3','CH-4']) plt.show() ================================================ FILE: examples/device/audio_4_channel_mic/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/audio_4_channel_mic/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN) #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #else #define EPNUM_AUDIO 0x01 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode_4_Ch", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2", // 4: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = (uint16_t) str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/audio_4_channel_mic_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(audio_4_channel_mic_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Add libm for GCC if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_libraries(${PROJECT_NAME} PUBLIC m) endif() # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/device/audio_4_channel_mic_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_4_channel_mic_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/audio_4_channel_mic_freertos/README.md ================================================ # How to build example for Esp32s3 1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) 2. cd into examples directory ``` $ cd /tinyusb/examples/device/audio_4_channel_mic_freertos ``` 3. Run cmake in project directory specifying the board ``` $ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . $ ninja.exe -C build ``` 4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 eg. > /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_4_channel_mic_freertos.bin ================================================ FILE: examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults ================================================ CONFIG_IDF_CMAKE=y CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y ================================================ FILE: examples/device/audio_4_channel_mic_freertos/skip.txt ================================================ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI mcu:RAXXX mcu:STM32L0 board:lpcxpresso11u37 board:lpcxpresso1347 family:broadcom_32bit family:broadcom_64bit family:nuc121_125 family:hpmicro ================================================ FILE: examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/audio_4_channel_mic_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber * * 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. * */ /* plot_audio_samples.py requires following modules: * $ sudo apt install libportaudio * $ pip3 install sounddevice matplotlib * * Then run * $ python3 plot_audio_samples.py */ #include #include #include #include #include "bsp/board_api.h" #include "tusb.h" #ifdef ESP_PLATFORM // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/timers.h" #define USBD_STACK_SIZE 4096 #else #include "FreeRTOS.h" #include "queue.h" #include "semphr.h" #include "task.h" #include "timers.h" // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (4 * configMINIMAL_STACK_SIZE / 2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ #define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t audio_stack[AUDIO_STACK_SIZE]; StaticTask_t audio_taskdef; #endif static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t clkValid; // Range states audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000]; void led_blinking_task(void *param); void usb_device_task(void *param); void audio_isr_task(void *param); /*------------- MAIN -------------*/ int main(void) { board_init(); // Init values sampFreq = AUDIO_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; // Generate dummy data uint16_t *p_buff = i2s_dummy_buffer; uint16_t dataVal = 0; for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE / 1000; cnt++) { // CH0 saw wave *p_buff++ = dataVal; // CH1 inverted saw wave *p_buff++ = 3200 + AUDIO_SAMPLE_RATE / 1000 - dataVal; dataVal += 32; // CH3 square wave *p_buff++ = cnt < (AUDIO_SAMPLE_RATE / 1000 / 2) ? 3400 : 5000; // CH4 sinus wave float t = 2 * 3.1415f * cnt / (AUDIO_SAMPLE_RATE / 1000); *p_buff++ = (uint16_t) ((int16_t) (sinf(t) * 750) + 6000); } #if configSUPPORT_STATIC_ALLOCATION // blinky task xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); // Create a task for tinyusb device stack xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, usb_device_stack, &usb_device_taskdef); // Audio receive (I2S) ISR simulation // To simulate a ISR the priority is set to the highest xTaskCreateStatic(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, audio_stack, &audio_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); xTaskCreate(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // tinyusb device task tud_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio receive ISR, one frame is received every 1ms. // We assume that the audio data is read from an I2S buffer. // In a real application, this would be replaced with actual I2S receive callback. void audio_isr_task(void *param) { (void) param; while (1) { vTaskDelay(1); tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); } } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific set request received for an interface bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); (void) itf; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); volume[channelNum] = ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific get request received for an interface bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; ret.bmChannelConfig = 0; ret.iChannelNames = 0; TU_LOG1(" Get terminal connector\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); } break; // Unknown/Unsupported control selector default: TU_BREAKPOINT(); return false; } } // Feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG1(" Get Mute of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Volume of channel: %u\r\n", channelNum); return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB ret.subrange[0].bMax = 90; // +90 dB ret.subrange[0].bRes = 1; // 1 dB steps return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == 4) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Sample Freq.\r\n"); // Buffered control transfer is needed for IN flow control to work return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Sample Freq. range\r\n"); return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG1(" Get Sample Freq. valid\r\n"); return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } TU_LOG1(" Unsupported entity: %d\r\n", entityID); return false;// Yet not implemented } ///--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void *param) { (void) param; static bool led_state = false; while (1) { // Blink every interval ms vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); board_led_write(led_state); led_state = 1 - led_state;// toggle } } ================================================ FILE: examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py ================================================ #!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np import platform if __name__ == '__main__': # If you got "ValueError: No input device matching", that is because your PC name example device # differently from tested list below. Uncomment the next line to see full list and try to pick correct one # print(sd.query_devices()) fs = 48000 # Sample rate duration = 100e-3 # Duration of recording if platform.system() == 'Windows': # WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows) device = 'Microphone (MicNode_4_Ch), Windows WDM-KS' elif platform.system() == 'Darwin': device = 'MicNode_4_Ch' else: device ='default' myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=4, dtype='int16', device=device) print('Waiting...') sd.wait() # Wait until recording is finished print('Done!') time = np.arange(0, duration, 1 / fs) # time vector plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode 4 Channel') plt.show() ================================================ FILE: examples/device/audio_4_channel_mic_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN) #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #else #define EPNUM_AUDIO 0x01 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode_4_Ch", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2", // 4: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/audio_test/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(audio_test C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/audio_test/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_test/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/audio_test/skip.txt ================================================ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif ================================================ FILE: examples/device/audio_test/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber * * 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. * */ /* plot_audio_samples.py requires following modules: * $ sudo apt install libportaudio * $ pip3 install sounddevice matplotlib * * Then run * $ python3 plot_audio_samples.py */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t clkValid; // Range states audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2]; uint16_t startVal = 0; void led_blinking_task(void); void audio_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // Init values sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; while (1) { tud_task();// tinyusb device task led_blinking_task(); audio_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio receive callback, one frame is received every 1ms. // We assume that the audio data is read from an I2S buffer. // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } start_ms = curr_ms; for (size_t cnt = 0; cnt < sizeof(test_buffer_audio) / 2; cnt++) { test_buffer_audio[cnt] = startVal++; } tud_audio_write((uint8_t *) test_buffer_audio, sizeof(test_buffer_audio)); } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific set request received for an interface bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); (void) itf; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; // return tud_control_xfer(rhport, p_request, &tmp, 1); return false;// Yet not implemented } // Invoked when audio class specific get request received for an interface bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); } break; // Unknown/Unsupported control selector default: TU_BREAKPOINT(); return false; } } // Feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB ret.subrange[0].bMax = 90; // +90 dB ret.subrange[0].bRes = 1; // 1 dB steps return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == 4) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } TU_LOG2(" Unsupported entity: %d\r\n", entityID); return false;// Yet not implemented } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; startVal = 0; return true; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } ================================================ FILE: examples/device/audio_test/src/plot_audio_samples.py ================================================ #!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np import platform import csv if __name__ == '__main__': # If you got "ValueError: No input device matching", that is because your PC name example device # differently from tested list below. Uncomment the next line to see full list and try to pick correct one # print(sd.query_devices()) fs = 48000 # Sample rate duration = 3 # Duration of recording if platform.system() == 'Windows': # MME is needed since there are more than one MicNode device APIs (at least in Windows) device = 'Microphone (MicNode), Windows WASAPI' elif platform.system() == 'Darwin': device = 'MicNode' else: device ='default' myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device) print('Waiting...') sd.wait() # Wait until recording is finished print('Done!') time = np.arange(0, duration, 1 / fs) # time vector plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode') plt.show() samples = np.array(myrecording) np.savetxt('Output.csv', samples, delimiter=",", fmt='%s') ================================================ FILE: examples/device/audio_test/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! #define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/audio_test/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_ONE_CH_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #else #define EPNUM_AUDIO 0x01 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2", // 4: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/audio_test_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(audio_test_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/device/audio_test_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_test_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/audio_test_freertos/README.md ================================================ # How to build example for Esp32s3 1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) 2. cd into examples directory ``` $ cd /tinyusb/examples/device/audio_test_freertos ``` 3. Run cmake in project directory specifying the board ``` $ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . $ ninja.exe -C build ``` 4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 eg. > /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin ================================================ FILE: examples/device/audio_test_freertos/sdkconfig.defaults ================================================ CONFIG_IDF_CMAKE=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y ================================================ FILE: examples/device/audio_test_freertos/skip.txt ================================================ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI mcu:RAXXX family:broadcom_32bit family:broadcom_64bit board:stm32l0538disco family:nuc121_125 family:hpmicro ================================================ FILE: examples/device/audio_test_freertos/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/audio_test_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber * * 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. * */ /* plot_audio_samples.py requires following modules: * $ sudo apt install libportaudio * $ pip3 install sounddevice matplotlib * * Then run * $ python3 plot_audio_samples.py */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #ifdef ESP_PLATFORM // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/timers.h" #define USBD_STACK_SIZE 4096 #else #include "FreeRTOS.h" #include "queue.h" #include "semphr.h" #include "task.h" #include "timers.h" // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (4 * configMINIMAL_STACK_SIZE / 2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t audio_stack[AUDIO_STACK_SIZE]; StaticTask_t audio_taskdef; #endif static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t clkValid; // Range states audio20_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state audio20_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state // Audio test data uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2]; uint16_t startVal = 0; void led_blinking_task(void *param); void usb_device_task(void *param); void audio_isr_task(void *param); /*------------- MAIN -------------*/ int main(void) { board_init(); // Init values sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; #if configSUPPORT_STATIC_ALLOCATION // blinky task xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); // Create a task for tinyusb device stack xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, usb_device_stack, &usb_device_taskdef); // Audio receive (I2S) ISR simulation // To simulate a ISR the priority is set to the highest xTaskCreateStatic(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, audio_stack, &audio_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // tinyusb device task tud_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio receive ISR, one frame is received every 1ms. // We assume that the audio data is read from an I2S buffer. // In a real application, this would be replaced with actual I2S receive callback. void audio_isr_task(void *param) { (void) param; while (1) { vTaskDelay(1); for (size_t cnt = 0; cnt < sizeof(test_buffer_audio) / 2; cnt++) { test_buffer_audio[cnt] = startVal++; } tud_audio_write((uint8_t *) test_buffer_audio, sizeof(test_buffer_audio)); } } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific set request received for an interface bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); (void) itf; // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); volume[channelNum] = (uint16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t ep = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) ep; return false;// Yet not implemented } // Invoked when audio class specific get request received for an interface bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t itf = TU_U16_LOW(p_request->wIndex); (void) channelNum; (void) ctrlSel; (void) itf; return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Page 91 in UAC2 specification uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == 1) { switch (ctrlSel) { case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; ret.bmChannelConfig = (audio20_channel_config_t) 0; ret.iChannelNames = 0; TU_LOG1(" Get terminal connector\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); } break; // Unknown/Unsupported control selector default: TU_BREAKPOINT(); return false; } } // Feature unit if (entityID == 2) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG1(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB ret.subrange[0].bMax = 90; // +90 dB ret.subrange[0].bRes = 1; // 1 dB steps return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == 4) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG1(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO20_CS_REQ_RANGE: TU_LOG1(" Get Sample Freq. range\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG1(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } TU_LOG1(" Unsupported entity: %d\r\n", entityID); return false;// Yet not implemented } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; startVal = 0; return true; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void *param) { (void) param; static bool led_state = false; while (1) { // Blink every interval ms vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); board_led_write(led_state); led_state = 1 - led_state;// toggle } } ================================================ FILE: examples/device/audio_test_freertos/src/plot_audio_samples.py ================================================ #!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np import platform if __name__ == '__main__': # If you got "ValueError: No input device matching", that is because your PC name example device # differently from tested list below. Uncomment the next line to see full list and try to pick correct one # print(sd.query_devices()) fs = 48000 # Sample rate duration = 3 # Duration of recording if platform.system() == 'Windows': # MME is needed since there are more than one MicNode device APIs (at least in Windows) device = 'Microphone (MicNode), Windows WASAPI' elif platform.system() == 'Darwin': device = 'MicNode' else: device ='default' myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device) print('Waiting...') sd.wait() # Wait until recording is finished print('Done!') time = np.arange(0, duration, 1 / fs) # time vector plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode') plt.show() ================================================ FILE: examples/device/audio_test_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! #define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/audio_test_freertos/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO20_MIC_ONE_CH_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #else #define EPNUM_AUDIO 0x01 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2", // 4: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/audio_test_multi_rate/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(audio_test_multi_rate C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/audio_test_multi_rate/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/audio_test_multi_rate/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/audio_test_multi_rate/skip.txt ================================================ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif ================================================ FILE: examples/device/audio_test_multi_rate/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber * Copyright (c) 2022 HiFiPhile * * 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. * */ /* plot_audio_samples.py requires following modules: * $ sudo apt install libportaudio * $ pip3 install sounddevice matplotlib * * Then run * $ python3 plot_audio_samples.py */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0 uint32_t sampFreq; uint8_t bytesPerSample; uint8_t clkValid; // Range states // List of supported sample rates static const uint32_t sampleRatesList[] = { 32000, 48000, 96000}; #define N_sampleRates TU_ARRAY_SIZE(sampleRatesList) // Bytes per format of every Alt settings static const uint8_t bytesPerSampleAltList[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = { CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, }; // Audio test data CFG_TUD_MEM_ALIGN uint8_t test_buffer_audio[(TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; uint16_t startVal = 0; void led_blinking_task(void); void audio_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // Init values sampFreq = sampleRatesList[0]; clkValid = 1; while (1) { tud_task();// tinyusb device task led_blinking_task(); audio_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio receive callback, one frame is received every 1ms. // We assume that the audio data is read from an I2S buffer. // In a real application, this would be replaced with actual I2S receive callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } start_ms = curr_ms; // 16bit if (bytesPerSample == 2) { uint16_t *pData_16 = (uint16_t *) ((void *) test_buffer_audio); for (size_t cnt = 0; cnt < sampFreq / 1000; cnt++) { pData_16[cnt] = startVal++; } } // 24bit in 32bit slot else if (bytesPerSample == 4) { uint32_t *pData_32 = (uint32_t *) ((void *) test_buffer_audio); for (size_t cnt = 0; cnt < sampFreq / 1000; cnt++) { pData_32[cnt] = (uint32_t) startVal++ << 16U; } } tud_audio_write((uint8_t *) test_buffer_audio, (uint16_t) (sampFreq / 1000 * bytesPerSample)); } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // UAC1 Helper Functions //--------------------------------------------------------------------+ static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { // Request uses 3 bytes TU_VERIFY(p_request->wLength == 3); sampFreq = tu_unaligned_read32(pBuff) & 0x00FFFFFF; TU_LOG2("EP set current freq: %" PRIu32 "\r\n", sampFreq); return true; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { TU_LOG2("EP get current freq\r\n"); uint8_t freq[3]; freq[0] = (uint8_t) (sampFreq & 0xFF); freq[1] = (uint8_t) ((sampFreq >> 8) & 0xFF); freq[2] = (uint8_t) ((sampFreq >> 16) & 0xFF); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our feature unit (ID defined in usbd.h) if (entityID == 0x02) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength ==1); mute[channelNum] = pBuff[0]; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; default: return false; // not supported } case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength == 2); volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; default: return false; // not supported } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our feature unit (ID defined in usbd.h) if (entityID == 0x02) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_GET_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); { int16_t vol = (int16_t) volume[channelNum]; vol = vol * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); } case AUDIO10_CS_REQ_GET_MIN: TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); { int16_t min = -90; // -90 dB min = min * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); } case AUDIO10_CS_REQ_GET_MAX: TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); { int16_t max = 30; // +30 dB max = max * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); } case AUDIO10_CS_REQ_GET_RES: TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); { int16_t res = 1; // 1 dB res = res * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } //--------------------------------------------------------------------+ // UAC2 Helper Functions //--------------------------------------------------------------------+ #if TUD_OPT_HIGH_SPEED static bool audio20_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // We do not support any set range requests here, only current value requests TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); // If request is for our feature unit if (entityID == UAC2_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Request uses format layout 1 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); mute[channelNum] = ((audio20_control_cur_1_t *) pBuff)->bCur; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; case AUDIO20_FU_CTRL_VOLUME: // Request uses format layout 2 TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); volume[channelNum] = (int16_t) ((audio20_control_cur_2_t *) pBuff)->bCur; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == UAC2_ENTITY_CLOCK) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_4_t)); sampFreq = (uint32_t) ((audio20_control_cur_4_t *) pBuff)->bCur; TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq); return true; break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Input terminal (Microphone input) if (entityID == UAC2_ENTITY_INPUT_TERMINAL) { switch (ctrlSel) { case AUDIO20_TE_CTRL_CONNECTOR: { // The terminal connector control only has a get request with only the CUR attribute. audio20_desc_channel_cluster_t ret; // Those are dummy values for now ret.bNrChannels = 1; ret.bmChannelConfig = 0; ret.iChannelNames = 0; TU_LOG2(" Get terminal connector\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); } break; // Unknown/Unsupported control selector default: TU_BREAKPOINT(); return false; } } // Feature unit if (entityID == UAC2_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO20_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO20_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); case AUDIO20_CS_REQ_RANGE: TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); // Copy values - only for testing - better is version below audio20_control_range_2_n_t(1) ret; ret.wNumSubRanges = 1; ret.subrange[0].bMin = -90;// -90 dB ret.subrange[0].bMax = 30; // +30 dB ret.subrange[0].bRes = 1; // 1 dB steps return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } // Clock Source unit if (entityID == UAC2_ENTITY_CLOCK) { switch (ctrlSel) { case AUDIO20_CS_CTRL_SAM_FREQ: // channelNum is always zero in this case switch (p_request->bRequest) { case AUDIO20_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO20_CS_REQ_RANGE: { TU_LOG2(" Get Sample Freq. range\r\n"); audio20_control_range_4_n_t(N_sampleRates) rangef = { .wNumSubRanges = tu_htole16(N_sampleRates)}; TU_LOG1("Clock get %d freq ranges\r\n", N_sampleRates); for (uint8_t i = 0; i < N_sampleRates; i++) { rangef.subrange[i].bMin = (int32_t) sampleRatesList[i]; rangef.subrange[i].bMax = (int32_t) sampleRatesList[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes); } return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &rangef, sizeof(rangef)); } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; case AUDIO20_CS_CTRL_CLK_VALID: // Only cur attribute exists for this request TU_LOG2(" Get Sample Freq. valid\r\n"); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } #endif // TUD_OPT_HIGH_SPEED //--------------------------------------------------------------------+ // Main Callback Functions //--------------------------------------------------------------------+ // Invoked when set interface is called, typically on start/stop streaming or format change bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; //uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); // Clear buffer when streaming format is changed if (alt != 0) { bytesPerSample = bytesPerSampleAltList[alt - 1]; } return true; } // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; if (tud_audio_version() == 1) { return audio10_set_req_ep(p_request, pBuff); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_ep(rhport, p_request); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; if (tud_audio_version() == 1) { return audio10_set_req_entity(p_request, pBuff); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_set_req_entity(p_request, pBuff); #endif } return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_entity(rhport, p_request); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_get_req_entity(rhport, p_request); #endif } return false;// Yet not implemented } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; startVal = 0; return true; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } ================================================ FILE: examples/device/audio_test_multi_rate/src/plot_audio_samples.py ================================================ #!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np import platform import csv if __name__ == '__main__': # If you got "ValueError: No input device matching", that is because your PC name example device # differently from tested list below. Uncomment the next line to see full list and try to pick correct one # print(sd.query_devices()) fs = 96000 # Sample rate duration = 100e-3 # Duration of recording if platform.system() == 'Windows': # MME is needed since there are more than one MicNode device APIs (at least in Windows) device = 'Microphone (MicNode) MME' elif platform.system() == 'Darwin': device = 'MicNode' else: device ='default' myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device) print('Waiting...') sd.wait() # Wait until recording is finished print('Done!') time = np.arange(0, duration, 1 / fs) # time vector plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode') plt.show() samples = np.array(myrecording) np.savetxt('Output.csv', samples, delimiter=",", fmt='%s') ================================================ FILE: examples/device/audio_test_multi_rate/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif #include "usb_descriptors.h" //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 // 16bit in 16bit slots #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16 // 24bit in 32bit slots (UAC2 only) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 24 // Have a look into audio_device.h for all configurations #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! // UAC1 (Full-Speed) Endpoint size calculation #define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(false, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // UAC2 (High-Speed) Endpoint size calculation #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) // Tx flow control needs buffer size >= 4* EP size to work correctly // Example write FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/audio_test_multi_rate/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2022 HiFiPhile * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #else #define EPNUM_AUDIO 0x01 #endif #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_MIC_ONE_CH_DESC_LEN(3)) uint8_t const desc_uac1_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO10_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ 2, /*_nBitsUsedPerSample*/ 16, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, 32000, 48000, 96000) }; TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); #if TUD_OPT_HIGH_SPEED #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN) uint8_t const desc2_uac2_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_epin*/ 0x80 | EPNUM_AUDIO) }; TU_VERIFY_STATIC(sizeof(desc2_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = 0x0200, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index;// for multiple configurations // if link speed is high return fullspeed config, and vice versa return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc2_uac2_configuration; } #endif// highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if(tud_speed_get() == TUSB_SPEED_FULL) { return desc_uac1_configuration; } else { return desc2_uac2_configuration; } #else return desc_uac1_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "PaniRCorp", // 1: Manufacturer "MicNode", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2", // 4: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/audio_test_multi_rate/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 HiFiPhile * * 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. * */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ // #include "tusb.h" // Unit numbers are arbitrary selected #define UAC2_ENTITY_CLOCK 0x04 #define UAC2_ENTITY_INPUT_TERMINAL 0x01 #define UAC2_ENTITY_OUTPUT_TERMINAL 0x03 #define UAC2_ENTITY_FEATURE_UNIT 0x02 #define TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 1 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO20_MIC_ONE_CH_2_FORMAT_DESCRIPTOR(_itfnum, _stridx, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS | AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS, /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_INPUT_TERMINAL, /*_srcid*/ UAC2_ENTITY_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_FEATURE_UNIT, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) #endif ================================================ FILE: examples/device/board_test/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(board_test C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() if (RTOS STREQUAL zephyr) set(EXE_NAME app) else() set(EXE_NAME ${PROJECT_NAME}) add_executable(${EXE_NAME}) endif() # Example source target_sources(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${EXE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${EXE_NAME} ${RTOS}) ================================================ FILE: examples/device/board_test/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/board_test/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/board_test/sdkconfig.defaults ================================================ CONFIG_IDF_CMAKE=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y ================================================ FILE: examples/device/board_test/src/CMakeLists.txt ================================================ idf_component_register(SRCS "main.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/board_test/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" /* Blink pattern * - 250 ms : button is not pressed * - 1000 ms : button is pressed (and hold) */ enum { BLINK_PRESSED = 250, BLINK_UNPRESSED = 1000 }; #define HELLO_STR "Hello from TinyUSB\r\n" // board test example does not use both device and host stack #if CFG_TUSB_OS != OPT_OS_NONE uint32_t tusb_time_millis_api(void) { return osal_time_millis(); } void tusb_time_delay_ms_api(uint32_t ms) { osal_task_delay(ms); } #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Task parameter type: ULONG for ThreadX, void* for FreeRTOS and noos #if CFG_TUSB_OS == OPT_OS_THREADX #define RTOS_PARAM ULONG #elif CFG_TUSB_OS == OPT_OS_FREERTOS #define RTOS_PARAM void* static void freertos_init(void); #else #define RTOS_PARAM void* #endif static void board_test_loop(RTOS_PARAM param) { (void) param; uint32_t start_ms = 0; (void) start_ms; bool led_state = false; while (1) { uint32_t interval_ms = board_button_read() ? BLINK_PRESSED : BLINK_UNPRESSED; int ch = board_getchar(); if (ch > 0) { board_putchar(ch); #ifndef LOGGER_UART board_uart_write(&ch, 1); #endif } // Blink and print every interval ms #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(interval_ms / portTICK_PERIOD_MS); #elif CFG_TUSB_OS == OPT_OS_THREADX tx_thread_sleep(_osal_ms2tick(interval_ms)); #else if (tusb_time_millis_api() - start_ms < interval_ms) { continue; // not enough time } #endif start_ms = tusb_time_millis_api(); if (ch < 0) { // skip if echoing printf(HELLO_STR); #ifndef LOGGER_UART board_uart_write(HELLO_STR, sizeof(HELLO_STR)-1); #endif } board_led_write(led_state); led_state = !led_state; // toggle } } int main(void) { board_init(); board_led_write(true); #if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); #elif CFG_TUSB_OS == OPT_OS_THREADX tx_kernel_enter(); #else board_test_loop(NULL); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #ifdef ESP_PLATFORM #define MAIN_STACK_SIZE 4096 #else #define MAIN_STACK_SIZE 512 #endif #if configSUPPORT_STATIC_ALLOCATION static StackType_t _main_stack[MAIN_STACK_SIZE]; static StaticTask_t _main_taskdef; #endif static void freertos_init(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(board_test_loop, "main", MAIN_STACK_SIZE, NULL, 1, _main_stack, &_main_taskdef); #else xTaskCreate(board_test_loop, "main", MAIN_STACK_SIZE, NULL, 1, NULL); #endif #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } //--------------------------------------------------------------------+ // ThreadX //--------------------------------------------------------------------+ #elif CFG_TUSB_OS == OPT_OS_THREADX #define MAIN_TASK_STACK_SIZE 1024 static TX_THREAD _main_thread; static ULONG _main_thread_stack[MAIN_TASK_STACK_SIZE / sizeof(ULONG)]; void tx_application_define(void *first_unused_memory) { (void) first_unused_memory; static CHAR main_thread_name[] = "main"; tx_thread_create(&_main_thread, main_thread_name, board_test_loop, 0, _main_thread_stack, MAIN_TASK_STACK_SIZE, 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } #endif ================================================ FILE: examples/device/board_test/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif // This example only test LED & GPIO, disable both device and host stack #define CFG_TUD_ENABLED 0 #define CFG_TUH_ENABLED 0 // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/cdc_dual_ports/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_dual_ports C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/cdc_dual_ports/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/cdc_dual_ports/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/cdc_dual_ports/skip.txt ================================================ board:stm32f407disco board:stm32f411disco ================================================ FILE: examples/device/cdc_dual_ports/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include #include "bsp/board_api.h" #include "tusb.h" /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static void led_blinking_task(void); static void cdc_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task cdc_task(); led_blinking_task(); } } // echo to either Serial0 or Serial1 // with Serial0 as all lower case, Serial1 as all upper case static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { uint8_t const case_diff = 'a' - 'A'; for (uint32_t i = 0; i < count; i++) { if (itf == 0) { // echo back 1st port as lower case if (isupper(buf[i])) { buf[i] += case_diff; } } else { // echo back 2nd port as upper case if (islower(buf[i])) { buf[i] -= case_diff; } } tud_cdc_n_write_char(itf, buf[i]); } tud_cdc_n_write_flush(itf); } // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ static void cdc_task(void) { for (uint8_t itf = 0; itf < CFG_TUD_CDC; itf++) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_n_connected(itf) ) { if (tud_cdc_n_available(itf)) { uint8_t buf[64]; uint32_t count = tud_cdc_n_read(itf, buf, sizeof(buf)); // echo back to both serial ports echo_serial_port(0, buf, count); echo_serial_port(1, buf, count); } // Press on-board button to send Uart status notification static uint32_t btn_prev = 0; static cdc_notify_uart_state_t uart_state = { .value = 0 }; const uint32_t btn = board_button_read(); if (!btn_prev && btn) { uart_state.dsr ^= 1; tud_cdc_notify_uart_state(&uart_state); } btn_prev = btn; } } } // Invoked when cdc when line state changed e.g connected/disconnected // Use to reset to DFU when disconnect with 1200 bps void tud_cdc_line_state_cb(uint8_t instance, bool dtr, bool rts) { (void)rts; // DTR = false is counted as disconnected if (!dtr) { // touch1200 only with first CDC instance (Serial) if (instance == 0) { cdc_line_coding_t coding; tud_cdc_get_line_coding(&coding); if (coding.bit_rate == 1200) { board_reset_to_bootloader(); } } } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/cdc_dual_ports/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by board.mk #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 2 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/cdc_dual_ports/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC_0 = 0, ITF_NUM_CDC_0_DATA, ITF_NUM_CDC_1, ITF_NUM_CDC_1_DATA, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 #define EPNUM_CDC_0_IN 0x82 #define EPNUM_CDC_1_NOTIF 0x84 #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x85 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_0_NOTIF 0x83 #define EPNUM_CDC_0_OUT 0x02 #define EPNUM_CDC_0_IN 0x81 #define EPNUM_CDC_1_NOTIF 0x86 #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x84 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 #define EPNUM_CDC_0_IN 0x83 #define EPNUM_CDC_1_NOTIF 0x84 #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x86 #else #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 #define EPNUM_CDC_0_IN 0x82 #define EPNUM_CDC_1_NOTIF 0x83 #define EPNUM_CDC_1_OUT 0x04 #define EPNUM_CDC_1_IN 0x84 #endif static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64), // 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512), // 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512), }; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index;// for multiple configurations // if link speed is high return fullspeed config, and vice versa return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration; } #endif// highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/cdc_msc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_msc C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() if (RTOS STREQUAL zephyr) set(EXE_NAME app) else() set(EXE_NAME ${PROJECT_NAME}) add_executable(${EXE_NAME}) endif() # Example source target_sources(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${EXE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${EXE_NAME} ${RTOS}) ================================================ FILE: examples/device/cdc_msc/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/cdc_msc/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c \ src/msc_disk.c \ src/usb_descriptors.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/cdc_msc/prj.conf ================================================ CONFIG_GPIO=y CONFIG_FPU=y CONFIG_NO_OPTIMIZATIONS=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_NRFX_POWER=y ================================================ FILE: examples/device/cdc_msc/skip.txt ================================================ mcu:SAMD11 family:espressif board:ch32v203g_r0_1v0 ================================================ FILE: examples/device/cdc_msc/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static bool blink_enable = true; void led_blinking_task(void); void cdc_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); cdc_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ void cdc_task(void) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_connected() ) { // connected and there are data available if (tud_cdc_available()) { // read data char buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); (void)count; // Echo back // Note: Skip echo by commenting out write() and write_flush() // for throughput test e.g // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 tud_cdc_write(buf, count); tud_cdc_write_flush(); } // Press on-board button to send Uart status notification static cdc_notify_uart_state_t uart_state = {.value = 0}; static uint32_t btn_prev = 0; const uint32_t btn = board_button_read(); if ((btn_prev == 0u) && (btn != 0u)) { uart_state.dsr ^= 1; uart_state.dcd ^= 1; tud_cdc_notify_uart_state(&uart_state); } btn_prev = btn; } } // Invoked when cdc when line state changed e.g connected/disconnected void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void)itf; (void)rts; if (dtr) { // Terminal connected blink_enable = false; board_led_write(true); } else { // Terminal disconnected blink_enable = true; } } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t itf) { (void)itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; if (blink_enable) { // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = !led_state; } } ================================================ FILE: examples/device/cdc_msc/src/msc_disk.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #if CFG_TUD_MSC // whether host does safe-eject static bool ejected = false; // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined #define README_CONTENTS \ "This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" enum { DISK_BLOCK_NUM = 16,// 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; // fat_num = 1; fat12_root_entry_num = 16; // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC"; // FAT magic code at offset 510-511 { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T', 'i', 'n', 'y', 'U', 'S', 'B', ' ', 'M', 'S', 'C', 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA }, //------------- Block1: FAT12 Table -------------// { 0xF8, 0xFF, 0xFF, 0xFF, 0x0F// first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// { // first entry is volume label 'T', 'i', 'n', 'y', 'U', 'S', 'B', ' ', 'M', 'S', 'C', 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // second entry is readme file 'R', 'E', 'A', 'D', 'M', 'E', ' ', ' ', 'T', 'X', 'T', 0x20, 0x00, 0xC6, 0x52, 0x6D, 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, sizeof(README_CONTENTS) - 1, 0x00, 0x00, 0x00// readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// {README_CONTENTS} }; // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uint32_t bufsize) { (void) lun; (void) bufsize; const char vid[] = "TinyUSB"; const char pid[] = "Mass Storage"; const char rev[] = "1.0"; (void) strncpy((char*) inquiry_resp->vendor_id, vid, 8); (void) strncpy((char*) inquiry_resp->product_id, pid, 16); (void) strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; // RAM disk is ready until ejected if (ejected) { // Additional Sense 3A-00 is NOT_FOUND return tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); } return true; } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; if (load_eject) { if (start) { // load disk storage } else { // unload disk storage ejected = true; } } return true; } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { (void) lun; // out of ramdisk if (lba >= DISK_BLOCK_NUM) { return -1; } // Check for overflow of offset + bufsize if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) { return -1; } uint8_t const *addr = msc_disk[lba] + offset; (void) memcpy(buffer, addr, bufsize); return (int32_t) bufsize; } bool tud_msc_is_writable_cb(uint8_t lun) { (void) lun; #ifdef CFG_EXAMPLE_MSC_READONLY return false; #else return true; #endif } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) { (void) lun; // out of ramdisk if (lba >= DISK_BLOCK_NUM) { return -1; } #ifndef CFG_EXAMPLE_MSC_READONLY uint8_t *addr = msc_disk[lba] + offset; (void) memcpy(addr, buffer, bufsize); #else (void) lba; (void) offset; (void) buffer; #endif return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { (void) lun; (void) scsi_cmd; (void) buffer; (void) bufsize; // currently no other commands are supported // Set Sense = Invalid Command Operation (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); return -1; // stall/failed command request; } #endif ================================================ FILE: examples/device/cdc_msc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/cdc_msc/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_MSC, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x85 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x81 #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_MSC_OUT 0x03 #define EPNUM_MSC_IN 0x83 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN) // full speed configuration static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface "TinyUSB MSC", // 5: MSC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/cdc_msc_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_msc_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/device/cdc_msc_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/cdc_msc_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/msc_disk.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/cdc_msc_freertos/sdkconfig.defaults ================================================ CONFIG_IDF_CMAKE=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y ================================================ FILE: examples/device/cdc_msc_freertos/skip.txt ================================================ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI mcu:RAXXX mcu:STM32L0 family:broadcom_32bit family:broadcom_64bit family:nuc121_125 family:hpmicro ================================================ FILE: examples/device/cdc_msc_freertos/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" "msc_disk.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/cdc_msc_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define CDC_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t cdc_stack[CDC_STACK_SIZE]; StaticTask_t cdc_taskdef; #endif static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static void usb_device_task(void *param); void led_blinking_task(void* param); void cdc_task(void *params); extern void msc_disk_init(void); //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); // Create task for: tinyusb, blinky, cdc #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif #ifndef ESP_PLATFORM // only start scheduler for non-espressif mcu vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks static void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); msc_disk_init(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tud_task(); // following code only run if tud_task() process at least 1 event tud_cdc_write_flush(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ void cdc_task(void *params) { (void) params; // RTOS forever loop while (1) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_connected() ) { // There are data available while (tud_cdc_available()) { uint8_t buf[64]; // read and echo back uint32_t count = tud_cdc_read(buf, sizeof(buf)); (void) count; // Echo back // Note: Skip echo by commenting out write() and write_flush() // for throughput test e.g // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000 tud_cdc_write(buf, count); } tud_cdc_write_flush(); // Press on-board button to send Uart status notification static uint32_t btn_prev = 0; static cdc_notify_uart_state_t uart_state = { .value = 0 }; const uint32_t btn = board_button_read(); if (!btn_prev && btn) { uart_state.dsr ^= 1; tud_cdc_notify_uart_state(&uart_state); } btn_prev = btn; } // For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog vTaskDelay(1); } } // Invoked when cdc when line state changed e.g connected/disconnected void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; // TODO set some indicator if (dtr) { // Terminal connected } else { // Terminal disconnected } } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t itf) { (void) itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void* param) { (void) param; static bool led_state = false; while (1) { // Blink every interval ms vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); board_led_write(led_state); led_state = 1 - led_state; // toggle } } ================================================ FILE: examples/device/cdc_msc_freertos/src/msc_disk.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #if CFG_TUD_MSC // Use async IO in example or not #define CFG_EXAMPLE_MSC_ASYNC_IO 1 // Simulate read/write operation delay #define CFG_EXAMPLE_MSC_IO_DELAY_MS 0 #if CFG_EXAMPLE_MSC_ASYNC_IO #define IO_STACK_SIZE configMINIMAL_STACK_SIZE typedef struct { uint8_t lun; bool is_read; uint32_t lba; uint32_t offset; void* buffer; uint32_t bufsize; } io_ops_t; QueueHandle_t io_queue; #if configSUPPORT_STATIC_ALLOCATION uint8_t io_queue_buf[sizeof(io_ops_t)]; StaticQueue_t io_queue_static; StackType_t io_stack[IO_STACK_SIZE]; StaticTask_t io_taskdef; #endif static void io_task(void *params); #endif void msc_disk_init(void); // whether host does safe-eject static bool ejected = false; // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined #define README_CONTENTS \ "This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" enum { DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; // fat_num = 1; fat12_root_entry_num = 16; // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC"; // FAT magic code at offset 510-511 { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , 'M' , 'S' , 'C' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA }, //------------- Block1: FAT12 Table -------------// { 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// { // first entry is volume label 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , 'M' , 'S' , 'C' , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // second entry is readme file 'R' , 'E' , 'A' , 'D' , 'M' , 'E' , ' ' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D, 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, sizeof(README_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// README_CONTENTS }; #if CFG_EXAMPLE_MSC_ASYNC_IO void msc_disk_init(void) { #if configSUPPORT_STATIC_ALLOCATION io_queue = xQueueCreateStatic(1, sizeof(io_ops_t), io_queue_buf, &io_queue_static); xTaskCreateStatic(io_task, "io", IO_STACK_SIZE, NULL, 2, io_stack, &io_taskdef); #else io_queue = xQueueCreate(1, sizeof(io_ops_t)); xTaskCreate(io_task, "io", IO_STACK_SIZE, NULL, 2, NULL); #endif } static void io_task(void *params) { (void) params; io_ops_t io_ops; while (1) { if (xQueueReceive(io_queue, &io_ops, portMAX_DELAY)) { uint8_t* addr = (uint8_t*) (uintptr_t) (msc_disk[io_ops.lba] + io_ops.offset); int32_t nbytes = io_ops.bufsize; if (io_ops.is_read) { memcpy(io_ops.buffer, addr, io_ops.bufsize); } else { #ifndef CFG_EXAMPLE_MSC_READONLY memcpy((uint8_t*) addr, io_ops.buffer, io_ops.bufsize); #else nbytes = -1; // failed to write #endif } tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS); tud_msc_async_io_done(nbytes, false); } } } #else void msc_disk_init() {} #endif // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp, uint32_t bufsize) { (void) lun; (void) bufsize; const char vid[] = "TinyUSB"; const char pid[] = "Mass Storage"; const char rev[] = "1.0"; strncpy((char*) inquiry_resp->vendor_id, vid, 8); strncpy((char*) inquiry_resp->product_id, pid, 16); strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; // RAM disk is ready until ejected if (ejected) { // Additional Sense 3A-00 is NOT_FOUND tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); return false; } return true; } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; if (load_eject) { if (start) { // load disk storage } else { // unload disk storage ejected = true; } } return true; } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; // out of ramdisk if (lba >= DISK_BLOCK_NUM) { return TUD_MSC_RET_ERROR; } // Check for overflow of offset + bufsize if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) { return TUD_MSC_RET_ERROR; } #if CFG_EXAMPLE_MSC_ASYNC_IO io_ops_t io_ops = {.is_read = true, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize}; // Send IO operation to IO task TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS); return TUD_MSC_RET_ASYNC; #else uint8_t const *addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); return bufsize; #endif } bool tud_msc_is_writable_cb (uint8_t lun) { (void) lun; #ifdef CFG_EXAMPLE_MSC_READONLY return false; #else return true; #endif } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { // out of ramdisk if (lba >= DISK_BLOCK_NUM) { return TUD_MSC_RET_ERROR; } // Check for overflow of offset + bufsize if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) { return TUD_MSC_RET_ERROR; } #ifdef CFG_EXAMPLE_MSC_READONLY (void) lun; (void) buffer; return bufsize; #elif CFG_EXAMPLE_MSC_ASYNC_IO io_ops_t io_ops = {.is_read = false, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize}; // Send IO operation to IO task TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS); return TUD_MSC_RET_ASYNC; #else uint8_t *addr = msc_disk[lba] + offset; memcpy(addr, buffer, bufsize); tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS); return bufsize; #endif } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { (void) lun; (void) scsi_cmd; (void) buffer; (void) bufsize; // currently no other commands are supported // Set Sense = Invalid Command Operation (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); return -1; // stall/failed command request; } #endif ================================================ FILE: examples/device/cdc_msc_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by board.mk #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif // can be defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/cdc_msc_freertos/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_MSC, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x85 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x81 #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x84 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_MSC_OUT 0x03 #define EPNUM_MSC_IN 0x83 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN) static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface "TinyUSB MSC", // 5: MSC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/cdc_uac2/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_uac2 C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/uac2_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) # Uncomment me to enable UART based debugging # pico_enable_stdio_uart(${PROJECT_NAME} 1) ================================================ FILE: examples/device/cdc_uac2/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/cdc_uac2/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/cdc_app.c \ src/main.c \ src/uac2_app.c \ src/usb_descriptors.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/cdc_uac2/README.md ================================================ #### Composite CDC + UAC2 on Pico This example provides a composite CDC + UAC2 device on top of a Raspberry Pi Pico board. #### Use Cases - The CDC + UAC2 composite device happens to be important, especially in the amateur radio community. Modern radios (`rigs`) like Icom IC-7300 + IC-705 expose a sound card and a serial device (`composite device`) to the computer over a single USB cable. This allows for Audio I/O and CAT control over a single USB cable which is very convenient. By including and maintaining this example in TinyUSB repository, we enable the amateur radio community to build (`homebrew`) radios with similar functionality as the (expensive) commercial rigs. This PR is important in bridging this specific gap between the commercial rigs and homebrew equipment. - https://digirig.net/digirig-mobile-rev-1-9/ is a digital interface for interfacing radios (that lack an inbuilt digital interface) with computers. Digirig Mobile works brilliantly (is OSS!) and is a big improvement over traditional digital interfaces (like the SignaLink USB Interface). By using a Raspberry Pi Pico powered CDC + UAC2 composite device, we can simplify the Digirig Mobile schematic, drastically reduce the manufacturing cost, and (again) enable the homebrewers community to homebrew a modern digital interface with ease themselves. #### Build Steps ``` cd examples/device/cdc_uac2 export PICO_SDK_PATH=$HOME/pico-sdk cmake -DFAMILY=rp2040 pico . cmake -DFAMILY=rp2040 -DCMAKE_BUILD_TYPE=Debug # use this for debugging make BOARD=raspberry_pi_pico all ``` #### Development Notes Please try to keep this code synchronized with the `uac2_headset` example included in this repository. ================================================ FILE: examples/device/cdc_uac2/skip.txt ================================================ mcu:LPC11UXX mcu:LPC13XX mcu:NUC121 mcu:SAMD11 mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif ================================================ FILE: examples/device/cdc_uac2/src/cdc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2022 Angel Molina (angelmolinu@gmail.com) * * 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 "bsp/board_api.h" #include "tusb.h" #include "common.h" // Invoked when cdc when line state changed e.g connected/disconnected void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; if (dtr) { // Terminal connected } else { // Terminal disconnected } } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t itf) { uint8_t buf[64]; uint32_t count; // connected() check for DTR bit // Most but not all terminal client set this when making connection if (tud_cdc_connected()) { if (tud_cdc_available() > 0) { count = tud_cdc_n_read(itf, buf, sizeof(buf)); (void) count; tud_cdc_n_write(itf, buf, count); tud_cdc_n_write_flush(itf); // dummy code to check that cdc serial is responding board_led_write(0); board_delay(50); board_led_write(1); board_delay(50); board_led_write(0); } } } ================================================ FILE: examples/device/cdc_uac2/src/common.h ================================================ #ifndef __COMMON_H__ #define __COMMON_H__ /* Blink pattern * - 25 ms : streaming data * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_STREAMING = 25, BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; enum { VOLUME_CTRL_0_DB = 0, VOLUME_CTRL_10_DB = 2560, VOLUME_CTRL_20_DB = 5120, VOLUME_CTRL_30_DB = 7680, VOLUME_CTRL_40_DB = 10240, VOLUME_CTRL_50_DB = 12800, VOLUME_CTRL_60_DB = 15360, VOLUME_CTRL_70_DB = 17920, VOLUME_CTRL_80_DB = 20480, VOLUME_CTRL_90_DB = 23040, VOLUME_CTRL_100_DB = 25600, VOLUME_CTRL_SILENCE = 0x8000, }; void led_blinking_task(void); void audio_task(void); #endif ================================================ FILE: examples/device/cdc_uac2/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * Copyright (c) 2022 Angel Molina * Copyright (c) 2023 Dhiru Kholia * * 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 #include #include "bsp/board_api.h" #include "tusb.h" #include "common.h" extern uint32_t blink_interval_ms; #if (CFG_TUSB_MCU == OPT_MCU_RP2040) #include "pico/stdlib.h" #endif /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); #if (CFG_TUSB_MCU == OPT_MCU_RP2040) stdio_init_all(); #endif TU_LOG1("CDC UAC2 example running\r\n"); while (1) { tud_task(); // TinyUSB device task led_blinking_task(); audio_task(); #if (CFG_TUSB_MCU == OPT_MCU_RP2040) // printf("Hello, world!\r\n"); #endif } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = BLINK_MOUNTED; } ================================================ FILE: examples/device/cdc_uac2/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jerzy Kasenberg * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif #include "usb_descriptors.h" //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_AUDIO 1 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 // Audio format type I specifications #if defined(__RX__) #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 // 16bit/48kHz is the best quality for Renesas RX #else #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 // 24bit/96kHz is the best quality for full-speed, high-speed is needed beyond this #endif #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 1 // Changed // 16bit in 16bit slots #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX 16 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16 #if defined(__RX__) // 8bit in 8bit slots #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 1 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX 8 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX 1 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 8 #else // 24bit in 32bit slots #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX 24 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 24 #endif // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/cdc_uac2/src/uac2_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * Copyright (c) 2022 Angel Molina (angelmolinu@gmail.com) * * 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 #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" #include "common.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ // List of supported sample rates const uint32_t sample_rates[] = {44100, 48000}; uint32_t current_sample_rate = 44100; #define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates) uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 // Buffer for speaker data int32_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 4]; // Speaker data size received in the last frame uint16_t spk_data_size; // Resolution per format const uint8_t resolutions_per_format[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = {CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX}; // Current resolution, update on format change uint8_t current_resolution; //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio transfer callback, one frame is sent/received every 1ms. // In a real application, this would be replaced with actual I2S send/receive callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) { return; // not enough time } start_ms = curr_ms; // When new data arrived, copy data from speaker buffer, to microphone buffer // and send it over // Only support speaker & headphone both have the same resolution // If one is 16bit another is 24bit be care of LOUD noise ! spk_data_size = tud_audio_read(spk_buf, sizeof(spk_buf)); if (spk_data_size) { tud_audio_write((uint8_t *) spk_buf, spk_data_size); } } // Helper for clock get requests static bool tud_audio_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio20_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) }; TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) { rangef.subrange[i].bMin = (int32_t) sample_rates[i]; rangef.subrange[i].bMax = (int32_t) sample_rates[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); } return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef)); } } else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t cur_valid = { .bCur = 1 }; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid)); } TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } // Helper for clock set requests static bool tud_audio_clock_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void)rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *)buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } else { TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } // Helper for feature unit get requests static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) } }; TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol)); } else if (request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol)); } } TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } // Helper for feature unit set requests static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void)rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *)buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *)buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); return true; } else { TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) { return tud_audio_clock_get_request(rhport, request); } if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) { return tud_audio_feature_unit_get_request(rhport, request); } else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); } return false; } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) { return tud_audio_feature_unit_set_request(rhport, request, buf); } if (request->bEntityID == UAC2_ENTITY_CLOCK) { return tud_audio_clock_set_request(rhport, request, buf); } TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) { (void)rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt == 0) { // Audio streaming stop blink_interval_ms = BLINK_MOUNTED; } return true; } bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) { (void)rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); TU_LOG2("Set interface %d alt %d\r\n", itf, alt); if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0) { // Audio streaming start blink_interval_ms = BLINK_STREAMING; } if(alt != 0) { current_resolution = resolutions_per_format[alt-1]; } return true; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; } ================================================ FILE: examples/device/cdc_uac2/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jerzy Kasenberg * Copyright (c) 2022 Angel Molina (angelmolinu@gmail.com) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_HEADSET_STEREO_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO_IN 0x03 #define EPNUM_AUDIO_OUT 0x03 #define EPNUM_CDC_NOTIF 0x84 #define EPNUM_CDC_OUT 0x05 #define EPNUM_CDC_IN 0x85 #elif CFG_TUSB_MCU == OPT_MCU_NRF5X // ISO endpoints for NRF5x are fixed to 0x08 (0x88) #define EPNUM_AUDIO_IN 0x08 #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x85 #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x84 #endif static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80), // CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 6, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64) }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80), // CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 6, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512) }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = 0x0100, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB headset", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB Speakers", // 4: Audio Interface "TinyUSB Microphone", // 5: Audio Interface "TinyUSB CDC", // 6: Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/cdc_uac2/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenbreg * Copyright (c) 2022 Angel Molina (angelmolinu@gmail.com) * * 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. * */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ // #include "tusb.h" // Unit numbers are arbitrary selected #define UAC2_ENTITY_CLOCK 0x04 // Speaker path #define UAC2_ENTITY_SPK_INPUT_TERMINAL 0x01 #define UAC2_ENTITY_SPK_FEATURE_UNIT 0x02 #define UAC2_ENTITY_SPK_OUTPUT_TERMINAL 0x03 // Microphone path #define UAC2_ENTITY_MIC_INPUT_TERMINAL 0x11 #define UAC2_ENTITY_MIC_OUTPUT_TERMINAL 0x13 enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING_SPK, ITF_NUM_AUDIO_STREAMING_MIC, ITF_NUM_CDC, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #define TUD_AUDIO_HEADSET_STEREO_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 2, Alternate 1 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 2 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ 3, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x05),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) #endif ================================================ FILE: examples/device/dfu/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(dfu C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/dfu/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/dfu/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/dfu/skip.txt ================================================ mcu:TM4C mcu:BCM2835 family:espressif ================================================ FILE: examples/device/dfu/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* * After device is enumerated in dfu mode run the following commands * * To transfer firmware from host to device (best to test with text file) * * $ dfu-util -d cafe -a 0 -D [filename] * $ dfu-util -d cafe -a 1 -D [filename] * * To transfer firmware from device to host: * * $ dfu-util -d cafe -a 0 -U [filename] * $ dfu-util -d cafe -a 1 -U [filename] * */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ const char *upload_image[2] = {"Hello world from TinyUSB DFU! - Partition 0", "Hello world from TinyUSB DFU! - Partition 1"}; /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // DFU callbacks // Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. //--------------------------------------------------------------------+ // Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) // Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. // During this period, USB host won't try to communicate with us. uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) { if (state == DFU_DNBUSY) { // For this example // - Atl0 Flash is fast : 1 ms // - Alt1 EEPROM is slow: 100 ms return (alt == 0) ? 1 : 100; } else if (state == DFU_MANIFEST) { // since we don't buffer entire image and do any flashing in manifest stage return 0; } else { // nothing to do } return 0; } // Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests // This callback could be returned before flashing op is complete (async). // Once finished flashing, application must call tud_dfu_finish_flashing() void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, const uint8_t *data, uint16_t length) { (void)alt; (void)block_num; //printf("\r\nReceived Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); for (uint16_t i = 0; i < length; i++) { printf("%c", data[i]); } // flashing op for download complete without error tud_dfu_finish_flashing(DFU_STATUS_OK); } // Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) // Application can do checksum, or actual flashing if buffered entire image previously. // Once finished flashing, application must call tud_dfu_finish_flashing() void tud_dfu_manifest_cb(uint8_t alt) { (void)alt; printf("Download completed, enter manifestation\r\n"); // flashing op for manifest is complete without error // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. tud_dfu_finish_flashing(DFU_STATUS_OK); } // Invoked when received DFU_UPLOAD request // Application must populate data with up to length bytes and // Return the number of written bytes uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t *data, uint16_t length) { (void)block_num; (void)length; if (block_num != 0u) { return 0; // for this example we only support single block upload } const uint16_t xfer_len = tu_min16((uint16_t)strlen(upload_image[alt]), length); memcpy(data, upload_image[alt], xfer_len); return xfer_len; } // Invoked when the Host has terminated a download or upload transfer void tud_dfu_abort_cb(uint8_t alt) { (void)alt; printf("Host aborted transfer\r\n"); } // Invoked when a DFU_DETACH request is received void tud_dfu_detach_cb(void) { printf("Host detach, we should probably reboot\r\n"); } //--------------------------------------------------------------------+ // BLINKING TASK + Indicator pulse //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/dfu/src/tusb_config.h ================================================ /* * tusb_config.h * * Created on: May 5, 2021 * Author: Jeremiah McCarthy */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_DFU 1 // DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR #define CFG_TUD_DFU_XFER_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/dfu/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4)) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static const tusb_desc_device_t desc_device = {.bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0201, #if CFG_TUD_CDC // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, #else .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, #endif .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01}; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor const uint8_t *tud_descriptor_device_cb(void) { return (const uint8_t *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ // Number of Alternate Interface (each for 1 flash partition) #define ALT_COUNT 2 enum { ITF_NUM_DFU_MODE, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT)) #define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // BOS Descriptor //--------------------------------------------------------------------+ /* Microsoft OS 2.0 registry property descriptor Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx device should create DeviceInterfaceGUIDs. It can be done by driver and in case of real PnP solution device should expose MS "Microsoft OS 2.0 registry property descriptor". Such descriptor can insert any record into Windows registry per device/configuration/interface. In our case it will insert "DeviceInterfaceGUIDs" multistring property. GUID is freshly generated and should be OK to use. https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) #define MS_OS_20_DESC_LEN 0xA2 #define VENDOR_REQUEST_MICROSOFT 1 // BOS Descriptor is required for webUSB const uint8_t desc_bos[] = { // total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), // Microsoft OS 2.0 descriptor TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)}; const uint8_t *tud_descriptor_bos_cb(void) { return desc_bos; } const uint8_t desc_ms_os_20[] = { // Set header: length, type, windows version, total length U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible // MS OS 2.0 Registry property descriptor: length, type U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A),// wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, U16_TO_U8S_LE(0x0050),// wPropertyDataLength //bPropertyData: {3E7E0711-DF3B-4158-A32F-E5951B2AB9A1}. '{', 0x00, '3', 0x00, 'E', 0x00, '7', 0x00, 'E', 0x00, '0', 0x00, '7', 0x00, '1', 0x00, '1', 0x00, '-', 0x00, 'D', 0x00, 'F', 0x00, '3', 0x00, 'B', 0x00, '-', 0x00, '4', 0x00, '1', 0x00, '5', 0x00, '8', 0x00, '-', 0x00, 'A', 0x00, '3', 0x00, '2', 0x00, 'F', 0x00, '-', 0x00, 'E', 0x00, '5', 0x00, '9', 0x00, '5', 0x00, '1', 0x00, 'B', 0x00, '2', 0x00, 'A', 0x00, 'B', 0x00, '9', 0x00, 'A', 0x00, '1', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 }; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { // nothing to with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) { return true; } if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR) { if (request->bRequest == VENDOR_REQUEST_MICROSOFT) { if (request->wIndex == 7) { return tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_ms_os_20, MS_OS_20_DESC_LEN); } else { return false; } } } // stall unknown request return false; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static const char *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "FLASH", // 4: DFU Partition 1 "EEPROM", // 5: DFU Partition 2 }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/dfu_runtime/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(dfu_runtime C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/dfu_runtime/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/dfu_runtime/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/dfu_runtime/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* After device is enumerated, run following command * * $ dfu-util -l * * It should be able to list our device as in Runtime mode. Then run * * $ dfu-util -e * * This will send DETACH command to put device into bootloader. Since this example * is minimal, it doesn't actually go into DFU mode but rather change the LED blinking * pattern to fast rate as indicator. */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 1000 ms : device should reboot * - 250 ms : device not mounted * - 0 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_DFU_MODE = 100, BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Invoked on DFU_DETACH request to reboot to the bootloader void tud_dfu_runtime_reboot_to_dfu_cb(void) { blink_interval_ms = BLINK_DFU_MODE; } //--------------------------------------------------------------------+ // BLINKING TASK + Indicator pulse //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/dfu_runtime/src/tusb_config.h ================================================ /* * tusb_config.h * * Created on: Oct 28, 2019 * Author: Sylvain Munaut */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_DFU_RUNTIME 1 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/dfu_runtime/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4)) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static const tusb_desc_device_t desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0201, #if CFG_TUD_CDC // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, #else .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, #endif .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_DFU_RT, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_RT_DESC_LEN) uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, attributes, detach timeout, transfer size */ TUD_DFU_RT_DESCRIPTOR(ITF_NUM_DFU_RT, 4, 0x0d, 1000, 4096), }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void) index;// for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // BOS Descriptor //--------------------------------------------------------------------+ /* Microsoft OS 2.0 registry property descriptor Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx device should create DeviceInterfaceGUIDs. It can be done by driver and in case of real PnP solution device should expose MS "Microsoft OS 2.0 registry property descriptor". Such descriptor can insert any record into Windows registry per device/configuration/interface. In our case it will insert "DeviceInterfaceGUIDs" multistring property. GUID is freshly generated and should be OK to use. https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) #define MS_OS_20_DESC_LEN 0xA2 #define VENDOR_REQUEST_MICROSOFT 1 // BOS Descriptor is required for webUSB const uint8_t desc_bos[] = { // total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), // Microsoft OS 2.0 descriptor TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)}; const uint8_t *tud_descriptor_bos_cb(void) { return desc_bos; } uint8_t const desc_ms_os_20[] = { // Set header: length, type, windows version, total length U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sub-compatible // MS OS 2.0 Registry property descriptor: length, type U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A),// wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, U16_TO_U8S_LE(0x0050),// wPropertyDataLength //bPropertyData: {F7CC2C68-3B14-4D72-B876-1A981AD2C9E5}. '{', 0x00, 'F', 0x00, '7', 0x00, 'C', 0x00, 'C', 0x00, '2', 0x00, 'C', 0x00, '6', 0x00, '8', 0x00, '-', 0x00, '3', 0x00, 'B', 0x00, '1', 0x00, '4', 0x00, '-', 0x00, '4', 0x00, 'D', 0x00, '7', 0x00, '2', 0x00, '-', 0x00, 'B', 0x00, '8', 0x00, '7', 0x00, '6', 0x00, '-', 0x00, '1', 0x00, 'A', 0x00, '9', 0x00, '8', 0x00, '1', 0x00, 'A', 0x00, 'D', 0x00, '2', 0x00, 'C', 0x00, '9', 0x00, 'E', 0x00, '5', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 }; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { // nothing to with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) { return true; } if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR) { if (request->bRequest == VENDOR_REQUEST_MICROSOFT) { if (request->wIndex == 7) { return tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_ms_os_20, MS_OS_20_DESC_LEN); } else { return false; } } } switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: switch (request->bRequest) { case VENDOR_REQUEST_MICROSOFT: if (request->wIndex == 7) { return tud_control_xfer(rhport, request, (void *) (uintptr_t) desc_ms_os_20, MS_OS_20_DESC_LEN); } else { return false; } default: break; } break; default: break; } // stall unknown request return false; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]){0x09, 0x04},// 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB DFU runtime", // 4: DFU runtime }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/dynamic_configuration/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(dynamic_configuration C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/dynamic_configuration/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/dynamic_configuration/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/dynamic_configuration/skip.txt ================================================ mcu:SAMD11 family:espressif board:ch32v203g_r0_1v0 ================================================ FILE: examples/device/dynamic_configuration/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); void cdc_task(void); void midi_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); cdc_task(); midi_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ void cdc_task(void) { if (tud_cdc_connected()) { // connected and there are data available read and echo back if (tud_cdc_available()) { uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); for (uint32_t i = 0; i < count; i++) { tud_cdc_write_char(buf[i]); if (buf[i] == '\r') { tud_cdc_write_char('\n'); } } tud_cdc_write_flush(); } } } // Invoked when cdc when line state changed e.g connected/disconnected void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; // connected if (dtr && rts) { // print initial message when connected tud_cdc_write_str("\r\nTinyUSB CDC MSC device example\r\n"); } } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t itf) { (void) itf; } //--------------------------------------------------------------------+ // MIDI Task //--------------------------------------------------------------------+ // Variable that holds the current position in the sequence. uint32_t note_pos = 0; // Store example melody as an array of note values static const uint8_t note_sequence[] = { 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78, 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61, 56,61,64,68,74,78,81,86,90,93,98,102 }; void midi_task(void) { static uint32_t start_ms = 0; uint8_t const cable_num = 0; // MIDI jack associated with USB endpoint uint8_t const channel = 0; // 0 for channel 1 // The MIDI interface always creates input and output port/jack descriptors // regardless of these being used or not. Therefore incoming traffic should be read // (possibly just discarded) to avoid the sender blocking in IO uint8_t packet[4]; while( tud_midi_available() ) tud_midi_packet_read(packet); // send note every 1000 ms if (tusb_time_millis_api() - start_ms < 286) { return; // not enough time } start_ms += 286; // Previous positions in the note sequence. int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. if (previous < 0) { previous = sizeof(note_sequence) - 1; } // Send Note On for current position at full velocity (127) on channel 1. uint8_t note_on[3] = { 0x90 | channel, note_sequence[note_pos], 127 }; tud_midi_stream_write(cable_num, note_on, 3); // Send Note Off for previous note. uint8_t note_off[3] = { 0x80 | channel, note_sequence[previous], 0}; tud_midi_stream_write(cable_num, note_off, 3); // Increment position note_pos++; // If we are at the end of the sequence, start over. if (note_pos >= sizeof(note_sequence)) { note_pos = 0; } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return;// not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } ================================================ FILE: examples/device/dynamic_configuration/src/msc_disk.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #if CFG_TUD_MSC // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined #define README_CONTENTS \ "This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" enum { DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; // fat_num = 1; fat12_root_entry_num = 16; // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC"; // FAT magic code at offset 510-511 { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , 'M' , 'S' , 'C' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA }, //------------- Block1: FAT12 Table -------------// { 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// { // first entry is volume label 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , 'M' , 'S' , 'C' , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // second entry is readme file 'R' , 'E' , 'A' , 'D' , 'M' , 'E' , ' ' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D, 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, sizeof(README_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// README_CONTENTS }; // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uint32_t bufsize) { (void) lun; (void) bufsize; const char vid[] = "TinyUSB"; const char pid[] = "Mass Storage"; const char rev[] = "1.0"; strncpy((char*) inquiry_resp->vendor_id, vid, 8); strncpy((char*) inquiry_resp->product_id, pid, 16); strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; return true; // RAM disk is always ready } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; if ( load_eject ) { if (start) { // load disk storage }else { // unload disk storage } } return true; } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; // out of ramdisk if ( lba >= DISK_BLOCK_NUM ) { return -1; } uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); return (int32_t) bufsize; } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { (void) lun; // out of ramdisk if ( lba >= DISK_BLOCK_NUM ) { return -1; } #ifndef CFG_EXAMPLE_MSC_READONLY uint8_t* addr = msc_disk[lba] + offset; memcpy(addr, buffer, bufsize); #else (void) lba; (void) offset; (void) buffer; #endif return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { (void) lun; (void) scsi_cmd; (void) buffer; (void) bufsize; // currently no other commands are supported // Set Sense = Invalid Command Operation (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); return -1; // stall/failed command request; } #endif ================================================ FILE: examples/device/dynamic_configuration/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 1 #define CFG_TUD_MIDI 1 #define CFG_TUD_HID 0 #define CFG_TUD_VENDOR 0 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MIDI FIFO size of TX and RX #define CFG_TUD_MIDI_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_MIDI_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/dynamic_configuration/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) // Configuration mode // 0 : enumerated as CDC/MIDI. Board button is not pressed when enumerating // 1 : enumerated as MSC. Board button is pressed when enumerating static uint32_t mode = 0; //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ tusb_desc_device_t const desc_device_0 = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; tusb_desc_device_t const desc_device_1 = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID + 11, // should be different PID than desc0 .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { mode = board_button_read(); return (uint8_t const*) (mode ? &desc_device_1 : &desc_device_0); } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_0_NUM_CDC = 0, ITF_0_NUM_CDC_DATA, ITF_0_NUM_MIDI, ITF_0_NUM_MIDI_STREAMING, ITF_0_NUM_TOTAL }; enum { ITF_1_NUM_MSC = 0, ITF_1_NUM_TOTAL }; #define CONFIG_0_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MIDI_DESC_LEN) #define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 #define EPNUM_0_CDC_IN 0x82 #define EPNUM_0_MIDI_OUT 0x05 #define EPNUM_0_MIDI_IN 0x85 #define EPNUM_1_MSC_OUT 0x02 #define EPNUM_1_MSC_IN 0x82 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 #define EPNUM_0_CDC_IN 0x83 #define EPNUM_0_MIDI_OUT 0x04 #define EPNUM_0_MIDI_IN 0x85 #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 #else #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 #define EPNUM_0_CDC_IN 0x82 #define EPNUM_0_MIDI_OUT 0x03 #define EPNUM_0_MIDI_IN 0x83 #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x81 #endif uint8_t const desc_configuration_0[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_0_NUM_CDC, 0, EPNUM_0_CDC_NOTIF, 8, EPNUM_0_CDC_OUT, EPNUM_0_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_0_NUM_MIDI, 0, EPNUM_0_MIDI_OUT, EPNUM_0_MIDI_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), }; uint8_t const desc_configuration_1[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_1_NUM_TOTAL, 0, CONFIG_1_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_1_NUM_MSC, 0, EPNUM_1_MSC_OUT, EPNUM_1_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return mode ? desc_configuration_1 : desc_configuration_0; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/hid_boot_interface/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_boot_interface C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/hid_boot_interface/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/hid_boot_interface/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/hid_boot_interface/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); void hid_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); hid_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ // Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..) // tud_hid_report_complete_cb() is used to send the next report after previous one is complete void hid_task(void) { // Poll every 10ms const uint32_t interval_ms = 10; static uint32_t start_ms = 0; if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; uint32_t const btn = board_button_read(); if (tud_suspended() && btn) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); } else { // keyboard interface if (tud_hid_n_ready(ITF_NUM_KEYBOARD)) { // used to avoid send multiple consecutive zero report for keyboard static bool has_keyboard_key = false; uint8_t const report_id = 0; uint8_t const modifier = 0; if (btn) { uint8_t keycode[6] = {0}; keycode[0] = HID_KEY_ARROW_RIGHT; tud_hid_n_keyboard_report(ITF_NUM_KEYBOARD, report_id, modifier, keycode); has_keyboard_key = true; } else { // send empty key report if previously has key pressed if (has_keyboard_key) { tud_hid_n_keyboard_report(ITF_NUM_KEYBOARD, report_id, modifier, NULL); } has_keyboard_key = false; } } // mouse interface if (tud_hid_n_ready(ITF_NUM_MOUSE)) { if (btn) { uint8_t const report_id = 0; uint8_t const button_mask = 0; int8_t const vertical = 0; int8_t const horizontal = 0; int8_t const delta = 5; tud_hid_n_mouse_report(ITF_NUM_MOUSE, report_id, button_mask, delta, delta, vertical, horizontal); } } } } // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { (void)instance; (void)protocol; // nothing to do since we use the same compatible boot report for both Boot and Report mode. // TODO set a indicator for user } // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len) { (void)instance; (void)report; (void)len; // nothing to do } // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb( uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { // TODO not Implemented (void)instance; (void)report_id; (void)report_type; (void)buffer; (void)reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb( uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { (void)report_id; // keyboard interface if (instance == ITF_NUM_KEYBOARD) { // Set keyboard LED e.g Capslock, Numlock etc... if (report_type == HID_REPORT_TYPE_OUTPUT) { // bufsize should be (at least) 1 if (bufsize < 1) { return; } uint8_t const kbd_leds = buffer[0]; if (kbd_leds & KEYBOARD_LED_CAPSLOCK) { // Capslock On: disable blink, turn led on blink_interval_ms = 0; board_led_write(true); } else { // Caplocks Off: back to normal blink board_led_write(false); blink_interval_ms = BLINK_MOUNTED; } } } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // blink is disabled if (!blink_interval_ms) { return; } // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/hid_boot_interface/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_HID 2 // 1 for boot keyboard, 1 for boot mouse #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 8 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/hid_boot_interface/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4)) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01}; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_keyboard_report[] = {TUD_HID_REPORT_DESC_KEYBOARD()}; uint8_t const desc_hid_mouse_report[] = {TUD_HID_REPORT_DESC_MOUSE()}; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) { return (instance == 0) ? desc_hid_keyboard_report : desc_hid_mouse_report; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2 * TUD_HID_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 1 Interrupt, 2 Bulk, 3 Iso, 4 Interrupt, 5 Bulk etc ... #define EPNUM_KEYBOARD 0x81 #define EPNUM_MOUSE 0x84 #else #define EPNUM_KEYBOARD 0x81 #define EPNUM_MOUSE 0x82 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR( ITF_NUM_KEYBOARD, 0, HID_ITF_PROTOCOL_KEYBOARD, sizeof(desc_hid_keyboard_report), EPNUM_KEYBOARD, CFG_TUD_HID_EP_BUFSIZE, 10), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR( ITF_NUM_MOUSE, 0, HID_ITF_PROTOCOL_MOUSE, sizeof(desc_hid_mouse_report), EPNUM_MOUSE, CFG_TUD_HID_EP_BUFSIZE, 10)}; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/hid_boot_interface/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { ITF_NUM_KEYBOARD, ITF_NUM_MOUSE, ITF_NUM_TOTAL }; #endif ================================================ FILE: examples/device/hid_composite/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_composite C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/hid_composite/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/hid_composite/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/hid_composite/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); void hid_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); hid_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ static void send_hid_report(uint8_t report_id, uint32_t btn) { // skip if hid is not ready yet if (!tud_hid_ready()) { return; } switch (report_id) { case REPORT_ID_KEYBOARD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_keyboard_key = false; if (btn != 0u) { uint8_t keycode[6] = {0}; keycode[0] = HID_KEY_A; tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); has_keyboard_key = true; } else { // send empty key report if previously has key pressed if (has_keyboard_key) { tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); } has_keyboard_key = false; } break; } case REPORT_ID_MOUSE: { int8_t const delta = 5; // no button, right + down, no scroll, no pan tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0); break; } case REPORT_ID_CONSUMER_CONTROL: { // use to avoid send multiple consecutive zero report static bool has_consumer_key = false; if (btn != 0u) { // volume down uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT; tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2); has_consumer_key = true; } else { // send empty key report (release key) if previously has key pressed uint16_t empty_key = 0; if (has_consumer_key) { tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2); } has_consumer_key = false; } break; } case REPORT_ID_GAMEPAD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_gamepad_key = false; hid_gamepad_report_t report = {.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0, .hat = 0, .buttons = 0}; if (btn != 0u) { report.hat = GAMEPAD_HAT_UP; report.buttons = GAMEPAD_BUTTON_A; tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); has_gamepad_key = true; } else { report.hat = GAMEPAD_HAT_CENTERED; report.buttons = 0; if (has_gamepad_key) { tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); } has_gamepad_key = false; } break; } case REPORT_ID_STYLUS_PEN: { static bool touch_state = false; hid_stylus_report_t report = {.attr = 0, .x = 0, .y = 0}; if (btn != 0u) { report.attr = STYLUS_ATTR_TIP_SWITCH | STYLUS_ATTR_IN_RANGE; report.x = 100; report.y = 100; tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report)); touch_state = true; } else { report.attr = 0; if (touch_state) { tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report)); } touch_state = false; } break; } default: break; // unknown report id } } // Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..) // tud_hid_report_complete_cb() is used to send the next report after previous one is complete void hid_task(void) { // Poll every 10ms const uint32_t interval_ms = 10; static uint32_t start_ms = 0; if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; uint32_t const btn = board_button_read(); // Remote wakeup if (tud_suspended() && btn != 0u) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); } else { // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() send_hid_report(REPORT_ID_KEYBOARD, btn); } } // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len) { (void)instance; (void)len; uint8_t next_report_id = report[0] + 1u; if (next_report_id < REPORT_ID_COUNT) { send_hid_report(next_report_id, board_button_read()); } } // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb( uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { // TODO not Implemented (void)instance; (void)report_id; (void)report_type; (void)buffer; (void)reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb( uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { (void)instance; if (report_type == HID_REPORT_TYPE_OUTPUT) { // Set keyboard LED e.g Capslock, Numlock etc... if (report_id == REPORT_ID_KEYBOARD) { // bufsize should be (at least) 1 if (bufsize < 1) { return; } uint8_t const kbd_leds = buffer[0]; if ((kbd_leds & KEYBOARD_LED_CAPSLOCK) != 0u) { // Capslock On: disable blink, turn led on blink_interval_ms = 0; board_led_write(true); } else { // Caplocks Off: back to normal blink board_led_write(false); blink_interval_ms = BLINK_MOUNTED; } } } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // blink is disabled if (0u == blink_interval_ms) { return; } // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/hid_composite/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_HID 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 16 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/hid_composite/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )), TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )), TUD_HID_REPORT_DESC_STYLUS_PEN( HID_REPORT_ID(REPORT_ID_STYLUS_PEN )), TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )), TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD )) }; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) { (void) instance; return desc_hid_report; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_HID, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN) #define EPNUM_HID 0x81 uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5) }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // other speed config is basically configuration with type = OTHER_SPEED_CONFIG memcpy(desc_other_speed_config, desc_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; // this example use the same configuration for both high and full speed mode return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // This example use the same configuration for both high and full speed mode return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/hid_composite/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { REPORT_ID_KEYBOARD = 1, REPORT_ID_MOUSE, REPORT_ID_STYLUS_PEN, REPORT_ID_CONSUMER_CONTROL, REPORT_ID_GAMEPAD, REPORT_ID_COUNT }; #endif /* USB_DESCRIPTORS_H_ */ ================================================ FILE: examples/device/hid_composite_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_composite_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/device/hid_composite_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/hid_composite_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/usb_descriptors.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/hid_composite_freertos/sdkconfig.defaults ================================================ CONFIG_IDF_CMAKE=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y ================================================ FILE: examples/device/hid_composite_freertos/skip.txt ================================================ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI mcu:RAXXX family:broadcom_32bit family:broadcom_64bit family:hpmicro ================================================ FILE: examples/device/hid_composite_freertos/src/CMakeLists.txt ================================================ idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/hid_composite_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" #ifdef ESP_PLATFORM // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/queue.h" #include "freertos/task.h" #include "freertos/timers.h" #define USBD_STACK_SIZE 4096 #else #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" #include "task.h" #include "timers.h" // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define HID_STACK_SZIE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; // static timer & task #if configSUPPORT_STATIC_ALLOCATION StaticTimer_t blinky_tmdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t hid_stack[HID_STACK_SZIE]; StaticTask_t hid_taskdef; #endif TimerHandle_t blinky_tm; void led_blinky_cb(TimerHandle_t xTimer); void usb_device_task(void* param); void hid_task(void* params); //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION // soft timer for blinky blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); // Create a task for tinyusb device stack xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); // Create HID task xTaskCreateStatic(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef); #else blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); xTaskCreate(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); #endif xTimerStart(blinky_tm, 0); // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void* param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tud_task(); // following code only run if tud_task() process at least 1 event } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); } // Invoked when device is unmounted void tud_umount_cb(void) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); } // Invoked when usb bus is resumed void tud_resume_cb(void) { if (tud_mounted()) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); } else { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); } } //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ static void send_hid_report(uint8_t report_id, uint32_t btn) { // skip if hid is not ready yet if ( !tud_hid_ready() ) return; switch(report_id) { case REPORT_ID_KEYBOARD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_keyboard_key = false; if ( btn ) { uint8_t keycode[6] = { 0 }; keycode[0] = HID_KEY_A; tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); has_keyboard_key = true; }else { // send empty key report if previously has key pressed if (has_keyboard_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); has_keyboard_key = false; } } break; case REPORT_ID_MOUSE: { int8_t const delta = 5; // no button, right + down, no scroll, no pan tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0); } break; case REPORT_ID_CONSUMER_CONTROL: { // use to avoid send multiple consecutive zero report static bool has_consumer_key = false; if ( btn ) { // volume down uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT; tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2); has_consumer_key = true; }else { // send empty key report (release key) if previously has key pressed uint16_t empty_key = 0; if (has_consumer_key) tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2); has_consumer_key = false; } } break; case REPORT_ID_GAMEPAD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_gamepad_key = false; hid_gamepad_report_t report = { .x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0, .hat = 0, .buttons = 0 }; if ( btn ) { report.hat = GAMEPAD_HAT_UP; report.buttons = GAMEPAD_BUTTON_A; tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); has_gamepad_key = true; }else { report.hat = GAMEPAD_HAT_CENTERED; report.buttons = 0; if (has_gamepad_key) tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); has_gamepad_key = false; } } break; default: break; } } void hid_task(void* param) { (void) param; while(1) { // Poll every 10ms vTaskDelay(pdMS_TO_TICKS(10)); uint32_t const btn = board_button_read(); // Remote wakeup if ( tud_suspended() && btn ) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); } else { // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() send_hid_report(REPORT_ID_KEYBOARD, btn); } } } // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) len; uint8_t next_report_id = report[0] + 1; if (next_report_id < REPORT_ID_COUNT) { send_hid_report(next_report_id, board_button_read()); } } // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented (void) instance; (void) report_id; (void) report_type; (void) buffer; (void) reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { (void) instance; if (report_type == HID_REPORT_TYPE_OUTPUT) { // Set keyboard LED e.g Capslock, Numlock etc... if (report_id == REPORT_ID_KEYBOARD) { // bufsize should be (at least) 1 if ( bufsize < 1 ) return; uint8_t const kbd_leds = buffer[0]; if (kbd_leds & KEYBOARD_LED_CAPSLOCK) { // Capslock On: disable blink, turn led on xTimerStop(blinky_tm, portMAX_DELAY); board_led_write(true); }else { // Caplocks Off: back to normal blink board_led_write(false); xTimerStart(blinky_tm, portMAX_DELAY); } } } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinky_cb(TimerHandle_t xTimer) { (void) xTimer; static bool led_state = false; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/hid_composite_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by board.mk #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // This examples use FreeRTOS #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif // can be defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_HID 1 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 16 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/hid_composite_freertos/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )), TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )), TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )), TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD )) }; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) { (void) instance; return desc_hid_report; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_HID, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN) #define EPNUM_HID 0x81 uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5) }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // other speed config is basically configuration with type = OTHER_SPEED_CONFIG memcpy(desc_other_speed_config, desc_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; // this example use the same configuration for both high and full speed mode return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/hid_composite_freertos/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { REPORT_ID_KEYBOARD = 1, REPORT_ID_MOUSE, REPORT_ID_CONSUMER_CONTROL, REPORT_ID_GAMEPAD, REPORT_ID_COUNT }; #endif /* USB_DESCRIPTORS_H_ */ ================================================ FILE: examples/device/hid_generic_inout/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_generic_inout C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/hid_generic_inout/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/hid_generic_inout/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/hid_generic_inout/boards.js ================================================ module.exports = { "Adafruit Boards":[0x239A,0xFFFF], "TinyUSB example":[0xCAFE,0xFFFF] } ================================================ FILE: examples/device/hid_generic_inout/hid_test.js ================================================ // IMPORTANT: install the dependency via 'npm i node-hid' in the same location as the script // If the install fails on windows you may need to run 'npm i -g windows-build-tools' first to be able to compile native code needed for this library var HID = require('node-hid'); var os = require('os') // list of supported devices var boards = require('./boards.js') var devices = HID.devices(); // this will choose any device found in the boards.js file var deviceInfo = devices.find(anySupportedBoard); var reportLen = 64; var message = "Hello World!" // Turn our string into an array of integers e.g. 'ascii codes', though charCodeAt spits out UTF-16 // This means if you have characters in your string that are not Latin-1 you will have to add additional logic for character codes above 255 var messageBuffer = Array.from(message, function(c){return c.charCodeAt(0)}); // HIDAPI requires us to prepend a 0 for single hid report as dummy reportID messageBuffer.unshift(0) // Some OSes expect that you always send a buffer that equals your report length // So lets fill up the rest of the buffer with zeros var paddingBuf = Array(reportLen-messageBuffer.length); paddingBuf.fill(0) messageBuffer = messageBuffer.concat(paddingBuf) // check if we actually found a device and if so send our messageBuffer to it if( deviceInfo ) { console.log(deviceInfo) var device = new HID.HID( deviceInfo.path ); // register an event listener for data coming from the device device.on("data", function(data) { // Print what we get from the device console.log(data.toString('ascii')); }); // the same for any error that occur device.on("error", function(err) {console.log(err)}); // send our message to the device every 500ms setInterval(function () { device.write(messageBuffer); },500) } function anySupportedBoard(d) { for (var key in boards) { if (boards.hasOwnProperty(key)) { if (isDevice(boards[key],d)) { console.log("Found " + d.product); return true; } } } return false; } function isDevice(board,d){ // product id 0xff is matches all return d.vendorId==board[0] && (d.productId==board[1] || board[1] == 0xFFFF); } ================================================ FILE: examples/device/hid_generic_inout/hid_test.py ================================================ #!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ import hid # default is TinyUSB (0xcafe), Adafruit (0x239a), RaspberryPi (0x2e8a), Espressif (0x303a) VID USB_VID = (0xcafe, 0x239a, 0x2e8a, 0x303a) print("VID list: " + ", ".join('%02x' % v for v in USB_VID)) for vid in USB_VID: for dict in hid.enumerate(vid): print(dict) dev = hid.Device(dict['vendor_id'], dict['product_id']) if dev: while True: # Get input from console and encode to UTF8 for array of chars. # hid generic in/out is single report therefore by HIDAPI requirement # it must be preceded, with 0x00 as dummy reportID str_out = b'\x00' str_out += input("Send text to HID Device : ").encode('utf-8') dev.write(str_out) str_in = dev.read(64) print("Received from HID Device:", str_in, '\n') ================================================ FILE: examples/device/hid_generic_inout/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" /* This example demonstrate HID Generic raw Input & Output. * It will receive data from Host (In endpoint) and echo back (Out endpoint). * HID Report descriptor use vendor for usage page (using template TUD_HID_REPORT_DESC_GENERIC_INOUT) * * There are 2 ways to test the sketch * 1. Using nodejs * - Install nodejs and npm to your PC * * - Install excellent node-hid (https://github.com/node-hid/node-hid) by * $ npm install node-hid * * - Run provided hid test script * $ node hid_test.js * * 2. Using python * - Install `hid` package (https://pypi.org/project/hid/) by * $ pip install hid * * - hid package replies on hidapi (https://github.com/libusb/hidapi) for backend, * which already available in Linux. However on windows, you may need to download its dlls from their release page and * copy it over to folder where python is installed. * * - Run provided hid test script to send and receive data to this device. * $ python3 hid_test.py */ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented (void) itf; (void) report_id; (void) report_type; (void) buffer; (void) reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { // This example doesn't use multiple report and report ID (void) itf; (void) report_id; (void) report_type; // echo back anything we received from host tud_hid_report(0, buffer, bufsize); } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/hid_generic_inout/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 1 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 64 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/hid_generic_inout/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE) }; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) { (void) itf; return desc_hid_report; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_HID, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN) #if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_HID_OUT 0x01 #define EPNUM_HID_IN 0x82 #else #define EPNUM_HID_OUT 0x01 #define EPNUM_HID_IN 0x81 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, protocol, report descriptor len, EP Out & In address, size & polling interval TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID_OUT, EPNUM_HID_IN, CFG_TUD_HID_EP_BUFSIZE, 10) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/hid_multiple_interface/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_multiple_interface C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/hid_multiple_interface/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/hid_multiple_interface/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/hid_multiple_interface/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ // Interface index depends on the order in configuration descriptor enum { ITF_KEYBOARD = 0, ITF_MOUSE = 1 }; /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); void hid_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); hid_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ void hid_task(void) { // Poll every 10ms const uint32_t interval_ms = 10; static uint32_t start_ms = 0; if ( tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; uint32_t const btn = board_button_read(); // Remote wakeup if ( tud_suspended() && btn ) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); } /*------------- Keyboard -------------*/ if ( tud_hid_n_ready(ITF_KEYBOARD) ) { // use to avoid send multiple consecutive zero report for keyboard static bool has_key = false; if ( btn ) { uint8_t keycode[6] = { 0 }; keycode[0] = HID_KEY_A; tud_hid_n_keyboard_report(ITF_KEYBOARD, 0, 0, keycode); has_key = true; }else { // send empty key report if previously has key pressed if (has_key) tud_hid_n_keyboard_report(ITF_KEYBOARD, 0, 0, NULL); has_key = false; } } /*------------- Mouse -------------*/ if ( tud_hid_n_ready(ITF_MOUSE) ) { if ( btn ) { int8_t const delta = 5; // no button, right + down, no scroll pan tud_hid_n_mouse_report(ITF_MOUSE, 0, 0x00, delta, delta, 0, 0); } } } // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented (void) itf; (void) report_id; (void) report_type; (void) buffer; (void) reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { // TODO set LED based on CAPLOCK, NUMLOCK etc... (void) itf; (void) report_id; (void) report_type; (void) buffer; (void) bufsize; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/hid_multiple_interface/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_HID 2 #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 8 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/hid_multiple_interface/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_report1[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; uint8_t const desc_hid_report2[] = { TUD_HID_REPORT_DESC_MOUSE() }; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) { if (itf == 0) { return desc_hid_report1; } else if (itf == 1) { return desc_hid_report2; } return NULL; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_HID1, ITF_NUM_HID2, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_HID_DESC_LEN) #define EPNUM_HID1 0x81 #define EPNUM_HID2 0x82 uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR(ITF_NUM_HID1, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report1), EPNUM_HID1, CFG_TUD_HID_EP_BUFSIZE, 10), TUD_HID_DESCRIPTOR(ITF_NUM_HID2, 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report2), EPNUM_HID2, CFG_TUD_HID_EP_BUFSIZE, 10) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "Keyboard Interface", // 4: Interface 1 String "Mouse Interface", // 5: Interface 2 String }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/midi_test/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(midi_test C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/midi_test/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/midi_test/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/midi_test/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" /* This MIDI example send sequence of note (on/off) repeatedly. To test on PC, you need to install * synth software and midi connection management software. On * - Linux (Ubuntu): install qsynth, qjackctl. Then connect TinyUSB output port to FLUID Synth input port * - Windows: install MIDI-OX * - MacOS: SimpleSynth */ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); void midi_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); midi_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // MIDI Task //--------------------------------------------------------------------+ // Variable that holds the current position in the sequence. uint32_t note_pos = 0; // Store example melody as an array of note values const uint8_t note_sequence[] = { 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78, 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61, 56,61,64,68,74,78,81,86,90,93,98,102 }; void midi_task(void) { static uint32_t start_ms = 0; uint8_t const cable_num = 0; // MIDI jack associated with USB endpoint uint8_t const channel = 0; // 0 for channel 1 // The MIDI interface always creates input and output port/jack descriptors // regardless of these being used or not. Therefore incoming traffic should be read // (possibly just discarded) to avoid the sender blocking in IO while (tud_midi_available()) { uint8_t packet[4]; tud_midi_packet_read(packet); } // send note periodically if (tusb_time_millis_api() - start_ms < 286) { return; // not enough time } start_ms += 286; // Previous positions in the note sequence. int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. if (previous < 0) { previous = sizeof(note_sequence) - 1; } // Send Note On for current position at full velocity (127) on channel 1. uint8_t note_on[3] = { 0x90 | channel, note_sequence[note_pos], 127 }; tud_midi_stream_write(cable_num, note_on, 3); // Send Note Off for previous note. uint8_t note_off[3] = { 0x80 | channel, note_sequence[previous], 0}; tud_midi_stream_write(cable_num, note_off, 3); // Increment position note_pos++; // If we are at the end of the sequence, start over. if (note_pos >= sizeof(note_sequence)) { note_pos = 0; } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/midi_test/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 1 #define CFG_TUD_VENDOR 0 // MIDI FIFO size of TX and RX #define CFG_TUD_MIDI_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_MIDI_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/midi_test/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_MIDI = 0, ITF_NUM_MIDI_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MIDI_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x82 #else #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x81 #endif static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 64) }; #if TUD_OPT_HIGH_SPEED static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 512) }; #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/midi_test_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(midi_test_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example with FreeRTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/device/midi_test_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/midi_test_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c \ src/usb_descriptors.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/midi_test_freertos/skip.txt ================================================ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI mcu:RAXXX family:broadcom_32bit family:broadcom_64bit family:hpmicro ================================================ FILE: examples/device/midi_test_freertos/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS main.c usb_descriptors.c INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/midi_test_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" /* This MIDI example send sequence of note (on/off) repeatedly. To test on PC, you need to install * synth software and midi connection management software. On * - Linux (Ubuntu): install qsynth, qjackctl. Then connect TinyUSB output port to FLUID Synth input port * - Windows: install MIDI-OX * - MacOS: SimpleSynth */ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define MIDI_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t midi_stack[MIDI_STACK_SIZE]; StaticTask_t midi_taskdef; #endif /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void usb_device_task(void *param); void led_blinking_task(void* param); void midi_task(void* param); //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); xTaskCreateStatic(midi_task, "midi", MIDI_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, midi_stack, &midi_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(midi_task, "midi", MIDI_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); #endif #ifndef ESP_PLATFORM // only start scheduler for non-espressif mcu vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tud_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // MIDI Task //--------------------------------------------------------------------+ // Store example melody as an array of note values const uint8_t note_sequence[] = { 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78, 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61, 56,61,64,68,74,78,81,86,90,93,98,102 }; void midi_task(void* param) { (void) param; const uint8_t cable_num = 0; // MIDI jack associated with USB endpoint const uint8_t channel = 0; // 0 for channel 1 // Variable that holds the current position in the sequence. uint32_t note_pos = 0; while (1) { // send note periodically vTaskDelay(286 / portTICK_PERIOD_MS); // Previous positions in the note sequence. int previous = (int) (note_pos - 1); // If we currently are at position 0, set the // previous position to the last note in the sequence. if (previous < 0) { previous = sizeof(note_sequence) - 1; } // Send Note On for current position at full velocity (127) on channel 1. uint8_t note_on[3] = { 0x90 | channel, note_sequence[note_pos], 127 }; tud_midi_stream_write(cable_num, note_on, 3); // Send Note Off for previous note. uint8_t note_off[3] = { 0x80 | channel, note_sequence[previous], 0}; tud_midi_stream_write(cable_num, note_off, 3); // Increment position note_pos++; // If we are at the end of the sequence, start over. if (note_pos >= sizeof(note_sequence)) { note_pos = 0; } // The MIDI interface always creates input and output port/jack descriptors // regardless of these being used or not. Therefore incoming traffic should be read // (possibly just discarded) to avoid the sender blocking in IO while (tud_midi_available()) { uint8_t packet[4]; tud_midi_packet_read(packet); } } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void* param) { (void) param; static bool led_state = false; while (1) { // Blink every interval ms vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); board_led_write(led_state); led_state = 1 - led_state; // toggle } } ================================================ FILE: examples/device/midi_test_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 1 #define CFG_TUD_VENDOR 0 // MIDI FIFO size of TX and RX #define CFG_TUD_MIDI_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_MIDI_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/midi_test_freertos/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_MIDI = 0, ITF_NUM_MIDI_STREAMING, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MIDI_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x82 #else #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x81 #endif static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 64) }; #if TUD_OPT_HIGH_SPEED static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI_OUT, (0x80 | EPNUM_MIDI_IN), 512) }; #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/msc_dual_lun/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(msc_dual_lun C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() if (RTOS STREQUAL zephyr) set(EXE_NAME app) else() set(EXE_NAME ${PROJECT_NAME}) add_executable(${EXE_NAME}) endif() # Example source target_sources(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk_dual.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${EXE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${EXE_NAME} ${RTOS}) ================================================ FILE: examples/device/msc_dual_lun/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/msc_dual_lun/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/msc_dual_lun/prj.conf ================================================ CONFIG_GPIO=y CONFIG_FPU=y CONFIG_NO_OPTIMIZATIONS=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_NRFX_POWER=y ================================================ FILE: examples/device/msc_dual_lun/skip.txt ================================================ mcu:SAMD11 mcu:MKL25ZXX family:espressif ================================================ FILE: examples/device/msc_dual_lun/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Task parameter type: ULONG for ThreadX, void* for FreeRTOS and noos #if CFG_TUSB_OS == OPT_OS_THREADX #define RTOS_PARAM ULONG #elif CFG_TUSB_OS == OPT_OS_FREERTOS #define RTOS_PARAM void* static void freertos_init(void); #else #define RTOS_PARAM void* #endif void led_blinking_task(RTOS_PARAM param); //--------------------------------------------------------------------+ // USB Device Task //--------------------------------------------------------------------+ static void usb_device_init(void) { tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO static void usb_device_task(RTOS_PARAM param) { (void) param; usb_device_init(); while (1) { tud_task(); } } #endif //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); #if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); #elif CFG_TUSB_OS == OPT_OS_THREADX tx_kernel_enter(); #else // noos + pico-sdk: init USB then run polling loop usb_device_init(); while (1) { tud_task(); led_blinking_task(NULL); } #endif } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(RTOS_PARAM param) { (void) param; static uint32_t start_ms = 0; static bool led_state = false; while (1) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #elif CFG_TUSB_OS == OPT_OS_THREADX tx_thread_sleep(_osal_ms2tick(blink_interval_ms)); #else if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } #endif start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } } //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 #else #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2 * (CFG_TUSB_DEBUG ? 2 : 1)) #endif #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #if configSUPPORT_STATIC_ALLOCATION static StackType_t _usb_device_stack[USBD_STACK_SIZE]; static StaticTask_t _usb_device_taskdef; static StackType_t _blinky_stack[BLINKY_STACK_SIZE]; static StaticTask_t _blinky_taskdef; #endif static void freertos_init(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, _usb_device_stack, &_usb_device_taskdef); xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, _blinky_stack, &_blinky_taskdef); #else xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); #endif #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } //--------------------------------------------------------------------+ // ThreadX //--------------------------------------------------------------------+ #elif CFG_TUSB_OS == OPT_OS_THREADX #define USBD_STACK_SIZE 4096 #define BLINKY_STACK_SIZE 512 static TX_THREAD _usb_device_thread; static ULONG _usb_device_stack[USBD_STACK_SIZE / sizeof(ULONG)]; static TX_THREAD _blinky_thread; static ULONG _blinky_stack[BLINKY_STACK_SIZE / sizeof(ULONG)]; void tx_application_define(void *first_unused_memory) { (void) first_unused_memory; static CHAR usbd_name[] = "usbd"; static CHAR blinky_name[] = "blinky"; tx_thread_create(&_usb_device_thread, usbd_name, usb_device_task, 0, _usb_device_stack, USBD_STACK_SIZE, 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); tx_thread_create(&_blinky_thread, blinky_name, led_blinking_task, 0, _blinky_stack, BLINKY_STACK_SIZE, 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } #endif ================================================ FILE: examples/device/msc_dual_lun/src/msc_disk_dual.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #if CFG_TUD_MSC // When button is pressed, LUN1 will be set to not ready to simulate // medium not present (e.g SD card removed) // Some MCU doesn't have enough 8KB SRAM to store the whole disk // We will use Flash as read-only disk with board that has // CFG_EXAMPLE_MSC_READONLY defined #if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) #define MSC_CONST const #else #define MSC_CONST #endif enum { DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; //--------------------------------------------------------------------+ // LUN 0 //--------------------------------------------------------------------+ #define README0_CONTENTS \ "LUN0: This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" MSC_CONST uint8_t msc_disk0[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; // fat_num = 1; fat12_root_entry_num = 16; // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB 0 "; // FAT magic code at offset 510-511 { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , '0' , ' ' , ' ' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA }, //------------- Block1: FAT12 Table -------------// { 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// { // first entry is volume label 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , '0' , ' ' , ' ' , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // second entry is readme file 'R' , 'E' , 'A' , 'D' , 'M' , 'E' , '0' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D, 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, sizeof(README0_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// README0_CONTENTS }; //--------------------------------------------------------------------+ // LUN 1 //--------------------------------------------------------------------+ #define README1_CONTENTS \ "LUN1: This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" MSC_CONST uint8_t msc_disk1[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; // fat_num = 1; fat12_root_entry_num = 16; // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; // filesystem_type = "FAT12 "; volume_serial_number = 0x5678; volume_label = "TinyUSB 1 "; // FAT magic code at offset 510-511 { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x78, 0x56, 0x00, 0x00, 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , '1' , ' ' , ' ' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA }, //------------- Block1: FAT12 Table -------------// { 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Block2: Root Directory -------------// { // first entry is volume label 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , '1' , ' ' , ' ' , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // second entry is readme file 'R' , 'E' , 'A' , 'D' , 'M' , 'E' , '1' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D, 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, sizeof(README1_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files size (4 Bytes) }, //------------- Block3: Readme Content -------------// README1_CONTENTS }; // Invoked to determine max LUN uint8_t tud_msc_get_maxlun_cb(void) { return 2; // dual LUN } // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uint32_t bufsize) { (void) lun; (void) bufsize; const char vid[] = "TinyUSB"; const char pid[] = "Mass Storage"; const char rev[] = "1.0"; strncpy((char*) inquiry_resp->vendor_id, vid, 8); strncpy((char*) inquiry_resp->product_id, pid, 16); strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { return ( lun == 1 && board_button_read() ) ? false : true; } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; if (load_eject) { if (start) { // load disk storage } else { // unload disk storage } } return true; } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { // out of ramdisk if (lba >= DISK_BLOCK_NUM) return -1; uint8_t const* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(buffer, addr, bufsize); return (int32_t) bufsize; } bool tud_msc_is_writable_cb(uint8_t lun) { (void) lun; #if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) return false; #else return true; #endif } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { // out of ramdisk if (lba >= DISK_BLOCK_NUM) { return -1; } #if defined(CFG_EXAMPLE_MSC_READONLY) || defined(CFG_EXAMPLE_MSC_DUAL_READONLY) (void) lun; (void) lba; (void) offset; (void) buffer; #else uint8_t* addr = (lun ? msc_disk1[lba] : msc_disk0[lba]) + offset; memcpy(addr, buffer, bufsize); #endif return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks (MUST not be handled here) int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { (void) buffer; (void) bufsize; switch (scsi_cmd[0]) { default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status return -1; } } #endif ================================================ FILE: examples/device/msc_dual_lun/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/msc_dual_lun/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_MSC, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_MSC_OUT 0x02 #define EPNUM_MSC_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_MSC_OUT 0x02 #define EPNUM_MSC_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 #else #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x81 #endif static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64), }; #if TUD_OPT_HIGH_SPEED static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512), }; #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/mtp/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(mtp C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() if (RTOS STREQUAL zephyr) set(EXE_NAME app) else() set(EXE_NAME ${PROJECT_NAME}) add_executable(${EXE_NAME}) endif() # Example source target_sources(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/mtp_fs_example.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${EXE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${EXE_NAME} ${RTOS}) ================================================ FILE: examples/device/mtp/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/mtp/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/mtp/prj.conf ================================================ CONFIG_GPIO=y CONFIG_FPU=y CONFIG_NO_OPTIMIZATIONS=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_NRFX_POWER=y CONFIG_NRFX_UARTE0=y ================================================ FILE: examples/device/mtp/skip.txt ================================================ board:cynthion_d11 ================================================ FILE: examples/device/mtp/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/mtp/src/mtp_fs_example.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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 "bsp/board_api.h" #include "tusb.h" #include "tinyusb_logo_png.h" //--------------------------------------------------------------------+ // Dataset //--------------------------------------------------------------------+ //------------- device info -------------// #define DEV_INFO_MANUFACTURER "TinyUSB" #define DEV_INFO_MODEL "MTP Example" #define DEV_INFO_VERSION "1.0" #define DEV_PROP_FRIENDLY_NAME "TinyUSB MTP" //------------- storage info -------------// #define STORAGE_DESCRIPTION { 'd', 'i', 's', 'k', 0 } #define VOLUME_IDENTIFIER { 'v', 'o', 'l', 0 } enum { STORAGE_DESC_LEN = TU_ARRAY_SIZE((uint16_t[]) STORAGE_DESCRIPTION), VOLUME_ID_LEN = TU_ARRAY_SIZE((uint16_t[])VOLUME_IDENTIFIER) }; typedef MTP_STORAGE_INFO_STRUCT(STORAGE_DESC_LEN, VOLUME_ID_LEN) storage_info_t; storage_info_t storage_info = { #ifdef CFG_EXAMPLE_MTP_READONLY .storage_type = MTP_STORAGE_TYPE_FIXED_ROM, #else .storage_type = MTP_STORAGE_TYPE_FIXED_RAM, #endif .filesystem_type = MTP_FILESYSTEM_TYPE_GENERIC_HIERARCHICAL, .access_capability = MTP_ACCESS_CAPABILITY_READ_WRITE, .max_capacity_in_bytes = 0, // calculated at runtime .free_space_in_bytes = 0, // calculated at runtime .free_space_in_objects = 0, // calculated at runtime .storage_description = { .count = (TU_FIELD_SIZE(storage_info_t, storage_description)-1) / sizeof(uint16_t), .utf16 = STORAGE_DESCRIPTION }, .volume_identifier = { .count = (TU_FIELD_SIZE(storage_info_t, volume_identifier)-1) / sizeof(uint16_t), .utf16 = VOLUME_IDENTIFIER } }; //--------------------------------------------------------------------+ // MTP FILESYSTEM //--------------------------------------------------------------------+ // only allow to add 1 more object to make it simpler to manage memory #define FS_MAX_FILE_COUNT 3UL #define FS_MAX_FILENAME_LEN 16 #ifdef CFG_EXAMPLE_MTP_READONLY #define FS_MAX_CAPACITY_BYTES 0 #else #define FS_MAX_CAPACITY_BYTES (4 * 1024UL) // object data buffer (excluding 2 predefined files) with simple allocation pointer uint8_t fs_buf[FS_MAX_CAPACITY_BYTES]; #endif #define FS_FIXED_DATETIME "20250808T173500.0" // "YYYYMMDDTHHMMSS.s" #define README_TXT_CONTENT "TinyUSB MTP Filesystem example" typedef struct { uint16_t name[FS_MAX_FILENAME_LEN]; uint16_t object_format; uint16_t protection_status; uint32_t image_pix_width; uint32_t image_pix_height; uint32_t image_bit_depth; uint32_t parent; uint16_t association_type; uint32_t size; uint8_t* data; } fs_file_t; // Files system, handle is index + 1 static fs_file_t fs_objects[FS_MAX_FILE_COUNT] = { { .name = { 'r', 'e', 'a', 'd', 'm', 'e', '.', 't', 'x', 't', 0 }, // readme.txt .object_format = MTP_OBJ_FORMAT_TEXT, .protection_status = MTP_PROTECTION_STATUS_READ_ONLY, .image_pix_width = 0, .image_pix_height = 0, .image_bit_depth = 0, .parent = 0, .association_type = MTP_ASSOCIATION_UNDEFINED, .size = sizeof(README_TXT_CONTENT)-1, .data = (uint8_t*) (uintptr_t) README_TXT_CONTENT, }, { .name = { 't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'p', 'n', 'g', 0 }, // "tinyusb.png" .object_format = MTP_OBJ_FORMAT_PNG, .protection_status = MTP_PROTECTION_STATUS_READ_ONLY, .image_pix_width = 128, .image_pix_height = 64, .image_bit_depth = 32, .parent = 0, .association_type = MTP_ASSOCIATION_UNDEFINED, .size = LOGO_LEN, .data = (uint8_t*) (uintptr_t) logo_bin } }; enum { SUPPORTED_STORAGE_ID = 0x00010001u // physical = 1, logical = 1 }; static int32_t fs_get_device_info(tud_mtp_cb_data_t* cb_data); static int32_t fs_open_close_session(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_storage_ids(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_storage_info(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_device_properties(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_object_handles(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_object_info(tud_mtp_cb_data_t* cb_data); static int32_t fs_get_object(tud_mtp_cb_data_t* cb_data); static int32_t fs_delete_object(tud_mtp_cb_data_t* cb_data); static int32_t fs_send_object_info(tud_mtp_cb_data_t* cb_data); static int32_t fs_send_object(tud_mtp_cb_data_t* cb_data); typedef int32_t (*fs_op_handler_t)(tud_mtp_cb_data_t* cb_data); typedef struct { uint32_t op_code; fs_op_handler_t handler; }fs_op_handler_dict_t; fs_op_handler_dict_t fs_op_handler_dict[] = { { MTP_OP_GET_DEVICE_INFO, fs_get_device_info }, { MTP_OP_OPEN_SESSION, fs_open_close_session }, { MTP_OP_CLOSE_SESSION, fs_open_close_session }, { MTP_OP_GET_STORAGE_IDS, fs_get_storage_ids }, { MTP_OP_GET_STORAGE_INFO, fs_get_storage_info }, { MTP_OP_GET_DEVICE_PROP_DESC, fs_get_device_properties }, { MTP_OP_GET_DEVICE_PROP_VALUE, fs_get_device_properties }, { MTP_OP_GET_OBJECT_HANDLES, fs_get_object_handles }, { MTP_OP_GET_OBJECT_INFO, fs_get_object_info }, { MTP_OP_GET_OBJECT, fs_get_object }, { MTP_OP_DELETE_OBJECT, fs_delete_object }, { MTP_OP_SEND_OBJECT_INFO, fs_send_object_info }, { MTP_OP_SEND_OBJECT, fs_send_object }, }; static bool is_session_opened = false; static uint32_t send_obj_handle = 0; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Get pointer to object info from handle static inline fs_file_t* fs_get_file(uint32_t handle) { if (handle == 0 || handle > FS_MAX_FILE_COUNT) { return NULL; } return &fs_objects[handle-1]; } static inline bool fs_file_exist(fs_file_t* f) { return f->name[0] != 0; } // Get the number of allocated nodes in filesystem static uint32_t fs_get_file_count(void) { uint32_t count = 0; for (size_t i = 0; i < FS_MAX_FILE_COUNT; i++) { if (fs_file_exist(&fs_objects[i])) { count++; } } return count; } static inline fs_file_t* fs_create_file(void) { for (size_t i = 0; i < FS_MAX_FILE_COUNT; i++) { fs_file_t* f = &fs_objects[i]; if (!fs_file_exist(f)) { send_obj_handle = i + 1; return f; } } return NULL; } // simple malloc static inline uint8_t* fs_malloc(size_t size) { #ifdef CFG_EXAMPLE_MTP_READONLY (void) size; return NULL; #else if (size > FS_MAX_CAPACITY_BYTES) { return NULL; } return fs_buf; #endif } //--------------------------------------------------------------------+ // Control Request callback //--------------------------------------------------------------------+ bool tud_mtp_request_cancel_cb(tud_mtp_request_cb_data_t* cb_data) { mtp_request_reset_cancel_data_t cancel_data; memcpy(&cancel_data, cb_data->buf, sizeof(cancel_data)); (void) cancel_data.code; (void ) cancel_data.transaction_id; return true; } // Invoked when received Device Reset request // return false to stall the request bool tud_mtp_request_device_reset_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return true; } // Invoked when received Get Extended Event request. Application fill callback data's buffer for response // return negative to stall the request int32_t tud_mtp_request_get_extended_event_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return false; // not implemented yet } // Invoked when received Get DeviceStatus request. Application fill callback data's buffer for response // return negative to stall the request int32_t tud_mtp_request_get_device_status_cb(tud_mtp_request_cb_data_t* cb_data) { uint16_t* buf16 = (uint16_t*)(uintptr_t) cb_data->buf; buf16[0] = 4; // length buf16[1] = MTP_RESP_OK; // status return 4; } //--------------------------------------------------------------------+ // Bulk Only Protocol //--------------------------------------------------------------------+ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; fs_op_handler_t handler = NULL; for (size_t i = 0; i < TU_ARRAY_SIZE(fs_op_handler_dict); i++) { if (fs_op_handler_dict[i].op_code == command->header.code) { handler = fs_op_handler_dict[i].handler; break; } } int32_t resp_code; if (handler == NULL) { resp_code = MTP_RESP_OPERATION_NOT_SUPPORTED; } else { resp_code = handler(cb_data); if (resp_code > MTP_RESP_UNDEFINED) { // send response if needed io_container->header->code = (uint16_t)resp_code; tud_mtp_response_send(io_container); } } return resp_code; } int32_t tud_mtp_data_xfer_cb(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; fs_op_handler_t handler = NULL; for (size_t i = 0; i < TU_ARRAY_SIZE(fs_op_handler_dict); i++) { if (fs_op_handler_dict[i].op_code == command->header.code) { handler = fs_op_handler_dict[i].handler; break; } } int32_t resp_code; if (handler == NULL) { resp_code = MTP_RESP_OPERATION_NOT_SUPPORTED; } else { resp_code = handler(cb_data); if (resp_code > MTP_RESP_UNDEFINED) { // send response if needed io_container->header->code = (uint16_t)resp_code; tud_mtp_response_send(io_container); } } return 0; } int32_t tud_mtp_data_complete_cb(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* resp = &cb_data->io_container; switch (command->header.code) { case MTP_OP_SEND_OBJECT_INFO: { fs_file_t* f = fs_get_file(send_obj_handle); if (f == NULL) { resp->header->code = MTP_RESP_GENERAL_ERROR; break; } // parameter is: storage id, parent handle, new handle (void) mtp_container_add_uint32(resp, SUPPORTED_STORAGE_ID); (void) mtp_container_add_uint32(resp, f->parent); (void) mtp_container_add_uint32(resp, send_obj_handle); resp->header->code = MTP_RESP_OK; break; } default: resp->header->code = (cb_data->xfer_result == XFER_RESULT_SUCCESS) ? MTP_RESP_OK : MTP_RESP_GENERAL_ERROR; break; } tud_mtp_response_send(resp); return 0; } int32_t tud_mtp_response_complete_cb(tud_mtp_cb_data_t* cb_data) { (void) cb_data; return 0; // nothing to do } //--------------------------------------------------------------------+ // File System Handlers //--------------------------------------------------------------------+ static int32_t fs_get_device_info(tud_mtp_cb_data_t* cb_data) { // Device info is already prepared up to playback formats. Application only need to add string fields int32_t resp_code = 0; mtp_container_info_t* io_container = &cb_data->io_container; (void) mtp_container_add_cstring(io_container, DEV_INFO_MANUFACTURER); (void) mtp_container_add_cstring(io_container, DEV_INFO_MODEL); (void) mtp_container_add_cstring(io_container, DEV_INFO_VERSION); enum { MAX_SERIAL_NCHARS = 32 }; uint16_t serial_utf16[MAX_SERIAL_NCHARS+1]; size_t nchars = board_usb_get_serial(serial_utf16, MAX_SERIAL_NCHARS); serial_utf16[tu_min32(nchars, MAX_SERIAL_NCHARS)] = 0; // ensure null termination (void) mtp_container_add_string(io_container, serial_utf16); if (!tud_mtp_data_send(io_container)) { resp_code = MTP_RESP_DEVICE_BUSY; } return resp_code; } static int32_t fs_open_close_session(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; if (command->header.code == MTP_OP_OPEN_SESSION) { if (is_session_opened) { return MTP_RESP_SESSION_ALREADY_OPEN; } is_session_opened = true; } else { // close session if (!is_session_opened) { return MTP_RESP_SESSION_NOT_OPEN; } is_session_opened = false; } return MTP_RESP_OK; } static int32_t fs_get_storage_ids(tud_mtp_cb_data_t* cb_data) { mtp_container_info_t* io_container = &cb_data->io_container; uint32_t storage_ids [] = { SUPPORTED_STORAGE_ID }; (void) mtp_container_add_auint32(io_container, 1, storage_ids); tud_mtp_data_send(io_container); return 0; } static int32_t fs_get_storage_info(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint32_t storage_id = command->params[0]; TU_VERIFY(SUPPORTED_STORAGE_ID == storage_id, -1); // update storage info with current free space storage_info.max_capacity_in_bytes = sizeof(README_TXT_CONTENT) + LOGO_LEN + FS_MAX_CAPACITY_BYTES; storage_info.free_space_in_objects = FS_MAX_FILE_COUNT - fs_get_file_count(); storage_info.free_space_in_bytes = storage_info.free_space_in_objects ? FS_MAX_CAPACITY_BYTES : 0; (void) mtp_container_add_raw(io_container, &storage_info, sizeof(storage_info)); tud_mtp_data_send(io_container); return 0; } static int32_t fs_get_device_properties(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint16_t dev_prop_code = (uint16_t) command->params[0]; if (command->header.code == MTP_OP_GET_DEVICE_PROP_DESC) { // get describing dataset mtp_device_prop_desc_header_t device_prop_header; device_prop_header.device_property_code = dev_prop_code; switch (dev_prop_code) { case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME: device_prop_header.datatype = MTP_DATA_TYPE_STR; device_prop_header.get_set = MTP_MODE_GET; (void) mtp_container_add_raw(io_container, &device_prop_header, sizeof(device_prop_header)); (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // factory (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // current (void) mtp_container_add_uint8(io_container, 0); // no form tud_mtp_data_send(io_container); break; default: return MTP_RESP_PARAMETER_NOT_SUPPORTED; } } else { // get value switch (dev_prop_code) { case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME: (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); tud_mtp_data_send(io_container); break; default: return MTP_RESP_PARAMETER_NOT_SUPPORTED; } } return 0; } static int32_t fs_get_object_handles(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint32_t storage_id = command->params[0]; const uint32_t obj_format = command->params[1]; // optional const uint32_t parent_handle = command->params[2]; // folder handle, 0xFFFFFFFF is root (void)obj_format; if (storage_id != 0xFFFFFFFFu && storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } uint32_t handles[FS_MAX_FILE_COUNT] = { 0 }; uint32_t count = 0u; for (uint8_t i = 0u; i < FS_MAX_FILE_COUNT; i++) { fs_file_t* f = &fs_objects[i]; if (fs_file_exist(f) && (parent_handle == f->parent || (parent_handle == 0xFFFFFFFFu && f->parent == 0u))) { handles[count++] = (uint32_t) i + 1u; // handle is index + 1 } } (void) mtp_container_add_auint32(io_container, count, handles); tud_mtp_data_send(io_container); return 0; } static int32_t fs_get_object_info(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint32_t obj_handle = command->params[0]; fs_file_t* f = fs_get_file(obj_handle); if (f == NULL) { return MTP_RESP_INVALID_OBJECT_HANDLE; } mtp_object_info_header_t obj_info_header = { .storage_id = SUPPORTED_STORAGE_ID, .object_format = f->object_format, .protection_status = f->protection_status, .object_compressed_size = f->size, .thumb_format = MTP_OBJ_FORMAT_UNDEFINED, .thumb_compressed_size = 0, .thumb_pix_width = 0, .thumb_pix_height = 0, .image_pix_width = f->image_pix_width, .image_pix_height = f->image_pix_height, .image_bit_depth = f->image_bit_depth, .parent_object = f->parent, .association_type = f->association_type, .association_desc = 0, .sequence_number = 0 }; (void) mtp_container_add_raw(io_container, &obj_info_header, sizeof(obj_info_header)); (void) mtp_container_add_string(io_container, f->name); (void) mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); (void) mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); (void) mtp_container_add_cstring(io_container, ""); // keywords, not used tud_mtp_data_send(io_container); return 0; } static int32_t fs_get_object(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint32_t obj_handle = command->params[0]; const fs_file_t* f = fs_get_file(obj_handle); if (f == NULL) { return MTP_RESP_INVALID_OBJECT_HANDLE; } if (cb_data->phase == MTP_PHASE_COMMAND) { // If file contents is larger than CFG_TUD_MTP_EP_BUFSIZE, data may only partially is added here // the rest will be sent in tud_mtp_data_more_cb (void) mtp_container_add_raw(io_container, f->data, f->size); tud_mtp_data_send(io_container); } else if (cb_data->phase == MTP_PHASE_DATA) { // continue sending remaining data: file contents offset is xferred byte minus header size const uint32_t offset = cb_data->total_xferred_bytes - sizeof(mtp_container_header_t); const uint32_t xact_len = tu_min32(f->size - offset, io_container->payload_bytes); if (xact_len > 0) { memcpy(io_container->payload, f->data + offset, xact_len); tud_mtp_data_send(io_container); } } else { // nothing to do } return 0; } static int32_t fs_send_object_info(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; mtp_container_info_t* io_container = &cb_data->io_container; const uint32_t storage_id = command->params[0]; const uint32_t parent_handle = command->params[1]; // folder handle, 0xFFFFFFFF is root (void) parent_handle; if (!is_session_opened) { return MTP_RESP_SESSION_NOT_OPEN; } if (storage_id != 0xFFFFFFFFu && storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } if (cb_data->phase == MTP_PHASE_COMMAND) { (void) tud_mtp_data_receive(io_container); } else if (cb_data->phase == MTP_PHASE_DATA) { mtp_object_info_header_t* obj_info = (mtp_object_info_header_t*) io_container->payload; if (obj_info->storage_id != 0 && obj_info->storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } if (obj_info->parent_object != 0 && obj_info->parent_object != 0xFFFFFFFFu) { // not root fs_file_t* parent = fs_get_file(obj_info->parent_object); if (parent == NULL || 0u == parent->association_type) { return MTP_RESP_INVALID_PARENT_OBJECT; } } uint8_t* f_buf = fs_malloc(obj_info->object_compressed_size); if (f_buf == NULL) { return MTP_RESP_STORE_FULL; } fs_file_t* f = fs_create_file(); if (f == NULL) { return MTP_RESP_STORE_FULL; } f->object_format = obj_info->object_format; f->protection_status = obj_info->protection_status; f->image_pix_width = obj_info->image_pix_width; f->image_pix_height = obj_info->image_pix_height; f->image_bit_depth = obj_info->image_bit_depth; f->parent = obj_info->parent_object; f->association_type = obj_info->association_type; f->size = obj_info->object_compressed_size; f->data = f_buf; uint8_t* buf = io_container->payload + sizeof(mtp_object_info_header_t); (void) mtp_container_get_string(buf, f->name); // ignore date created/modified/keywords } else { // nothing to do } return 0; } static int32_t fs_send_object(tud_mtp_cb_data_t* cb_data) { mtp_container_info_t* io_container = &cb_data->io_container; fs_file_t* f = fs_get_file(send_obj_handle); if (f == NULL) { return MTP_RESP_INVALID_OBJECT_HANDLE; } if (cb_data->phase == MTP_PHASE_COMMAND) { io_container->header->len += f->size; tud_mtp_data_receive(io_container); } else { // file contents offset is total xferred minus header size minus last received chunk const uint32_t offset = cb_data->total_xferred_bytes - sizeof(mtp_container_header_t) - io_container->payload_bytes; memcpy(f->data + offset, io_container->payload, io_container->payload_bytes); if (cb_data->total_xferred_bytes - sizeof(mtp_container_header_t) < f->size) { tud_mtp_data_receive(io_container); } } return 0; } static int32_t fs_delete_object(tud_mtp_cb_data_t* cb_data) { const mtp_container_command_t* command = cb_data->command_container; const uint32_t obj_handle = command->params[0]; const uint32_t obj_format = command->params[1]; // optional (void) obj_format; if (!is_session_opened) { return MTP_RESP_SESSION_NOT_OPEN; } fs_file_t* f = fs_get_file(obj_handle); if (f == NULL) { return MTP_RESP_INVALID_OBJECT_HANDLE; } // delete object by clear the name f->name[0] = 0; return MTP_RESP_OK; } ================================================ FILE: examples/device/mtp/src/tinyusb_logo_png.h ================================================ // convert using tools/file2carray.py enum { LOGO_LEN = 2733 }; static const uint8_t logo_bin[] __attribute__((aligned(16))) = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0xd2, 0xd6, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x0a, 0x62, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x9c, 0x7d, 0x54, 0x54, 0x65, 0x1a, 0xc0, 0x7f, 0xc3, 0x00, 0x29, 0x1f, 0x31, 0x88, 0x61, 0x90, 0xd6, 0xa1, 0xb3, 0xba, 0x1a, 0x18, 0x7e, 0xf2, 0xad, 0x40, 0x82, 0xb8, 0x9b, 0x2b, 0x43, 0x1e, 0xd2, 0x00, 0x53, 0xc0, 0xea, 0xec, 0xc9, 0x70, 0x18, 0x3d, 0x5b, 0xb1, 0x9e, 0x4a, 0x6d, 0x13, 0x2d, 0xcb, 0x76, 0xcd, 0x00, 0xf3, 0x8b, 0x10, 0x8a, 0x8e, 0xd6, 0xee, 0xda, 0x8a, 0x96, 0x30, 0x66, 0xa2, 0xa0, 0x91, 0x64, 0xae, 0x16, 0x98, 0x45, 0x9d, 0x2c, 0x93, 0x8f, 0x05, 0x11, 0x92, 0x81, 0xbb, 0x7f, 0xa8, 0x93, 0x33, 0x23, 0xcc, 0xdc, 0x61, 0x60, 0x46, 0xb8, 0xbf, 0xbf, 0x78, 0xdf, 0xfb, 0x3c, 0xcf, 0xfb, 0xc0, 0x7d, 0xee, 0x73, 0xdf, 0xf7, 0xb9, 0xef, 0x8b, 0x8c, 0x6b, 0x08, 0x82, 0x90, 0x08, 0x2c, 0x03, 0x02, 0x81, 0x21, 0x48, 0x0c, 0x44, 0xda, 0x81, 0x6a, 0xe0, 0x55, 0x99, 0x4c, 0x56, 0x0c, 0x20, 0x03, 0x10, 0x04, 0x61, 0x35, 0xb0, 0xc2, 0x86, 0x8e, 0x49, 0xf4, 0x3f, 0x6b, 0x64, 0x32, 0x59, 0x96, 0x4c, 0x10, 0x84, 0x19, 0xc0, 0x47, 0x5c, 0x0b, 0x06, 0x89, 0x41, 0x45, 0xac, 0x03, 0xa0, 0x42, 0xba, 0xf9, 0x83, 0x15, 0x95, 0x4c, 0x10, 0x84, 0x8b, 0x80, 0x97, 0xad, 0x3d, 0x91, 0xb0, 0x09, 0x4d, 0x32, 0x41, 0x10, 0x3a, 0x01, 0x07, 0x5b, 0x7b, 0x22, 0x61, 0x1b, 0x1c, 0x90, 0xd2, 0xff, 0xa0, 0x46, 0x7a, 0xf2, 0x07, 0x39, 0x52, 0x00, 0x0c, 0x72, 0x1c, 0x2d, 0x55, 0x3c, 0x52, 0x5e, 0x4e, 0x53, 0x63, 0x93, 0x28, 0x9d, 0x49, 0x93, 0x27, 0x31, 0xe2, 0xce, 0x3b, 0x4d, 0xca, 0x5d, 0xba, 0x74, 0x89, 0xea, 0x13, 0xd5, 0x26, 0xe5, 0x46, 0x8c, 0xf0, 0xe6, 0x77, 0xa3, 0x47, 0x8b, 0xf2, 0x41, 0x42, 0x1f, 0x99, 0x20, 0x08, 0x5d, 0x58, 0x30, 0x0f, 0x48, 0x7c, 0x68, 0x2e, 0x9f, 0x57, 0x55, 0x89, 0xd2, 0xd9, 0x94, 0x9b, 0xc3, 0xcc, 0xb8, 0x38, 0x93, 0x72, 0x27, 0xbf, 0x38, 0x49, 0xc2, 0x9c, 0x39, 0x78, 0x78, 0x78, 0x74, 0x2b, 0xd3, 0xd6, 0xd6, 0x46, 0xbc, 0x52, 0xc9, 0x9a, 0x75, 0x6b, 0x45, 0xf9, 0x20, 0xa1, 0x8f, 0xc5, 0x19, 0xa0, 0x3f, 0xa8, 0xfc, 0xec, 0x38, 0x72, 0xc7, 0x9b, 0xbb, 0xb8, 0x22, 0x2b, 0x8b, 0x4e, 0x6d, 0x67, 0x3f, 0x7b, 0x34, 0xf0, 0x90, 0xe6, 0x00, 0x83, 0x1c, 0xbb, 0x0e, 0x80, 0xb6, 0xb6, 0x36, 0x5e, 0x5c, 0xb5, 0x8a, 0x0f, 0x76, 0xbf, 0x0f, 0x40, 0xdd, 0x77, 0xdf, 0xf1, 0xe2, 0xaa, 0x55, 0x1c, 0xfe, 0xf4, 0xb0, 0x8d, 0x3d, 0x1b, 0x38, 0xd8, 0x75, 0x00, 0x68, 0xb5, 0x5a, 0x34, 0xa5, 0x65, 0x9c, 0x3a, 0x75, 0x0a, 0x80, 0xa6, 0xa6, 0xff, 0xa1, 0x29, 0x2d, 0xa3, 0xae, 0xee, 0x3b, 0x1b, 0x7b, 0x36, 0x70, 0xb0, 0xeb, 0x39, 0x80, 0xbb, 0xbb, 0x3b, 0x1f, 0x6b, 0xca, 0x74, 0xed, 0xfb, 0x03, 0xef, 0xd7, 0xb5, 0x57, 0x64, 0x65, 0xd9, 0xca, 0xad, 0x01, 0x85, 0x5d, 0x07, 0x80, 0xbd, 0x70, 0xb9, 0xf5, 0x32, 0x3f, 0x5f, 0xf8, 0x19, 0xb9, 0x83, 0x03, 0x6e, 0xee, 0xee, 0x28, 0x14, 0x0a, 0x1c, 0x1c, 0xec, 0x3a, 0x79, 0x9a, 0x8d, 0xd9, 0xcb, 0xc0, 0x8e, 0x8e, 0x0e, 0x56, 0x3e, 0xff, 0xbc, 0xae, 0xfd, 0xf1, 0xfe, 0x8f, 0xb8, 0x78, 0xf1, 0xa2, 0xa8, 0xc1, 0x22, 0xa6, 0x4d, 0x63, 0xe4, 0xa8, 0x91, 0x7a, 0x7d, 0xa1, 0x61, 0x61, 0x3c, 0x38, 0x7b, 0xb6, 0xae, 0xfd, 0xf7, 0x0d, 0x1b, 0x38, 0x73, 0xfa, 0x0c, 0xfb, 0xf7, 0xed, 0xe3, 0xe1, 0xf9, 0xf3, 0xba, 0xfd, 0x43, 0x1f, 0xab, 0x3c, 0x86, 0xd0, 0xd5, 0x45, 0x50, 0x48, 0x30, 0x69, 0x8b, 0x17, 0x73, 0xef, 0xbd, 0xf7, 0xea, 0xae, 0x7d, 0xb4, 0x7f, 0x3f, 0x07, 0x35, 0x1a, 0x51, 0xbe, 0xad, 0x5c, 0xbd, 0x1a, 0xb9, 0x5c, 0x0e, 0x5c, 0x9d, 0x6b, 0x94, 0xec, 0x2d, 0xe1, 0xa0, 0x46, 0x43, 0xf5, 0x89, 0x13, 0xb4, 0xb7, 0xb7, 0xeb, 0xc9, 0xba, 0xb9, 0xb9, 0xe1, 0x1f, 0x10, 0x40, 0x4c, 0x6c, 0x0c, 0xf1, 0x09, 0x09, 0x0c, 0x1b, 0x36, 0x4c, 0x77, 0xed, 0xc7, 0x1f, 0x7f, 0x64, 0xd3, 0xc6, 0x8d, 0xa2, 0xc6, 0x06, 0x70, 0x90, 0x39, 0xf0, 0xec, 0x5f, 0xb3, 0x18, 0xea, 0xe2, 0x22, 0x4a, 0xef, 0xdd, 0xa2, 0x77, 0x38, 0x79, 0xf2, 0x0b, 0xbd, 0xbe, 0xe4, 0x94, 0x14, 0xc6, 0xdd, 0x77, 0x9f, 0x59, 0xfa, 0x66, 0x07, 0x40, 0x5b, 0x5b, 0x1b, 0xe3, 0xc7, 0x99, 0x67, 0x54, 0x0c, 0x8b, 0xd2, 0x52, 0x59, 0xf1, 0xdc, 0x73, 0xba, 0x76, 0x5c, 0x4c, 0x2c, 0x67, 0x6b, 0x6b, 0x45, 0xd9, 0x28, 0x28, 0x2a, 0x24, 0x24, 0x34, 0x54, 0xd7, 0x5e, 0xff, 0xf2, 0x2b, 0xbc, 0xf9, 0xc6, 0x1b, 0xa2, 0x6c, 0x9c, 0xa9, 0xad, 0xa1, 0xa1, 0xa1, 0x81, 0x7f, 0x6c, 0x78, 0x9d, 0xe2, 0xe2, 0x77, 0xcd, 0x5e, 0x62, 0x0e, 0x19, 0x32, 0x84, 0xa5, 0x99, 0x99, 0xa4, 0xa5, 0xa7, 0xe9, 0x96, 0xac, 0x73, 0xe3, 0x95, 0x54, 0x57, 0x9b, 0x2e, 0x64, 0x19, 0xf2, 0xf4, 0xb3, 0xcf, 0xf2, 0xd8, 0x13, 0x8f, 0x9b, 0x2d, 0xdf, 0xdc, 0xdc, 0x4c, 0x44, 0x68, 0x28, 0x97, 0x5b, 0x2f, 0xeb, 0xfa, 0x14, 0x0a, 0x05, 0x87, 0xca, 0x0f, 0x9b, 0x1d, 0x48, 0x03, 0x23, 0x8f, 0x59, 0x81, 0xea, 0x13, 0x27, 0x98, 0x3d, 0xeb, 0x0f, 0x14, 0x15, 0x16, 0x8a, 0xaa, 0x2f, 0xb4, 0xb7, 0xb7, 0xb3, 0x76, 0xcd, 0x1a, 0x32, 0x96, 0x3c, 0x45, 0xa7, 0x56, 0x0b, 0xc0, 0x53, 0xaa, 0xa5, 0x16, 0xf9, 0x90, 0x97, 0x9b, 0xa3, 0x77, 0x33, 0x4d, 0x51, 0xb4, 0xb3, 0xd0, 0x48, 0x3e, 0xe5, 0xd1, 0x05, 0xa2, 0xb2, 0x88, 0x14, 0x00, 0xd7, 0x78, 0xe2, 0xb1, 0xc7, 0x69, 0x68, 0x68, 0xb0, 0x58, 0x7f, 0x5f, 0x49, 0x09, 0x6b, 0xb3, 0xaf, 0x56, 0x25, 0xa3, 0xa2, 0xa3, 0x09, 0x9c, 0x30, 0x41, 0xb4, 0x8d, 0xc6, 0x86, 0x46, 0x76, 0x16, 0x14, 0x98, 0x25, 0xab, 0xd5, 0x6a, 0x29, 0xc8, 0xcf, 0xd7, 0xeb, 0x73, 0x72, 0x72, 0x22, 0x29, 0x25, 0x45, 0xd4, 0x98, 0x66, 0x4f, 0x02, 0x9d, 0x9d, 0x9d, 0xd9, 0x71, 0x83, 0x73, 0xab, 0x57, 0xae, 0xa4, 0xb6, 0xa6, 0x46, 0xd4, 0x60, 0x19, 0x2a, 0x15, 0x93, 0xa7, 0x4c, 0xd1, 0xeb, 0xf3, 0xf1, 0xf5, 0x11, 0x65, 0xa3, 0xaf, 0x68, 0x6a, 0x6c, 0xec, 0xb5, 0x8d, 0x1d, 0xdb, 0xb7, 0x91, 0xf8, 0x70, 0x22, 0xa3, 0xc7, 0x8c, 0x61, 0x69, 0xa6, 0x8a, 0xb4, 0x85, 0x8b, 0x44, 0xdb, 0xc8, 0xcb, 0xcd, 0x21, 0x39, 0x25, 0x05, 0x17, 0xd7, 0x9e, 0x9f, 0xe2, 0x0f, 0xf7, 0xec, 0xe1, 0xfc, 0xf9, 0xf3, 0x7a, 0x7d, 0x73, 0xe2, 0xe3, 0xf1, 0xf6, 0xf6, 0x16, 0x35, 0x9e, 0xd9, 0x01, 0x20, 0x97, 0xcb, 0x09, 0x8f, 0x08, 0xd7, 0xb5, 0xdd, 0xdd, 0xdd, 0x45, 0x0d, 0x04, 0x30, 0x76, 0xdc, 0x58, 0x3d, 0x1b, 0xf6, 0xc4, 0x5d, 0x77, 0xdd, 0x45, 0x70, 0x48, 0x08, 0x23, 0x47, 0x8d, 0xa4, 0xab, 0xab, 0x8b, 0xe3, 0xc7, 0x8e, 0x73, 0xf4, 0xc8, 0x11, 0x51, 0x36, 0x3a, 0xb5, 0x9d, 0x14, 0x15, 0x16, 0xf2, 0xdc, 0x0b, 0x2f, 0x30, 0x3d, 0x32, 0x92, 0x29, 0x53, 0xa7, 0x70, 0xfc, 0xd8, 0x71, 0x51, 0x36, 0xae, 0x67, 0x01, 0x53, 0x73, 0x81, 0xfc, 0x6d, 0xdb, 0x8d, 0xfa, 0x16, 0xa5, 0xa5, 0x8a, 0x1a, 0x0b, 0xa4, 0x57, 0x80, 0x8e, 0x98, 0x99, 0xb1, 0xac, 0x5b, 0xff, 0x0a, 0x19, 0x2a, 0x15, 0x2a, 0xb5, 0x9a, 0x82, 0xa2, 0x42, 0xfe, 0xfc, 0xe4, 0x93, 0xa2, 0xed, 0x94, 0x95, 0xfe, 0x56, 0xb7, 0x58, 0x92, 0x91, 0x61, 0x91, 0x2f, 0xa6, 0xe6, 0x02, 0x95, 0x15, 0x15, 0x46, 0x93, 0xcc, 0xb0, 0xf0, 0x70, 0xb3, 0x67, 0xfe, 0x37, 0x22, 0x05, 0x40, 0x0f, 0x2c, 0x4a, 0x4b, 0xd5, 0x2d, 0x0d, 0xcd, 0xe5, 0xfb, 0xba, 0x3a, 0x9a, 0x9a, 0xae, 0x7e, 0x26, 0x8f, 0x98, 0x36, 0x8d, 0xa9, 0x41, 0x53, 0x45, 0x8f, 0x6b, 0x6a, 0x2e, 0xb0, 0xe5, 0xad, 0xb7, 0x8c, 0xfa, 0x52, 0xd3, 0xd3, 0x44, 0x8f, 0x03, 0x52, 0x00, 0xf4, 0x88, 0x97, 0x97, 0x17, 0x0a, 0x85, 0x42, 0xb4, 0x5e, 0x7d, 0x7d, 0xbd, 0xee, 0xe7, 0x25, 0x19, 0xd6, 0x5d, 0x11, 0x7c, 0x7b, 0xee, 0x5b, 0xca, 0x0e, 0x94, 0xea, 0xf5, 0xf9, 0xf9, 0xf9, 0x11, 0x19, 0x15, 0x65, 0xd1, 0x38, 0x76, 0x1b, 0x00, 0x81, 0x81, 0x81, 0x6c, 0xdc, 0xb4, 0x89, 0xdc, 0xcd, 0x9b, 0x89, 0x57, 0x2a, 0x01, 0x58, 0x98, 0xba, 0x88, 0x3d, 0x25, 0x7b, 0xd9, 0xf5, 0xcf, 0x0f, 0x48, 0x4d, 0x4b, 0x43, 0x26, 0xeb, 0xfb, 0xed, 0x8c, 0xb7, 0xdf, 0x7e, 0xbb, 0x68, 0x9d, 0xc6, 0x86, 0xdf, 0x26, 0x94, 0xe1, 0x11, 0xe1, 0x4c, 0x0d, 0x0a, 0xb2, 0xc8, 0xc6, 0xcd, 0xb2, 0xc0, 0xb6, 0xad, 0x5b, 0xe9, 0xea, 0xea, 0xd2, 0xeb, 0x4b, 0x7b, 0x6c, 0xb1, 0xc5, 0x95, 0x49, 0xbb, 0x2c, 0x05, 0xfb, 0xfa, 0xfa, 0x52, 0x50, 0x54, 0xa8, 0x5b, 0xcf, 0xce, 0x88, 0x8d, 0x61, 0x7a, 0x64, 0x24, 0xf1, 0x09, 0x4a, 0x9d, 0x4c, 0x60, 0x60, 0x20, 0x1d, 0x37, 0x59, 0x0a, 0x59, 0x1b, 0x4b, 0x82, 0xac, 0xab, 0x4b, 0xbf, 0x8e, 0x90, 0xa1, 0x5a, 0xca, 0x82, 0xa4, 0x64, 0xd1, 0x76, 0x0c, 0x57, 0x04, 0x4d, 0x4d, 0x4d, 0xec, 0xde, 0xb5, 0x4b, 0x4f, 0x46, 0xa1, 0x50, 0xa0, 0x54, 0x2a, 0x6f, 0xa6, 0x6e, 0x16, 0x76, 0x99, 0x01, 0xe6, 0x28, 0x95, 0x0c, 0x75, 0x71, 0x61, 0x5d, 0x76, 0x36, 0xe1, 0x21, 0xa1, 0xe4, 0x6f, 0xdf, 0x41, 0x7c, 0x82, 0x92, 0xa3, 0x47, 0x8e, 0x70, 0xbf, 0xbf, 0x3f, 0x33, 0x1f, 0x98, 0x41, 0x4b, 0x4b, 0x0b, 0xf3, 0x93, 0x1e, 0xb1, 0xb5, 0xab, 0x66, 0x11, 0x1a, 0x16, 0x46, 0x50, 0x70, 0xb0, 0x68, 0x3d, 0xc3, 0x2c, 0x50, 0x58, 0x50, 0x40, 0xdb, 0x65, 0xfd, 0xd7, 0x42, 0xf2, 0x82, 0x14, 0xd1, 0xe5, 0xe3, 0x1b, 0xb1, 0xcb, 0x00, 0x18, 0x35, 0x6a, 0x14, 0x70, 0x75, 0x69, 0xf6, 0xe8, 0xc2, 0x85, 0xb8, 0xb9, 0xbb, 0x01, 0x57, 0x9f, 0xc6, 0x27, 0x97, 0x3c, 0xc5, 0xdc, 0xc4, 0x44, 0x5a, 0x2f, 0xb5, 0x72, 0xcf, 0xdd, 0x77, 0xdb, 0xd2, 0x4d, 0x51, 0xa8, 0x97, 0x2f, 0xb7, 0x48, 0xef, 0xfa, 0x5c, 0x40, 0xab, 0xd5, 0x52, 0xb8, 0x73, 0xa7, 0xde, 0x35, 0x27, 0x27, 0x27, 0x92, 0x17, 0x2c, 0xe8, 0x95, 0x5f, 0x76, 0xf9, 0x0a, 0x70, 0x76, 0x76, 0x06, 0x30, 0xfa, 0xe5, 0x82, 0x43, 0x42, 0x08, 0x0e, 0x09, 0xd1, 0xb5, 0xaf, 0x97, 0x5e, 0x6f, 0x05, 0xa6, 0x4c, 0x9d, 0x42, 0x70, 0x48, 0x08, 0x15, 0x47, 0x8f, 0x8a, 0xd2, 0xbb, 0x9e, 0x05, 0xbc, 0x86, 0x7b, 0xf1, 0xd3, 0xf9, 0x9f, 0xf4, 0xae, 0x59, 0x52, 0xf8, 0x31, 0xc4, 0x2e, 0x03, 0xa0, 0x20, 0x3f, 0x9f, 0xd2, 0xd2, 0x03, 0x26, 0xe5, 0x04, 0x41, 0xe8, 0x07, 0x6f, 0xac, 0x87, 0x4a, 0x9d, 0xc9, 0x23, 0x0f, 0xcf, 0x13, 0xad, 0xf7, 0x56, 0x5e, 0x1e, 0xc3, 0xef, 0x18, 0x6e, 0xd4, 0x6f, 0x49, 0xe1, 0xc7, 0x10, 0xbb, 0x0c, 0x80, 0xea, 0xea, 0xea, 0x9b, 0x7e, 0x4d, 0xf3, 0xf0, 0xf0, 0x20, 0x2a, 0x3a, 0x9a, 0xdb, 0x86, 0xdc, 0x46, 0xd5, 0x67, 0x55, 0xa2, 0x4b, 0xd1, 0xb6, 0x66, 0x6a, 0x50, 0x10, 0xa1, 0x61, 0x61, 0x1c, 0x29, 0x2f, 0x17, 0xa5, 0x57, 0x5f, 0x5f, 0xaf, 0xb7, 0xb4, 0x04, 0xcb, 0x0b, 0x3f, 0x86, 0xd8, 0xe5, 0x1c, 0xe0, 0x99, 0xac, 0x2c, 0x6a, 0xbf, 0x3d, 0x47, 0x4c, 0x6c, 0xac, 0xae, 0x2f, 0x6e, 0xd6, 0x2c, 0x0e, 0x68, 0xca, 0x58, 0xbf, 0xe1, 0x35, 0x5e, 0xca, 0xce, 0xe6, 0xc3, 0x92, 0xbd, 0x24, 0xce, 0x13, 0xff, 0x34, 0xd9, 0x9a, 0xcc, 0x65, 0x6a, 0xab, 0xd8, 0xb1, 0xb4, 0xf0, 0x63, 0x88, 0x5d, 0x06, 0xc0, 0xdd, 0xf7, 0x5c, 0x9d, 0xdc, 0xd5, 0xd6, 0xd4, 0x20, 0x93, 0xc9, 0xc8, 0x50, 0xa9, 0xd8, 0xf8, 0xe6, 0x26, 0x14, 0x9e, 0x9e, 0x1c, 0xd4, 0x68, 0x78, 0x79, 0xed, 0x5a, 0xae, 0x5c, 0xb9, 0xc2, 0x5f, 0x9e, 0x7e, 0xda, 0xc6, 0x9e, 0x8a, 0x67, 0xd2, 0xe4, 0xc9, 0xbd, 0xfe, 0x1e, 0xd2, 0x9b, 0xc2, 0x8f, 0x21, 0x76, 0xf9, 0x0a, 0xa8, 0xad, 0xa9, 0x61, 0x66, 0x5c, 0x1c, 0x1b, 0x73, 0xde, 0xa4, 0x53, 0xab, 0xc5, 0x3f, 0x20, 0x00, 0xad, 0x56, 0x4b, 0xf6, 0x4b, 0x2f, 0xb1, 0x7d, 0xeb, 0x36, 0x00, 0x66, 0xc4, 0xc4, 0x30, 0x61, 0xe2, 0x44, 0x9c, 0x9c, 0x9c, 0x6c, 0xec, 0xad, 0x78, 0x54, 0x6a, 0x75, 0xaf, 0x76, 0x36, 0xa7, 0x2e, 0x4e, 0xb7, 0xda, 0x96, 0x34, 0xbb, 0xcc, 0x00, 0x9b, 0x73, 0xf3, 0xa8, 0xac, 0xa8, 0x60, 0xec, 0xd8, 0xb1, 0xf8, 0x07, 0x04, 0xf0, 0x7d, 0x5d, 0x1d, 0x49, 0xf3, 0xe6, 0xeb, 0x6e, 0xbe, 0xe7, 0x30, 0x4f, 0xc6, 0x8d, 0x1b, 0x47, 0xcd, 0xd7, 0x35, 0x74, 0x74, 0x74, 0xd8, 0xd8, 0x5b, 0xf1, 0x4c, 0x9c, 0x34, 0x89, 0x88, 0x69, 0xd3, 0x2c, 0xd2, 0x55, 0x28, 0x14, 0x24, 0x24, 0x24, 0x58, 0xcd, 0x17, 0x8b, 0x33, 0x80, 0x25, 0x25, 0x52, 0x73, 0x69, 0x69, 0x69, 0x21, 0x69, 0xde, 0x7c, 0x7c, 0x7c, 0x7c, 0x70, 0x75, 0x73, 0xe3, 0xdc, 0x37, 0xdf, 0xd0, 0xd9, 0xf9, 0x5b, 0x75, 0xad, 0xa5, 0xb9, 0x85, 0x88, 0xd0, 0x30, 0xae, 0xdc, 0x82, 0x37, 0xff, 0x3a, 0x2a, 0x75, 0x26, 0x9f, 0x1e, 0x3a, 0x24, 0x5a, 0xaf, 0xb7, 0x85, 0x1f, 0x43, 0x2c, 0x0e, 0x80, 0x61, 0x5e, 0xc3, 0x4c, 0x0b, 0x19, 0xf0, 0xeb, 0xaf, 0xbf, 0x9a, 0x25, 0xf7, 0xc7, 0xd9, 0x0f, 0xe2, 0xef, 0x1f, 0xd0, 0xed, 0xf5, 0x96, 0xe6, 0x66, 0xaa, 0xaa, 0xaa, 0xa8, 0xac, 0xa8, 0x10, 0xed, 0x83, 0xbd, 0x30, 0x61, 0xe2, 0x44, 0xa6, 0x47, 0x46, 0xf2, 0xc9, 0xc1, 0x83, 0x66, 0xeb, 0x38, 0x3a, 0x3a, 0x92, 0x94, 0x2c, 0xbe, 0xa4, 0xdc, 0xa3, 0x4d, 0x4b, 0x15, 0xc7, 0x8c, 0xf9, 0xbd, 0x68, 0x1d, 0xc3, 0x42, 0x46, 0x77, 0x44, 0x47, 0x3f, 0x40, 0xc2, 0xdc, 0x87, 0x4c, 0xca, 0xe5, 0xe5, 0xe4, 0xb2, 0x2e, 0x3b, 0x5b, 0xb4, 0x1f, 0xf6, 0x82, 0x7a, 0xf9, 0x32, 0x0e, 0x7d, 0xf2, 0x89, 0xd9, 0xf5, 0x8c, 0x39, 0xf1, 0xf1, 0x66, 0x9d, 0xae, 0x16, 0x83, 0xc5, 0x01, 0x10, 0x33, 0x33, 0x96, 0xb5, 0x6b, 0xd6, 0x88, 0xd2, 0x29, 0x7e, 0xe7, 0x1d, 0x62, 0x66, 0xc6, 0xe2, 0xe7, 0xe7, 0xd7, 0xa3, 0x5c, 0x5e, 0x6e, 0x2e, 0x1f, 0xbc, 0xbf, 0xbb, 0xdb, 0xeb, 0x1e, 0x0a, 0x05, 0xea, 0x65, 0xcb, 0x49, 0x5f, 0x9c, 0xce, 0xeb, 0xaf, 0xbd, 0x26, 0xca, 0x07, 0x7b, 0x22, 0x60, 0xfc, 0x78, 0x22, 0xa3, 0xa2, 0xd0, 0x94, 0x95, 0x99, 0x16, 0xc6, 0x7a, 0x4b, 0xbf, 0x1b, 0xb1, 0x38, 0x00, 0xfc, 0xfc, 0xfc, 0x88, 0x9b, 0x35, 0x8b, 0x7d, 0x25, 0x25, 0x66, 0xeb, 0x9c, 0x3b, 0x77, 0x8e, 0xb8, 0x19, 0x31, 0x78, 0x8f, 0xf0, 0xc6, 0xd5, 0xc5, 0x95, 0xfa, 0x86, 0x06, 0x94, 0x09, 0x4a, 0xbd, 0x6d, 0xe1, 0x00, 0x0d, 0xf5, 0xf5, 0x46, 0x7b, 0xf1, 0x6f, 0x64, 0xc8, 0x85, 0x5f, 0x68, 0x6e, 0x6e, 0xc6, 0x41, 0x2e, 0xc7, 0xb1, 0x9b, 0xd3, 0xc3, 0xb7, 0x0a, 0x2a, 0x75, 0x26, 0x07, 0x35, 0x1a, 0x93, 0x59, 0xc0, 0x5a, 0x85, 0x1f, 0x43, 0x7a, 0xf5, 0xd7, 0x7b, 0x7e, 0xe5, 0x0b, 0x9c, 0xfa, 0xf2, 0x4b, 0x7e, 0xf8, 0xe1, 0x07, 0xb3, 0x75, 0xba, 0xba, 0xba, 0x4c, 0xbe, 0x0a, 0x9e, 0xc9, 0xca, 0x32, 0xeb, 0x15, 0xb0, 0xf7, 0xc3, 0xff, 0xd0, 0xda, 0xda, 0x6a, 0xf6, 0xd8, 0xf6, 0x48, 0xc0, 0xf8, 0xf1, 0x44, 0x45, 0x47, 0x53, 0x56, 0x5a, 0xda, 0xa3, 0x5c, 0x5f, 0x3c, 0xfd, 0xd0, 0xcb, 0x00, 0xf0, 0x1e, 0x31, 0x82, 0xe2, 0xdd, 0xbb, 0x58, 0x9e, 0xa9, 0xa6, 0xfc, 0xb0, 0xf5, 0x4e, 0xec, 0xd6, 0xd4, 0x7c, 0xdd, 0xe3, 0x3a, 0xf9, 0xe2, 0xc5, 0x5f, 0xf8, 0xec, 0xd8, 0x71, 0xde, 0x2b, 0x2e, 0xb6, 0xda, 0x98, 0xb6, 0x44, 0xa5, 0xce, 0x44, 0x53, 0x56, 0xd6, 0x6d, 0x16, 0xb0, 0x66, 0xe1, 0xc7, 0x90, 0x5e, 0xe7, 0x4f, 0x6f, 0x6f, 0x6f, 0xf2, 0x77, 0x16, 0x70, 0xac, 0xb2, 0x92, 0x3d, 0xff, 0xfa, 0x37, 0xe5, 0x87, 0x0f, 0x53, 0xf7, 0x7d, 0x5d, 0x8f, 0x87, 0x2b, 0xe4, 0x72, 0x39, 0xc3, 0xef, 0xb8, 0x03, 0x1f, 0x1f, 0x1f, 0x46, 0x8f, 0x1e, 0x63, 0x74, 0x3d, 0x2f, 0x27, 0x97, 0xbc, 0x9c, 0xdc, 0xde, 0xba, 0x76, 0xcb, 0xe0, 0x1f, 0x10, 0x40, 0xf4, 0x8c, 0x07, 0x28, 0xfd, 0xf8, 0xe6, 0x1f, 0xc0, 0xac, 0x59, 0xf8, 0x31, 0xc4, 0xe2, 0x7f, 0x11, 0xd3, 0x13, 0x9d, 0x5a, 0x2d, 0x3f, 0x5f, 0xb8, 0x40, 0x73, 0x73, 0x33, 0xda, 0x6b, 0x6b, 0xf5, 0xa1, 0x2e, 0x2e, 0x38, 0x3b, 0x39, 0x31, 0xd4, 0xc5, 0x05, 0x4f, 0x4f, 0x4f, 0xd1, 0x9b, 0x2d, 0x07, 0x3a, 0xff, 0x3d, 0x75, 0x8a, 0xf8, 0xd9, 0x7f, 0x32, 0xca, 0x02, 0x62, 0x8f, 0x7a, 0x89, 0xa5, 0x4f, 0x66, 0x50, 0x72, 0x47, 0x47, 0x7c, 0x7d, 0x7d, 0xf1, 0xf5, 0xf5, 0xed, 0x0b, 0xf3, 0x03, 0x92, 0xfb, 0xfc, 0xfd, 0x09, 0x09, 0x0d, 0x35, 0xfa, 0x52, 0xf8, 0x48, 0x72, 0x72, 0x9f, 0xdd, 0x7c, 0xb0, 0xd3, 0x52, 0xf0, 0x60, 0xa4, 0xad, 0xad, 0x8d, 0xd3, 0xa7, 0x4f, 0xeb, 0xf5, 0x39, 0x3a, 0x3a, 0x92, 0x2c, 0xf2, 0xa8, 0x97, 0x58, 0xa4, 0x00, 0xb0, 0x13, 0x76, 0xbd, 0xf7, 0x9e, 0xd1, 0xf1, 0xb4, 0x39, 0xf1, 0xf1, 0xdc, 0xe9, 0x63, 0xdd, 0xc2, 0x8f, 0x21, 0x52, 0x00, 0xd8, 0x01, 0x82, 0x20, 0xf0, 0xf6, 0x0e, 0xe3, 0xdd, 0xcd, 0x7d, 0xb5, 0xf4, 0xbb, 0x11, 0x29, 0x00, 0xec, 0x80, 0xb2, 0x03, 0xa5, 0x9c, 0x3d, 0x7b, 0x56, 0xaf, 0x2f, 0x34, 0x2c, 0xac, 0x4f, 0x0a, 0x3f, 0x86, 0x48, 0x01, 0x60, 0x07, 0x6c, 0xdd, 0xb2, 0xc5, 0xa8, 0x2f, 0x35, 0x3d, 0xbd, 0x5f, 0xc6, 0x96, 0x02, 0xc0, 0xc6, 0x7c, 0x75, 0xe6, 0x2b, 0xa3, 0x9d, 0xc2, 0x7e, 0x7e, 0x7e, 0x44, 0x45, 0x47, 0xf5, 0xcb, 0xf8, 0x52, 0x00, 0xd8, 0x98, 0x2d, 0x9b, 0x37, 0x1b, 0xad, 0xfd, 0xfb, 0xb2, 0xf0, 0x63, 0x48, 0x9f, 0x14, 0x82, 0x24, 0xcc, 0xa3, 0xbe, 0xbe, 0x9e, 0xe9, 0x61, 0xe1, 0x7a, 0xfb, 0x24, 0xfa, 0xba, 0xf0, 0x63, 0x88, 0x94, 0x01, 0x6c, 0xc8, 0xdb, 0x3b, 0x76, 0x18, 0x6d, 0x92, 0x49, 0x4a, 0xb1, 0xee, 0x8e, 0x1f, 0x53, 0x48, 0x19, 0xc0, 0x86, 0xb4, 0xb6, 0xb6, 0xa2, 0x35, 0x38, 0xdd, 0xe4, 0xea, 0xea, 0xda, 0xaf, 0x9f, 0xb8, 0xa5, 0x00, 0x18, 0xe4, 0x38, 0x00, 0xb7, 0xd6, 0xf9, 0x2a, 0x09, 0xab, 0xe2, 0x00, 0xf4, 0xfe, 0xdf, 0x63, 0x49, 0xdc, 0xaa, 0x34, 0x3a, 0x00, 0xe2, 0x0e, 0xaa, 0x49, 0x0c, 0x24, 0xca, 0x65, 0x82, 0x20, 0x44, 0x03, 0x07, 0x90, 0xe6, 0x01, 0x83, 0x0d, 0x01, 0x88, 0x75, 0x90, 0xc9, 0x64, 0x65, 0xc0, 0x8b, 0xb6, 0xf6, 0x46, 0xa2, 0xdf, 0xf9, 0x9b, 0x4c, 0x26, 0x3b, 0xa0, 0x7b, 0xea, 0x05, 0x41, 0x98, 0x0b, 0xa8, 0x81, 0x89, 0xc0, 0x50, 0x9b, 0xb9, 0x25, 0xd1, 0x97, 0xb4, 0x03, 0x9f, 0x03, 0xeb, 0x65, 0x32, 0xd9, 0x2e, 0x80, 0xff, 0x03, 0xff, 0x08, 0x81, 0xdd, 0xa8, 0xcb, 0xf5, 0x99, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, }; ================================================ FILE: examples/device/mtp/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_MTP 1 #define CFG_TUD_MTP_EP_BUFSIZE 512 #define CFG_TUD_MTP_EP_CONTROL_BUFSIZE 16 // should be enough to hold data in MTP control request //------------- MTP device info -------------// #define CFG_TUD_MTP_DEVICEINFO_EXTENSIONS "microsoft.com: 1.0; " #define CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS \ MTP_OP_GET_DEVICE_INFO, \ MTP_OP_OPEN_SESSION, \ MTP_OP_CLOSE_SESSION, \ MTP_OP_GET_STORAGE_IDS, \ MTP_OP_GET_STORAGE_INFO, \ MTP_OP_GET_OBJECT_HANDLES, \ MTP_OP_GET_OBJECT_INFO, \ MTP_OP_GET_OBJECT, \ MTP_OP_DELETE_OBJECT, \ MTP_OP_SEND_OBJECT_INFO, \ MTP_OP_SEND_OBJECT, \ MTP_OP_RESET_DEVICE, \ MTP_OP_GET_DEVICE_PROP_DESC, \ MTP_OP_GET_DEVICE_PROP_VALUE, \ MTP_OP_SET_DEVICE_PROP_VALUE #define CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS \ MTP_EVENT_OBJECT_ADDED #define CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES \ MTP_DEV_PROP_DEVICE_FRIENDLY_NAME #define CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS \ MTP_OBJ_FORMAT_UNDEFINED, \ MTP_OBJ_FORMAT_ASSOCIATION, \ MTP_OBJ_FORMAT_TEXT, \ MTP_OBJ_FORMAT_PNG #define CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS \ MTP_OBJ_FORMAT_UNDEFINED, \ MTP_OBJ_FORMAT_ASSOCIATION, \ MTP_OBJ_FORMAT_TEXT, \ MTP_OBJ_FORMAT_PNG #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/mtp/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] MTP | VENDOR | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | PID_MAP(MTP, 5)) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_UNSPECIFIED, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_MTP = 0, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_MTP_EVT 0x81 #define EPNUM_MTP_OUT 0x02 #define EPNUM_MTP_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_MTP_EVT 0x83 #define EPNUM_MTP_OUT 0x02 #define EPNUM_MTP_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MTP_EVT 0x81 #define EPNUM_MTP_OUT 0x03 #define EPNUM_MTP_IN 0x82 #else #define EPNUM_MTP_EVT 0x81 #define EPNUM_MTP_OUT 0x02 #define EPNUM_MTP_IN 0x82 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MTP_DESC_LEN) // full speed configuration const uint8_t desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size TUD_MTP_DESCRIPTOR(ITF_NUM_MTP, 4, EPNUM_MTP_EVT, 64, 1, EPNUM_MTP_OUT, EPNUM_MTP_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size TUD_MTP_DESCRIPTOR(ITF_NUM_MTP, 4, EPNUM_MTP_EVT, 64, 1, EPNUM_MTP_OUT, EPNUM_MTP_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete const uint8_t*tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_MTP, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUsb", // 1: Manufacturer "TinyUsb Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB MTP", // 4: MTP Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) { chr_count = max_count; } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/net_lwip_webserver/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_LIST_DIR}/../../../hw/bsp/family_support.cmake) # Prefer the tinyusb lwip set(LWIP ${TOP}/lib/lwip) # If we can't find one from tinyusb then check cmake var before giving up if (NOT EXISTS ${LWIP}/src) set(LWIP ${TINYUSB_LWIP_PATH}) endif() if (NOT EXISTS ${LWIP}/src) family_example_missing_dependency(${PROJECT_NAME} "lib/lwip") return() endif() project(net_lwip_webserver C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/main.c ${CMAKE_CURRENT_LIST_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src ${LWIP}/src/include ${LWIP}/src/include/ipv4 ${LWIP}/src/include/lwip/apps ${TOP}/lib/networking ) # lib/networking sources target_sources(${PROJECT_NAME} PUBLIC ${TOP}/lib/networking/dhserver.c ${TOP}/lib/networking/dnserver.c ${TOP}/lib/networking/rndis_reports.c ) # lwip sources target_sources(${PROJECT_NAME} PUBLIC ${LWIP}/src/core/altcp.c ${LWIP}/src/core/altcp_alloc.c ${LWIP}/src/core/altcp_tcp.c ${LWIP}/src/core/def.c ${LWIP}/src/core/dns.c ${LWIP}/src/core/inet_chksum.c ${LWIP}/src/core/init.c ${LWIP}/src/core/ip.c ${LWIP}/src/core/mem.c ${LWIP}/src/core/memp.c ${LWIP}/src/core/netif.c ${LWIP}/src/core/pbuf.c ${LWIP}/src/core/raw.c ${LWIP}/src/core/stats.c ${LWIP}/src/core/sys.c ${LWIP}/src/core/tcp.c ${LWIP}/src/core/tcp_in.c ${LWIP}/src/core/tcp_out.c ${LWIP}/src/core/timeouts.c ${LWIP}/src/core/udp.c ${LWIP}/src/core/ipv4/autoip.c ${LWIP}/src/core/ipv4/dhcp.c ${LWIP}/src/core/ipv4/etharp.c ${LWIP}/src/core/ipv4/icmp.c ${LWIP}/src/core/ipv4/igmp.c ${LWIP}/src/core/ipv4/ip4.c ${LWIP}/src/core/ipv4/ip4_addr.c ${LWIP}/src/core/ipv4/ip4_frag.c ${LWIP}/src/netif/ethernet.c ${LWIP}/src/netif/slipif.c ${LWIP}/src/apps/http/httpd.c ${LWIP}/src/apps/http/fs.c ${LWIP}/src/apps/lwiperf/lwiperf.c ) # due to warnings from other net source, we need to prevent error from some of the warnings options if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${PROJECT_NAME} PUBLIC -Wno-error=null-dereference -Wno-error=conversion -Wno-error=sign-conversion -Wno-error=sign-compare ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") endif () # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/net_lwip_webserver/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/net_lwip_webserver/Makefile ================================================ include ../../../hw/bsp/family_support.mk # suppress warning caused by lwip CFLAGS_GCC += \ -Wno-error=null-dereference \ -Wno-error=unused-parameter \ -Wno-error=unused-variable INC += \ src \ $(TOP)/lib/lwip/src/include \ $(TOP)/lib/lwip/src/include/ipv4 \ $(TOP)/lib/lwip/src/include/lwip/apps \ $(TOP)/lib/networking # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) # lwip sources SRC_C += \ lib/lwip/src/core/altcp.c \ lib/lwip/src/core/altcp_alloc.c \ lib/lwip/src/core/altcp_tcp.c \ lib/lwip/src/core/def.c \ lib/lwip/src/core/dns.c \ lib/lwip/src/core/inet_chksum.c \ lib/lwip/src/core/init.c \ lib/lwip/src/core/ip.c \ lib/lwip/src/core/mem.c \ lib/lwip/src/core/memp.c \ lib/lwip/src/core/netif.c \ lib/lwip/src/core/pbuf.c \ lib/lwip/src/core/raw.c \ lib/lwip/src/core/stats.c \ lib/lwip/src/core/sys.c \ lib/lwip/src/core/tcp.c \ lib/lwip/src/core/tcp_in.c \ lib/lwip/src/core/tcp_out.c \ lib/lwip/src/core/timeouts.c \ lib/lwip/src/core/udp.c \ lib/lwip/src/core/ipv4/autoip.c \ lib/lwip/src/core/ipv4/dhcp.c \ lib/lwip/src/core/ipv4/etharp.c \ lib/lwip/src/core/ipv4/icmp.c \ lib/lwip/src/core/ipv4/igmp.c \ lib/lwip/src/core/ipv4/ip4.c \ lib/lwip/src/core/ipv4/ip4_addr.c \ lib/lwip/src/core/ipv4/ip4_frag.c \ lib/lwip/src/core/ipv6/dhcp6.c \ lib/lwip/src/core/ipv6/ethip6.c \ lib/lwip/src/core/ipv6/icmp6.c \ lib/lwip/src/core/ipv6/inet6.c \ lib/lwip/src/core/ipv6/ip6.c \ lib/lwip/src/core/ipv6/ip6_addr.c \ lib/lwip/src/core/ipv6/ip6_frag.c \ lib/lwip/src/core/ipv6/mld6.c \ lib/lwip/src/core/ipv6/nd6.c \ lib/lwip/src/netif/ethernet.c \ lib/lwip/src/netif/slipif.c \ lib/lwip/src/apps/http/httpd.c \ lib/lwip/src/apps/http/fs.c \ lib/lwip/src/apps/lwiperf/lwiperf.c \ lib/networking/dhserver.c \ lib/networking/dnserver.c \ lib/networking/rndis_reports.c include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/net_lwip_webserver/skip.txt ================================================ mcu:CH32V103 mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX mcu:LPC15XX mcu:MCXA15 mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:STM32L0 mcu:STM32F0 mcu:KINETIS_KL mcu:STM32H7RS mcu:STM32N6 family:broadcom_64bit family:broadcom_32bit family:espressif board:at_start_f425 board:curiosity_nano board:frdm_kl25z # lpc55 has weird error 'ncm_interface' causes a section type conflict with 'ntb_parameters' family:lpc55 family:nuc126 family:nuc100_120 ================================================ FILE: examples/device/net_lwip_webserver/src/arch/bpstruct.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels * */ #if defined(__ICCARM__) #pragma pack(1) #endif ================================================ FILE: examples/device/net_lwip_webserver/src/arch/cc.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels * */ #ifndef CC_H__ #define CC_H__ //#include "cpu.h" typedef int sys_prot_t; /* define compiler specific symbols */ #if defined (__ICCARM__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_USE_INCLUDES #elif defined (__CC_ARM) #define PACK_STRUCT_BEGIN __packed #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #elif defined (__GNUC__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #elif defined (__TASKING__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #endif #define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) #endif /* CC_H__ */ ================================================ FILE: examples/device/net_lwip_webserver/src/arch/epstruct.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels * */ #if defined(__ICCARM__) #pragma pack() #endif ================================================ FILE: examples/device/net_lwip_webserver/src/lwipopts.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Simon Goldschmidt * */ #ifndef LWIPOPTS_H__ #define LWIPOPTS_H__ /* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ #define NO_SYS 1 #define MEM_ALIGNMENT 4 #define LWIP_RAW 0 #define LWIP_NETCONN 0 #define LWIP_SOCKET 0 #define LWIP_DHCP 0 #define LWIP_ICMP 1 #define LWIP_UDP 1 #define LWIP_TCP 1 #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 TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) #define TCP_SND_BUF (4 * TCP_MSS) #define TCP_WND (4 * TCP_MSS) #define ETHARP_SUPPORT_STATIC_ENTRIES 1 #define LWIP_HTTPD_CGI 0 #define LWIP_HTTPD_SSI 0 #define LWIP_HTTPD_SSI_INCLUDE_TAG 0 #define LWIP_SINGLE_NETIF 1 #define LWIP_NETIF_LINK_CALLBACK 1 #define PBUF_POOL_SIZE 4 #define HTTPD_USE_CUSTOM_FSDATA 0 #define LWIP_MULTICAST_PING 1 #define LWIP_BROADCAST_PING 1 #define LWIP_IPV6_MLD 0 #define LWIP_IPV6_SEND_ROUTER_SOLICIT 0 #endif /* __LWIPOPTS_H__ */ ================================================ FILE: examples/device/net_lwip_webserver/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Peter Lawrence * * influenced by lrndis https://github.com/fetisov/lrndis * * 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. * */ /* this appears as either a RNDIS or CDC-ECM USB virtual network adapter; the OS picks its preference RNDIS should be valid on Linux and Windows hosts, and CDC-ECM should be valid on Linux and macOS hosts The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server. Link State Control: - Press the user button to toggle the network link state (UP/DOWN) - This simulates "ethernet cable unplugged/plugged" events - The host OS will see the network interface as disconnected/connected accordingly - Use this to test network error handling and recovery in host applications */ /* Some smartphones *may* work with this implementation as well, but likely have limited (broken) drivers, and likely their manufacturer has not tested such functionality. Some code workarounds could be tried: The smartphone may only have an ECM driver, but refuse to automatically pick ECM (unlike the OSes above); try modifying ./examples/devices/net_lwip_webserver/usb_descriptors.c so that CONFIG_ID_ECM is default. The smartphone may be artificially picky about which Ethernet MAC address to recognize; if this happens, try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 (clearing bit 1). */ #include "bsp/board_api.h" #include "tusb.h" #include "dhserver.h" #include "dnserver.h" #include "httpd.h" #include "lwip/ethip6.h" #include "lwip/init.h" #include "lwip/timeouts.h" #include "lwip/sys.h" #ifdef INCLUDE_IPERF #include "lwip/apps/lwiperf.h" #endif #define INIT_IP4(a, b, c, d) \ { PP_HTONL(LWIP_MAKEU32(a, b, c, d)) } /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; /* lwip context */ static struct netif netif_data; /* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ /* ideally speaking, this should be generated from the hardware's unique ID (if available) */ /* it is suggested that the first byte is 0x02 to indicate a link-local address */ uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00}; /* network parameters of this MCU */ static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1); static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0); static const ip4_addr_t gateway = INIT_IP4(0, 0, 0, 0); /* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ static dhcp_entry_t entries[] = { /* mac ip address lease time */ {{0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60}, {{0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60}, {{0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60}, }; static const dhcp_config_t dhcp_config = { .router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */ .port = 67, /* listen port */ .dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */ "usb", /* dns suffix */ TU_ARRAY_SIZE(entries), /* num entry */ entries /* entries */ }; static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { (void) netif; for (;;) { /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ if (!tud_ready()) return ERR_USE; /* if the network driver can accept another packet, we make it happen */ if (tud_network_can_xmit(p->tot_len)) { tud_network_xmit(p, 0 /* unused for this example */); return ERR_OK; } /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ tud_task(); } } static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) { return etharp_output(netif, p, addr); } #if LWIP_IPV6 static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) { return ethip6_output(netif, p, addr); } #endif static err_t netif_init_cb(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); netif->mtu = CFG_TUD_NET_MTU; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; netif->state = NULL; netif->name[0] = 'E'; netif->name[1] = 'X'; netif->linkoutput = linkoutput_fn; netif->output = ip4_output_fn; #if LWIP_IPV6 netif->output_ip6 = ip6_output_fn; #endif return ERR_OK; } /* notifies the USB host about the link state change. */ static void usbnet_netif_link_callback(struct netif *netif) { bool link_up = netif_is_link_up(netif); tud_network_link_state(BOARD_TUD_RHPORT, link_up); } static void init_lwip(void) { struct netif *netif = &netif_data; lwip_init(); /* the lwip virtual MAC address must be different from the host's; to ensure this, we toggle the LSbit */ netif->hwaddr_len = sizeof(tud_network_mac_address); memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); netif->hwaddr[5] ^= 0x01; netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ethernet_input); #if LWIP_IPV6 netif_create_ip6_linklocal_address(netif, 1); #endif netif_set_default(netif); #if LWIP_NETIF_LINK_CALLBACK // Set the link callback to notify USB host about link state changes netif_set_link_callback(netif, usbnet_netif_link_callback); netif_set_link_up(netif); #else tud_network_link_state(BOARD_TUD_RHPORT, true); #endif } /* handle any DNS requests from dns-server */ static bool dns_query_proc(const char *name, ip4_addr_t *addr) { if (0 == strcmp(name, "tiny.usb")) { *addr = ipaddr; return true; } return false; } bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { struct netif *netif = &netif_data; if (size) { struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); if (p == NULL) { printf("ERROR: Failed to allocate pbuf of size %d\n", size); return false; } /* Copy buf to pbuf */ pbuf_take(p, src, size); // Surrender ownership of our pbuf unless there was an error // Only call pbuf_free if not Ok else it will panic with "pbuf_free: p->ref > 0" // or steal it from whatever took ownership of it with undefined consequences. // See: https://savannah.nongnu.org/patch/index.php?10121 if (netif->input(p, netif) != ERR_OK) { printf("ERROR: netif input failed\n"); pbuf_free(p); } // Signal tinyusb that the current frame has been processed. tud_network_recv_renew(); } return true; } uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { struct pbuf *p = (struct pbuf *) ref; (void) arg; /* unused for this example */ return pbuf_copy_partial(p, dst, p->tot_len, 0); } static void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } static void handle_link_state_switch(void) { /* Check for button press to toggle link state */ static bool last_link_state = true; static bool last_button_state = false; bool current_button_state = board_button_read(); if (current_button_state && !last_button_state) { /* Button pressed - toggle link state */ last_link_state = !last_link_state; if (last_link_state) { printf("Link state: UP\n"); netif_set_link_up(&netif_data); } else { printf("Link state: DOWN\n"); netif_set_link_down(&netif_data); } /* LWIP callback will notify USB host about the change */ } last_button_state = current_button_state; } int main(void) { /* initialize TinyUSB */ board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); /* initialize lwip, dhcp-server, dns-server, and http */ init_lwip(); while (!netif_is_up(&netif_data)); while (dhserv_init(&dhcp_config) != ERR_OK); while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK); httpd_init(); #ifdef INCLUDE_IPERF // test with: iperf -c 192.168.7.1 -e -i 1 -M 5000 -l 8192 -r lwiperf_start_tcp_server_default(NULL, NULL); #endif #if CFG_TUD_NCM printf("USB NCM network interface initialized\n"); #elif CFG_TUD_ECM_RNDIS printf("USB RNDIS/ECM network interface initialized\n"); #endif while (1) { tud_task(); sys_check_timeouts(); // service lwip handle_link_state_switch(); led_blinking_task(); } } // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } /* lwip has provision for using a mutex, when applicable */ /* This implementation is for single-threaded use only */ sys_prot_t sys_arch_protect(void) { return 0; } void sys_arch_unprotect(sys_prot_t pval) { (void) pval; } /* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ uint32_t sys_now(void) { return tusb_time_millis_api(); } ================================================ FILE: examples/device/net_lwip_webserver/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif #include "lwipopts.h" //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) #endif // Use different configurations to test all net devices (also due to resource limitations) #ifndef USE_ECM #if TU_CHECK_MCU(OPT_MCU_LPC15XX, OPT_MCU_LPC40XX, OPT_MCU_LPC51UXX, OPT_MCU_LPC54) #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAML2X) #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) #define USE_ECM 1 #else #define USE_ECM 0 #define INCLUDE_IPERF #endif #endif //-------------------------------------------------------------------- // NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING //-------------------------------------------------------------------- // Must be >> MTU // Can be set to 2048 without impact #define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) // Must be >> MTU // Can be set to smaller values if wNtbOutMaxDatagrams==1 #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) // Number of NCM transfer blocks for reception side #ifndef CFG_TUD_NCM_OUT_NTB_N #define CFG_TUD_NCM_OUT_NTB_N 1 #endif // Number of NCM transfer blocks for transmission side #ifndef CFG_TUD_NCM_IN_NTB_N #define CFG_TUD_NCM_IN_NTB_N 1 #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled #define CFG_TUD_ECM_RNDIS USE_ECM #define CFG_TUD_NCM (1 - CFG_TUD_ECM_RNDIS) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/net_lwip_webserver/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "class/net/net_device.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] NET | VENDOR | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID \ (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | \ PID_MAP(ECM_RNDIS, 5) | PID_MAP(NCM, 5)) // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_INTERFACE, STRID_MAC, STRID_COUNT }; enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; enum { #if CFG_TUD_ECM_RNDIS CONFIG_ID_RNDIS = 0, CONFIG_ID_ECM = 1, #else CONFIG_ID_NCM = 0, #endif CONFIG_ID_COUNT }; //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static const tusb_desc_device_t desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, #if CFG_TUD_NCM .bcdUSB = 0x0201, #else .bcdUSB = 0x0200, #endif // Use Interface Association Descriptor (IAD) device class .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0101, .iManufacturer = STRID_MANUFACTURER, .iProduct = STRID_PRODUCT, .iSerialNumber = STRID_SERIAL, .bNumConfigurations = CONFIG_ID_COUNT // multiple configurations }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor const uint8_t *tud_descriptor_device_cb(void) { return (const uint8_t *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #define MAIN_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) #define ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) #define NCM_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_NCM_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_NET_NOTIF 0x83 #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x83 #else #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x82 #endif #if CFG_TUD_ECM_RNDIS static uint8_t const rndis_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(CONFIG_ID_RNDIS + 1, ITF_NUM_TOTAL, 0, MAIN_CONFIG_TOTAL_LEN, 0, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_RNDIS_DESCRIPTOR( ITF_NUM_CDC, STRID_INTERFACE, EPNUM_NET_NOTIF, 8, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE), }; static const uint8_t ecm_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(CONFIG_ID_ECM + 1, ITF_NUM_TOTAL, 0, ALT_CONFIG_TOTAL_LEN, 0, 100), // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. TUD_CDC_ECM_DESCRIPTOR( ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), }; #else static uint8_t const ncm_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(CONFIG_ID_NCM + 1, ITF_NUM_TOTAL, 0, NCM_CONFIG_TOTAL_LEN, 0, 100), // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. TUD_CDC_NCM_DESCRIPTOR( ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), }; #endif // Configuration array: RNDIS and CDC-ECM // - Windows only works with RNDIS // - MacOS only works with CDC-ECM // - Linux will work on both static const uint8_t *const configuration_arr[CONFIG_ID_COUNT] = { #if CFG_TUD_ECM_RNDIS [CONFIG_ID_RNDIS] = rndis_configuration, [CONFIG_ID_ECM] = ecm_configuration #else [CONFIG_ID_NCM] = ncm_configuration #endif }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { return (index < CONFIG_ID_COUNT) ? configuration_arr[index] : NULL; } #if CFG_TUD_NCM //--------------------------------------------------------------------+ // BOS Descriptor //--------------------------------------------------------------------+ /* Used to automatically load the NCM driver on Windows 10, otherwise manual driver install is needed. Associate NCM interface with WINNCM driver. */ /* Microsoft OS 2.0 registry property descriptor Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx device should create DeviceInterfaceGUIDs. It can be done by driver and in case of real PnP solution device should expose MS "Microsoft OS 2.0 registry property descriptor". Such descriptor can insert any record into Windows registry per device/configuration/interface. In our case it will insert "DeviceInterfaceGUIDs" multistring property. GUID is freshly generated and should be OK to use. https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) #define MS_OS_20_DESC_LEN 0xB2 // BOS Descriptor is required for webUSB const uint8_t desc_bos[] = { // total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), // Microsoft OS 2.0 descriptor TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)}; const uint8_t *tud_descriptor_bos_cb(void) { return desc_bos; } const uint8_t desc_ms_os_20[] = { // Set header: length, type, windows version, total length U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), // Configuration subset header: length, type, configuration index, reserved, configuration total length U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A), // Function Subset header: length, type, first interface, reserved, subset length U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_CDC, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08), // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'N', 'C', 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible // MS OS 2.0 Registry property descriptor: length, type U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08 - 0x08 - 0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, U16_TO_U8S_LE(0x0050), // wPropertyDataLength //bPropertyData: {12345678-0D08-43FD-8B3E-127CA8AFFF9D} '{', 0x00, '1', 0x00, '2', 0x00, '3', 0x00, '4', 0x00, '5', 0x00, '6', 0x00, '7', 0x00, '8', 0x00, '-', 0x00, '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, '8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00}; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { // nothing to with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) { return true; } switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: switch (request->bRequest) { case 1: if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor uint16_t total_len; memcpy(&total_len, desc_ms_os_20 + 8, 2); return tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_ms_os_20, total_len); } else { return false; } default: break; // nothing to do } break; default: break; // nothing to do } // stall unknown request return false; } #endif //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // array of pointer to string descriptors static const char *string_desc_arr[STRID_COUNT] = { [STRID_LANGID] = (const char[]){0x09, 0x04}, // supported language is English (0x0409) [STRID_MANUFACTURER] = "TinyUSB", // Manufacturer [STRID_PRODUCT] = "TinyUSB Device", // Product [STRID_SERIAL] = NULL, // Serials will use unique ID if possible [STRID_INTERFACE] = "TinyUSB Network Interface", // Interface Description [STRID_MAC] = NULL // STRID_MAC index is handled separately }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; unsigned int chr_count = 0; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; case STRID_MAC: // Convert MAC address into UTF-16 for (unsigned i = 0; i < sizeof(tud_network_mac_address); i++) { _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 4) & 0xf]; _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; } break; default: { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/printer_to_cdc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(printer_to_cdc C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/printer_to_cdc/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/printer_to_cdc/README.md ================================================ #### Printer to CDC This example demonstrates a USB composite device with a Printer class interface and a CDC serial interface. Data flows bidirectionally between the two: - Data sent to the Printer (from host) is forwarded to the CDC serial port - Data sent to the CDC serial port (from host) is forwarded to the Printer IN endpoint This is useful for debugging printer class communication or as a reference for implementing printer class devices. #### USB Interfaces | Interface | Class | Description | |-----------|-------|-------------| | 0 | CDC ACM | Virtual serial port | | 2 | Printer | USB Printer (bidirectional, protocol 2) | #### How to Test The device exposes two endpoints on the host: - `/dev/ttyACM0` (CDC serial port) - `/dev/usb/lp0` (USB printer) Note: the actual device numbers may vary depending on your system. **Prerequisites (Linux):** ```bash # Load the USB printer kernel module if not already loaded sudo modprobe usblp # Check devices exist ls /dev/ttyACM* /dev/usb/lp* ``` **Test Printer to CDC (host writes to printer, reads from CDC):** ```bash # Terminal 1: read from CDC cat /dev/ttyACM0 # Terminal 2: write to printer echo "hello from printer" > /dev/usb/lp0 # "hello from printer" appears in Terminal 1 ``` **Test CDC to Printer (host writes to CDC, reads from printer):** ```bash # Terminal 1: read from printer IN endpoint cat /dev/usb/lp0 # Terminal 2: write to CDC echo "hello from cdc" > /dev/ttyACM0 # "hello from cdc" appears in Terminal 1 ``` **Interactive bidirectional test:** ```bash # Terminal 1: open CDC serial port minicom -D /dev/ttyACM0 # Terminal 2: send to printer echo "tinyusb print example" > /dev/usb/lp0 # Text appears in minicom. Type in minicom to send data back through printer TX. ``` #### IEEE 1284 Device ID The device responds to GET_DEVICE_ID requests with: ``` MFG:TinyUSB;MDL:Printer to CDC;CMD:PS;CLS:PRINTER; ``` Verify with: ```bash cat /sys/class/usbmisc/lp0/device/ieee1284_id ``` ================================================ FILE: examples/device/printer_to_cdc/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. * */ /* This example demonstrates a USB Printer + CDC composite device. * Data received on the Printer interface is forwarded to the CDC serial port, * and data received on the CDC serial port is forwarded back to the Printer interface. * * To test: * 1. Flash the device * 2. Open a serial terminal on the CDC port (e.g. /dev/ttyACM0) * 3. Send data to the printer: echo "hello" > /dev/usb/lp0 * 4. The data appears on the CDC serial terminal * 5. Type in the serial terminal to send data back through the printer TX */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" // -------------------------------------------------------------------+ // Tasks // -------------------------------------------------------------------+ // Forward data from Printer RX to CDC TX static void printer_to_cdc_task(void) { uint32_t avail = tud_printer_read_available(); if (avail == 0 || !tud_cdc_write_available()) { return; } uint8_t buf[64]; uint32_t count = tud_printer_read(buf, TU_MIN(sizeof(buf), tud_cdc_write_available())); if (count > 0) { tud_cdc_write(buf, count); tud_cdc_write_flush(); } } // Forward data from CDC RX to Printer TX static void cdc_to_printer_task(void) { uint32_t avail = tud_printer_write_available(); if (tud_cdc_available() == 0 || avail == 0) { return; } uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, TU_MIN(sizeof(buf), avail)); if (count > 0) { tud_printer_write(buf, count); tud_printer_write_flush(); } } int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task printer_to_cdc_task(); // forward printer data to CDC cdc_to_printer_task(); // forward CDC data to printer } } //--------------------------------------------------------------------+ // Printer callbacks //--------------------------------------------------------------------+ void tud_printer_rx_cb(uint8_t itf) { (void)itf; } // IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). // The rest is the Device ID string using standard abbreviated keys. static const char printer_device_id[] = "\x00\x34" // total length = 52 = 0x0034 (big-endian) "MFG:TinyUSB;" "MDL:Printer to CDC;" "CMD:PS;" "CLS:PRINTER;"; TU_VERIFY_STATIC(sizeof(printer_device_id) - 1 == 52, "device ID length mismatch"); uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { (void)itf; return (uint8_t const *)printer_device_id; } ================================================ FILE: examples/device/printer_to_cdc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. * */ #ifndef _TUSB_CONFIG_H_ #define _TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_HID 0 #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #define CFG_TUD_PRINTER 1 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Printer buffer sizes #define CFG_TUD_PRINTER_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_PRINTER_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_PRINTER_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_PRINTER_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* _TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/printer_to_cdc/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" #define USB_VID 0xCafe #define USB_PID 0x4005 #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ // Endpoint numbers #if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #define EPNUM_PRINTER_OUT 0x04 #define EPNUM_PRINTER_IN 0x85 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_PRINTER_OUT 0x03 #define EPNUM_PRINTER_IN 0x83 #endif // full speed configuration static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), // Interface number, string index, EP Bulk Out address, EP Bulk In address, EP size TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 64), }; #if TUD_OPT_HIGH_SPEED // high speed configuration static uint8_t const desc_hs_configuration[] = { TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER, 5, EPNUM_PRINTER_OUT, EPNUM_PRINTER_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // if link speed is high return fullspeed config, and vice versa memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // TUD_OPT_HIGH_SPEED uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void) index; #if TUD_OPT_HIGH_SPEED return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_CDC, STRID_PRINTER, }; static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serial, use unique ID if possible "TinyUSB CDC", // 4: CDC Interface "TinyUSB Printer", // 5: Printer Interface }; static uint16_t _desc_str[32 + 1]; uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; if (chr_count > max_count) { chr_count = max_count; } for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/printer_to_cdc/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { ITF_NUM_CDC, ITF_NUM_CDC_DATA, ITF_NUM_PRINTER, ITF_NUM_TOTAL, }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_PRINTER_DESC_LEN) #endif /* USB_DESCRIPTORS_H_ */ ================================================ FILE: examples/device/uac2_headset/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(uac2_headset C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/uac2_headset/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/uac2_headset/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/uac2_headset/skip.txt ================================================ mcu:LPC11UXX mcu:LPC13XX mcu:NUC121 mcu:SAMD11 mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif ================================================ FILE: examples/device/uac2_headset/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * * 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 #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ // List of supported sample rates const uint32_t sample_rates[] = {44100, 48000}; uint32_t current_sample_rate = 44100; #define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates) /* Blink pattern * - 25 ms : streaming data * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_STREAMING = 25, BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; enum { VOLUME_CTRL_0_DB = 0, VOLUME_CTRL_10_DB = 2560, VOLUME_CTRL_20_DB = 5120, VOLUME_CTRL_30_DB = 7680, VOLUME_CTRL_40_DB = 10240, VOLUME_CTRL_50_DB = 12800, VOLUME_CTRL_60_DB = 15360, VOLUME_CTRL_70_DB = 17920, VOLUME_CTRL_80_DB = 20480, VOLUME_CTRL_90_DB = 23040, VOLUME_CTRL_100_DB = 25600, VOLUME_CTRL_SILENCE = 0x8000, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0 // Buffer for microphone data int32_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 4]; // Buffer for speaker data int32_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 4]; // Speaker data size received in the last frame int spk_data_size; // Resolution per format const uint8_t resolutions_per_format[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = {CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX}; // Current resolution, update on format change uint8_t current_resolution; void led_blinking_task(void); void audio_task(void); void audio_control_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); TU_LOG1("Headset running\r\n"); while (1) { tud_task();// TinyUSB device task audio_task(); audio_control_task(); led_blinking_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // Audio Callback Functions //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // UAC1 Helper Functions //--------------------------------------------------------------------+ static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { // Request uses 3 bytes TU_VERIFY(p_request->wLength == 3); current_sample_rate = tu_unaligned_read32(pBuff) & 0x00FFFFFF; TU_LOG2("EP set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { TU_LOG2("EP get current freq\r\n"); uint8_t freq[3]; freq[0] = (uint8_t) (current_sample_rate & 0xFF); freq[1] = (uint8_t) ((current_sample_rate >> 8) & 0xFF); freq[2] = (uint8_t) ((current_sample_rate >> 16) & 0xFF); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our speaker feature unit if (entityID == UAC1_ENTITY_SPK_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength == 1); mute[channelNum] = pBuff[0]; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; default: return false; // not supported } case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength == 2); volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; default: return false; // not supported } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our speaker feature unit if (entityID == UAC1_ENTITY_SPK_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_GET_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); { int16_t vol = (int16_t) volume[channelNum]; vol = vol * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); } case AUDIO10_CS_REQ_GET_MIN: TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); { int16_t min = -90; // -90 dB min = min * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); } case AUDIO10_CS_REQ_GET_MAX: TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); { int16_t max = 30; // +30 dB max = max * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); } case AUDIO10_CS_REQ_GET_RES: TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); { int16_t res = 1; // 1 dB res = res * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } //--------------------------------------------------------------------+ // UAC2 Helper Functions //--------------------------------------------------------------------+ #if TUD_OPT_HIGH_SPEED // Helper for clock get requests static bool audio20_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio20_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)}; TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); for (uint8_t i = 0; i < N_SAMPLE_RATES; i++) { rangef.subrange[i].bMin = (int32_t) sample_rates[i]; rangef.subrange[i].bMax = (int32_t) sample_rates[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes); } return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef)); } } else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t cur_valid = {.bCur = 1}; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid)); } TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } // Helper for clock set requests static bool audio20_clock_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void) rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *) buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } else { TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } // Helper for feature unit get requests static bool audio20_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1)); } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}}; TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol)); } else if (request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol)); } } TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } // Helper for feature unit set requests static bool audio20_feature_unit_set_request(uint8_t rhport, audio20_control_request_t const *request, uint8_t const *buf) { (void) rhport; TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *) buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *) buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); return true; } else { TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) return audio20_clock_get_request(rhport, request); if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) return audio20_feature_unit_get_request(rhport, request); else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); } return false; } static bool audio20_set_req_entity(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) return audio20_feature_unit_set_request(rhport, request, buf); if (request->bEntityID == UAC2_ENTITY_CLOCK) return audio20_clock_set_request(rhport, request, buf); TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } #endif // TUD_OPT_HIGH_SPEED // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; if (tud_audio_version() == 1) { return audio10_set_req_ep(p_request, pBuff); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_ep(rhport, p_request); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_entity(rhport, p_request); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_get_req_entity(rhport, p_request); #endif } return false; } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { (void) rhport; if (tud_audio_version() == 1) { return audio10_set_req_entity(p_request, buf); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_set_req_entity(rhport, p_request, buf); #endif } return false; } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt == 0) { blink_interval_ms = BLINK_MOUNTED; } return true; } bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); TU_LOG2("Set interface %d alt %d\r\n", itf, alt); if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0) { blink_interval_ms = BLINK_STREAMING; } // Clear buffer when streaming format is changed spk_data_size = 0; if (alt != 0) { current_resolution = resolutions_per_format[alt - 1]; } return true; } //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio transfer callback, one frame is sent/received every 1ms. // In a real application, this would be replaced with actual I2S send/receive callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; // When new data arrived, copy data from speaker buffer, to microphone buffer // and send it over // Only support speaker & headphone both have the same resolution // If one is 16bit another is 24bit be care of LOUD noise ! spk_data_size = tud_audio_read(spk_buf, sizeof(spk_buf)); if (spk_data_size) { if (current_resolution == 16) { int16_t *src = (int16_t *) spk_buf; int16_t *limit = (int16_t *) spk_buf + spk_data_size / 2; int16_t *dst = (int16_t *) mic_buf; while (src < limit) { // Combine two channels into one int32_t left = *src++; int32_t right = *src++; *dst++ = (int16_t) ((left >> 1) + (right >> 1)); } tud_audio_write((uint8_t *) mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } else if (current_resolution == 24) { int32_t *src = spk_buf; int32_t *limit = spk_buf + spk_data_size / 4; int32_t *dst = mic_buf; while (src < limit) { // Combine two channels into one int32_t left = *src++; int32_t right = *src++; *dst++ = (int32_t) ((uint32_t) ((left >> 1) + (right >> 1)) & 0xffffff00ul); } tud_audio_write((uint8_t *) mic_buf, (uint16_t) (spk_data_size / 2)); spk_data_size = 0; } } } void audio_control_task(void) { // Press on-board button to control volume // Open host volume control, volume should switch between 10% and 100% // Poll every 50ms const uint32_t interval_ms = 50; static uint32_t start_ms = 0; static uint32_t btn_prev = 0; if (tusb_time_millis_api() - start_ms < interval_ms) return;// not enough time start_ms += interval_ms; uint32_t btn = board_button_read(); // Even UAC1 spec have status interrupt support like UAC2, most host do not support it // So you have to either use UAC2 or use old day HID volume control TU_VERIFY((tud_audio_version() == 1),); if (!btn_prev && btn) { // Adjust volume between 0dB (100%) and -30dB (10%) for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) { volume[i] = volume[i] == 0 ? -VOLUME_CTRL_30_DB : 0; } // 6.1 Interrupt Data Message const audio_interrupt_data_t data = {.v2 = { .bInfo = 0, // Class-specific interrupt, originated from an interface .bAttribute = AUDIO20_CS_REQ_CUR, // Caused by current settings .wValue_cn_or_mcn = 0, // CH0: master volume .wValue_cs = AUDIO20_FU_CTRL_VOLUME, // Volume change .wIndex_ep_or_int = 0, // From the interface itself .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT,// From feature unit }}; tud_audio_int_write(&data); } btn_prev = btn; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; } ================================================ FILE: examples/device/uac2_headset/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jerzy Kasenberg * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif #include "usb_descriptors.h" //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_AUDIO 1 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- // Allow volume controlled by on-baord button #define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 1 // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 // Audio format type I specifications /* 24bit/48kHz is the best quality for headset or 24bit/96kHz for 2ch speaker, high-speed is needed beyond this */ #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 // 16bit in 16bit slots #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX 16 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX 2 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16 // 24bit in 32bit slots (UAC2 only) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX 24 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX 4 #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX 24 // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 // UAC1 (Full-Speed) Endpoint size calculation #define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(false, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // UAC2 (High-Speed) Endpoint size calculation #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // Maximum EP IN size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) // Tx flow control needs buffer size >= 4* EP size to work correctly // Example write FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_IN, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_IN)) // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 // UAC1 (Full-Speed) Endpoint size calculation #define CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(false, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) // UAC2 (High-Speed) Endpoint size calculation #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) #define CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) // Maximum EP OUT size for all AS alternate settings used #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, TU_MAX(CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT)) // Rx flow control needs buffer size >= 4* EP size to work correctly // Example read FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, TU_MAX(32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_1_EP_SZ_OUT, 32 * CFG_TUD_AUDIO20_FUNC_1_FORMAT_2_EP_SZ_OUT)) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/uac2_headset/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jerzy Kasenberg * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_HEADSET_STEREO_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO_IN 0x03 #define EPNUM_AUDIO_OUT 0x03 #define EPNUM_AUDIO_INT 0x01 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 #elif CFG_TUSB_MCU == OPT_MCU_NRF5X // ISO endpoints for NRF5x are fixed to 0x08 (0x88) #define EPNUM_AUDIO_IN 0x08 #define EPNUM_AUDIO_OUT 0x08 #define EPNUM_AUDIO_INT 0x01 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 #define EPNUM_AUDIO_INT 0x02 #endif #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_HEADSET_STEREO_DESC_LEN(2)) uint8_t const desc_uac1_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_TOTAL_LEN, 0x00, 100), // Interface number, string index, bytes per sample RX/TX, bits used per sample RX/TX, EP Out & EP In address, EP sizes, sample rate TUD_AUDIO10_HEADSET_STEREO_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 4, \ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX, \ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX, \ EPNUM_AUDIO_OUT, CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_OUT, \ EPNUM_AUDIO_IN | 0x80, CFG_TUD_AUDIO10_FUNC_1_FORMAT_1_EP_SZ_IN, \ 44100, 48000) }; TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); #if TUD_OPT_HIGH_SPEED #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_HEADSET_STEREO_DESC_LEN) uint8_t const desc_uac2_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_TOTAL_LEN, 0x00, 100), // String index, EP Out & EP In address, EP Interrupt address TUD_AUDIO20_HEADSET_STEREO_DESCRIPTOR(5, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80, EPNUM_AUDIO_INT | 0x80) }; TU_VERIFY_STATIC(sizeof(desc_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = 0x0200, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc_uac2_configuration; } #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if(tud_speed_get() == TUSB_SPEED_FULL) { return desc_uac1_configuration; } else { return desc_uac2_configuration; } #else return desc_uac1_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Headset", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB UAC1 Headset", // 4: Function "TinyUSB UAC2 Headset", // 5: Function }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/uac2_headset/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenbreg * * 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. * */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING_SPK, ITF_NUM_AUDIO_STREAMING_MIC, ITF_NUM_TOTAL }; //--------------------------------------------------------------------+ // UAC2 DESCRIPTOR TEMPLATES //--------------------------------------------------------------------+ // Unit numbers are arbitrary selected #define UAC2_ENTITY_CLOCK 0x04 // Speaker path #define UAC2_ENTITY_SPK_INPUT_TERMINAL 0x01 #define UAC2_ENTITY_SPK_FEATURE_UNIT 0x02 #define UAC2_ENTITY_SPK_OUTPUT_TERMINAL 0x03 // Microphone path #define UAC2_ENTITY_MIC_INPUT_TERMINAL 0x11 #define UAC2_ENTITY_MIC_OUTPUT_TERMINAL 0x13 #define TUD_AUDIO20_HEADSET_STEREO_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 1, Alternate 1 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 1, Alternate 2 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 0 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ /* Interface 2, Alternate 1 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 2 */\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO20_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin, _epint) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch1*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), /*_ctrlch2*/ (AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */\ TUD_AUDIO20_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x02, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) //--------------------------------------------------------------------+ // UAC1 DESCRIPTOR TEMPLATES //--------------------------------------------------------------------+ // UAC1 entity IDs for speaker and microphone // Speaker path #define UAC1_ENTITY_SPK_INPUT_TERMINAL 0x01 #define UAC1_ENTITY_SPK_FEATURE_UNIT 0x02 #define UAC1_ENTITY_SPK_OUTPUT_TERMINAL 0x03 // Microphone path #define UAC1_ENTITY_MIC_INPUT_TERMINAL 0x11 #define UAC1_ENTITY_MIC_OUTPUT_TERMINAL 0x13 #define TUD_AUDIO10_HEADSET_STEREO_DESC_LEN(_nfreqs) (\ +TUD_AUDIO10_DESC_STD_AC_LEN\ + TUD_AUDIO10_DESC_CS_AC_LEN(2)\ + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)\ + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 (speaker) */\ + TUD_AUDIO10_DESC_STD_AS_LEN\ /* Interface 1, Alternate 1 (speaker) */\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs)\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN\ /* Interface 2, Alternate 0 (microphone) */\ + TUD_AUDIO10_DESC_STD_AS_LEN\ /* Interface 2, Alternate 1 (microphone) */\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs)\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO10_HEADSET_STEREO_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample_RX, _nBitsUsedPerSample_RX, _nBytesPerSample_TX, _nBitsUsedPerSample_TX, _epout, _epoutsize, _epin, _epinsize, ...) \ /* Standard AC Interface Descriptor(4.3.1) */\ TUD_AUDIO10_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.3.2) */\ TUD_AUDIO10_DESC_CS_AC(/*_bcdADC*/ 0x0100, /*_totallen*/ (TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1)+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN), /*_itf*/ ((_itfnum)+1), ((_itfnum)+2)),\ /* Speaker Input Terminal Descriptor(4.3.2.1) */\ TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_nchannels*/ 0x02, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ /* Speaker Feature Unit Descriptor(4.3.2.5) */\ TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ UAC1_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlmaster*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch1*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch2*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME)),\ /* Speaker Output Terminal Descriptor(4.3.2.2) */\ TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ UAC1_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_HEADPHONES, /*_assocTerm*/ 0x00, /*_srcid*/ UAC1_ENTITY_SPK_FEATURE_UNIT, /*_stridx*/ 0x00),\ /* Microphone Input Terminal Descriptor(4.3.2.1) */\ TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ UAC1_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_nchannels*/ 0x01, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ /* Microphone Output Terminal Descriptor(4.3.2.2) */\ TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_srcid*/ UAC1_ENTITY_MIC_INPUT_TERMINAL, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.5.1) - Speaker Interface 1, Alternate 0 */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Standard AS Interface Descriptor(4.5.1) - Speaker Interface 1, Alternate 1 */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.5.2) */\ TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ UAC1_ENTITY_SPK_INPUT_TERMINAL, /*_delay*/ 0x01, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ /* Type I Format Type Descriptor(2.2.5) */\ TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x02, /*_subframesize*/ _nBytesPerSample_RX, /*_bitresolution*/ _nBitsUsedPerSample_RX, /*_freqs*/ __VA_ARGS__),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01, /*_syncep*/ 0x00),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.5.1) - Microphone Interface 2, Alternate 0 */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+2), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Standard AS Interface Descriptor(4.5.1) - Microphone Interface 2, Alternate 1 */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+2), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AS Interface Descriptor(4.5.2) */\ TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ UAC1_ENTITY_MIC_OUTPUT_TERMINAL, /*_delay*/ 0x01, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ /* Type I Format Type Descriptor(2.2.5) */\ TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x01, /*_subframesize*/ _nBytesPerSample_TX, /*_bitresolution*/ _nBitsUsedPerSample_TX, /*_freqs*/ __VA_ARGS__),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS), /*_maxEPsize*/ _epinsize, /*_interval*/ 0x01, /*_syncep*/ 0x00),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001) #endif ================================================ FILE: examples/device/uac2_speaker_fb/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(uac2_speaker_fb C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/uac2_speaker_fb/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/uac2_speaker_fb/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/uac2_speaker_fb/skip.txt ================================================ mcu:LPC11UXX mcu:LPC13XX mcu:NUC121 mcu:SAMD11 mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:broadcom_64bit ================================================ FILE: examples/device/uac2_speaker_fb/src/audio_debug.py ================================================ #!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ # Install python3 matplotlib package https://pypi.org/project/matplotlib/ from ctypes import Structure, c_uint32, c_uint8, c_int8, c_int16, c_uint16 import signal try: import hid import matplotlib.pyplot as plt import matplotlib.animation as animation except: print("Missing import, please try 'pip install hid matplotlib' or consult your OS's python package manager.") exit(1) # Example must be compiled with CFG_AUDIO_DEBUG=1 VID = 0xcafe PID = 0x4014 CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX = 2 class audio_debug_info_t (Structure): _fields_ = [("sample_rate", c_uint32), ("alt_settings", c_uint8), ("mute", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int8), ("volume", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int16), ("fifo_size", c_uint16), ("fifo_count", c_uint16), ("fifo_count_avg", c_uint16) ] dev = hid.Device(VID, PID) if dev: signal.signal(signal.SIGINT, signal.SIG_DFL) # Create figure for plotting fig = plt.figure() ax = fig.add_subplot(1, 1, 1) fifo_avg = [] fifo_cnt = [] # This function is called periodically from FuncAnimation def animate(i): info = None for i in range(30): try: str_in = dev.read(64, 50) info = audio_debug_info_t.from_buffer_copy(str_in) global fifo_avg global fifo_cnt fifo_avg.append(info.fifo_count_avg) fifo_cnt.append(info.fifo_count) except: exit(1) # Limit to 1000 items fifo_avg = fifo_avg[-1000:] fifo_cnt = fifo_cnt[-1000:] if info is not None: # Draw x and y lists ax.clear() ax.plot(fifo_cnt, label='FIFO count') ax.plot(fifo_avg, label='FIFO average') ax.legend() ax.set_ylim(bottom=0, top=info.fifo_size) # Format plot ax.set_title('FIFO information') ax.grid(True) print(f'Sample rate:{info.sample_rate} | Alt settings:{info.alt_settings} | Volume:{info.volume[:]}') ani = animation.FuncAnimation(fig, animate, interval=10, cache_frame_data=False) # type: ignore plt.show(block=True) ================================================ FILE: examples/device/uac2_speaker_fb/src/common_types.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 HiFiPhile * * 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. * */ #ifndef _COMMON_TYPES_H_ #define _COMMON_TYPES_H_ enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, #if CFG_AUDIO_DEBUG ITF_NUM_DEBUG, #endif ITF_NUM_TOTAL }; #if CFG_AUDIO_DEBUG typedef struct { uint32_t sample_rate; uint8_t alt_settings; uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; uint16_t fifo_size; uint16_t fifo_count; uint16_t fifo_count_avg; } audio_debug_info_t; #endif #endif ================================================ FILE: examples/device/uac2_speaker_fb/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * * 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 #include #include "bsp/board_api.h" #include "common_types.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 25 ms : streaming data * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_STREAMING = 25, BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; enum { VOLUME_CTRL_0_DB = 0, VOLUME_CTRL_10_DB = 2560, VOLUME_CTRL_20_DB = 5120, VOLUME_CTRL_30_DB = 7680, VOLUME_CTRL_40_DB = 10240, VOLUME_CTRL_50_DB = 12800, VOLUME_CTRL_60_DB = 15360, VOLUME_CTRL_70_DB = 17920, VOLUME_CTRL_80_DB = 20480, VOLUME_CTRL_90_DB = 23040, VOLUME_CTRL_100_DB = 25600, VOLUME_CTRL_SILENCE = 0x8000, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Audio controls // Current states uint8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0 uint32_t current_sample_rate = 44100; // Buffer for speaker data uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 2]; void led_blinking_task(void); void audio_task(void); #if CFG_AUDIO_DEBUG void audio_debug_task(void); uint8_t current_alt_settings; volatile uint16_t fifo_count; volatile uint32_t fifo_count_avg; #endif /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); TU_LOG1("Speaker running\r\n"); while (1) { tud_task();// TinyUSB device task led_blinking_task(); #if CFG_AUDIO_DEBUG audio_debug_task(); #endif audio_task(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // Application Callback API Implementations //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // UAC1 Helper Functions //--------------------------------------------------------------------+ static bool audio10_set_req_ep(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { // Request uses 3 bytes TU_VERIFY(p_request->wLength == 3); current_sample_rate = tu_unaligned_read32(pBuff) & 0x00FFFFFF; TU_LOG2("EP set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_get_req_ep(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); switch (ctrlSel) { case AUDIO10_EP_CTRL_SAMPLING_FREQ: if (p_request->bRequest == AUDIO10_CS_REQ_GET_CUR) { TU_LOG2("EP get current freq\r\n"); uint8_t freq[3]; freq[0] = (uint8_t) (current_sample_rate & 0xFF); freq[1] = (uint8_t) ((current_sample_rate >> 8) & 0xFF); freq[2] = (uint8_t) ((current_sample_rate >> 16) & 0xFF); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, freq, sizeof(freq)); } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } return false; } static bool audio10_set_req_entity(tusb_control_request_t const *p_request, uint8_t *pBuff) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our feature unit if (entityID == UAC1_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength == 1); mute[channelNum] = pBuff[0]; TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); return true; default: return false; // not supported } case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_SET_CUR: // Only 1st form is supported TU_VERIFY(p_request->wLength == 2); volume[channelNum] = (int16_t)tu_unaligned_read16(pBuff) / 256; TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); return true; default: return false; // not supported } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } static bool audio10_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t channelNum = TU_U16_LOW(p_request->wValue); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // If request is for our feature unit if (entityID == UAC1_ENTITY_FEATURE_UNIT) { switch (ctrlSel) { case AUDIO10_FU_CTRL_MUTE: // Audio control mute cur parameter block consists of only one byte - we thus can send it right away // There does not exist a range parameter block for mute TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1); case AUDIO10_FU_CTRL_VOLUME: switch (p_request->bRequest) { case AUDIO10_CS_REQ_GET_CUR: TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); { int16_t vol = (int16_t) volume[channelNum]; vol = vol * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &vol, sizeof(vol)); } case AUDIO10_CS_REQ_GET_MIN: TU_LOG2(" Get Volume min of channel: %u\r\n", channelNum); { int16_t min = -90; // -90 dB min = min * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &min, sizeof(min)); } case AUDIO10_CS_REQ_GET_MAX: TU_LOG2(" Get Volume max of channel: %u\r\n", channelNum); { int16_t max = 30; // +30 dB max = max * 256; // convert to 1/256 dB units return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &max, sizeof(max)); } case AUDIO10_CS_REQ_GET_RES: TU_LOG2(" Get Volume res of channel: %u\r\n", channelNum); { int16_t res = 128; // 0.5 dB return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &res, sizeof(res)); } // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } break; // Unknown/Unsupported control default: TU_BREAKPOINT(); return false; } } return false; } //--------------------------------------------------------------------+ // UAC2 Helper Functions //--------------------------------------------------------------------+ #if TUD_OPT_HIGH_SPEED // List of supported sample rates for UAC2 const uint32_t sample_rates[] = {44100, 48000, 88200, 96000}; #define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates) static bool audio20_clock_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { if (request->bRequest == AUDIO20_CS_REQ_CUR) { TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio20_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)}; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_4_n_t(N_SAMPLE_RATES) rangef = { .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)}; TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); for (uint8_t i = 0; i < N_SAMPLE_RATES; i++) { rangef.subrange[i].bMin = (int32_t) sample_rates[i]; rangef.subrange[i].bMax = (int32_t) sample_rates[i]; rangef.subrange[i].bRes = 0; TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes); } return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef)); } } else if (request->bControlSelector == AUDIO20_CS_CTRL_CLK_VALID && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t cur_valid = {.bCur = 1}; TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid)); } TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } static bool audio20_clock_set_request(audio20_control_request_t const *request, uint8_t const *buf) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_CS_CTRL_SAM_FREQ) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_4_t)); current_sample_rate = (uint32_t) ((audio20_control_cur_4_t const *) buf)->bCur; TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } else { TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } static bool audio20_feature_unit_get_request(uint8_t rhport, audio20_control_request_t const *request) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE && request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]}; TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1)); } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { if (request->bRequest == AUDIO20_CS_REQ_RANGE) { audio20_control_range_2_n_t(1) range_vol = { .wNumSubRanges = tu_htole16(1), .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}}; TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol)); } else if (request->bRequest == AUDIO20_CS_REQ_CUR) { audio20_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])}; TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol)); } } TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } static bool audio20_feature_unit_set_request(audio20_control_request_t const *request, uint8_t const *buf) { TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT); TU_VERIFY(request->bRequest == AUDIO20_CS_REQ_CUR); if (request->bControlSelector == AUDIO20_FU_CTRL_MUTE) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_1_t)); mute[request->bChannelNumber] = ((audio20_control_cur_1_t const *) buf)->bCur; TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; } else if (request->bControlSelector == AUDIO20_FU_CTRL_VOLUME) { TU_VERIFY(request->wLength == sizeof(audio20_control_cur_2_t)); volume[request->bChannelNumber] = ((audio20_control_cur_2_t const *) buf)->bCur; TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); return true; } else { TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } } static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const *p_request) { audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_CLOCK) return audio20_clock_get_request(rhport, request); if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) return audio20_feature_unit_get_request(rhport, request); else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); } return false; } static bool audio20_set_req_entity(tusb_control_request_t const *p_request, uint8_t *buf) { audio20_control_request_t const *request = (audio20_control_request_t const *) p_request; if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT) return audio20_feature_unit_set_request(request, buf); if (request->bEntityID == UAC2_ENTITY_CLOCK) return audio20_clock_set_request(request, buf); TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); return false; } #endif // TUD_OPT_HIGH_SPEED //--------------------------------------------------------------------+ // Main Callback Functions //--------------------------------------------------------------------+ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); TU_LOG2("Set interface %d alt %d\r\n", itf, alt); if (ITF_NUM_AUDIO_STREAMING == itf && alt != 0) blink_interval_ms = BLINK_STREAMING; #if CFG_AUDIO_DEBUG current_alt_settings = alt; #endif return true; } // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) pBuff; if (tud_audio_version() == 1) { return audio10_set_req_ep(p_request, pBuff); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_ep(rhport, p_request); } else if (tud_audio_version() == 2) { // We do not support any requests here } return false;// Yet not implemented } // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { (void) rhport; if (tud_audio_version() == 1) { return audio10_set_req_entity(p_request, buf); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_set_req_entity(p_request, buf); #endif } return false; } // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; if (tud_audio_version() == 1) { return audio10_get_req_entity(rhport, p_request); #if TUD_OPT_HIGH_SPEED } else if (tud_audio_version() == 2) { return audio20_get_req_entity(rhport, p_request); #endif } return false; } bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) { blink_interval_ms = BLINK_MOUNTED; } return true; } void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t *feedback_param) { (void) func_id; (void) alt_itf; // Set feedback method to fifo counting feedback_param->method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT; feedback_param->sample_freq = current_sample_rate; // About FIFO threshold: // // By default the threshold is set to half FIFO size, which works well in most cases, // you can reduce the threshold to have less latency. // // For example, here we could set the threshold to 2 ms of audio data, as audio_task() read audio data every 1 ms, // having 2 ms threshold allows some margin and a quick response: // // feedback_param->fifo_count.fifo_threshold = // current_sample_rate * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX / 1000 * 2; } #if CFG_AUDIO_DEBUG bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { (void) rhport; (void) n_bytes_received; (void) func_id; (void) ep_out; (void) cur_alt_setting; fifo_count = tud_audio_available(); // Same averaging method used in UAC2 class const uint32_t ff_count32 = (uint32_t) fifo_count << 16; fifo_count_avg = (uint32_t) (((uint64_t) fifo_count_avg * 63 + ff_count32) >> 6); return true; } #endif //--------------------------------------------------------------------+ // AUDIO Task //--------------------------------------------------------------------+ // This task simulates an audio transmit callback, one frame is sent every 1ms. // In a real application, this would be replaced with actual I2S transmit callback. void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; uint16_t length = (uint16_t) (current_sample_rate / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX); if (current_sample_rate == 44100 && (curr_ms % 10 == 0)) { // Take one more sample every 10 cycles, to have a average reading speed of 44.1 // This correction is not needed in real world cases length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX; } else if (current_sample_rate == 88200 && (curr_ms % 5 == 0)) { // Take one more sample every 5 cycles, to have a average reading speed of 88.2 // This correction is not needed in real world cases length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX; } tud_audio_read(i2s_dummy_buffer, length); } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; } #if CFG_AUDIO_DEBUG //--------------------------------------------------------------------+ // HID interface for audio debug //--------------------------------------------------------------------+ // Every 1ms, we will sent 1 debug information report void audio_debug_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = tusb_time_millis_api(); if (start_ms == curr_ms) return;// not enough time start_ms = curr_ms; audio_debug_info_t debug_info; debug_info.sample_rate = current_sample_rate; debug_info.alt_settings = current_alt_settings; debug_info.fifo_size = CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ; debug_info.fifo_count = fifo_count; debug_info.fifo_count_avg = (uint16_t) (fifo_count_avg >> 16); for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) { debug_info.mute[i] = mute[i]; debug_info.volume[i] = volume[i]; } if (tud_hid_ready()) tud_hid_report(0, &debug_info, sizeof(debug_info)); } // Invoked when received GET_REPORT control request // Unused here uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { // TODO not Implemented (void) itf; (void) report_id; (void) report_type; (void) buffer; (void) reqlen; return 0; } // Invoked when received SET_REPORT control request or // Unused here void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { // This example doesn't use multiple report and report ID (void) itf; (void) report_id; (void) report_type; (void) buffer; (void) bufsize; } #endif ================================================ FILE: examples/device/uac2_speaker_fb/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jerzy Kasenberg * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif #include "usb_descriptors.h" //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif // It's recommended to disable debug unless for control requests debugging, // as the extra time needed will impact data stream ! #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- // Expose audio class debug information via HID interface #ifndef CFG_AUDIO_DEBUG #define CFG_AUDIO_DEBUG 1 #endif #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif #define CFG_TUD_HID_EP_BUFSIZE 64 //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #if CFG_AUDIO_DEBUG #define CFG_TUD_HID 1 #else #define CFG_TUD_HID 0 #endif #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 // 16bit data in 16bit slots #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 #define CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX 16 // UAC1 Full-Speed endpoint size #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_FS 48000 #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS TUD_AUDIO_EP_SIZE(false, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_FS, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) // UAC2 High-Speed endpoint size #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_HS 96000 #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS TUD_AUDIO_EP_SIZE(true, CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE_HS, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS) // AUDIO_FEEDBACK_METHOD_FIFO_COUNT needs buffer size >= 4* EP size to work correctly // Example read FIFO every 1ms (8 HS frames), so buffer size should be 8 times larger for HS device #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(4 * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, 32 * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS) // Enable OUT EP #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 // Enable feedback EP #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 1 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/uac2_speaker_fb/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 HiFiPhile * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" #include "common_types.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VENDOR, 5) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } #if CFG_AUDIO_DEBUG //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ uint8_t const desc_hid_report[] = { HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ HID_USAGE ( 0x01 ),\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ HID_USAGE ( 0x02 ),\ HID_LOGICAL_MIN ( 0x00 ),\ HID_LOGICAL_MAX_N ( 0xff, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT( sizeof(audio_debug_info_t) ),\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END }; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) { (void) itf; return desc_hid_report; } #endif //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 #define EPNUM_AUDIO_FB 0x03 #define EPNUM_DEBUG 0x04 #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 #define EPNUM_AUDIO_FB 0x08 #define EPNUM_DEBUG 0x01 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO 0x02 #define EPNUM_AUDIO_FB 0x01 #define EPNUM_DEBUG 0x03 #else #define EPNUM_AUDIO 0x01 #define EPNUM_AUDIO_FB 0x01 #define EPNUM_DEBUG 0x02 #endif #if CFG_AUDIO_DEBUG #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(2) + TUD_HID_DESC_LEN) #else #define CONFIG_UAC1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(2)) #endif uint8_t const desc_uac1_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC1_TOTAL_LEN, 0x00, 100), // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, sample rates (44.1kHz, 48kHz) TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 5, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_FS, EPNUM_AUDIO_FB | 0x80, 44100, 48000), #if CFG_AUDIO_DEBUG // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) #endif }; TU_VERIFY_STATIC(sizeof(desc_uac1_configuration) == CONFIG_UAC1_TOTAL_LEN, "Incorrect size"); #if TUD_OPT_HIGH_SPEED #if CFG_AUDIO_DEBUG #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN) #else #define CONFIG_UAC2_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN) #endif uint8_t const desc_uac2_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_UAC2_TOTAL_LEN, 0x00, 100), // Interface number, string index, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size, TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(ITF_NUM_AUDIO_CONTROL, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_HS, EPNUM_AUDIO_FB | 0x80, 4), #if CFG_AUDIO_DEBUG // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7) #endif }; TU_VERIFY_STATIC(sizeof(desc_uac2_configuration) == CONFIG_UAC2_TOTAL_LEN, "Incorrect size"); // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = 0x0200, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index;// for multiple configurations // if link speed is high return fullspeed config, and vice versa return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_uac1_configuration : desc_uac2_configuration; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if(tud_speed_get() == TUSB_SPEED_FULL) { return desc_uac1_configuration; } else { return desc_uac2_configuration; } #else return desc_uac1_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Speaker", // 2: Product NULL, // 3: Serials will use unique ID if possible "UAC2 Speaker", // 4: Audio Interface "UAC1 Speaker", // 5: UAC1 Audio Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/uac2_speaker_fb/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 HiFiPhile * * 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. * */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ //--------------------------------------------------------------------+ // UAC2 DESCRIPTOR TEMPLATES //--------------------------------------------------------------------+ // Defined in TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR #define UAC2_ENTITY_CLOCK 0x04 #define UAC2_ENTITY_INPUT_TERMINAL 0x01 #define UAC2_ENTITY_FEATURE_UNIT 0x02 #define UAC2_ENTITY_OUTPUT_TERMINAL 0x03 #define TUD_AUDIO20_SPEAKER_STEREO_FB_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2)\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN) #define TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1) //--------------------------------------------------------------------+ // UAC1 DESCRIPTOR TEMPLATES //--------------------------------------------------------------------+ // Defined in TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR #define UAC1_ENTITY_INPUT_TERMINAL 0x01 #define UAC1_ENTITY_FEATURE_UNIT 0x02 #define UAC1_ENTITY_OUTPUT_TERMINAL 0x03 #define TUD_AUDIO10_SPEAKER_STEREO_FB_DESC_LEN(_nfreqs) (\ + TUD_AUDIO10_DESC_STD_AC_LEN\ + TUD_AUDIO10_DESC_CS_AC_LEN(1)\ + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs)\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN\ + TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP_LEN) #define TUD_AUDIO10_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, ...) \ /* Standard AC Interface Descriptor(4.3.1) */\ TUD_AUDIO10_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.3.2) */\ TUD_AUDIO10_DESC_CS_AC(/*_bcdADC*/ 0x0100, /*_totallen*/ (TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(2)), /*_itf*/ ((_itfnum)+1)),\ /* Input Terminal Descriptor(4.3.2.1) */\ TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_nchannels*/ 0x02, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_LEFT_FRONT | AUDIO10_CHANNEL_CONFIG_RIGHT_FRONT, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.3.2.2) */\ TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x00, /*_srcid*/ 0x02, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.3.2.5) */\ TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlmaster*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch1*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch2*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME)),\ /* Standard AS Interface Descriptor(4.5.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.5.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.5.2) */\ TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_delay*/ 0x00, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ /* Type I Format Type Descriptor(2.2.5) */\ TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x02, /*_subframesize*/ _nBytesPerSample, /*_bitresolution*/ _nBitsUsedPerSample, /*_freqs*/ __VA_ARGS__),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01, /*_sync_ep*/ _epfb),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Synch Endpoint Descriptor (4.6.2.1) */\ TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP(/*_ep*/ _epfb, /*_bRefresh*/ 0) //---------------------------------------------------------------------------+ // UAC1 Isochronous Synch Endpoint bRefresh Workaround // // bRefresh value is set to 0, while UAC1 spec requires it to be between // 1 (2 ms) and 9 (512 ms) // // This value has been tested to work with Windows, macOS and Linux. // // Rationale: // Some USB device controllers (e.g. Synopsys DWC2) require a known transfer // interval to manually schedule isochronous IN transfers. For data isochronous // endpoints, the bInterval field in the endpoint descriptor is used. However, // for synch endpoint it's unclear which field the host uses to determine the // transfer interval. Windows and macOS use bRefresh, while Linux uses bInterval. // // Since bInterval is fixed to 1, if bRefresh is set to 2 then Windows and macOS // will schedule the feedback transfer every 4 ms, but Linux will schedule it // every 1 ms. DWC2 controller cannot handle this discrepancy without knwowing // the actual interval, therefore we set bRefresh to 0 to let the transfer // execute every 1 ms, which is the same as bInterval. // // Rant: // WTF USB-IF? Why have two fields that mean the same thing? Why not just use // bInterval for both data and synch endpoints? Why is bRefresh even necessary? // // Note: // For the moment DWC2 driver doesn't have proper support for bInterval > 1 // for isochronous IN endpoints. The implementation would be complex and CPU // intensive (cfr. // https://github.com/torvalds/linux/blob/master/drivers/usb/dwc2/gadget.c) // It MAY work in some cases if you are lucky, but it's not guaranteed. //---------------------------------------------------------------------------+ #endif ================================================ FILE: examples/device/usbtmc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(usbtmc C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usbtmc_app.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/usbtmc/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/usbtmc/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/usbtmc/skip.txt ================================================ mcu:BCM2835 family:espressif ================================================ FILE: examples/device/usbtmc/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "main.h" #include "usbtmc_app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 0 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 0, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(); usbtmc_app_task_iter(); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // BLINKING TASK + Indicator pulse //--------------------------------------------------------------------+ volatile uint8_t doPulse = false; // called from USB context void led_indicator_pulse(void) { doPulse = true; } void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; if(blink_interval_ms == BLINK_MOUNTED) // Mounted { if(doPulse) { led_state = true; board_led_write(true); start_ms = tusb_time_millis_api(); doPulse = false; } else if (led_state == true) { if ( tusb_time_millis_api() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms. { return; // not enough time } led_state = false; board_led_write(false); } } else { // Blink every interval ms if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } } ================================================ FILE: examples/device/usbtmc/src/main.h ================================================ #ifndef MAIN_H #define MAIN_H void led_indicator_pulse(void); #endif ================================================ FILE: examples/device/usbtmc/src/tusb_config.h ================================================ /* * tusb_config.h * * Created on: Sep 5, 2019 * Author: nconrad */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_USBTMC 1 #define CFG_TUD_USBTMC_ENABLE_INT_EP 1 #define CFG_TUD_USBTMC_ENABLE_488 1 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/usbtmc/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "class/usbtmc/usbtmc.h" #include "class/usbtmc/usbtmc_device.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xcafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_UNSPECIFIED, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ #if defined(CFG_TUD_USBTMC) # define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints, _bulkMaxPacketLength) \ TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, TUD_USBTMC_PROTOCOL_USB488), \ TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */_bulkMaxPacketLength) #if CFG_TUD_USBTMC_ENABLE_INT_EP // USBTMC Interrupt xfer always has length of 2, but we use epMaxSize=8 for // compatibility with mcus that only allow 8, 16, 32 or 64 for FS endpoints # define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \ TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3, _bulkMaxPacketLength), \ TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 8, /* bInterval = */16u ) # define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN) #else # define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \ TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u, _bulkMaxPacketLength) # define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN) #endif /* CFG_TUD_USBTMC_ENABLE_INT_EP */ #else # define USBTMC_DESC_LEN (0) #endif /* CFG_TUD_USBTMC */ enum { ITF_NUM_USBTMC, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_USBTMC_DESC_LEN) static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 64), }; #if TUD_OPT_HIGH_SPEED static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_UNSPECIFIED, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB USBTMC", // 4: USBTMC }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/usbtmc/src/usbtmc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Nathan Conrad * * 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 #include /* atoi */ #include "tusb.h" #include "bsp/board_api.h" #include "main.h" #include "usbtmc_app.h" #if (CFG_TUD_USBTMC_ENABLE_488) static usbtmc_response_capabilities_488_t const #else static usbtmc_response_capabilities_t const #endif tud_usbtmc_app_capabilities = { .USBTMC_status = USBTMC_STATUS_SUCCESS, .bcdUSBTMC = USBTMC_VERSION, .bmIntfcCapabilities = { .listenOnly = 0, .talkOnly = 0, .supportsIndicatorPulse = 1 }, .bmDevCapabilities = { .canEndBulkInOnTermChar = 0 }, #if (CFG_TUD_USBTMC_ENABLE_488) .bcdUSB488 = USBTMC_488_VERSION, .bmIntfcCapabilities488 = { .supportsTrigger = 1, .supportsREN_GTL_LLO = 0, .is488_2 = 1 }, .bmDevCapabilities488 = { .SCPI = 1, .SR1 = 0, .RL1 = 0, .DT1 =0, } #endif }; #define IEEE4882_STB_QUESTIONABLE (0x08u) #define IEEE4882_STB_MAV (0x10u) #define IEEE4882_STB_SER (0x20u) #define IEEE4882_STB_SRQ (0x40u) static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n"; //static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer and a bunch of other text to make it longer than a packet, perhaps? lets make it three transfers...\n"; static volatile uint8_t status; // 0=not query, 1=queried, 2=delay,set(MAV), 3=delay 4=ready? // (to simulate delay) static volatile uint16_t queryState = 0; static volatile uint32_t queryDelayStart; static volatile uint32_t bulkInStarted; static volatile uint32_t idnQuery; static uint32_t resp_delay = 125u; // Adjustable delay, to allow for better testing static size_t buffer_len; static size_t buffer_tx_ix; // for transmitting using multiple transfers static uint8_t buffer[225]; // A few packets long should be enough. void tud_usbtmc_open_cb(uint8_t interface_id) { (void)interface_id; tud_usbtmc_start_bus_read(); } #if (CFG_TUD_USBTMC_ENABLE_488) usbtmc_response_capabilities_488_t const * #else usbtmc_response_capabilities_t const * #endif tud_usbtmc_get_capabilities_cb(void) { return &tud_usbtmc_app_capabilities; } bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg) { (void)msg; // Let trigger set the SRQ status |= IEEE4882_STB_SRQ; return true; } bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader) { (void)msgHeader; buffer_len = 0; if(msgHeader->TransferSize > sizeof(buffer)) { return false; } return true; } bool tud_usbtmc_msg_data_cb(void *data, size_t len, bool transfer_complete) { // If transfer isn't finished, we just ignore it (for now) if(len + buffer_len < sizeof(buffer)) { memcpy(&(buffer[buffer_len]), data, len); buffer_len += len; } else { return false; // buffer overflow! } queryState = transfer_complete; idnQuery = 0; if ( transfer_complete && (len >= 4) && (!strncmp("*idn?", data, 4) || !strncmp("*IDN?", data, 4)) ) { idnQuery = 1; } if ( transfer_complete && (!strncmp("delay ", data, 5) || !strncmp("DELAY ", data, 5)) ) { queryState = 0; int d = atoi((char*)data + 5); if(d > 10000) d = 10000; if(d<0) d=0; resp_delay = (uint32_t)d; } tud_usbtmc_start_bus_read(); return true; } bool tud_usbtmc_msgBulkIn_complete_cb(void) { if((buffer_tx_ix == buffer_len) || idnQuery) // done { status &= (uint8_t)~(IEEE4882_STB_MAV); // clear MAV queryState = 0; bulkInStarted = 0; buffer_tx_ix = 0; } tud_usbtmc_start_bus_read(); return true; } static unsigned int msgReqLen; bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request) { msgReqLen = request->TransferSize; #ifdef xDEBUG uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); #endif if(queryState == 0 || (buffer_tx_ix == 0)) { TU_ASSERT(bulkInStarted == 0); bulkInStarted = 1; // > If a USBTMC interface receives a Bulk-IN request prior to receiving a USBTMC command message // that expects a response, the device must NAK the request (*not stall*) } else { size_t txlen = tu_min32(buffer_len-buffer_tx_ix,msgReqLen); tud_usbtmc_transmit_dev_msg_data(&buffer[buffer_tx_ix], txlen, (buffer_tx_ix+txlen) == buffer_len, false); buffer_tx_ix += txlen; } // Always return true indicating not to stall the EP. return true; } void usbtmc_app_task_iter(void) { switch(queryState) { case 0: break; case 1: queryDelayStart = tusb_time_millis_api(); queryState = 2; break; case 2: if( (tusb_time_millis_api() - queryDelayStart) > resp_delay) { queryDelayStart = tusb_time_millis_api(); queryState=3; status |= 0x10u; // MAV status |= 0x40u; // SRQ } break; case 3: if( (tusb_time_millis_api() - queryDelayStart) > resp_delay) { queryState = 4; } break; case 4: // time to transmit; if(bulkInStarted && (buffer_tx_ix == 0)) { if(idnQuery) { tud_usbtmc_transmit_dev_msg_data(idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); queryState = 0; bulkInStarted = 0; } else { buffer_tx_ix = tu_min32(buffer_len,msgReqLen); tud_usbtmc_transmit_dev_msg_data(buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); } // MAV is cleared in the transfer complete callback. } break; default: TU_ASSERT(false,); } } bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult) { *tmcResult = USBTMC_STATUS_SUCCESS; queryState = 0; bulkInStarted = false; status = 0; return true; } bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp) { queryState = 0; bulkInStarted = false; status = 0; buffer_tx_ix = 0u; buffer_len = 0u; rsp->USBTMC_status = USBTMC_STATUS_SUCCESS; rsp->bmClear.BulkInFifoBytes = 0u; return true; } bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult) { bulkInStarted = 0; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; tud_usbtmc_start_bus_read(); return true; } bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult) { *tmcResult = USBTMC_STATUS_SUCCESS; return true; } bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; tud_usbtmc_start_bus_read(); return true; } void tud_usbtmc_bulkIn_clearFeature_cb(void) { } void tud_usbtmc_bulkOut_clearFeature_cb(void) { tud_usbtmc_start_bus_read(); } // Return status byte, but put the transfer result status code in the rspResult argument. uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult) { uint8_t old_status = status; status = (uint8_t)(status & ~(IEEE4882_STB_SRQ)); // clear SRQ *tmcResult = USBTMC_STATUS_SUCCESS; // Increment status so that we see different results on each read... return old_status; } bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult) { (void)msg; led_indicator_pulse(); *tmcResult = USBTMC_STATUS_SUCCESS; return true; } ================================================ FILE: examples/device/usbtmc/src/usbtmc_app.h ================================================ #ifndef USBTMC_APP_H #define USBTMC_APP_H void usbtmc_app_task_iter(void); #endif ================================================ FILE: examples/device/usbtmc/visaQuery.py ================================================ #!/usr/bin/env python3 import pyvisa import time import sys def test_idn(): idn = inst.query("*idn?"); assert (idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n") assert (inst.is_4882_compliant) def test_echo(m,n): longstr = "0123456789abcdefghijklmnopqrstuvwxyz" * 50 t0 = time.monotonic() #Next try echo from 1 to 175 characters (200 is max buffer size on DUT) for i in range(m,n): #print(i) x = longstr[0:i] xt = x + inst.write_termination y = inst.query(x) #print(x) #print (":".join("{:02x}".format(ord(c)) for c in xt)) #print (":".join("{:02x}".format(ord(c)) for c in y)) assert(xt == y), f"failed i={i}" #inst.read_stb();# Just to make USB logging easier by sending a control query (bad thing is that this made things slow) t = time.monotonic() - t0 print(f" elapsed: {t:0.3} sec") def test_trig(): # clear SRQ inst.read_stb() assert (inst.read_stb() == 0) inst.assert_trigger() time.sleep(0.3) # SRQ may have some delay assert (inst.read_stb() & 0x40), "SRQ not set after 0.3 seconds" assert (inst.read_stb() == 0) def test_mav(): inst.write("delay 50") inst.read_stb() # clear STB assert (inst.read_stb() == 0) inst.write("123") time.sleep(0.3) assert (inst.read_stb() & 0x10), "MAV not set after 0.5 seconds" rsp = inst.read() assert(rsp == "123\r\n") def test_srq(): assert (inst.read_stb() == 0) inst.write("123") #inst.enable_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE) #waitrsp = inst.wait_on_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, 5000) #inst.discard_events(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE) #inst.wait_for_srq() time.sleep(0.3) stb = inst.read_stb() msg = "SRQ not set after 0.5 seconds, was {:02x}".format(stb) assert (stb == 0x50),msg assert (inst.read_stb() == 0x10), "SRQ set at second read!" rsp = inst.read() assert(rsp == "123\r\n") def test_read_timeout(): inst.timeout = 500 # First read with no MAV inst.read_stb() assert (inst.read_stb() == 0) inst.write("delay 500") t0 = time.monotonic() try: rsp = inst.read() assert(False), "Read should have resulted in timeout" except pyvisa.VisaIOError: print(" Got expected exception") t = time.monotonic() - t0 assert ((t*1000.0) > (inst.timeout - 300)) assert ((t*1000.0) < (inst.timeout + 300)) print(f"Delay was {t:0.3}") # Response is still in queue, so send a clear (to be more helpful to the next test) inst.clear() time.sleep(0.3) assert(0 == (inst.read_stb() & 0x10)), "MAV not reset after clear" def test_abort_in(): inst.timeout = 200 # First read with no MAV inst.read_stb() assert (inst.read_stb() == 0) inst.write("delay 500") inst.write("xxx") t0 = time.monotonic() try: rsp = inst.read() assert(False), "Read should have resulted in timeout" except pyvisa.VisaIOError: print(" Got expected exception") t = time.monotonic() - t0 assert ((t*1000.0) > (inst.timeout - 300)) assert ((t*1000.0) < (inst.timeout + 300)) print(f" Delay was {t:0.3}") # Response is still in queue, so read it out (to be more helpful to the next test) inst.timeout = 800 y = inst.read() assert(y == "xxx\r\n") def test_indicate(): # perform indicator pulse usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM) retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=64, request_value=0x0000, index=usb_iface, length=0x0001) # pyvisa used to return (statuscode,bytes), but now only returns bytes, so we need to handle both cases if(isinstance(retv,bytes)): assert(retv == b'\x01') else: assert((retv[1] == pyvisa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}" def test_multi_read(): old_chunk_size = inst.chunk_size longstr = "0123456789abcdefghijklmnopqrstuvwxyz" * 10 timeout = 10 x = longstr[0:174] inst.chunk_size = 50 # Seems chunk size only applies to read but not write inst.write(x) # I'm not sure how to request just the remaining bit using a max count... so just read it all. y = inst.read() assert (x + "\r\n" == y) #inst.chunk_size = old_chunk_size def test_stall_ep0(): usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM) inst.read_stb() # This is an invalid request, should create stall. try: retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=60, request_value=0x0000, index=usb_iface, length=0x0001) assert(False) except pyvisa.VisaIOError: pass assert (inst.read_stb() == 0) rm = pyvisa.ResourceManager() reslist = rm.list_resources("USB?::?*::INSTR") print(reslist) if (len(reslist) == 0): sys.exit() inst = rm.open_resource(reslist[0]); inst.timeout = 3000 inst.clear() print("+ IDN") test_idn() print("+test abort in") test_abort_in() inst.timeout = 2000 print("+ multi read") test_multi_read() print("+ echo delay=0") inst.write("delay 0") test_echo(1,175) print("+ echo delay=2") inst.write("delay 2") test_echo(1,175) print("+ echo delay=150") inst.write("delay 150") test_echo(53,76) test_echo(165,170) print("+ Read timeout (no MAV)") test_read_timeout() print("+ Test EP0 stall recovery") test_stall_ep0() print("+ MAV") test_mav() print("+ SRQ") test_srq() print("+ indicate") test_indicate() print("+ TRIG") test_trig() # Untested: # abort bulk out # LLO, GTL, etc # Throughput rate? # Transmitting a message using multiple transfers inst.close() print("Test complete") ================================================ FILE: examples/device/video_capture/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(video_capture C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) if (FORCE_READONLY) target_compile_definitions(${PROJECT_NAME} PRIVATE CFG_EXAMPLE_VIDEO_READONLY ) endif() # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/video_capture/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/video_capture/Makefile ================================================ include ../../../hw/bsp/family_support.mk ifeq ($(DISABLE_MJPEG),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG endif ifeq ($(FORCE_READONLY),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY endif INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/video_capture/skip.txt ================================================ mcu:CH32V103 mcu:CH32V20X mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 ================================================ FILE: examples/device/video_capture/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/video_capture/src/images.h ================================================ #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) // uncopmressed frame static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 1 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 2 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 3 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 4 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 5 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 6 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 7 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 8 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 9 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 10 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 11 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 12 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 13 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 14 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 15 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 16 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 17 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 18 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 19 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 20 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 21 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 22 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 23 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 24 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 25 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 26 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 27 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 28 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 29 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 30 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 31 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 32 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 33 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 34 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 35 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 36 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 37 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 38 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 39 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 40 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 41 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 42 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 43 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 44 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 45 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 46 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 47 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 48 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 49 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 50 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 51 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 52 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 53 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 54 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 55 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 56 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 57 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 58 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 59 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 60 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 61 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 62 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 63 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 64 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 65 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 66 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 67 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 68 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 69 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 70 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 71 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 72 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 73 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 74 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 75 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 76 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 77 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 78 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 79 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 80 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 81 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 82 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 83 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 84 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 85 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 86 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 87 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 88 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 89 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 90 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 91 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 92 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 93 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 94 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 95 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 96 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; #else // mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define color_bar_0_jpg_len 511 #define color_bar_1_jpg_len 512 #define color_bar_2_jpg_len 511 #define color_bar_3_jpg_len 511 #define color_bar_4_jpg_len 511 #define color_bar_5_jpg_len 512 #define color_bar_6_jpg_len 511 #define color_bar_7_jpg_len 511 unsigned char color_bar_0_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 }; unsigned char color_bar_1_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 }; unsigned char color_bar_2_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 }; unsigned char color_bar_3_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 }; unsigned char color_bar_4_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 }; unsigned char color_bar_5_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 }; unsigned char color_bar_6_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 }; unsigned char color_bar_7_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 }; #endif ================================================ FILE: examples/device/video_capture/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void* param); void usb_device_task(void *param); void video_task(void* param); #if CFG_TUSB_OS == OPT_OS_FREERTOS void freertos_init(void); #endif #if !defined(CFG_EXAMPLE_VIDEO_READONLY) || defined(CFG_EXAMPLE_VIDEO_BUFFERLESS) /* EBU color bars: https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { /* Y, U, Y, V */ { 235, 128, 235, 128}, /* 100% White */ { 219, 16, 219, 138}, /* Yellow */ { 188, 154, 188, 16}, /* Cyan */ { 173, 42, 173, 26}, /* Green */ { 78, 214, 78, 230}, /* Magenta */ { 63, 102, 63, 240}, /* Red */ { 32, 240, 32, 118}, /* Blue */ { 16, 128, 16, 128}, /* Black */ }; #endif //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); // If using FreeRTOS: create blinky, tinyusb device, video task #if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); #else // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(NULL); video_task(NULL); } #endif } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } #ifdef CFG_EXAMPLE_VIDEO_BUFFERLESS #ifndef CFG_EXAMPLE_VIDEO_DISABLE_MJPEG #error Demo only supports YUV2 please define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG #endif void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request) { static uint32_t frame_counter = 0; (void)ctl_idx; (void)stm_idx; /* Offset will be zero at the start of a new frame */ if (!request->offset) frame_counter++; for (size_t buf_pos = 0; buf_pos < request->length; buf_pos += 2) { /* Position within the current line (pixel relative) */ int line_pos = ((request->offset + buf_pos)>>1) % FRAME_WIDTH; /* Choose color based on the position and change the table offset every 4 frames */ const uint8_t* color = bar_color[(line_pos/(FRAME_WIDTH / 8) + (frame_counter>>2)) % 8]; /* Copy pixel data for odd or even pixels */ memcpy(&((uint8_t*)request->buf)[buf_pos], &color[(line_pos & 1) ? 2 : 0], 2); } } #endif //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ static unsigned frame_num = 0; static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; #ifndef CFG_EXAMPLE_VIDEO_BUFFERLESS #ifdef CFG_EXAMPLE_VIDEO_READONLY // For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. // To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" #if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) static struct { uint32_t size; uint8_t const *buffer; } const frames[] = { {color_bar_0_jpg_len, color_bar_0_jpg}, {color_bar_1_jpg_len, color_bar_1_jpg}, {color_bar_2_jpg_len, color_bar_2_jpg}, {color_bar_3_jpg_len, color_bar_3_jpg}, {color_bar_4_jpg_len, color_bar_4_jpg}, {color_bar_5_jpg_len, color_bar_5_jpg}, {color_bar_6_jpg_len, color_bar_6_jpg}, {color_bar_7_jpg_len, color_bar_7_jpg}, }; #endif #else // YUY2 frame buffer static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; static void fill_color_bar(uint8_t* buffer, unsigned start_position) { uint8_t* p; /* Generate the 1st line */ uint8_t* end = &buffer[FRAME_WIDTH * 2]; unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); p = &buffer[idx * 4]; for (unsigned i = 0; i < 8; ++i) { for (int j = 0; j < FRAME_WIDTH / (2 * 8); ++j) { memcpy(p, &bar_color[i], 4); p += 4; if (end <= p) { p = buffer; } } } /* Duplicate the 1st line to the others */ p = &buffer[FRAME_WIDTH * 2]; for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { memcpy(p, buffer, FRAME_WIDTH * 2); p += FRAME_WIDTH * 2; } } #endif #endif /* NDEF CFG_EXAMPLE_VIDEO_BUFFERLESS */ static void video_send_frame(void) { static unsigned start_ms = 0; static unsigned already_sent = 0; if (!tud_video_n_streaming(0, 0)) { already_sent = 0; frame_num = 0; return; } if (!already_sent) { already_sent = 1; tx_busy = 1; start_ms = tusb_time_millis_api(); #if defined(CFG_EXAMPLE_VIDEO_BUFFERLESS) tud_video_n_frame_xfer(0, 0, NULL, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #elif defined (CFG_EXAMPLE_VIDEO_READONLY) #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); #endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } unsigned cur = tusb_time_millis_api(); if (cur - start_ms < interval_ms) { return; // not enough time } if (tx_busy) { return; } start_ms += interval_ms; tx_busy = 1; #if defined(CFG_EXAMPLE_VIDEO_BUFFERLESS) tud_video_n_frame_xfer(0, 0, NULL, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #elif defined(CFG_EXAMPLE_VIDEO_READONLY) #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); #endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } void video_task(void* param) { (void) param; while(1) { video_send_frame(); #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(interval_ms / portTICK_PERIOD_MS); #else return; #endif } } void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { (void) ctl_idx; (void) stm_idx; tx_busy = 0; /* flip buffer */ ++frame_num; } int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const* parameters) { (void) ctl_idx; (void) stm_idx; /* convert unit to ms from 100 ns */ interval_ms = parameters->dwFrameInterval / 10000; return VIDEO_ERROR_NONE; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void* param) { (void) param; static uint32_t start_ms = 0; static bool led_state = false; while (1) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } #endif start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } } //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { main(); } #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t video_stack[VIDEO_STACK_SIZE]; StaticTask_t video_taskdef; #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tud_task(); } } void freertos_init(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } #endif ================================================ FILE: examples/device/video_capture/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// // The number of video control interfaces #define CFG_TUD_VIDEO 1 // The number of video streaming interfaces #define CFG_TUD_VIDEO_STREAMING 1 // video streaming endpoint buffer size #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface #define CFG_TUD_VIDEO_STREAMING_BULK 0 //#define CFG_EXAMPLE_VIDEO_READONLY //#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG //#define CFG_EXAMPLE_VIDEO_BUFFERLESS #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/video_capture/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VIDEO, 5) | PID_MAP(VENDOR, 6) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_UVC_CONTROL, STRID_UVC_STREAMING, }; // array of pointer to string descriptors char const* string_desc_arr[] = { (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "UVC Control", // 4: UVC Interface "UVC Streaming", // 5: UVC Interface }; //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for Video // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = STRID_MANUFACTURER, .iProduct = STRID_PRODUCT, .iSerialNumber = STRID_SERIAL, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const* tud_descriptor_device_cb(void) { return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ /* Time stamp base clock. It is a deprecated parameter. */ #define UVC_CLOCK_FREQUENCY 27000000 /* video capture path */ #define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 #define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 enum { ITF_NUM_VIDEO_CONTROL, ITF_NUM_VIDEO_STREAMING, ITF_NUM_TOTAL }; // Select appropriate endpoint number #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x82 : 0x83) #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88) #elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) #define EPNUM_VIDEO_IN 0x81 #else #define EPNUM_VIDEO_IN 0x81 #endif #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define USE_MJPEG 1 #else #define USE_MJPEG 0 #endif #define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_control_header_1itf_t header; tusb_desc_video_control_camera_terminal_t camera_terminal; tusb_desc_video_control_output_terminal_t output_terminal; } uvc_control_desc_t; /* Windows support YUY2 and NV12 * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; #if USE_MJPEG tusb_desc_video_format_mjpeg_t format; tusb_desc_video_frame_mjpeg_continuous_t frame; #else tusb_desc_video_format_uncompressed_t format; tusb_desc_video_frame_uncompressed_continuous_t frame; #endif tusb_desc_video_streaming_color_matching_t color; #if USE_ISO_STREAMING // For ISO streaming, USB spec requires to alternate interface tusb_desc_interface_t itf_alt; #endif tusb_desc_endpoint_t ep; } uvc_streaming_desc_t; typedef struct TU_ATTR_PACKED { tusb_desc_configuration_t config; tusb_desc_interface_assoc_t iad; uvc_control_desc_t video_control; uvc_streaming_desc_t video_streaming; } uvc_cfg_desc_t; const uvc_cfg_desc_t desc_fs_configuration = { .config = { .bLength = sizeof(tusb_desc_configuration_t), .bDescriptorType = TUSB_DESC_CONFIGURATION, .wTotalLength = sizeof(uvc_cfg_desc_t), .bNumInterfaces = ITF_NUM_TOTAL, .bConfigurationValue = 1, .iConfiguration = 0, .bmAttributes = TU_BIT(7), .bMaxPower = 100 / 2 }, .iad = { .bLength = sizeof(tusb_desc_interface_assoc_t), .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, .bFirstInterface = ITF_NUM_VIDEO_CONTROL, .bInterfaceCount = 2, .bFunctionClass = TUSB_CLASS_VIDEO, .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, .iFunction = 0 }, .video_control = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_CONTROL }, .header = { .bLength = sizeof(tusb_desc_video_control_header_1itf_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, .bcdUVC = VIDEO_BCD_1_50, .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only .dwClockFrequency = UVC_CLOCK_FREQUENCY, .bInCollection = 1, .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING } }, .camera_terminal = { .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, .wTerminalType = VIDEO_ITT_CAMERA, .bAssocTerminal = 0, .iTerminal = 0, .wObjectiveFocalLengthMin = 0, .wObjectiveFocalLengthMax = 0, .wOcularFocalLength = 0, .bControlSize = 3, .bmControls = { 0, 0, 0 } }, .output_terminal = { .bLength = sizeof(tusb_desc_video_control_output_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .wTerminalType = VIDEO_TT_STREAMING, .bAssocTerminal = 0, .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, .iTerminal = 0 } }, .video_streaming = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, .bAlternateSetting = 0, .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING }, .header = { .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, .bNumFormats = 1, .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only .bEndpointAddress = EPNUM_VIDEO_IN, .bmInfo = 0, .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .bStillCaptureMethod = 0, .bTriggerSupport = 0, .bTriggerUsage = 0, .bControlSize = 1, .bmaControls = { 0 } }, .format = { #if USE_MJPEG .bLength = sizeof(tusb_desc_video_format_mjpeg_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, .bFormatIndex = 1, // 1-based index .bNumFrameDescriptors = 1, .bmFlags = 0, #else .bLength = sizeof(tusb_desc_video_format_uncompressed_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, .bFormatIndex = 1, // 1-based index .bNumFrameDescriptors = 1, .guidFormat = { TUD_VIDEO_GUID_YUY2 }, .bBitsPerPixel = 16, #endif .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, .bmInterlaceFlags = 0, .bCopyProtect = 0 }, .frame = { #if USE_MJPEG .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, #else .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, #endif .bFrameIndex = 1, // 1-based index .bmCapabilities = 0, .wWidth = FRAME_WIDTH, .wHeight = FRAME_HEIGHT, .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, .dwDefaultFrameInterval = 10000000 / FRAME_RATE, .bFrameIntervalType = 0, // continuous .dwFrameInterval = { 10000000 / FRAME_RATE, // min 10000000, // max 10000000 / FRAME_RATE // step } }, .color = { .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M }, #if USE_ISO_STREAMING .itf_alt = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, .bAlternateSetting = 1, .bNumEndpoints = 1, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING }, #endif .ep = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = EPNUM_VIDEO_IN, .bmAttributes = { .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous }, .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, .bInterval = 1 } } }; #if TUD_OPT_HIGH_SPEED uvc_cfg_desc_t desc_hs_configuration; static uint8_t * get_hs_configuration_desc(void) { static bool init = false; if (!init) { desc_hs_configuration = desc_fs_configuration; // change endpoint bulk size to 512 if bulk streaming if (CFG_TUD_VIDEO_STREAMING_BULK) { desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; } } init = true; return (uint8_t *) &desc_hs_configuration; } // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa if (tud_speed_get() == TUSB_SPEED_HIGH) { return (uint8_t const*) &desc_fs_configuration; } else { return get_hs_configuration_desc(); } } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if (tud_speed_get() == TUSB_SPEED_HIGH) { return get_hs_configuration_desc(); } else #endif { return (uint8_t const*) &desc_fs_configuration; } } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) return NULL; const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/video_capture/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenbreg * Copyright (c) 2021 Koji KITAYAMA * * 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. * */ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ #define FRAME_WIDTH 128 #define FRAME_HEIGHT 96 #define FRAME_RATE 10 // NOTE: descriptor template is not used but leave here as reference #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + 7/* Endpoint */\ ) /* Windows support YUY2 and NV12 * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ #define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* EP */ \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) #endif ================================================ FILE: examples/device/video_capture_2ch/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(video_capture_2ch C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) if (FORCE_READONLY) target_compile_definitions(${PROJECT_NAME} PRIVATE CFG_EXAMPLE_VIDEO_READONLY ) endif() # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/video_capture_2ch/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/video_capture_2ch/Makefile ================================================ include ../../../hw/bsp/family_support.mk ifeq ($(DISABLE_MJPEG),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG endif ifeq ($(FORCE_READONLY),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY endif INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/video_capture_2ch/skip.txt ================================================ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 family:espressif board:curiosity_nano board:kuiic board:frdm_k32l2b board:lpcxpresso11u68 board:stm32f303disco board:stm32l412nucleo board:ek_tm4c123gxl board:uno_r4 board:ra4m1_ek ================================================ FILE: examples/device/video_capture_2ch/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/video_capture_2ch/src/images.h ================================================ #if defined(CFG_EXAMPLE_VIDEO_READONLY) //--------------------------------------------------------------------+ // YUY2 Uncompressed Frame (fixed) //--------------------------------------------------------------------+ static const unsigned char framebuf_yuy2_readonly[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 1 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 2 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 3 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 4 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 5 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 6 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 7 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 8 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 9 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 10 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 11 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 12 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 13 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 14 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 15 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 16 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 17 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 18 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 19 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 20 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 21 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 22 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 23 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 24 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 25 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 26 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 27 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 28 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 29 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 30 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 31 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 32 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 33 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 34 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 35 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 36 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 37 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 38 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 39 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 40 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 41 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 42 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 43 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 44 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 45 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 46 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 47 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 48 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 49 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 50 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 51 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 52 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 53 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 54 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 55 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 56 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 57 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 58 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 59 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 60 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 61 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 62 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 63 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 64 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 65 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 66 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 67 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 68 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 69 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 70 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 71 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 72 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 73 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 74 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 75 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 76 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 77 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 78 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 79 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 80 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 81 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 82 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 83 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 84 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 85 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 86 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 87 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 88 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 89 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 90 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 91 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 92 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 93 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 94 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 95 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, /* 96 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; #endif //--------------------------------------------------------------------+ // MPEG Compressed Frame (fixed) //--------------------------------------------------------------------+ unsigned char color_bar_0_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 }; unsigned char color_bar_1_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 }; unsigned char color_bar_2_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 }; unsigned char color_bar_3_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 }; unsigned char color_bar_4_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 }; unsigned char color_bar_5_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 }; unsigned char color_bar_6_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 }; unsigned char color_bar_7_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 }; ================================================ FILE: examples/device/video_capture_2ch/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void* param); void usb_device_task(void *param); void video_task(void* param); #if CFG_TUSB_OS == OPT_OS_FREERTOS void freertos_init(void); #endif //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); // If using FreeRTOS: create blinky, tinyusb device, video task #if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); #else // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task led_blinking_task(NULL); video_task(NULL); } #endif } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ #define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8) static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1}; static unsigned tx_busy = 0; static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE}; // For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. // To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" static struct { uint32_t size; uint8_t const *buffer; } const framebuf_mjpeg[] = { {sizeof(color_bar_0_jpg), color_bar_0_jpg}, {sizeof(color_bar_1_jpg), color_bar_1_jpg}, {sizeof(color_bar_2_jpg), color_bar_2_jpg}, {sizeof(color_bar_3_jpg), color_bar_3_jpg}, {sizeof(color_bar_4_jpg), color_bar_4_jpg}, {sizeof(color_bar_5_jpg), color_bar_5_jpg}, {sizeof(color_bar_6_jpg), color_bar_6_jpg}, {sizeof(color_bar_7_jpg), color_bar_7_jpg}, }; #if !defined(CFG_EXAMPLE_VIDEO_READONLY) // YUY2 frame buffer static uint8_t framebuf_yuy2[FRAMEBUF_SIZE]; static void fill_color_bar(uint8_t* buffer, unsigned start_position) { /* EBU color bars: https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { /* Y, U, Y, V */ { 235, 128, 235, 128}, /* 100% White */ { 219, 16, 219, 138}, /* Yellow */ { 188, 154, 188, 16}, /* Cyan */ { 173, 42, 173, 26}, /* Green */ { 78, 214, 78, 230}, /* Magenta */ { 63, 102, 63, 240}, /* Red */ { 32, 240, 32, 118}, /* Blue */ { 16, 128, 16, 128}, /* Black */ }; uint8_t* p; /* Generate the 1st line */ uint8_t* end = &buffer[FRAME_WIDTH * 2]; unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); p = &buffer[idx * 4]; for (unsigned i = 0; i < 8; ++i) { for (int j = 0; j < FRAME_WIDTH / (2 * 8); ++j) { memcpy(p, &bar_color[i], 4); p += 4; if (end <= p) { p = buffer; } } } /* Duplicate the 1st line to the others */ p = &buffer[FRAME_WIDTH * 2]; for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { memcpy(p, buffer, FRAME_WIDTH * 2); p += FRAME_WIDTH * 2; } } #endif static size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, void **fb) { uint32_t idx = ctl_idx + stm_idx; if (idx == 0) { // stream 0 use uncompressed YUY2 frame #if defined(CFG_EXAMPLE_VIDEO_READONLY) *fb = (void*)(uintptr_t ) &framebuf_yuy2_readonly[(fnum % (FRAME_WIDTH / 2)) * 4]; #else fill_color_bar(framebuf_yuy2, frame_num[idx]); *fb = framebuf_yuy2; #endif return FRAMEBUF_SIZE; }else { // stream 1 use MJPEG frame size_t const bar_id = fnum & 0x7; *fb = (void*)(uintptr_t) framebuf_mjpeg[bar_id].buffer; return framebuf_mjpeg[bar_id].size; } } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ static void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, }; static unsigned already_sent = 0; uint32_t idx = ctl_idx + stm_idx; if (!tud_video_n_streaming(ctl_idx, stm_idx)) { already_sent &= ~(1u << idx); frame_num[idx] = 0; return; } void* fp; size_t fb_size; if (!(already_sent & (1u << idx))) { already_sent |= 1u << idx; tx_busy |= 1u << idx; start_ms[idx] = tusb_time_millis_api(); fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); } unsigned cur = tusb_time_millis_api(); if (cur - start_ms[idx] < interval_ms[idx]) return; // not enough time if (tx_busy & (1u << idx)) return; start_ms[idx] += interval_ms[idx]; tx_busy |= 1u << idx; fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); } void video_task(void* param) { (void) param; while(1) { video_send_frame(0, 0); video_send_frame(1, 0); #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(interval_ms[0] / portTICK_PERIOD_MS); #else return; #endif } } void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { uint32_t idx = ctl_idx + stm_idx; tx_busy &= ~(1u << idx); /* flip buffer */ ++frame_num[idx]; } int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const* parameters) { uint32_t idx = ctl_idx + stm_idx; /* convert unit to ms from 100 ns */ interval_ms[idx] = parameters->dwFrameInterval / 10000; return VIDEO_ERROR_NONE; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void* param) { (void) param; static uint32_t start_ms = 0; static bool led_state = false; while (1) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time #endif start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } } //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { main(); } #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t video_stack[VIDEO_STACK_SIZE]; StaticTask_t video_taskdef; #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tud_task(); } } void freertos_init(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } #endif ================================================ FILE: examples/device/video_capture_2ch/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// // The number of video control interfaces #define CFG_TUD_VIDEO 2 // The number of video streaming interfaces #define CFG_TUD_VIDEO_STREAMING 2 // video streaming endpoint buffer size #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface #define CFG_TUD_VIDEO_STREAMING_BULK 1 //#define CFG_EXAMPLE_VIDEO_READONLY //#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG #define CFG_TUD_VIDEO_LOG_LEVEL 1 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/video_capture_2ch/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(AUDIO, 4) | PID_MAP(VIDEO, 5) | PID_MAP(VENDOR, 6) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_UVC_CONTROL_1, STRID_UVC_STREAMING_1, STRID_UVC_CONTROL_2, STRID_UVC_STREAMING_2, }; // array of pointer to string descriptors char const* string_desc_arr[] = { (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "UVC Control 1", // 4: UVC Interface 1 "UVC Streaming 1", // 5: UVC Interface 1 "UVC Control 2", // 6: UVC Interface 2 "UVC Streaming 2", // 7: UVC Interface 2 }; //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for Video // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = STRID_MANUFACTURER, .iProduct = STRID_PRODUCT, .iSerialNumber = STRID_SERIAL, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const* tud_descriptor_device_cb(void) { return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ /* Time stamp base clock. It is a deprecated parameter. */ #define UVC_CLOCK_FREQUENCY 27000000 /* video capture path */ #define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 #define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 enum { ITF_NUM_VIDEO_CONTROL_1, ITF_NUM_VIDEO_STREAMING_1, ITF_NUM_VIDEO_CONTROL_2, ITF_NUM_VIDEO_STREAMING_2, ITF_NUM_TOTAL }; #define EPNUM_VIDEO_IN_1 0x81 #define EPNUM_VIDEO_IN_2 0x82 #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define USE_MJPEG 1 #else #define USE_MJPEG 0 #endif #define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_control_header_1itf_t header; tusb_desc_video_control_camera_terminal_t camera_terminal; tusb_desc_video_control_output_terminal_t output_terminal; } uvc_control_desc_t; /* Windows support YUY2 and NV12 * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; tusb_desc_video_format_uncompressed_t format; tusb_desc_video_frame_uncompressed_continuous_t frame; tusb_desc_video_streaming_color_matching_t color; #if USE_ISO_STREAMING // For ISO streaming, USB spec requires to alternate interface tusb_desc_interface_t itf_alt; #endif tusb_desc_endpoint_t ep; } uvc_streaming_yuy2_desc_t; typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; tusb_desc_video_format_mjpeg_t format; tusb_desc_video_frame_mjpeg_continuous_t frame; tusb_desc_video_streaming_color_matching_t color; #if USE_ISO_STREAMING // For ISO streaming, USB spec requires to alternate interface tusb_desc_interface_t itf_alt; #endif tusb_desc_endpoint_t ep; } uvc_streaming_mpeg_desc_t; typedef struct TU_ATTR_PACKED { tusb_desc_configuration_t config; struct TU_ATTR_PACKED { tusb_desc_interface_assoc_t iad; uvc_control_desc_t video_control; uvc_streaming_yuy2_desc_t video_streaming; } uvc_yuy2; struct TU_ATTR_PACKED { tusb_desc_interface_assoc_t iad; uvc_control_desc_t video_control; uvc_streaming_mpeg_desc_t video_streaming; } uvc_mpeg; } uvc_cfg_desc_t; const uvc_cfg_desc_t desc_fs_configuration = { .config = { .bLength = sizeof(tusb_desc_configuration_t), .bDescriptorType = TUSB_DESC_CONFIGURATION, .wTotalLength = sizeof(uvc_cfg_desc_t), .bNumInterfaces = ITF_NUM_TOTAL, .bConfigurationValue = 1, .iConfiguration = 0, .bmAttributes = TU_BIT(7), .bMaxPower = 100 / 2 }, //------------- Stream 0: YUY2 -------------// .uvc_yuy2 = { .iad = { .bLength = sizeof(tusb_desc_interface_assoc_t), .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, .bFirstInterface = ITF_NUM_VIDEO_CONTROL_1, .bInterfaceCount = 2, .bFunctionClass = TUSB_CLASS_VIDEO, .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, .iFunction = 0 }, .video_control = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_CONTROL_1 }, .header = { .bLength = sizeof(tusb_desc_video_control_header_1itf_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, .bcdUVC = VIDEO_BCD_1_50, .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only .dwClockFrequency = UVC_CLOCK_FREQUENCY, .bInCollection = 1, .baInterfaceNr = {ITF_NUM_VIDEO_STREAMING_1} }, .camera_terminal = { .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, .wTerminalType = VIDEO_ITT_CAMERA, .bAssocTerminal = 0, .iTerminal = 0, .wObjectiveFocalLengthMin = 0, .wObjectiveFocalLengthMax = 0, .wOcularFocalLength = 0, .bControlSize = 3, .bmControls = {0, 0, 0} }, .output_terminal = { .bLength = sizeof(tusb_desc_video_control_output_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .wTerminalType = VIDEO_TT_STREAMING, .bAssocTerminal = 0, .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, .iTerminal = 0 } }, .video_streaming = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, .bAlternateSetting = 0, .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING_1 }, .header = { .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, .bNumFormats = 1, .wTotalLength = sizeof(uvc_streaming_yuy2_desc_t) - sizeof(tusb_desc_interface_t) - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0), // CS VS descriptors only .bEndpointAddress = EPNUM_VIDEO_IN_1, .bmInfo = 0, .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .bStillCaptureMethod = 0, .bTriggerSupport = 0, .bTriggerUsage = 0, .bControlSize = 1, .bmaControls = {0} }, .format = { .bLength = sizeof(tusb_desc_video_format_uncompressed_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, .bFormatIndex = 1, // 1-based index .bNumFrameDescriptors = 1, .guidFormat = {TUD_VIDEO_GUID_YUY2}, .bBitsPerPixel = 16, .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, .bmInterlaceFlags = 0, .bCopyProtect = 0 }, .frame = { .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, .bFrameIndex = 1, // 1-based index .bmCapabilities = 0, .wWidth = FRAME_WIDTH, .wHeight = FRAME_HEIGHT, .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, .dwDefaultFrameInterval = 10000000 / FRAME_RATE, .bFrameIntervalType = 0, // continuous .dwFrameInterval = { 10000000 / FRAME_RATE, // min 10000000, // max 10000000 / FRAME_RATE // step } }, .color = { .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M }, #if USE_ISO_STREAMING .itf_alt = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, .bAlternateSetting = 1, .bNumEndpoints = 1, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING_1 }, #endif .ep = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = EPNUM_VIDEO_IN_1, .bmAttributes = { .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous }, .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, .bInterval = 1 } } }, //------------- Stream 1: MPEG -------------// .uvc_mpeg = { .iad = { .bLength = sizeof(tusb_desc_interface_assoc_t), .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, .bFirstInterface = ITF_NUM_VIDEO_CONTROL_2, .bInterfaceCount = 2, .bFunctionClass = TUSB_CLASS_VIDEO, .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, .iFunction = 0 }, .video_control = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_CONTROL_2 }, .header = { .bLength = sizeof(tusb_desc_video_control_header_1itf_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, .bcdUVC = VIDEO_BCD_1_50, .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only .dwClockFrequency = UVC_CLOCK_FREQUENCY, .bInCollection = 1, .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 } }, .camera_terminal = { .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, .wTerminalType = VIDEO_ITT_CAMERA, .bAssocTerminal = 0, .iTerminal = 0, .wObjectiveFocalLengthMin = 0, .wObjectiveFocalLengthMax = 0, .wOcularFocalLength = 0, .bControlSize = 3, .bmControls = { 0, 0, 0 } }, .output_terminal = { .bLength = sizeof(tusb_desc_video_control_output_terminal_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .wTerminalType = VIDEO_TT_STREAMING, .bAssocTerminal = 0, .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, .iTerminal = 0 } }, .video_streaming = { .itf = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, .bAlternateSetting = 0, .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING_2 }, .header = { .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, .bNumFormats = 1, .wTotalLength = sizeof(uvc_streaming_mpeg_desc_t) - sizeof(tusb_desc_interface_t) - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only .bEndpointAddress = EPNUM_VIDEO_IN_2, .bmInfo = 0, .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, .bStillCaptureMethod = 0, .bTriggerSupport = 0, .bTriggerUsage = 0, .bControlSize = 1, .bmaControls = { 0 } }, .format = { .bLength = sizeof(tusb_desc_video_format_mjpeg_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, .bFormatIndex = 1, // 1-based index .bNumFrameDescriptors = 1, .bmFlags = 0, .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, .bmInterlaceFlags = 0, .bCopyProtect = 0 }, .frame = { .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, .bFrameIndex = 1, // 1-based index .bmCapabilities = 0, .wWidth = FRAME_WIDTH, .wHeight = FRAME_HEIGHT, .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, .dwDefaultFrameInterval = 10000000 / FRAME_RATE, .bFrameIntervalType = 0, // continuous .dwFrameInterval = { 10000000 / FRAME_RATE, // min 10000000, // max 10000000 / FRAME_RATE // step } }, .color = { .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M }, #if USE_ISO_STREAMING .itf_alt = { .bLength = sizeof(tusb_desc_interface_t), .bDescriptorType = TUSB_DESC_INTERFACE, .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, .bAlternateSetting = 1, .bNumEndpoints = 1, .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, .iInterface = STRID_UVC_STREAMING_2 }, #endif .ep = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = EPNUM_VIDEO_IN_2, .bmAttributes = { .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous }, .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, .bInterval = 1 } } } }; #if TUD_OPT_HIGH_SPEED uvc_cfg_desc_t desc_hs_configuration; static uint8_t * get_hs_configuration_desc(void) { static bool init = false; if (!init) { desc_hs_configuration = desc_fs_configuration; // change endpoint bulk size to 512 if bulk streaming if (CFG_TUD_VIDEO_STREAMING_BULK) { desc_hs_configuration.uvc_yuy2.video_streaming.ep.wMaxPacketSize = 512; desc_hs_configuration.uvc_mpeg.video_streaming.ep.wMaxPacketSize = 512; } } init = true; return (uint8_t *) &desc_hs_configuration; } // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa if (tud_speed_get() == TUSB_SPEED_HIGH) { return (uint8_t const*) &desc_fs_configuration; } else { return get_hs_configuration_desc(); } } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if (tud_speed_get() == TUSB_SPEED_HIGH) { return get_hs_configuration_desc(); } else #endif { return (uint8_t const*) &desc_fs_configuration; } } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) return NULL; const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/video_capture_2ch/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenbreg * Copyright (c) 2021 Koji KITAYAMA * * 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. * */ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ #define FRAME_WIDTH 128 #define FRAME_HEIGHT 96 #define FRAME_RATE 10 // NOTE: descriptor template is not used but leave here as reference #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ /* Interface 1, Alternate 1 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + 7/* Endpoint */\ ) #define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ /* control */\ + TUD_VIDEO_DESC_STD_VC_LEN\ + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ /* Interface 1, Alternate 0 */\ + TUD_VIDEO_DESC_STD_VS_LEN\ + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + 7/* Endpoint */\ ) /* Windows support YUY2 and NV12 * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ #define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ /* EP */ \ TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ /* Video stream format */ \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* EP */ \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) #endif ================================================ FILE: examples/device/webusb_serial/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(webusb_serial C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/device/webusb_serial/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/device/webusb_serial/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/device/webusb_serial/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/device/webusb_serial/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* This example demonstrates WebUSB as web serial with browser with WebUSB support (e.g Chrome). * After enumerated successfully, browser will pop-up notification * with URL to landing page, click on it to test * - Click "Connect" and select device, When connected the on-board LED will litted up. * - Any charters received from either webusb/Serial will be echo back to webusb and Serial * * Note: * - The WebUSB landing page notification is currently disabled in Chrome * on Windows due to Chromium issue 656702 (https://crbug.com/656702). You have to * go to landing page (below) to test * * - On Windows 7 and prior: You need to use Zadig tool to manually bind the * WebUSB interface with the WinUSB driver for Chrome to access. From windows 8 and 10, this * is done automatically by firmware. * * - On Linux/macOS, udev permission may need to be updated by * - copying '/examples/device/99-tinyusb.rules' file to /etc/udev/rules.d/ then * - run 'sudo udevadm control --reload-rules && sudo udevadm trigger' */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, BLINK_ALWAYS_ON = UINT32_MAX, BLINK_ALWAYS_OFF = 0 }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; #define URL "example.tinyusb.org/webusb-serial/index.html" const tusb_desc_webusb_url_t desc_url = { .bLength = 3 + sizeof(URL) - 1, .bDescriptorType = 3, // WEBUSB URL type .bScheme = 1, // 0: http, 1: https .url = URL }; static bool web_serial_connected = false; //------------- prototypes -------------// void led_blinking_task(void); void cdc_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task tud_cdc_write_flush(); led_blinking_task(); } } // send characters to both CDC and WebUSB static void echo_all(const uint8_t buf[], uint32_t count) { // echo to web serial if (web_serial_connected) { tud_vendor_write(buf, count); tud_vendor_write_flush(); } // echo to cdc if (tud_cdc_connected()) { tud_cdc_write(buf, count); } } //--------------------------------------------------------------------+ // Device callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // WebUSB use vendor class //--------------------------------------------------------------------+ // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { // nothing to with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) { return true; } switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: switch (request->bRequest) { case VENDOR_REQUEST_WEBUSB: // match vendor request in BOS descriptor // Get landing page url return tud_control_xfer(rhport, request, (void*)(uintptr_t)&desc_url, desc_url.bLength); case VENDOR_REQUEST_MICROSOFT: if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor uint16_t total_len; memcpy(&total_len, desc_ms_os_20 + 8, 2); return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len); } else { return false; } default: break; } break; case TUSB_REQ_TYPE_CLASS: if (request->bRequest == 0x22) { // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to connect and disconnect. web_serial_connected = (request->wValue != 0); // Always lit LED if connected if (web_serial_connected) { board_led_write(true); blink_interval_ms = BLINK_ALWAYS_ON; tud_vendor_write_str("\r\nWebUSB interface connected\r\n"); tud_vendor_write_flush(); } else { tud_vendor_write_clear(); // anything left in the buffer is now thrown out blink_interval_ms = BLINK_MOUNTED; } // response with status OK return tud_control_status(rhport, request); } break; default: break; } // stall unknown request return false; } void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) { (void)idx; (void)buffer; (void)bufsize; while (tud_vendor_available()) { uint8_t buf[64]; const uint32_t count = tud_vendor_read(buf, sizeof(buf)); echo_all(buf, count); } } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ // Invoked when cdc when line state changed e.g connected/disconnected void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void)itf; // connected if (dtr && rts) { // print initial message when connected tud_cdc_write_str("\r\nTinyUSB WebUSB device example\r\n"); } } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t idx) { (void)idx; while (tud_cdc_available()) { uint8_t buf[64]; const uint32_t count = tud_cdc_read(buf, sizeof(buf)); echo_all(buf, count); // echo back to both web serial and cdc } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/device/webusb_serial/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 1 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Vendor FIFO size of TX and RX // If zero: vendor endpoints will not be buffered #define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/device/webusb_serial/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "usb_descriptors.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0210, // at least 2.1 or 3.x for BOS & webUSB // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_VENDOR, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_VENDOR_OUT 0x05 #define EPNUM_VENDOR_IN 0x85 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x81 #define EPNUM_VENDOR_OUT 0x05 #define EPNUM_VENDOR_IN 0x84 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #define EPNUM_VENDOR_OUT 0x04 #define EPNUM_VENDOR_IN 0x85 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define EPNUM_VENDOR_OUT 0x03 #define EPNUM_VENDOR_IN 0x83 #endif uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & IN address, EP size TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 64) }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations return desc_configuration; } //--------------------------------------------------------------------+ // BOS Descriptor //--------------------------------------------------------------------+ /* Microsoft OS 2.0 registry property descriptor Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx device should create DeviceInterfaceGUIDs. It can be done by driver and in case of real PnP solution device should expose MS "Microsoft OS 2.0 registry property descriptor". Such descriptor can insert any record into Windows registry per device/configuration/interface. In our case it will insert "DeviceInterfaceGUIDs" multistring property. GUID is freshly generated and should be OK to use. https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) #define MS_OS_20_DESC_LEN 0xB2 // BOS Descriptor is required for webUSB uint8_t const desc_bos[] = { // total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2), // Vendor Code, iLandingPage TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1), // Microsoft OS 2.0 descriptor TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT) }; uint8_t const * tud_descriptor_bos_cb(void) { return desc_bos; } uint8_t const desc_ms_os_20[] = { // Set header: length, type, windows version, total length U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), // Configuration subset header: length, type, configuration index, reserved, configuration total length U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A), // Function Subset header: length, type, first interface, reserved, subset length U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_VENDOR, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08), // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible // MS OS 2.0 Registry property descriptor: length, type U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, U16_TO_U8S_LE(0x0050), // wPropertyDataLength //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”. '{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00, '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, '8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 }; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface "TinyUSB WebUSB" // 5: Vendor Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch ( index ) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if ( chr_count > max_count ) chr_count = max_count; // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/device/webusb_serial/src/usb_descriptors.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. */ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ enum { VENDOR_REQUEST_WEBUSB = 1, VENDOR_REQUEST_MICROSOFT = 2 }; extern uint8_t const desc_ms_os_20[]; #endif /* USB_DESCRIPTORS_H_ */ ================================================ FILE: examples/device/webusb_serial/website/application.js ================================================ 'use strict'; (async () => { // bind to the html const uiBody = document.body; const uiToggleThemeBtn = document.getElementById('theme-toggle'); const uiConnectWebUsbSerialBtn = document.getElementById('connect_webusb_serial_btn'); const uiConnectSerialBtn = document.getElementById('connect_serial_btn'); const uiDisconnectBtn = document.getElementById('disconnect_btn'); const uiNewlineModeSelect = document.getElementById('newline_mode_select'); const uiAutoReconnectCheckbox = document.getElementById('auto_reconnect_checkbox'); const uiForgetDeviceBtn = document.getElementById('forget_device_btn'); const uiForgetAllDevicesBtn = document.getElementById('forget_all_devices_btn'); const uiResetAllBtn = document.getElementById('reset_all_btn'); const uiCopyOutputBtn = document.getElementById('copy_output_btn'); const uiDownloadOutputCsvBtn = document.getElementById('download_csv_output_btn'); const uiStatusSpan = document.getElementById('status_span'); const uiCommandHistoryClearBtn = document.getElementById('clear_command_history_btn'); const uiCommandHistoryScrollbox = document.getElementById('command_history_scrollbox'); const uiCommandLineInput = document.getElementById('command_line_input'); const uiSendModeBtn = document.getElementById('send_mode_btn'); const uiReceivedDataClearBtn = document.getElementById('clear_received_data_btn'); const uiReceivedDataScrollbox = document.getElementById('received_data_scrollbox'); const uiNearTheBottomThreshold = 100; // pixels from the bottom to trigger scroll const maxCommandHistoryLength = 123; // max number of command history entries const maxReceivedDataLength = 8192 / 8; // max number of received data entries const THEME_STATES = ['auto', 'light', 'dark']; /// https://stackoverflow.com/a/6234804/4479969 const escapeHtml = unsafe => { if (typeof unsafe !== 'string') unsafe = String(unsafe); return unsafe .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); }; class CommandHistoryEntry { constructor(text) { this.text = text; this.time = Date.now(); this.count = 1; } } class ReceivedDataEntry { constructor(text) { this.text = text; this.time = Date.now(); this.terminated = false; } } class Application { constructor() { this.currentPort = null; this.textEncoder = new TextEncoder(); this.textDecoder = new TextDecoder(); this.reconnectTimeoutId = null; this.commandHistory = []; this.uiCommandHistoryIndex = -1; this.receivedData = []; // bind the UI elements uiToggleThemeBtn.addEventListener('click', () => this.toggleTheme()); // Listener for OS Theme Changes window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { const currentPreference = localStorage.getItem('theme') || 'auto'; // Only act if the user is in automatic mode if (currentPreference === 'auto') { this.setTheme('auto'); } }); uiConnectWebUsbSerialBtn.addEventListener('click', () => this.connectWebUsbSerialPort()); uiConnectSerialBtn.addEventListener('click', () => this.connectSerialPort()); uiDisconnectBtn.addEventListener('click', () => this.disconnectPort()); uiNewlineModeSelect.addEventListener('change', () => this.setNewlineMode()); uiAutoReconnectCheckbox.addEventListener('change', () => this.autoReconnectChanged()); uiForgetDeviceBtn.addEventListener('click', () => this.forgetPort()); uiForgetAllDevicesBtn.addEventListener('click', () => this.forgetAllPorts()); uiResetAllBtn.addEventListener('click', () => this.resetAll()); uiCopyOutputBtn.addEventListener('click', () => this.copyOutput()); uiDownloadOutputCsvBtn.addEventListener('click', () => this.downloadOutputCsv()); uiCommandHistoryClearBtn.addEventListener('click', () => this.clearCommandHistory()); uiCommandLineInput.addEventListener('keydown', (e) => this.handleCommandLineInput(e)); uiSendModeBtn.addEventListener('click', () => this.toggleSendMode()); uiReceivedDataClearBtn.addEventListener('click', () => this.clearReceivedData()); window.addEventListener('beforeunload', () => this.beforeUnloadHandler()); // restore state from localStorage try { this.restoreState(); } catch (error) { console.error('Failed to restore state from localStorage', error); this.resetAll(); this.restoreState(); } this.updateUIConnectionState(); this.connectWebUsbSerialPort(true); } beforeUnloadHandler() { // Save the scroll position of the command history and received data localStorage.setItem('commandHistoryScrollTop', uiCommandHistoryScrollbox.scrollTop); localStorage.setItem('receivedDataScrollTop', uiReceivedDataScrollbox.scrollTop); } restoreState() { // Restore theme choice const savedTheme = localStorage.getItem('theme'); if (savedTheme) { this.setTheme(savedTheme); } // Restore command history let savedCommandHistory = JSON.parse(localStorage.getItem('commandHistory') || '[]'); for (const cmd of savedCommandHistory) { this.addCommandToHistoryUI(cmd); } // Restore scroll position for command history const commandHistoryScrollTop = localStorage.getItem('commandHistoryScrollTop'); if (commandHistoryScrollTop) { uiCommandHistoryScrollbox.scrollTop = parseInt(commandHistoryScrollTop, 10); } // Restore received data let savedReceivedData = JSON.parse(localStorage.getItem('receivedData') || '[]'); for (let line of savedReceivedData) { line.terminated = true; this.addReceivedDataEntryUI(line); } // Restore scroll position for received data const receivedDataScrollTop = localStorage.getItem('receivedDataScrollTop'); if (receivedDataScrollTop) { uiReceivedDataScrollbox.scrollTop = parseInt(receivedDataScrollTop, 10); } this.sendMode = localStorage.getItem('sendMode') || 'command'; this.setSendMode(this.sendMode); uiAutoReconnectCheckbox.checked = !(localStorage.getItem('autoReconnect') === 'false'); let savedNewlineMode = localStorage.getItem('newlineMode'); if (savedNewlineMode) { uiNewlineModeSelect.value = savedNewlineMode; } } setTheme(theme) { const modeName = theme.charAt(0).toUpperCase() + theme.slice(1); uiToggleThemeBtn.textContent = `Theme: ${modeName}`; if (theme === 'auto') { // In auto mode, we rely on the OS preference. // We check the media query and add/remove the class accordingly. const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (prefersDark) { uiBody.classList.add('dark-mode'); } else { uiBody.classList.remove('dark-mode'); } } else if (theme === 'light') { // Force light mode by removing the class. uiBody.classList.remove('dark-mode'); } else if (theme === 'dark') { // Force dark mode by adding the class. uiBody.classList.add('dark-mode'); } // Save the theme to localStorage localStorage.setItem('theme', theme); } toggleTheme() { const currentTheme = localStorage.getItem('theme') || 'auto'; const nextThemeIndex = (THEME_STATES.indexOf(currentTheme) + 1) % THEME_STATES.length; const nextTheme = THEME_STATES[nextThemeIndex]; this.setTheme(nextTheme); } addCommandToHistoryUI(commandHistoryEntry) { let commandHistoryEntryBtn = null; let lastCommandMatched = false; if (this.commandHistory.length > 0) { let lastCommandEntry = this.commandHistory[this.commandHistory.length - 1]; if (lastCommandEntry.text === commandHistoryEntry.text) { lastCommandEntry.count++; lastCommandEntry.time = Date.now(); lastCommandMatched = true; // Update the last command entry commandHistoryEntryBtn = uiCommandHistoryScrollbox.lastElementChild; let time_str = new Date(lastCommandEntry.time).toLocaleString(); commandHistoryEntryBtn.querySelector('.command-history-entry-time').textContent = time_str; commandHistoryEntryBtn.querySelector('.command-history-entry-text').textContent = lastCommandEntry.text; commandHistoryEntryBtn.querySelector('.command-history-entry-count').textContent = '×' + lastCommandEntry.count; } } if (!lastCommandMatched) { this.commandHistory.push(commandHistoryEntry); // Create a new command history entry commandHistoryEntryBtn = document.createElement('button'); commandHistoryEntryBtn.className = 'command-history-entry'; commandHistoryEntryBtn.type = 'button'; let time_str = new Date(commandHistoryEntry.time).toLocaleString(); commandHistoryEntryBtn.innerHTML = ` ${escapeHtml(time_str)} ${escapeHtml(commandHistoryEntry.text)} ×${escapeHtml(commandHistoryEntry.count)} `; commandHistoryEntryBtn.addEventListener('click', () => { if (uiCommandLineInput.disabled) return; uiCommandLineInput.value = commandHistoryEntry.text; uiCommandLineInput.focus(); }); uiCommandHistoryScrollbox.appendChild(commandHistoryEntryBtn); } // Limit the command history length while (this.commandHistory.length > maxCommandHistoryLength) { this.commandHistory.shift(); uiCommandHistoryScrollbox.removeChild(uiCommandHistoryScrollbox.firstElementChild); } } appendNewCommandToHistory(commandHistoryEntry) { const wasNearBottom = this.isNearBottom(uiCommandHistoryScrollbox); this.addCommandToHistoryUI(commandHistoryEntry); // Save the command history to localStorage localStorage.setItem('commandHistory', JSON.stringify(this.commandHistory)); // Scroll to the new entry if near the bottom if (wasNearBottom) { this.scrollToBottom(uiCommandHistoryScrollbox); } } clearCommandHistory() { this.commandHistory = []; uiCommandHistoryScrollbox.textContent = ''; localStorage.removeItem('commandHistory'); this.setStatus('Command history cleared', 'info'); } isNearBottom(container) { return container.scrollHeight - container.scrollTop <= container.clientHeight + uiNearTheBottomThreshold; } scrollToBottom(container) { requestAnimationFrame(() => { container.scrollTop = container.scrollHeight; }); } addReceivedDataEntryUI(receivedDataEntry) { let newReceivedDataEntries = []; let updateLastReceivedDataEntry = false; if (this.receivedData.length <= 0) { newReceivedDataEntries.push(receivedDataEntry); } else { let lastReceivedDataEntry = this.receivedData[this.receivedData.length - 1]; // Check if the last entry is terminated if (lastReceivedDataEntry.terminated) { newReceivedDataEntries.push(receivedDataEntry); } else { if (!lastReceivedDataEntry.terminated) { updateLastReceivedDataEntry = true; this.receivedData.pop(); receivedDataEntry.text = lastReceivedDataEntry.text + receivedDataEntry.text; } // split the text into lines let lines = receivedDataEntry.text.split(/\r?\n/); // check if the last line is terminated by checking if it ends with an empty string let lastLineTerminated = lines[lines.length - 1] === ''; if (lastLineTerminated) { lines.pop(); // remove the last empty line } // create new entries for each line for (let i = 0; i < lines.length; i++) { let line = lines[i]; let entry = new ReceivedDataEntry(line); if (i === lines.length - 1) { entry.terminated = lastLineTerminated; } else { entry.terminated = true; } newReceivedDataEntries.push(entry); } // if the last line is terminated, modify the last entry if (lastLineTerminated) { newReceivedDataEntries[newReceivedDataEntries.length - 1].terminated = true; } else { newReceivedDataEntries[newReceivedDataEntries.length - 1].terminated = false; } } } this.receivedData.push(...newReceivedDataEntries); if (updateLastReceivedDataEntry) { // update the rendering of the last entry let lastReceivedDataEntryBtn = uiReceivedDataScrollbox.lastElementChild; lastReceivedDataEntryBtn.querySelector('.received-data-entry-text').textContent = newReceivedDataEntries[0].text; lastReceivedDataEntryBtn.querySelector('.received-data-entry-time').textContent = new Date(newReceivedDataEntries[0].time).toLocaleString(); newReceivedDataEntries.shift(); } // render the new entries let documentFragment = document.createDocumentFragment(); for (const entry of newReceivedDataEntries) { let receivedDataEntryBtn = document.createElement('div'); receivedDataEntryBtn.className = 'received-data-entry'; receivedDataEntryBtn.innerHTML = ` ${escapeHtml(new Date(entry.time).toLocaleString())} ${escapeHtml(entry.text)} `; documentFragment.appendChild(receivedDataEntryBtn); } uiReceivedDataScrollbox.appendChild(documentFragment); // Limit the received data length while (this.receivedData.length > maxReceivedDataLength) { this.receivedData.shift(); uiReceivedDataScrollbox.removeChild(uiReceivedDataScrollbox.firstElementChild); } } appendNewReceivedData(receivedDataEntry) { const wasNearBottom = this.isNearBottom(uiReceivedDataScrollbox); this.addReceivedDataEntryUI(receivedDataEntry); // Save the received data to localStorage localStorage.setItem('receivedData', JSON.stringify(this.receivedData)); // Scroll to the new entry if near the bottom if (wasNearBottom) { this.scrollToBottom(uiReceivedDataScrollbox); } } clearReceivedData() { this.receivedData = []; uiReceivedDataScrollbox.textContent = ''; localStorage.removeItem('receivedData'); this.setStatus('Received data cleared', 'info'); } setStatus(msg, level = 'info') { console.error(msg); uiStatusSpan.textContent = msg; uiStatusSpan.className = 'status status-' + level; } /// force_connected is used to instantly change the UI to the connected state while the device is still connecting /// Otherwise we would have to wait for the connection to be established. /// This can take until the device sends the first data packet. updateUIConnectionState(force_connected = false) { if (force_connected || (this.currentPort && this.currentPort.isConnected)) { uiConnectWebUsbSerialBtn.style.display = 'none'; uiConnectSerialBtn.style.display = 'none'; uiDisconnectBtn.style.display = 'block'; uiCommandLineInput.disabled = false; if (this.currentPort instanceof SerialPort) { uiDisconnectBtn.textContent = 'Disconnect from WebSerial'; } else if (this.currentPort instanceof WebUsbSerialPort) { uiDisconnectBtn.textContent = 'Disconnect from WebUSB'; } else { uiDisconnectBtn.textContent = 'Disconnect'; } } else { if (serial.isWebUsbSupported()) { uiConnectWebUsbSerialBtn.style.display = 'block'; } if (serial.isWebSerialSupported()) { uiConnectSerialBtn.style.display = 'block'; } if (!serial.isWebUsbSupported() && !serial.isWebSerialSupported()) { this.setStatus('Your browser does not support WebUSB or WebSerial', 'error'); } uiDisconnectBtn.style.display = 'none'; uiCommandLineInput.disabled = true; uiCommandLineInput.value = ''; uiCommandLineInput.blur(); } } async disconnectPort() { this.stopAutoReconnect(); if (!this.currentPort) { this.updateUIConnectionState(); return; }; try { await this.currentPort.disconnect(); this.setStatus('Disconnected', 'info'); } catch (error) { this.setStatus(`Disconnect error: ${error.message}`, 'error'); } this.updateUIConnectionState(); } async onReceive(dataView) { this.updateUIConnectionState(); let text = this.textDecoder.decode(dataView); let receivedDataEntry = new ReceivedDataEntry(text); this.appendNewReceivedData(receivedDataEntry); } async onReceiveError(error) { this.setStatus(`Read error: ${error.message}`, 'error'); await this.disconnectPort(); // Start auto reconnect on error if enabled this.tryAutoReconnect(); } async connectSerialPort() { if (!serial.isWebSerialSupported()) { this.setStatus('Serial not supported on this browser', 'error'); return; } try { this.setStatus('Requesting device...', 'info'); this.currentPort = await serial.requestSerialPort(); this.updateUIConnectionState(true); this.currentPort.onReceiveError = error => this.onReceiveError(error); this.currentPort.onReceive = dataView => this.onReceive(dataView); await this.currentPort.connect(); this.setStatus('Connected', 'info'); } catch (error) { this.setStatus(`Connection failed: ${error.message}`, 'error'); if (this.currentPort) { await this.currentPort.forgetDevice(); this.currentPort = null; } } finally { this.updateUIConnectionState(); } } async connectWebUsbSerialPort(initial = false) { if (!serial.isWebUsbSupported()) { this.setStatus('WebUSB not supported on this browser', 'error'); return; } try { let first_time_connection = false; let grantedDevices = await serial.getWebUsbSerialPorts(); if (initial) { if (!uiAutoReconnectCheckbox.checked || grantedDevices.length === 0) { return false; } // Connect to the device that was saved to localStorage otherwise use the first one const savedPortInfo = JSON.parse(localStorage.getItem('webUSBSerialPort')); if (savedPortInfo) { for (const device of grantedDevices) { if (device._device.vendorId === savedPortInfo.vendorId && device._device.productId === savedPortInfo.productId) { this.currentPort = device; break; } } } if (!this.currentPort) { this.currentPort = grantedDevices[0]; } this.setStatus('Connecting to first device...', 'info'); } else { // Prompt the user to select a device this.setStatus('Requesting device...', 'info'); this.currentPort = await serial.requestWebUsbSerialPort(); first_time_connection = true; } this.currentPort.onReceiveError = error => this.onReceiveError(error); this.currentPort.onReceive = dataView => this.onReceive(dataView); try { this.updateUIConnectionState(true); await this.currentPort.connect(); // save the port to localStorage const portInfo = { vendorId: this.currentPort._device.vendorId, productId: this.currentPort._device.productId, } localStorage.setItem('webUSBSerialPort', JSON.stringify(portInfo)); this.setStatus('Connected', 'info'); uiCommandLineInput.focus(); } catch (error) { if (first_time_connection) { // Forget the device if a first time connection fails await this.currentPort.forgetDevice(); this.currentPort = null; } throw error; } finally { this.updateUIConnectionState(); } this.updateUIConnectionState(); } catch (error) { this.setStatus(`Connection failed: ${error.message}`, 'error'); } } async reconnectPort() { if (this.currentPort) { this.setStatus('Reconnecting...', 'info'); try { await this.currentPort.connect(); this.setStatus('Reconnected', 'info'); } catch (error) { this.setStatus(`Reconnect failed: ${error.message}`, 'error'); } finally { this.updateUIConnectionState(); } } this.updateUIConnectionState(); } async forgetPort() { this.stopAutoReconnect(); if (this.currentPort) { await this.currentPort.forgetDevice(); this.currentPort = null; this.setStatus('Device forgotten', 'info'); } else { this.setStatus('No device to forget', 'error'); } this.updateUIConnectionState(); } async forgetAllPorts() { this.stopAutoReconnect(); await this.forgetPort(); if (serial.isWebUsbSupported()) { let ports = await serial.getWebUsbSerialPorts(); for (const p of ports) { await p.forgetDevice(); } } this.updateUIConnectionState(); } setNewlineMode() { localStorage.setItem('newlineMode', uiNewlineModeSelect.value); } autoReconnectChanged() { if (uiAutoReconnectCheckbox.checked) { this.setStatus('Auto-reconnect enabled', 'info'); this.tryAutoReconnect(); } else { this.setStatus('Auto-reconnect disabled', 'info'); this.stopAutoReconnect(); } localStorage.setItem('autoReconnect', uiAutoReconnectCheckbox.checked); } stopAutoReconnect() { if (this.reconnectTimeoutId !== null) { clearTimeout(this.reconnectTimeoutId); this.reconnectTimeoutId = null; this.setStatus('Auto-reconnect stopped.', 'info'); } } async autoReconnectTimeout() { this.reconnectTimeoutId = null; if (!uiAutoReconnectCheckbox.checked) { this.setStatus('Auto-reconnect stopped.', 'info'); return; } if (this.currentPort && !this.currentPort.isConnected) { try { await this.currentPort.connect(); this.setStatus('Reconnected successfully', 'info'); } catch (error) { this.setStatus(`Reconnect failed: ${error.message}`, 'error'); // Try again after a delay this.tryAutoReconnect(); } finally { this.updateUIConnectionState(); } } } tryAutoReconnect() { this.updateUIConnectionState(); if (!uiAutoReconnectCheckbox.checked) return; if (this.reconnectTimeoutId !== null) return; // already trying this.setStatus('Attempting to auto-reconnect...', 'info'); this.reconnectTimeoutId = setTimeout(async () => { await this.autoReconnectTimeout(); }, 1000); } async handleCommandLineInput(e) { // Instant mode: send key immediately including special keys like Backspace, arrows, enter, etc. if (this.sendMode === 'instant') { e.preventDefault(); // Ignore only pure modifier keys without text representation if (e.key.length === 1 || e.key === 'Enter' || e.key === 'Backspace' || e.key === 'Tab' || e.key === 'Escape' || e.key === 'Delete' ) { let sendText = ''; switch (e.key) { case 'Enter': switch (uiNewlineModeSelect.value) { case 'CR': sendText = '\r'; break; case 'CRLF': sendText = '\r\n'; break; default: sendText = '\n'; break; } break; case 'Backspace': // Usually no straightforward char to send for Backspace, // but often ASCII DEL '\x7F' or '\b' (0x08) is sent. sendText = '\x08'; // backspace break; case 'Tab': sendText = '\t'; break; case 'Escape': // Ignore or send ESC control char if needed sendText = '\x1B'; break; case 'Delete': sendText = '\x7F'; // DEL char break; default: sendText = e.key; } try { await this.currentPort.send(this.textEncoder.encode(sendText)); } catch (error) { this.setStatus(`Send error: ${error.message}`, 'error'); this.tryAutoReconnect(); } } return; } // Command mode: handle up/down arrow keys for history if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { e.preventDefault(); if (this.commandHistory.length === 0) return; if (e.key === 'ArrowUp') { if (this.uiCommandHistoryIndex === -1) this.uiCommandHistoryIndex = this.commandHistory.length - 1; else if (this.uiCommandHistoryIndex > 0) this.uiCommandHistoryIndex--; } else if (e.key === 'ArrowDown') { if (this.uiCommandHistoryIndex !== -1) this.uiCommandHistoryIndex++; if (this.uiCommandHistoryIndex >= this.commandHistory.length) this.uiCommandHistoryIndex = -1; } uiCommandLineInput.value = this.uiCommandHistoryIndex === -1 ? '' : this.commandHistory[this.uiCommandHistoryIndex].text; return; } if (e.key !== 'Enter' || !this.currentPort.isConnected) return; e.preventDefault(); const text = uiCommandLineInput.value; if (!text) return; // Convert to Uint8Array with newline based on config let sendText = text; switch (uiNewlineModeSelect.value) { case 'CR': sendText += '\r'; break; case 'CRLF': sendText += '\r\n'; break; case 'ANY': sendText += '\n'; break; } const data = this.textEncoder.encode(sendText); try { await this.currentPort.send(data); this.uiCommandHistoryIndex = -1; let history_cmd_text = sendText.replace(/[\r\n]+$/, ''); let history_entry = new CommandHistoryEntry(history_cmd_text); this.appendNewCommandToHistory(history_entry); uiCommandLineInput.value = ''; } catch (error) { this.setStatus(`Send error: ${error.message}`, 'error'); this.tryAutoReconnect(); } } toggleSendMode() { if (this.sendMode === 'instant') { this.setSendMode('command'); } else { this.setSendMode('instant'); } } setSendMode(mode) { this.sendMode = mode; if (mode === 'instant') { uiSendModeBtn.classList.remove('send-mode-command'); uiSendModeBtn.classList.add('send-mode-instant'); uiSendModeBtn.textContent = 'Instant mode'; } else { uiSendModeBtn.classList.remove('send-mode-instant'); uiSendModeBtn.classList.add('send-mode-command'); uiSendModeBtn.textContent = 'Command mode'; } localStorage.setItem('sendMode', this.sendMode); } copyOutput() { let text = ''; for (const entry of this.receivedData) { text += entry.text; if (entry.terminated) { text += '\n'; } } if (text) { navigator.clipboard.writeText(text).then(() => { this.setStatus('Output copied to clipboard', 'info'); }, () => { this.setStatus('Failed to copy output', 'error'); }); } else { this.setStatus('No output to copy', 'error'); } } downloadOutputCsv() { // save , let csvContent = 'data:text/csv;charset=utf-8,'; for (const entry of this.receivedData) { let sanitizedText = entry.text.replace(/"/g, '""').replace(/[\r\n]+$/, ''); let line = new Date(entry.time).toISOString() + ',"' + sanitizedText + '"'; csvContent += line + '\n'; } const encodedUri = encodeURI(csvContent); const link = document.createElement('a'); link.setAttribute('href', encodedUri); const filename = new Date().toISOString().replace(/:/g, '-') + '_tinyusb_received_serial_data.csv'; link.setAttribute('download', filename); document.body.appendChild(link); link.click(); document.body.removeChild(link); } async resetAll() { await this.forgetAllPorts(); // Clear localStorage localStorage.clear(); // reload the page window.location.reload(); } } const app = new Application(); })() ================================================ FILE: examples/device/webusb_serial/website/divider.js ================================================ (async () => { const uiResizer = document.getElementById('resizer'); const uiLeftColumn = uiResizer.previousElementSibling; const uiRightColumn = uiResizer.nextElementSibling; const uiParent = uiResizer.parentElement; let isResizing = false; let abortSignal = null; function onMouseMove(e) { // we resize the columns by applying felx: to the columns // compute the percentage the mouse is in the parent const percentage = (e.clientX - uiParent.offsetLeft) / uiParent.clientWidth; // clamp the percentage between 0.1 and 0.9 const clampedPercentage = Math.max(0.1, Math.min(0.9, percentage)); // set the flex property of the columns uiLeftColumn.style.flex = `${clampedPercentage}`; uiRightColumn.style.flex = `${1 - clampedPercentage}`; } function onMouseUp(e) { // restore user selection document.body.style.userSelect = ''; // remove the mousemove and mouseup events if (abortSignal) { abortSignal.abort(); abortSignal = null; } } uiResizer.addEventListener('mousedown', e => { e.preventDefault(); isResizing = true; // prevent text selection document.body.style.userSelect = 'none'; // register the mousemove and mouseup events abortSignal = new AbortController(); document.addEventListener('mousemove', onMouseMove, { signal: abortSignal.signal }); document.addEventListener('mouseup', onMouseUp, { signal: abortSignal.signal }); }); })(); ================================================ FILE: examples/device/webusb_serial/website/index.html ================================================ TinyUSB WebUSB Serial

TinyUSB - WebUSB Serial

Find my source on GitHub
Click "Connect" to start

Command History

Received Data

================================================ FILE: examples/device/webusb_serial/website/serial.js ================================================ 'use strict'; /// Web Serial API Implementation /// https://developer.mozilla.org/en-US/docs/Web/API/SerialPort class SerialPort { constructor(port) { this._port = port; this._readLoopPromise = null; this._reader = null; this._writer = null; this._initialized = false; this._keepReading = true; this.isConnected = false; } /// Connect and start reading loop async connect(options = { baudRate: 9600 }) { if (this._initialized) { try { await this.disconnect(); } catch (error) { console.error('Error disconnecting previous port:', error); } if (this._readLoopPromise) { try { await this._readLoopPromise; } catch (error) { console.error('Error in read loop:', error); } } this._readLoopPromise = null; } this._initialized = true; this.isConnected = true; this._keepReading = true; try { await this._port.open(options); } catch (error) { this.isConnected = false; throw error; } this._readLoopPromise = this._readLoop(); } /// Internal continuous read loop async _readLoop() { try { while (this._port.readable && this._keepReading) { this._reader = this._port.readable.getReader(); try { while (true) { const { value, done } = await this._reader.read(); if (done) { // |reader| has been canceled. break; } if (this.onReceive) { this.onReceive(value); } } } catch (error) { if (this.onReceiveError) this.onReceiveError(error); } finally { this._reader.releaseLock(); } } } finally { this.isConnected = false; await this._port.close(); } } /// Stop reading and release port async disconnect() { this._keepReading = false; if (this._reader) { try { await this._reader.cancel(); } catch (error) { console.error('Error cancelling reader:', error); } this._reader.releaseLock(); } if (this._writer) { try { await this._writer.abort(); } catch (error) { console.error('Error closing writer:', error); } this._writer.releaseLock(); } try { await this._port.close(); } catch (error) { console.error('Error closing port:', error); } if (this._readLoopPromise) { try { await this._readLoopPromise; } catch (error) { console.error('Error in read loop:', error); } } } /// Send data to port send(data) { if (!this._port.writable) { throw new Error('Port is not writable'); } this._writer = this._port.writable.getWriter(); if (!this._writer) { throw new Error('Failed to get writer from port'); } try { return this._writer.write(data); } finally { this._writer.releaseLock(); } } async forgetDevice() {} } /// WebUSB Implementation class WebUsbSerialPort { constructor(device) { this._device = device; this._interfaceNumber = 0; this._endpointIn = 0; this._endpointOut = 0; this.isConnected = false; this._readLoopPromise = null; this._initialized = false; this._keepReading = true; this._vendorId = device.vendorId; this._productId = device.productId; } _isSameWebUsbSerialPort(webUsbSerialPort) { return this._vendorId === webUsbSerialPort._vendorId && this._productId === webUsbSerialPort._productId; } /// Connect and start reading loop async connect() { if (this._initialized) { try { await this.disconnect(); } catch (error) { console.error('Error disconnecting previous device:', error); } const webUsbSerialPorts = await serial.getWebUsbSerialPorts(); const webUsbSerialPort = webUsbSerialPorts.find(serialPort => this._isSameWebUsbSerialPort(serialPort)); this._device = webUsbSerialPort ? webUsbSerialPort._device : this._device; } this._initialized = true; this.isConnected = true; this._keepReading = true; try { await this._device.open(); if (!this._device.configuration) { await this._device.selectConfiguration(1); } // Find interface with vendor-specific class (0xFF) and endpoints for (const iface of this._device.configuration.interfaces) { for (const alternate of iface.alternates) { if (alternate.interfaceClass === 0xff) { this._interfaceNumber = iface.interfaceNumber; for (const endpoint of alternate.endpoints) { if (endpoint.direction === 'out') this._endpointOut = endpoint.endpointNumber; else if (endpoint.direction === 'in') this._endpointIn = endpoint.endpointNumber; } } } } if (this._interfaceNumber === undefined) { throw new Error('No suitable interface found.'); } await this._device.claimInterface(this._interfaceNumber); await this._device.selectAlternateInterface(this._interfaceNumber, 0); // Set device to ENABLE (0x22 = SET_CONTROL_LINE_STATE, value 0x01 = activate) await this._device.controlTransferOut({ requestType: 'class', recipient: 'interface', request: 0x22, value: 0x01, index: this._interfaceNumber, }); } catch (error) { this.isConnected = false; throw error; } this._readLoopPromise = this._readLoop(); } /// Internal continuous read loop async _readLoop() { try { while (this._keepReading && this.isConnected) { try { const result = await this._device.transferIn(this._endpointIn, 16384); if (result.data && this.onReceive) { this.onReceive(result.data); } } catch (error) { this.isConnected = false; if (this.onReceiveError) { this.onReceiveError(error); } } } } finally { this.isConnected = false; await this._device.close(); } } /// Stop reading and release device async disconnect() { this._keepReading = false; try { await this._device.controlTransferOut({ requestType: 'class', recipient: 'interface', request: 0x22, value: 0x00, index: this._interfaceNumber, }); } catch (error) { console.error('Error sending control transfer:', error); } await this._device.releaseInterface(this._interfaceNumber); if (this._readLoopPromise) { try { await this._readLoopPromise; } catch (error) { console.error('Error in read loop:', error); } } } /// Send data to device send(data) { return this._device.transferOut(this._endpointOut, data); } async forgetDevice() { await this.disconnect(); await this._device.forget(); } } // Utility Functions const serial = { isWebSerialSupported: () => 'serial' in navigator, isWebUsbSupported: () => 'usb' in navigator, async getSerialPorts() { if (!this.isWebSerialSupported()) return []; const ports = await navigator.serial.getPorts(); return ports.map(port => new SerialPort(port)); }, async getWebUsbSerialPorts() { if (!this.isWebUsbSupported()) return []; const devices = await navigator.usb.getDevices(); return devices.map(device => new WebUsbSerialPort(device)); }, async requestSerialPort() { const port = await navigator.serial.requestPort(); return new SerialPort(port); }, async requestWebUsbSerialPort() { const filters = [ { vendorId: 0xcafe }, // TinyUSB { vendorId: 0x239a }, // Adafruit { vendorId: 0x2e8a }, // Raspberry Pi { vendorId: 0x303a }, // Espressif { vendorId: 0x2341 }, // Arduino ]; const device = await navigator.usb.requestDevice({ filters }); return new WebUsbSerialPort(device); } }; ================================================ FILE: examples/device/webusb_serial/website/style.css ================================================ * { box-sizing: border-box; margin: 0; padding: 0; } /* Reset default margins and make html, body full height */ html, body { height: 100%; font-family: sans-serif; background: #f5f5f5; color: #333; } body { display: flex; flex-direction: column; height: 100vh; } /* Header row styling */ .header { display: flex; justify-content: space-between; align-items: center; padding: 0.5em 1em; gap: 1em; flex-shrink: 0; } h1, h2 { margin: 0; } .app-title { flex-grow: 1; } .btn-theme { background-color: #6b6b6b; color: #fff; } .github-link { font-weight: 600; } /* Main is flex column */ main { display: flex; flex-direction: column; flex: 1; width: 100%; } /* Controls top row in main*/ .controls-section, .status-section { padding: 1rem; flex-shrink: 0; display: flex; flex-direction: row; flex-wrap: wrap; gap: 0.5rem; } /* Container for the two columns */ .io-container { display: flex; flex: 1; /* fill remaining vertical space */ width: 100%; overflow: hidden; } /* Both columns flex equally and full height */ .column { flex: 1; padding: 1rem; display: flex; flex-direction: column; } .heading-with-controls { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; } .command-history-entry { all: unset; display: flex; flex-direction: row; gap: 0.5rem; background: none; border: none; border-bottom: 1px solid #ccc; /* light gray line */ padding: 0.5rem 1rem; margin: 0; text-align: left; cursor: pointer; } .command-history-entry:hover { background-color: #f0f0f0; } .monospaced { font-family: 'Courier New', Courier, monospace; font-size: 1rem; color: #333; } .scrollbox-wrapper { position: relative; padding: 0.5rem; flex: 1; display: block; overflow: hidden; } .scrollbox { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow-y: auto; overflow-x: auto; margin-top: 0.5rem; margin-bottom: 0.5rem; background-color: #fff; border-radius: 0.5rem; white-space: nowrap; display: flex; flex-direction: column; align-items: stretch; } .send-container { display: flex; flex-direction: row; gap: 0.5rem; } .send-mode-command { background-color: lightgray; /* light-gray */ } .send-mode-instant { background-color: blue; } .btn { padding: 0.5rem 1rem; font-size: 1rem; border: none; border-radius: 0.3rem; cursor: pointer; } .good { background-color: #2ecc71; /* green */ color: #fff; } .danger { background-color: #e74c3c; /* red */ color: #fff; } .input { width: 100%; padding: 12px 16px; font-size: 1rem; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; border: 2px solid #ddd; border-radius: 8px; background-color: #fafafa; color: #333; transition: border-color 0.3s ease, box-shadow 0.3s ease; outline: none; box-sizing: border-box; } .input::placeholder { color: #aaa; font-style: italic; } .input:focus { border-color: #0078d7; box-shadow: 0 0 6px rgba(0, 120, 215, 0.5); background-color: #fff; } .resizer { width: 5px; background-color: #ccc; cursor: col-resize; height: 100%; } /* ================================ Togglable Dark Mode ================================ */ /* This class will be added to the body element by JavaScript */ body.dark-mode { /* Invert base background and text colors */ background: #1e1e1e; color: #d4d4d4; } body.dark-mode input[type="checkbox"] { border-color: #888; accent-color: #2e2e2e; opacity: 0.8; } body.dark-mode .btn-theme { background-color: #b0b0b0; color: #000; } body.dark-mode .github-link { color: #58a6ff; } body.dark-mode .resizer { background-color: #444; } body.dark-mode .input { background-color: #3c3c3c; color: #f0f0f0; border: 2px solid #555; } body.dark-mode .input::placeholder { color: #888; } body.dark-mode .input:focus { background-color: #2a2d2e; border-color: #0078d7; } body.dark-mode .scrollbox { background-color: #252526; scrollbar-color: #555 #2e2e2e; border: 1px solid #444; } body.dark-mode .monospaced { color: #d4d4d4; } body.dark-mode .command-history-entry { border-bottom: 1px solid #444; } body.dark-mode .command-history-entry:hover { background-color: #3c3c3c; } body.dark-mode .send-mode-command { background-color: #555; color: #f5f5f5; } body.dark-mode select { background-color: #3c3c3c; color: #f0f0f0; border: 2px solid #555; } body.dark-mode select:focus { background-color: #2a2d2e; border-color: #0078d7; outline: none; } body.dark-mode option { background-color: #3c3c3c; color: #f0f0f0; } ================================================ FILE: examples/dual/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake) project(tinyusb_dual_examples C CXX ASM) family_initialize_project(tinyusb_dual_examples ${CMAKE_CURRENT_LIST_DIR}) if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb) message("Skipping dual host/device mode examples as Pico-PIO-USB is not available") else () # family_add_subdirectory will filter what to actually add based on selected FAMILY set(EXAMPLE_LIST host_hid_to_device_cdc host_info_to_device_cdc dynamic_switch ) foreach (example ${EXAMPLE_LIST}) family_add_subdirectory(${example}) endforeach () endif () ================================================ FILE: examples/dual/CMakePresets.json ================================================ { "version": 6, "include": [ "../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/dual/dynamic_switch/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(dynamic_switch C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_dual_usb_example(${PROJECT_NAME} noos) ================================================ FILE: examples/dual/dynamic_switch/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/dual/dynamic_switch/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) # Include device and host stack SRC_C += \ src/class/cdc/cdc_device.c \ src/host/hub.c \ src/host/usbh.c include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/dual/dynamic_switch/README.md ================================================ # Dynamic Switch Example This example demonstrates TinyUSB's dual-role capability by allowing runtime switching between USB device and host modes. ## Features - **Button-triggered mode switching**: Press the board button to switch between device and host modes - **Device Mode**: Acts as a USB CDC (Virtual Serial Port) that echoes all received data - **Host Mode**: Enumerates connected USB devices and prints device information - **Dynamic switching**: Deinitializes the current stack and reinitializes in the new mode ## Usage 1. **Build and flash** the example to your board 2. **Default behavior**: The board starts in **Device mode** 3. **Device mode**: - Connect the board to a PC - Open a serial terminal (e.g., `screen /dev/ttyACM0` or PuTTY) - Type characters - they will be echoed back to you 4. **Switch to Host mode**: - Press the board button - Connect a USB device to the board - The board will enumerate the device and print its descriptors to the debug console 5. **Switch back to Device mode**: Press the button again ## LED Patterns The onboard LED indicates the USB connection status: - **Fast blink (250ms)**: Not mounted/connected - **Slow blink (1000ms)**: Successfully mounted/connected - **Very slow blink (2500ms)**: Suspended (device mode only) ## Serial Output The example prints status messages to the debug UART: ``` ====================================== TinyUSB Dynamic Switch Example Press button to switch between device and host modes Starting in DEVICE mode... ====================================== [DEVICE] Mounted --- Switching USB mode --- Stopping DEVICE mode... Starting HOST mode... Mode switch complete! [HOST] Device attached, address = 1 Device 1: ID 1234:5678 SN ABC123 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 0200 bDeviceClass 239 ... ``` ================================================ FILE: examples/dual/dynamic_switch/only.txt ================================================ family:espressif mcu:LPC43XX mcu:MIMXRT1XXX mcu:STM32C0 mcu:STM32G0 mcu:STM32H5 mcu:STM32F2 mcu:STM32F4 mcu:STM32U5 mcu:STM32F7 mcu:STM32H7 mcu:STM32H7RS ================================================ FILE: examples/dual/dynamic_switch/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/dual/dynamic_switch/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* This example demonstrates dynamic switching between device and host modes: * - Press button to switch between device and host modes * - Device mode: CDC echo (echoes input back to output) * - Host mode: Prints connected device information */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #if CFG_TUSB_OS == OPT_OS_FREERTOS #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 #define USBH_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif #define CDC_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1)) #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ // English #define LANGUAGE_ID 0x0409 /* Blink pattern * - 250 ms : not mounted * - 1000 ms : mounted * - 2500 ms : suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; #if CFG_TUSB_OS == OPT_OS_FREERTOS // static task for FreeRTOS #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_stack[USBD_STACK_SIZE > USBH_STACK_SIZE ? USBD_STACK_SIZE : USBH_STACK_SIZE]; StaticTask_t usb_taskdef; StackType_t cdc_stack[CDC_STACK_SIZE]; StaticTask_t cdc_taskdef; #endif #endif static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static tusb_role_t current_role = TUSB_ROLE_DEVICE; #if CFG_TUSB_OS == OPT_OS_FREERTOS static void usb_task(void *param); void led_blinking_task(void *param); void cdc_task(void *params); #else void led_blinking_task(void); void cdc_task(void); #endif void usb_mode_switch(void); static void print_device_info(uint8_t daddr); static void print_utf16(uint16_t* temp_buf, size_t buf_len); // Declare buffer for USB transfer CFG_TUH_MEM_SECTION struct { TUH_EPBUF_TYPE_DEF(tusb_desc_device_t, device); TUH_EPBUF_DEF(serial, 64*sizeof(uint16_t)); TUH_EPBUF_DEF(buf, 128*sizeof(uint16_t)); } desc; //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ int main(void) { board_init(); printf("\r\n======================================\r\n"); printf("TinyUSB Dynamic Switch Example\r\n"); printf("Press button to switch between device and host modes\r\n"); printf("Starting in DEVICE mode...\r\n"); printf("======================================\r\n\r\n"); #if CFG_TUSB_OS == OPT_OS_FREERTOS // Create FreeRTOS tasks #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_task, "usb", USBD_STACK_SIZE > USBH_STACK_SIZE ? USBD_STACK_SIZE : USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_stack, &usb_taskdef); xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_task, "usb", USBD_STACK_SIZE > USBH_STACK_SIZE ? USBD_STACK_SIZE : USBH_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); #endif #ifndef ESP_PLATFORM // only start scheduler for non-espressif mcu vTaskStartScheduler(); #endif #else // Initialize in device mode by default tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_RHPORT, &dev_init); current_role = TUSB_ROLE_DEVICE; board_init_after_tusb(); while (1) { // Check for button press to switch modes static bool pending_switch = false; if (board_button_read()) { if (!pending_switch) { pending_switch = true; usb_mode_switch(); } } else { pending_switch = false; } // Process USB tasks based on current mode if (current_role == TUSB_ROLE_DEVICE) { tud_task(); cdc_task(); } else { tuh_task(); } led_blinking_task(); } #endif } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // USB Task for FreeRTOS // This top level thread processes all usb events and mode switching static void usb_task(void *param) { (void) param; // init device stack on configured roothub port // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_RHPORT, &dev_init); current_role = TUSB_ROLE_DEVICE; board_init_after_tusb(); // RTOS forever loop while (1) { // Check for button press to switch modes static bool pending_switch = false; if (board_button_read()) { if (!pending_switch) { pending_switch = true; usb_mode_switch(); } } else { pending_switch = false; } // Process USB tasks based on current mode // Use _ext version to allow return and read button state if (current_role == TUSB_ROLE_DEVICE) { tud_task_ext(10, false); } else { tuh_task_ext(10, false); } } } #endif //--------------------------------------------------------------------+ // Mode Switching //--------------------------------------------------------------------+ void usb_mode_switch(void) { printf("\r\n--- Switching USB mode ---\r\n"); // Deinitialize current mode if (current_role == TUSB_ROLE_DEVICE) { printf("Stopping DEVICE mode...\r\n"); tusb_deinit(BOARD_RHPORT); } else { printf("Stopping HOST mode...\r\n"); tusb_deinit(BOARD_RHPORT); } #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(pdMS_TO_TICKS(100)); // Small delay for clean transition #else tusb_time_delay_ms_api(100); // Small delay for clean transition #endif // Switch to the other mode if (current_role == TUSB_ROLE_DEVICE) { printf("Starting HOST mode...\r\n"); tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_RHPORT, &host_init); current_role = TUSB_ROLE_HOST; } else { printf("Starting DEVICE mode...\r\n"); tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_RHPORT, &dev_init); current_role = TUSB_ROLE_DEVICE; } blink_interval_ms = BLINK_NOT_MOUNTED; printf("Mode switch complete!\r\n\r\n"); } //--------------------------------------------------------------------+ // Device Mode: CDC Task //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS void cdc_task(void *params) { (void) params; // RTOS forever loop while (1) { // Only process CDC when in device mode if (current_role == TUSB_ROLE_DEVICE) { // Connected and there are data available while (tud_cdc_available()) { uint8_t buf[64]; // Read data uint32_t count = tud_cdc_read(buf, sizeof(buf)); // Echo back tud_cdc_write(buf, count); // Add newline for carriage return for (uint32_t i = 0; i < count; i++) { if (buf[i] == '\r') { tud_cdc_write_char('\n'); break; } } } tud_cdc_write_flush(); } vTaskDelay(pdMS_TO_TICKS(10)); } } #else void cdc_task(void) { // Connected and there are data available if (tud_cdc_available()) { uint8_t buf[64]; // Read data uint32_t count = tud_cdc_read(buf, sizeof(buf)); // Echo back for (uint32_t i = 0; i < count; i++) { tud_cdc_write_char(buf[i]); if (buf[i] == '\r') { tud_cdc_write_char('\n'); } } tud_cdc_write_flush(); } } #endif //--------------------------------------------------------------------+ // Device Callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { printf("[DEVICE] Mounted\r\n"); blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { printf("[DEVICE] Unmounted\r\n"); blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; printf("[DEVICE] Suspended\r\n"); blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { printf("[DEVICE] Resumed\r\n"); blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // Host Callbacks //--------------------------------------------------------------------+ // Invoked when device is mounted (configured) void tuh_mount_cb(uint8_t daddr) { printf("[HOST] Device attached, address = %d\r\n", daddr); blink_interval_ms = BLINK_MOUNTED; print_device_info(daddr); } // Invoked when device is unmounted (unplugged) void tuh_umount_cb(uint8_t daddr) { printf("[HOST] Device removed, address = %d\r\n", daddr); blink_interval_ms = BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // Host Device Info //--------------------------------------------------------------------+ static void print_device_info(uint8_t daddr) { // Get Device Descriptor uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc.device, 18); if (XFER_RESULT_SUCCESS != xfer_result) { printf("Failed to get device descriptor\r\n"); return; } printf("Device %u: ID %04x:%04x SN ", daddr, desc.device.idVendor, desc.device.idProduct); xfer_result = XFER_RESULT_FAILED; if (desc.device.iSerialNumber != 0) { xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, desc.serial, sizeof(desc.serial)); } if (XFER_RESULT_SUCCESS != xfer_result) { uint16_t* serial = (uint16_t*)(uintptr_t) desc.serial; serial[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * 3 + 2)); serial[1] = 'n'; serial[2] = '/'; serial[3] = 'a'; serial[4] = 0; } print_utf16((uint16_t*)(uintptr_t) desc.serial, sizeof(desc.serial)/2); printf("\r\n"); printf("Device Descriptor:\r\n"); printf(" bLength %u\r\n", desc.device.bLength); printf(" bDescriptorType %u\r\n", desc.device.bDescriptorType); printf(" bcdUSB %04x\r\n", desc.device.bcdUSB); printf(" bDeviceClass %u\r\n", desc.device.bDeviceClass); printf(" bDeviceSubClass %u\r\n", desc.device.bDeviceSubClass); printf(" bDeviceProtocol %u\r\n", desc.device.bDeviceProtocol); printf(" bMaxPacketSize0 %u\r\n", desc.device.bMaxPacketSize0); printf(" idVendor 0x%04x\r\n", desc.device.idVendor); printf(" idProduct 0x%04x\r\n", desc.device.idProduct); printf(" bcdDevice %04x\r\n", desc.device.bcdDevice); // Get Manufacturer string if (desc.device.iManufacturer) { if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf))) { printf(" iManufacturer %u ", desc.device.iManufacturer); print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2); printf("\r\n"); } } // Get Product string if (desc.device.iProduct) { if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf))) { printf(" iProduct %u ", desc.device.iProduct); print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2); printf("\r\n"); } } // Get Serial string if (desc.device.iSerialNumber) { printf(" iSerialNumber %u ", desc.device.iSerialNumber); print_utf16((uint16_t*)(uintptr_t) desc.serial, sizeof(desc.serial)/2); printf("\r\n"); } else { printf(" iSerialNumber 0\r\n"); } printf(" bNumConfigurations %u\r\n", desc.device.bNumConfigurations); printf("\r\n"); } static void print_utf16(uint16_t* temp_buf, size_t buf_len) { if (temp_buf[0] == 0 || (temp_buf[0] >> 8) != TUSB_DESC_STRING) { printf("(invalid)"); return; } size_t chr_count = (temp_buf[0] & 0xff) / 2 - 1; if (chr_count > buf_len - 1) { chr_count = buf_len - 1; } for (size_t i = 0; i < chr_count; i++) { uint16_t ch = temp_buf[1 + i]; if (ch <= 0x7F) { putchar((char) ch); } else { // TODO support UTF16 to UTF8 conversion putchar('?'); } } } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS void led_blinking_task(void *param) { (void) param; static bool led_state = false; // RTOS forever loop while (1) { board_led_write(led_state); led_state = 1 - led_state; // toggle vTaskDelay(pdMS_TO_TICKS(blink_interval_ms)); } } #else void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } #endif ================================================ FILE: examples/dual/dynamic_switch/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef _TUSB_CONFIG_H_ #define _TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used can be defined by board.mk, default to port 0 #ifndef BOARD_RHPORT #if defined(BOARD_TUD_RHPORT) #define BOARD_RHPORT BOARD_TUD_RHPORT #else #define BOARD_RHPORT 0 #define BOARD_TUD_RHPORT 0 #endif #endif #if defined(BOARD_TUH_RHPORT) #if BOARD_TUH_RHPORT != BOARD_RHPORT #undef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT BOARD_RHPORT #endif #else #define BOARD_TUH_RHPORT BOARD_RHPORT #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_MAX_SPEED #if defined(BOARD_TUD_MAX_SPEED) #define BOARD_MAX_SPEED BOARD_TUD_MAX_SPEED #else #define BOARD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device and Host stacks (dual role) #define CFG_TUD_ENABLED 1 #define CFG_TUH_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_MAX_SPEED #define CFG_TUH_MAX_SPEED BOARD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUD_MEM_SECTION #define CFG_TUD_MEM_SECTION #endif #ifndef CFG_TUD_MEM_ALIGN #define CFG_TUD_MEM_ALIGN __attribute__((aligned(4))) #endif #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION CFG_TUD_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN CFG_TUD_MEM_ALIGN #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // max device support (excluding hub device) #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports #define CFG_TUH_CDC 0 #define CFG_TUH_HID 0 #define CFG_TUH_MSC 0 #define CFG_TUH_VENDOR 0 // max endpoint pair supported by each device #define CFG_TUH_ENDPOINT_MAX 16 #ifdef __cplusplus } #endif #endif /* _TUSB_CONFIG_H_ */ ================================================ FILE: examples/dual/dynamic_switch/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4)) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { return (uint8_t const *) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), }; #endif // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors static char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials, will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { return NULL; } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) { chr_count = max_count; } // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/dual/host_hid_to_device_cdc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(host_hid_to_device_cdc C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_dual_usb_example(${PROJECT_NAME} noos) # due to warnings from Pico-PIO-USB if (FAMILY STREQUAL rp2040) target_compile_options(${PROJECT_NAME} PUBLIC -Wno-error=shadow -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls -Wno-error=sign-conversion -Wno-error=conversion -Wno-error=sign-compare -Wno-error=unused-function ) endif () ================================================ FILE: examples/dual/host_hid_to_device_cdc/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/dual/host_hid_to_device_cdc/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) CFLAGS_GCC += -Wno-error=cast-align -Wno-error=null-dereference SRC_C += \ src/class/hid/hid_host.c \ src/host/hub.c \ src/host/usbh.c include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/dual/host_hid_to_device_cdc/only.txt ================================================ board:mimxrt1060_evk board:mimxrt1064_evk board:mcb1800 mcu:CH32V20X mcu:RP2040 mcu:ra6m5 mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 ================================================ FILE: examples/dual/host_hid_to_device_cdc/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ // This example runs both host and device concurrently. The USB host receive // reports from HID device and print it out over USB Device CDC interface. #include #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ // uncomment if you are using colemak layout // #define KEYBOARD_COLEMAK #ifdef KEYBOARD_COLEMAK const uint8_t colemak[128] = { 0 , 0, 0, 0, 0, 0, 0, 22, 9 , 23, 7, 0, 24, 17, 8, 12, 0 , 14, 28, 51, 0, 19, 21, 10, 15 , 0, 0, 0, 13, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 18, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0 }; #endif static uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII}; /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host HID <-> Device CDC Example\r\n"); // init device and host stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); while (1) { tud_task(); // tinyusb device task tuh_task(); // tinyusb host task led_blinking_task(); } } //--------------------------------------------------------------------+ // Device CDC //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Invoked when CDC interface received data from host void tud_cdc_rx_cb(uint8_t itf) { (void) itf; char buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); // TODO control LED on keyboard of host stack (void) count; } //--------------------------------------------------------------------+ // Host HID //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { (void) desc_report; (void) desc_len; // Interface protocol (hid_interface_protocol_enum_t) const char* protocol_str[] = {"None", "Keyboard", "Mouse"}; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); char tempbuf[256]; int count = sprintf( tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]); tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); // Receive report from boot keyboard & mouse only // tuh_hid_report_received_cb() will be invoked when report is available if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE) { if (!tuh_hid_receive_report(dev_addr, instance)) { tud_cdc_write_str("Error: cannot request report\r\n"); } } } // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { char tempbuf[256]; int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance); tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } // look up new key in previous keys static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) { for (uint8_t i = 0; i < 6; i++) { if (report->keycode[i] == keycode) { return true; } } return false; } // convert hid keycode to ascii and print via usb device CDC (ignore non-printable) static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const* report) { (void) dev_addr; static hid_keyboard_report_t prev_report = {0, 0, {0}}; // previous report to check key released bool flush = false; for (uint8_t i = 0; i < 6; i++) { uint8_t keycode = report->keycode[i]; if (keycode) { if (find_key_in_report(&prev_report, keycode)) { // exist in previous report means the current key is holding } else { // not existed in previous report means the current key is pressed // remap the key code for Colemak layout #ifdef KEYBOARD_COLEMAK uint8_t colemak_key_code = colemak[keycode]; if (colemak_key_code != 0) keycode = colemak_key_code; #endif bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0]; if (ch) { if (ch == '\n') tud_cdc_write("\r", 1); tud_cdc_write(&ch, 1); flush = true; } } } // TODO example skips key released } if (flush) { tud_cdc_write_flush(); } prev_report = *report; } // send mouse report to usb device CDC static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const* report) { //------------- button state -------------// //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-'; char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-'; char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'; char tempbuf[32]; int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel); tud_cdc_write(tempbuf, (uint32_t) count); tud_cdc_write_flush(); } // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { (void) len; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); switch (itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report); break; case HID_ITF_PROTOCOL_MOUSE: process_mouse_report(dev_addr, (hid_mouse_report_t const*) report); break; default: break; } // continue to request to receive report if (!tuh_hid_receive_report(dev_addr, instance)) { tud_cdc_write_str("Error: cannot request report\r\n"); } } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/dual/host_hid_to_device_cdc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // RHPort number used for host can be defined by board.mk, default to port 1 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 1 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack, Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_ENABLED 1 #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED // Enable Host stack, Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_ENABLED 1 #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED #if CFG_TUSB_MCU == OPT_MCU_RP2040 // Use pico-pio-usb as host controller for raspberry rp2040 #define CFG_TUH_RPI_PIO_USB 1 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUD_MEM_SECTION #define CFG_TUD_MEM_SECTION #endif #ifndef CFG_TUD_MEM_ALIGN #define CFG_TUD_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif #define CFG_TUH_HUB 1 // max device support (excluding hub device) #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 #ifdef __cplusplus } #endif #endif ================================================ FILE: examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const* tud_descriptor_device_cb(void) { return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x81 #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr[] = { (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/dual/host_info_to_device_cdc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(host_info_to_device_cdc C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_dual_usb_example(${PROJECT_NAME} ${RTOS}) # due to warnings from Pico-PIO-USB if (FAMILY STREQUAL rp2040) target_compile_options(${PROJECT_NAME} PUBLIC -Wno-error=shadow -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls -Wno-error=sign-conversion -Wno-error=conversion -Wno-error=sign-compare -Wno-error=unused-function ) endif () ================================================ FILE: examples/dual/host_info_to_device_cdc/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/dual/host_info_to_device_cdc/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) CFLAGS_GCC += -Wno-error=cast-align -Wno-error=null-dereference SRC_C += \ src/host/hub.c \ src/host/usbh.c include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/dual/host_info_to_device_cdc/only.txt ================================================ board:mimxrt1060_evk board:mimxrt1064_evk board:mcb1800 mcu:CH32V20X mcu:RP2040 mcu:ra6m5 mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 mcu:ESP32P4 ================================================ FILE: examples/dual/host_info_to_device_cdc/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" "usb_descriptors.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/dual/host_info_to_device_cdc/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* Host example will get device descriptors of attached devices and print it out via device cdc as follows: * Device 1: ID 046d:c52f SN 11223344 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 0200 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x046d idProduct 0xc52f bcdDevice 2200 iManufacturer 1 Logitech iProduct 2 USB Receiver iSerialNumber 0 bNumConfigurations 1 * */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ // Language ID: English #define LANGUAGE_ID 0x0409 /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static bool is_printable[CFG_TUH_DEVICE_MAX + 1] = {0}; static tusb_desc_device_t descriptor_device[CFG_TUH_DEVICE_MAX+1]; static void print_utf16(uint16_t *temp_buf, size_t buf_len); static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device); static void led_blinking_task(void); static void cdc_task(void); #if CFG_TUSB_OS == OPT_OS_FREERTOS static void freertos_init(void); #endif #define cdc_printf(...) \ do { \ char _tempbuf[256]; \ char* _bufptr = _tempbuf; \ uint32_t count = (uint32_t) sprintf(_tempbuf, __VA_ARGS__); \ while (count > 0) { \ uint32_t wr_count = tud_cdc_write(_bufptr, count); \ count -= wr_count; \ _bufptr += wr_count; \ if (count > 0){ \ tud_task(); \ tud_cdc_write_flush(); \ } \ } \ } while(0) static void usb_device_init(void) { // init device and host stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); } static void usb_host_init(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); } //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ static void main_task(void* param) { (void) param; while (1) { cdc_task(); led_blinking_task(); // preempted RTOS run device/host stack in its own task #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO tud_task(); // tinyusb device task tuh_task(); // tinyusb host task #endif } } int main(void) { board_init(); #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO printf("TinyUSB Host Information -> Device CDC Example\r\n"); usb_device_init(); usb_host_init(); main_task(NULL); #elif CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); // create RTOS tasks for device, host stack and main_task() #else #error RTOS not supported #endif return 0; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO // USB Device Driver task for RTOS static void usb_device_task(void *param) { (void) param; usb_device_init(); while (1) { // put this thread to waiting state until there is new events tud_task(); } } static void usb_host_task(void *param) { (void) param; usb_host_init(); while (1) { // put this thread to waiting state until there is new events tuh_task(); } } #endif //--------------------------------------------------------------------+ // Device CDC //--------------------------------------------------------------------+ // Invoked when device is mounted void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } void cdc_task(void) { static uint32_t connected_ms = 0; if (!tud_cdc_connected()) { connected_ms = tusb_time_millis_api(); return; } // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding. // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop if (tusb_time_millis_api() - connected_ms < 100) { return; // wait for stable connection } for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) { if (tuh_mounted(daddr)) { if (is_printable[daddr]) { is_printable[daddr] = false; print_device_info(daddr, &descriptor_device[daddr]); tud_cdc_write_flush(); } } } } //--------------------------------------------------------------------+ // Host Get device information //--------------------------------------------------------------------+ static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device) { // Get String descriptor using Sync API uint16_t serial[64]; uint16_t buf[128]; (void) buf; cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device->idVendor, desc_device->idProduct); uint8_t xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial)); if (XFER_RESULT_SUCCESS != xfer_result) { serial[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * 1 + 2)); serial[1] = '0'; serial[2] = 0; } print_utf16(serial, TU_ARRAY_SIZE(serial)); cdc_printf("\r\n"); cdc_printf("Device Descriptor:\r\n"); cdc_printf(" bLength %u\r\n" , desc_device->bLength); cdc_printf(" bDescriptorType %u\r\n" , desc_device->bDescriptorType); cdc_printf(" bcdUSB %04x\r\n" , desc_device->bcdUSB); cdc_printf(" bDeviceClass %u\r\n" , desc_device->bDeviceClass); cdc_printf(" bDeviceSubClass %u\r\n" , desc_device->bDeviceSubClass); cdc_printf(" bDeviceProtocol %u\r\n" , desc_device->bDeviceProtocol); cdc_printf(" bMaxPacketSize0 %u\r\n" , desc_device->bMaxPacketSize0); cdc_printf(" idVendor 0x%04x\r\n" , desc_device->idVendor); cdc_printf(" idProduct 0x%04x\r\n" , desc_device->idProduct); cdc_printf(" bcdDevice %04x\r\n" , desc_device->bcdDevice); cdc_printf(" iManufacturer %u " , desc_device->iManufacturer); xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); if (XFER_RESULT_SUCCESS == xfer_result) { print_utf16(buf, TU_ARRAY_SIZE(buf)); } cdc_printf("\r\n"); cdc_printf(" iProduct %u " , desc_device->iProduct); xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf)); if (XFER_RESULT_SUCCESS == xfer_result) { print_utf16(buf, TU_ARRAY_SIZE(buf)); } cdc_printf("\r\n"); cdc_printf(" iSerialNumber %u " , desc_device->iSerialNumber); cdc_printf("%s \r\n", (char*)serial); // serial is already to UTF-8 cdc_printf(" bNumConfigurations %u\r\n" , desc_device->bNumConfigurations); } void tuh_enum_descriptor_device_cb(uint8_t daddr, tusb_desc_device_t const* desc_device) { (void) daddr; descriptor_device[daddr] = *desc_device; // save device descriptor } void tuh_mount_cb(uint8_t daddr) { cdc_printf("mounted device %u\r\n", daddr); tud_cdc_write_flush(); is_printable[daddr] = true; } void tuh_umount_cb(uint8_t daddr) { cdc_printf("unmounted device %u\r\n", daddr); tud_cdc_write_flush(); is_printable[daddr] = false; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return;// not enough time } start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } //--------------------------------------------------------------------+ // String Descriptor Helper //--------------------------------------------------------------------+ static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { // TODO: Check for runover. (void)utf8_len; // Get the UTF-16 length out of the data itself. for (size_t i = 0; i < utf16_len; i++) { uint16_t chr = utf16[i]; if (chr < 0x80) { *utf8++ = chr & 0xffu; } else if (chr < 0x800) { *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F)); *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); } else { // TODO: Verify surrogate. *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F)); *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F)); *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F)); } // TODO: Handle UTF-16 code points that take two entries. } } // Count how many bytes a utf-16-le encoded string will take in utf-8. static int _count_utf8_bytes(const uint16_t *buf, size_t len) { size_t total_bytes = 0; for (size_t i = 0; i < len; i++) { uint16_t chr = buf[i]; if (chr < 0x80) { total_bytes += 1; } else if (chr < 0x800) { total_bytes += 2; } else { total_bytes += 3; } // TODO: Handle UTF-16 code points that take two entries. } return (int) total_bytes; } static void print_utf16(uint16_t *temp_buf, size_t buf_len) { if ((temp_buf[0] & 0xff) == 0) { return;// empty } size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; cdc_printf("%s", (char*) temp_buf); } //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #ifdef ESP_PLATFORM #define USBD_STACK_SIZE 4096 #define USBH_STACK_SIZE 4096 void app_main(void) { main(); } #else // Increase stack size when debug log is enabled #define USBD_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2)) #define USBH_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2)) #endif #define MAIN_STACK_SIZE (configMINIMAL_STACK_SIZE*4) // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t main_stack[MAIN_STACK_SIZE]; StaticTask_t main_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; StackType_t usb_host_stack[USBH_STACK_SIZE]; StaticTask_t usb_host_taskdef; #endif void freertos_init(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); xTaskCreateStatic(main_task, "main", MAIN_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, main_stack, &main_taskdef); #else xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(main_task, "main", MAIN_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } #endif ================================================ FILE: examples/dual/host_info_to_device_cdc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // RHPort number used for host can be defined by board.mk, default to port 1 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 1 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack, Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_ENABLED 1 #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED // Enable Host stack, Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_ENABLED 1 #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED #if CFG_TUSB_MCU == OPT_MCU_RP2040 // Use pico-pio-usb as host controller for raspberry rp2040 #define CFG_TUH_RPI_PIO_USB 1 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUD_MEM_SECTION #define CFG_TUD_MEM_SECTION #endif #ifndef CFG_TUD_MEM_ALIGN #define CFG_TUD_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif #define CFG_TUH_HUB 1 // max device support (excluding hub device) #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports #ifdef __cplusplus } #endif #endif ================================================ FILE: examples/dual/host_info_to_device_cdc/src/usb_descriptors.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) #define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const* tud_descriptor_device_cb(void) { return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 // CXD56 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) #define EPNUM_CDC_NOTIF 0x83 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x81 #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x83 #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #endif #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration static uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration static uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), }; // other speed configuration static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change configuration based on speed static tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00 }; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void) { return (uint8_t const*) &desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // String Descriptor Index enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, }; // array of pointer to string descriptors char const* string_desc_arr[] = { (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: examples/host/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake) project(tinyusb_host_examples C CXX ASM) family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY set(EXAMPLE_LIST bare_api cdc_msc_hid cdc_msc_hid_freertos device_info hid_controller midi_rx msc_file_explorer ) foreach (example ${EXAMPLE_LIST}) family_add_subdirectory(${example}) endforeach () ================================================ FILE: examples/host/CMakePresets.json ================================================ { "version": 6, "include": [ "../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/bare_api/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(bare_api C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/bare_api/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/bare_api/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/bare_api/only.txt ================================================ family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/bare_api/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/bare_api/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "class/hid/hid.h" // English #define LANGUAGE_ID 0x0409 #define BUF_COUNT 4 CFG_TUH_MEM_SECTION tusb_desc_device_t desc_device; CFG_TUH_MEM_SECTION uint8_t buf_pool[BUF_COUNT][64]; uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer CFG_TUH_MEM_SECTION uint16_t temp_buf[128]; // temp buffer for string descriptor //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); static void print_utf16(uint16_t *temp_buf, size_t buf_len); void print_device_descriptor(tuh_xfer_t* xfer); void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); uint8_t* get_hid_buf(uint8_t daddr); void free_hid_buf(uint8_t daddr); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Bare API Example\r\n"); // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); while (1) { // tinyusb host task tuh_task(); led_blinking_task(); } } /*------------- TinyUSB Callbacks -------------*/ // Invoked when device is mounted (configured) void tuh_mount_cb(uint8_t daddr) { printf("Device attached, address = %d\r\n", daddr); // Get Device Descriptor // TODO: invoking control transfer now has issue with mounting hub with multiple devices attached, fix later tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0); } /// Invoked when device is unmounted (bus reset/unplugged) void tuh_umount_cb(uint8_t daddr) { printf("Device removed, address = %d\r\n", daddr); free_hid_buf(daddr); } //--------------------------------------------------------------------+ // Device Descriptor //--------------------------------------------------------------------+ void print_device_descriptor(tuh_xfer_t *xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { printf("Failed to get device descriptor\r\n"); return; } uint8_t const daddr = xfer->daddr; printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); printf("Device Descriptor:\r\n"); printf(" bLength %u\r\n" , desc_device.bLength); printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType); printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB); printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass); printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass); printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol); printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0); printf(" idVendor 0x%04x\r\n" , desc_device.idVendor); printf(" idProduct 0x%04x\r\n" , desc_device.idProduct); printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice); // Get String descriptor using Sync API printf(" iManufacturer %u ", desc_device.iManufacturer); if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) { print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); } printf("\r\n"); printf(" iProduct %u ", desc_device.iProduct); if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) { print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); } printf("\r\n"); printf(" iSerialNumber %u ", desc_device.iSerialNumber); if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) { print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf)); } printf("\r\n"); printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); // Get configuration descriptor with sync API if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf))) { parse_config_descriptor(daddr, (tusb_desc_configuration_t *) temp_buf); } } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ // count total length of an interface uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); // simple configuration parser to open and listen to HID Endpoint IN void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const *desc_cfg) { uint8_t const *desc_end = ((uint8_t const *) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); uint8_t const *p_desc = tu_desc_next(desc_cfg); // parse each interfaces while (p_desc < desc_end) { uint8_t assoc_itf_count = 1; // Class will always starts with Interface Association (if any) and then Interface descriptor if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) { tusb_desc_interface_assoc_t const *desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; assoc_itf_count = desc_iad->bInterfaceCount; p_desc = tu_desc_next(p_desc);// next to Interface } // must be interface from now if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) { return; } tusb_desc_interface_t const *desc_itf = (tusb_desc_interface_t const *) p_desc; uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end - p_desc)); // probably corrupted descriptor if (drv_len < sizeof(tusb_desc_interface_t)) { return; } // only open and listen to HID endpoint IN if (desc_itf->bInterfaceClass == TUSB_CLASS_HID) { open_hid_interface(dev_addr, desc_itf, drv_len); } // next Interface or IAD descriptor p_desc += drv_len; } } uint16_t count_interface_total_len(tusb_desc_interface_t const *desc_itf, uint8_t itf_count, uint16_t max_len) { uint8_t const *p_desc = (uint8_t const *) desc_itf; uint16_t len = 0; while (itf_count--) { // Next on interface desc len += tu_desc_len(desc_itf); p_desc = tu_desc_next(p_desc); while (len < max_len) { // return on IAD regardless of itf count if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { return len; } if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && ((tusb_desc_interface_t const *) p_desc)->bAlternateSetting == 0) { break; } len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } } return len; } //--------------------------------------------------------------------+ // HID Interface //--------------------------------------------------------------------+ void hid_report_received(tuh_xfer_t* xfer); void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { // len = interface + hid + n*endpoints uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); // corrupted descriptor if (max_len < drv_len) { return; } uint8_t const *p_desc = (uint8_t const *) desc_itf; // HID descriptor p_desc = tu_desc_next(p_desc); tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; if (HID_DESC_TYPE_HID != desc_hid->bDescriptorType) { return; } // Endpoint descriptor p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; for (int i = 0; i < desc_itf->bNumEndpoints; i++) { if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) { return; } if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { if (!tuh_edpt_open(daddr, desc_ep)) { return; // skip if failed to open endpoint } uint8_t *buf = get_hid_buf(daddr); if (!buf) { return;// out of memory } tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = desc_ep->bEndpointAddress, .buflen = 64, .buffer = buf, .complete_cb = hid_report_received, .user_data = (uintptr_t) buf,// since buffer is not available in callback, use user data to store the buffer }; // submit transfer for this EP tuh_edpt_xfer(&xfer); printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); } p_desc = tu_desc_next(p_desc); desc_ep = (tusb_desc_endpoint_t const *) p_desc; } } void hid_report_received(tuh_xfer_t *xfer) { // Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram // For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback uint8_t *buf = (uint8_t *) xfer->user_data; if (xfer->result == XFER_RESULT_SUCCESS) { printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); for (uint32_t i = 0; i < xfer->actual_len; i++) { if (i % 16 == 0) { printf("\r\n "); } printf("%02X ", buf[i]); } printf("\r\n"); } // continue to submit transfer, with updated buffer // other field remain the same xfer->buflen = 64; xfer->buffer = buf; tuh_edpt_xfer(xfer); } //--------------------------------------------------------------------+ // Buffer helper //--------------------------------------------------------------------+ // get an buffer from pool uint8_t *get_hid_buf(uint8_t daddr) { for (size_t i = 0; i < BUF_COUNT; i++) { if (buf_owner[i] == 0) { buf_owner[i] = daddr; return buf_pool[i]; } } // out of memory, increase BUF_COUNT return NULL; } // free all buffer owned by device void free_hid_buf(uint8_t daddr) { for (size_t i = 0; i < BUF_COUNT; i++) { if (buf_owner[i] == daddr) buf_owner[i] = 0; } } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < interval_ms) { return; // not enough time } start_ms += interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } //--------------------------------------------------------------------+ // String Descriptor Helper //--------------------------------------------------------------------+ static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { // TODO: Check for runover. (void) utf8_len; // Get the UTF-16 length out of the data itself. for (size_t i = 0; i < utf16_len; i++) { uint16_t chr = utf16[i]; if (chr < 0x80) { *utf8++ = chr & 0xffu; } else if (chr < 0x800) { *utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F)); *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); } else { // TODO: Verify surrogate. *utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F)); *utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F)); *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); } // TODO: Handle UTF-16 code points that take two entries. } } // Count how many bytes a utf-16-le encoded string will take in utf-8. static int _count_utf8_bytes(const uint16_t *buf, size_t len) { size_t total_bytes = 0; for (size_t i = 0; i < len; i++) { uint16_t chr = buf[i]; if (chr < 0x80) { total_bytes += 1; } else if (chr < 0x800) { total_bytes += 2; } else { total_bytes += 3; } // TODO: Handle UTF-16 code points that take two entries. } return (int) total_bytes; } static void print_utf16(uint16_t *buf, size_t buf_len) { if ((buf[0] & 0xff) == 0) return;// empty size_t utf16_len = ((buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = (size_t) _count_utf8_bytes(buf + 1, utf16_len); _convert_utf16le_to_utf8(buf + 1, utf16_len, (uint8_t *) buf, sizeof(uint16_t) * buf_len); ((uint8_t *) buf)[utf8_len] = '\0'; printf("%s", (char *) buf); } ================================================ FILE: examples/host/bare_api/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 // only hub class is enabled #define CFG_TUH_HUB 1 // max device support (excluding hub device) // 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) // Max endpoint per device #define CFG_TUH_ENDPOINT_MAX 8 // Enable tuh_edpt_xfer() API #define CFG_TUH_API_EDPT_XFER 1 #ifdef __cplusplus } #endif #endif ================================================ FILE: examples/host/cdc_msc_hid/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_msc_hid C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/cdc_msc_hid/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/cdc_msc_hid/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/cdc_app.c \ src/hid_app.c \ src/main.c \ src/msc_app.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/cdc_msc_hid/only.txt ================================================ family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/cdc_msc_hid/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/cdc_msc_hid/src/app.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_TINYUSB_EXAMPLES_APP_H #define TUSB_TINYUSB_EXAMPLES_APP_H #include void cdc_app_task(void); void hid_app_task(void); #endif ================================================ FILE: examples/host/cdc_msc_hid/src/cdc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb.h" #include "bsp/board_api.h" #include "app.h" static size_t get_console_inputs(uint8_t* buf, size_t bufsize) { size_t count = 0; while (count < bufsize) { int ch = board_getchar(); if (ch <= 0) { break; } buf[count] = (uint8_t) ch; count++; } return count; } void cdc_app_task(void) { uint8_t buf[64 + 1]; // +1 for extra null character uint32_t const bufsize = sizeof(buf) - 1; uint32_t count = get_console_inputs(buf, bufsize); buf[count] = 0; // loop over all mounted interfaces for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { if (tuh_cdc_mounted(idx)) { // console --> cdc interfaces if (count > 0) { tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } } } } //--------------------------------------------------------------------+ // TinyUSB callbacks //--------------------------------------------------------------------+ // Invoked when received new data void tuh_cdc_rx_cb(uint8_t idx) { uint8_t buf[64 + 1]; // +1 for extra null character uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console const uint32_t count = tuh_cdc_read(idx, buf, bufsize); if (count) { buf[count] = 0; printf("%s", (char*) buf); #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? fflush(stdout);// flush right away, else nanolib will wait for newline #endif } } // Invoked when a device with CDC interface is mounted // idx is index of cdc interface in the internal pool. void tuh_cdc_mount_cb(uint8_t idx) { tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack // while eneumerating new cdc device cdc_line_coding_t line_coding = {0}; if (tuh_cdc_get_line_coding_local(idx, &line_coding)) { printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #else // Set Line Coding upon mounted cdc_line_coding_t new_line_coding = { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }; tuh_cdc_set_line_coding(idx, &new_line_coding, NULL, 0); #endif } // Invoked when a device with CDC interface is unmounted void tuh_cdc_umount_cb(uint8_t idx) { tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); } ================================================ FILE: examples/host/cdc_msc_hid/src/hid_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "app.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #define MAX_REPORT 4 static uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII}; // Each HID instance can has multiple reports static struct { uint8_t report_count; tuh_hid_report_info_t report_info[MAX_REPORT]; } hid_info[CFG_TUH_HID]; static void process_kbd_report(hid_keyboard_report_t const *report); static void process_mouse_report(hid_mouse_report_t const *report); static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len); void hid_app_task(void) { // nothing to do } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); // Interface protocol (hid_interface_protocol_enum_t) const char *protocol_str[] = {"None", "Keyboard", "Mouse"}; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]); // By default, host stack will use boot protocol on supported interface. // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) if (itf_protocol == HID_ITF_PROTOCOL_NONE) { hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); printf("HID has %u reports \r\n", hid_info[instance].report_count); } // request to receive report // tuh_hid_report_received_cb() will be invoked when report is available if (!tuh_hid_receive_report(dev_addr, instance)) { printf("Error: cannot request to receive report\r\n"); } } // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); } // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); switch (itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: TU_LOG2("HID receive boot keyboard report\r\n"); process_kbd_report((hid_keyboard_report_t const *) report); break; case HID_ITF_PROTOCOL_MOUSE: TU_LOG2("HID receive boot mouse report\r\n"); process_mouse_report((hid_mouse_report_t const *) report); break; default: // Generic report requires matching ReportID and contents with previous parsed report info process_generic_report(dev_addr, instance, report, len); break; } // continue to request to receive report if (!tuh_hid_receive_report(dev_addr, instance)) { printf("Error: cannot request to receive report\r\n"); } } //--------------------------------------------------------------------+ // Keyboard //--------------------------------------------------------------------+ // look up new key in previous keys static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { for (uint8_t i = 0; i < 6; i++) { if (report->keycode[i] == keycode) { return true; } } return false; } static void process_kbd_report(hid_keyboard_report_t const *report) { static hid_keyboard_report_t prev_report = {0, 0, {0}};// previous report to check key released //------------- example code ignore control (non-printable) key affects -------------// for (uint8_t i = 0; i < 6; i++) { if (report->keycode[i]) { if (find_key_in_report(&prev_report, report->keycode[i])) { // exist in previous report means the current key is holding } else { // not existed in previous report means the current key is pressed bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; putchar(ch); if (ch == '\r') { putchar('\n'); } #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? fflush(stdout);// flush right away, else nanolib will wait for newline #endif } } // TODO example skips key released } prev_report = *report; } //--------------------------------------------------------------------+ // Mouse //--------------------------------------------------------------------+ static void cursor_movement(int8_t x, int8_t y, int8_t wheel) { printf("(%d %d %d)\r\n", x, y, wheel); } static void process_mouse_report(hid_mouse_report_t const *report) { static hid_mouse_report_t prev_report = {0}; // button state uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; if (button_changed_mask & report->buttons) { printf(" %c%c%c ", report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); } // cursor movement cursor_movement(report->x, report->y, report->wheel); } //--------------------------------------------------------------------+ // Generic Report //--------------------------------------------------------------------+ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { (void) dev_addr; (void) len; uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info; tuh_hid_report_info_t *rpt_info = NULL; if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) { // Simple report without report ID as 1st byte rpt_info = &rpt_info_arr[0]; } else { // Composite report, 1st byte is report ID, data starts from 2nd byte uint8_t const rpt_id = report[0]; // Find report id in the array for (uint8_t i = 0; i < rpt_count; i++) { if (rpt_id == rpt_info_arr[i].report_id) { rpt_info = &rpt_info_arr[i]; break; } } report++; len--; } if (!rpt_info) { printf("Couldn't find report info !\r\n"); return; } // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples: // - Keyboard : Desktop, Keyboard // - Mouse : Desktop, Mouse // - Gamepad : Desktop, Gamepad // - Consumer Control (Media Key) : Consumer, Consumer Control // - System Control (Power key) : Desktop, System Control // - Generic (vendor) : 0xFFxx, xx if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) { switch (rpt_info->usage) { case HID_USAGE_DESKTOP_KEYBOARD: TU_LOG2("HID receive keyboard report\r\n"); // Assume keyboard follow boot report layout process_kbd_report((hid_keyboard_report_t const *) report); break; case HID_USAGE_DESKTOP_MOUSE: TU_LOG2("HID receive mouse report\r\n"); // Assume mouse follow boot report layout process_mouse_report((hid_mouse_report_t const *) report); break; default: printf("report[%u] ", rpt_info->report_id); for (uint8_t i = 0; i < len; i++) { printf("%02X ", report[i]); } printf("\r\n"); break; } } } ================================================ FILE: examples/host/cdc_msc_hid/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host CDC MSC HID Example\r\n"); // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 // FeatherWing MAX3421E use MAX3421E's GPIO0 for VBUS enable enum { IOPINS1_ADDR = 20u << 3, /* 0xA0 */ }; tuh_max3421_reg_write(BOARD_TUH_RHPORT, IOPINS1_ADDR, 0x01, false); #endif while (1) { // tinyusb host task tuh_task(); led_blinking_task(); cdc_app_task(); hid_app_task(); } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ void tuh_mount_cb(uint8_t dev_addr) { // application set-up printf("A device with address %u is mounted\r\n", dev_addr); } void tuh_umount_cb(uint8_t dev_addr) { // application tear-down printf("A device with address %u is unmounted \r\n", dev_addr); } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < interval_ms) { return;// not enough time } start_ms += interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/host/cdc_msc_hid/src/msc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include "tusb.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ static scsi_inquiry_resp_t inquiry_resp; static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; if (csw->status != 0) { printf("Inquiry failed\r\n"); return false; } // Print out Vendor ID, Product ID and Rev printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev); // Get capacity of device uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } //------------- IMPLEMENTATION -------------// void tuh_msc_mount_cb(uint8_t dev_addr) { printf("A MassStorage device is mounted\r\n"); uint8_t const lun = 0; tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0); } void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; printf("A MassStorage device is unmounted\r\n"); } ================================================ FILE: examples/host/cdc_msc_hid/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_CDC 2 // number of supported CDC devices. also activates CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- HID -------------// #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 //------------- CDC -------------// // Set Line Control state on enumeration/mounted: // DTR ( bit 0), RTS (bit 1) #define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width #define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/host/cdc_msc_hid_freertos/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc_msc_hid_freertos C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} freertos) ================================================ FILE: examples/host/cdc_msc_hid_freertos/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/cdc_msc_hid_freertos/Makefile ================================================ RTOS = freertos include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE = \ src/cdc_app.c \ src/hid_app.c \ src/main.c \ src/msc_app.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/cdc_msc_hid_freertos/only.txt ================================================ family:espressif family:samd21 family:samd5x_e5x mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/cdc_msc_hid_freertos/skip.txt ================================================ mcu:CH32F20X mcu:RP2040 board:lpcxpresso54114 mcu:FT90X ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "cdc_app.c" "hid_app.c" "main.c" "msc_app.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/app.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_TINYUSB_EXAMPLES_APP_H #define TUSB_TINYUSB_EXAMPLES_APP_H #include void cdc_app_init(void); void hid_app_init(void); void msc_app_init(void); #endif ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/cdc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb.h" #include "bsp/board_api.h" #include "app.h" #ifdef ESP_PLATFORM #define CDC_STACK_SZIE 2048 #else #define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2) #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #if configSUPPORT_STATIC_ALLOCATION StackType_t cdc_stack[CDC_STACK_SZIE]; StaticTask_t cdc_taskdef; #endif static void cdc_app_task(void* param); void cdc_app_init(void) { #if configSUPPORT_STATIC_ALLOCATION (void) xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); #else (void) xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); #endif } // helper static size_t get_console_inputs(uint8_t *buf, size_t bufsize) { size_t count = 0; while (count < bufsize) { int ch = board_getchar(); if (ch <= 0) { break; } buf[count] = (uint8_t) ch; count++; } return count; } static void cdc_app_task(void* param) { (void) param; uint8_t buf[64 + 1]; // +1 for extra null character uint32_t const bufsize = sizeof(buf) - 1; while (1) { uint32_t count = get_console_inputs(buf, bufsize); buf[count] = 0; if (count) { // loop over all mounted interfaces for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { if (tuh_cdc_mounted(idx)) { // console --> cdc interfaces tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } } } vTaskDelay(1); } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ // Invoked when received new data void tuh_cdc_rx_cb(uint8_t idx) { uint8_t buf[64 + 1]; // +1 for extra null character uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console uint32_t count = tuh_cdc_read(idx, buf, bufsize); buf[count] = 0; printf("%s", (char *) buf); } void tuh_cdc_mount_cb(uint8_t idx) { tuh_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration // otherwise you need to call tuh_cdc_set_line_coding() first cdc_line_coding_t line_coding = { 0 }; if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #endif } void tuh_cdc_umount_cb(uint8_t idx) { tuh_itf_info_t itf_info = { 0 }; tuh_cdc_itf_get_info(idx, &itf_info); printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); } ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/hid_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "app.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // If your host terminal support ansi escape code such as TeraTerm // it can be use to simulate mouse cursor movement within terminal #define USE_ANSI_ESCAPE 0 #define MAX_REPORT 4 static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; // Each HID instance can has multiple reports static struct { uint8_t report_count; tuh_hid_report_info_t report_info[MAX_REPORT]; } hid_info[CFG_TUH_HID]; static void process_kbd_report(hid_keyboard_report_t const *report); static void process_mouse_report(hid_mouse_report_t const *report); static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len); void hid_app_init(void) { // nothing to do } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); // Interface protocol (hid_interface_protocol_enum_t) const char *protocol_str[] = { "None", "Keyboard", "Mouse" }; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]); // By default host stack will use activate boot protocol on supported interface. // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) if (itf_protocol == HID_ITF_PROTOCOL_NONE) { hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); printf("HID has %u reports \r\n", hid_info[instance].report_count); } // request to receive report // tuh_hid_report_received_cb() will be invoked when report is available if (!tuh_hid_receive_report(dev_addr, instance)) { printf("Error: cannot request to receive report\r\n"); } } // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); } // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); switch (itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: TU_LOG2("HID receive boot keyboard report\r\n"); process_kbd_report((hid_keyboard_report_t const *) report); break; case HID_ITF_PROTOCOL_MOUSE: TU_LOG2("HID receive boot mouse report\r\n"); process_mouse_report((hid_mouse_report_t const *) report); break; default: // Generic report requires matching ReportID and contents with previous parsed report info process_generic_report(dev_addr, instance, report, len); break; } // continue to request to receive report if (!tuh_hid_receive_report(dev_addr, instance)) { printf("Error: cannot request to receive report\r\n"); } } //--------------------------------------------------------------------+ // Keyboard //--------------------------------------------------------------------+ // look up new key in previous keys static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { for (uint8_t i = 0; i < 6; i++) { if (report->keycode[i] == keycode) return true; } return false; } static void process_kbd_report(hid_keyboard_report_t const *report) { static hid_keyboard_report_t prev_report = { 0, 0, { 0 } }; // previous report to check key released //------------- example code ignore control (non-printable) key affects -------------// for (uint8_t i = 0; i < 6; i++) { if (report->keycode[i]) { if (find_key_in_report(&prev_report, report->keycode[i])) { // exist in previous report means the current key is holding } else { // not existed in previous report means the current key is pressed bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; putchar(ch); if (ch == '\r') putchar('\n'); // added new line for enter key #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? fflush(stdout); // flush right away, else nanolib will wait for newline #endif } } // TODO example skips key released } prev_report = *report; } //--------------------------------------------------------------------+ // Mouse //--------------------------------------------------------------------+ static void cursor_movement(int8_t x, int8_t y, int8_t wheel) { #if USE_ANSI_ESCAPE // Move X using ansi escape if ( x < 0) { printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left }else if ( x > 0) { printf(ANSI_CURSOR_FORWARD(%d), x); // move right } // Move Y using ansi escape if ( y < 0) { printf(ANSI_CURSOR_UP(%d), (-y)); // move up }else if ( y > 0) { printf(ANSI_CURSOR_DOWN(%d), y); // move down } // Scroll using ansi escape if (wheel < 0) { printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up }else if (wheel > 0) { printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down } printf("\r\n"); #else printf("(%d %d %d)\r\n", x, y, wheel); #endif } static void process_mouse_report(hid_mouse_report_t const *report) { static hid_mouse_report_t prev_report = { 0 }; //------------- button state -------------// uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; if (button_changed_mask & report->buttons) { printf(" %c%c%c ", report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); } //------------- cursor movement -------------// cursor_movement(report->x, report->y, report->wheel); } //--------------------------------------------------------------------+ // Generic Report //--------------------------------------------------------------------+ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { (void) dev_addr; (void) len; uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info; tuh_hid_report_info_t *rpt_info = NULL; if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) { // Simple report without report ID as 1st byte rpt_info = &rpt_info_arr[0]; } else { // Composite report, 1st byte is report ID, data starts from 2nd byte uint8_t const rpt_id = report[0]; // Find report id in the array for (uint8_t i = 0; i < rpt_count; i++) { if (rpt_id == rpt_info_arr[i].report_id) { rpt_info = &rpt_info_arr[i]; break; } } report++; len--; } if (!rpt_info) { printf("Couldn't find report info !\r\n"); return; } // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples: // - Keyboard : Desktop, Keyboard // - Mouse : Desktop, Mouse // - Gamepad : Desktop, Gamepad // - Consumer Control (Media Key) : Consumer, Consumer Control // - System Control (Power key) : Desktop, System Control // - Generic (vendor) : 0xFFxx, xx if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) { switch (rpt_info->usage) { case HID_USAGE_DESKTOP_KEYBOARD: TU_LOG1("HID receive keyboard report\r\n"); // Assume keyboard follow boot report layout process_kbd_report((hid_keyboard_report_t const *) report); break; case HID_USAGE_DESKTOP_MOUSE: TU_LOG1("HID receive mouse report\r\n"); // Assume mouse follow boot report layout process_mouse_report((hid_mouse_report_t const *) report); break; default: break; } } } ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" #include "app.h" #ifdef ESP_PLATFORM #define USBH_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled #define USBH_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2)) #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; // static timer & task #if configSUPPORT_STATIC_ALLOCATION StaticTimer_t blinky_tmdef; StackType_t usb_host_stack[USBH_STACK_SIZE]; StaticTask_t usb_host_taskdef; #endif TimerHandle_t blinky_tm; static void led_blinky_cb(TimerHandle_t xTimer); static void usb_host_task(void* param); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n"); // Create soft timer for blinky, task for tinyusb stack #if configSUPPORT_STATIC_ALLOCATION blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); #else blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); xTaskCreate(usb_host_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); #endif xTimerStart(blinky_tm, 0); // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif return 0; } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif // USB Host task // This top level thread process all usb events and invoke callbacks static void usb_host_task(void *param) { (void) param; // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; if (!tusb_init(BOARD_TUH_RHPORT, &host_init)) { printf("Failed to init USB Host Stack\r\n"); vTaskSuspend(NULL); } board_init_after_tusb(); #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 // FeatherWing MAX3421E use MAX3421E's GPIO0 for VBUS enable enum { IOPINS1_ADDR = 20u << 3, /* 0xA0 */ }; tuh_max3421_reg_write(BOARD_TUH_RHPORT, IOPINS1_ADDR, 0x01, false); #endif cdc_app_init(); hid_app_init(); msc_app_init(); // RTOS forever loop while (1) { // put this thread to waiting state until there is new events tuh_task(); // following code only run if tuh_task() process at least 1 event } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ void tuh_mount_cb(uint8_t dev_addr) { // application set-up printf("A device with address %d is mounted\r\n", dev_addr); } void tuh_umount_cb(uint8_t dev_addr) { // application tear-down printf("A device with address %d is unmounted \r\n", dev_addr); } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ static void led_blinky_cb(TimerHandle_t xTimer) { (void) xTimer; static bool led_state = false; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/msc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include "tusb.h" #include "app.h" // define the buffer to be place in USB/DMA memory with correct alignment/cache line size CFG_TUH_MEM_SECTION static struct { TUH_EPBUF_TYPE_DEF(scsi_inquiry_resp_t, inquiry); } scsi_resp; void msc_app_init(void) { // nothing to do } static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) { msc_cbw_t const *cbw = cb_data->cbw; msc_csw_t const *csw = cb_data->csw; if (csw->status != 0) { printf("Inquiry failed\r\n"); return false; } // Print out Vendor ID, Product ID and Rev printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev); // Get capacity of device uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024 * 1024) / block_size)); printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } //------------- IMPLEMENTATION -------------// void tuh_msc_mount_cb(uint8_t dev_addr) { printf("A MassStorage device is mounted\r\n"); uint8_t const lun = 0; tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0); } void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; printf("A MassStorage device is unmounted\r\n"); } ================================================ FILE: examples/host/cdc_msc_hid_freertos/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_FREERTOS #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_CDC 1 // number of supported CDC devices. also activates CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- HID -------------// #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 //------------- CDC -------------// // Set Line Control state on enumeration/mounted: // DTR ( bit 0), RTS (bit 1) #define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width #define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/host/device_info/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(device_info C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/device_info/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/device_info/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/device_info/only.txt ================================================ family:espressif family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/device_info/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/device_info/src/CMakeLists.txt ================================================ # This file is for ESP-IDF only idf_component_register(SRCS "main.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) ================================================ FILE: examples/host/device_info/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows: * Device 1: ID 046d:c52f SN 11223344 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 0200 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x046d idProduct 0xc52f bcdDevice 2200 iManufacturer 1 Logitech iProduct 2 USB Receiver iSerialNumber 0 bNumConfigurations 1 * */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" // English #define LANGUAGE_ID 0x0409 //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; // Declare for buffer for usb transfer, may need to be in USB/DMA section and // multiple of dcache line size if dcache is enabled (for some ports). CFG_TUH_MEM_SECTION struct { TUH_EPBUF_TYPE_DEF(tusb_desc_device_t, device); TUH_EPBUF_DEF(serial, 64*sizeof(uint16_t)); TUH_EPBUF_DEF(buf, 128*sizeof(uint16_t)); } desc; void led_blinking_task(void* param); static void print_utf16(uint16_t* temp_buf, size_t buf_len); #if CFG_TUSB_OS == OPT_OS_FREERTOS void init_freertos_task(void); #endif //-------------------------------------------------------------------- // Main //-------------------------------------------------------------------- static void init_tinyusb(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); } int main(void) { board_init(); printf("TinyUSB Device Info Example\r\n"); #if CFG_TUSB_OS == OPT_OS_FREERTOS init_freertos_task(); #else board_delay(100); // wait for uart to be ready init_tinyusb(); while (1) { tuh_task(); // tinyusb host task led_blinking_task(NULL); } #endif } /*------------- TinyUSB Callbacks -------------*/ // Invoked when device is mounted (configured) void tuh_mount_cb(uint8_t daddr) { blink_interval_ms = BLINK_MOUNTED; // Get Device Descriptor uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc.device, 18); if (XFER_RESULT_SUCCESS != xfer_result) { printf("Failed to get device descriptor\r\n"); return; } printf("Device %u: ID %04x:%04x SN ", daddr, desc.device.idVendor, desc.device.idProduct); xfer_result = XFER_RESULT_FAILED; if (desc.device.iSerialNumber != 0) { xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, desc.serial, sizeof(desc.serial)); } if (XFER_RESULT_SUCCESS != xfer_result) { uint16_t* serial = (uint16_t*)(uintptr_t) desc.serial; serial[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * 1 + 2)); serial[1] = '0'; // simply 0 serial[2] = 0; } print_utf16((uint16_t*)(uintptr_t) desc.serial, sizeof(desc.serial)/2); printf("\r\n"); printf("Device Descriptor:\r\n"); printf(" bLength %u\r\n", desc.device.bLength); printf(" bDescriptorType %u\r\n", desc.device.bDescriptorType); printf(" bcdUSB %04x\r\n", desc.device.bcdUSB); printf(" bDeviceClass %u\r\n", desc.device.bDeviceClass); printf(" bDeviceSubClass %u\r\n", desc.device.bDeviceSubClass); printf(" bDeviceProtocol %u\r\n", desc.device.bDeviceProtocol); printf(" bMaxPacketSize0 %u\r\n", desc.device.bMaxPacketSize0); printf(" idVendor 0x%04x\r\n", desc.device.idVendor); printf(" idProduct 0x%04x\r\n", desc.device.idProduct); printf(" bcdDevice %04x\r\n", desc.device.bcdDevice); // Get String descriptor using Sync API printf(" iManufacturer %u ", desc.device.iManufacturer); if (desc.device.iManufacturer != 0) { xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf)); if (XFER_RESULT_SUCCESS == xfer_result) { print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2); } } printf("\r\n"); printf(" iProduct %u ", desc.device.iProduct); if (desc.device.iProduct != 0) { xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf)); if (XFER_RESULT_SUCCESS == xfer_result) { print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2); } } printf("\r\n"); printf(" iSerialNumber %u ", desc.device.iSerialNumber); printf("%s\r\n", (char*)desc.serial); // serial is already to UTF-8 printf(" bNumConfigurations %u\r\n", desc.device.bNumConfigurations); } // Invoked when device is unmounted (bus reset/unplugged) void tuh_umount_cb(uint8_t daddr) { blink_interval_ms = BLINK_NOT_MOUNTED; printf("Device removed, address = %d\r\n", daddr); } //--------------------------------------------------------------------+ // String Descriptor Helper //--------------------------------------------------------------------+ static void _convert_utf16le_to_utf8(const uint16_t* utf16, size_t utf16_len, uint8_t* utf8, size_t utf8_len) { // TODO: Check for runover. (void) utf8_len; // Get the UTF-16 length out of the data itself. for (size_t i = 0; i < utf16_len; i++) { uint16_t chr = utf16[i]; if (chr < 0x80) { *utf8++ = chr & 0xffu; } else if (chr < 0x800) { *utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F)); *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); } else { // TODO: Verify surrogate. *utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F)); *utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F)); *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F)); } // TODO: Handle UTF-16 code points that take two entries. } } // Count how many bytes a utf-16-le encoded string will take in utf-8. static int _count_utf8_bytes(const uint16_t* buf, size_t len) { size_t total_bytes = 0; for (size_t i = 0; i < len; i++) { uint16_t chr = buf[i]; if (chr < 0x80) { total_bytes += 1; } else if (chr < 0x800) { total_bytes += 2; } else { total_bytes += 3; } // TODO: Handle UTF-16 code points that take two entries. } return (int) total_bytes; } static void print_utf16(uint16_t* temp_buf, size_t buf_len) { if ((temp_buf[0] & 0xff) == 0) return; // empty size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len); _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t*) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; printf("%s", (char*) temp_buf); } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void* param) { (void) param; static uint32_t start_ms = 0; static bool led_state = false; while (1) { #if CFG_TUSB_OS == OPT_OS_FREERTOS vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); #else if (tusb_time_millis_api() - start_ms < blink_interval_ms) { return; // not enough time } #endif start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } } //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_FREERTOS #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #ifdef ESP_PLATFORM #define USB_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled #define USB_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif // static task #if configSUPPORT_STATIC_ALLOCATION StackType_t blinky_stack[BLINKY_STACK_SIZE]; StaticTask_t blinky_taskdef; StackType_t usb_stack[USB_STACK_SIZE]; StaticTask_t usb_taskdef; #endif #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif void usb_host_task(void *param) { (void) param; board_delay(100); // wait for uart to be ready init_tinyusb(); while (1) { tuh_task(); } } void init_freertos_task(void) { #if configSUPPORT_STATIC_ALLOCATION xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); xTaskCreateStatic(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_stack, &usb_taskdef); #else xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); xTaskCreate(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); #endif // only start scheduler for non-espressif mcu #ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } #endif ================================================ FILE: examples/host/device_info/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 // only hub class is enabled #define CFG_TUH_HUB 1 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) #ifdef __cplusplus } #endif #endif ================================================ FILE: examples/host/hid_controller/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(hid_controller C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/hid_controller/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/hid_controller/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/hid_app.c \ src/main.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/hid_controller/only.txt ================================================ family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/hid_controller/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/hid_controller/src/app.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_TINYUSB_EXAMPLES_APP_H #define TUSB_TINYUSB_EXAMPLES_APP_H #include void hid_app_task(void); #endif ================================================ FILE: examples/host/hid_controller/src/hid_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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 "bsp/board_api.h" #include "tusb.h" #include "app.h" /* From https://www.kernel.org/doc/html/latest/input/gamepad.html ____________________________ __ / [__ZL__] [__ZR__] \ | / [__ TL __] [__ TR __] \ | Front Triggers __/________________________________\__ __| / _ \ | / /\ __ (N) \ | / || __ |MO| __ _ _ \ | Main Pad | <===DP===> |SE| |ST| (W) -|- (E) | | \ || ___ ___ _ / | /\ \/ / \ / \ (S) /\ __| / \________ | LS | ____ | RS | ________/ \ | | / \ \___/ / \ \___/ / \ | | Control Sticks | / \_____/ \_____/ \ | __| | / \ | \_____/ \_____/ |________|______| |______|___________| D-Pad Left Right Action Pad Stick Stick |_____________| Menu Pad Most gamepads have the following features: - Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST. - D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right. - Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START. - Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also provide a digital button if you press them. - Triggers are located on the upper-side of the pad in vertical direction. The upper buttons are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right. - Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors. */ // Sony DS4 report layout detail https://www.psdevwiki.com/ps4/DS4-USB typedef struct TU_ATTR_PACKED { uint8_t x, y, z, rz; // joystick struct { uint8_t dpad : 4; // (hat format, 0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW) uint8_t square : 1; // west uint8_t cross : 1; // south uint8_t circle : 1; // east uint8_t triangle : 1; // north }; struct { uint8_t l1 : 1; uint8_t r1 : 1; uint8_t l2 : 1; uint8_t r2 : 1; uint8_t share : 1; uint8_t option : 1; uint8_t l3 : 1; uint8_t r3 : 1; }; struct { uint8_t ps : 1; // playstation button uint8_t tpad : 1; // track pad click uint8_t counter : 6; // +1 each report }; uint8_t l2_trigger; // 0 released, 0xff fully pressed uint8_t r2_trigger; // as above // uint16_t timestamp; // uint8_t battery; // // int16_t gyro[3]; // x, y, z; // int16_t accel[3]; // x, y, z // there is still lots more info } sony_ds4_report_t; typedef struct TU_ATTR_PACKED { // First 16 bits set what data is pertinent in this structure (1 = set; 0 = not set) uint8_t set_rumble : 1; uint8_t set_led : 1; uint8_t set_led_blink : 1; uint8_t set_ext_write : 1; uint8_t set_left_volume : 1; uint8_t set_right_volume : 1; uint8_t set_mic_volume : 1; uint8_t set_speaker_volume : 1; uint8_t set_flags2; uint8_t reserved; uint8_t motor_right; uint8_t motor_left; uint8_t lightbar_red; uint8_t lightbar_green; uint8_t lightbar_blue; uint8_t lightbar_blink_on; uint8_t lightbar_blink_off; uint8_t ext_data[8]; uint8_t volume_left; uint8_t volume_right; uint8_t volume_mic; uint8_t volume_speaker; uint8_t other[9]; } sony_ds4_output_report_t; static bool ds4_mounted = false; static uint8_t ds4_dev_addr = 0; static uint8_t ds4_instance = 0; static uint8_t motor_left = 0; static uint8_t motor_right = 0; // check if device is Sony DualShock 4 static inline bool is_sony_ds4(uint8_t dev_addr) { uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); return ( (vid == 0x054c && (pid == 0x09cc || pid == 0x05c4)) // Sony DualShock4 || (vid == 0x0f0d && pid == 0x005e) // Hori FC4 || (vid == 0x0f0d && pid == 0x00ee) // Hori PS4 Mini (PS4-099U) || (vid == 0x1f4f && pid == 0x1002) // ASW GG xrd controller ); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ void hid_app_task(void) { if (ds4_mounted) { const uint32_t interval_ms = 200; static uint32_t start_ms = 0; uint32_t current_time_ms = tusb_time_millis_api(); if ( current_time_ms - start_ms >= interval_ms) { start_ms = current_time_ms; sony_ds4_output_report_t output_report = {0}; output_report.set_rumble = 1; output_report.motor_left = motor_left; output_report.motor_right = motor_right; tuh_hid_send_report(ds4_dev_addr, ds4_instance, 5, &output_report, sizeof(output_report)); } } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { (void)desc_report; (void)desc_len; uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); printf("VID = %04x, PID = %04x\r\n", vid, pid); // Sony DualShock 4 [CUH-ZCT2x] if ( is_sony_ds4(dev_addr) ) { if (!ds4_mounted) { ds4_dev_addr = dev_addr; ds4_instance = instance; motor_left = 0; motor_right = 0; ds4_mounted = true; } // request to receive report // tuh_hid_report_received_cb() will be invoked when report is available if ( !tuh_hid_receive_report(dev_addr, instance) ) { printf("Error: cannot request to receive report\r\n"); } } } // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); if (ds4_mounted && ds4_dev_addr == dev_addr && ds4_instance == instance) { ds4_mounted = false; } } // check if different than 2 static inline bool diff_than_2(uint8_t x, uint8_t y) { return (x - y > 2) || (y - x > 2); } // check if 2 reports are different enough static bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) { bool result; // x, y, z, rz must different than 2 to be counted result = diff_than_2(rpt1->x, rpt2->x) || diff_than_2(rpt1->y , rpt2->y ) || diff_than_2(rpt1->z, rpt2->z) || diff_than_2(rpt1->rz, rpt2->rz); // check the rest with mem compare result |= memcmp(&rpt1->rz + 1, &rpt2->rz + 1, sizeof(sony_ds4_report_t)-6); return result; } static void process_sony_ds4(uint8_t const* report, uint16_t len) { (void)len; const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" }; // previous report used to compare for changes static sony_ds4_report_t prev_report = { 0 }; uint8_t const report_id = report[0]; report++; len--; // all buttons state is stored in ID 1 if (report_id == 1) { sony_ds4_report_t ds4_report; memcpy(&ds4_report, report, sizeof(ds4_report)); // counter is +1, assign to make it easier to compare 2 report prev_report.counter = ds4_report.counter; // only print if changes since it is polled ~ 5ms // Since count+1 after each report and x, y, z, rz fluctuate within 1 or 2 // We need more than memcmp to check if report is different enough if ( diff_report(&prev_report, &ds4_report) ) { printf("(x, y, z, rz) = (%u, %u, %u, %u)\r\n", ds4_report.x, ds4_report.y, ds4_report.z, ds4_report.rz); printf("DPad = %s ", dpad_str[ds4_report.dpad]); if (ds4_report.square ) printf("Square "); if (ds4_report.cross ) printf("Cross "); if (ds4_report.circle ) printf("Circle "); if (ds4_report.triangle ) printf("Triangle "); if (ds4_report.l1 ) printf("L1 "); if (ds4_report.r1 ) printf("R1 "); if (ds4_report.l2 ) printf("L2 "); if (ds4_report.r2 ) printf("R2 "); if (ds4_report.share ) printf("Share "); if (ds4_report.option ) printf("Option "); if (ds4_report.l3 ) printf("L3 "); if (ds4_report.r3 ) printf("R3 "); if (ds4_report.ps ) printf("PS "); if (ds4_report.tpad ) printf("TPad "); printf("\r\n"); } // The left and right triggers control the intensity of the left and right rumble motors motor_left = ds4_report.l2_trigger; motor_right = ds4_report.r2_trigger; prev_report = ds4_report; } } // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { if (is_sony_ds4(dev_addr)) { process_sony_ds4(report, len); } // continue to request to receive report if (!tuh_hid_receive_report(dev_addr, instance)) { printf("Error: cannot request to receive report\r\n"); } } ================================================ FILE: examples/host/hid_controller/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* This example current worked and tested with following controller * - Sony DualShock 4 [CUH-ZCT2x] VID = 0x054c, PID = 0x09cc */ #include #include #include #include "bsp/board_api.h" #include "tusb.h" #include "app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host HID Controller Example\r\n"); printf("Note: Events only displayed for explicit supported controllers\r\n"); // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); while (1) { // tinyusb host task tuh_task(); led_blinking_task(); hid_app_task(); } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if ( tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/host/hid_controller/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 0 #define CFG_TUH_CDC 0 #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 0 #define CFG_TUH_VENDOR 0 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- HID -------------// #define CFG_TUH_HID_EP_BUFSIZE 64 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/host/midi_rx/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(midi_rx C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/midi_rx/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/midi_rx/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/midi_rx/only.txt ================================================ family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:ESP32P4 mcu:ESP32S2 mcu:ESP32S3 mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/midi_rx/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/midi_rx/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // STATIC GLOBALS DECLARATION //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); void midi_host_rx_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host MIDI Example\r\n"); // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); while (1) { tuh_task(); led_blinking_task(); midi_host_rx_task(); } } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < interval_ms) return;// not enough time start_ms += interval_ms; board_led_write(led_state); led_state = 1 - led_state;// toggle } //--------------------------------------------------------------------+ // MIDI host receive task //--------------------------------------------------------------------+ void midi_host_rx_task(void) { // nothing to do, we just print out received data in callback } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ // Invoked when device with MIDI interface is mounted. void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data) { printf("MIDI Interface Index = %u, Address = %u, Number of RX cables = %u, Number of TX cables = %u\r\n", idx, mount_cb_data->daddr, mount_cb_data->rx_cable_count, mount_cb_data->tx_cable_count); } // Invoked when device with hid interface is un-mounted void tuh_midi_umount_cb(uint8_t idx) { printf("MIDI Interface Index = %u is unmounted\r\n", idx); } void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes) { if (xferred_bytes == 0) { return; } uint8_t buffer[48]; uint8_t cable_num = 0; uint32_t bytes_read = tuh_midi_stream_read(idx, &cable_num, buffer, sizeof(buffer)); printf("Cable %u rx: ", cable_num); for (uint32_t i = 0; i < bytes_read; i++) { printf("%02X ", buffer[i]); } printf("\r\n"); } void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) idx; (void) xferred_bytes; } ================================================ FILE: examples/host/midi_rx/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif // Espressif IDF requires "freertos/" prefix in include path #ifdef ESP_PLATFORM #define CFG_TUSB_OS_INC_PATH freertos/ #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // #define CFG_TUH_MAX3421 1 // use max3421 as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) #define CFG_TUH_MIDI CFG_TUH_DEVICE_MAX #ifdef __cplusplus } #endif #endif ================================================ FILE: examples/host/msc_file_explorer/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(msc_file_explorer C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c ${TOP}/lib/fatfs/source/ff.c ${TOP}/lib/fatfs/source/ffsystem.c ${TOP}/lib/fatfs/source/ffunicode.c ) # Suppress warnings on fatfs if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${TOP}/lib/fatfs/source/ff.c PROPERTIES COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual" ) endif () # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ${TOP}/lib/fatfs/source ${TOP}/lib/embedded-cli ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT_NAME} noos) ================================================ FILE: examples/host/msc_file_explorer/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/host/msc_file_explorer/Makefile ================================================ include ../../../hw/bsp/family_support.mk FATFS_PATH = lib/fatfs/source INC += \ src \ $(TOP)/$(FATFS_PATH) \ $(TOP)/lib/embedded-cli \ # Example source EXAMPLE_SOURCE = \ src/main.c \ src/msc_app.c \ SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) # FatFS source SRC_C += \ $(FATFS_PATH)/ff.c \ $(FATFS_PATH)/ffsystem.c \ $(FATFS_PATH)/ffunicode.c \ # suppress warning caused by fatfs CFLAGS_GCC += -Wno-error=cast-qual include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/host/msc_file_explorer/only.txt ================================================ family:hpmicro family:samd21 family:samd5x_e5x mcu:CH32V20X mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX mcu:LPC40XX mcu:LPC43XX mcu:LPC54 mcu:LPC55 mcu:MAX3421 mcu:MIMXRT10XX mcu:MIMXRT11XX mcu:MIMXRT1XXX mcu:MSP432E4 mcu:RAXXX mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 mcu:STM32H5 mcu:STM32H7 mcu:STM32H7RS mcu:STM32N6 mcu:STM32U3 mcu:STM32U5 ================================================ FILE: examples/host/msc_file_explorer/skip.txt ================================================ board:lpcxpresso54114 ================================================ FILE: examples/host/msc_file_explorer/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ /* Example to show how to navigate mass storage device with built-in command line. * Type help for list of supported commands and syntax (mostly linux commands) > help * help Print list of commands * cat Usage: cat [FILE]... Concatenate FILE(s) to standard output.. * cd Usage: cd [DIR]... Change the current directory to DIR. * cp Usage: cp SOURCE DEST Copy SOURCE to DEST. * ls Usage: ls [DIR]... List information about the FILEs (the current directory by default). * pwd Usage: pwd Print the name of the current working directory. * mkdir Usage: mkdir DIR... Create the DIRECTORY(ies), if they do not already exist.. * mv Usage: mv SOURCE DEST... Rename SOURCE to DEST. * rm Usage: rm [FILE]... Remove (unlink) the FILE(s). */ #include #include #include "bsp/board_api.h" #include "tusb.h" #include "msc_app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); /*------------- MAIN -------------*/ int main(void) { board_init(); printf("TinyUSB Host MassStorage Explorer Example\r\n"); // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); board_init_after_tusb(); msc_app_init(); while (1) { // tinyusb host task tuh_task(); msc_app_task(); led_blinking_task(); } } //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ void tuh_mount_cb(uint8_t dev_addr) { (void) dev_addr; } void tuh_umount_cb(uint8_t dev_addr) { (void) dev_addr; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if (tusb_time_millis_api() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/host/msc_file_explorer/src/msc_app.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include "tusb.h" #include "bsp/board_api.h" #include "ff.h" #include "diskio.h" // lib/embedded-cli #define EMBEDDED_CLI_IMPL #include "embedded_cli.h" #include "msc_app.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ //------------- embedded-cli -------------// #define CLI_BUFFER_SIZE 512 #define CLI_RX_BUFFER_SIZE 16 #define CLI_CMD_BUFFER_SIZE 64 #define CLI_HISTORY_SIZE 32 #define CLI_BINDING_COUNT 8 static EmbeddedCli *_cli; static CLI_UINT cli_buffer[BYTES_TO_CLI_UINTS(CLI_BUFFER_SIZE)]; //------------- Elm Chan FatFS -------------// static CFG_TUH_MEM_SECTION FATFS fatfs[CFG_TUH_DEVICE_MAX]; // for simplicity only support 1 LUN per device static volatile bool _disk_busy[CFG_TUH_DEVICE_MAX]; static CFG_TUH_MEM_SECTION FIL file1, file2; static CFG_TUH_MEM_SECTION uint8_t rw_buf[512]; // define the buffer to be place in USB/DMA memory with correct alignment/cache line size CFG_TUH_MEM_SECTION static struct { TUH_EPBUF_TYPE_DEF(scsi_inquiry_resp_t, inquiry); } scsi_resp; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool cli_init(void); bool msc_app_init(void) { for (size_t i = 0; i < CFG_TUH_DEVICE_MAX; i++) { _disk_busy[i] = false; } // disable stdout buffered for echoing typing command #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? setbuf(stdout, NULL); #endif cli_init(); return true; } void msc_app_task(void) { if (!_cli) { return; } int ch = board_getchar(); if (ch > 0) { while (ch > 0) { embeddedCliReceiveChar(_cli, (char)ch); ch = board_getchar(); } embeddedCliProcess(_cli); } } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ static bool inquiry_complete_cb(uint8_t dev_addr, const tuh_msc_complete_data_t *cb_data) { const msc_cbw_t *cbw = cb_data->cbw; const msc_csw_t *csw = cb_data->csw; if (csw->status != 0) { printf("Inquiry failed\r\n"); return false; } // Print out Vendor ID, Product ID and Rev printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev); // Get capacity of device const uint32_t block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); const uint32_t block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024 * 1024) / block_size)); // printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); // For simplicity: we only mount 1 LUN per device const uint8_t drive_num = dev_addr - 1; char drive_path[3] = "0:"; drive_path[0] += drive_num; if (f_mount(&fatfs[drive_num], drive_path, 1) != FR_OK) { printf("mount failed\r\n"); return true; } // change to newly mounted drive f_chdrive(drive_path); FRESULT rc = f_chdir("/"); if (rc != FR_OK) { printf("chdir failed: %d\r\n", rc); } // print the drive label // char label[34]; // if ( FR_OK == f_getlabel(drive_path, label, NULL) ) // { // puts(label); // } return true; } //------------- IMPLEMENTATION -------------// void tuh_msc_mount_cb(uint8_t dev_addr) { printf("A MassStorage device (addr = %u) is mounted\r\n", dev_addr); const uint8_t lun = 0; tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0); } void tuh_msc_umount_cb(uint8_t dev_addr) { printf("A MassStorage device is unmounted\r\n"); const uint8_t drive_num = dev_addr - 1; char drive_path[3] = "0:"; drive_path[0] += drive_num; f_unmount(drive_path); // if ( phy_disk == f_get_current_drive() ) // { // active drive is unplugged --> change to other drive // for(uint8_t i=0; icliBuffer = cli_buffer; config->cliBufferSize = CLI_BUFFER_SIZE; config->rxBufferSize = CLI_RX_BUFFER_SIZE; config->cmdBufferSize = CLI_CMD_BUFFER_SIZE; config->historyBufferSize = CLI_HISTORY_SIZE; config->maxBindingCount = CLI_BINDING_COUNT; TU_ASSERT(embeddedCliRequiredSize(config) <= CLI_BUFFER_SIZE); _cli = embeddedCliNew(config); TU_ASSERT(_cli != NULL); _cli->writeChar = cli_write_char; embeddedCliAddBinding(_cli, (CliCommandBinding){"cat", "Usage: cat [FILE]...\r\n\tConcatenate FILE(s) to standard output..", true, NULL, cli_cmd_cat}); embeddedCliAddBinding(_cli, (CliCommandBinding){"cd", "Usage: cd [DIR]...\r\n\tChange the current directory to DIR.", true, NULL, cli_cmd_cd}); embeddedCliAddBinding(_cli, (CliCommandBinding){"cp", "Usage: cp SOURCE DEST\r\n\tCopy SOURCE to DEST.", true, NULL, cli_cmd_cp}); embeddedCliAddBinding(_cli, (CliCommandBinding){"ls", "Usage: ls [DIR]...\r\n\tList information about the FILEs (the " "current directory by default).", true, NULL, cli_cmd_ls}); embeddedCliAddBinding(_cli, (CliCommandBinding){"pwd", "Usage: pwd\r\n\tPrint the name of the current working directory.", true, NULL, cli_cmd_pwd}); embeddedCliAddBinding(_cli, (CliCommandBinding){"mkdir", "Usage: mkdir DIR...\r\n\tCreate the DIRECTORY(ies), if they do not " "already exist..", true, NULL, cli_cmd_mkdir}); embeddedCliAddBinding(_cli, (CliCommandBinding){"mv", "Usage: mv SOURCE DEST...\r\n\tRename SOURCE to DEST.", true, NULL, cli_cmd_mv}); embeddedCliAddBinding(_cli, (CliCommandBinding){"rm", "Usage: rm [FILE]...\r\n\tRemove (unlink) the FILE(s).", true, NULL, cli_cmd_rm}); return true; } void cli_cmd_cat(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); // need at least 1 argument if (argc == 0) { printf("invalid arguments\r\n"); return; } for (uint16_t i = 0; i < argc; i++) { FIL *fi = &file1; const char *fpath = embeddedCliGetToken(args, i + 1); // token count from 1 if (FR_OK != f_open(fi, fpath, FA_READ)) { printf("%s: No such file or directory\r\n", fpath); } else { UINT count = 0; while ((FR_OK == f_read(fi, rw_buf, sizeof(rw_buf), &count)) && (count > 0)) { for (UINT c = 0; c < count; c++) { const uint8_t ch = rw_buf[c]; if (isprint(ch) || iscntrl(ch)) { putchar(ch); } else { putchar('.'); } } } } f_close(fi); } } void cli_cmd_cd(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); // only support 1 argument if (argc != 1) { printf("invalid arguments\r\n"); return; } // default is current directory const char *dpath = args; if (FR_OK != f_chdir(dpath)) { printf("%s: No such file or directory\r\n", dpath); return; } } void cli_cmd_cp(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); if (argc != 2) { printf("invalid arguments\r\n"); return; } // default is current directory const char *src = embeddedCliGetToken(args, 1); const char *dst = embeddedCliGetToken(args, 2); FIL *f_src = &file1; FIL *f_dst = &file2; if (FR_OK != f_open(f_src, src, FA_READ)) { printf("cannot stat '%s': No such file or directory\r\n", src); return; } if (FR_OK != f_open(f_dst, dst, FA_WRITE | FA_CREATE_ALWAYS)) { printf("cannot create '%s'\r\n", dst); return; } else { UINT rd_count = 0; while ((FR_OK == f_read(f_src, rw_buf, sizeof(rw_buf), &rd_count)) && (rd_count > 0)) { UINT wr_count = 0; if (FR_OK != f_write(f_dst, rw_buf, rd_count, &wr_count)) { printf("cannot write to '%s'\r\n", dst); break; } } } f_close(f_src); f_close(f_dst); } void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); // only support 1 argument if (argc > 1) { printf("invalid arguments\r\n"); return; } // default is current directory const char *dpath = "."; if (argc) { dpath = args; } DIR dir; if (FR_OK != f_opendir(&dir, dpath)) { printf("cannot access '%s': No such file or directory\r\n", dpath); return; } FILINFO fno; while ((f_readdir(&dir, &fno) == FR_OK) && (fno.fname[0] != 0)) { if (fno.fname[0] != '.') // ignore . and .. entry { if (fno.fattrib & AM_DIR) { // directory printf("/%s\r\n", fno.fname); } else { printf("%-40s", fno.fname); if (fno.fsize < 1024) { printf("%" PRIu32 " B\r\n", fno.fsize); } else { printf("%" PRIu32 " KB\r\n", fno.fsize / 1024); } } } } f_closedir(&dir); } void cli_cmd_pwd(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); if (argc != 0) { printf("invalid arguments\r\n"); return; } char path[256]; if (FR_OK != f_getcwd(path, sizeof(path))) { printf("cannot get current working directory\r\n"); } puts(path); } void cli_cmd_mkdir(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); // only support 1 argument if (argc != 1) { printf("invalid arguments\r\n"); return; } // default is current directory const char *dpath = args; if (FR_OK != f_mkdir(dpath)) { printf("%s: cannot create this directory\r\n", dpath); return; } } void cli_cmd_mv(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); if (argc != 2) { printf("invalid arguments\r\n"); return; } // default is current directory const char *src = embeddedCliGetToken(args, 1); const char *dst = embeddedCliGetToken(args, 2); if (FR_OK != f_rename(src, dst)) { printf("cannot mv %s to %s\r\n", src, dst); return; } } void cli_cmd_rm(EmbeddedCli *cli, char *args, void *context) { (void)cli; (void)context; uint16_t argc = embeddedCliGetTokenCount(args); // need at least 1 argument if (argc == 0) { printf("invalid arguments\r\n"); return; } for (uint16_t i = 0; i < argc; i++) { const char *fpath = embeddedCliGetToken(args, i + 1); // token count from 1 if (FR_OK != f_unlink(fpath)) { printf("cannot remove '%s': No such file or directory\r\n", fpath); } } } ================================================ FILE: examples/host/msc_file_explorer/src/msc_app.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef MSC_APP_H #define MSC_APP_H #include #include bool msc_app_init(void); void msc_app_task(void); #endif ================================================ FILE: examples/host/msc_file_explorer/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION #endif #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // Host Configuration //-------------------------------------------------------------------- // Enable Host stack #define CFG_TUH_ENABLED 1 // #define CFG_TUH_MAX3421 1 // use max3421 as host controller #if CFG_TUSB_MCU == OPT_MCU_RP2040 // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // host roothub port is 1 if using either pio-usb or max3421 #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) #define BOARD_TUH_RHPORT 1 #endif #endif // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_MSC 1 #define CFG_TUH_CDC 0 #define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_VENDOR 0 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- MSC -------------// #define CFG_TUH_MSC_MAXLUN 4 // typical for most card reader #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/typec/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake) project(tinyusb_host_examples C CXX ASM) family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(power_delivery) ================================================ FILE: examples/typec/CMakePresets.json ================================================ { "version": 6, "include": [ "../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/typec/power_delivery/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(power_delivery C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) # Espressif has its own cmake build system if(FAMILY STREQUAL "espressif") return() endif() add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: examples/typec/power_delivery/CMakePresets.json ================================================ { "version": 6, "include": [ "../../../hw/bsp/BoardPresets.json" ] } ================================================ FILE: examples/typec/power_delivery/Makefile ================================================ include ../../../hw/bsp/family_support.mk INC += \ src \ # Example source EXAMPLE_SOURCE += \ src/main.c SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) include ../../../hw/bsp/family_rules.mk ================================================ FILE: examples/typec/power_delivery/only.txt ================================================ mcu:STM32G4 ================================================ FILE: examples/typec/power_delivery/src/main.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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 #include #include #include "bsp/board_api.h" #include "tusb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ // Voltage and current for selecting PDO // DANGEROUS: Please make sure your board can withstand the voltage and current // defined here. Otherwise, you may damage your board, smoke can come out #define VOLTAGE_MAX_MV 5000 // maximum voltage in mV #define CURRENT_MAX_MA 500 // maximum current in mA #define CURRENT_OPERATING_MA 100 // operating current in mA /* Blink pattern * - 250 ms : button is not pressed * - 1000 ms : button is pressed (and hold) */ enum { BLINK_PRESSED = 250, BLINK_UNPRESSED = 1000 }; static uint32_t blink_interval_ms = BLINK_UNPRESSED; void led_blinking_task(void); #define HELLO_STR "Hello from TinyUSB\r\n" int main(void) { board_init(); board_led_write(true); tuc_init(0, TUSB_TYPEC_PORT_SNK); while (1) { led_blinking_task(); // tinyusb typec task tuc_task(); } } #ifdef ESP_PLATFORM void app_main(void) { main(); } #endif //--------------------------------------------------------------------+ // TypeC PD callbacks //--------------------------------------------------------------------+ bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end) { switch (header->msg_type) { case PD_DATA_SOURCE_CAP: { printf("PD Source Capabilities\r\n"); // Examine source capability and select a suitable PDO (starting from 1 with safe5v) uint8_t selected_pos = 1; for(size_t i=0; in_data_obj; i++) { TU_VERIFY(dobj < p_end); uint32_t const pdo = tu_le32toh(tu_unaligned_read32(dobj)); switch ((pdo >> 30) & 0x03ul) { case PD_PDO_TYPE_FIXED: { pd_pdo_fixed_t const* fixed = (pd_pdo_fixed_t const*) &pdo; uint32_t const voltage_mv = fixed->voltage_50mv*50; uint32_t const current_ma = fixed->current_max_10ma*10; printf("[Fixed] %"PRIu32" mV %"PRIu32" mA\r\n", voltage_mv, current_ma); if (voltage_mv <= VOLTAGE_MAX_MV && current_ma >= CURRENT_MAX_MA) { // Found a suitable PDO selected_pos = i+1; } break; } case PD_PDO_TYPE_BATTERY: break; case PD_PDO_TYPE_VARIABLE: break; case PD_PDO_TYPE_APDO: break; } dobj += 4; } //------------- Response with selected PDO -------------// // Be careful and make sure your board can withstand the selected PDO // voltage other than safe5v e.g 12v or 20v printf("Selected PDO %u\r\n", selected_pos); // Send request with selected PDO position as response to Source Cap pd_rdo_fixed_variable_t rdo = { .current_extremum_10ma = 50, // max 500mA .current_operate_10ma = 30, // 300mA .reserved = 0, .epr_mode_capable = 0, .unchunked_ext_msg_support = 0, .no_usb_suspend = 0, .usb_comm_capable = 1, .capability_mismatch = 0, .give_back_flag = 0, // exteremum is max .object_position = selected_pos, }; tuc_msg_request(rhport, &rdo); break; } default: break; } return true; } bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header) { (void) rhport; switch (header->msg_type) { case PD_CTRL_ACCEPT: printf("PD Request Accepted\r\n"); // preparing for power transition break; case PD_CTRL_REJECT: printf("PD Request Rejected\r\n"); // try to negotiate further power break; case PD_CTRL_PS_READY: printf("PD Power Ready\r\n"); // Source is ready to supply power break; default: break; } return true; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms if ( tusb_time_millis_api() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); led_state = 1 - led_state; // toggle } ================================================ FILE: examples/typec/power_delivery/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #define CFG_TUD_ENABLED 0 #define CFG_TUH_ENABLED 0 // Enable TYPEC stack #define CFG_TUC_ENABLED 1 // special example that doesn't enable device or host stack // This can cause some TinyUSB API missing, this define hack to allow us to fill those API // to pass the compilation process #if CFG_TUD_ENABLED == 0 #define tud_int_handler(x) #endif // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: examples/west.yml ================================================ manifest: remotes: - name: zephyrproject-rtos url-base: https://github.com/zephyrproject-rtos projects: - name: zephyr remote: zephyrproject-rtos revision: main path: zephyr import: true self: path: . ================================================ FILE: hw/bsp/BoardPresets.json ================================================ { "version": 6, "configurePresets": [ { "name": "default", "hidden": true, "description": "Configure preset for the ${presetName} board", "generator": "Ninja Multi-Config", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { "CMAKE_DEFAULT_BUILD_TYPE": "RelWithDebInfo", "BOARD": "${presetName}" } }, { "name": "default single config", "hidden": true, "description": "Configure preset for the ${presetName} board", "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { "BOARD": "${presetName}" } }, { "name": "adafruit_clue", "inherits": "default" }, { "name": "adafruit_feather_rp2040_usb_host", "inherits": "default" }, { "name": "adafruit_fruit_jam", "inherits": "default" }, { "name": "adafruit_metro_rp2350", "inherits": "default" }, { "name": "apard32690", "inherits": "default" }, { "name": "arduino_nano33_ble", "inherits": "default" }, { "name": "at32f403a_weact_blackpill", "inherits": "default" }, { "name": "at_start_f402", "inherits": "default" }, { "name": "at_start_f403a", "inherits": "default" }, { "name": "at_start_f405", "inherits": "default" }, { "name": "at_start_f407", "inherits": "default" }, { "name": "at_start_f413", "inherits": "default" }, { "name": "at_start_f415", "inherits": "default" }, { "name": "at_start_f423", "inherits": "default" }, { "name": "at_start_f425", "inherits": "default" }, { "name": "at_start_f435", "inherits": "default" }, { "name": "at_start_f437", "inherits": "default" }, { "name": "at_start_f455", "inherits": "default" }, { "name": "at_start_f456", "inherits": "default" }, { "name": "at_start_f457", "inherits": "default" }, { "name": "atsamd21_xpro", "inherits": "default" }, { "name": "atsaml21_xpro", "inherits": "default" }, { "name": "b_g474e_dpow1", "inherits": "default" }, { "name": "b_u585i_iot2a", "inherits": "default" }, { "name": "ch32v103r_r1_1v0", "inherits": "default" }, { "name": "ch32v203c_r0_1v0", "inherits": "default" }, { "name": "ch32v203g_r0_1v0", "inherits": "default" }, { "name": "ch32v307v_r1_1v0", "inherits": "default" }, { "name": "circuitplayground_bluefruit", "inherits": "default" }, { "name": "circuitplayground_express", "inherits": "default" }, { "name": "curiosity_nano", "inherits": "default" }, { "name": "cynthion_d11", "inherits": "default" }, { "name": "cynthion_d21", "inherits": "default" }, { "name": "d5035_01", "inherits": "default" }, { "name": "da14695_dk_usb", "inherits": "default" }, { "name": "da1469x_dk_pro", "inherits": "default" }, { "name": "daisyseed", "inherits": "default" }, { "name": "double_m33_express", "inherits": "default" }, { "name": "ea4088_quickstart", "inherits": "default" }, { "name": "ea4357", "inherits": "default" }, { "name": "ek_tm4c123gxl", "inherits": "default" }, { "name": "ek_tm4c1294xl", "inherits": "default" }, { "name": "f1c100s", "inherits": "default" }, { "name": "feather_m0_express", "inherits": "default" }, { "name": "feather_m4_express", "inherits": "default" }, { "name": "feather_nrf52840_express", "inherits": "default" }, { "name": "feather_nrf52840_sense", "inherits": "default" }, { "name": "feather_rp2040_max3421", "inherits": "default" }, { "name": "feather_stm32f405", "inherits": "default" }, { "name": "fomu", "inherits": "default" }, { "name": "frdm_k32l2a4s", "inherits": "default" }, { "name": "frdm_k32l2b", "inherits": "default" }, { "name": "frdm_k64f", "inherits": "default" }, { "name": "frdm_kl25z", "inherits": "default" }, { "name": "frdm_mcxa153", "inherits": "default" }, { "name": "frdm_mcxa156", "inherits": "default" }, { "name": "frdm_mcxn947", "inherits": "default" }, { "name": "frdm_rw612", "inherits": "default" }, { "name": "hpm6750evk2", "inherits": "default" }, { "name": "itsybitsy_m0", "inherits": "default" }, { "name": "itsybitsy_m4", "inherits": "default" }, { "name": "itsybitsy_nrf52840", "inherits": "default" }, { "name": "kuiic", "inherits": "default" }, { "name": "lpcxpresso11u37", "inherits": "default" }, { "name": "lpcxpresso11u68", "inherits": "default" }, { "name": "lpcxpresso1347", "inherits": "default" }, { "name": "lpcxpresso1549", "inherits": "default" }, { "name": "lpcxpresso1769", "inherits": "default" }, { "name": "lpcxpresso18s37", "inherits": "default" }, { "name": "lpcxpresso43s67", "inherits": "default" }, { "name": "lpcxpresso51u68", "inherits": "default" }, { "name": "lpcxpresso54114", "inherits": "default" }, { "name": "lpcxpresso54608", "inherits": "default" }, { "name": "lpcxpresso54628", "inherits": "default" }, { "name": "lpcxpresso55s28", "inherits": "default" }, { "name": "lpcxpresso55s69", "inherits": "default" }, { "name": "max32650evkit", "inherits": "default" }, { "name": "max32650fthr", "inherits": "default" }, { "name": "max32651evkit", "inherits": "default" }, { "name": "max32666evkit", "inherits": "default" }, { "name": "max32666fthr", "inherits": "default" }, { "name": "max32690evkit", "inherits": "default" }, { "name": "max78002evkit", "inherits": "default" }, { "name": "mbed1768", "inherits": "default" }, { "name": "mcb1800", "inherits": "default" }, { "name": "mcu_link", "inherits": "default" }, { "name": "mcxn947brk", "inherits": "default" }, { "name": "metro_m0_express", "inherits": "default" }, { "name": "metro_m4_express", "inherits": "default" }, { "name": "metro_m7_1011", "inherits": "default" }, { "name": "mimxrt1010_evk", "inherits": "default" }, { "name": "mimxrt1015_evk", "inherits": "default" }, { "name": "mimxrt1020_evk", "inherits": "default" }, { "name": "mimxrt1024_evk", "inherits": "default" }, { "name": "mimxrt1050_evkb", "inherits": "default" }, { "name": "mimxrt1060_evk", "inherits": "default" }, { "name": "mimxrt1064_evk", "inherits": "default" }, { "name": "mimxrt1170_evkb", "inherits": "default" }, { "name": "mm32f327x_mb39", "inherits": "default" }, { "name": "mm32f327x_pitaya_lite", "inherits": "default" }, { "name": "msp_exp430f5529lp", "inherits": "default" }, { "name": "msp_exp432e401y", "inherits": "default" }, { "name": "nanoch32v203", "inherits": "default" }, { "name": "nanoch32v305", "inherits": "default" }, { "name": "nrf52833dk", "inherits": "default" }, { "name": "nrf52840dk", "inherits": "default" }, { "name": "nrf52840dongle", "inherits": "default" }, { "name": "nrf5340dk", "inherits": "default" }, { "name": "nrf54h20dk", "inherits": "default" }, { "name": "nutiny_nuc126v", "inherits": "default" }, { "name": "nutiny_sdk_nuc120", "inherits": "default" }, { "name": "nutiny_sdk_nuc121", "inherits": "default" }, { "name": "nutiny_sdk_nuc125", "inherits": "default" }, { "name": "nutiny_sdk_nuc505", "inherits": "default" }, { "name": "pico_sdk", "inherits": "default" }, { "name": "portenta_c33", "inherits": "default" }, { "name": "pybadge", "inherits": "default" }, { "name": "pyboardv11", "inherits": "default" }, { "name": "pyportal", "inherits": "default" }, { "name": "qtpy", "inherits": "default" }, { "name": "ra2a1_ek", "inherits": "default" }, { "name": "ra4m1_ek", "inherits": "default" }, { "name": "ra4m3_ek", "inherits": "default" }, { "name": "ra6m1_ek", "inherits": "default" }, { "name": "ra6m5_ek", "inherits": "default" }, { "name": "ra8m1_ek", "inherits": "default" }, { "name": "raspberry_pi_pico", "inherits": "default" }, { "name": "raspberry_pi_pico2", "inherits": "default" }, { "name": "raspberry_pi_pico_w", "inherits": "default" }, { "name": "raspberrypi_cm4", "inherits": "default" }, { "name": "raspberrypi_zero", "inherits": "default" }, { "name": "raspberrypi_zero2", "inherits": "default" }, { "name": "samd11_xplained", "inherits": "default" }, { "name": "same54_xplained", "inherits": "default" }, { "name": "same70_qmtech", "inherits": "default" }, { "name": "same70_xplained", "inherits": "default" }, { "name": "samg55_xplained", "inherits": "default" }, { "name": "saml22_feather", "inherits": "default" }, { "name": "seeeduino_xiao", "inherits": "default" }, { "name": "sensorwatch_m0", "inherits": "default" }, { "name": "sipeed_longan_nano", "inherits": "default" }, { "name": "sltb009a", "inherits": "default" }, { "name": "sparkfun_samd21_mini_usb", "inherits": "default" }, { "name": "spresense", "inherits": "default" }, { "name": "stlinkv3mini", "inherits": "default" }, { "name": "stm32c071nucleo", "inherits": "default" }, { "name": "stm32f070rbnucleo", "inherits": "default" }, { "name": "stm32f072disco", "inherits": "default" }, { "name": "stm32f072eval", "inherits": "default" }, { "name": "stm32f103_bluepill", "inherits": "default" }, { "name": "stm32f103_mini_2", "inherits": "default" }, { "name": "stm32f103ze_iar", "inherits": "default" }, { "name": "stm32f207nucleo", "inherits": "default" }, { "name": "stm32f303disco", "inherits": "default" }, { "name": "stm32f401blackpill", "inherits": "default" }, { "name": "stm32f407blackvet", "inherits": "default" }, { "name": "stm32f407disco", "inherits": "default" }, { "name": "stm32f411blackpill", "inherits": "default" }, { "name": "stm32f411disco", "inherits": "default" }, { "name": "stm32f412disco", "inherits": "default" }, { "name": "stm32f412nucleo", "inherits": "default" }, { "name": "stm32f439nucleo", "inherits": "default" }, { "name": "stm32f723disco", "inherits": "default" }, { "name": "stm32f746disco", "inherits": "default" }, { "name": "stm32f746nucleo", "inherits": "default" }, { "name": "stm32f767nucleo", "inherits": "default" }, { "name": "stm32f769disco", "inherits": "default" }, { "name": "stm32g0b1nucleo", "inherits": "default" }, { "name": "stm32g474nucleo", "inherits": "default" }, { "name": "stm32g491nucleo", "inherits": "default" }, { "name": "stm32h503nucleo", "inherits": "default" }, { "name": "stm32h563nucleo", "inherits": "default" }, { "name": "stm32h573i_dk", "inherits": "default" }, { "name": "stm32h723nucleo", "inherits": "default" }, { "name": "stm32h743eval", "inherits": "default" }, { "name": "stm32h743nucleo", "inherits": "default" }, { "name": "stm32h745disco", "inherits": "default" }, { "name": "stm32h747disco", "inherits": "default" }, { "name": "stm32h750_weact", "inherits": "default" }, { "name": "stm32h750bdk", "inherits": "default" }, { "name": "stm32h7s3nucleo", "inherits": "default" }, { "name": "stm32l052dap52", "inherits": "default" }, { "name": "stm32l0538disco", "inherits": "default" }, { "name": "stm32l412nucleo", "inherits": "default" }, { "name": "stm32l476disco", "inherits": "default" }, { "name": "stm32l496nucleo", "inherits": "default" }, { "name": "stm32l4p5nucleo", "inherits": "default" }, { "name": "stm32l4r5nucleo", "inherits": "default" }, { "name": "stm32n6570dk", "inherits": "default" }, { "name": "stm32n657nucleo", "inherits": "default" }, { "name": "stm32u083cdk", "inherits": "default" }, { "name": "stm32u545nucleo", "inherits": "default" }, { "name": "stm32u575eval", "inherits": "default" }, { "name": "stm32u575nucleo", "inherits": "default" }, { "name": "stm32u5a5nucleo", "inherits": "default" }, { "name": "stm32wb55nucleo", "inherits": "default" }, { "name": "stm32wba_nucleo", "inherits": "default" }, { "name": "teensy_35", "inherits": "default" }, { "name": "teensy_40", "inherits": "default" }, { "name": "teensy_41", "inherits": "default" }, { "name": "trinket_m0", "inherits": "default" }, { "name": "uno_r4", "inherits": "default" }, { "name": "waveshare_openh743i", "inherits": "default" }, { "name": "xmc4500_relax", "inherits": "default" }, { "name": "xmc4700_relax", "inherits": "default" }, { "name": "adafruit_feather_esp32_v2", "inherits": "default single config" }, { "name": "adafruit_feather_esp32c6", "inherits": "default single config" }, { "name": "adafruit_feather_esp32s2", "inherits": "default single config" }, { "name": "adafruit_feather_esp32s3", "inherits": "default single config" }, { "name": "adafruit_magtag_29gray", "inherits": "default single config" }, { "name": "adafruit_metro_esp32s2", "inherits": "default single config" }, { "name": "espressif_addax_1", "inherits": "default single config" }, { "name": "espressif_c3_devkitc", "inherits": "default single config" }, { "name": "espressif_c6_devkitc", "inherits": "default single config" }, { "name": "espressif_kaluga_1", "inherits": "default single config" }, { "name": "espressif_p4_function_ev", "inherits": "default single config" }, { "name": "espressif_s2_devkitc", "inherits": "default single config" }, { "name": "espressif_s3_devkitc", "inherits": "default single config" }, { "name": "espressif_s3_devkitm", "inherits": "default single config" }, { "name": "espressif_saola_1", "inherits": "default single config" } ], "buildPresets": [ { "name": "adafruit_clue", "description": "Build preset for the adafruit_clue board", "configurePreset": "adafruit_clue" }, { "name": "adafruit_feather_esp32_v2", "description": "Build preset for the adafruit_feather_esp32_v2 board", "configurePreset": "adafruit_feather_esp32_v2" }, { "name": "adafruit_feather_esp32c6", "description": "Build preset for the adafruit_feather_esp32c6 board", "configurePreset": "adafruit_feather_esp32c6" }, { "name": "adafruit_feather_esp32s2", "description": "Build preset for the adafruit_feather_esp32s2 board", "configurePreset": "adafruit_feather_esp32s2" }, { "name": "adafruit_feather_esp32s3", "description": "Build preset for the adafruit_feather_esp32s3 board", "configurePreset": "adafruit_feather_esp32s3" }, { "name": "adafruit_feather_rp2040_usb_host", "description": "Build preset for the adafruit_feather_rp2040_usb_host board", "configurePreset": "adafruit_feather_rp2040_usb_host" }, { "name": "adafruit_fruit_jam", "description": "Build preset for the adafruit_fruit_jam board", "configurePreset": "adafruit_fruit_jam" }, { "name": "adafruit_magtag_29gray", "description": "Build preset for the adafruit_magtag_29gray board", "configurePreset": "adafruit_magtag_29gray" }, { "name": "adafruit_metro_esp32s2", "description": "Build preset for the adafruit_metro_esp32s2 board", "configurePreset": "adafruit_metro_esp32s2" }, { "name": "adafruit_metro_rp2350", "description": "Build preset for the adafruit_metro_rp2350 board", "configurePreset": "adafruit_metro_rp2350" }, { "name": "apard32690", "description": "Build preset for the apard32690 board", "configurePreset": "apard32690" }, { "name": "arduino_nano33_ble", "description": "Build preset for the arduino_nano33_ble board", "configurePreset": "arduino_nano33_ble" }, { "name": "at32f403a_weact_blackpill", "description": "Build preset for the at32f403a_weact_blackpill board", "configurePreset": "at32f403a_weact_blackpill" }, { "name": "at_start_f402", "description": "Build preset for the at_start_f402 board", "configurePreset": "at_start_f402" }, { "name": "at_start_f403a", "description": "Build preset for the at_start_f403a board", "configurePreset": "at_start_f403a" }, { "name": "at_start_f405", "description": "Build preset for the at_start_f405 board", "configurePreset": "at_start_f405" }, { "name": "at_start_f407", "description": "Build preset for the at_start_f407 board", "configurePreset": "at_start_f407" }, { "name": "at_start_f413", "description": "Build preset for the at_start_f413 board", "configurePreset": "at_start_f413" }, { "name": "at_start_f415", "description": "Build preset for the at_start_f415 board", "configurePreset": "at_start_f415" }, { "name": "at_start_f423", "description": "Build preset for the at_start_f423 board", "configurePreset": "at_start_f423" }, { "name": "at_start_f425", "description": "Build preset for the at_start_f425 board", "configurePreset": "at_start_f425" }, { "name": "at_start_f435", "description": "Build preset for the at_start_f435 board", "configurePreset": "at_start_f435" }, { "name": "at_start_f437", "description": "Build preset for the at_start_f437 board", "configurePreset": "at_start_f437" }, { "name": "at_start_f455", "description": "Build preset for the at_start_f455 board", "configurePreset": "at_start_f455" }, { "name": "at_start_f456", "description": "Build preset for the at_start_f456 board", "configurePreset": "at_start_f456" }, { "name": "at_start_f457", "description": "Build preset for the at_start_f457 board", "configurePreset": "at_start_f457" }, { "name": "atsamd21_xpro", "description": "Build preset for the atsamd21_xpro board", "configurePreset": "atsamd21_xpro" }, { "name": "atsaml21_xpro", "description": "Build preset for the atsaml21_xpro board", "configurePreset": "atsaml21_xpro" }, { "name": "b_g474e_dpow1", "description": "Build preset for the b_g474e_dpow1 board", "configurePreset": "b_g474e_dpow1" }, { "name": "b_u585i_iot2a", "description": "Build preset for the b_u585i_iot2a board", "configurePreset": "b_u585i_iot2a" }, { "name": "ch32v103r_r1_1v0", "description": "Build preset for the ch32v103r_r1_1v0 board", "configurePreset": "ch32v103r_r1_1v0" }, { "name": "ch32v203c_r0_1v0", "description": "Build preset for the ch32v203c_r0_1v0 board", "configurePreset": "ch32v203c_r0_1v0" }, { "name": "ch32v203g_r0_1v0", "description": "Build preset for the ch32v203g_r0_1v0 board", "configurePreset": "ch32v203g_r0_1v0" }, { "name": "ch32v307v_r1_1v0", "description": "Build preset for the ch32v307v_r1_1v0 board", "configurePreset": "ch32v307v_r1_1v0" }, { "name": "circuitplayground_bluefruit", "description": "Build preset for the circuitplayground_bluefruit board", "configurePreset": "circuitplayground_bluefruit" }, { "name": "circuitplayground_express", "description": "Build preset for the circuitplayground_express board", "configurePreset": "circuitplayground_express" }, { "name": "curiosity_nano", "description": "Build preset for the curiosity_nano board", "configurePreset": "curiosity_nano" }, { "name": "cynthion_d11", "description": "Build preset for the cynthion_d11 board", "configurePreset": "cynthion_d11" }, { "name": "cynthion_d21", "description": "Build preset for the cynthion_d21 board", "configurePreset": "cynthion_d21" }, { "name": "d5035_01", "description": "Build preset for the d5035_01 board", "configurePreset": "d5035_01" }, { "name": "da14695_dk_usb", "description": "Build preset for the da14695_dk_usb board", "configurePreset": "da14695_dk_usb" }, { "name": "da1469x_dk_pro", "description": "Build preset for the da1469x_dk_pro board", "configurePreset": "da1469x_dk_pro" }, { "name": "daisyseed", "description": "Build preset for the daisyseed board", "configurePreset": "daisyseed" }, { "name": "double_m33_express", "description": "Build preset for the double_m33_express board", "configurePreset": "double_m33_express" }, { "name": "ea4088_quickstart", "description": "Build preset for the ea4088_quickstart board", "configurePreset": "ea4088_quickstart" }, { "name": "ea4357", "description": "Build preset for the ea4357 board", "configurePreset": "ea4357" }, { "name": "ek_tm4c123gxl", "description": "Build preset for the ek_tm4c123gxl board", "configurePreset": "ek_tm4c123gxl" }, { "name": "ek_tm4c1294xl", "description": "Build preset for the ek_tm4c1294xl board", "configurePreset": "ek_tm4c1294xl" }, { "name": "espressif_addax_1", "description": "Build preset for the espressif_addax_1 board", "configurePreset": "espressif_addax_1" }, { "name": "espressif_c3_devkitc", "description": "Build preset for the espressif_c3_devkitc board", "configurePreset": "espressif_c3_devkitc" }, { "name": "espressif_c6_devkitc", "description": "Build preset for the espressif_c6_devkitc board", "configurePreset": "espressif_c6_devkitc" }, { "name": "espressif_kaluga_1", "description": "Build preset for the espressif_kaluga_1 board", "configurePreset": "espressif_kaluga_1" }, { "name": "espressif_p4_function_ev", "description": "Build preset for the espressif_p4_function_ev board", "configurePreset": "espressif_p4_function_ev" }, { "name": "espressif_s2_devkitc", "description": "Build preset for the espressif_s2_devkitc board", "configurePreset": "espressif_s2_devkitc" }, { "name": "espressif_s3_devkitc", "description": "Build preset for the espressif_s3_devkitc board", "configurePreset": "espressif_s3_devkitc" }, { "name": "espressif_s3_devkitm", "description": "Build preset for the espressif_s3_devkitm board", "configurePreset": "espressif_s3_devkitm" }, { "name": "espressif_saola_1", "description": "Build preset for the espressif_saola_1 board", "configurePreset": "espressif_saola_1" }, { "name": "f1c100s", "description": "Build preset for the f1c100s board", "configurePreset": "f1c100s" }, { "name": "feather_m0_express", "description": "Build preset for the feather_m0_express board", "configurePreset": "feather_m0_express" }, { "name": "feather_m4_express", "description": "Build preset for the feather_m4_express board", "configurePreset": "feather_m4_express" }, { "name": "feather_nrf52840_express", "description": "Build preset for the feather_nrf52840_express board", "configurePreset": "feather_nrf52840_express" }, { "name": "feather_nrf52840_sense", "description": "Build preset for the feather_nrf52840_sense board", "configurePreset": "feather_nrf52840_sense" }, { "name": "feather_rp2040_max3421", "description": "Build preset for the feather_rp2040_max3421 board", "configurePreset": "feather_rp2040_max3421" }, { "name": "feather_stm32f405", "description": "Build preset for the feather_stm32f405 board", "configurePreset": "feather_stm32f405" }, { "name": "fomu", "description": "Build preset for the fomu board", "configurePreset": "fomu" }, { "name": "frdm_k32l2a4s", "description": "Build preset for the frdm_k32l2a4s board", "configurePreset": "frdm_k32l2a4s" }, { "name": "frdm_k32l2b", "description": "Build preset for the frdm_k32l2b board", "configurePreset": "frdm_k32l2b" }, { "name": "frdm_k64f", "description": "Build preset for the frdm_k64f board", "configurePreset": "frdm_k64f" }, { "name": "frdm_kl25z", "description": "Build preset for the frdm_kl25z board", "configurePreset": "frdm_kl25z" }, { "name": "frdm_mcxa153", "description": "Build preset for the frdm_mcxa153 board", "configurePreset": "frdm_mcxa153" }, { "name": "frdm_mcxa156", "description": "Build preset for the frdm_mcxa156 board", "configurePreset": "frdm_mcxa156" }, { "name": "frdm_mcxn947", "description": "Build preset for the frdm_mcxn947 board", "configurePreset": "frdm_mcxn947" }, { "name": "frdm_rw612", "description": "Build preset for the frdm_rw612 board", "configurePreset": "frdm_rw612" }, { "name": "hpm6750evk2", "description": "Build preset for the hpm6750evk2 board", "configurePreset": "hpm6750evk2" }, { "name": "itsybitsy_m0", "description": "Build preset for the itsybitsy_m0 board", "configurePreset": "itsybitsy_m0" }, { "name": "itsybitsy_m4", "description": "Build preset for the itsybitsy_m4 board", "configurePreset": "itsybitsy_m4" }, { "name": "itsybitsy_nrf52840", "description": "Build preset for the itsybitsy_nrf52840 board", "configurePreset": "itsybitsy_nrf52840" }, { "name": "kuiic", "description": "Build preset for the kuiic board", "configurePreset": "kuiic" }, { "name": "lpcxpresso11u37", "description": "Build preset for the lpcxpresso11u37 board", "configurePreset": "lpcxpresso11u37" }, { "name": "lpcxpresso11u68", "description": "Build preset for the lpcxpresso11u68 board", "configurePreset": "lpcxpresso11u68" }, { "name": "lpcxpresso1347", "description": "Build preset for the lpcxpresso1347 board", "configurePreset": "lpcxpresso1347" }, { "name": "lpcxpresso1549", "description": "Build preset for the lpcxpresso1549 board", "configurePreset": "lpcxpresso1549" }, { "name": "lpcxpresso1769", "description": "Build preset for the lpcxpresso1769 board", "configurePreset": "lpcxpresso1769" }, { "name": "lpcxpresso18s37", "description": "Build preset for the lpcxpresso18s37 board", "configurePreset": "lpcxpresso18s37" }, { "name": "lpcxpresso43s67", "description": "Build preset for the lpcxpresso43s67 board", "configurePreset": "lpcxpresso43s67" }, { "name": "lpcxpresso51u68", "description": "Build preset for the lpcxpresso51u68 board", "configurePreset": "lpcxpresso51u68" }, { "name": "lpcxpresso54114", "description": "Build preset for the lpcxpresso54114 board", "configurePreset": "lpcxpresso54114" }, { "name": "lpcxpresso54608", "description": "Build preset for the lpcxpresso54608 board", "configurePreset": "lpcxpresso54608" }, { "name": "lpcxpresso54628", "description": "Build preset for the lpcxpresso54628 board", "configurePreset": "lpcxpresso54628" }, { "name": "lpcxpresso55s28", "description": "Build preset for the lpcxpresso55s28 board", "configurePreset": "lpcxpresso55s28" }, { "name": "lpcxpresso55s69", "description": "Build preset for the lpcxpresso55s69 board", "configurePreset": "lpcxpresso55s69" }, { "name": "max32650evkit", "description": "Build preset for the max32650evkit board", "configurePreset": "max32650evkit" }, { "name": "max32650fthr", "description": "Build preset for the max32650fthr board", "configurePreset": "max32650fthr" }, { "name": "max32651evkit", "description": "Build preset for the max32651evkit board", "configurePreset": "max32651evkit" }, { "name": "max32666evkit", "description": "Build preset for the max32666evkit board", "configurePreset": "max32666evkit" }, { "name": "max32666fthr", "description": "Build preset for the max32666fthr board", "configurePreset": "max32666fthr" }, { "name": "max32690evkit", "description": "Build preset for the max32690evkit board", "configurePreset": "max32690evkit" }, { "name": "max78002evkit", "description": "Build preset for the max78002evkit board", "configurePreset": "max78002evkit" }, { "name": "mbed1768", "description": "Build preset for the mbed1768 board", "configurePreset": "mbed1768" }, { "name": "mcb1800", "description": "Build preset for the mcb1800 board", "configurePreset": "mcb1800" }, { "name": "mcu_link", "description": "Build preset for the mcu_link board", "configurePreset": "mcu_link" }, { "name": "mcxn947brk", "description": "Build preset for the mcxn947brk board", "configurePreset": "mcxn947brk" }, { "name": "metro_m0_express", "description": "Build preset for the metro_m0_express board", "configurePreset": "metro_m0_express" }, { "name": "metro_m4_express", "description": "Build preset for the metro_m4_express board", "configurePreset": "metro_m4_express" }, { "name": "metro_m7_1011", "description": "Build preset for the metro_m7_1011 board", "configurePreset": "metro_m7_1011" }, { "name": "mimxrt1010_evk", "description": "Build preset for the mimxrt1010_evk board", "configurePreset": "mimxrt1010_evk" }, { "name": "mimxrt1015_evk", "description": "Build preset for the mimxrt1015_evk board", "configurePreset": "mimxrt1015_evk" }, { "name": "mimxrt1020_evk", "description": "Build preset for the mimxrt1020_evk board", "configurePreset": "mimxrt1020_evk" }, { "name": "mimxrt1024_evk", "description": "Build preset for the mimxrt1024_evk board", "configurePreset": "mimxrt1024_evk" }, { "name": "mimxrt1050_evkb", "description": "Build preset for the mimxrt1050_evkb board", "configurePreset": "mimxrt1050_evkb" }, { "name": "mimxrt1060_evk", "description": "Build preset for the mimxrt1060_evk board", "configurePreset": "mimxrt1060_evk" }, { "name": "mimxrt1064_evk", "description": "Build preset for the mimxrt1064_evk board", "configurePreset": "mimxrt1064_evk" }, { "name": "mimxrt1170_evkb", "description": "Build preset for the mimxrt1170_evkb board", "configurePreset": "mimxrt1170_evkb" }, { "name": "mm32f327x_mb39", "description": "Build preset for the mm32f327x_mb39 board", "configurePreset": "mm32f327x_mb39" }, { "name": "mm32f327x_pitaya_lite", "description": "Build preset for the mm32f327x_pitaya_lite board", "configurePreset": "mm32f327x_pitaya_lite" }, { "name": "msp_exp430f5529lp", "description": "Build preset for the msp_exp430f5529lp board", "configurePreset": "msp_exp430f5529lp" }, { "name": "msp_exp432e401y", "description": "Build preset for the msp_exp432e401y board", "configurePreset": "msp_exp432e401y" }, { "name": "nanoch32v203", "description": "Build preset for the nanoch32v203 board", "configurePreset": "nanoch32v203" }, { "name": "nanoch32v305", "description": "Build preset for the nanoch32v305 board", "configurePreset": "nanoch32v305" }, { "name": "nrf52833dk", "description": "Build preset for the nrf52833dk board", "configurePreset": "nrf52833dk" }, { "name": "nrf52840dk", "description": "Build preset for the nrf52840dk board", "configurePreset": "nrf52840dk" }, { "name": "nrf52840dongle", "description": "Build preset for the nrf52840dongle board", "configurePreset": "nrf52840dongle" }, { "name": "nrf5340dk", "description": "Build preset for the nrf5340dk board", "configurePreset": "nrf5340dk" }, { "name": "nrf54h20dk", "description": "Build preset for the nrf54h20dk board", "configurePreset": "nrf54h20dk" }, { "name": "nutiny_nuc126v", "description": "Build preset for the nutiny_nuc126v board", "configurePreset": "nutiny_nuc126v" }, { "name": "nutiny_sdk_nuc120", "description": "Build preset for the nutiny_sdk_nuc120 board", "configurePreset": "nutiny_sdk_nuc120" }, { "name": "nutiny_sdk_nuc121", "description": "Build preset for the nutiny_sdk_nuc121 board", "configurePreset": "nutiny_sdk_nuc121" }, { "name": "nutiny_sdk_nuc125", "description": "Build preset for the nutiny_sdk_nuc125 board", "configurePreset": "nutiny_sdk_nuc125" }, { "name": "nutiny_sdk_nuc505", "description": "Build preset for the nutiny_sdk_nuc505 board", "configurePreset": "nutiny_sdk_nuc505" }, { "name": "pico_sdk", "description": "Build preset for the pico_sdk board", "configurePreset": "pico_sdk" }, { "name": "portenta_c33", "description": "Build preset for the portenta_c33 board", "configurePreset": "portenta_c33" }, { "name": "pybadge", "description": "Build preset for the pybadge board", "configurePreset": "pybadge" }, { "name": "pyboardv11", "description": "Build preset for the pyboardv11 board", "configurePreset": "pyboardv11" }, { "name": "pyportal", "description": "Build preset for the pyportal board", "configurePreset": "pyportal" }, { "name": "qtpy", "description": "Build preset for the qtpy board", "configurePreset": "qtpy" }, { "name": "ra2a1_ek", "description": "Build preset for the ra2a1_ek board", "configurePreset": "ra2a1_ek" }, { "name": "ra4m1_ek", "description": "Build preset for the ra4m1_ek board", "configurePreset": "ra4m1_ek" }, { "name": "ra4m3_ek", "description": "Build preset for the ra4m3_ek board", "configurePreset": "ra4m3_ek" }, { "name": "ra6m1_ek", "description": "Build preset for the ra6m1_ek board", "configurePreset": "ra6m1_ek" }, { "name": "ra6m5_ek", "description": "Build preset for the ra6m5_ek board", "configurePreset": "ra6m5_ek" }, { "name": "ra8m1_ek", "description": "Build preset for the ra8m1_ek board", "configurePreset": "ra8m1_ek" }, { "name": "raspberry_pi_pico", "description": "Build preset for the raspberry_pi_pico board", "configurePreset": "raspberry_pi_pico" }, { "name": "raspberry_pi_pico2", "description": "Build preset for the raspberry_pi_pico2 board", "configurePreset": "raspberry_pi_pico2" }, { "name": "raspberry_pi_pico_w", "description": "Build preset for the raspberry_pi_pico_w board", "configurePreset": "raspberry_pi_pico_w" }, { "name": "raspberrypi_cm4", "description": "Build preset for the raspberrypi_cm4 board", "configurePreset": "raspberrypi_cm4" }, { "name": "raspberrypi_zero", "description": "Build preset for the raspberrypi_zero board", "configurePreset": "raspberrypi_zero" }, { "name": "raspberrypi_zero2", "description": "Build preset for the raspberrypi_zero2 board", "configurePreset": "raspberrypi_zero2" }, { "name": "samd11_xplained", "description": "Build preset for the samd11_xplained board", "configurePreset": "samd11_xplained" }, { "name": "same54_xplained", "description": "Build preset for the same54_xplained board", "configurePreset": "same54_xplained" }, { "name": "same70_qmtech", "description": "Build preset for the same70_qmtech board", "configurePreset": "same70_qmtech" }, { "name": "same70_xplained", "description": "Build preset for the same70_xplained board", "configurePreset": "same70_xplained" }, { "name": "samg55_xplained", "description": "Build preset for the samg55_xplained board", "configurePreset": "samg55_xplained" }, { "name": "saml22_feather", "description": "Build preset for the saml22_feather board", "configurePreset": "saml22_feather" }, { "name": "seeeduino_xiao", "description": "Build preset for the seeeduino_xiao board", "configurePreset": "seeeduino_xiao" }, { "name": "sensorwatch_m0", "description": "Build preset for the sensorwatch_m0 board", "configurePreset": "sensorwatch_m0" }, { "name": "sipeed_longan_nano", "description": "Build preset for the sipeed_longan_nano board", "configurePreset": "sipeed_longan_nano" }, { "name": "sltb009a", "description": "Build preset for the sltb009a board", "configurePreset": "sltb009a" }, { "name": "sparkfun_samd21_mini_usb", "description": "Build preset for the sparkfun_samd21_mini_usb board", "configurePreset": "sparkfun_samd21_mini_usb" }, { "name": "spresense", "description": "Build preset for the spresense board", "configurePreset": "spresense" }, { "name": "stlinkv3mini", "description": "Build preset for the stlinkv3mini board", "configurePreset": "stlinkv3mini" }, { "name": "stm32c071nucleo", "description": "Build preset for the stm32c071nucleo board", "configurePreset": "stm32c071nucleo" }, { "name": "stm32f070rbnucleo", "description": "Build preset for the stm32f070rbnucleo board", "configurePreset": "stm32f070rbnucleo" }, { "name": "stm32f072disco", "description": "Build preset for the stm32f072disco board", "configurePreset": "stm32f072disco" }, { "name": "stm32f072eval", "description": "Build preset for the stm32f072eval board", "configurePreset": "stm32f072eval" }, { "name": "stm32f103_bluepill", "description": "Build preset for the stm32f103_bluepill board", "configurePreset": "stm32f103_bluepill" }, { "name": "stm32f103_mini_2", "description": "Build preset for the stm32f103_mini_2 board", "configurePreset": "stm32f103_mini_2" }, { "name": "stm32f103ze_iar", "description": "Build preset for the stm32f103ze_iar board", "configurePreset": "stm32f103ze_iar" }, { "name": "stm32f207nucleo", "description": "Build preset for the stm32f207nucleo board", "configurePreset": "stm32f207nucleo" }, { "name": "stm32f303disco", "description": "Build preset for the stm32f303disco board", "configurePreset": "stm32f303disco" }, { "name": "stm32f401blackpill", "description": "Build preset for the stm32f401blackpill board", "configurePreset": "stm32f401blackpill" }, { "name": "stm32f407blackvet", "description": "Build preset for the stm32f407blackvet board", "configurePreset": "stm32f407blackvet" }, { "name": "stm32f407disco", "description": "Build preset for the stm32f407disco board", "configurePreset": "stm32f407disco" }, { "name": "stm32f411blackpill", "description": "Build preset for the stm32f411blackpill board", "configurePreset": "stm32f411blackpill" }, { "name": "stm32f411disco", "description": "Build preset for the stm32f411disco board", "configurePreset": "stm32f411disco" }, { "name": "stm32f412disco", "description": "Build preset for the stm32f412disco board", "configurePreset": "stm32f412disco" }, { "name": "stm32f412nucleo", "description": "Build preset for the stm32f412nucleo board", "configurePreset": "stm32f412nucleo" }, { "name": "stm32f439nucleo", "description": "Build preset for the stm32f439nucleo board", "configurePreset": "stm32f439nucleo" }, { "name": "stm32f723disco", "description": "Build preset for the stm32f723disco board", "configurePreset": "stm32f723disco" }, { "name": "stm32f746disco", "description": "Build preset for the stm32f746disco board", "configurePreset": "stm32f746disco" }, { "name": "stm32f746nucleo", "description": "Build preset for the stm32f746nucleo board", "configurePreset": "stm32f746nucleo" }, { "name": "stm32f767nucleo", "description": "Build preset for the stm32f767nucleo board", "configurePreset": "stm32f767nucleo" }, { "name": "stm32f769disco", "description": "Build preset for the stm32f769disco board", "configurePreset": "stm32f769disco" }, { "name": "stm32g0b1nucleo", "description": "Build preset for the stm32g0b1nucleo board", "configurePreset": "stm32g0b1nucleo" }, { "name": "stm32g474nucleo", "description": "Build preset for the stm32g474nucleo board", "configurePreset": "stm32g474nucleo" }, { "name": "stm32g491nucleo", "description": "Build preset for the stm32g491nucleo board", "configurePreset": "stm32g491nucleo" }, { "name": "stm32h503nucleo", "description": "Build preset for the stm32h503nucleo board", "configurePreset": "stm32h503nucleo" }, { "name": "stm32h563nucleo", "description": "Build preset for the stm32h563nucleo board", "configurePreset": "stm32h563nucleo" }, { "name": "stm32h573i_dk", "description": "Build preset for the stm32h573i_dk board", "configurePreset": "stm32h573i_dk" }, { "name": "stm32h723nucleo", "description": "Build preset for the stm32h723nucleo board", "configurePreset": "stm32h723nucleo" }, { "name": "stm32h743eval", "description": "Build preset for the stm32h743eval board", "configurePreset": "stm32h743eval" }, { "name": "stm32h743nucleo", "description": "Build preset for the stm32h743nucleo board", "configurePreset": "stm32h743nucleo" }, { "name": "stm32h745disco", "description": "Build preset for the stm32h745disco board", "configurePreset": "stm32h745disco" }, { "name": "stm32h747disco", "description": "Build preset for the stm32h747disco board", "configurePreset": "stm32h747disco" }, { "name": "stm32h750_weact", "description": "Build preset for the stm32h750_weact board", "configurePreset": "stm32h750_weact" }, { "name": "stm32h750bdk", "description": "Build preset for the stm32h750bdk board", "configurePreset": "stm32h750bdk" }, { "name": "stm32h7s3nucleo", "description": "Build preset for the stm32h7s3nucleo board", "configurePreset": "stm32h7s3nucleo" }, { "name": "stm32l052dap52", "description": "Build preset for the stm32l052dap52 board", "configurePreset": "stm32l052dap52" }, { "name": "stm32l0538disco", "description": "Build preset for the stm32l0538disco board", "configurePreset": "stm32l0538disco" }, { "name": "stm32l412nucleo", "description": "Build preset for the stm32l412nucleo board", "configurePreset": "stm32l412nucleo" }, { "name": "stm32l476disco", "description": "Build preset for the stm32l476disco board", "configurePreset": "stm32l476disco" }, { "name": "stm32l496nucleo", "description": "Build preset for the stm32l496nucleo board", "configurePreset": "stm32l496nucleo" }, { "name": "stm32l4p5nucleo", "description": "Build preset for the stm32l4p5nucleo board", "configurePreset": "stm32l4p5nucleo" }, { "name": "stm32l4r5nucleo", "description": "Build preset for the stm32l4r5nucleo board", "configurePreset": "stm32l4r5nucleo" }, { "name": "stm32n6570dk", "description": "Build preset for the stm32n6570dk board", "configurePreset": "stm32n6570dk" }, { "name": "stm32n657nucleo", "description": "Build preset for the stm32n657nucleo board", "configurePreset": "stm32n657nucleo" }, { "name": "stm32u083cdk", "description": "Build preset for the stm32u083cdk board", "configurePreset": "stm32u083cdk" }, { "name": "stm32u545nucleo", "description": "Build preset for the stm32u545nucleo board", "configurePreset": "stm32u545nucleo" }, { "name": "stm32u575eval", "description": "Build preset for the stm32u575eval board", "configurePreset": "stm32u575eval" }, { "name": "stm32u575nucleo", "description": "Build preset for the stm32u575nucleo board", "configurePreset": "stm32u575nucleo" }, { "name": "stm32u5a5nucleo", "description": "Build preset for the stm32u5a5nucleo board", "configurePreset": "stm32u5a5nucleo" }, { "name": "stm32wb55nucleo", "description": "Build preset for the stm32wb55nucleo board", "configurePreset": "stm32wb55nucleo" }, { "name": "stm32wba_nucleo", "description": "Build preset for the stm32wba_nucleo board", "configurePreset": "stm32wba_nucleo" }, { "name": "teensy_35", "description": "Build preset for the teensy_35 board", "configurePreset": "teensy_35" }, { "name": "teensy_40", "description": "Build preset for the teensy_40 board", "configurePreset": "teensy_40" }, { "name": "teensy_41", "description": "Build preset for the teensy_41 board", "configurePreset": "teensy_41" }, { "name": "trinket_m0", "description": "Build preset for the trinket_m0 board", "configurePreset": "trinket_m0" }, { "name": "uno_r4", "description": "Build preset for the uno_r4 board", "configurePreset": "uno_r4" }, { "name": "waveshare_openh743i", "description": "Build preset for the waveshare_openh743i board", "configurePreset": "waveshare_openh743i" }, { "name": "xmc4500_relax", "description": "Build preset for the xmc4500_relax board", "configurePreset": "xmc4500_relax" }, { "name": "xmc4700_relax", "description": "Build preset for the xmc4700_relax board", "configurePreset": "xmc4700_relax" } ], "workflowPresets": [ { "name": "adafruit_clue", "steps": [ { "type": "configure", "name": "adafruit_clue" }, { "type": "build", "name": "adafruit_clue" } ] }, { "name": "adafruit_feather_esp32_v2", "steps": [ { "type": "configure", "name": "adafruit_feather_esp32_v2" }, { "type": "build", "name": "adafruit_feather_esp32_v2" } ] }, { "name": "adafruit_feather_esp32c6", "steps": [ { "type": "configure", "name": "adafruit_feather_esp32c6" }, { "type": "build", "name": "adafruit_feather_esp32c6" } ] }, { "name": "adafruit_feather_esp32s2", "steps": [ { "type": "configure", "name": "adafruit_feather_esp32s2" }, { "type": "build", "name": "adafruit_feather_esp32s2" } ] }, { "name": "adafruit_feather_esp32s3", "steps": [ { "type": "configure", "name": "adafruit_feather_esp32s3" }, { "type": "build", "name": "adafruit_feather_esp32s3" } ] }, { "name": "adafruit_feather_rp2040_usb_host", "steps": [ { "type": "configure", "name": "adafruit_feather_rp2040_usb_host" }, { "type": "build", "name": "adafruit_feather_rp2040_usb_host" } ] }, { "name": "adafruit_fruit_jam", "steps": [ { "type": "configure", "name": "adafruit_fruit_jam" }, { "type": "build", "name": "adafruit_fruit_jam" } ] }, { "name": "adafruit_magtag_29gray", "steps": [ { "type": "configure", "name": "adafruit_magtag_29gray" }, { "type": "build", "name": "adafruit_magtag_29gray" } ] }, { "name": "adafruit_metro_esp32s2", "steps": [ { "type": "configure", "name": "adafruit_metro_esp32s2" }, { "type": "build", "name": "adafruit_metro_esp32s2" } ] }, { "name": "adafruit_metro_rp2350", "steps": [ { "type": "configure", "name": "adafruit_metro_rp2350" }, { "type": "build", "name": "adafruit_metro_rp2350" } ] }, { "name": "apard32690", "steps": [ { "type": "configure", "name": "apard32690" }, { "type": "build", "name": "apard32690" } ] }, { "name": "arduino_nano33_ble", "steps": [ { "type": "configure", "name": "arduino_nano33_ble" }, { "type": "build", "name": "arduino_nano33_ble" } ] }, { "name": "at32f403a_weact_blackpill", "steps": [ { "type": "configure", "name": "at32f403a_weact_blackpill" }, { "type": "build", "name": "at32f403a_weact_blackpill" } ] }, { "name": "at_start_f402", "steps": [ { "type": "configure", "name": "at_start_f402" }, { "type": "build", "name": "at_start_f402" } ] }, { "name": "at_start_f403a", "steps": [ { "type": "configure", "name": "at_start_f403a" }, { "type": "build", "name": "at_start_f403a" } ] }, { "name": "at_start_f405", "steps": [ { "type": "configure", "name": "at_start_f405" }, { "type": "build", "name": "at_start_f405" } ] }, { "name": "at_start_f407", "steps": [ { "type": "configure", "name": "at_start_f407" }, { "type": "build", "name": "at_start_f407" } ] }, { "name": "at_start_f413", "steps": [ { "type": "configure", "name": "at_start_f413" }, { "type": "build", "name": "at_start_f413" } ] }, { "name": "at_start_f415", "steps": [ { "type": "configure", "name": "at_start_f415" }, { "type": "build", "name": "at_start_f415" } ] }, { "name": "at_start_f423", "steps": [ { "type": "configure", "name": "at_start_f423" }, { "type": "build", "name": "at_start_f423" } ] }, { "name": "at_start_f425", "steps": [ { "type": "configure", "name": "at_start_f425" }, { "type": "build", "name": "at_start_f425" } ] }, { "name": "at_start_f435", "steps": [ { "type": "configure", "name": "at_start_f435" }, { "type": "build", "name": "at_start_f435" } ] }, { "name": "at_start_f437", "steps": [ { "type": "configure", "name": "at_start_f437" }, { "type": "build", "name": "at_start_f437" } ] }, { "name": "at_start_f455", "steps": [ { "type": "configure", "name": "at_start_f455" }, { "type": "build", "name": "at_start_f455" } ] }, { "name": "at_start_f456", "steps": [ { "type": "configure", "name": "at_start_f456" }, { "type": "build", "name": "at_start_f456" } ] }, { "name": "at_start_f457", "steps": [ { "type": "configure", "name": "at_start_f457" }, { "type": "build", "name": "at_start_f457" } ] }, { "name": "atsamd21_xpro", "steps": [ { "type": "configure", "name": "atsamd21_xpro" }, { "type": "build", "name": "atsamd21_xpro" } ] }, { "name": "atsaml21_xpro", "steps": [ { "type": "configure", "name": "atsaml21_xpro" }, { "type": "build", "name": "atsaml21_xpro" } ] }, { "name": "b_g474e_dpow1", "steps": [ { "type": "configure", "name": "b_g474e_dpow1" }, { "type": "build", "name": "b_g474e_dpow1" } ] }, { "name": "b_u585i_iot2a", "steps": [ { "type": "configure", "name": "b_u585i_iot2a" }, { "type": "build", "name": "b_u585i_iot2a" } ] }, { "name": "ch32v103r_r1_1v0", "steps": [ { "type": "configure", "name": "ch32v103r_r1_1v0" }, { "type": "build", "name": "ch32v103r_r1_1v0" } ] }, { "name": "ch32v203c_r0_1v0", "steps": [ { "type": "configure", "name": "ch32v203c_r0_1v0" }, { "type": "build", "name": "ch32v203c_r0_1v0" } ] }, { "name": "ch32v203g_r0_1v0", "steps": [ { "type": "configure", "name": "ch32v203g_r0_1v0" }, { "type": "build", "name": "ch32v203g_r0_1v0" } ] }, { "name": "ch32v307v_r1_1v0", "steps": [ { "type": "configure", "name": "ch32v307v_r1_1v0" }, { "type": "build", "name": "ch32v307v_r1_1v0" } ] }, { "name": "circuitplayground_bluefruit", "steps": [ { "type": "configure", "name": "circuitplayground_bluefruit" }, { "type": "build", "name": "circuitplayground_bluefruit" } ] }, { "name": "circuitplayground_express", "steps": [ { "type": "configure", "name": "circuitplayground_express" }, { "type": "build", "name": "circuitplayground_express" } ] }, { "name": "curiosity_nano", "steps": [ { "type": "configure", "name": "curiosity_nano" }, { "type": "build", "name": "curiosity_nano" } ] }, { "name": "cynthion_d11", "steps": [ { "type": "configure", "name": "cynthion_d11" }, { "type": "build", "name": "cynthion_d11" } ] }, { "name": "cynthion_d21", "steps": [ { "type": "configure", "name": "cynthion_d21" }, { "type": "build", "name": "cynthion_d21" } ] }, { "name": "d5035_01", "steps": [ { "type": "configure", "name": "d5035_01" }, { "type": "build", "name": "d5035_01" } ] }, { "name": "da14695_dk_usb", "steps": [ { "type": "configure", "name": "da14695_dk_usb" }, { "type": "build", "name": "da14695_dk_usb" } ] }, { "name": "da1469x_dk_pro", "steps": [ { "type": "configure", "name": "da1469x_dk_pro" }, { "type": "build", "name": "da1469x_dk_pro" } ] }, { "name": "daisyseed", "steps": [ { "type": "configure", "name": "daisyseed" }, { "type": "build", "name": "daisyseed" } ] }, { "name": "double_m33_express", "steps": [ { "type": "configure", "name": "double_m33_express" }, { "type": "build", "name": "double_m33_express" } ] }, { "name": "ea4088_quickstart", "steps": [ { "type": "configure", "name": "ea4088_quickstart" }, { "type": "build", "name": "ea4088_quickstart" } ] }, { "name": "ea4357", "steps": [ { "type": "configure", "name": "ea4357" }, { "type": "build", "name": "ea4357" } ] }, { "name": "ek_tm4c123gxl", "steps": [ { "type": "configure", "name": "ek_tm4c123gxl" }, { "type": "build", "name": "ek_tm4c123gxl" } ] }, { "name": "ek_tm4c1294xl", "steps": [ { "type": "configure", "name": "ek_tm4c1294xl" }, { "type": "build", "name": "ek_tm4c1294xl" } ] }, { "name": "espressif_addax_1", "steps": [ { "type": "configure", "name": "espressif_addax_1" }, { "type": "build", "name": "espressif_addax_1" } ] }, { "name": "espressif_c3_devkitc", "steps": [ { "type": "configure", "name": "espressif_c3_devkitc" }, { "type": "build", "name": "espressif_c3_devkitc" } ] }, { "name": "espressif_c6_devkitc", "steps": [ { "type": "configure", "name": "espressif_c6_devkitc" }, { "type": "build", "name": "espressif_c6_devkitc" } ] }, { "name": "espressif_kaluga_1", "steps": [ { "type": "configure", "name": "espressif_kaluga_1" }, { "type": "build", "name": "espressif_kaluga_1" } ] }, { "name": "espressif_p4_function_ev", "steps": [ { "type": "configure", "name": "espressif_p4_function_ev" }, { "type": "build", "name": "espressif_p4_function_ev" } ] }, { "name": "espressif_s2_devkitc", "steps": [ { "type": "configure", "name": "espressif_s2_devkitc" }, { "type": "build", "name": "espressif_s2_devkitc" } ] }, { "name": "espressif_s3_devkitc", "steps": [ { "type": "configure", "name": "espressif_s3_devkitc" }, { "type": "build", "name": "espressif_s3_devkitc" } ] }, { "name": "espressif_s3_devkitm", "steps": [ { "type": "configure", "name": "espressif_s3_devkitm" }, { "type": "build", "name": "espressif_s3_devkitm" } ] }, { "name": "espressif_saola_1", "steps": [ { "type": "configure", "name": "espressif_saola_1" }, { "type": "build", "name": "espressif_saola_1" } ] }, { "name": "f1c100s", "steps": [ { "type": "configure", "name": "f1c100s" }, { "type": "build", "name": "f1c100s" } ] }, { "name": "feather_m0_express", "steps": [ { "type": "configure", "name": "feather_m0_express" }, { "type": "build", "name": "feather_m0_express" } ] }, { "name": "feather_m4_express", "steps": [ { "type": "configure", "name": "feather_m4_express" }, { "type": "build", "name": "feather_m4_express" } ] }, { "name": "feather_nrf52840_express", "steps": [ { "type": "configure", "name": "feather_nrf52840_express" }, { "type": "build", "name": "feather_nrf52840_express" } ] }, { "name": "feather_nrf52840_sense", "steps": [ { "type": "configure", "name": "feather_nrf52840_sense" }, { "type": "build", "name": "feather_nrf52840_sense" } ] }, { "name": "feather_rp2040_max3421", "steps": [ { "type": "configure", "name": "feather_rp2040_max3421" }, { "type": "build", "name": "feather_rp2040_max3421" } ] }, { "name": "feather_stm32f405", "steps": [ { "type": "configure", "name": "feather_stm32f405" }, { "type": "build", "name": "feather_stm32f405" } ] }, { "name": "fomu", "steps": [ { "type": "configure", "name": "fomu" }, { "type": "build", "name": "fomu" } ] }, { "name": "frdm_k32l2a4s", "steps": [ { "type": "configure", "name": "frdm_k32l2a4s" }, { "type": "build", "name": "frdm_k32l2a4s" } ] }, { "name": "frdm_k32l2b", "steps": [ { "type": "configure", "name": "frdm_k32l2b" }, { "type": "build", "name": "frdm_k32l2b" } ] }, { "name": "frdm_k64f", "steps": [ { "type": "configure", "name": "frdm_k64f" }, { "type": "build", "name": "frdm_k64f" } ] }, { "name": "frdm_kl25z", "steps": [ { "type": "configure", "name": "frdm_kl25z" }, { "type": "build", "name": "frdm_kl25z" } ] }, { "name": "frdm_mcxa153", "steps": [ { "type": "configure", "name": "frdm_mcxa153" }, { "type": "build", "name": "frdm_mcxa153" } ] }, { "name": "frdm_mcxa156", "steps": [ { "type": "configure", "name": "frdm_mcxa156" }, { "type": "build", "name": "frdm_mcxa156" } ] }, { "name": "frdm_mcxn947", "steps": [ { "type": "configure", "name": "frdm_mcxn947" }, { "type": "build", "name": "frdm_mcxn947" } ] }, { "name": "frdm_rw612", "steps": [ { "type": "configure", "name": "frdm_rw612" }, { "type": "build", "name": "frdm_rw612" } ] }, { "name": "hpm6750evk2", "steps": [ { "type": "configure", "name": "hpm6750evk2" }, { "type": "build", "name": "hpm6750evk2" } ] }, { "name": "itsybitsy_m0", "steps": [ { "type": "configure", "name": "itsybitsy_m0" }, { "type": "build", "name": "itsybitsy_m0" } ] }, { "name": "itsybitsy_m4", "steps": [ { "type": "configure", "name": "itsybitsy_m4" }, { "type": "build", "name": "itsybitsy_m4" } ] }, { "name": "itsybitsy_nrf52840", "steps": [ { "type": "configure", "name": "itsybitsy_nrf52840" }, { "type": "build", "name": "itsybitsy_nrf52840" } ] }, { "name": "kuiic", "steps": [ { "type": "configure", "name": "kuiic" }, { "type": "build", "name": "kuiic" } ] }, { "name": "lpcxpresso11u37", "steps": [ { "type": "configure", "name": "lpcxpresso11u37" }, { "type": "build", "name": "lpcxpresso11u37" } ] }, { "name": "lpcxpresso11u68", "steps": [ { "type": "configure", "name": "lpcxpresso11u68" }, { "type": "build", "name": "lpcxpresso11u68" } ] }, { "name": "lpcxpresso1347", "steps": [ { "type": "configure", "name": "lpcxpresso1347" }, { "type": "build", "name": "lpcxpresso1347" } ] }, { "name": "lpcxpresso1549", "steps": [ { "type": "configure", "name": "lpcxpresso1549" }, { "type": "build", "name": "lpcxpresso1549" } ] }, { "name": "lpcxpresso1769", "steps": [ { "type": "configure", "name": "lpcxpresso1769" }, { "type": "build", "name": "lpcxpresso1769" } ] }, { "name": "lpcxpresso18s37", "steps": [ { "type": "configure", "name": "lpcxpresso18s37" }, { "type": "build", "name": "lpcxpresso18s37" } ] }, { "name": "lpcxpresso43s67", "steps": [ { "type": "configure", "name": "lpcxpresso43s67" }, { "type": "build", "name": "lpcxpresso43s67" } ] }, { "name": "lpcxpresso51u68", "steps": [ { "type": "configure", "name": "lpcxpresso51u68" }, { "type": "build", "name": "lpcxpresso51u68" } ] }, { "name": "lpcxpresso54114", "steps": [ { "type": "configure", "name": "lpcxpresso54114" }, { "type": "build", "name": "lpcxpresso54114" } ] }, { "name": "lpcxpresso54608", "steps": [ { "type": "configure", "name": "lpcxpresso54608" }, { "type": "build", "name": "lpcxpresso54608" } ] }, { "name": "lpcxpresso54628", "steps": [ { "type": "configure", "name": "lpcxpresso54628" }, { "type": "build", "name": "lpcxpresso54628" } ] }, { "name": "lpcxpresso55s28", "steps": [ { "type": "configure", "name": "lpcxpresso55s28" }, { "type": "build", "name": "lpcxpresso55s28" } ] }, { "name": "lpcxpresso55s69", "steps": [ { "type": "configure", "name": "lpcxpresso55s69" }, { "type": "build", "name": "lpcxpresso55s69" } ] }, { "name": "max32650evkit", "steps": [ { "type": "configure", "name": "max32650evkit" }, { "type": "build", "name": "max32650evkit" } ] }, { "name": "max32650fthr", "steps": [ { "type": "configure", "name": "max32650fthr" }, { "type": "build", "name": "max32650fthr" } ] }, { "name": "max32651evkit", "steps": [ { "type": "configure", "name": "max32651evkit" }, { "type": "build", "name": "max32651evkit" } ] }, { "name": "max32666evkit", "steps": [ { "type": "configure", "name": "max32666evkit" }, { "type": "build", "name": "max32666evkit" } ] }, { "name": "max32666fthr", "steps": [ { "type": "configure", "name": "max32666fthr" }, { "type": "build", "name": "max32666fthr" } ] }, { "name": "max32690evkit", "steps": [ { "type": "configure", "name": "max32690evkit" }, { "type": "build", "name": "max32690evkit" } ] }, { "name": "max78002evkit", "steps": [ { "type": "configure", "name": "max78002evkit" }, { "type": "build", "name": "max78002evkit" } ] }, { "name": "mbed1768", "steps": [ { "type": "configure", "name": "mbed1768" }, { "type": "build", "name": "mbed1768" } ] }, { "name": "mcb1800", "steps": [ { "type": "configure", "name": "mcb1800" }, { "type": "build", "name": "mcb1800" } ] }, { "name": "mcu_link", "steps": [ { "type": "configure", "name": "mcu_link" }, { "type": "build", "name": "mcu_link" } ] }, { "name": "mcxn947brk", "steps": [ { "type": "configure", "name": "mcxn947brk" }, { "type": "build", "name": "mcxn947brk" } ] }, { "name": "metro_m0_express", "steps": [ { "type": "configure", "name": "metro_m0_express" }, { "type": "build", "name": "metro_m0_express" } ] }, { "name": "metro_m4_express", "steps": [ { "type": "configure", "name": "metro_m4_express" }, { "type": "build", "name": "metro_m4_express" } ] }, { "name": "metro_m7_1011", "steps": [ { "type": "configure", "name": "metro_m7_1011" }, { "type": "build", "name": "metro_m7_1011" } ] }, { "name": "mimxrt1010_evk", "steps": [ { "type": "configure", "name": "mimxrt1010_evk" }, { "type": "build", "name": "mimxrt1010_evk" } ] }, { "name": "mimxrt1015_evk", "steps": [ { "type": "configure", "name": "mimxrt1015_evk" }, { "type": "build", "name": "mimxrt1015_evk" } ] }, { "name": "mimxrt1020_evk", "steps": [ { "type": "configure", "name": "mimxrt1020_evk" }, { "type": "build", "name": "mimxrt1020_evk" } ] }, { "name": "mimxrt1024_evk", "steps": [ { "type": "configure", "name": "mimxrt1024_evk" }, { "type": "build", "name": "mimxrt1024_evk" } ] }, { "name": "mimxrt1050_evkb", "steps": [ { "type": "configure", "name": "mimxrt1050_evkb" }, { "type": "build", "name": "mimxrt1050_evkb" } ] }, { "name": "mimxrt1060_evk", "steps": [ { "type": "configure", "name": "mimxrt1060_evk" }, { "type": "build", "name": "mimxrt1060_evk" } ] }, { "name": "mimxrt1064_evk", "steps": [ { "type": "configure", "name": "mimxrt1064_evk" }, { "type": "build", "name": "mimxrt1064_evk" } ] }, { "name": "mimxrt1170_evkb", "steps": [ { "type": "configure", "name": "mimxrt1170_evkb" }, { "type": "build", "name": "mimxrt1170_evkb" } ] }, { "name": "mm32f327x_mb39", "steps": [ { "type": "configure", "name": "mm32f327x_mb39" }, { "type": "build", "name": "mm32f327x_mb39" } ] }, { "name": "mm32f327x_pitaya_lite", "steps": [ { "type": "configure", "name": "mm32f327x_pitaya_lite" }, { "type": "build", "name": "mm32f327x_pitaya_lite" } ] }, { "name": "msp_exp430f5529lp", "steps": [ { "type": "configure", "name": "msp_exp430f5529lp" }, { "type": "build", "name": "msp_exp430f5529lp" } ] }, { "name": "msp_exp432e401y", "steps": [ { "type": "configure", "name": "msp_exp432e401y" }, { "type": "build", "name": "msp_exp432e401y" } ] }, { "name": "nanoch32v203", "steps": [ { "type": "configure", "name": "nanoch32v203" }, { "type": "build", "name": "nanoch32v203" } ] }, { "name": "nanoch32v305", "steps": [ { "type": "configure", "name": "nanoch32v305" }, { "type": "build", "name": "nanoch32v305" } ] }, { "name": "nrf52833dk", "steps": [ { "type": "configure", "name": "nrf52833dk" }, { "type": "build", "name": "nrf52833dk" } ] }, { "name": "nrf52840dk", "steps": [ { "type": "configure", "name": "nrf52840dk" }, { "type": "build", "name": "nrf52840dk" } ] }, { "name": "nrf52840dongle", "steps": [ { "type": "configure", "name": "nrf52840dongle" }, { "type": "build", "name": "nrf52840dongle" } ] }, { "name": "nrf5340dk", "steps": [ { "type": "configure", "name": "nrf5340dk" }, { "type": "build", "name": "nrf5340dk" } ] }, { "name": "nrf54h20dk", "steps": [ { "type": "configure", "name": "nrf54h20dk" }, { "type": "build", "name": "nrf54h20dk" } ] }, { "name": "nutiny_nuc126v", "steps": [ { "type": "configure", "name": "nutiny_nuc126v" }, { "type": "build", "name": "nutiny_nuc126v" } ] }, { "name": "nutiny_sdk_nuc120", "steps": [ { "type": "configure", "name": "nutiny_sdk_nuc120" }, { "type": "build", "name": "nutiny_sdk_nuc120" } ] }, { "name": "nutiny_sdk_nuc121", "steps": [ { "type": "configure", "name": "nutiny_sdk_nuc121" }, { "type": "build", "name": "nutiny_sdk_nuc121" } ] }, { "name": "nutiny_sdk_nuc125", "steps": [ { "type": "configure", "name": "nutiny_sdk_nuc125" }, { "type": "build", "name": "nutiny_sdk_nuc125" } ] }, { "name": "nutiny_sdk_nuc505", "steps": [ { "type": "configure", "name": "nutiny_sdk_nuc505" }, { "type": "build", "name": "nutiny_sdk_nuc505" } ] }, { "name": "pico_sdk", "steps": [ { "type": "configure", "name": "pico_sdk" }, { "type": "build", "name": "pico_sdk" } ] }, { "name": "portenta_c33", "steps": [ { "type": "configure", "name": "portenta_c33" }, { "type": "build", "name": "portenta_c33" } ] }, { "name": "pybadge", "steps": [ { "type": "configure", "name": "pybadge" }, { "type": "build", "name": "pybadge" } ] }, { "name": "pyboardv11", "steps": [ { "type": "configure", "name": "pyboardv11" }, { "type": "build", "name": "pyboardv11" } ] }, { "name": "pyportal", "steps": [ { "type": "configure", "name": "pyportal" }, { "type": "build", "name": "pyportal" } ] }, { "name": "qtpy", "steps": [ { "type": "configure", "name": "qtpy" }, { "type": "build", "name": "qtpy" } ] }, { "name": "ra2a1_ek", "steps": [ { "type": "configure", "name": "ra2a1_ek" }, { "type": "build", "name": "ra2a1_ek" } ] }, { "name": "ra4m1_ek", "steps": [ { "type": "configure", "name": "ra4m1_ek" }, { "type": "build", "name": "ra4m1_ek" } ] }, { "name": "ra4m3_ek", "steps": [ { "type": "configure", "name": "ra4m3_ek" }, { "type": "build", "name": "ra4m3_ek" } ] }, { "name": "ra6m1_ek", "steps": [ { "type": "configure", "name": "ra6m1_ek" }, { "type": "build", "name": "ra6m1_ek" } ] }, { "name": "ra6m5_ek", "steps": [ { "type": "configure", "name": "ra6m5_ek" }, { "type": "build", "name": "ra6m5_ek" } ] }, { "name": "ra8m1_ek", "steps": [ { "type": "configure", "name": "ra8m1_ek" }, { "type": "build", "name": "ra8m1_ek" } ] }, { "name": "raspberry_pi_pico", "steps": [ { "type": "configure", "name": "raspberry_pi_pico" }, { "type": "build", "name": "raspberry_pi_pico" } ] }, { "name": "raspberry_pi_pico2", "steps": [ { "type": "configure", "name": "raspberry_pi_pico2" }, { "type": "build", "name": "raspberry_pi_pico2" } ] }, { "name": "raspberry_pi_pico_w", "steps": [ { "type": "configure", "name": "raspberry_pi_pico_w" }, { "type": "build", "name": "raspberry_pi_pico_w" } ] }, { "name": "raspberrypi_cm4", "steps": [ { "type": "configure", "name": "raspberrypi_cm4" }, { "type": "build", "name": "raspberrypi_cm4" } ] }, { "name": "raspberrypi_zero", "steps": [ { "type": "configure", "name": "raspberrypi_zero" }, { "type": "build", "name": "raspberrypi_zero" } ] }, { "name": "raspberrypi_zero2", "steps": [ { "type": "configure", "name": "raspberrypi_zero2" }, { "type": "build", "name": "raspberrypi_zero2" } ] }, { "name": "samd11_xplained", "steps": [ { "type": "configure", "name": "samd11_xplained" }, { "type": "build", "name": "samd11_xplained" } ] }, { "name": "same54_xplained", "steps": [ { "type": "configure", "name": "same54_xplained" }, { "type": "build", "name": "same54_xplained" } ] }, { "name": "same70_qmtech", "steps": [ { "type": "configure", "name": "same70_qmtech" }, { "type": "build", "name": "same70_qmtech" } ] }, { "name": "same70_xplained", "steps": [ { "type": "configure", "name": "same70_xplained" }, { "type": "build", "name": "same70_xplained" } ] }, { "name": "samg55_xplained", "steps": [ { "type": "configure", "name": "samg55_xplained" }, { "type": "build", "name": "samg55_xplained" } ] }, { "name": "saml22_feather", "steps": [ { "type": "configure", "name": "saml22_feather" }, { "type": "build", "name": "saml22_feather" } ] }, { "name": "seeeduino_xiao", "steps": [ { "type": "configure", "name": "seeeduino_xiao" }, { "type": "build", "name": "seeeduino_xiao" } ] }, { "name": "sensorwatch_m0", "steps": [ { "type": "configure", "name": "sensorwatch_m0" }, { "type": "build", "name": "sensorwatch_m0" } ] }, { "name": "sipeed_longan_nano", "steps": [ { "type": "configure", "name": "sipeed_longan_nano" }, { "type": "build", "name": "sipeed_longan_nano" } ] }, { "name": "sltb009a", "steps": [ { "type": "configure", "name": "sltb009a" }, { "type": "build", "name": "sltb009a" } ] }, { "name": "sparkfun_samd21_mini_usb", "steps": [ { "type": "configure", "name": "sparkfun_samd21_mini_usb" }, { "type": "build", "name": "sparkfun_samd21_mini_usb" } ] }, { "name": "spresense", "steps": [ { "type": "configure", "name": "spresense" }, { "type": "build", "name": "spresense" } ] }, { "name": "stlinkv3mini", "steps": [ { "type": "configure", "name": "stlinkv3mini" }, { "type": "build", "name": "stlinkv3mini" } ] }, { "name": "stm32c071nucleo", "steps": [ { "type": "configure", "name": "stm32c071nucleo" }, { "type": "build", "name": "stm32c071nucleo" } ] }, { "name": "stm32f070rbnucleo", "steps": [ { "type": "configure", "name": "stm32f070rbnucleo" }, { "type": "build", "name": "stm32f070rbnucleo" } ] }, { "name": "stm32f072disco", "steps": [ { "type": "configure", "name": "stm32f072disco" }, { "type": "build", "name": "stm32f072disco" } ] }, { "name": "stm32f072eval", "steps": [ { "type": "configure", "name": "stm32f072eval" }, { "type": "build", "name": "stm32f072eval" } ] }, { "name": "stm32f103_bluepill", "steps": [ { "type": "configure", "name": "stm32f103_bluepill" }, { "type": "build", "name": "stm32f103_bluepill" } ] }, { "name": "stm32f103_mini_2", "steps": [ { "type": "configure", "name": "stm32f103_mini_2" }, { "type": "build", "name": "stm32f103_mini_2" } ] }, { "name": "stm32f103ze_iar", "steps": [ { "type": "configure", "name": "stm32f103ze_iar" }, { "type": "build", "name": "stm32f103ze_iar" } ] }, { "name": "stm32f207nucleo", "steps": [ { "type": "configure", "name": "stm32f207nucleo" }, { "type": "build", "name": "stm32f207nucleo" } ] }, { "name": "stm32f303disco", "steps": [ { "type": "configure", "name": "stm32f303disco" }, { "type": "build", "name": "stm32f303disco" } ] }, { "name": "stm32f401blackpill", "steps": [ { "type": "configure", "name": "stm32f401blackpill" }, { "type": "build", "name": "stm32f401blackpill" } ] }, { "name": "stm32f407blackvet", "steps": [ { "type": "configure", "name": "stm32f407blackvet" }, { "type": "build", "name": "stm32f407blackvet" } ] }, { "name": "stm32f407disco", "steps": [ { "type": "configure", "name": "stm32f407disco" }, { "type": "build", "name": "stm32f407disco" } ] }, { "name": "stm32f411blackpill", "steps": [ { "type": "configure", "name": "stm32f411blackpill" }, { "type": "build", "name": "stm32f411blackpill" } ] }, { "name": "stm32f411disco", "steps": [ { "type": "configure", "name": "stm32f411disco" }, { "type": "build", "name": "stm32f411disco" } ] }, { "name": "stm32f412disco", "steps": [ { "type": "configure", "name": "stm32f412disco" }, { "type": "build", "name": "stm32f412disco" } ] }, { "name": "stm32f412nucleo", "steps": [ { "type": "configure", "name": "stm32f412nucleo" }, { "type": "build", "name": "stm32f412nucleo" } ] }, { "name": "stm32f439nucleo", "steps": [ { "type": "configure", "name": "stm32f439nucleo" }, { "type": "build", "name": "stm32f439nucleo" } ] }, { "name": "stm32f723disco", "steps": [ { "type": "configure", "name": "stm32f723disco" }, { "type": "build", "name": "stm32f723disco" } ] }, { "name": "stm32f746disco", "steps": [ { "type": "configure", "name": "stm32f746disco" }, { "type": "build", "name": "stm32f746disco" } ] }, { "name": "stm32f746nucleo", "steps": [ { "type": "configure", "name": "stm32f746nucleo" }, { "type": "build", "name": "stm32f746nucleo" } ] }, { "name": "stm32f767nucleo", "steps": [ { "type": "configure", "name": "stm32f767nucleo" }, { "type": "build", "name": "stm32f767nucleo" } ] }, { "name": "stm32f769disco", "steps": [ { "type": "configure", "name": "stm32f769disco" }, { "type": "build", "name": "stm32f769disco" } ] }, { "name": "stm32g0b1nucleo", "steps": [ { "type": "configure", "name": "stm32g0b1nucleo" }, { "type": "build", "name": "stm32g0b1nucleo" } ] }, { "name": "stm32g474nucleo", "steps": [ { "type": "configure", "name": "stm32g474nucleo" }, { "type": "build", "name": "stm32g474nucleo" } ] }, { "name": "stm32g491nucleo", "steps": [ { "type": "configure", "name": "stm32g491nucleo" }, { "type": "build", "name": "stm32g491nucleo" } ] }, { "name": "stm32h503nucleo", "steps": [ { "type": "configure", "name": "stm32h503nucleo" }, { "type": "build", "name": "stm32h503nucleo" } ] }, { "name": "stm32h563nucleo", "steps": [ { "type": "configure", "name": "stm32h563nucleo" }, { "type": "build", "name": "stm32h563nucleo" } ] }, { "name": "stm32h573i_dk", "steps": [ { "type": "configure", "name": "stm32h573i_dk" }, { "type": "build", "name": "stm32h573i_dk" } ] }, { "name": "stm32h723nucleo", "steps": [ { "type": "configure", "name": "stm32h723nucleo" }, { "type": "build", "name": "stm32h723nucleo" } ] }, { "name": "stm32h743eval", "steps": [ { "type": "configure", "name": "stm32h743eval" }, { "type": "build", "name": "stm32h743eval" } ] }, { "name": "stm32h743nucleo", "steps": [ { "type": "configure", "name": "stm32h743nucleo" }, { "type": "build", "name": "stm32h743nucleo" } ] }, { "name": "stm32h745disco", "steps": [ { "type": "configure", "name": "stm32h745disco" }, { "type": "build", "name": "stm32h745disco" } ] }, { "name": "stm32h747disco", "steps": [ { "type": "configure", "name": "stm32h747disco" }, { "type": "build", "name": "stm32h747disco" } ] }, { "name": "stm32h750_weact", "steps": [ { "type": "configure", "name": "stm32h750_weact" }, { "type": "build", "name": "stm32h750_weact" } ] }, { "name": "stm32h750bdk", "steps": [ { "type": "configure", "name": "stm32h750bdk" }, { "type": "build", "name": "stm32h750bdk" } ] }, { "name": "stm32h7s3nucleo", "steps": [ { "type": "configure", "name": "stm32h7s3nucleo" }, { "type": "build", "name": "stm32h7s3nucleo" } ] }, { "name": "stm32l052dap52", "steps": [ { "type": "configure", "name": "stm32l052dap52" }, { "type": "build", "name": "stm32l052dap52" } ] }, { "name": "stm32l0538disco", "steps": [ { "type": "configure", "name": "stm32l0538disco" }, { "type": "build", "name": "stm32l0538disco" } ] }, { "name": "stm32l412nucleo", "steps": [ { "type": "configure", "name": "stm32l412nucleo" }, { "type": "build", "name": "stm32l412nucleo" } ] }, { "name": "stm32l476disco", "steps": [ { "type": "configure", "name": "stm32l476disco" }, { "type": "build", "name": "stm32l476disco" } ] }, { "name": "stm32l496nucleo", "steps": [ { "type": "configure", "name": "stm32l496nucleo" }, { "type": "build", "name": "stm32l496nucleo" } ] }, { "name": "stm32l4p5nucleo", "steps": [ { "type": "configure", "name": "stm32l4p5nucleo" }, { "type": "build", "name": "stm32l4p5nucleo" } ] }, { "name": "stm32l4r5nucleo", "steps": [ { "type": "configure", "name": "stm32l4r5nucleo" }, { "type": "build", "name": "stm32l4r5nucleo" } ] }, { "name": "stm32n6570dk", "steps": [ { "type": "configure", "name": "stm32n6570dk" }, { "type": "build", "name": "stm32n6570dk" } ] }, { "name": "stm32n657nucleo", "steps": [ { "type": "configure", "name": "stm32n657nucleo" }, { "type": "build", "name": "stm32n657nucleo" } ] }, { "name": "stm32u083cdk", "steps": [ { "type": "configure", "name": "stm32u083cdk" }, { "type": "build", "name": "stm32u083cdk" } ] }, { "name": "stm32u545nucleo", "steps": [ { "type": "configure", "name": "stm32u545nucleo" }, { "type": "build", "name": "stm32u545nucleo" } ] }, { "name": "stm32u575eval", "steps": [ { "type": "configure", "name": "stm32u575eval" }, { "type": "build", "name": "stm32u575eval" } ] }, { "name": "stm32u575nucleo", "steps": [ { "type": "configure", "name": "stm32u575nucleo" }, { "type": "build", "name": "stm32u575nucleo" } ] }, { "name": "stm32u5a5nucleo", "steps": [ { "type": "configure", "name": "stm32u5a5nucleo" }, { "type": "build", "name": "stm32u5a5nucleo" } ] }, { "name": "stm32wb55nucleo", "steps": [ { "type": "configure", "name": "stm32wb55nucleo" }, { "type": "build", "name": "stm32wb55nucleo" } ] }, { "name": "stm32wba_nucleo", "steps": [ { "type": "configure", "name": "stm32wba_nucleo" }, { "type": "build", "name": "stm32wba_nucleo" } ] }, { "name": "teensy_35", "steps": [ { "type": "configure", "name": "teensy_35" }, { "type": "build", "name": "teensy_35" } ] }, { "name": "teensy_40", "steps": [ { "type": "configure", "name": "teensy_40" }, { "type": "build", "name": "teensy_40" } ] }, { "name": "teensy_41", "steps": [ { "type": "configure", "name": "teensy_41" }, { "type": "build", "name": "teensy_41" } ] }, { "name": "trinket_m0", "steps": [ { "type": "configure", "name": "trinket_m0" }, { "type": "build", "name": "trinket_m0" } ] }, { "name": "uno_r4", "steps": [ { "type": "configure", "name": "uno_r4" }, { "type": "build", "name": "uno_r4" } ] }, { "name": "waveshare_openh743i", "steps": [ { "type": "configure", "name": "waveshare_openh743i" }, { "type": "build", "name": "waveshare_openh743i" } ] }, { "name": "xmc4500_relax", "steps": [ { "type": "configure", "name": "xmc4500_relax" }, { "type": "build", "name": "xmc4500_relax" } ] }, { "name": "xmc4700_relax", "steps": [ { "type": "configure", "name": "xmc4700_relax" }, { "type": "build", "name": "xmc4700_relax" } ] } ] } ================================================ FILE: hw/bsp/ansi_escape.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /** \ingroup group_board * \defgroup group_ansi_esc ANSI Escape Code * @{ */ #ifndef TUSB_ANSI_ESC_CODE_H_ #define TUSB_ANSI_ESC_CODE_H_ #ifdef __cplusplus extern "C" { #endif #define CSI_CODE(seq) "\33[" seq #define CSI_SGR(x) CSI_CODE(#x) "m" //------------- Cursor movement -------------// /** \defgroup group_ansi_cursor Cursor Movement * @{ */ #define ANSI_CURSOR_UP(n) CSI_CODE(#n "A") ///< Move cursor up #define ANSI_CURSOR_DOWN(n) CSI_CODE(#n "B") ///< Move cursor down #define ANSI_CURSOR_FORWARD(n) CSI_CODE(#n "C") ///< Move cursor forward #define ANSI_CURSOR_BACKWARD(n) CSI_CODE(#n "D") ///< Move cursor backward #define ANSI_CURSOR_LINE_DOWN(n) CSI_CODE(#n "E") ///< Move cursor to the beginning of the line (n) down #define ANSI_CURSOR_LINE_UP(n) CSI_CODE(#n "F") ///< Move cursor to the beginning of the line (n) up #define ANSI_CURSOR_POSITION(n, m) CSI_CODE(#n ";" #m "H") ///< Move cursor to position (n, m) /** @} */ //------------- Screen -------------// /** \defgroup group_ansi_screen Screen Control * @{ */ #define ANSI_ERASE_SCREEN(n) CSI_CODE(#n "J") ///< Erase the screen #define ANSI_ERASE_LINE(n) CSI_CODE(#n "K") ///< Erase the line (n) #define ANSI_SCROLL_UP(n) CSI_CODE(#n "S") ///< Scroll the whole page up (n) lines #define ANSI_SCROLL_DOWN(n) CSI_CODE(#n "T") ///< Scroll the whole page down (n) lines /** @} */ //------------- Text Color -------------// /** \defgroup group_ansi_text Text Color * @{ */ #define ANSI_TEXT_BLACK CSI_SGR(30) #define ANSI_TEXT_RED CSI_SGR(31) #define ANSI_TEXT_GREEN CSI_SGR(32) #define ANSI_TEXT_YELLOW CSI_SGR(33) #define ANSI_TEXT_BLUE CSI_SGR(34) #define ANSI_TEXT_MAGENTA CSI_SGR(35) #define ANSI_TEXT_CYAN CSI_SGR(36) #define ANSI_TEXT_WHITE CSI_SGR(37) #define ANSI_TEXT_DEFAULT CSI_SGR(39) /** @} */ //------------- Background Color -------------// /** \defgroup group_ansi_background Background Color * @{ */ #define ANSI_BG_BLACK CSI_SGR(40) #define ANSI_BG_RED CSI_SGR(41) #define ANSI_BG_GREEN CSI_SGR(42) #define ANSI_BG_YELLOW CSI_SGR(43) #define ANSI_BG_BLUE CSI_SGR(44) #define ANSI_BG_MAGENTA CSI_SGR(45) #define ANSI_BG_CYAN CSI_SGR(46) #define ANSI_BG_WHITE CSI_SGR(47) #define ANSI_BG_DEFAULT CSI_SGR(49) /** @} */ #ifdef __cplusplus } #endif #endif /* TUSB_ANSI_ESC_CODE_H_ */ /** @} */ ================================================ FILE: hw/bsp/at32f402_405/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f402_405.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTGHS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(OTGFS1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif /* config led and key */ led_and_botton_init(); /* config usart to printf */ uart_print_init(115200); // printf("usart printf config success!\r\n"); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void led_and_botton_init(void) { /* LED */ gpio_init_type gpio_led_init_struct; /* enable the led clock */ LED_GPIO_CLK_EN(); /* set default parameter */ gpio_default_para_init(&gpio_led_init_struct); /* configure the led gpio */ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_led_init_struct.gpio_pins = LED_PIN | GPIO_PINS_5 | GPIO_PINS_6; gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(LED_PORT, &gpio_led_init_struct); gpio_bits_set(LED_PORT, GPIO_PINS_5); gpio_bits_set(LED_PORT, GPIO_PINS_6); /* Button */ gpio_init_type gpio_button_init_struct; /* enable the button clock */ BUTTON_GPIO_CLK_EN(); /* set default parameter */ gpio_default_para_init(&gpio_button_init_struct); /* configure the button gpio */ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_button_init_struct.gpio_pins = BUTTON_PIN; gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN; gpio_init(BUTTON_PORT, &gpio_button_init_struct); } /** * @brief usb 48M clock select * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT * @retval none */ void usb_clock48m_select(usb_clk48_s clk_s) { if(clk_s == USB_CLK_HICK) { crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK); /* enable the acc calibration ready interrupt */ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE); /* update the c1\c2\c3 value */ acc_write_c1(7980); acc_write_c2(8000); acc_write_c3(8020); /* open acc calibration */ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE); } else { crm_pllu_output_set(TRUE); /* wait till pll is ready */ while(crm_flag_get(CRM_PLLU_STABLE_FLAG) != SET){} crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_PLLU); } } void usb_gpio_config(void) { /* When the USB clock is enabled, the hardware will automatically configure the pins; but other special pins that need to be used, such as the pins used to detect VBUS or the pins that output the SOF signal, still need to be configured separately, and these pins are usually not required */ } /** * @brief initialize uart * @param baudrate: uart baudrate * @retval none */ void uart_print_init(uint32_t baudrate) { gpio_init_type gpio_init_struct; /* enable the uart and gpio clock */ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE); crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE); gpio_default_para_init(&gpio_init_struct); /* configure the uart tx pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct); gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM); /* configure uart param */ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(PRINT_UART, TRUE); usart_enable(PRINT_UART, TRUE); } // Get characters from UART. Return number of read bytes int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } // Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len) { #if CFG_TUSB_OS == OPT_OS_NONE int txsize = len; u16 timeout = 0xffff; while (txsize--) { while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) { timeout--; if(timeout == 0) { return 0; } } PRINT_UART->dt = (*((uint8_t const *)buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } void board_led_write(bool state) { gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON)); } uint32_t board_button_read(void) { return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * at32_uuid = ((volatile uint32_t*)0x1FFFF7E8); uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = at32_uuid[0]; id32[1] = at32_uuid[1]; id32[2] = at32_uuid[2]; return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f402_405/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f402_405) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f402_405/family.mk ================================================ AT32_FAMILY = at32f402_405 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F402_405 \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F flash: flash-atlink ================================================ FILE: hw/bsp/at32f403a_407/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f403a_407.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f403a_407/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f403a_407) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f403a_407/family.mk ================================================ AT32_FAMILY = at32f403a_407 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F403A_407 LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F flash: flash-atlink ================================================ FILE: hw/bsp/at32f413/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f413.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f413/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f413) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f413/family.mk ================================================ AT32_FAMILY = at32f413 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F413 LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F flash: flash-atlink ================================================ FILE: hw/bsp/at32f415/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f415.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } void board_led_write(bool state) { gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON)); } uint32_t board_button_read(void) { return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8); uint32_t *id32 = (uint32_t *) (uintptr_t) id; uint8_t const len = 12; id32[0] = at32_uuid[0]; id32[1] = at32_uuid[1]; id32[2] = at32_uuid[2]; return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f415/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f415) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4-nofpu CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f415/family.mk ================================================ AT32_FAMILY = at32f415 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4-nofpu CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F415 \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf flash: flash-atlink ================================================ FILE: hw/bsp/at32f423/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f423.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f423/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f423) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f423/family.mk ================================================ AT32_FAMILY = at32f423 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F423 \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf flash: flash-atlink ================================================ FILE: hw/bsp/at32f425/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f425.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } void board_led_write(bool state) { gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON)); } uint32_t board_button_read(void) { return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8); uint32_t *id32 = (uint32_t *) (uintptr_t) id; uint8_t const len = 12; id32[0] = at32_uuid[0]; id32[1] = at32_uuid[1]; id32[2] = at32_uuid[2]; return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f425/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f425) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4-nofpu CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f425/family.mk ================================================ AT32_FAMILY = at32f425 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4-nofpu CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F425 \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf flash: flash-atlink ================================================ FILE: hw/bsp/at32f435_437/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f435_437.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTGFS1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(OTGFS2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #else SysTick_Config(SystemCoreClock / 1000); NVIC_SetPriority(OTGFS1_IRQn, 0); NVIC_SetPriority(OTGFS2_IRQn, 0); #endif /* config led and key */ led_and_botton_init(); /* config usart printf */ uart_print_init(115200); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ /** * @brief usb 48M clock select * @param clk_s:USB_CLK_HICK, USB_CLK_HEXT * @retval none */ void usb_clock48m_select(usb_clk48_s clk_s) { if (clk_s == USB_CLK_HICK) { crm_usb_clock_source_select(CRM_USB_CLOCK_SOURCE_HICK); /* enable the acc calibration ready interrupt */ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, TRUE); /* update the c1\c2\c3 value */ acc_write_c1(7980); acc_write_c2(8000); acc_write_c3(8020); #ifdef BOARD_TUD_RHPORT #if BOARD_TUD_RHPORT == 0 acc_sof_select(ACC_SOF_OTG1); #else acc_sof_select(ACC_SOF_OTG2); #endif #endif /* open acc calibration */ acc_calibration_mode_enable(ACC_CAL_HICKTRIM, TRUE); } else { switch (system_core_clock) { /* 48MHz */ case 48000000: crm_usb_clock_div_set(CRM_USB_DIV_1); break; /* 72MHz */ case 72000000: crm_usb_clock_div_set(CRM_USB_DIV_1_5); break; /* 96MHz */ case 96000000: crm_usb_clock_div_set(CRM_USB_DIV_2); break; /* 120MHz */ case 120000000: crm_usb_clock_div_set(CRM_USB_DIV_2_5); break; /* 144MHz */ case 144000000: crm_usb_clock_div_set(CRM_USB_DIV_3); break; /* 168MHz */ case 168000000: crm_usb_clock_div_set(CRM_USB_DIV_3_5); break; /* 192MHz */ case 192000000: crm_usb_clock_div_set(CRM_USB_DIV_4); break; /* 216MHz */ case 216000000: crm_usb_clock_div_set(CRM_USB_DIV_4_5); break; /* 240MHz */ case 240000000: crm_usb_clock_div_set(CRM_USB_DIV_5); break; /* 264MHz */ case 264000000: crm_usb_clock_div_set(CRM_USB_DIV_5_5); break; /* 288MHz */ case 288000000: crm_usb_clock_div_set(CRM_USB_DIV_6); break; default: break; } } } void led_and_botton_init(void) { /* LED */ gpio_init_type gpio_led_init_struct; /* enable the led clock */ LED_GPIO_CLK_EN(); /* set default parameter */ gpio_default_para_init(&gpio_led_init_struct); /* configure the led gpio */ gpio_led_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_led_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_led_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_led_init_struct.gpio_pins = LED_PIN; gpio_led_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(LED_PORT, &gpio_led_init_struct); gpio_bits_set(LED_PORT, LED_PIN); gpio_bits_set(LED_PORT, GPIO_PINS_14); gpio_bits_set(LED_PORT, GPIO_PINS_15); /* Button */ gpio_init_type gpio_button_init_struct; /* enable the button clock */ BUTTON_GPIO_CLK_EN(); /* set default parameter */ gpio_default_para_init(&gpio_button_init_struct); /* configure the button gpio */ gpio_button_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_button_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_button_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_button_init_struct.gpio_pins = BUTTON_PIN; gpio_button_init_struct.gpio_pull = GPIO_PULL_DOWN; gpio_init(BUTTON_PORT, &gpio_button_init_struct); } /** * @brief initialize uart * @param baudrate: uart baudrate * @retval none */ void uart_print_init(uint32_t baudrate) { gpio_init_type gpio_init_struct; /* enable the uart and gpio clock */ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE); crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE); gpio_default_para_init(&gpio_init_struct); /* configure the uart tx pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct); gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM); /* configure uart param */ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(PRINT_UART, TRUE); usart_enable(PRINT_UART, TRUE); } // Get characters from UART. Return number of read bytes int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } // Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len) { #if CFG_TUSB_OS == OPT_OS_NONE int txsize = len; u16 timeout = 0xffff; while (txsize--) { while (usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET) { timeout--; if (timeout == 0) { return 0; } } PRINT_UART->dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } int inHandlerMode(void) { return __get_IPSR(); } void usb_gpio_config(void) { gpio_init_type gpio_init_struct; crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; /* dp and dm */ gpio_init_struct.gpio_pins = GPIO_PINS_11 | GPIO_PINS_12; gpio_init(GPIOA, &gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_14 | GPIO_PINS_15; gpio_init(GPIOB, &gpio_init_struct); gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE11, GPIO_MUX_10); gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE12, GPIO_MUX_10); gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE14, GPIO_MUX_12); gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE15, GPIO_MUX_12); } void board_led_write(bool state) { gpio_bits_write(LED_PORT, LED_PIN, state ^ (!LED_STATE_ON)); } uint32_t board_button_read(void) { return gpio_input_data_bit_read(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t *at32_uuid = ((volatile uint32_t *) 0x1FFFF7E8); uint32_t *id32 = (uint32_t *) (uintptr_t) id; uint8_t const len = 12; id32[0] = at32_uuid[0]; id32[1] = at32_uuid[1]; id32[2] = at32_uuid[2]; return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f435_437/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f435_437) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_exint.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=1 BOARD_TUH_RHPORT=0 BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f435_437/family.mk ================================================ AT32_FAMILY = at32f435_437 AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F435_437 \ -DBOARD_TUD_RHPORT=1 \ -DBOARD_TUH_RHPORT=0 \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ -DBOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_exint.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf flash: flash-atlink ================================================ FILE: hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // Include MCU header #include "at32f45x.h" #endif /* Cortex-M4 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ system_core_clock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); buf++; } return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void SVC_Handler(void) { } void PendSV_Handler(void) { } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, e.g.: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/at32f45x/family.cmake ================================================ include_guard() set(AT32_FAMILY at32f45x) set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${AT32_SDK_LIB}/cmsis/cm4/core_support ${AT32_SDK_LIB}/cmsis/cm4/device_support ${AT32_SDK_LIB}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/at32f45x/family.mk ================================================ AT32_FAMILY = at32f45x AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS_GCC += \ -flto CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_AT32F45X \ LDFLAGS_GCC += \ -flto --specs=nosys.specs -nostdlib -nostartfiles SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf flash: flash-atlink ================================================ FILE: hw/bsp/board.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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 "board_api.h" //--------------------------------------------------------------------+ // newlib read()/write() retarget //--------------------------------------------------------------------+ #ifdef __ICCARM__ #define sys_write __write #define sys_read __read #elif defined(__MSP430__) || defined(__RX__) || TU_CHECK_MCU(OPT_MCU_NUC120, OPT_MCU_NUC121, OPT_MCU_NUC126, OPT_MCU_NUC505) #define sys_write write #define sys_read read #else #define sys_write _write #define sys_read _read #endif int sys_write(int fhdl, const char *buf, size_t count) TU_ATTR_USED; int sys_read(int fhdl, char *buf, size_t count) TU_ATTR_USED; #if defined(LOGGER_RTT) // Logging with RTT // If using SES IDE, use the Syscalls/SEGGER_RTT_Syscalls_SES.c instead #if !(defined __SES_ARM) && !(defined __SES_RISCV) && !(defined __CROSSWORKS_ARM) #include "SEGGER_RTT.h" int sys_write(int fhdl, const char *buf, size_t count) { (void) fhdl; return (int) SEGGER_RTT_Write(0, buf, (int) count); } int sys_read(int fhdl, char *buf, size_t count) { (void) fhdl; int rd = (int) SEGGER_RTT_Read(0, buf, count); return (rd > 0) ? rd : -1; } #endif #elif defined(LOGGER_SWO) #define ITM_BASE 0xE0000000 #define ITM_STIM0 (*((volatile uint8_t*)(ITM_BASE + 0))) #define ITM_TER *((volatile uint32_t*)(ITM_BASE + 0xE00)) #define ITM_TCR *((volatile uint32_t*)(ITM_BASE + 0xE80)) #define ITM_TCR_ITMENA (1 << 0) // Logging with SWO for ARM Cortex-M int sys_write (int fhdl, const char *buf, size_t count) { (void) fhdl; uint8_t const* buf8 = (uint8_t const*) buf; if ((ITM_TCR & ITM_TCR_ITMENA) && (ITM_TER & 1ul)) { for(size_t i=0; i < count; i++) { while (!(ITM_STIM0 & 1ul)) { asm("nop"); } ITM_STIM0 = buf8[i]; } } return (int) count; } int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; (void) buf; (void) count; return 0; } #else // Default logging with on-board UART int sys_write (int fhdl, const char *buf, size_t count) { (void) fhdl; return board_uart_write(buf, (int) count); } int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; int rd = board_uart_read((uint8_t*) buf, (int) count); return (rd > 0) ? rd : -1; } #endif // Clang use picolibc #if defined(__clang__) static int cl_putc(char c, FILE *f) { (void) f; return sys_write(0, &c, 1); } static int cl_getc(FILE* f) { (void) f; char c; return sys_read(0, &c, 1) > 0 ? c : -1; } static FILE __stdio = FDEV_SETUP_STREAM(cl_putc, cl_getc, NULL, _FDEV_SETUP_RW); FILE *const stdin = &__stdio; __strong_reference(stdin, stdout); __strong_reference(stdin, stderr); #endif //--------------------------------------------------------------------+ // Weak board API (to be optionally implemented by board) //--------------------------------------------------------------------+ TU_ATTR_WEAK size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; // fixed serial string is 01234567889ABCDEF uint32_t* uid32 = (uint32_t*) (uintptr_t)id; uid32[0] = 0x67452301u; uid32[1] = 0xEFCDAB89u; return 8; } TU_ATTR_WEAK void board_init_after_tusb(void) { // nothing to do } TU_ATTR_WEAK void board_reset_to_bootloader(void) { // not implemented } //--------------------------------------------------------------------+ // Board API //--------------------------------------------------------------------+ int board_getchar(void) { char c; return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); } void board_putchar(int c) { (void) sys_write(0, (const char*)&c, 1); } //-------------------------------------------------------------------- // FreeRTOS hooks //-------------------------------------------------------------------- #if CFG_TUSB_OS == OPT_OS_FREERTOS && !defined(ESP_PLATFORM) #include "FreeRTOS.h" #include "task.h" void vApplicationMallocFailedHook(void); // missing prototype void vApplicationMallocFailedHook(void) { taskDISABLE_INTERRUPTS(); TU_ASSERT(false, ); } void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) { (void) pxTask; (void) pcTaskName; taskDISABLE_INTERRUPTS(); TU_ASSERT(false, ); } /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * used by the Idle task. */ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { /* If the buffers to be provided to the Idle task are declared inside this * function then they must be declared static - otherwise they will be allocated on * the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; /* Pass out a pointer to the StaticTask_t structure in which the Idle task's state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. Note that, as the array is necessarily of type StackType_t, configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the * application must provide an implementation of vApplicationGetTimerTaskMemory() * to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) { /* If the buffers to be provided to the Timer task are declared inside this * function then they must be declared static - otherwise they will be allocated on * the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; /* Pass out a pointer to the StaticTask_t structure in which the Timer task's state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; /* Pass out the array that will be used as the Timer task's stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. Note that, as the array is necessarily of type StackType_t, configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } #if CFG_TUSB_MCU == OPT_MCU_RX63X || CFG_TUSB_MCU == OPT_MCU_RX65X void vApplicationSetupTimerInterrupt(void); #include "iodefine.h" void vApplicationSetupTimerInterrupt(void) { /* Enable CMT0 */ unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); MSTP(CMT0) = 0; SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); CMT0.CMCR.WORD = TU_BIT(6) | 2; IR(CMT0, CMI0) = 0; IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY; IEN(CMT0, CMI0) = 1; CMT.CMSTR0.BIT.STR0 = 1; } #endif #endif //-------------------------------------------------------------------- // ThreadX hooks for ARM Cortex-M //-------------------------------------------------------------------- #if CFG_TUSB_OS == OPT_OS_THREADX && defined(__ARM_ARCH) #include "tx_api.h" #include "tx_initialize.h" // Newlib linker symbol: end of statically allocated RAM (start of heap) extern ULONG _end; // CMSIS standard variable for system clock frequency extern uint32_t SystemCoreClock; // Cortex-M SysTick registers (fixed addresses on all Cortex-M) #define _TX_SYST_CSR (*((volatile uint32_t *)0xE000E010U)) #define _TX_SYST_RVR (*((volatile uint32_t *)0xE000E014U)) #define _TX_SYST_CVR (*((volatile uint32_t *)0xE000E018U)) // SCB->SHP[10] = PendSV priority, [11] = SysTick priority (byte access at SCB base + 0xD22) #define _TX_SCB_SHPR3 (*((volatile uint32_t *)0xE000ED20U)) VOID _tx_initialize_low_level(VOID) { // Set the first available memory address for tx_application_define _tx_initialize_unused_memory = (VOID *)(&_end); // Configure SysTick for ThreadX tick rate: enable with processor clock + interrupt _TX_SYST_RVR = (SystemCoreClock / TX_TIMER_TICKS_PER_SECOND) - 1u; _TX_SYST_CVR = 0u; _TX_SYST_CSR = 0x07u; // CLKSOURCE=1, TICKINT=1, ENABLE=1 // SHPR3 bits[31:24] = SysTick priority, bits[23:16] = PendSV priority // PendSV must be lowest priority (0xFF). SysTick must be higher than PendSV (0x40) // so SysTick can preempt the PendSV scheduler idle loop (__tx_ts_wait) to tick the timer. _TX_SCB_SHPR3 = (_TX_SCB_SHPR3 & 0x0000FFFFU) | 0x40FF0000U; } // Weak callback for board-specific SysTick work (e.g. HAL_IncTick on STM32) void osal_threadx_tick_cb(void); TU_ATTR_WEAK void osal_threadx_tick_cb(void) { } // SysTick drives the ThreadX timer tick extern void _tx_timer_interrupt(void); void SysTick_Handler(void); void SysTick_Handler(void) { osal_threadx_tick_cb(); _tx_timer_interrupt(); } #endif ================================================ FILE: hw/bsp/board_api.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef BOARD_API_H_ #define BOARD_API_H_ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include "tusb.h" #if CFG_TUSB_OS == OPT_OS_ZEPHYR #include #elif CFG_TUSB_OS == OPT_OS_FREERTOS #ifdef ESP_PLATFORM // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/queue.h" #include "freertos/task.h" #include "freertos/timers.h" #else #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" #include "task.h" #include "timers.h" #endif #endif // Define the default baudrate #ifndef CFG_BOARD_UART_BAUDRATE #define CFG_BOARD_UART_BAUDRATE 115200 ///< Default baud rate #endif //--------------------------------------------------------------------+ // Board Porting API // For simplicity, only one LED and one Button are used //--------------------------------------------------------------------+ // Initialize on-board peripherals : led, button, uart and USB void board_init(void); // Init board after tinyusb is initialized void board_init_after_tusb(void); // Jump to bootloader void board_reset_to_bootloader(void); // Turn LED on or off void board_led_write(bool state); // Control led pattern using phase duration in ms. // For each phase, LED is toggle then repeated, board_led_task() is required to be called //void board_led_pattern(uint32_t const phase_ms[], uint8_t count); // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void); // Get board unique ID for USB serial number. Return number of bytes. Note max_len is typically 16 size_t board_get_unique_id(uint8_t id[], size_t max_len); // Get characters from UART. Return number of read bytes int board_uart_read(uint8_t *buf, int len); // Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len); //--------------------------------------------------------------------+ // Helper functions //--------------------------------------------------------------------+ static inline void board_led_on(void) { board_led_write(true); } static inline void board_led_off(void) { board_led_write(false); } // Get USB Serial number string from unique ID if available. Return number of character. // Input is string descriptor from index 1 (index 0 is type + len) static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars) { uint8_t uid[16] TU_ATTR_ALIGNED(4); size_t uid_len; // TODO work with make, but not working with esp32s3 cmake uid_len = board_get_unique_id(uid, sizeof(uid)); if ( uid_len > max_chars / 2u ) { uid_len = max_chars / 2u; } for ( size_t i = 0; i < uid_len; i++ ) { for ( size_t j = 0; j < 2; j++ ) { const unsigned char nibble_to_hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; const uint8_t nibble = (uint8_t) ((uid[i] >> (j * 4u)) & 0xfu); desc_str1[i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE } } return 2 * uid_len; } // TODO remove static inline void board_delay(uint32_t ms) { uint32_t start_ms = tusb_time_millis_api(); while ( tusb_time_millis_api() - start_ms < ms ) { // take chance to run usb background #if CFG_TUD_ENABLED tud_task(); #endif #if CFG_TUH_ENABLED tuh_task(); #endif } } // stdio getchar() is blocking, this is non-blocking version int board_getchar(void); void board_putchar(int c); #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake ================================================ set(CMAKE_SYSTEM_CPU arm1176jzf-s CACHE INTERNAL "System Processor") #set(SUFFIX "") function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC BCM_VERSION=2835 ) endfunction() ================================================ FILE: hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Raspberry Pi Zero url: https://www.raspberrypi.org/products/raspberry-pi-zero/ */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk ================================================ CPU_CORE = arm1176jzf-s CFLAGS += -DBCM_VERSION=2835 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2835 SUFFIX = ================================================ FILE: hw/bsp/broadcom_32bit/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Raspberry Pi */ #include "bsp/board_api.h" #include "board.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" #include "broadcom/mmu.h" #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // LED #define LED_PIN 18 #define LED_STATE_ON 1 // UART TX #define UART_TX_PIN 14 //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_init(void) { setup_mmu_flat_map(); init_caches(); // LED gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); gpio_set_pull(LED_PIN, BP_PULL_NONE); board_led_write(true); // Uart COMPLETE_MEMORY_READS; AUX->ENABLES_b.UART_1 = true; UART1->IER = 0; UART1->CNTL = 0; UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; UART1->MCR = 0; UART1->IER = 0; uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); UART1->BAUD = ((source_clock / (115200 * 8)) - 1); UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; COMPLETE_MEMORY_READS; gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); // Turn on USB peripheral. vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); // Timer 1/1024 second tick SYSTMR->CS_b.M1 = 1; SYSTMR->C1 = SYSTMR->CLO + 977; BP_EnableIRQ(TIMER_1_IRQn); BP_SetPriority(USB_IRQn, 0x00); BP_ClearPendingIRQ(USB_IRQn); BP_EnableIRQ(USB_IRQn); BP_EnableIRQs(); } void board_led_write(bool state) { gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} if (cbuf[i] == '\n') { UART1->IO = '\r'; while (!UART1->STAT_b.TX_READY) {} } UART1->IO = cbuf[i]; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/broadcom_32bit/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/broadcom) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS BCM2835 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/broadcom/link.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Startup & Linker script #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/broadcom/gen/interrupt_handlers.c ${SDK_DIR}/broadcom/gpio.c ${SDK_DIR}/broadcom/interrupts.c ${SDK_DIR}/broadcom/mmu.c ${SDK_DIR}/broadcom/caches.c ${SDK_DIR}/broadcom/vcmailbox.c ) target_compile_options(${BOARD_TARGET} PUBLIC -O0 -ffreestanding -mgeneral-regs-only -fno-exceptions -std=c17 ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_BCM2835) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" "LINKER:--entry=_start" --specs=nosys.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" "LINKER:--entry=_start" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/broadcom_32bit/family.mk ================================================ MCU_DIR = hw/mcu/broadcom include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -Wall \ -O0 \ -ffreestanding \ -nostdlib \ -nostartfiles \ -mgeneral-regs-only \ -fno-exceptions \ -std=c17 CROSS_COMPILE = arm-none-eabi- # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ $(MCU_DIR)/broadcom/gpio.c \ $(MCU_DIR)/broadcom/interrupts.c \ $(MCU_DIR)/broadcom/mmu.c \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).s $(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ # Copy to kernel to netboot drive or SD card # Change destinaation to fit your need flash: $(BUILD)/kernel$(SUFFIX).img @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-a72 CACHE INTERNAL "System Processor") set(BCM_VERSION 2711) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Raspberry CM4 url: https://www.raspberrypi.org/products/compute-module-4 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk ================================================ CPU_CORE = cortex-a72 CFLAGS += -DBCM_VERSION=2711 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2711 ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-a53 CACHE INTERNAL "System Processor") set(BCM_VERSION 2837) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Raspberry Zero2 url: https://www.raspberrypi.org/products/raspberry-pi-zero-2-w */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk ================================================ CPU_CORE = cortex-a53 CFLAGS += -DBCM_VERSION=2837 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2837 ================================================ FILE: hw/bsp/broadcom_64bit/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Raspberry Pi */ #include "bsp/board_api.h" #include "board.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" #include "broadcom/mmu.h" #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // LED #define LED_PIN 18 #define LED_STATE_ON 1 // UART TX #define UART_TX_PIN 14 //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_init(void) { setup_mmu_flat_map(); init_caches(); // LED gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); gpio_set_pull(LED_PIN, BP_PULL_NONE); board_led_write(true); // Uart COMPLETE_MEMORY_READS; AUX->ENABLES_b.UART_1 = true; UART1->IER = 0; UART1->CNTL = 0; UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; UART1->MCR = 0; UART1->IER = 0; uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); UART1->BAUD = ((source_clock / (115200 * 8)) - 1); UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; COMPLETE_MEMORY_READS; gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); // Turn on USB peripheral. vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); // Timer 1/1024 second tick SYSTMR->CS_b.M1 = 1; SYSTMR->C1 = SYSTMR->CLO + 977; BP_EnableIRQ(TIMER_1_IRQn); BP_SetPriority(USB_IRQn, 0x00); BP_ClearPendingIRQ(USB_IRQn); BP_EnableIRQ(USB_IRQn); BP_EnableIRQs(); } void board_led_write(bool state) { gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} if (cbuf[i] == '\n') { UART1->IO = '\r'; while (!UART1->STAT_b.TX_READY) {} } UART1->IO = cbuf[i]; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/broadcom_64bit/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/broadcom) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/aarch64_${TOOLCHAIN}.cmake) set(FAMILY_MCUS BCM2711 BCM2835 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/broadcom/link8.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot8.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/broadcom/gen/interrupt_handlers.c ${SDK_DIR}/broadcom/gpio.c ${SDK_DIR}/broadcom/interrupts.c ${SDK_DIR}/broadcom/mmu.c ${SDK_DIR}/broadcom/caches.c ${SDK_DIR}/broadcom/vcmailbox.c ) target_compile_options(${BOARD_TARGET} PUBLIC -O0 -ffreestanding -mgeneral-regs-only -fno-exceptions -std=c17 ) target_compile_definitions(${BOARD_TARGET} PUBLIC BCM_VERSION=${BCM_VERSION} ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ${CMSIS_5}/CMSIS/Core_A/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_BCM${BCM_VERSION}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" "LINKER:--entry=_start" --specs=nosys.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" "LINKER:--entry=_start" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/broadcom_64bit/family.mk ================================================ MCU_DIR = hw/mcu/broadcom include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -Wall \ -O0 \ -ffreestanding \ -nostdlib \ -nostartfiles \ --specs=nosys.specs \ -mgeneral-regs-only \ -std=c17 CROSS_COMPILE = aarch64-none-elf- # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-qual -Wno-error=redundant-decls SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ $(MCU_DIR)/broadcom/gpio.c \ $(MCU_DIR)/broadcom/interrupts.c \ $(MCU_DIR)/broadcom/mmu.c \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c LD_FILE = $(MCU_DIR)/broadcom/link8.ld INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) \ $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include SRC_S += $(MCU_DIR)/broadcom/boot8.s $(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ # Copy to kernel to netboot drive or SD card # Change destinaation to fit your need flash: $(BUILD)/kernel8.img @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy ================================================ FILE: hw/bsp/ch32f20x/boards/ch32f205r-r0/board.cmake ================================================ set(MCU_VARIANT D8C) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CH32F20x_D8C ) endfunction() ================================================ FILE: hw/bsp/ch32f20x/boards/ch32f205r-r0/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023, Denis Krasutski * * 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. */ /* metadata: name: CH32F205r-r0 url: https://github.com/openwch/ch32f20x */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED: need to wire pin LED1 to PC0 in the P1 header #define LED_PORT GPIOC #define LED_PIN GPIO_Pin_1 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE) // Button: need to wire pin KEY to PC1 in the P1 header #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_Pin_0 #define BUTTON_STATE_ACTIVE 0 #define BUTTON_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE) // UART #define UART_DEV USART2 #define UART_DEV_IRQn USART2_IRQn #define UART_DEV_IRQHandler USART2_IRQHandler #define UART_DEV_GPIO_PORT GPIOA #define UART_DEV_TX_PIN GPIO_Pin_2 #define UART_DEV_CLK_EN() do { \ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); \ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); \ } while(0) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32f20x/boards/ch32f205r-r0/board.mk ================================================ LD_FILE = $(FAMILY_PATH)/ch32f205.ld SRC_S += \ $(FAMILY_PATH)/startup_gcc_ch32f20x_d8c.s CFLAGS += \ -DCH32F20x_D8C ================================================ FILE: hw/bsp/ch32f20x/ch32f205.ld ================================================ ENTRY(Reset_Handler) _Min_Heap_Size = 0x200; _Min_Stack_Size = 0x400; MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } SECTIONS { .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) . = ALIGN(4); } >FLASH .text : { . = ALIGN(4); _stext = .; *(.text) *(.text*) *(.glue_7) *(.glue_7t) *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; } >FLASH .rodata : { . = ALIGN(4); *(.rodata) *(.rodata*) . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH _sidata = LOADADDR(.data); .data : { . = ALIGN(4); _sdata = .; *(.data) *(.data*) . = ALIGN(4); _edata = .; } >RAM AT> FLASH . = ALIGN(4); .bss : { _sbss = .; __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; __bss_end__ = _ebss; } >RAM ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); __HeapStart = .; . = . + _Min_Heap_Size; __HeapEnd = .; __StackLimit = .; . = . + _Min_Stack_Size; __StackTop = .; . = ALIGN(4); } >RAM _estack = __StackTop; _sstack = __StackLimit; /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/ch32f20x/ch32f20x_conf.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32f20x_conf.h * Author : WCH * Version : V1.0.0 * Date : 2021/08/08 * Description : Library configuration file. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32F20x_CONF_H #define __CH32F20x_CONF_H #include "ch32f20x_adc.h" #include "ch32f20x_bkp.h" #include "ch32f20x_can.h" #include "ch32f20x_crc.h" #include "ch32f20x_dac.h" #include "ch32f20x_dbgmcu.h" #include "ch32f20x_dma.h" #include "ch32f20x_exti.h" #include "ch32f20x_flash.h" #include "ch32f20x_fsmc.h" #include "ch32f20x_gpio.h" #include "ch32f20x_i2c.h" #include "ch32f20x_iwdg.h" #include "ch32f20x_pwr.h" #include "ch32f20x_rcc.h" #include "ch32f20x_rtc.h" #include "ch32f20x_sdio.h" #include "ch32f20x_spi.h" #include "ch32f20x_tim.h" #include "ch32f20x_usart.h" #include "ch32f20x_wwdg.h" #include "ch32f20x_it.h" #include "ch32f20x_misc.h" #endif /* __CH32F20x_CONF_H */ ================================================ FILE: hw/bsp/ch32f20x/ch32f20x_it.c ================================================ #include "ch32f20x_it.h" #include "ch32f20x.h" /* -------------------------------------------------------------------------- */ void NMI_Handler(void) { } /* -------------------------------------------------------------------------- */ void MemManage_Handler(void) { } /* -------------------------------------------------------------------------- */ void BusFault_Handler(void) { } /* -------------------------------------------------------------------------- */ void UsageFault_Handler(void) { } /* -------------------------------------------------------------------------- */ void DebugMon_Handler(void) { } /* -------------------------------------------------------------------------- */ ================================================ FILE: hw/bsp/ch32f20x/ch32f20x_it.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32f20x_it.h * Author : WCH * Version : V1.0.0 * Date : 2021/08/08 * Description : This file contains the headers of the interrupt handlers. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32F20xIT_H #define __CH32F20xIT_H #include "ch32f20x.h" void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void DebugMon_Handler(void); void USBHS_IRQHandler(void); void SysTick_Handler(void); #endif /* __CH32F20xIT_H */ ================================================ FILE: hw/bsp/ch32f20x/core_cm3.h ================================================ /* There is core_cm3.h wrapper just to avoid warnings from CMSIS headers */ /* if you want use original file add to make file: INC += \ $(TOP)/$(CH32F20X_SDK_SRC)/CMSIS */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include <../../CMSIS/core_cm3.h> #pragma GCC diagnostic pop ================================================ FILE: hw/bsp/ch32f20x/debug_uart.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Denis Krasutski * * 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. * * This file is part of the TinyUSB stack. */ #include #include "board.h" #include "debug_uart.h" #define UART_RINGBUFFER_SIZE_TX 64 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) static char tx_buf[UART_RINGBUFFER_SIZE_TX]; static unsigned int tx_produce = 0; static volatile unsigned int tx_consume = 0; void UART_DEV_IRQHandler(void) { if(USART_GetITStatus(UART_DEV, USART_IT_TC) != RESET) { USART_ClearITPendingBit(UART_DEV, USART_IT_TC); if(tx_consume != tx_produce) { USART_SendData(UART_DEV, tx_buf[tx_consume]); tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; } } } void uart_write(char c) { unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; NVIC_DisableIRQ(UART_DEV_IRQn); if((tx_consume != tx_produce) || (USART_GetFlagStatus(UART_DEV, USART_FLAG_TXE) == RESET)) { tx_buf[tx_produce] = c; tx_produce = tx_produce_next; } else { USART_SendData(UART_DEV, c); } NVIC_EnableIRQ(UART_DEV_IRQn); } void uart_sync(void) { while(tx_consume != tx_produce) { //Waiting for transfer complete } } void usart_printf_init(uint32_t baudrate) { tx_produce = 0; tx_consume = 0; UART_DEV_CLK_EN(); GPIO_InitTypeDef gpio_config = { .GPIO_Pin = UART_DEV_TX_PIN, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_Mode = GPIO_Mode_AF_PP, }; GPIO_Init(UART_DEV_GPIO_PORT, &gpio_config); USART_InitTypeDef uart_config = { .USART_BaudRate = baudrate, .USART_WordLength = USART_WordLength_8b, .USART_StopBits = USART_StopBits_1, .USART_Parity = USART_Parity_No, .USART_HardwareFlowControl = USART_HardwareFlowControl_None, .USART_Mode = USART_Mode_Tx, }; USART_Init(UART_DEV, &uart_config); USART_ITConfig(UART_DEV, USART_IT_TC, ENABLE); USART_Cmd(UART_DEV, ENABLE); NVIC_InitTypeDef nvic_config = { .NVIC_IRQChannel = UART_DEV_IRQn, .NVIC_IRQChannelPreemptionPriority = 1, .NVIC_IRQChannelSubPriority = 3, .NVIC_IRQChannelCmd = ENABLE, }; NVIC_Init(&nvic_config); } ================================================ FILE: hw/bsp/ch32f20x/debug_uart.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Denis Krasutski * * 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. * * This file is part of the TinyUSB stack. */ #include void uart_write(char c); void uart_sync(void); void usart_printf_init(uint32_t baudrate); ================================================ FILE: hw/bsp/ch32f20x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Denis Krasutski * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: WCH */ #include "stdio.h" #include "debug_uart.h" #include "ch32f20x.h" #include "ch32f20x_it.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBHS_IRQHandler(void) { tud_int_handler(0); } void board_init(void) { /* Disable interrupts during init */ __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USBHS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif usart_printf_init(115200); // USB HS Clock config RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); // LED LED_CLOCK_EN(); GPIO_InitTypeDef led_pin_config = { .GPIO_Pin = LED_PIN, .GPIO_Mode = GPIO_Mode_Out_OD, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(LED_PORT, &led_pin_config); // Button BUTTON_CLOCK_EN(); GPIO_InitTypeDef button_pin_config = { .GPIO_Pin = BUTTON_PIN, .GPIO_Mode = GPIO_Mode_IPU, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(BUTTON_PORT, &button_pin_config); /* Enable interrupts globally */ __enable_irq(); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { int txsize = len; while ( txsize-- ) { uart_write(*(uint8_t const*) buf); buf++; } return len; } ================================================ FILE: hw/bsp/ch32f20x/family.cmake ================================================ include_guard() set(CH32_FAMILY ch32f20x) set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}) set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS CH32F20X CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/ch32f205.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/startup_gcc_ch32f20x_d8c.s) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_SRC_DIR}/StdPeriphDriver/src/${CH32_FAMILY}_gpio.c ${SDK_SRC_DIR}/StdPeriphDriver/src/${CH32_FAMILY}_misc.c ${SDK_SRC_DIR}/StdPeriphDriver/src/${CH32_FAMILY}_rcc.c ${SDK_SRC_DIR}/StdPeriphDriver/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_SRC_DIR}/StdPeriphDriver/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_CH32F20X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/wch/dcd_ch32_usbhs.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/ch32f20x/family.mk ================================================ # Submodules CH32F20X_SDK = hw/mcu/wch/ch32f20x # WCH-SDK paths CH32F20X_SDK_SRC = $(CH32F20X_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_CH32F20X \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_gpio.c \ $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_misc.c \ $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_rcc.c \ $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_usart.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(CH32F20X_SDK_SRC)/StdPeriphDriver/inc # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM3 flash: flash-stlink ================================================ FILE: hw/bsp/ch32f20x/startup_gcc_ch32f20x_d8c.s ================================================ /** ****************************************************************************** * @file startup_gcc_ch32f20x_d8c.s * @author Denis Krasutski * @brief CH32F205 Devices vector table * This module performs: * - Set the initial SP * - Set the initial PC == Reset_Handler, * - Set the vector table entries with the exceptions ISR address * - Branches to main in the C library (which eventually * calls main()). * After Reset the Cortex-M3 processor is in Thread mode, * priority is Privileged, and the Stack is set to Main. ****************************************************************************** */ .syntax unified .cpu cortex-m3 .thumb .global g_pfnVectors .global Default_Handler /* start address for the initialization values of the .data section. defined in linker script */ .word _sidata /* start address for the .data section. defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata /* start address for the .bss section. defined in linker script */ .word _sbss /* end address for the .bss section. defined in linker script */ .word _ebss .section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: /* set stack pointer */ ldr sp, =_estack /* Call the clock system initialization function.*/ bl SystemInit /* Copy the data segment initializers from flash to SRAM */ ldr r0, =_sdata ldr r1, =_edata ldr r2, =_sidata movs r3, #0 b LoopCopyDataInit CopyDataInit: ldr r4, [r2, r3] str r4, [r0, r3] adds r3, r3, #4 LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss movs r3, #0 b LoopFillZerobss FillZerobss: str r3, [r2] adds r2, r2, #4 LoopFillZerobss: cmp r2, r4 bcc FillZerobss /* Call static constructors */ bl __libc_init_array /* Call the application's entry point.*/ bl main bx lr .size Reset_Handler, .-Reset_Handler .section .text.Default_Handler,"ax",%progbits Default_Handler: Infinite_Loop: b Infinite_Loop .size Default_Handler, .-Default_Handler /****************************************************************************** * * The minimal vector table for a Cortex M3. Note that the proper constructs * must be placed on this to ensure that it ends up at physical address * 0x0000.0000. * *******************************************************************************/ .section .isr_vector,"a",%progbits .type g_pfnVectors, %object .size g_pfnVectors, .-g_pfnVectors g_pfnVectors: .word _estack .word Reset_Handler .word NMI_Handler .word HardFault_Handler .word MemManage_Handler .word BusFault_Handler .word UsageFault_Handler .word 0 .word 0 .word 0 .word 0 .word SVC_Handler .word DebugMon_Handler .word 0 .word PendSV_Handler .word SysTick_Handler /******************************************************************************* External Interrupts *******************************************************************************/ .word WWDG_IRQHandler .word PVD_IRQHandler .word TAMPER_IRQHandler .word RTC_IRQHandler .word FLASH_IRQHandler .word RCC_IRQHandler .word EXTI0_IRQHandler .word EXTI1_IRQHandler .word EXTI2_IRQHandler .word EXTI3_IRQHandler .word EXTI4_IRQHandler .word DMA1_Channel1_IRQHandler .word DMA1_Channel2_IRQHandler .word DMA1_Channel3_IRQHandler .word DMA1_Channel4_IRQHandler .word DMA1_Channel5_IRQHandler .word DMA1_Channel6_IRQHandler .word DMA1_Channel7_IRQHandler .word ADC1_2_IRQHandler .word USB_HP_CAN1_TX_IRQHandler .word USB_LP_CAN1_RX0_IRQHandler .word CAN1_RX1_IRQHandler .word CAN1_SCE_IRQHandler .word EXTI9_5_IRQHandler .word TIM1_BRK_IRQHandler .word TIM1_UP_IRQHandler .word TIM1_TRG_COM_IRQHandler .word TIM1_CC_IRQHandler .word TIM2_IRQHandler .word TIM3_IRQHandler .word TIM4_IRQHandler .word I2C1_EV_IRQHandler .word I2C1_ER_IRQHandler .word I2C2_EV_IRQHandler .word I2C2_ER_IRQHandler .word SPI1_IRQHandler .word SPI2_IRQHandler .word USART1_IRQHandler .word USART2_IRQHandler .word USART3_IRQHandler .word EXTI15_10_IRQHandler .word RTCAlarm_IRQHandler .word 0 .word TIM8_BRK_IRQHandler .word TIM8_UP_IRQHandler .word TIM8_TRG_COM_IRQHandler .word TIM8_CC_IRQHandler .word RNG_IRQHandler .word FSMC_IRQHandler .word SDIO_IRQHandler .word TIM5_IRQHandler .word SPI3_IRQHandler .word UART4_IRQHandler .word UART5_IRQHandler .word TIM6_IRQHandler .word TIM7_IRQHandler .word DMA2_Channel1_IRQHandler .word DMA2_Channel2_IRQHandler .word DMA2_Channel3_IRQHandler .word DMA2_Channel4_IRQHandler .word DMA2_Channel5_IRQHandler .word ETH_IRQHandler .word ETH_WKUP_IRQHandler .word CAN2_TX_IRQHandler .word CAN2_RX0_IRQHandler .word CAN2_RX1_IRQHandler .word CAN2_SCE_IRQHandler .word OTG_FS_IRQHandler .word USBHSWakeup_IRQHandler .word USBHS_IRQHandler .word DVP_IRQHandler .word UART6_IRQHandler .word UART7_IRQHandler .word UART8_IRQHandler .word TIM9_BRK_IRQHandler .word TIM9_UP_IRQHandler .word TIM9_TRG_COM_IRQHandler .word TIM9_CC_IRQHandler .word TIM10_BRK_IRQHandler .word TIM10_UP_IRQHandler .word TIM10_TRG_COM_IRQHandler .word TIM10_CC_IRQHandler .word DMA2_Channel6_IRQHandler .word DMA2_Channel7_IRQHandler .word DMA2_Channel8_IRQHandler .word DMA2_Channel9_IRQHandler .word DMA2_Channel10_IRQHandler .word DMA2_Channel11_IRQHandler /******************************************************************************* * * Provide weak aliases * *******************************************************************************/ .weak NMI_Handler .thumb_set NMI_Handler,Default_Handler .weak HardFault_Handler .thumb_set HardFault_Handler,Default_Handler .weak MemManage_Handler .thumb_set MemManage_Handler,Default_Handler .weak BusFault_Handler .thumb_set BusFault_Handler,Default_Handler .weak UsageFault_Handler .thumb_set UsageFault_Handler,Default_Handler .weak SVC_Handler .thumb_set SVC_Handler,Default_Handler .weak DebugMon_Handler .thumb_set DebugMon_Handler,Default_Handler .weak PendSV_Handler .thumb_set PendSV_Handler,Default_Handler .weak SysTick_Handler .thumb_set SysTick_Handler,Default_Handler .weak WWDG_IRQHandler .thumb_set WWDG_IRQHandler,Default_Handler .weak PVD_IRQHandler .thumb_set PVD_IRQHandler,Default_Handler .weak TAMPER_IRQHandler .thumb_set TAMPER_IRQHandler,Default_Handler .weak RTC_IRQHandler .thumb_set RTC_IRQHandler,Default_Handler .weak FLASH_IRQHandler .thumb_set FLASH_IRQHandler,Default_Handler .weak RCC_IRQHandler .thumb_set RCC_IRQHandler,Default_Handler .weak EXTI0_IRQHandler .thumb_set EXTI0_IRQHandler,Default_Handler .weak EXTI1_IRQHandler .thumb_set EXTI1_IRQHandler,Default_Handler .weak EXTI2_IRQHandler .thumb_set EXTI2_IRQHandler,Default_Handler .weak EXTI3_IRQHandler .thumb_set EXTI3_IRQHandler,Default_Handler .weak EXTI4_IRQHandler .thumb_set EXTI4_IRQHandler,Default_Handler .weak DMA1_Channel1_IRQHandler .thumb_set DMA1_Channel1_IRQHandler,Default_Handler .weak DMA1_Channel2_IRQHandler .thumb_set DMA1_Channel2_IRQHandler,Default_Handler .weak DMA1_Channel3_IRQHandler .thumb_set DMA1_Channel3_IRQHandler,Default_Handler .weak DMA1_Channel4_IRQHandler .thumb_set DMA1_Channel4_IRQHandler,Default_Handler .weak DMA1_Channel5_IRQHandler .thumb_set DMA1_Channel5_IRQHandler,Default_Handler .weak DMA1_Channel6_IRQHandler .thumb_set DMA1_Channel6_IRQHandler,Default_Handler .weak DMA1_Channel7_IRQHandler .thumb_set DMA1_Channel7_IRQHandler,Default_Handler .weak ADC1_2_IRQHandler .thumb_set ADC1_2_IRQHandler,Default_Handler .weak USB_HP_CAN1_TX_IRQHandler .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler .weak USB_LP_CAN1_RX0_IRQHandler .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler .weak CAN1_RX1_IRQHandler .thumb_set CAN1_RX1_IRQHandler,Default_Handler .weak CAN1_SCE_IRQHandler .thumb_set CAN1_SCE_IRQHandler,Default_Handler .weak EXTI9_5_IRQHandler .thumb_set EXTI9_5_IRQHandler,Default_Handler .weak TIM1_BRK_IRQHandler .thumb_set TIM1_BRK_IRQHandler,Default_Handler .weak TIM1_UP_IRQHandler .thumb_set TIM1_UP_IRQHandler,Default_Handler .weak TIM1_TRG_COM_IRQHandler .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler .weak TIM1_CC_IRQHandler .thumb_set TIM1_CC_IRQHandler,Default_Handler .weak TIM2_IRQHandler .thumb_set TIM2_IRQHandler,Default_Handler .weak TIM3_IRQHandler .thumb_set TIM3_IRQHandler,Default_Handler .weak TIM4_IRQHandler .thumb_set TIM4_IRQHandler,Default_Handler .weak I2C1_EV_IRQHandler .thumb_set I2C1_EV_IRQHandler,Default_Handler .weak I2C1_ER_IRQHandler .thumb_set I2C1_ER_IRQHandler,Default_Handler .weak I2C2_EV_IRQHandler .thumb_set I2C2_EV_IRQHandler,Default_Handler .weak I2C2_ER_IRQHandler .thumb_set I2C2_ER_IRQHandler,Default_Handler .weak SPI1_IRQHandler .thumb_set SPI1_IRQHandler,Default_Handler .weak SPI2_IRQHandler .thumb_set SPI2_IRQHandler,Default_Handler .weak USART1_IRQHandler .thumb_set USART1_IRQHandler,Default_Handler .weak USART2_IRQHandler .thumb_set USART2_IRQHandler,Default_Handler .weak USART3_IRQHandler .thumb_set USART3_IRQHandler,Default_Handler .weak EXTI15_10_IRQHandler .thumb_set EXTI15_10_IRQHandler,Default_Handler .weak RTCAlarm_IRQHandler .thumb_set RTCAlarm_IRQHandler,Default_Handler .weak TIM8_BRK_IRQHandler .thumb_set TIM8_BRK_IRQHandler,Default_Handler .weak TIM8_UP_IRQHandler .thumb_set TIM8_UP_IRQHandler,Default_Handler .weak TIM8_TRG_COM_IRQHandler .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler .weak TIM8_CC_IRQHandler .thumb_set TIM8_CC_IRQHandler,Default_Handler .weak RNG_IRQHandler .thumb_set RNG_IRQHandler,Default_Handler .weak FSMC_IRQHandler .thumb_set FSMC_IRQHandler,Default_Handler .weak SDIO_IRQHandler .thumb_set SDIO_IRQHandler,Default_Handler .weak TIM5_IRQHandler .thumb_set TIM5_IRQHandler,Default_Handler .weak SPI3_IRQHandler .thumb_set SPI3_IRQHandler,Default_Handler .weak UART4_IRQHandler .thumb_set UART4_IRQHandler,Default_Handler .weak UART5_IRQHandler .thumb_set UART5_IRQHandler,Default_Handler .weak TIM6_IRQHandler .thumb_set TIM6_IRQHandler,Default_Handler .weak TIM7_IRQHandler .thumb_set TIM7_IRQHandler,Default_Handler .weak DMA2_Channel1_IRQHandler .thumb_set DMA2_Channel1_IRQHandler,Default_Handler .weak DMA2_Channel2_IRQHandler .thumb_set DMA2_Channel2_IRQHandler,Default_Handler .weak DMA2_Channel3_IRQHandler .thumb_set DMA2_Channel3_IRQHandler,Default_Handler .weak DMA2_Channel4_IRQHandler .thumb_set DMA2_Channel4_IRQHandler,Default_Handler .weak DMA2_Channel5_IRQHandler .thumb_set DMA2_Channel5_IRQHandler,Default_Handler .weak ETH_IRQHandler .thumb_set ETH_IRQHandler,Default_Handler .weak ETH_WKUP_IRQHandler .thumb_set ETH_WKUP_IRQHandler,Default_Handler .weak CAN2_TX_IRQHandler .thumb_set CAN2_TX_IRQHandler,Default_Handler .weak CAN2_RX0_IRQHandler .thumb_set CAN2_RX0_IRQHandler,Default_Handler .weak CAN2_RX1_IRQHandler .thumb_set CAN2_RX1_IRQHandler,Default_Handler .weak CAN2_SCE_IRQHandler .thumb_set CAN2_SCE_IRQHandler,Default_Handler .weak OTG_FS_IRQHandler .thumb_set OTG_FS_IRQHandler,Default_Handler .weak USBHSWakeup_IRQHandler .thumb_set USBHSWakeup_IRQHandler,Default_Handler .weak USBHS_IRQHandler .thumb_set USBHS_IRQHandler,Default_Handler .weak DVP_IRQHandler .thumb_set DVP_IRQHandler,Default_Handler .weak UART6_IRQHandler .thumb_set UART6_IRQHandler,Default_Handler .weak UART7_IRQHandler .thumb_set UART7_IRQHandler,Default_Handler .weak UART8_IRQHandler .thumb_set UART8_IRQHandler,Default_Handler .weak TIM9_BRK_IRQHandler .thumb_set TIM9_BRK_IRQHandler,Default_Handler .weak TIM9_UP_IRQHandler .thumb_set TIM9_UP_IRQHandler,Default_Handler .weak TIM9_TRG_COM_IRQHandler .thumb_set TIM9_TRG_COM_IRQHandler,Default_Handler .weak TIM9_CC_IRQHandler .thumb_set TIM9_CC_IRQHandler,Default_Handler .weak TIM10_BRK_IRQHandler .thumb_set TIM10_BRK_IRQHandler,Default_Handler .weak TIM10_UP_IRQHandler .thumb_set TIM10_UP_IRQHandler,Default_Handler .weak TIM10_TRG_COM_IRQHandler .thumb_set TIM10_TRG_COM_IRQHandler,Default_Handler .weak TIM10_CC_IRQHandler .thumb_set TIM10_CC_IRQHandler,Default_Handler .weak DMA2_Channel6_IRQHandler .thumb_set DMA2_Channel6_IRQHandler,Default_Handler .weak DMA2_Channel7_IRQHandler .thumb_set DMA2_Channel7_IRQHandler,Default_Handler .weak DMA2_Channel8_IRQHandler .thumb_set DMA2_Channel8_IRQHandler,Default_Handler .weak DMA2_Channel9_IRQHandler .thumb_set DMA2_Channel9_IRQHandler,Default_Handler .weak DMA2_Channel10_IRQHandler .thumb_set DMA2_Channel10_IRQHandler,Default_Handler .weak DMA2_Channel11_IRQHandler .thumb_set DMA2_Channel11_IRQHandler,Default_Handler ================================================ FILE: hw/bsp/ch32f20x/system_ch32f20x.c ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32f20x.c * Author : WCH * Version : V1.0.0 * Date : 2021/08/08 * Description : CH32F20x Device Peripheral Access Layer System Source File. * For CH32F208 HSE = 32Mhz * For others HSE = 8Mhz ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #include "ch32f20x.h" /* * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after * reset the HSI is used as SYSCLK source). * If none of the define below is enabled, the HSI is used as System clock source. */ //#define SYSCLK_FREQ_HSE HSE_VALUE //#define SYSCLK_FREQ_48MHz_HSE 48000000 //#define SYSCLK_FREQ_56MHz_HSE 56000000 //#define SYSCLK_FREQ_72MHz_HSE 72000000 #define SYSCLK_FREQ_96MHz_HSE 96000000 //#define SYSCLK_FREQ_120MHz_HSE 120000000 //#define SYSCLK_FREQ_144MHz_HSE 144000000 //#define SYSCLK_FREQ_HSI HSI_VALUE //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 //#define SYSCLK_FREQ_72MHz_HSI 72000000 //#define SYSCLK_FREQ_96MHz_HSI 96000000 //#define SYSCLK_FREQ_120MHz_HSI 120000000 //#define SYSCLK_FREQ_144MHz_HSI 144000000 /* Uncomment the following line if you need to relocate your vector Table in Internal SRAM */ /* #define VECT_TAB_SRAM */ /* Vector Table base offset field This value must be a multiple of 0x200 */ #define VECT_TAB_OFFSET 0x0 /* Clock Definitions */ #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_96MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_120MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_144MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_96MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_120MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_144MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */ #else uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ #endif __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /* system_private_function_proto_types */ static void SetSysClock( void ); #ifdef SYSCLK_FREQ_HSE static void SetSysClockToHSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSE static void SetSysClockTo48_HSE( void ); #elif defined SYSCLK_FREQ_56MHz_HSE static void SetSysClockTo56_HSE( void ); #elif defined SYSCLK_FREQ_72MHz_HSE static void SetSysClockTo72_HSE( void ); #elif defined SYSCLK_FREQ_96MHz_HSE static void SetSysClockTo96_HSE( void ); #elif defined SYSCLK_FREQ_120MHz_HSE static void SetSysClockTo120_HSE( void ); #elif defined SYSCLK_FREQ_144MHz_HSE static void SetSysClockTo144_HSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSI static void SetSysClockTo48_HSI( void ); #elif defined SYSCLK_FREQ_56MHz_HSI static void SetSysClockTo56_HSI( void ); #elif defined SYSCLK_FREQ_72MHz_HSI static void SetSysClockTo72_HSI( void ); #elif defined SYSCLK_FREQ_96MHz_HSI static void SetSysClockTo96_HSI( void ); #elif defined SYSCLK_FREQ_120MHz_HSI static void SetSysClockTo120_HSI( void ); #elif defined SYSCLK_FREQ_144MHz_HSI static void SetSysClockTo144_HSI( void ); #endif /********************************************************************* * @fn SystemInit * * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, * the PLL and update the SystemCoreClock variable. * * @return none */ void SystemInit( void ) { RCC->CTLR |= ( uint32_t )0x00000001; #ifdef CH32F20x_D8C RCC->CFGR0 &= ( uint32_t )0xF8FF0000; #else RCC->CFGR0 &= ( uint32_t )0xF0FF0000; #endif RCC->CTLR &= ( uint32_t )0xFEF6FFFF; RCC->CTLR &= ( uint32_t )0xFFFBFFFF; RCC->CFGR0 &= ( uint32_t )0xFF80FFFF; #ifdef CH32F20x_D8C RCC->CTLR &= ( uint32_t )0xEBFFFFFF; RCC->INTR = 0x00FF0000; RCC->CFGR2 = 0x00000000; #else RCC->INTR = 0x009F0000; #endif SetSysClock(); #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ #endif } /********************************************************************* * @fn SystemCoreClockUpdate * * @brief Update SystemCoreClock variable according to Clock Register Values. * * @return none */ void SystemCoreClockUpdate( void ) { uint32_t tmp = 0, pllmull = 0, pllsource = 0; uint8_t Pll_6_5 = 0; #if defined (CH32F20x_D8C) uint8_t Pll2mull = 0; #endif tmp = RCC->CFGR0 & RCC_SWS; switch( tmp ) { case 0x00: SystemCoreClock = HSI_VALUE; break; case 0x04: SystemCoreClock = HSE_VALUE; break; case 0x08: pllmull = RCC->CFGR0 & RCC_PLLMULL; pllsource = RCC->CFGR0 & RCC_PLLSRC; pllmull = ( pllmull >> 18 ) + 2; #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) if( pllmull == 17 ) { pllmull = 18; } #else if( pllmull == 2 ) { pllmull = 18; } if( pllmull == 15 ) { pllmull = 13; /* *6.5 */ Pll_6_5 = 1; } if( pllmull == 16 ) { pllmull = 15; } if( pllmull == 17 ) { pllmull = 16; } #endif if( pllsource == 0x00 ) { if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE) SystemCoreClock = HSI_VALUE * pllmull; else SystemCoreClock = (HSI_VALUE >> 1) * pllmull; } else { #if defined (CH32F20x_D8C) if(RCC->CFGR2 & (1<<16)){ /* PLL2 */ SystemCoreClock = HSE_VALUE/(((RCC->CFGR2 & 0xF0)>>4) + 1); /* PREDIV2 */ Pll2mull = (uint8_t)((RCC->CFGR2 & 0xF00)>>8); if(Pll2mull == 0) SystemCoreClock = (SystemCoreClock * 5)>>1; else if(Pll2mull == 1) SystemCoreClock = (SystemCoreClock * 25)>>1; else if(Pll2mull == 15) SystemCoreClock = SystemCoreClock * 20; else SystemCoreClock = SystemCoreClock * (Pll2mull + 2); SystemCoreClock = SystemCoreClock/((RCC->CFGR2 & 0xF) + 1); /* PREDIV1 */ } else{/* HSE */ SystemCoreClock = HSE_VALUE/((RCC->CFGR2 & 0xF) + 1); /* PREDIV1 */ } SystemCoreClock = SystemCoreClock * pllmull; #else #if defined (CH32F20x_D8W) if((RCC->CFGR0 & (3<<22)) == (3<<22)) { SystemCoreClock = ((HSE_VALUE>>1)) * pllmull; } else #endif if( ( RCC->CFGR0 & RCC_PLLXTPRE ) != ( uint32_t )RESET ) { #ifdef CH32F20x_D8W SystemCoreClock = ( ( HSE_VALUE >> 2 ) >> 1 ) * pllmull; #else SystemCoreClock = ( HSE_VALUE >> 1 ) * pllmull; #endif } else { #ifdef CH32F20x_D8W SystemCoreClock = ( HSE_VALUE >> 2 ) * pllmull; #else SystemCoreClock = HSE_VALUE * pllmull; #endif } #endif } if( Pll_6_5 == 1 ) SystemCoreClock = ( SystemCoreClock / 2 ); break; default: SystemCoreClock = HSI_VALUE; break; } tmp = AHBPrescTable[( ( RCC->CFGR0 & RCC_HPRE ) >> 4 )]; SystemCoreClock >>= tmp; } /********************************************************************* * @fn SetSysClock * * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClock( void ) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_48MHz_HSE SetSysClockTo48_HSE(); #elif defined SYSCLK_FREQ_56MHz_HSE SetSysClockTo56_HSE(); #elif defined SYSCLK_FREQ_72MHz_HSE SetSysClockTo72_HSE(); #elif defined SYSCLK_FREQ_96MHz_HSE SetSysClockTo96_HSE(); #elif defined SYSCLK_FREQ_120MHz_HSE SetSysClockTo120_HSE(); #elif defined SYSCLK_FREQ_144MHz_HSE SetSysClockTo144_HSE(); #elif defined SYSCLK_FREQ_48MHz_HSI SetSysClockTo48_HSI(); #elif defined SYSCLK_FREQ_56MHz_HSI SetSysClockTo56_HSI(); #elif defined SYSCLK_FREQ_72MHz_HSI SetSysClockTo72_HSI(); #elif defined SYSCLK_FREQ_96MHz_HSI SetSysClockTo96_HSI(); #elif defined SYSCLK_FREQ_120MHz_HSI SetSysClockTo120_HSI(); #elif defined SYSCLK_FREQ_144MHz_HSI SetSysClockTo144_HSI(); #endif /* If none of the define above is enabled, the HSI is used as System clock * source (default after reset) */ } #ifdef SYSCLK_FREQ_HSE /********************************************************************* * @fn SetSysClockToHSE * * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockToHSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV1; /* Select HSE as system clock source * CH32F20x_D6 (HSE=8Mhz) * CH32F20x_D8 (HSE=8Mhz) * CH32F20x_D8W (HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_HSE; /* Wait till HSE is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x04 ) { } } else { /* If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSE /********************************************************************* * @fn SetSysClockTo48_HSE * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz(HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_56MHz_HSE /********************************************************************* * @fn SetSysClockTo56_HSE * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz(HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_72MHz_HSE /********************************************************************* * @fn SetSysClockTo72_HSE * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz(HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_96MHz_HSE /********************************************************************* * @fn SetSysClockTo96_HSE * * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo96_HSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz(HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_120MHz_HSE /********************************************************************* * @fn SetSysClockTo120_HSE * * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo120_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { #if defined (CH32F20x_D8W) RCC->CFGR0 |= (uint32_t)(3<<22); /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; #else /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; #endif /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz(HSE=32Mhz) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_144MHz_HSE /********************************************************************* * @fn SetSysClockTo144_HSE * * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo144_HSE( void ) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) { HSEStatus = ( uint32_t )0x01; } else { HSEStatus = ( uint32_t )0x00; } if( HSEStatus == ( uint32_t )0x01 ) { /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8Mhz) * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8Mhz) * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz(HSE=32Mhz) */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSI /********************************************************************* * @fn SetSysClockTo48_HSI * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSI( void ) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } #elif defined SYSCLK_FREQ_56MHz_HSI /********************************************************************* * @fn SetSysClockTo56_HSI * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSI( void ) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } #elif defined SYSCLK_FREQ_72MHz_HSI /********************************************************************* * @fn SetSysClockTo72_HSI * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSI( void ) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } #elif defined SYSCLK_FREQ_96MHz_HSI /********************************************************************* * @fn SetSysClockTo96_HSI * * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo96_HSI( void ) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } #elif defined SYSCLK_FREQ_120MHz_HSI /********************************************************************* * @fn SetSysClockTo120_HSI * * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo120_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_144MHz_HSI /********************************************************************* * @fn SetSysClockTo144_HSI * * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo144_HSI( void ) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); #if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18 ); #else RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18_EXTEN ); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) { } /* Select PLL as system clock source */ RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) { } } #endif ================================================ FILE: hw/bsp/ch32f20x/system_ch32f20x.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32f20x.h * Author : WCH * Version : V1.0.0 * Date : 2021/08/08 * Description : CH32F20x Device Peripheral Access Layer System Header File. *******************************************************************************/ #ifndef __SYSTEM_CH32F20x_H #define __SYSTEM_CH32F20x_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ /* System_Exported_Functions */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); #ifdef __cplusplus } #endif #endif /*__CH32F20x_SYSTEM_H */ ================================================ FILE: hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake ================================================ set(LD_FLASH_SIZE 64K) set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() ================================================ FILE: hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h ================================================ /* metadata: name: CH32V103R-R1-1v1 url: https://github.com/openwch/ch32v103/tree/main/SCHPCB/CH32V103R-R1-1v1 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_10 #define LED_STATE_ON 0 #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_Pin_1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk ================================================ CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=64K \ -Wl,--defsym=__RAM_SIZE=20K \ ================================================ FILE: hw/bsp/ch32v10x/ch32v10x_conf.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v10x_conf.h * Author : WCH * Version : V1.0.0 * Date : 2020/04/30 * Description : Library configuration file. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32V10x_CONF_H #define __CH32V10x_CONF_H #include "ch32v10x_adc.h" #include "ch32v10x_bkp.h" #include "ch32v10x_crc.h" #include "ch32v10x_dbgmcu.h" #include "ch32v10x_dma.h" #include "ch32v10x_exti.h" #include "ch32v10x_flash.h" #include "ch32v10x_gpio.h" #include "ch32v10x_i2c.h" #include "ch32v10x_iwdg.h" #include "ch32v10x_pwr.h" #include "ch32v10x_rcc.h" #include "ch32v10x_rtc.h" #include "ch32v10x_spi.h" #include "ch32v10x_tim.h" #include "ch32v10x_usart.h" #include "ch32v10x_wwdg.h" #include "ch32v10x_usb.h" #include "ch32v10x_usb_host.h" #include "ch32v10x_it.h" #include "ch32v10x_misc.h" #endif /* __CH32V10x_CONF_H */ ================================================ FILE: hw/bsp/ch32v10x/ch32v10x_it.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v10x_it.h * Author : WCH * Version : V1.0.0 * Date : 2022/08/20 * Description : This file contains the headers of the interrupt handlers. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32V10x_IT_H #define __CH32V10x_IT_H #ifdef __cplusplus extern "C" { #endif #include "ch32v10x.h" void USBHD_IRQHandler(void); void USBWakeUp_IRQHandler(void); void SysTick_Handler(void); #ifdef __cplusplus } #endif #endif /* __CH32V10x_IT_H */ ================================================ FILE: hw/bsp/ch32v10x/family.c ================================================ /* metadata: manufacturer: WCH */ #include // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "ch32v10x.h" #include "ch32v10x_it.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" __attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } __attribute__((interrupt)) __attribute__((used)) void USBWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; __attribute__((interrupt)) __attribute__((used)) void SysTick_Handler(void) { SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; system_ticks++; } static uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); SysTick->CTLR = 0; SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; SysTick->CMPLR0 = (u8)(ticks & 0xFF); SysTick->CMPLR1 = (u8)(ticks >> 8); SysTick->CMPLR2 = (u8)(ticks >> 16); SysTick->CMPLR3 = (u8)(ticks >> 24); SysTick->CMPHR0 = SysTick->CMPHR1 = SysTick->CMPHR2 = SysTick->CMPHR3 = 0; SysTick->CTLR = 1; return 0; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void board_init(void) { __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #endif RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); EXTEN->EXTEN_CTR |= EXTEN_USBFS_IO_EN; uint8_t usb_div; switch (SystemCoreClock) { case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; case 72000000: usb_div = RCC_USBCLKSource_PLLCLK_1Div5; break; default: TU_ASSERT(0,); break; } RCC_USBCLKConfig(usb_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBFS, ENABLE); #ifdef LED_PIN GPIO_InitTypeDef led_init = { .GPIO_Pin = LED_PIN, .GPIO_Mode = GPIO_Mode_Out_OD, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(LED_PORT, &led_init); #endif #ifdef BUTTON_PIN GPIO_InitTypeDef button_init = { .GPIO_Pin = BUTTON_PIN, .GPIO_Mode = GPIO_Mode_IPU, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(BUTTON_PORT, &button_init); #endif // UART TX is PA9 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitTypeDef usart_init = { .GPIO_Pin = GPIO_Pin_9, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_Mode = GPIO_Mode_AF_PP, }; GPIO_Init(GPIOA, &usart_init); USART_InitTypeDef usart = { .USART_BaudRate = 115200, .USART_WordLength = USART_WordLength_8b, .USART_StopBits = USART_StopBits_1, .USART_Parity = USART_Parity_No, .USART_Mode = USART_Mode_Tx, .USART_HardwareFlowControl = USART_HardwareFlowControl_None, }; USART_Init(USART1, &usart); USART_Cmd(USART1, ENABLE); __enable_irq(); board_led_write(true); } void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { const char *bufc = (const char *) buf; for (int i = 0; i < len; i++) { while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, *bufc++); } return len; } ================================================ FILE: hw/bsp/ch32v10x/family.cmake ================================================ include_guard() #set(UF2_FAMILY_ID 0x699b62ec) set(CH32_FAMILY ch32v10x) set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v103) set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS CH32V103 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${CH32_FAMILY}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_SRC_DIR}/Core/core_riscv.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${BOARD_TARGET} PUBLIC -mcmodel=medany) endif() endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_CH32V103) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd_wch(${TARGET}) #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) endfunction() ================================================ FILE: hw/bsp/ch32v10x/family.mk ================================================ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- CH32_FAMILY = ch32v10x SDK_DIR = hw/mcu/wch/ch32v103 SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 # Port0 use FSDev, Port1 use USBFS PORT ?= 0 CFLAGS += \ -mcmodel=medany \ -ffat-lto-objects \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_CH32V103 # https://github.com/openwch/ch32v20x/pull/12 CFLAGS += -Wno-error=strict-prototypes LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg flash: flash-openocd-wch ================================================ FILE: hw/bsp/ch32v10x/linker/ch32v10x.ld ================================================ /* Define default values if not already defined */ __FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; __RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE } ENTRY( _start ) __stack_size = 2048; PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } ================================================ FILE: hw/bsp/ch32v10x/system_ch32v10x.c ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v10x.c * Author : WCH * Version : V1.0.0 * Date : 2020/04/30 * Description : CH32V10x Device Peripheral Access Layer System Source File. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #include "ch32v10x.h" /* * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after * reset the HSI is used as SYSCLK source). * If none of the define below is enabled, the HSI is used as System clock source. */ //#define SYSCLK_FREQ_HSE HSE_VALUE //#define SYSCLK_FREQ_48MHz_HSE 48000000 //#define SYSCLK_FREQ_56MHz_HSE 56000000 #define SYSCLK_FREQ_72MHz_HSE 72000000 //#define SYSCLK_FREQ_HSI HSI_VALUE //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 //#define SYSCLK_FREQ_72MHz_HSI 72000000 /* Clock Definitions */ #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ #else uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ #endif __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /* ch32v10x_system_private_function_proto_types */ static void SetSysClock(void); #ifdef SYSCLK_FREQ_HSE static void SetSysClockToHSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSE static void SetSysClockTo48_HSE( void ); #elif defined SYSCLK_FREQ_56MHz_HSE static void SetSysClockTo56_HSE( void ); #elif defined SYSCLK_FREQ_72MHz_HSE static void SetSysClockTo72_HSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSI static void SetSysClockTo48_HSI( void ); #elif defined SYSCLK_FREQ_56MHz_HSI static void SetSysClockTo56_HSI( void ); #elif defined SYSCLK_FREQ_72MHz_HSI static void SetSysClockTo72_HSI( void ); #endif /********************************************************************* * @fn SystemInit * * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, * the PLL and update the SystemCoreClock variable. * * @return none */ void SystemInit(void) { RCC->CTLR |= (uint32_t)0x00000001; RCC->CFGR0 &= (uint32_t)0xF8FF0000; RCC->CTLR &= (uint32_t)0xFEF6FFFF; RCC->CTLR &= (uint32_t)0xFFFBFFFF; RCC->CFGR0 &= (uint32_t)0xFF80FFFF; RCC->INTR = 0x009F0000; SetSysClock(); } /********************************************************************* * @fn SystemCoreClockUpdate * * @brief Update SystemCoreClock variable according to Clock Register Values. * * @return none */ void SystemCoreClockUpdate(void) { uint32_t tmp = 0, pllmull = 0, pllsource = 0; tmp = RCC->CFGR0 & RCC_SWS; switch(tmp) { case 0x00: SystemCoreClock = HSI_VALUE; break; case 0x04: SystemCoreClock = HSE_VALUE; break; case 0x08: pllmull = RCC->CFGR0 & RCC_PLLMULL; pllsource = RCC->CFGR0 & RCC_PLLSRC; pllmull = (pllmull >> 18) + 2; if(pllsource == 0x00) { if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE ) { SystemCoreClock = ( HSI_VALUE ) * pllmull; } else { SystemCoreClock = ( HSI_VALUE >> 1 ) * pllmull; } } else { if((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) { SystemCoreClock = (HSE_VALUE >> 1) * pllmull; } else { SystemCoreClock = HSE_VALUE * pllmull; } } break; default: SystemCoreClock = HSI_VALUE; break; } tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; SystemCoreClock >>= tmp; } /********************************************************************* * @fn SetSysClock * * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClock(void) { //GPIO_IPD_Unused(); #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_48MHz_HSE SetSysClockTo48_HSE(); #elif defined SYSCLK_FREQ_56MHz_HSE SetSysClockTo56_HSE(); #elif defined SYSCLK_FREQ_72MHz_HSE SetSysClockTo72_HSE(); #elif defined SYSCLK_FREQ_48MHz_HSI SetSysClockTo48_HSI(); #elif defined SYSCLK_FREQ_56MHz_HSI SetSysClockTo56_HSI(); #elif defined SYSCLK_FREQ_72MHz_HSI SetSysClockTo72_HSI(); #endif /* If none of the define above is enabled, the HSI is used as System clock * source (default after reset) */ } #ifdef SYSCLK_FREQ_HSE /********************************************************************* * @fn SetSysClockToHSE * * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockToHSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if(HSEStatus == (uint32_t)0x01) { FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 0 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; /* Select HSE as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; /* Wait till HSE is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) { } } else { /* If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSE /********************************************************************* * @fn SetSysClockTo48_HSE * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if(HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 1 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_56MHz_HSE /********************************************************************* * @fn SetSysClockTo56_HSE * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if(HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 2 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_72MHz_HSE /********************************************************************* * @fn SetSysClockTo72_HSE * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if(HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 2 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSI /********************************************************************* * @fn SetSysClockTo48_HSI * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 1 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_56MHz_HSI /********************************************************************* * @fn SetSysClockTo56_HSI * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 1 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_72MHz_HSI /********************************************************************* * @fn SetSysClockTo72_HSI * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* Enable Prefetch Buffer */ FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; /* Flash 1 wait state */ FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #endif ================================================ FILE: hw/bsp/ch32v10x/system_ch32v10x.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v10x.h * Author : WCH * Version : V1.0.0 * Date : 2020/04/30 * Description : CH32V10x Device Peripheral Access Layer System Header File. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __SYSTEM_CH32V10x_H #define __SYSTEM_CH32V10x_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ /* System_Exported_Functions */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); #ifdef __cplusplus } #endif #endif /*__CH32V10x_SYSTEM_H */ ================================================ FILE: hw/bsp/ch32v10x/wch-riscv.cfg ================================================ adapter driver wlinke adapter speed 6000 transport select sdi wlink_set_address 0x00000000 set _CHIPNAME wch_riscv sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME $_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 echo "Ready for Remote Connections" ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake ================================================ set(MCU_VARIANT D6) # 64KB zero-wait, 224KB total flash #set(LD_FLASH_SIZE 64K) set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 20K) # set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h ================================================ /* metadata: name: CH32V203C-R0-1v0 url: https://github.com/openwch/ch32v20x/tree/main/SCHPCB/CH32V203C-R0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_0 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) #define LED_MODE GPIO_Mode_Out_OD #define UART_DEV USART1 #define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) #define UART_TX_PIN GPIO_Pin_9 #define UART_RX_PIN GPIO_Pin_10 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk ================================================ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSE=144000000 \ -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ # 64KB zero-wait, 224KB total flash LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=20K \ ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake ================================================ set(MCU_VARIANT D6) # 32KB zero-wait, 224KB total flash #set(LD_FLASH_SIZE 32K) set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 10K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSI=144000000 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h ================================================ /* metadata: name: CH32V203G-R0-1v0 url: https://github.com/openwch/ch32v20x/tree/main/SCHPCB/CH32V203C-R0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_0 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) #define LED_MODE GPIO_Mode_Out_OD #define UART_DEV USART2 #define UART_CLOCK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE) #define UART_TX_PIN GPIO_Pin_2 #define UART_RX_PIN GPIO_Pin_3 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk ================================================ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSI=144000000 \ -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ # 32KB zero-wait, 224KB total flash LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=10K \ ================================================ FILE: hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake ================================================ set(MCU_VARIANT D6) # 64KB zero-wait, 224KB total flash set(LD_FLASH_SIZE 64K) #set(LD_FLASH_SIZE 224K) set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() ================================================ FILE: hw/bsp/ch32v20x/boards/nanoch32v203/board.h ================================================ /* metadata: name: nanoCH32V203 url: https://github.com/wuxx/nanoCH32V203 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_15 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) #define LED_MODE GPIO_Mode_Out_OD #define UART_DEV USART1 #define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) #define UART_TX_PIN GPIO_Pin_9 #define UART_RX_PIN GPIO_Pin_10 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v20x/boards/nanoch32v203/board.mk ================================================ MCU_VARIANT = D6 CFLAGS += \ -DSYSCLK_FREQ_144MHz_HSE=144000000 \ -DCH32_FLASH_ENHANCE_READ_MODE=1 \ -DCFG_EXAMPLE_MSC_DUAL_READONLY \ # 64KB zero-wait , 224KB total flash LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=224K \ -Wl,--defsym=__RAM_SIZE=20K \ ================================================ FILE: hw/bsp/ch32v20x/ch32v20x_conf.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v20x_conf.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : Library configuration file. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32V20x_CONF_H #define __CH32V20x_CONF_H #include "ch32v20x_adc.h" #include "ch32v20x_bkp.h" #include "ch32v20x_can.h" #include "ch32v20x_crc.h" #include "ch32v20x_dbgmcu.h" #include "ch32v20x_dma.h" #include "ch32v20x_exti.h" #include "ch32v20x_flash.h" #include "ch32v20x_gpio.h" #include "ch32v20x_i2c.h" #include "ch32v20x_iwdg.h" #include "ch32v20x_pwr.h" #include "ch32v20x_rcc.h" #include "ch32v20x_rtc.h" #include "ch32v20x_spi.h" #include "ch32v20x_tim.h" #include "ch32v20x_usart.h" #include "ch32v20x_wwdg.h" #include "ch32v20x_it.h" #include "ch32v20x_misc.h" #endif /* __CH32V20x_CONF_H */ ================================================ FILE: hw/bsp/ch32v20x/ch32v20x_it.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v20x_it.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : This file contains the headers of the interrupt handlers. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __CH32V20x_IT_H #define __CH32V20x_IT_H #ifdef __cplusplus extern "C" { #endif #include "ch32v20x.h" void USB_LP_CAN1_RX0_IRQHandler(void); void USB_HP_CAN1_TX_IRQHandler(void); void USBWakeUp_IRQHandler(void); void USBHD_IRQHandler(void); void USBHDWakeUp_IRQHandler(void); void SysTick_Handler(void); #ifdef __cplusplus } #endif #endif /* __CH32V20x_IT_H */ ================================================ FILE: hw/bsp/ch32v20x/family.c ================================================ /* metadata: manufacturer: WCH */ #include // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "ch32v20x.h" #include "ch32v20x_it.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" /* CH32v203 depending on variants can support 2 USB IPs: FSDEV (port0) and USBFS (port1). * By default, we use FSDEV, but you can explicitly select by define: * - CFG_TUD_WCH_USBIP_FSDEV * - CFG_TUD_WCH_USBIP_USBFS */ // Port0: USBD (fsdev) __attribute__((interrupt)) __attribute__((used)) void USB_LP_CAN1_RX0_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_FSDEV tud_int_handler(0); #endif } __attribute__((interrupt)) __attribute__((used)) void USB_HP_CAN1_TX_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_FSDEV tud_int_handler(0); #endif } __attribute__((interrupt)) __attribute__((used)) void USBWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_FSDEV tud_int_handler(0); #endif } // Port1: USBFS __attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) { #if CFG_TUD_ENABLED && CFG_TUD_WCH_USBIP_USBFS tud_int_handler(1); #endif #if CFG_TUH_ENABLED tuh_int_handler(1); #endif } __attribute__((interrupt)) __attribute__((used)) void USBHDWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } //--------------------------------------------------------------------+ // Board API //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; __attribute__((interrupt)) void SysTick_Handler(void) { SysTick->SR = 0; system_ticks++; } static uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); SysTick->CTLR = 0; SysTick->SR = 0; SysTick->CNT = 0; SysTick->CMP = ticks - 1; SysTick->CTLR = 0xF; return 0; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void board_init(void) { __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #endif LED_CLOCK_EN(); GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Pin = LED_PIN, .GPIO_Mode = LED_MODE, .GPIO_Speed = GPIO_Speed_10MHz, }; GPIO_Init(LED_PORT, &GPIO_InitStructure); #ifdef UART_DEV UART_CLOCK_EN(); GPIO_InitTypeDef usart_init = { .GPIO_Pin = UART_TX_PIN | UART_RX_PIN, .GPIO_Speed = GPIO_Speed_50MHz, .GPIO_Mode = GPIO_Mode_AF_PP, }; GPIO_Init(GPIOA, &usart_init); USART_InitTypeDef usart = { .USART_BaudRate = 115200, .USART_WordLength = USART_WordLength_8b, .USART_StopBits = USART_StopBits_1, .USART_Parity = USART_Parity_No, .USART_Mode = USART_Mode_Tx | USART_Mode_Rx, .USART_HardwareFlowControl = USART_HardwareFlowControl_None, }; USART_Init(UART_DEV, &usart); USART_Cmd(UART_DEV, ENABLE); #endif // USB init uint8_t usb_div; switch (SystemCoreClock) { case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break; case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break; default: TU_ASSERT(0,); break; } RCC_USBCLKConfig(usb_div); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS __enable_irq(); } void board_reset_to_bootloader(void) { // board_led_write(true); // // __disable_irq(); // // #if CFG_TUD_ENABLED // tud_deinit(0); // RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, ENABLE); // RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, DISABLE); // #endif // // SysTick->CTLR = 0; // for (int i = WWDG_IRQn; i< DMA1_Channel8_IRQn; i++) { // NVIC_DisableIRQ(i); // } // // __enable_irq(); // // // define function pointer to BOOT ROM address // void (*bootloader_entry)(void) = (void (*)(void))0x1FFF8000; // // bootloader_entry(); // // board_led_write(false); // while(1) { } } void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { return false; } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t* ch32_uuid = ((volatile uint32_t*) 0x1FFFF7E8UL); uint32_t* serial_32 = (uint32_t*) (uintptr_t) id; serial_32[0] = ch32_uuid[0]; serial_32[1] = ch32_uuid[1]; serial_32[2] = ch32_uuid[2]; return 12; } int board_uart_read(uint8_t *buf, int len) { #ifdef UART_DEV int count; for (count = 0; count < len; count++) { if (USART_GetFlagStatus(UART_DEV, USART_FLAG_RXNE) == RESET) { break; } buf[count] = USART_ReceiveData(UART_DEV); } return count; #else (void) buf; (void) len; return 0; #endif } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV const char *bufc = (const char *) buf; for (int i = 0; i < len; i++) { while (USART_GetFlagStatus(UART_DEV, USART_FLAG_TC) == RESET); USART_SendData(UART_DEV, *bufc++); } #else (void) buf; (void) len; #endif return len; } ================================================ FILE: hw/bsp/ch32v20x/family.cmake ================================================ include_guard() set(UF2_FAMILY_ID 0x699b62ec) set(CH32_FAMILY ch32v20x) set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}) set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") # Port0 use FSDev, Port1 use USBFS if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () # only port1 support host mode set(RHPORT_HOST 1) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${CH32_FAMILY}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_SRC_DIR}/Core/core_riscv.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_flash.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC CH32V20x_${MCU_VARIANT} BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUH_RHPORT=${RHPORT_HOST} ) if (RHPORT_DEVICE EQUAL 0) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUD_WCH_USBIP_FSDEV=1) elseif (RHPORT_DEVICE EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUH_WCH_USBIP_USBFS=1) else() message(FATAL_ERROR "Invalid RHPORT_DEVICE ${RHPORT_DEVICE}") endif() update_board(${BOARD_TARGET}) if (LD_FLASH_SIZE STREQUAL 224K) target_compile_definitions(${BOARD_TARGET} PUBLIC CH32_FLASH_ENHANCE_READ_MODE=1 ) endif() if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PUBLIC -mcmodel=medany) endif() endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ${TOP}/src/portable/wch/hcd_ch32_usbfs.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC -nostartfiles --specs=nosys.specs --specs=nano.specs -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd_wch(${TARGET}) family_flash_wlink_rs(${TARGET}) #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) endfunction() ================================================ FILE: hw/bsp/ch32v20x/family.mk ================================================ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- CH32_FAMILY = ch32v20x SDK_DIR = hw/mcu/wch/ch32v20x SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 # Port0 use FSDev, Port1 use USBFS PORT ?= 0 CFLAGS += \ -mcmodel=medany \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X # https://github.com/openwch/ch32v20x/pull/12 CFLAGS += -Wno-error=strict-prototypes ifeq ($(PORT),0) $(info "Using FSDEV driver") CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 $(info "Using USBFS Host driver") CFLAGS += -DCFG_TUH_WCH_USBIP_USBFS=1 else $(info "Using USBFS driver") CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ src/portable/wch/hcd_ch32_usbfs.c \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg flash: flash-wlink-rs #flash: flash-openocd-wch ================================================ FILE: hw/bsp/ch32v20x/linker/ch32v20x.ld ================================================ /* Define default values if not already defined */ __flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 64K; __ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 20K; __stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size } ENTRY( _start ) PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } ================================================ FILE: hw/bsp/ch32v20x/system_ch32v20x.c ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v20x.c * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : CH32V20x Device Peripheral Access Layer System Source File. * For HSE = 32Mhz (CH32V208x/CH32V203RBT6) * For HSE = 8Mhz (other CH32V203x) ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #include "ch32v20x.h" /* * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after * reset the HSI is used as SYSCLK source). * If none of the define below is enabled, the HSI is used as System clock source. */ //#define SYSCLK_FREQ_HSE HSE_VALUE // #define SYSCLK_FREQ_48MHz_HSE 48000000 //#define SYSCLK_FREQ_56MHz_HSE 56000000 // #define SYSCLK_FREQ_72MHz_HSE 72000000 // #define SYSCLK_FREQ_96MHz_HSE 96000000 //#define SYSCLK_FREQ_120MHz_HSE 120000000 //#define SYSCLK_FREQ_144MHz_HSE 144000000 //#define SYSCLK_FREQ_HSI HSI_VALUE //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 //#define SYSCLK_FREQ_72MHz_HSI 72000000 //#define SYSCLK_FREQ_96MHz_HSI 96000000 //#define SYSCLK_FREQ_120MHz_HSI 120000000 //#define SYSCLK_FREQ_144MHz_HSI 144000000 /* Clock Definitions */ #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_96MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_120MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_144MHz_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_96MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_120MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_144MHz_HSI uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */ #else uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ #endif __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /* system_private_function_proto_types */ static void SetSysClock(void); #ifdef SYSCLK_FREQ_HSE static void SetSysClockToHSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSE static void SetSysClockTo48_HSE( void ); #elif defined SYSCLK_FREQ_56MHz_HSE static void SetSysClockTo56_HSE( void ); #elif defined SYSCLK_FREQ_72MHz_HSE static void SetSysClockTo72_HSE( void ); #elif defined SYSCLK_FREQ_96MHz_HSE static void SetSysClockTo96_HSE( void ); #elif defined SYSCLK_FREQ_120MHz_HSE static void SetSysClockTo120_HSE( void ); #elif defined SYSCLK_FREQ_144MHz_HSE static void SetSysClockTo144_HSE( void ); #elif defined SYSCLK_FREQ_48MHz_HSI static void SetSysClockTo48_HSI( void ); #elif defined SYSCLK_FREQ_56MHz_HSI static void SetSysClockTo56_HSI( void ); #elif defined SYSCLK_FREQ_72MHz_HSI static void SetSysClockTo72_HSI( void ); #elif defined SYSCLK_FREQ_96MHz_HSI static void SetSysClockTo96_HSI( void ); #elif defined SYSCLK_FREQ_120MHz_HSI static void SetSysClockTo120_HSI( void ); #elif defined SYSCLK_FREQ_144MHz_HSI static void SetSysClockTo144_HSI( void ); #endif /********************************************************************* * @fn SystemInit * * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, * the PLL and update the SystemCoreClock variable. * * @return none */ void SystemInit (void) { // Enable Flash enhance read mode for full 224KB #if defined(CH32_FLASH_ENHANCE_READ_MODE) && CH32_FLASH_ENHANCE_READ_MODE == 1 FLASH->KEYR = 0x45670123; // FLASH_Unlock_Fast(); FLASH->KEYR = 0xCDEF89AB; FLASH->CTLR |= (1 << 24); // Enhanced Read Mode FLASH->CTLR |= (1 << 15); // FLASH_Lock_Fast(); #endif RCC->CTLR |= (uint32_t)0x00000001; RCC->CFGR0 &= (uint32_t)0xF8FF0000; RCC->CTLR &= (uint32_t)0xFEF6FFFF; RCC->CTLR &= (uint32_t)0xFFFBFFFF; RCC->CFGR0 &= (uint32_t)0xFF80FFFF; RCC->INTR = 0x009F0000; SetSysClock(); } /********************************************************************* * @fn SystemCoreClockUpdate * * @brief Update SystemCoreClock variable according to Clock Register Values. * * @return none */ void SystemCoreClockUpdate (void) { uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0; tmp = RCC->CFGR0 & RCC_SWS; switch (tmp) { case 0x00: SystemCoreClock = HSI_VALUE; break; case 0x04: SystemCoreClock = HSE_VALUE; break; case 0x08: pllmull = RCC->CFGR0 & RCC_PLLMULL; pllsource = RCC->CFGR0 & RCC_PLLSRC; pllmull = ( pllmull >> 18) + 2; if(pllmull == 17) pllmull = 18; if (pllsource == 0x00) { if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){ SystemCoreClock = HSI_VALUE * pllmull; } else{ SystemCoreClock = (HSI_VALUE >> 1) * pllmull; } } else { #if defined (CH32V20x_D8W) if((RCC->CFGR0 & (3<<22)) == (3<<22)) { SystemCoreClock = ((HSE_VALUE>>1)) * pllmull; } else #endif if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) { #if defined (CH32V20x_D8) || defined (CH32V20x_D8W) SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull; #else SystemCoreClock = (HSE_VALUE >> 1) * pllmull; #endif } else { #if defined (CH32V20x_D8) || defined (CH32V20x_D8W) SystemCoreClock = (HSE_VALUE>>2) * pllmull; #else SystemCoreClock = HSE_VALUE * pllmull; #endif } } if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2); break; default: SystemCoreClock = HSI_VALUE; break; } tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; SystemCoreClock >>= tmp; } /********************************************************************* * @fn SetSysClock * * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_48MHz_HSE SetSysClockTo48_HSE(); #elif defined SYSCLK_FREQ_56MHz_HSE SetSysClockTo56_HSE(); #elif defined SYSCLK_FREQ_72MHz_HSE SetSysClockTo72_HSE(); #elif defined SYSCLK_FREQ_96MHz_HSE SetSysClockTo96_HSE(); #elif defined SYSCLK_FREQ_120MHz_HSE SetSysClockTo120_HSE(); #elif defined SYSCLK_FREQ_144MHz_HSE SetSysClockTo144_HSE(); #elif defined SYSCLK_FREQ_48MHz_HSI SetSysClockTo48_HSI(); #elif defined SYSCLK_FREQ_56MHz_HSI SetSysClockTo56_HSI(); #elif defined SYSCLK_FREQ_72MHz_HSI SetSysClockTo72_HSI(); #elif defined SYSCLK_FREQ_96MHz_HSI SetSysClockTo96_HSI(); #elif defined SYSCLK_FREQ_120MHz_HSI SetSysClockTo120_HSI(); #elif defined SYSCLK_FREQ_144MHz_HSI SetSysClockTo144_HSI(); #endif /* If none of the define above is enabled, the HSI is used as System clock * source (default after reset) */ } #ifdef SYSCLK_FREQ_HSE /********************************************************************* * @fn SetSysClockToHSE * * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockToHSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; /* Select HSE as system clock source * CH32V20x_D6 (HSE=8MHZ) * CH32V20x_D8 (HSE=32MHZ) * CH32V20x_D8W (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; /* Wait till HSE is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) { } } else { /* If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSE /********************************************************************* * @fn SetSysClockTo48_HSE * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_56MHz_HSE /********************************************************************* * @fn SetSysClockTo56_HSE * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_72MHz_HSE /********************************************************************* * @fn SetSysClockTo72_HSE * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_96MHz_HSE /********************************************************************* * @fn SetSysClockTo96_HSE * * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo96_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_120MHz_HSE /********************************************************************* * @fn SetSysClockTo120_HSE * * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo120_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if(HSEStatus == (uint32_t)0x01) { #if defined (CH32V20x_D8W) RCC->CFGR0 |= (uint32_t)(3<<22); /* HCLK = SYSCLK/2 */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; #else /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; #endif /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_144MHz_HSE /********************************************************************* * @fn SetSysClockTo144_HSE * * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo144_HSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ) * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz_HSI /********************************************************************* * @fn SetSysClockTo48_HSI * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_56MHz_HSI /********************************************************************* * @fn SetSysClockTo56_HSI * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_72MHz_HSI /********************************************************************* * @fn SetSysClockTo72_HSI * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_96MHz_HSI /********************************************************************* * @fn SetSysClockTo96_HSI * * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo96_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_120MHz_HSI /********************************************************************* * @fn SetSysClockTo120_HSI * * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo120_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #elif defined SYSCLK_FREQ_144MHz_HSI /********************************************************************* * @fn SetSysClockTo144_HSI * * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo144_HSI(void) { EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18); /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } #endif ================================================ FILE: hw/bsp/ch32v20x/system_ch32v20x.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v20x.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : CH32V20x Device Peripheral Access Layer System Header File. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef __SYSTEM_ch32v20x_H #define __SYSTEM_ch32v20x_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ /* System_Exported_Functions */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); #ifdef __cplusplus } #endif #endif /*__CH32V20x_SYSTEM_H */ ================================================ FILE: hw/bsp/ch32v20x/wch-riscv.cfg ================================================ adapter driver wlinke adapter speed 6000 transport select sdi wlink_set_address 0x00000000 set _CHIPNAME wch_riscv sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME $_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 echo "Ready for Remote Connections" ================================================ FILE: hw/bsp/ch32v30x/boards/ch32v307v_r1_1v0/board.cmake ================================================ set(LD_FLASH_SIZE 256K) set(LD_RAM_SIZE 64K) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/ch32v30x/boards/ch32v307v_r1_1v0/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries * * 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. */ /* metadata: name: CH32V307V-R1-1v0 url: https://github.com/openwch/ch32v307/tree/main/SCHPCB/CH32V307V-R1-1v0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED: need to wire pin LED1 to PC0 in the J3 header #define LED_PORT GPIOC #define LED_PIN GPIO_Pin_0 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE) // Button: need to wire pin KEY to PC1 in the J3 header #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_Pin_1 #define BUTTON_STATE_ACTIVE 0 #define BUTTON_CLOCK_EN() do { } while(0) // same as LED clock, no need to do anything // TODO UART port #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v30x/boards/ch32v307v_r1_1v0/board.mk ================================================ LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=256K \ -Wl,--defsym=__RAM_SIZE=64K \ ================================================ FILE: hw/bsp/ch32v30x/boards/nanoch32v305/board.cmake ================================================ set(LD_FLASH_SIZE 128K) set(LD_RAM_SIZE 32K) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/ch32v30x/boards/nanoch32v305/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries * * 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. */ /* metadata: name: nanoCH32V305 url: https://github.com/wuxx/nanoCH32V305 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_3 #define LED_STATE_ON 0 #define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) // TODO UART port #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ch32v30x/boards/nanoch32v305/board.mk ================================================ LDFLAGS += \ -Wl,--defsym=__FLASH_SIZE=128K \ -Wl,--defsym=__RAM_SIZE=32K \ ================================================ FILE: hw/bsp/ch32v30x/ch32v30x_conf.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v30x_conf.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : Library configuration file. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ #ifndef __CH32V30x_CONF_H #define __CH32V30x_CONF_H #include "ch32v30x_adc.h" #include "ch32v30x_bkp.h" #include "ch32v30x_can.h" #include "ch32v30x_crc.h" #include "ch32v30x_dac.h" #include "ch32v30x_dbgmcu.h" #include "ch32v30x_dma.h" #include "ch32v30x_exti.h" #include "ch32v30x_flash.h" #include "ch32v30x_fsmc.h" #include "ch32v30x_gpio.h" #include "ch32v30x_i2c.h" #include "ch32v30x_iwdg.h" #include "ch32v30x_pwr.h" #include "ch32v30x_rcc.h" #include "ch32v30x_rtc.h" #include "ch32v30x_sdio.h" #include "ch32v30x_spi.h" #include "ch32v30x_tim.h" #include "ch32v30x_usart.h" #include "ch32v30x_wwdg.h" #include "ch32v30x_it.h" #include "ch32v30x_misc.h" #endif /* __CH32V30x_CONF_H */ ================================================ FILE: hw/bsp/ch32v30x/ch32v30x_it.c ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v30x_it.c * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : Main Interrupt Service Routines. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ #include "ch32v30x_it.h" void NMI_Handler(void) __attribute__((naked)); void HardFault_Handler(void) __attribute__((naked)); /********************************************************************* * @fn NMI_Handler * * @brief This function handles NMI exception. * * @return none */ void NMI_Handle(void){ __asm volatile ("call NMI_Handler_impl; mret"); } __attribute__((used)) void NMI_Handler_impl(void) { } /********************************************************************* * @fn HardFault_Handler * * @brief This function handles Hard Fault exception. * * @return none */ void HardFault_Handler(void){ __asm volatile ("call HardFault_Handler_impl; mret"); } __attribute__((used)) void HardFault_Handler_impl(void) { while (1) { } } ================================================ FILE: hw/bsp/ch32v30x/ch32v30x_it.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : ch32v30x_it.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : This file contains the headers of the interrupt handlers. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ #ifndef __CH32V30x_IT_H #define __CH32V30x_IT_H #ifdef __cplusplus extern "C" { #endif #include "ch32v30x.h" void USBHS_IRQHandler(void); void OTG_FS_IRQHandler(void); void SysTick_Handler(void); #ifdef __cplusplus } #endif #endif /* __CH32V30x_IT_H */ ================================================ FILE: hw/bsp/ch32v30x/debug_uart.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill * * 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. * * This file is part of the TinyUSB stack. */ #include "debug_uart.h" #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) static char tx_buf[UART_RINGBUFFER_SIZE_TX]; static unsigned int tx_produce; static volatile unsigned int tx_consume; void USART1_IRQHandler(void) __attribute__((naked)); void USART1_IRQHandler(void) { __asm volatile ("call USART1_IRQHandler_impl; mret"); } void USART1_IRQHandler_impl(void) __attribute__((used)) ; void USART1_IRQHandler_impl(void) { if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_TC); if(tx_consume != tx_produce) { USART_SendData(USART1, tx_buf[tx_consume]); tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; } } } void uart_write(char c) { unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; NVIC_DisableIRQ(USART1_IRQn); if((tx_consume != tx_produce) || (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)) { tx_buf[tx_produce] = c; tx_produce = tx_produce_next; } else { USART_SendData(USART1, c); } NVIC_EnableIRQ(USART1_IRQn); } void uart_sync(void) { while(tx_consume != tx_produce); } void usart_printf_init(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; tx_produce = 0; tx_consume = 0; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_TC, ENABLE); USART_Cmd(USART1, ENABLE); NVIC_InitTypeDef NVIC_InitStructure = { 0 }; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } ================================================ FILE: hw/bsp/ch32v30x/debug_uart.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill * * 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. * * This file is part of the TinyUSB stack. */ #include void uart_write(char c); void uart_sync(void); void usart_printf_init(uint32_t baudrate); ================================================ FILE: hw/bsp/ch32v30x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: WCH */ #include "stdio.h" // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "debug_uart.h" #include "ch32v30x.h" #include "ch32v30x_it.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ // TODO maybe having FS as port0, HS as port1 __attribute__((interrupt)) void USBHS_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBHS tud_int_handler(0); #endif } __attribute__((interrupt)) void OTG_FS_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ static uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); SysTick->CTLR = 0; SysTick->SR = 0; SysTick->CNT = 0; SysTick->CMP = ticks - 1; SysTick->CTLR = 0xF; return 0; } void board_init(void) { /* Disable interrupts during init */ __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #endif usart_printf_init(CFG_BOARD_UART_BAUDRATE); #ifdef CH32V30x_D8C // v305/v307: Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); #endif // Fullspeed USB uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; case 96000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div2; break; case 144000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div3; break; default: TU_ASSERT(0,); break; } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); GPIO_InitTypeDef GPIO_InitStructure = {0}; // LED LED_CLOCK_EN(); GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); // Button #ifdef BUTTON_PORT BUTTON_CLOCK_EN(); GPIO_InitStructure.GPIO_Pin = BUTTON_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BUTTON_PORT, &GPIO_InitStructure); #endif /* Enable interrupts globally */ __enable_irq(); board_delay(2); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; __attribute__((interrupt)) void SysTick_Handler(void) { SysTick->SR = 0; system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { #ifdef BUTTON_PORT return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); #else return false; #endif } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { int txsize = len; const char* bufc = (const char*) buf; while (txsize--) { uart_write(*bufc++); } uart_sync(); return len; } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char* file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/ch32v30x/family.cmake ================================================ include_guard() set(CH32_FAMILY ch32v30x) set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307) set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") # default to highspeed, used to select USBFS / USBHS driver if (NOT DEFINED SPEED) set(SPEED high) endif() #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch32v30x.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_SRC_DIR}/Core/core_riscv.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) if (SPEED STREQUAL high) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUD_WCH_USBIP_USBHS=1 # BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED ) else () target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUD_WCH_USBIP_USBFS=1 ) endif () update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -msmall-data-limit=8 -mno-save-restore -fmessage-length=0 -fsigned-char ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_CH32V307) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/wch/dcd_ch32_usbhs.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC -nostartfiles --specs=nosys.specs --specs=nano.specs -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_openocd_wch(${TARGET}) family_flash_wlink_rs(${TARGET}) endfunction() ================================================ FILE: hw/bsp/ch32v30x/family.mk ================================================ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- CH32_FAMILY = ch32v30x SDK_DIR = hw/mcu/wch/ch32v307 SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 # default to use high speed port, unless specified in board.mk or command line SPEED ?= high CFLAGS += \ -flto \ -msmall-data-limit=8 \ -mno-save-restore \ -fmessage-length=0 \ -fsigned-char \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ # https://github.com/openwch/ch32v307/pull/90 CFLAGS += -Wno-error=strict-prototypes ifeq ($(SPEED),high) $(info "Using USBHS driver for HighSpeed mode") CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 else $(info "Using USBFS driver for FullSpeed mode") CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ src/portable/wch/dcd_ch32_usbfs.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c SRC_S += \ $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_D8C.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc LD_FILE ?= $(FAMILY_PATH)/linker/ch32v30x.ld # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg flash: flash-openocd-wch ================================================ FILE: hw/bsp/ch32v30x/linker/ch32v30x.ld ================================================ /* Define default values if not already defined */ __flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 128K; __ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K; __stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size } ENTRY( _start ) PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.glue_7) *(.glue_7t) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); __freertos_irq_stack_top = .; } >RAM } ================================================ FILE: hw/bsp/ch32v30x/system_ch32v30x.c ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v30x.c * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : CH32V30x Device Peripheral Access Layer System Source File. * For HSE = 8Mhz * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * SPDX-License-Identifier: Apache-2.0 *********************************************************************************/ #include "ch32v30x.h" /* * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after * reset the HSI is used as SYSCLK source). * If none of the define below is enabled, the HSI is used as System clock source. */ // #define SYSCLK_FREQ_HSE HSE_VALUE /* #define SYSCLK_FREQ_24MHz 24000000 */ //#define SYSCLK_FREQ_48MHz 48000000 /* #define SYSCLK_FREQ_56MHz 56000000 */ //#define SYSCLK_FREQ_72MHz 72000000 //#define SYSCLK_FREQ_96MHz 96000000 //#define SYSCLK_FREQ_120MHz 120000000 #define SYSCLK_FREQ_144MHz 144000000 /* Clock Definitions */ #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_24MHz uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_48MHz uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_56MHz uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_72MHz uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_96MHz uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_120MHz uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz; /* System Clock Frequency (Core Clock) */ #elif defined SYSCLK_FREQ_144MHz uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz; /* System Clock Frequency (Core Clock) */ #else /* HSI Selected as System Clock source */ uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ #endif __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /* system_private_function_proto_types */ static void SetSysClock(void); #ifdef SYSCLK_FREQ_HSE static void SetSysClockToHSE(void); #elif defined SYSCLK_FREQ_24MHz static void SetSysClockTo24(void); #elif defined SYSCLK_FREQ_48MHz static void SetSysClockTo48(void); #elif defined SYSCLK_FREQ_56MHz static void SetSysClockTo56(void); #elif defined SYSCLK_FREQ_72MHz static void SetSysClockTo72(void); #elif defined SYSCLK_FREQ_96MHz static void SetSysClockTo96(void); #elif defined SYSCLK_FREQ_120MHz static void SetSysClockTo120(void); #elif defined SYSCLK_FREQ_144MHz static void SetSysClockTo144(void); #endif /********************************************************************* * @fn SystemInit * * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, * the PLL and update the SystemCoreClock variable. * * @return none */ void SystemInit (void) { RCC->CTLR |= (uint32_t)0x00000001; #ifdef CH32V30x_D8C RCC->CFGR0 &= (uint32_t)0xF8FF0000; #else RCC->CFGR0 &= (uint32_t)0xF0FF0000; #endif RCC->CTLR &= (uint32_t)0xFEF6FFFF; RCC->CTLR &= (uint32_t)0xFFFBFFFF; RCC->CFGR0 &= (uint32_t)0xFF80FFFF; #ifdef CH32V30x_D8C RCC->CTLR &= (uint32_t)0xEBFFFFFF; RCC->INTR = 0x00FF0000; RCC->CFGR2 = 0x00000000; #else RCC->INTR = 0x009F0000; #endif SetSysClock(); } /********************************************************************* * @fn SystemCoreClockUpdate * * @brief Update SystemCoreClock variable according to Clock Register Values. * * @return none */ void SystemCoreClockUpdate (void) { uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0; tmp = RCC->CFGR0 & RCC_SWS; switch (tmp) { case 0x00: SystemCoreClock = HSI_VALUE; break; case 0x04: SystemCoreClock = HSE_VALUE; break; case 0x08: pllmull = RCC->CFGR0 & RCC_PLLMULL; pllsource = RCC->CFGR0 & RCC_PLLSRC; pllmull = ( pllmull >> 18) + 2; #ifdef CH32V30x_D8 if(pllmull == 17) pllmull = 18; #else if(pllmull == 2) pllmull = 18; if(pllmull == 15){ pllmull = 13; /* *6.5 */ Pll_6_5 = 1; } if(pllmull == 16) pllmull = 15; if(pllmull == 17) pllmull = 16; #endif if (pllsource == 0x00) { SystemCoreClock = (HSI_VALUE >> 1) * pllmull; } else { if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) { SystemCoreClock = (HSE_VALUE >> 1) * pllmull; } else { SystemCoreClock = HSE_VALUE * pllmull; } } if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2); break; default: SystemCoreClock = HSI_VALUE; break; } tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; SystemCoreClock >>= tmp; } /********************************************************************* * @fn SetSysClock * * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); #elif defined SYSCLK_FREQ_96MHz SetSysClockTo96(); #elif defined SYSCLK_FREQ_120MHz SetSysClockTo120(); #elif defined SYSCLK_FREQ_144MHz SetSysClockTo144(); #endif /* If none of the define above is enabled, the HSI is used as System clock * source (default after reset) */ } #ifdef SYSCLK_FREQ_HSE /********************************************************************* * @fn SetSysClockToHSE * * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockToHSE(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; /* Select HSE as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; /* Wait till HSE is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) { } } else { /* If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_24MHz /********************************************************************* * @fn SetSysClockTo24 * * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo24(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_48MHz /********************************************************************* * @fn SetSysClockTo48 * * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo48(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_56MHz /********************************************************************* * @fn SetSysClockTo56 * * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo56(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_72MHz /********************************************************************* * @fn SetSysClockTo72 * * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_96MHz /********************************************************************* * @fn SetSysClockTo96 * * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo96(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 12 = 96 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_120MHz /********************************************************************* * @fn SetSysClockTo120 * * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo120(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 15 = 120 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #elif defined SYSCLK_FREQ_144MHz /********************************************************************* * @fn SetSysClockTo144 * * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. * * @return none */ static void SetSysClockTo144(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; RCC->CTLR |= ((uint32_t)RCC_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CTLR & RCC_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CTLR & RCC_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* HCLK = SYSCLK */ RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; /* PLL configuration: PLLCLK = HSE * 18 = 144 MHz */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); #ifdef CH32V30x_D8 RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18); #else RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN); #endif /* Enable PLL */ RCC->CTLR |= RCC_PLLON; /* Wait till PLL is ready */ while((RCC->CTLR & RCC_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) { } } else { /* * If HSE fails to start-up, the application will have wrong clock * configuration. User can add here some code to deal with this error */ } } #endif ================================================ FILE: hw/bsp/ch32v30x/system_ch32v30x.h ================================================ /********************************** (C) COPYRIGHT ******************************* * File Name : system_ch32v30x.h * Author : WCH * Version : V1.0.0 * Date : 2021/06/06 * Description : CH32V30x Device Peripheral Access Layer System Header File. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * SPDX-License-Identifier: Apache-2.0 *******************************************************************************/ #ifndef __SYSTEM_CH32V30x_H #define __SYSTEM_CH32V30x_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ /* System_Exported_Functions */ extern void SystemInit(void); extern void SystemCoreClockUpdate(void); #ifdef __cplusplus } #endif #endif /*__CH32V30x_SYSTEM_H */ ================================================ FILE: hw/bsp/ch32v30x/wch-riscv.cfg ================================================ adapter driver wlinke adapter speed 6000 transport select sdi wlink_set_address 0x00000000 set _CHIPNAME wch_riscv sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME $_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 echo "Ready for Remote Connections" ================================================ FILE: hw/bsp/cxd56/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "nuttx/config.h" #endif /* Cortex-M4F port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // CXD56 (Cortex-M4F) has 3 priority bits #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< #define LED_PIN PIN_I2S1_BCK #define BUTTON_PIN PIN_HIF_IRQ_OUT #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/cxd56/boards/spresense/board.mk ================================================ # Spresense board configuration SERIAL ?= /dev/ttyUSB0 # flash flash: $(BUILD)/$(PROJECT).spk @echo FLASH $< @$(PYTHON) $(TOP)/hw/mcu/sony/cxd56/tools/flash_writer.py -s -c $(SERIAL) -d -b 115200 -n $< ================================================ FILE: hw/bsp/cxd56/family.c ================================================ /* * The MIT License (MIT) * * Copyright 2019 Sony Semiconductor Solutions Corporation * * 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. * * This file is part of the TinyUSB stack. */ #include #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" // Initialize on-board peripherals : led, button, uart and USB void board_init(void) { boardctl(BOARDIOC_INIT, 0); board_gpio_write(PIN_I2S1_BCK, -1); board_gpio_config(PIN_I2S1_BCK, 0, false, true, PIN_FLOAT); board_gpio_write(PIN_HIF_IRQ_OUT, -1); board_gpio_config(PIN_HIF_IRQ_OUT, 0, true, true, PIN_FLOAT); }; void board_late_initialize(void) { } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ // Turn LED on or off void board_led_write(bool state) { board_gpio_write(LED_PIN, state); } // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void) { if (board_gpio_read(BUTTON_PIN)) { return 0; } return 1; } // Get characters from UART int board_uart_read(uint8_t *buf, int len) { int r = read(0, buf, len); return r; } // Send characters to UART int board_uart_write(void const *buf, int len) { int r = write(1, buf, len); return r; } // Get current milliseconds uint32_t tusb_time_millis_api(void) { struct timespec tp; /* Wait until RTC is available */ while (g_rtc_enabled == false); if (clock_gettime(CLOCK_MONOTONIC, &tp)) { return 0; } return (((uint64_t)tp.tv_sec) * 1000 + tp.tv_nsec / 1000000); } ================================================ FILE: hw/bsp/cxd56/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/sony/cxd56/spresense-exported-sdk) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS CXD56 CACHE INTERNAL "") # Detect platform for mkspk tool if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") set(MKSPK ${TOP}/hw/mcu/sony/cxd56/mkspk/mkspk) elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(MKSPK ${TOP}/hw/mcu/sony/cxd56/mkspk/mkspk) else() set(MKSPK ${TOP}/hw/mcu/sony/cxd56/mkspk/mkspk.exe) endif() #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_GNU ${SDK_DIR}/nuttx/scripts/ramconfig.ld) set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # BOARD Target #------------------------------------ function(family_add_board BOARD_TARGET) # Spresense uses NuttX libraries add_library(${BOARD_TARGET} INTERFACE) target_include_directories(${BOARD_TARGET} INTERFACE ${SDK_DIR}/nuttx/include ${SDK_DIR}/nuttx/arch ${SDK_DIR}/nuttx/arch/chip ${SDK_DIR}/nuttx/arch/os ${SDK_DIR}/sdk/include ) target_compile_definitions(${BOARD_TARGET} INTERFACE CONFIG_HAVE_DOUBLE main=spresense_main ) target_compile_options(${BOARD_TARGET} INTERFACE -pipe -std=gnu11 -fno-builtin -fno-strength-reduce -fomit-frame-pointer -Wno-error=undef -Wno-error=cast-align -Wno-error=unused-parameter -Wno-error=shadow -Wno-error=redundant-decls ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_CXD56) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/sony/cxd56/dcd_cxd56.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) target_link_libraries(${TARGET} PUBLIC ${SDK_DIR}/nuttx/libs/libapps.a ${SDK_DIR}/nuttx/libs/libnuttx.a gcc # Compiler runtime support for FP operations like __aeabi_dmul ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -Xlinker --entry=__start -nostartfiles -nodefaultlibs -Wl,--gc-sections -u spresense_main --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" -Xlinker --entry=__start -nostartfiles -nodefaultlibs -u spresense_main ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Build mkspk tool add_custom_command(OUTPUT ${MKSPK} COMMAND $(MAKE) -C ${TOP}/hw/mcu/sony/cxd56/mkspk COMMENT "Building mkspk tool" ) # Create .spk file add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.spk COMMAND ${MKSPK} -c 2 $ nuttx ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.spk DEPENDS ${TARGET} ${MKSPK} COMMENT "Creating ${TARGET}.spk" ) endfunction() ================================================ FILE: hw/bsp/cxd56/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk # Platforms are: Linux, Darwin, MSYS, CYGWIN PLATFORM := $(firstword $(subst _, ,$(shell uname -s 2>/dev/null))) ifeq ($(PLATFORM),Darwin) # macOS MKSPK = $(TOP)/hw/mcu/sony/cxd56/mkspk/mkspk else ifeq ($(PLATFORM),Linux) # Linux MKSPK = $(TOP)/hw/mcu/sony/cxd56/mkspk/mkspk else # Cygwin/MSYS2 MKSPK = $(TOP)/hw/mcu/sony/cxd56/mkspk/mkspk.exe endif CFLAGS += \ -DCONFIG_HAVE_DOUBLE \ -Dmain=spresense_main \ -pipe \ -std=gnu11 \ -fno-strength-reduce \ -fomit-frame-pointer \ -Wno-error=undef \ -Wno-error=cast-align \ -Wno-error=unused-parameter \ -DCFG_TUSB_MCU=OPT_MCU_CXD56 \ CPU_CORE ?= cortex-m4 # suppress following warnings from mcu driver # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration CFLAGS += -Wno-error=shadow -Wno-error=redundant-decls LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SPRESENSE_SDK = $(TOP)/hw/mcu/sony/cxd56/spresense-exported-sdk SRC_C += src/portable/sony/cxd56/dcd_cxd56.c INC += \ $(SPRESENSE_SDK)/nuttx/include \ $(SPRESENSE_SDK)/nuttx/arch \ $(SPRESENSE_SDK)/nuttx/arch/chip \ $(SPRESENSE_SDK)/nuttx/arch/os \ $(SPRESENSE_SDK)/sdk/include \ $(TOP)/$(BOARD_PATH) LIBS += \ $(SPRESENSE_SDK)/nuttx/libs/libapps.a \ $(SPRESENSE_SDK)/nuttx/libs/libnuttx.a \ LD_FILE = hw/mcu/sony/cxd56/spresense-exported-sdk/nuttx/scripts/ramconfig.ld LDFLAGS += \ -Xlinker --entry=__start \ -nostartfiles \ -nodefaultlibs \ -Wl,--gc-sections \ -u spresense_main $(MKSPK): $(BUILD)/$(PROJECT).elf $(MAKE) -C $(TOP)/hw/mcu/sony/cxd56/mkspk $(BUILD)/$(PROJECT).spk: $(MKSPK) @echo CREATE $@ @$(MKSPK) -c 2 $(BUILD)/$(PROJECT).elf nuttx $@ # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F ================================================ FILE: hw/bsp/da1469x/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "DA1469xAB.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< #include #define LED_STATE_OFF (1-LED_STATE_ON) //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } // DA146xx driver function that must be called whenever VBUS changes. extern void tusb_vbus_changed(bool present); #if defined(NEED_VBUS_MONITOR) && CFG_TUD_ENABLED // VBUS change interrupt handler void VBUS_IRQHandler(void) { bool present = (CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0; // Clear VBUS interrupt CRG_TOP->VBUS_IRQ_CLEAR_REG = 1; tusb_vbus_changed(present); } #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ void UnhandledIRQ(void) { CRG_TOP->SYS_CTRL_REG = 0x80; __BKPT(1); while (1); } void board_init(void) { // LED hal_gpio_init_out(LED_PIN, LED_STATE_ON); hal_gpio_init_out(1, 0); hal_gpio_init_out(2, 0); hal_gpio_init_out(3, 0); hal_gpio_init_out(4, 0); hal_gpio_init_out(5, 0); // Button hal_gpio_init_in(BUTTON_PIN, BUTTON_STATE_ACTIVE ? HAL_GPIO_PULL_DOWN : HAL_GPIO_PULL_UP); // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #if CFG_TUD_ENABLED #ifdef NEED_VBUS_MONITOR // Setup interrupt for both connect and disconnect CRG_TOP->VBUS_IRQ_MASK_REG = CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk | CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk; NVIC_SetPriority(VBUS_IRQn, 2); // Trigger interrupt at the start to inform driver about VBUS state at start // otherwise it could go unnoticed. NVIC_SetPendingIRQ(VBUS_IRQn); NVIC_EnableIRQ(VBUS_IRQn); #else // This board is USB powered there is no need to monitor VBUS line. Notify driver that VBUS is present. tusb_vbus_changed(true); #endif /* Setup USB IRQ */ NVIC_SetPriority(USB_IRQn, 2); NVIC_EnableIRQ(USB_IRQn); /* Use PLL96 / 2 clock not HCLK */ CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk; mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { hal_gpio_write(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == hal_gpio_read(BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/da1469x/family.cmake ================================================ include_guard() set(MCU_DIR ${TOP}/hw/mcu/dialog/da1469x) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(CMAKE_SYSTEM_CPU cortex-m33-nodsp CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS DA1469X CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/da1469x.ld) endif () if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) set(STARTUP_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/gcc_startup_da1469x.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${MCU_DIR}/src/system_da1469x.c ${MCU_DIR}/src/da1469x_clock.c ${MCU_DIR}/src/hal_gpio.c ) target_compile_options(${BOARD_TARGET} PUBLIC -mthumb-interwork) target_compile_definitions(${BOARD_TARGET} PUBLIC CORE_M33 CFG_TUD_ENDPOINT0_SIZE=8 ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${MCU_DIR}/include ${MCU_DIR}/SDK_10.0.8.105/sdk/bsp/include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_flash_jlink_dialog TARGET) set(JLINKEXE JLinkExe) set(JLINK_IF swd) # mkimage from sdk set(MKIMAGE $ENV{HOME}/code/tinyusb-mcu-driver/dialog/SDK_10.0.8.105/binaries/mkimage) file(GENERATE OUTPUT $/version.h CONTENT "#define SW_VERSION \"v_1.0.0.1\" #define SW_VERSION_DATE \"2024-07-17 17:55\"" ) file(GENERATE OUTPUT $/${TARGET}.jlink CONTENT "r halt loadfile $/${TARGET}-image.bin 0x16000000 r go exit" ) add_custom_target(${TARGET}-image DEPENDS ${TARGET} COMMAND ${MKIMAGE} da1469x $/${TARGET}.bin $/version.h $/${TARGET}.bin.img COMMAND cp ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/product_header.dump $/${TARGET}-image.bin COMMAND cat $/${TARGET}.bin.img >> $/${TARGET}-image.bin ) add_custom_target(${TARGET}-jlink DEPENDS ${TARGET}-image COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink ) endfunction() function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_DA1469X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/dialog/da146xx/dcd_da146xx.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink_dialog(${TARGET}) endfunction() ================================================ FILE: hw/bsp/da1469x/family.mk ================================================ MCU_DIR = hw/mcu/dialog/da1469x include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -mthumb \ -mthumb-interwork \ -mabi=aapcs \ -mcpu=cortex-m33+nodsp \ -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 \ -DCORE_M33 \ -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ -DCFG_TUD_ENDPOINT0_SIZE=8\ LDFLAGS_GCC += \ -nostdlib \ --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. LD_FILE = $(FAMILY_PATH)/linker/da1469x.ld # While this is for da1469x chip, there is chance that da1468x chip family will also work SRC_C += \ src/portable/dialog/da146xx/dcd_da146xx.c \ ${MCU_DIR}/src/system_da1469x.c \ ${MCU_DIR}/src/da1469x_clock.c \ ${MCU_DIR}/src/hal_gpio.c \ SRC_S += $(FAMILY_PATH)/gcc_startup_da1469x.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/${MCU_DIR}/include \ $(TOP)/${MCU_DIR}/SDK_10.0.8.105/sdk/bsp/include # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure # flash using jlink but with some twists flash: flash-dialog # SDK_BINARY_PATH is the path to the SDK binary files SDK_BINARY_PATH = $(HOME)/code/tinyusb-mcu-driver/dialog/SDK_10.0.8.105/binaries MKIMAGE = $(SDK_BINARY_PATH)/mkimage $(BUILD)/$(PROJECT)-image.bin: $(BUILD)/$(PROJECT).bin @echo '#define SW_VERSION "v_1.0.0.1"' >$(BUILD)/version.h @echo '#define SW_VERSION_DATE "'`date +"%Y-%m-%d %H:%M"`'"' >> $(BUILD)/version.h $(MKIMAGE) da1469x $^ $(BUILD)/version.h $^.img cp $(TOP)/$(FAMILY_PATH)/product_header.dump $(BUILD)/$(PROJECT)-image.bin cat $^.img >> $(BUILD)/$(PROJECT)-image.bin flash-dialog: $(BUILD)/$(PROJECT)-image.bin @echo r > $(BUILD)/$(BOARD).jlink @echo halt >> $(BUILD)/$(BOARD).jlink @echo loadfile $^ 0x16000000 >> $(BUILD)/$(BOARD).jlink @echo r >> $(BUILD)/$(BOARD).jlink @echo go >> $(BUILD)/$(BOARD).jlink @echo exit >> $(BUILD)/$(BOARD).jlink $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink ================================================ FILE: hw/bsp/da1469x/gcc_startup_da1469x.S ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "syscfg/syscfg.h" .syntax unified .arch armv7-m .section .stack .align 3 #ifdef __STACK_SIZE .equ Stack_Size, __STACK_SIZE #else .equ Stack_Size, 0xC00 #endif .equ SYS_CTRL_REG, 0x50000024 .equ CACHE_FLASH_REG, 0x100C0040 .equ RESET_STAT_REG, 0x500000BC .globl __StackTop .globl __StackLimit __StackLimit: .space Stack_Size .size __StackLimit, . - __StackLimit __StackTop: .size __StackTop, . - __StackTop .section .heap .align 3 #ifdef __HEAP_SIZE .equ Heap_Size, __HEAP_SIZE #else .equ Heap_Size, 0 #endif .globl __HeapBase .globl __HeapLimit __HeapBase: .if Heap_Size .space Heap_Size .endif .size __HeapBase, . - __HeapBase __HeapLimit: .size __HeapLimit, . - __HeapLimit .section .isr_vector .align 2 .globl __isr_vector __isr_vector: .long __StackTop .long Reset_Handler /* Cortex-M33 interrupts */ .long NMI_Handler .long HardFault_Handler .long MemoryManagement_Handler .long BusFault_Handler .long UsageFault_Handler .long SecureFault_Handler .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long SVC_Handler .long DebugMonitor_Handler .long 0 /* Reserved */ .long PendSV_Handler .long SysTick_Handler /* DA1469x interrupts */ .long SENSOR_NODE_IRQHandler .long DMA_IRQHandler .long CHARGER_STATE_IRQHandler .long CHARGER_ERROR_IRQHandler .long CMAC2SYS_IRQHandler .long UART_IRQHandler .long UART2_IRQHandler .long UART3_IRQHandler .long I2C_IRQHandler .long I2C2_IRQHandler .long SPI_IRQHandler .long SPI2_IRQHandler .long PCM_IRQHandler .long SRC_IN_IRQHandler .long SRC_OUT_IRQHandler .long USB_IRQHandler .long TIMER_IRQHandler .long TIMER2_IRQHandler .long RTC_IRQHandler .long KEY_WKUP_GPIO_IRQHandler .long PDC_IRQHandler .long VBUS_IRQHandler .long MRM_IRQHandler .long MOTOR_CONTROLLER_IRQHandler .long TRNG_IRQHandler .long DCDC_IRQHandler .long XTAL32M_RDY_IRQHandler .long ADC_IRQHandler .long ADC2_IRQHandler .long CRYPTO_IRQHandler .long CAPTIMER1_IRQHandler .long RFDIAG_IRQHandler .long LCD_CONTROLLER_IRQHandler .long PLL_LOCK_IRQHandler .long TIMER3_IRQHandler .long TIMER4_IRQHandler .long LRA_IRQHandler .long RTC_EVENT_IRQHandler .long GPIO_P0_IRQHandler .long GPIO_P1_IRQHandler .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .size __isr_vector, . - __isr_vector .text .thumb .thumb_func .align 2 .globl Reset_Handler .type Reset_Handler, %function Reset_Handler: /* Make sure interrupt vector is remapped at 0x0 */ ldr r1, =SYS_CTRL_REG ldrh r2, [r1, #0] orrs r2, r2, #8 strh r2, [r1, #0] #if !MYNEWT_VAL(RAM_RESIDENT) /* * Flash is remapped at 0x0 with an offset, i.e. 0x0 does not correspond to * 0x16000000 but to start of an image on flash. This is calculated from product * header by 1st state bootloader and configured in CACHE_FLASH_REG. We need to * retrieve proper offset value for calculations later. */ ldr r1, =CACHE_FLASH_REG ldr r4, [r1, #0] mov r2, r4 mov r3, #0xFFFF bic r4, r4, r3 /* CACHE_FLASH_REG[FLASH_REGION_BASE] */ mov r3, #0xFFF0 and r2, r2, r3 /* CACHE_FLASH_REG[FLASH_REGION_OFFSET] */ lsr r2, r2, #2 orr r4, r4, r2 /* Copy ISR vector from flash to RAM */ ldr r1, =__isr_vector_start /* src ptr */ ldr r2, =__isr_vector_end /* src end */ ldr r3, =__intvect_start__ /* dst ptr */ /* Make sure we copy from QSPIC address range, not from remapped range */ cmp r1, r4 itt lt addlt r1, r1, r4 addlt r2, r2, r4 .loop_isr_copy: cmp r1, r2 ittt lt ldrlt r0, [r1], #4 strlt r0, [r3], #4 blt .loop_isr_copy /* Copy QSPI code from flash to RAM */ ldr r1, =__text_ram_addr /* src ptr */ ldr r2, =__text_ram_start__ /* ptr */ ldr r3, =__text_ram_end__ /* dst end */ .loop_code_text_ram_copy: cmp r2, r3 ittt lt ldrlt r0, [r1], #4 strlt r0, [r2], #4 blt .loop_code_text_ram_copy /* Copy data from flash to RAM */ ldr r1, =__etext /* src ptr */ ldr r2, =__data_start__ /* dst ptr */ ldr r3, =__data_end__ /* dst end */ .loop_data_copy: cmp r2, r3 ittt lt ldrlt r0, [r1], #4 strlt r0, [r2], #4 blt .loop_data_copy #endif /* Clear BSS */ movs r0, 0 ldr r1, =__bss_start__ ldr r2, =__bss_end__ .loop_bss_clear: cmp r1, r2 itt lt strlt r0, [r1], #4 blt .loop_bss_clear ldr r0, =__HeapBase ldr r1, =__HeapLimit /* Call static constructors */ bl __libc_init_array bl SystemInit bl main .pool .size Reset_Handler, . - Reset_Handler /* Default interrupt handler */ .type Default_Handler, %function Default_Handler: ldr r1, =SYS_CTRL_REG ldrh r2, [r1, #0] orrs r2, r2, #0x80 /* DEBUGGER_ENABLE */ strh r2, [r1, #0] b . .size Default_Handler, . - Default_Handler /* Default handlers for all interrupts */ .macro IRQ handler .weak \handler .set \handler, Default_Handler .endm /* Cortex-M33 interrupts */ IRQ NMI_Handler IRQ HardFault_Handler IRQ MemoryManagement_Handler IRQ BusFault_Handler IRQ UsageFault_Handler IRQ SecureFault_Handler IRQ SVC_Handler IRQ DebugMonitor_Handler IRQ PendSV_Handler IRQ SysTick_Handler /* DA1469x interrupts */ IRQ SENSOR_NODE_IRQHandler IRQ DMA_IRQHandler IRQ CHARGER_STATE_IRQHandler IRQ CHARGER_ERROR_IRQHandler IRQ CMAC2SYS_IRQHandler IRQ UART_IRQHandler IRQ UART2_IRQHandler IRQ UART3_IRQHandler IRQ I2C_IRQHandler IRQ I2C2_IRQHandler IRQ SPI_IRQHandler IRQ SPI2_IRQHandler IRQ PCM_IRQHandler IRQ SRC_IN_IRQHandler IRQ SRC_OUT_IRQHandler IRQ USB_IRQHandler IRQ TIMER_IRQHandler IRQ TIMER2_IRQHandler IRQ RTC_IRQHandler IRQ KEY_WKUP_GPIO_IRQHandler IRQ PDC_IRQHandler IRQ VBUS_IRQHandler IRQ MRM_IRQHandler IRQ MOTOR_CONTROLLER_IRQHandler IRQ TRNG_IRQHandler IRQ DCDC_IRQHandler IRQ XTAL32M_RDY_IRQHandler IRQ ADC_IRQHandler IRQ ADC2_IRQHandler IRQ CRYPTO_IRQHandler IRQ CAPTIMER1_IRQHandler IRQ RFDIAG_IRQHandler IRQ LCD_CONTROLLER_IRQHandler IRQ PLL_LOCK_IRQHandler IRQ TIMER3_IRQHandler IRQ TIMER4_IRQHandler IRQ LRA_IRQHandler IRQ RTC_EVENT_IRQHandler IRQ GPIO_P0_IRQHandler IRQ GPIO_P1_IRQHandler IRQ RESERVED40_IRQHandler IRQ RESERVED41_IRQHandler IRQ RESERVED42_IRQHandler IRQ RESERVED43_IRQHandler IRQ RESERVED44_IRQHandler IRQ RESERVED45_IRQHandler IRQ RESERVED46_IRQHandler IRQ RESERVED47_IRQHandler .end ================================================ FILE: hw/bsp/da1469x/linker/da1469x.ld ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ MEMORY { /* * Flash is remapped at 0x0 by 1st stage bootloader, but this is done with * an offset derived from image header thus it is safer to use remapped * address space at 0x0 instead of QSPI_M address space at 0x16000000. * Bootloader partition is 32K, but 9K is currently reserved for product * header (8K) and image header (1K). * First 512 bytes of SYSRAM are remapped at 0x0 and used as ISR vector * (there's no need to reallocate ISR vector) and thus cannot be used by * application. */ FLASH (r) : ORIGIN = (0x00000000), LENGTH = (1024 * 1024) RAM (rw) : ORIGIN = (0x20000000), LENGTH = (512 * 1024) } OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapBase * __HeapLimit * __StackLimit * __StackTop * __stack * __bssnz_start__ * __bssnz_end__ */ ENTRY(Reset_Handler) SECTIONS { __text = .; .text : { __isr_vector_start = .; KEEP(*(.isr_vector)) /* ISR vector shall have exactly 512 bytes */ . = __isr_vector_start + 0x200; __isr_vector_end = .; *(.text) *(.text.*) *(.libcmac.rom) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) *(.eh_frame*) . = ALIGN(4); } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } > FLASH __exidx_start = .; .ARM : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) . = ALIGN(4); } > FLASH __exidx_end = .; .intvect : { . = ALIGN(4); __intvect_start__ = .; . = . + (__isr_vector_end - __isr_vector_start); . = ALIGN(4); } > RAM .sleep_state (NOLOAD) : { . = ALIGN(4); *(sleep_state) } > RAM /* This section will be zeroed by RTT package init */ .rtt (NOLOAD): { . = ALIGN(4); *(.rtt) . = ALIGN(4); } > RAM __text_ram_addr = LOADADDR(.text_ram); .text_ram : { . = ALIGN(4); __text_ram_start__ = .; *(.text_ram*) . = ALIGN(4); __text_ram_end__ = .; } > RAM AT > FLASH __etext = LOADADDR(.data); .data : { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); *(.preinit_array) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); *(SORT(.init_array.*)) *(.init_array) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); *(SORT(.fini_array.*)) *(.fini_array) PROVIDE_HIDDEN (__fini_array_end = .); *(.jcr) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH .bssnz : { . = ALIGN(4); __bssnz_start__ = .; *(.bss.core.nz*) . = ALIGN(4); __bssnz_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .cmac (NOLOAD) : { . = ALIGN(0x400); *(.libcmac.ram) } > RAM /* Heap starts after BSS */ . = ALIGN(8); __HeapBase = .; /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > RAM _ram_start = ORIGIN(RAM); /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Top of head is the bottom of the stack */ __HeapLimit = __StackLimit; end = __HeapLimit; /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") /* Check that intvect is at the beginning of RAM */ ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") } ================================================ FILE: hw/bsp/efm32/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "em_device.h" #endif /* Cortex-M4F port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // EFM32GG12B has 3 priority bits #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<PWRCTRL = (immediate_switch ? EMU_PWRCTRL_IMMEDIATEPWRSWITCH : 0) | EMU_PWRCTRL_REGPWRSEL_DVDD | EMU_PWRCTRL_ANASW_AVDD; } static void emu_reg_init(float target_voltage) { if(target_voltage < 2300.f || target_voltage >= 3800.f) return; uint8_t level = ((target_voltage - 2300.f) / 100.f); EMU->R5VCTRL = EMU_R5VCTRL_INPUTMODE_AUTO; EMU->R5VOUTLEVEL = level; /* Reg output to 3.3V*/ } static void emu_dcdc_init(float target_voltage, float max_ln_current, float max_lp_current, float max_reverse_current) { if(target_voltage < 1800.f || target_voltage >= 3000.f) return; if(max_ln_current <= 0.f || max_ln_current > 200.f) return; if(max_lp_current <= 0.f || max_lp_current > 10000.f) return; if(max_reverse_current < 0.f || max_reverse_current > 160.f) return; // Low Power & Low Noise current limit uint8_t lp_bias = 0; if(max_lp_current < 75.f) lp_bias = 0; else if(max_lp_current < 500.f) lp_bias = 1; else if(max_lp_current < 2500.f) lp_bias = 2; else lp_bias = 3; EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~_EMU_DCDCMISCCTRL_LPCMPBIASEM234H_MASK) | ((uint32_t)lp_bias << _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT); EMU->DCDCMISCCTRL |= EMU_DCDCMISCCTRL_LNFORCECCM; // Force CCM to prevent reverse current EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN; // Enable duty cycling of the bias for LP mode EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK) | 4; // Set RCO Band to 7MHz uint8_t fet_count = 0; if(max_ln_current < 20.f) fet_count = 4; else if(max_ln_current >= 20.f && max_ln_current < 40.f) fet_count = 8; else fet_count = 16; EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~_EMU_DCDCMISCCTRL_NFETCNT_MASK) | ((uint32_t)(fet_count - 1) << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT); EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~_EMU_DCDCMISCCTRL_PFETCNT_MASK) | ((uint32_t)(fet_count - 1) << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT); uint8_t ln_current_limit = (((max_ln_current + 40.f) * 1.5f) / (5.f * fet_count)) - 1; uint8_t lp_current_limit = 1; // Recommended value EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK)) | ((uint32_t)ln_current_limit << _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT) | ((uint32_t)lp_current_limit << _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT); uint8_t z_det_limit = ((max_reverse_current + 40.f) * 1.5f) / (2.5f * fet_count); EMU->DCDCZDETCTRL = (EMU->DCDCZDETCTRL & ~_EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK) | ((uint32_t)z_det_limit << _EMU_DCDCZDETCTRL_ZDETILIMSEL_SHIFT); EMU->DCDCCLIMCTRL |= EMU_DCDCCLIMCTRL_BYPLIMEN; // Enable bypass current limiter to prevent overcurrent when switching modes // Output Voltage if(target_voltage > 1800.f) { float max_vout = 3000.f; float min_vout = 1800.f; float diff_vout = max_vout - min_vout; uint8_t ln_vref_high = (DEVINFO->DCDCLNVCTRL0 & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK) >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT; uint8_t ln_vref_low = (DEVINFO->DCDCLNVCTRL0 & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK) >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT; uint8_t ln_vref = ((target_voltage - min_vout) * (float)(ln_vref_high - ln_vref_low)) / diff_vout; ln_vref += ln_vref_low; EMU->DCDCLNVCTRL = (ln_vref << _EMU_DCDCLNVCTRL_LNVREF_SHIFT) | EMU_DCDCLNVCTRL_LNATT; uint8_t lp_vref_low = 0; uint8_t lp_vref_high = 0; switch(lp_bias) { case 0: { lp_vref_high = (DEVINFO->DCDCLPVCTRL2 & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK) >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL2 & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK) >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT; } break; case 1: { lp_vref_high = (DEVINFO->DCDCLPVCTRL2 & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK) >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL2 & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK) >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT; } break; case 2: { lp_vref_high = (DEVINFO->DCDCLPVCTRL3 & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK) >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL3 & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK) >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT; } break; case 3: { lp_vref_high = (DEVINFO->DCDCLPVCTRL3 & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK) >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL3 & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK) >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT; } break; } uint8_t lp_vref = ((target_voltage - min_vout) * (float)(lp_vref_high - lp_vref_low)) / diff_vout; lp_vref += lp_vref_low; EMU->DCDCLPVCTRL = (lp_vref << _EMU_DCDCLPVCTRL_LPVREF_SHIFT) | EMU_DCDCLPVCTRL_LPATT; } else { float max_vout = 1800.f; float min_vout = 1200.f; float diff_vout = max_vout - min_vout; uint8_t ln_vref_high = (DEVINFO->DCDCLNVCTRL0 & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK) >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT; uint8_t ln_vref_low = (DEVINFO->DCDCLNVCTRL0 & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK) >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT; uint8_t ln_vref = ((target_voltage - min_vout) * (float)(ln_vref_high - ln_vref_low)) / diff_vout; ln_vref += ln_vref_low; EMU->DCDCLNVCTRL = ln_vref << _EMU_DCDCLNVCTRL_LNVREF_SHIFT; uint8_t lp_vref_low = 0; uint8_t lp_vref_high = 0; switch(lp_bias) { case 0: { lp_vref_high = (DEVINFO->DCDCLPVCTRL0 & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK) >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL0 & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK) >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT; } break; case 1: { lp_vref_high = (DEVINFO->DCDCLPVCTRL0 & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK) >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL0 & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK) >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT; } break; case 2: { lp_vref_high = (DEVINFO->DCDCLPVCTRL1 & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK) >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL1 & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK) >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT; } break; case 3: { lp_vref_high = (DEVINFO->DCDCLPVCTRL1 & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK) >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT; lp_vref_low = (DEVINFO->DCDCLPVCTRL1 & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK) >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT; } break; } uint8_t lp_vref = ((target_voltage - min_vout) * (float)(lp_vref_high - lp_vref_low)) / diff_vout; lp_vref += lp_vref_low; EMU->DCDCLPVCTRL = lp_vref << _EMU_DCDCLPVCTRL_LPVREF_SHIFT; } EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK) | (((DEVINFO->DCDCLPCMPHYSSEL1 & (((uint32_t)0xFF) << (lp_bias * 8))) >> (lp_bias * 8)) << _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT); while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY); // Wait for configuration to write // Calibration //EMU->DCDCLNCOMPCTRL = 0x57204077; // Compensation for 1uF DCDC capacitor EMU->DCDCLNCOMPCTRL = 0xB7102137; // Compensation for 4.7uF DCDC capacitor // Enable DCDC converter EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODEEM4_EM4LOWPOWER | EMU_DCDCCTRL_DCDCMODEEM23_EM23LOWPOWER | EMU_DCDCCTRL_DCDCMODE_LOWNOISE; // Switch digital domain to DVDD EMU->PWRCTRL = EMU_PWRCTRL_REGPWRSEL_DVDD | EMU_PWRCTRL_ANASW_AVDD; } static void cmu_hfxo_startup_calib(uint16_t ib_trim, uint16_t c_tune) { if(CMU->STATUS & CMU_STATUS_HFXOENS) return; CMU->HFXOSTARTUPCTRL = (CMU->HFXOSTARTUPCTRL & ~(_CMU_HFXOSTARTUPCTRL_CTUNE_MASK | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK)) | (((uint32_t)c_tune << _CMU_HFXOSTARTUPCTRL_CTUNE_SHIFT) & _CMU_HFXOSTARTUPCTRL_CTUNE_MASK) | (((uint32_t)ib_trim << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT) & _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK); } static void cmu_hfxo_steady_calib(uint16_t ib_trim, uint16_t c_tune) { if(CMU->STATUS & CMU_STATUS_HFXOENS) return; CMU->HFXOSTEADYSTATECTRL = (CMU->HFXOSTEADYSTATECTRL & ~(_CMU_HFXOSTEADYSTATECTRL_CTUNE_MASK | _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_MASK)) | (((uint32_t)c_tune << _CMU_HFXOSTEADYSTATECTRL_CTUNE_SHIFT) & _CMU_HFXOSTEADYSTATECTRL_CTUNE_MASK) | (((uint32_t)ib_trim << _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_SHIFT) & _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_MASK); } static void cmu_hfrco_calib(uint32_t calibration) { if(CMU->STATUS & CMU_STATUS_DPLLENS) return; while(CMU->SYNCBUSY & CMU_SYNCBUSY_HFRCOBSY); CMU->HFRCOCTRL = calibration; while(CMU->SYNCBUSY & CMU_SYNCBUSY_HFRCOBSY); } static void cmu_ushfrco_calib(uint8_t enable, uint32_t calibration) { if(CMU->USBCRCTRL & CMU_USBCRCTRL_USBCREN) return; if(!enable) { CMU->OSCENCMD = CMU_OSCENCMD_USHFRCODIS; while(CMU->STATUS & CMU_STATUS_USHFRCOENS); return; } while(CMU->SYNCBUSY & CMU_SYNCBUSY_USHFRCOBSY); CMU->USHFRCOCTRL = calibration | CMU_USHFRCOCTRL_FINETUNINGEN; while(CMU->SYNCBUSY & CMU_SYNCBUSY_USHFRCOBSY); if(enable && !(CMU->STATUS & CMU_STATUS_USHFRCOENS)) { CMU->OSCENCMD = CMU_OSCENCMD_USHFRCOEN; while(!(CMU->STATUS & CMU_STATUS_USHFRCORDY)); } } static void cmu_auxhfrco_calib(uint8_t enable, uint32_t calibration) { if(!enable) { CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCODIS; while(CMU->STATUS & CMU_STATUS_AUXHFRCOENS); return; } while(CMU->SYNCBUSY & CMU_SYNCBUSY_AUXHFRCOBSY); CMU->AUXHFRCOCTRL = calibration; while(CMU->SYNCBUSY & CMU_SYNCBUSY_AUXHFRCOBSY); if(enable && !(CMU->STATUS & CMU_STATUS_AUXHFRCOENS)) { CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN; while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY)); } } static void cmu_init(void) { // Change SDIO clock to HFXO if HFRCO selected and disable it CMU->SDIOCTRL = CMU_SDIOCTRL_SDIOCLKDIS | CMU_SDIOCTRL_SDIOCLKSEL_HFXO; while(CMU->STATUS & CMU_STATUS_SDIOCLKENS); // Change QSPI clock to HFXO if HFRCO selected and disable it CMU->QSPICTRL = CMU_QSPICTRL_QSPI0CLKDIS | CMU_QSPICTRL_QSPI0CLKSEL_HFXO; while(CMU->STATUS & CMU_STATUS_QSPI0CLKENS); // Disable DPLL if enabled if(CMU->STATUS & CMU_STATUS_DPLLENS) { CMU->OSCENCMD = CMU_OSCENCMD_DPLLDIS; while(CMU->STATUS & CMU_STATUS_DPLLENS); } // Disable HFXO if enabled if(CMU->STATUS & CMU_STATUS_HFXOENS) { CMU->OSCENCMD = CMU_OSCENCMD_HFXODIS; while(CMU->STATUS & CMU_STATUS_HFXOENS); } // Setup HFXO CMU->HFXOCTRL = CMU_HFXOCTRL_PEAKDETMODE_AUTOCMD | CMU_HFXOCTRL_MODE_XTAL; CMU->HFXOCTRL1 = CMU_HFXOCTRL1_PEAKDETTHR_DEFAULT; CMU->HFXOSTEADYSTATECTRL |= CMU_HFXOSTEADYSTATECTRL_PEAKMONEN; CMU->HFXOTIMEOUTCTRL = (7 << _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_SHIFT) | (8 << _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_SHIFT) | (12 << _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_SHIFT); // Enable HFXO and wait for it to be ready CMU->OSCENCMD = CMU_OSCENCMD_HFXOEN; while(!(CMU->STATUS & CMU_STATUS_HFXORDY)); // Switch main clock to HFXO and wait for it to be selected CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO; while((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) != CMU_HFCLKSTATUS_SELECTED_HFXO); // Calibrate HFRCO for 72MHz and enable tuning by PLL cmu_hfrco_calib((DEVINFO->HFRCOCAL16) | CMU_HFRCOCTRL_FINETUNINGEN); // Setup the PLL CMU->DPLLCTRL = CMU_DPLLCTRL_REFSEL_HFXO | CMU_DPLLCTRL_AUTORECOVER | CMU_DPLLCTRL_EDGESEL_RISE | CMU_DPLLCTRL_MODE_FREQLL; // 72MHz = 50MHz (HFXO) * 1.44 (144/100) CMU->DPLLCTRL1 = (143 << _CMU_DPLLCTRL1_N_SHIFT) | (99 << _CMU_DPLLCTRL1_M_SHIFT); // fHFRCO = fHFXO * (N + 1) / (M + 1) // Enable the DPLL and wait for it to be ready CMU->OSCENCMD = CMU_OSCENCMD_DPLLEN; while(!(CMU->STATUS & CMU_STATUS_DPLLRDY)); // Config peripherals for the new frequency (freq > 32MHz) CMU->CTRL |= CMU_CTRL_WSHFLE; // Set prescalers CMU->HFPRESC = CMU_HFPRESC_HFCLKLEPRESC_DIV2 | CMU_HFPRESC_PRESC_NODIVISION; CMU->HFBUSPRESC = 1 << _CMU_HFBUSPRESC_PRESC_SHIFT; CMU->HFCOREPRESC = 0 << _CMU_HFCOREPRESC_PRESC_SHIFT; CMU->HFPERPRESC = 1 << _CMU_HFPERPRESC_PRESC_SHIFT; CMU->HFEXPPRESC = 0 << _CMU_HFEXPPRESC_PRESC_SHIFT; CMU->HFPERPRESCB = 0 << _CMU_HFPERPRESCB_PRESC_SHIFT; CMU->HFPERPRESCC = 1 << _CMU_HFPERPRESCC_PRESC_SHIFT; // Enable clock to peripherals CMU->CTRL |= CMU_CTRL_HFPERCLKEN; // Switch main clock to HFRCO and wait for it to be selected CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFRCO; while((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) != CMU_HFCLKSTATUS_SELECTED_HFRCO); // LFA Clock CMU->LFACLKSEL = CMU_LFACLKSEL_LFA_LFRCO; // LFB Clock CMU->LFBCLKSEL = CMU_LFBCLKSEL_LFB_LFRCO; // LFC Clock CMU->LFCCLKSEL = CMU_LFCCLKSEL_LFC_LFRCO; // LFE Clock CMU->LFECLKSEL = CMU_LFECLKSEL_LFE_ULFRCO; } static void systick_init(void) { SysTick->LOAD = (72000000 / 1000) - 1; SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk; SCB->SHP[11] = 7 << (8 - __NVIC_PRIO_BITS); // Set priority 3,1 (min) } static void gpio_init(void) { CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_GPIO; // NC - Not Connected (not available in mcu package) // NR - Not routed (no routing to pin on pcb, floating) // NU - Not used (not currently in use) // Port A GPIO->P[0].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (6 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[0].MODEL = GPIO_P_MODEL_MODE0_DISABLED // NU | GPIO_P_MODEL_MODE1_DISABLED // NU | GPIO_P_MODEL_MODE2_DISABLED // NU | GPIO_P_MODEL_MODE3_DISABLED // NU | GPIO_P_MODEL_MODE4_DISABLED // NU | GPIO_P_MODEL_MODE5_DISABLED // NU | GPIO_P_MODEL_MODE6_DISABLED // NU | GPIO_P_MODEL_MODE7_DISABLED; // NC GPIO->P[0].MODEH = GPIO_P_MODEH_MODE8_DISABLED // GPIO - MIC_ENABLE | GPIO_P_MODEH_MODE9_DISABLED // NC | GPIO_P_MODEH_MODE10_DISABLED // NC | GPIO_P_MODEH_MODE11_DISABLED // NC | GPIO_P_MODEH_MODE12_WIREDAND // LED0R | GPIO_P_MODEH_MODE13_WIREDAND // LED0B | GPIO_P_MODEH_MODE14_WIREDAND // LED0G | GPIO_P_MODEH_MODE15_DISABLED; // NU GPIO->P[0].DOUT = 0x7000; // Leds off By default GPIO->P[0].OVTDIS = 0; // Port B GPIO->P[1].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (6 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[1].MODEL = GPIO_P_MODEL_MODE0_DISABLED // NC | GPIO_P_MODEL_MODE1_DISABLED // NC | GPIO_P_MODEL_MODE2_DISABLED // NC | GPIO_P_MODEL_MODE3_DISABLED // NU | GPIO_P_MODEL_MODE4_DISABLED // NU | GPIO_P_MODEL_MODE5_DISABLED // NU | GPIO_P_MODEL_MODE6_DISABLED // NU | GPIO_P_MODEL_MODE7_DISABLED; // MAIN_LFXTAL_P GPIO->P[1].MODEH = GPIO_P_MODEH_MODE8_DISABLED // MAIN_LFXTAL_N | GPIO_P_MODEH_MODE9_DISABLED // NC | GPIO_P_MODEH_MODE10_DISABLED // NC | GPIO_P_MODEH_MODE11_DISABLED // PDM_DAT0 - MIC_DATA | GPIO_P_MODEH_MODE12_DISABLED // PDM_CLK - MIC_CLOCK | GPIO_P_MODEH_MODE13_DISABLED // MAIN_HFXTAL_P | GPIO_P_MODEH_MODE14_DISABLED // MAIN_HFXTAL_N | GPIO_P_MODEH_MODE15_DISABLED; // NC GPIO->P[1].DOUT = 0; GPIO->P[1].OVTDIS = 0; // Port C GPIO->P[2].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (7 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[2].MODEL = GPIO_P_MODEL_MODE0_DISABLED // NC | GPIO_P_MODEL_MODE1_DISABLED // NC | GPIO_P_MODEL_MODE2_DISABLED // NC | GPIO_P_MODEL_MODE3_DISABLED // NC | GPIO_P_MODEL_MODE4_DISABLED // NU | GPIO_P_MODEL_MODE5_DISABLED // NU | GPIO_P_MODEL_MODE6_DISABLED // NC | GPIO_P_MODEL_MODE7_DISABLED; // NC GPIO->P[2].MODEH = GPIO_P_MODEH_MODE8_DISABLED // NC | GPIO_P_MODEH_MODE9_DISABLED // NC | GPIO_P_MODEH_MODE10_DISABLED // NC | GPIO_P_MODEH_MODE11_DISABLED // NC | GPIO_P_MODEH_MODE12_DISABLED // NC | GPIO_P_MODEH_MODE13_DISABLED // NC | GPIO_P_MODEH_MODE14_DISABLED // NC | GPIO_P_MODEH_MODE15_DISABLED; // NC GPIO->P[2].DOUT = 0; GPIO->P[2].OVTDIS = 0; // Port D GPIO->P[3].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (6 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[3].MODEL = GPIO_P_MODEL_MODE0_DISABLED // NU | GPIO_P_MODEL_MODE1_DISABLED // NU | GPIO_P_MODEL_MODE2_DISABLED // NU | GPIO_P_MODEL_MODE3_DISABLED // NU | GPIO_P_MODEL_MODE4_DISABLED // NU | GPIO_P_MODEL_MODE5_INPUT // GPIO - BTN0 | GPIO_P_MODEL_MODE6_WIREDAND // LED1R | GPIO_P_MODEL_MODE7_DISABLED; // NU GPIO->P[3].MODEH = GPIO_P_MODEH_MODE8_INPUT // GPIO - BTN1 | GPIO_P_MODEH_MODE9_DISABLED // NC | GPIO_P_MODEH_MODE10_DISABLED // NC | GPIO_P_MODEH_MODE11_DISABLED // NC | GPIO_P_MODEH_MODE12_DISABLED // NC | GPIO_P_MODEH_MODE13_DISABLED // NC | GPIO_P_MODEH_MODE14_DISABLED // NC | GPIO_P_MODEH_MODE15_DISABLED; // NC GPIO->P[3].DOUT = 0; GPIO->P[3].OVTDIS = 0; // Port E GPIO->P[4].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (6 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[4].MODEL = GPIO_P_MODEL_MODE0_DISABLED // NC | GPIO_P_MODEL_MODE1_DISABLED // NC | GPIO_P_MODEL_MODE2_DISABLED // NC | GPIO_P_MODEL_MODE3_DISABLED // NC | GPIO_P_MODEL_MODE4_DISABLED // NU | GPIO_P_MODEL_MODE5_DISABLED // NU | GPIO_P_MODEL_MODE6_DISABLED // NU | GPIO_P_MODEL_MODE7_DISABLED; // NU GPIO->P[4].MODEH = GPIO_P_MODEH_MODE8_DISABLED // NU | GPIO_P_MODEH_MODE9_DISABLED // NU | GPIO_P_MODEH_MODE10_DISABLED // NU | GPIO_P_MODEH_MODE11_DISABLED // NU | GPIO_P_MODEH_MODE12_WIREDAND // LED1B | GPIO_P_MODEH_MODE13_DISABLED // NU | GPIO_P_MODEH_MODE14_DISABLED // NU | GPIO_P_MODEH_MODE15_DISABLED; // NU GPIO->P[4].DOUT = 0; GPIO->P[4].OVTDIS = 0; // Port F GPIO->P[5].CTRL = GPIO_P_CTRL_DRIVESTRENGTHALT_STRONG | (6 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT) | GPIO_P_CTRL_DRIVESTRENGTH_STRONG | (6 << _GPIO_P_CTRL_SLEWRATE_SHIFT); GPIO->P[5].MODEL = GPIO_P_MODEL_MODE0_PUSHPULL // SWCLK | GPIO_P_MODEL_MODE1_PUSHPULL // SWDIO | GPIO_P_MODEL_MODE2_PUSHPULL // SWO | GPIO_P_MODEL_MODE3_DISABLED // NC | GPIO_P_MODEL_MODE4_DISABLED // NC | GPIO_P_MODEL_MODE5_DISABLED // NU | GPIO_P_MODEL_MODE6_DISABLED // NC | GPIO_P_MODEL_MODE7_DISABLED; // NC GPIO->P[5].MODEH = GPIO_P_MODEH_MODE8_DISABLED // NC | GPIO_P_MODEH_MODE9_DISABLED // NC | GPIO_P_MODEH_MODE10_DISABLED // USB N | GPIO_P_MODEH_MODE11_DISABLED // USB P | GPIO_P_MODEH_MODE12_WIREDAND // LED1G | GPIO_P_MODEH_MODE13_DISABLED // NC | GPIO_P_MODEH_MODE14_DISABLED // NC | GPIO_P_MODEH_MODE15_DISABLED; // NC GPIO->P[5].DOUT = 0; GPIO->P[5].OVTDIS = 0; // Debugger Route GPIO->ROUTEPEN &= ~(GPIO_ROUTEPEN_TDIPEN | GPIO_ROUTEPEN_TDOPEN); // Disable JTAG GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN; // Enable SWO GPIO->ROUTELOC0 = GPIO_ROUTELOC0_SWVLOC_LOC0; // SWO on PF2 // External interrupts GPIO->EXTIPSELL = GPIO_EXTIPSELL_EXTIPSEL0_PORTE // NU | GPIO_EXTIPSELL_EXTIPSEL1_PORTB // NU | GPIO_EXTIPSELL_EXTIPSEL2_PORTB // NU | GPIO_EXTIPSELL_EXTIPSEL3_PORTB // NU | GPIO_EXTIPSELL_EXTIPSEL4_PORTA // NU | GPIO_EXTIPSELL_EXTIPSEL5_PORTA // NU | GPIO_EXTIPSELL_EXTIPSEL6_PORTC // NU | GPIO_EXTIPSELL_EXTIPSEL7_PORTC; // NU GPIO->EXTIPSELH = GPIO_EXTIPSELH_EXTIPSEL8_PORTA // NU | GPIO_EXTIPSELH_EXTIPSEL9_PORTE // NU | GPIO_EXTIPSELH_EXTIPSEL10_PORTF // NU | GPIO_EXTIPSELH_EXTIPSEL11_PORTA // NU | GPIO_EXTIPSELH_EXTIPSEL12_PORTA // NU | GPIO_EXTIPSELH_EXTIPSEL13_PORTE // NU | GPIO_EXTIPSELH_EXTIPSEL14_PORTF // NU | GPIO_EXTIPSELH_EXTIPSEL15_PORTA; // NU GPIO->EXTIPINSELL = GPIO_EXTIPINSELL_EXTIPINSEL0_PIN3 // NU | GPIO_EXTIPINSELL_EXTIPINSEL1_PIN1 // NU | GPIO_EXTIPINSELL_EXTIPINSEL2_PIN2 // NU | GPIO_EXTIPINSELL_EXTIPINSEL3_PIN3 // NU | GPIO_EXTIPINSELL_EXTIPINSEL4_PIN6 // NU | GPIO_EXTIPINSELL_EXTIPINSEL5_PIN7 // NU | GPIO_EXTIPINSELL_EXTIPINSEL6_PIN4 // NU | GPIO_EXTIPINSELL_EXTIPINSEL7_PIN7; // NU GPIO->EXTIPINSELH = GPIO_EXTIPINSELH_EXTIPINSEL8_PIN8 // NU | GPIO_EXTIPINSELH_EXTIPINSEL9_PIN9 // NU | GPIO_EXTIPINSELH_EXTIPINSEL10_PIN11 // NU | GPIO_EXTIPINSELH_EXTIPINSEL11_PIN8 // NU | GPIO_EXTIPINSELH_EXTIPINSEL12_PIN13 // NU | GPIO_EXTIPINSELH_EXTIPINSEL13_PIN15 // NU | GPIO_EXTIPINSELH_EXTIPINSEL14_PIN12 // NU | GPIO_EXTIPINSELH_EXTIPINSEL15_PIN12; // NU } /*--------------------------------------------------------------------*/ /* Board Init */ /*--------------------------------------------------------------------*/ void board_init(void) { emu_dcdc_init(1800.f, 50.f, 100.f, 0.f); // Init DC-DC converter (1.8 V, 50 mA active, 100 uA sleep, 0 mA reverse limit) emu_init(0); emu_reg_init(3300.f); // set output regulator to 3.3V cmu_hfxo_startup_calib(0x200, 0x145); // Config HFXO Startup for 1280 uA, 36 pF (18 pF + 2 pF CLOAD) cmu_hfxo_steady_calib(0x009, 0x145); // Config HFXO Steady for 12 uA, 36 pF (18 pF + 2 pF CLOAD) cmu_init(); // Init Clock Management Unit cmu_ushfrco_calib(1, DEVINFO->USHFRCOCAL13); // Enable and calibrate USHFRCO for 48 MHz cmu_auxhfrco_calib(1, DEVINFO->AUXHFRCOCAL11); // Enable and calibrate AUXHFRCO for 32 MHz CMU->USBCRCTRL = CMU_USBCRCTRL_USBCREN; // enable USB clock recovery CMU->USBCTRL = CMU_USBCTRL_USBCLKSEL_USHFRCO | CMU_USBCTRL_USBCLKEN; // select USHFRCO as USB Phy clock source and enable it CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_USB; // enable USB peripheral clock systick_init(); // Init system tick gpio_init(); // Init IOs } /*--------------------------------------------------------------------*/ /* Board porting API */ /*--------------------------------------------------------------------*/ void board_led_write(bool state) { // Combine red and blue for pink Because it looks good :) GPIO->P[LED_PORT].DOUT = (GPIO->P[LED_PORT].DOUT & ~((1 << LED_PIN_R) | (1 << LED_PIN_B))) | (state << LED_PIN_R) | (state << LED_PIN_B); } uint32_t board_button_read(void) { return !!(GPIO->P[BUTTON_PORT].DIN & (1 << BUTTON_PIN)); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/efm32/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # EFM32_FAMILY should be set by board.cmake (e.g. efm32gg12b) string(TOUPPER ${EFM32_FAMILY} EFM32_FAMILY_UPPER) set(SILABS_CMSIS ${TOP}/hw/mcu/silabs/cmsis-dfp-${EFM32_FAMILY}/Device/SiliconLabs/${EFM32_FAMILY_UPPER}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS EFM32GG CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_GNU ${SILABS_CMSIS}/Source/GCC/${EFM32_FAMILY}.ld) set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SILABS_CMSIS}/Source/GCC/startup_${EFM32_FAMILY}.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SILABS_CMSIS}/Source/system_${EFM32_FAMILY}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_5}/CMSIS/Core/Include ${SILABS_CMSIS}/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS __START=main ${EFM32_MCU} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_EFM32GG) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/efm32/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -mthumb \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ -D__STARTUP_CLEAR_BSS \ -D__START=main \ -DCFG_TUSB_MCU=OPT_MCU_EFM32GG CPU_CORE ?= cortex-m4 # EFM32_FAMILY should be set by board.mk (e.g. efm32gg12b) SILABS_CMSIS = hw/mcu/silabs/cmsis-dfp-$(EFM32_FAMILY)/Device/SiliconLabs/$(shell echo $(EFM32_FAMILY) | tr a-z A-Z) LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE = $(SILABS_CMSIS)/Source/GCC/$(EFM32_FAMILY).ld SRC_C += \ $(SILABS_CMSIS)/Source/system_$(EFM32_FAMILY).c \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ SRC_S += \ $(SILABS_CMSIS)/Source/GCC/startup_$(EFM32_FAMILY).S INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SILABS_CMSIS)/Include \ $(TOP)/$(BOARD_PATH) # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F ================================================ FILE: hw/bsp/espressif/boards/CMakeLists.txt ================================================ set(hw_dir "${CMAKE_CURRENT_LIST_DIR}/../../../") idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES driver usb REQUIRES led_strip src tinyusb_src) ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather ESP32 v2 url: https://www.adafruit.com/product/5400 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 0 #define NEOPIXEL_POWER_PIN 2 #define NEOPIXEL_POWER_STATE 1 #define BUTTON_PIN 38 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI3_HOST #define MAX3421_SCK_PIN 5 #define MAX3421_MOSI_PIN 19 #define MAX3421_MISO_PIN 21 #define MAX3421_CS_PIN 33 #define MAX3421_INTR_PIN 15 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32c6/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32c6") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32c6/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather EPS32-C6 url: https://www.adafruit.com/product/5933 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 15 #define BUTTON_PIN 9 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 21 #define MAX3421_MOSI_PIN 22 #define MAX3421_MISO_PIN 23 #define MAX3421_CS_PIN 8 #define MAX3421_INTR_PIN 7 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather ESP32S2 url: https://www.adafruit.com/product/5000 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 33 #define NEOPIXEL_POWER_PIN 21 #define NEOPIXEL_POWER_STATE 1 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 36 #define MAX3421_MOSI_PIN 35 #define MAX3421_MISO_PIN 37 #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s3") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/adafruit_feather_esp32s3/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather ESP32S3 url: https://www.adafruit.com/product/5323 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 33 #define NEOPIXEL_POWER_PIN 21 #define NEOPIXEL_POWER_STATE 1 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 36 #define MAX3421_MOSI_PIN 35 #define MAX3421_MISO_PIN 37 #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/adafruit_magtag_29gray/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") ================================================ FILE: hw/bsp/espressif/boards/adafruit_magtag_29gray/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit MagTag 2.9" Grayscale url: https://www.adafruit.com/product/4800 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 1 #define NEOPIXEL_POWER_PIN 21 #define NEOPIXEL_POWER_STATE 0 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Metro ESP32-S2 url: https://www.adafruit.com/product/4775 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 45 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 36 #define MAX3421_MOSI_PIN 35 #define MAX3421_MISO_PIN 37 #define MAX3421_CS_PIN 15 #define MAX3421_INTR_PIN 14 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_addax_1/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s3") ================================================ FILE: hw/bsp/espressif/boards/espressif_addax_1/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif Addax-1 url: n/a */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Note: On the production version (v1.1) WS2812 is connected to GPIO 47 #define NEOPIXEL_PIN 47 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32c3") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/espressif_c3_devkitc/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif C3 DevKitC url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c3/esp32-c3-devkitc-02/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 8 #define BUTTON_PIN 9 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 4 #define MAX3421_MOSI_PIN 6 #define MAX3421_MISO_PIN 5 #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 7 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_c6_devkitc/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32c6") set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/espressif/boards/espressif_c6_devkitc/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif C6 DevKitC url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 8 #define BUTTON_PIN 9 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 4 #define MAX3421_MOSI_PIN 6 #define MAX3421_MISO_PIN 5 #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 7 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_kaluga_1/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") ================================================ FILE: hw/bsp/espressif/boards/espressif_kaluga_1/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif Kaluga 1 url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-kaluga-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Note: need to insert jumper next to WS2812 pixel #define NEOPIXEL_PIN 45 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 36 #define MAX3421_MOSI_PIN 35 #define MAX3421_MISO_PIN 37 #define MAX3421_CS_PIN 15 #define MAX3421_INTR_PIN 14 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32p4") list(APPEND SDKCONFIG_DEFAULTS "${CMAKE_CURRENT_LIST_DIR}/sdkconfig.defaults") ================================================ FILE: hw/bsp/espressif/boards/espressif_p4_function_ev/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif P4 Function EV url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // #define NEOPIXEL_PIN 48 #define BUTTON_PIN 35 #define BUTTON_STATE_ACTIVE 0 // For CI hardware test, to test both device and host on the same HS port with help of TS3USB30 // https://www.adafruit.com/product/5871 #define HIL_TS3USB30_MODE_PIN 47 #define HIL_TS3USB30_MODE_DEVICE 1 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_p4_function_ev/sdkconfig.defaults ================================================ CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y CONFIG_ESP32P4_REV_MIN_1=y ================================================ FILE: hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") ================================================ FILE: hw/bsp/espressif/boards/espressif_s2_devkitc/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif S2 DevKitC url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-devkitc-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 18 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 36 #define MAX3421_MOSI_PIN 35 #define MAX3421_MISO_PIN 37 #define MAX3421_CS_PIN 15 #define MAX3421_INTR_PIN 14 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_s3_devkitc/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s3") ================================================ FILE: hw/bsp/espressif/boards/espressif_s3_devkitc/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif S3 DevKitC url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitc-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 38 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 39 #define MAX3421_MOSI_PIN 42 #define MAX3421_MISO_PIN 21 #define MAX3421_CS_PIN 15 #define MAX3421_INTR_PIN 14 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_s3_devkitm/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s3") ================================================ FILE: hw/bsp/espressif/boards/espressif_s3_devkitm/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif S3 DevKitM url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitm-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define NEOPIXEL_PIN 48 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 // SPI for USB host shield #define MAX3421_SPI_HOST SPI2_HOST #define MAX3421_SCK_PIN 39 #define MAX3421_MOSI_PIN 42 #define MAX3421_MISO_PIN 21 #define MAX3421_CS_PIN 15 #define MAX3421_INTR_PIN 14 // For CI hardware test, to test both device and host on the same HS port with help of TS3USB30 // https://www.adafruit.com/product/5871 #define HIL_TS3USB30_MODE_PIN 47 #define HIL_TS3USB30_MODE_DEVICE 1 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/espressif_saola_1/board.cmake ================================================ # Apply board specific content here set(IDF_TARGET "esp32s2") ================================================ FILE: hw/bsp/espressif/boards/espressif_saola_1/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Espresif S2 Saola 1 url: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s2/esp32-s2-saola-1/index.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Note: On the production version (v1.2) WS2812 is connected to GPIO 18, // however earlier revision v1.1 WS2812 is connected to GPIO 17 #define NEOPIXEL_PIN 18 #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/espressif/boards/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Espressif */ #include "bsp/board_api.h" #include "board.h" #include "esp_rom_gpio.h" #include "esp_mac.h" #include "hal/gpio_ll.h" #include "driver/gpio.h" #include "driver/uart.h" #include "esp_private/periph_ctrl.h" #ifdef NEOPIXEL_PIN #include "led_strip.h" static led_strip_handle_t led_strip; #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 #include "driver/spi_master.h" static void max3421_init(void); #endif #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4, OPT_MCU_ESP32P4) static bool usb_init(uint8_t rhport, bool is_host); #endif //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ // Initialize on-board peripherals : led, button, uart and USB void board_init(void) { #ifdef NEOPIXEL_PIN #ifdef NEOPIXEL_POWER_PIN gpio_reset_pin(NEOPIXEL_POWER_PIN); gpio_set_direction(NEOPIXEL_POWER_PIN, GPIO_MODE_OUTPUT); gpio_set_level(NEOPIXEL_POWER_PIN, NEOPIXEL_POWER_STATE); #endif // WS2812 Neopixel driver with RMT peripheral led_strip_rmt_config_t rmt_config = { .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency, default = 10 Mhz .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 }; led_strip_config_t strip_config = { .strip_gpio_num = NEOPIXEL_PIN, // The GPIO that connected to the LED strip's data line .max_leds = 1, // The number of LEDs in the strip, .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip .led_model = LED_MODEL_WS2812, // LED strip model .flags.invert_out = false, // whether to invert the output signal }; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); led_strip_clear(led_strip); // off #endif // Button esp_rom_gpio_pad_select_gpio(BUTTON_PIN); gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); #if CONFIG_USB_OTG_SUPPORTED #if CFG_TUD_ENABLED usb_init(BOARD_TUD_RHPORT, false); #endif #if CFG_TUH_ENABLED usb_init(BOARD_TUH_RHPORT, true); #endif #endif #ifdef HIL_TS3USB30_MODE_PIN gpio_reset_pin(HIL_TS3USB30_MODE_PIN); gpio_set_direction(HIL_TS3USB30_MODE_PIN, GPIO_MODE_OUTPUT); gpio_set_level(HIL_TS3USB30_MODE_PIN, CFG_TUD_ENABLED ? HIL_TS3USB30_MODE_DEVICE : (1-HIL_TS3USB30_MODE_DEVICE)); #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 max3421_init(); #endif } #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4) #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ size_t board_get_unique_id(uint8_t id[], size_t max_len) { // use factory default MAC as serial ID esp_efuse_mac_get_default(id); return 6; } void board_led_write(bool state) { #ifdef NEOPIXEL_PIN led_strip_set_pixel(led_strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); led_strip_refresh(led_strip); #endif } // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void) { return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE; } // Get characters from UART int board_uart_read(uint8_t* buf, int len) { for (int i=0; i= ESP_IDF_VERSION_VAL(5, 3, 0) #include "esp_private/usb_phy.h" static usb_phy_handle_t phy_hdl; bool usb_init(uint8_t rhport, bool is_host) { (void) rhport; // Configure USB PHY usb_phy_config_t phy_conf = { .controller = USB_PHY_CTRL_OTG, #if defined(CONFIG_SOC_USB_UTMI_PHY_NUM) && CONFIG_SOC_USB_UTMI_PHY_NUM > 0 .target = USB_PHY_TARGET_UTMI, #else .target = USB_PHY_TARGET_INT, #endif // maybe we can use USB_OTG_MODE_DEFAULT and switch using dwc2 driver .otg_mode = is_host ? USB_OTG_MODE_HOST : USB_OTG_MODE_DEVICE, // https://github.com/hathach/tinyusb/issues/2943#issuecomment-2601888322 // Set speed to undefined (auto-detect) to avoid timinng/racing issue with S3 with host such as macOS .otg_speed = USB_PHY_SPEED_UNDEFINED, }; esp_err_t const err = usb_new_phy(&phy_conf, &phy_hdl); if (err != ESP_OK) { printf("usb_new_phy failed: %s\r\n", esp_err_to_name(err)); phy_hdl = NULL; return false; } return true; } #else #include "esp_private/usb_phy.h" #include "hal/usb_hal.h" #include "soc/usb_periph.h" static void configure_pins(usb_hal_context_t* usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support * for USB Host. */ for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { esp_rom_gpio_pad_select_gpio(iopin->pin); if (iopin->is_output) { esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false); } else { esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false); if ((iopin->pin != GPIO_MATRIX_CONST_ZERO_INPUT) && (iopin->pin != GPIO_MATRIX_CONST_ONE_INPUT)) { gpio_ll_input_enable(&GPIO, iopin->pin); } } esp_rom_gpio_pad_unhold(iopin->pin); } } if (!usb->use_external_phy) { gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); } } bool usb_init(void) { // USB Controller Hal init periph_module_reset(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE); usb_hal_context_t hal = { .use_external_phy = false // use built-in PHY }; usb_hal_init(&hal); configure_pins(&hal); return true; } #endif #endif //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static spi_device_handle_t max3421_spi; SemaphoreHandle_t max3421_intr_sem; static void IRAM_ATTR max3421_isr_handler(void* arg) { (void) arg; // arg is gpio num BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { portYIELD_FROM_ISR(); } } static void max3421_intr_task(void* param) { (void) param; while (1) { xSemaphoreTake(max3421_intr_sem, portMAX_DELAY); tuh_int_handler(BOARD_TUH_RHPORT, false); } } static void max3421_init(void) { // CS pin gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT); gpio_set_level(MAX3421_CS_PIN, 1); // SPI spi_bus_config_t buscfg = { .miso_io_num = MAX3421_MISO_PIN, .mosi_io_num = MAX3421_MOSI_PIN, .sclk_io_num = MAX3421_SCK_PIN, .quadwp_io_num = -1, .quadhd_io_num = -1, .data4_io_num = -1, .data5_io_num = -1, .data6_io_num = -1, .data7_io_num = -1, .max_transfer_sz = 1024 }; ESP_ERROR_CHECK(spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); spi_device_interface_config_t max3421_cfg = { .mode = 0, .clock_speed_hz = 20000000, // S2/S3 can work with 26 Mhz, but esp32 seems only work up to 20 Mhz .spics_io_num = -1, // manual control CS .queue_size = 1 }; ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi)); // Interrupt pin max3421_intr_sem = xSemaphoreCreateBinary(); xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL); gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); gpio_install_isr_service(0); gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); } void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; if (enabled) { gpio_intr_enable(MAX3421_INTR_PIN); } else { gpio_intr_disable(MAX3421_INTR_PIN); } } void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; gpio_set_level(MAX3421_CS_PIN, active ? 0 : 1); } bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { (void) rhport; if (tx_buf == NULL) { // fifo read, transmit rx_buf as dummy tx_buf = rx_buf; } // length in bits size_t const len_bits = xfer_bytes << 3; spi_transaction_t xact = { .length = len_bits, .rxlength = rx_buf ? len_bits : 0, .tx_buffer = tx_buf, .rx_buffer = rx_buf }; ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact)); return true; } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/CHANGELOG.md ================================================ ## 2.5.0 - Enabled support for IDF4.4 and above - with RMT backend only - Added API `led_strip_set_pixel_hsv` ## 2.4.0 - Support configurable SPI mode to control leds - recommend enabling DMA when using SPI mode ## 2.3.0 - Support configurable RMT channel size by setting `mem_block_symbols` ## 2.2.0 - Support for 4 components RGBW leds (SK6812): - in led_strip_config_t new fields led_pixel_format, controlling byte format (LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW) led_model, used to configure bit timing (LED_MODEL_WS2812, LED_MODEL_SK6812) - new API led_strip_set_pixel_rgbw - new interface type set_pixel_rgbw ## 2.1.0 - Support DMA feature, which offloads the CPU by a lot when it comes to drive a bunch of LEDs - Support various RMT clock sources - Acquire and release the power management lock before and after each refresh - New driver flag: `invert_out` which can invert the led control signal by hardware ## 2.0.0 - Reimplemented the driver using the new RMT driver (`driver/rmt_tx.h`) ## 1.0.0 - Initial driver version, based on the legacy RMT driver (`driver/rmt.h`) ================================================ FILE: hw/bsp/espressif/components/led_strip/CMakeLists.txt ================================================ include($ENV{IDF_PATH}/tools/cmake/version.cmake) set(srcs "src/led_strip_api.c") if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0") if(CONFIG_SOC_RMT_SUPPORTED) list(APPEND srcs "src/led_strip_rmt_dev.c" "src/led_strip_rmt_encoder.c") endif() else() list(APPEND srcs "src/led_strip_rmt_dev_idf4.c") endif() # the SPI backend driver relies on something that was added in IDF 5.1 if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1") if(CONFIG_SOC_GPSPI_SUPPORTED) list(APPEND srcs "src/led_strip_spi_dev.c") endif() endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS "include" "interface" REQUIRES "driver") ================================================ FILE: hw/bsp/espressif/components/led_strip/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: hw/bsp/espressif/components/led_strip/README.md ================================================ # LED Strip Driver [![Component Registry](https://components.espressif.com/components/espressif/led_strip/badge.svg)](https://components.espressif.com/components/espressif/led_strip) This driver is designed for addressable LEDs like [WS2812](http://www.world-semi.com/Certifications/WS2812B.html), where each LED is controlled by a single data line. ## Backend Controllers ### The [RMT](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html) Peripheral This is the most economical way to drive the LEDs because it only consumes one RMT channel, leaving other channels free to use. However, the memory usage increases dramatically with the number of LEDs. If the RMT hardware can't be assist by DMA, the driver will going into interrupt very frequently, thus result in a high CPU usage. What's worse, if the RMT interrupt is delayed or not serviced in time (e.g. if Wi-Fi interrupt happens on the same CPU core), the RMT transaction will be corrupted and the LEDs will display incorrect colors. If you want to use RMT to drive a large number of LEDs, you'd better to enable the DMA feature if possible [^1]. #### Allocate LED Strip Object with RMT Backend ```c #define BLINK_GPIO 0 led_strip_handle_t led_strip; /* LED strip initialization with the GPIO and pixels number*/ led_strip_config_t strip_config = { .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line .max_leds = 1, // The number of LEDs in the strip, .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip .led_model = LED_MODEL_WS2812, // LED strip model .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) }; led_strip_rmt_config_t rmt_config = { #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) .rmt_channel = 0, #else .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption .resolution_hz = 10 * 1000 * 1000, // 10MHz .flags.with_dma = false, // whether to enable the DMA feature #endif }; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); ``` You can create multiple LED strip objects with different GPIOs and pixel numbers. The backend driver will automatically allocate the RMT channel for you if there is more available. ### The [SPI](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html) Peripheral SPI peripheral can also be used to generate the timing required by the LED strip. However this backend is not as economical as the RMT one, because it will take up the whole **bus**, unlike the RMT just takes one **channel**. You **CAN'T** connect other devices to the same SPI bus if it's been used by the led_strip, because the led_strip doesn't have the concept of "Chip Select". Please note, the SPI backend has a dependency of **ESP-IDF >= 5.1** #### Allocate LED Strip Object with SPI Backend ```c #define BLINK_GPIO 0 led_strip_handle_t led_strip; /* LED strip initialization with the GPIO and pixels number*/ led_strip_config_t strip_config = { .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line .max_leds = 1, // The number of LEDs in the strip, .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip .led_model = LED_MODEL_WS2812, // LED strip model .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) }; led_strip_spi_config_t spi_config = { .clk_src = SPI_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs .spi_bus = SPI2_HOST, // SPI bus ID }; ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); ``` The number of LED strip objects can be created depends on how many free SPI buses are free to use in your project. ## FAQ * Which led_strip backend should I choose? * It depends on your application requirement and target chip's ability. ```mermaid flowchart LR A{Is RMT supported?} A --> |No| B[SPI backend] B --> C{Does the led strip has \n a larger number of LEDs?} C --> |No| D[Don't have to enable the DMA of the backend] C --> |Yes| E[Enable the DMA of the backend] A --> |Yes| F{Does the led strip has \n a larger number of LEDs?} F --> |Yes| G{Does RMT support DMA?} G --> |Yes| E G --> |No| B F --> |No| H[RMT backend] --> D ``` * How to set the brightness of the LED strip? * You can tune the brightness by scaling the value of each R-G-B element with a **same** factor. But pay attention to the overflow of the value. [^1]: The RMT DMA feature is not available on all ESP chips. Please check the data sheet before using it. ================================================ FILE: hw/bsp/espressif/components/led_strip/api.md ================================================ # API Reference ## Header files - [include/led_strip.h](#file-includeled_striph) - [include/led_strip_rmt.h](#file-includeled_strip_rmth) - [include/led_strip_spi.h](#file-includeled_strip_spih) - [include/led_strip_types.h](#file-includeled_strip_typesh) - [interface/led_strip_interface.h](#file-interfaceled_strip_interfaceh) ## File include/led_strip.h ## Functions | Type | Name | | ---: | :--- | | esp\_err\_t | [**led\_strip\_clear**](#function-led_strip_clear) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Clear LED strip (turn off all LEDs)_ | | esp\_err\_t | [**led\_strip\_del**](#function-led_strip_del) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Free LED strip resources._ | | esp\_err\_t | [**led\_strip\_refresh**](#function-led_strip_refresh) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Refresh memory colors to LEDs._ | | esp\_err\_t | [**led\_strip\_set\_pixel**](#function-led_strip_set_pixel) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue)
_Set RGB for a specific pixel._ | | esp\_err\_t | [**led\_strip\_set\_pixel\_hsv**](#function-led_strip_set_pixel_hsv) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint16\_t hue, uint8\_t saturation, uint8\_t value)
_Set HSV for a specific pixel._ | | esp\_err\_t | [**led\_strip\_set\_pixel\_rgbw**](#function-led_strip_set_pixel_rgbw) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue, uint32\_t white)
_Set RGBW for a specific pixel._ | ## Functions Documentation ### function `led_strip_clear` _Clear LED strip (turn off all LEDs)_ ```c esp_err_t led_strip_clear ( led_strip_handle_t strip ) ``` **Parameters:** - `strip` LED strip **Returns:** - ESP\_OK: Clear LEDs successfully - ESP\_FAIL: Clear LEDs failed because some other error occurred ### function `led_strip_del` _Free LED strip resources._ ```c esp_err_t led_strip_del ( led_strip_handle_t strip ) ``` **Parameters:** - `strip` LED strip **Returns:** - ESP\_OK: Free resources successfully - ESP\_FAIL: Free resources failed because error occurred ### function `led_strip_refresh` _Refresh memory colors to LEDs._ ```c esp_err_t led_strip_refresh ( led_strip_handle_t strip ) ``` **Parameters:** - `strip` LED strip **Returns:** - ESP\_OK: Refresh successfully - ESP\_FAIL: Refresh failed because some other error occurred **Note:** : After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. ### function `led_strip_set_pixel` _Set RGB for a specific pixel._ ```c esp_err_t led_strip_set_pixel ( led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue ) ``` **Parameters:** - `strip` LED strip - `index` index of pixel to set - `red` red part of color - `green` green part of color - `blue` blue part of color **Returns:** - ESP\_OK: Set RGB for a specific pixel successfully - ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters - ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred ### function `led_strip_set_pixel_hsv` _Set HSV for a specific pixel._ ```c esp_err_t led_strip_set_pixel_hsv ( led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value ) ``` **Parameters:** - `strip` LED strip - `index` index of pixel to set - `hue` hue part of color (0 - 360) - `saturation` saturation part of color (0 - 255) - `value` value part of color (0 - 255) **Returns:** - ESP\_OK: Set HSV color for a specific pixel successfully - ESP\_ERR\_INVALID\_ARG: Set HSV color for a specific pixel failed because of an invalid argument - ESP\_FAIL: Set HSV color for a specific pixel failed because other error occurred ### function `led_strip_set_pixel_rgbw` _Set RGBW for a specific pixel._ ```c esp_err_t led_strip_set_pixel_rgbw ( led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white ) ``` **Note:** Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) **Note:** Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component **Parameters:** - `strip` LED strip - `index` index of pixel to set - `red` red part of color - `green` green part of color - `blue` blue part of color - `white` separate white component **Returns:** - ESP\_OK: Set RGBW color for a specific pixel successfully - ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument - ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred ## File include/led_strip_rmt.h ## Structures and Types | Type | Name | | ---: | :--- | | struct | [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t)
_LED Strip RMT specific configuration._ | ## Functions | Type | Name | | ---: | :--- | | esp\_err\_t | [**led\_strip\_new\_rmt\_device**](#function-led_strip_new_rmt_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) \*rmt\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on RMT TX channel._ | ## Structures and Types Documentation ### struct `led_strip_rmt_config_t` _LED Strip RMT specific configuration._ Variables: - rmt\_clock\_source\_t clk_src
RMT clock source - struct [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) flags
Extra driver flags - size\_t mem_block_symbols
How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. - uint32\_t resolution_hz
RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied - uint32\_t with_dma
Use DMA to transmit data ## Functions Documentation ### function `led_strip_new_rmt_device` _Create LED strip based on RMT TX channel._ ```c esp_err_t led_strip_new_rmt_device ( const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip ) ``` **Parameters:** - `led_config` LED strip configuration - `rmt_config` RMT specific configuration - `ret_strip` Returned LED strip handle **Returns:** - ESP\_OK: create LED strip handle successfully - ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument - ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory - ESP\_FAIL: create LED strip handle failed because some other error ## File include/led_strip_spi.h ## Structures and Types | Type | Name | | ---: | :--- | | struct | [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t)
_LED Strip SPI specific configuration._ | ## Functions | Type | Name | | ---: | :--- | | esp\_err\_t | [**led\_strip\_new\_spi\_device**](#function-led_strip_new_spi_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) \*spi\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on SPI MOSI channel._ | ## Structures and Types Documentation ### struct `led_strip_spi_config_t` _LED Strip SPI specific configuration._ Variables: - spi\_clock\_source\_t clk_src
SPI clock source - struct [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) flags
Extra driver flags - spi\_host\_device\_t spi_bus
SPI bus ID. Which buses are available depends on the specific chip - uint32\_t with_dma
Use DMA to transmit data ## Functions Documentation ### function `led_strip_new_spi_device` _Create LED strip based on SPI MOSI channel._ ```c esp_err_t led_strip_new_spi_device ( const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip ) ``` **Note:** Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. **Parameters:** - `led_config` LED strip configuration - `spi_config` SPI specific configuration - `ret_strip` Returned LED strip handle **Returns:** - ESP\_OK: create LED strip handle successfully - ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument - ESP\_ERR\_NOT\_SUPPORTED: create LED strip handle failed because of unsupported configuration - ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory - ESP\_FAIL: create LED strip handle failed because some other error ## File include/led_strip_types.h ## Structures and Types | Type | Name | | ---: | :--- | | enum | [**led\_model\_t**](#enum-led_model_t)
_LED strip model._ | | enum | [**led\_pixel\_format\_t**](#enum-led_pixel_format_t)
_LED strip pixel format._ | | struct | [**led\_strip\_config\_t**](#struct-led_strip_config_t)
_LED Strip Configuration._ | | typedef struct [**led\_strip\_t**](#struct-led_strip_t) \* | [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t)
_LED strip handle._ | ## Structures and Types Documentation ### enum `led_model_t` _LED strip model._ ```c enum led_model_t { LED_MODEL_WS2812, LED_MODEL_SK6812, LED_MODEL_INVALID }; ``` **Note:** Different led model may have different timing parameters, so we need to distinguish them. ### enum `led_pixel_format_t` _LED strip pixel format._ ```c enum led_pixel_format_t { LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW, LED_PIXEL_FORMAT_INVALID }; ``` ### struct `led_strip_config_t` _LED Strip Configuration._ Variables: - struct [**led\_strip\_config\_t**](#struct-led_strip_config_t) flags
Extra driver flags - uint32\_t invert_out
Invert output signal - led\_model\_t led_model
LED model - led\_pixel\_format\_t led_pixel_format
LED pixel format - uint32\_t max_leds
Maximum LEDs in a single strip - int strip_gpio_num
GPIO number that used by LED strip ### typedef `led_strip_handle_t` _LED strip handle._ ```c typedef struct led_strip_t* led_strip_handle_t; ``` ## File interface/led_strip_interface.h ## Structures and Types | Type | Name | | ---: | :--- | | struct | [**led\_strip\_t**](#struct-led_strip_t)
_LED strip interface definition._ | | typedef struct [**led\_strip\_t**](#struct-led_strip_t) | [**led\_strip\_t**](#typedef-led_strip_t)
| ## Structures and Types Documentation ### struct `led_strip_t` _LED strip interface definition._ Variables: - esp\_err\_t(\* clear
_Clear LED strip (turn off all LEDs)_
**Parameters:** - `strip` LED strip - `timeout_ms` timeout value for clearing task **Returns:** - ESP\_OK: Clear LEDs successfully - ESP\_FAIL: Clear LEDs failed because some other error occurred - esp\_err\_t(\* del
_Free LED strip resources._
**Parameters:** - `strip` LED strip **Returns:** - ESP\_OK: Free resources successfully - ESP\_FAIL: Free resources failed because error occurred - esp\_err\_t(\* refresh
_Refresh memory colors to LEDs._
**Parameters:** - `strip` LED strip - `timeout_ms` timeout value for refreshing task **Returns:** - ESP\_OK: Refresh successfully - ESP\_FAIL: Refresh failed because some other error occurred **Note:** : After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. - esp\_err\_t(\* set_pixel
_Set RGB for a specific pixel._
**Parameters:** - `strip` LED strip - `index` index of pixel to set - `red` red part of color - `green` green part of color - `blue` blue part of color **Returns:** - ESP\_OK: Set RGB for a specific pixel successfully - ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters - ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred - esp\_err\_t(\* set_pixel_rgbw
_Set RGBW for a specific pixel. Similar to_ `set_pixel`_but also set the white component._
**Parameters:** - `strip` LED strip - `index` index of pixel to set - `red` red part of color - `green` green part of color - `blue` blue part of color - `white` separate white component **Returns:** - ESP\_OK: Set RGBW color for a specific pixel successfully - ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument - ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred ### typedef `led_strip_t` ```c typedef struct led_strip_t led_strip_t; ``` Type of LED strip ================================================ FILE: hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt ================================================ # For more information about build system see # https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html # The following five lines of boilerplate have to be in your project's # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) set(IDF_TARGET "esp32s3") include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(led_strip_rmt_ws2812) ================================================ FILE: hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md ================================================ # LED Strip Example (RMT backend + WS2812) This example demonstrates how to blink the WS2812 LED using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component. ## How to Use Example ### Hardware Required * A development board with Espressif SoC * A USB cable for Power supply and programming * WS2812 LED strip ### Configure the Example Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. Then assign the proper GPIO in the [source file](main/led_strip_rmt_ws2812_main.c). If your led strip has multiple LEDs, don't forget update the number. ### Build and Flash Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. (To exit the serial monitor, type ``Ctrl-]``.) See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. ## Example Output ```text I (299) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (309) example: Created LED strip object with RMT backend I (309) example: Start blinking LED strip ``` ================================================ FILE: hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt ================================================ idf_component_register(SRCS "led_strip_rmt_ws2812_main.c" INCLUDE_DIRS ".") ================================================ FILE: hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml ================================================ ## IDF Component Manager Manifest File dependencies: espressif/led_strip: version: '^2' override_path: '../../../' ================================================ FILE: hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c ================================================ /* * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "led_strip.h" #include "esp_log.h" #include "esp_err.h" // GPIO assignment #define LED_STRIP_BLINK_GPIO 48 // Numbers of the LED in the strip #define LED_STRIP_LED_NUMBERS 1 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) #define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) static const char *TAG = "example"; led_strip_handle_t configure_led(void) { // LED strip general initialization, according to your led board design led_strip_config_t strip_config = { .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip, .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip .led_model = LED_MODEL_WS2812, // LED strip model .flags.invert_out = false, // whether to invert the output signal }; // LED strip backend configuration: RMT led_strip_rmt_config_t rmt_config = { #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) .rmt_channel = 0, #else .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 #endif }; // LED Strip object handle led_strip_handle_t led_strip; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); ESP_LOGI(TAG, "Created LED strip object with RMT backend"); return led_strip; } void app_main(void) { led_strip_handle_t led_strip = configure_led(); bool led_on_off = false; ESP_LOGI(TAG, "Start blinking LED strip"); while (1) { if (led_on_off) { /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) { ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5)); } /* Refresh the strip to send data */ ESP_ERROR_CHECK(led_strip_refresh(led_strip)); ESP_LOGI(TAG, "LED ON!"); } else { /* Set all LED off to clear all pixels */ ESP_ERROR_CHECK(led_strip_clear(led_strip)); ESP_LOGI(TAG, "LED OFF!"); } led_on_off = !led_on_off; vTaskDelay(pdMS_TO_TICKS(500)); } } ================================================ FILE: hw/bsp/espressif/components/led_strip/idf_component.yml ================================================ version: "2.5.2" description: Driver for Addressable LED Strip (WS2812, etc) url: https://github.com/espressif/idf-extra-components/tree/master/led_strip dependencies: idf: ">=4.4" ================================================ FILE: hw/bsp/espressif/components/led_strip/include/led_strip.h ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "esp_err.h" #include "led_strip_rmt.h" #include "esp_idf_version.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) #include "led_strip_spi.h" #endif #ifdef __cplusplus extern "C" { #endif /** * @brief Set RGB for a specific pixel * * @param strip: LED strip * @param index: index of pixel to set * @param red: red part of color * @param green: green part of color * @param blue: blue part of color * * @return * - ESP_OK: Set RGB for a specific pixel successfully * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred */ esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); /** * @brief Set RGBW for a specific pixel * * @note Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component * * @param strip: LED strip * @param index: index of pixel to set * @param red: red part of color * @param green: green part of color * @param blue: blue part of color * @param white: separate white component * * @return * - ESP_OK: Set RGBW color for a specific pixel successfully * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred */ esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); /** * @brief Set HSV for a specific pixel * * @param strip: LED strip * @param index: index of pixel to set * @param hue: hue part of color (0 - 360) * @param saturation: saturation part of color (0 - 255) * @param value: value part of color (0 - 255) * * @return * - ESP_OK: Set HSV color for a specific pixel successfully * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because of an invalid argument * - ESP_FAIL: Set HSV color for a specific pixel failed because other error occurred */ esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value); /** * @brief Refresh memory colors to LEDs * * @param strip: LED strip * * @return * - ESP_OK: Refresh successfully * - ESP_FAIL: Refresh failed because some other error occurred * * @note: * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. */ esp_err_t led_strip_refresh(led_strip_handle_t strip); /** * @brief Clear LED strip (turn off all LEDs) * * @param strip: LED strip * * @return * - ESP_OK: Clear LEDs successfully * - ESP_FAIL: Clear LEDs failed because some other error occurred */ esp_err_t led_strip_clear(led_strip_handle_t strip); /** * @brief Free LED strip resources * * @param strip: LED strip * * @return * - ESP_OK: Free resources successfully * - ESP_FAIL: Free resources failed because error occurred */ esp_err_t led_strip_del(led_strip_handle_t strip); #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "esp_err.h" #include "led_strip_types.h" #include "esp_idf_version.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #include "driver/rmt_types.h" #endif #ifdef __cplusplus extern "C" { #endif /** * @brief LED Strip RMT specific configuration */ typedef struct { #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver doesn't support channel allocator */ #else // new driver supports specify the clock source and clock resolution rmt_clock_source_t clk_src; /*!< RMT clock source */ uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied */ #endif size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. */ struct { uint32_t with_dma: 1; /*!< Use DMA to transmit data */ } flags; /*!< Extra driver flags */ } led_strip_rmt_config_t; /** * @brief Create LED strip based on RMT TX channel * * @param led_config LED strip configuration * @param rmt_config RMT specific configuration * @param ret_strip Returned LED strip handle * @return * - ESP_OK: create LED strip handle successfully * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory * - ESP_FAIL: create LED strip handle failed because some other error */ esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip); #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/include/led_strip_spi.h ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "esp_err.h" #include "driver/spi_master.h" #include "led_strip_types.h" #ifdef __cplusplus extern "C" { #endif /** * @brief LED Strip SPI specific configuration */ typedef struct { spi_clock_source_t clk_src; /*!< SPI clock source */ spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ struct { uint32_t with_dma: 1; /*!< Use DMA to transmit data */ } flags; /*!< Extra driver flags */ } led_strip_spi_config_t; /** * @brief Create LED strip based on SPI MOSI channel * @note Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. * * @param led_config LED strip configuration * @param spi_config SPI specific configuration * @param ret_strip Returned LED strip handle * @return * - ESP_OK: create LED strip handle successfully * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of unsupported configuration * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory * - ESP_FAIL: create LED strip handle failed because some other error */ esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip); #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/include/led_strip_types.h ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #ifdef __cplusplus extern "C" { #endif /** * @brief LED strip pixel format */ typedef enum { LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ } led_pixel_format_t; /** * @brief LED strip model * @note Different led model may have different timing parameters, so we need to distinguish them. */ typedef enum { LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ LED_MODEL_INVALID /*!< Invalid LED strip model */ } led_model_t; /** * @brief LED strip handle */ typedef struct led_strip_t *led_strip_handle_t; /** * @brief LED Strip Configuration */ typedef struct { int strip_gpio_num; /*!< GPIO number that used by LED strip */ uint32_t max_leds; /*!< Maximum LEDs in a single strip */ led_pixel_format_t led_pixel_format; /*!< LED pixel format */ led_model_t led_model; /*!< LED model */ struct { uint32_t invert_out: 1; /*!< Invert output signal */ } flags; /*!< Extra driver flags */ } led_strip_config_t; #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h ================================================ /* * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif typedef struct led_strip_t led_strip_t; /*!< Type of LED strip */ /** * @brief LED strip interface definition */ struct led_strip_t { /** * @brief Set RGB for a specific pixel * * @param strip: LED strip * @param index: index of pixel to set * @param red: red part of color * @param green: green part of color * @param blue: blue part of color * * @return * - ESP_OK: Set RGB for a specific pixel successfully * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred */ esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); /** * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set the white component * * @param strip: LED strip * @param index: index of pixel to set * @param red: red part of color * @param green: green part of color * @param blue: blue part of color * @param white: separate white component * * @return * - ESP_OK: Set RGBW color for a specific pixel successfully * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred */ esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); /** * @brief Refresh memory colors to LEDs * * @param strip: LED strip * @param timeout_ms: timeout value for refreshing task * * @return * - ESP_OK: Refresh successfully * - ESP_FAIL: Refresh failed because some other error occurred * * @note: * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. */ esp_err_t (*refresh)(led_strip_t *strip); /** * @brief Clear LED strip (turn off all LEDs) * * @param strip: LED strip * @param timeout_ms: timeout value for clearing task * * @return * - ESP_OK: Clear LEDs successfully * - ESP_FAIL: Clear LEDs failed because some other error occurred */ esp_err_t (*clear)(led_strip_t *strip); /** * @brief Free LED strip resources * * @param strip: LED strip * * @return * - ESP_OK: Free resources successfully * - ESP_FAIL: Free resources failed because error occurred */ esp_err_t (*del)(led_strip_t *strip); }; #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_api.c ================================================ /* * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_log.h" #include "esp_check.h" #include "led_strip.h" #include "led_strip_interface.h" static const char *TAG = "led_strip"; esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); return strip->set_pixel(strip, index, red, green, blue); } esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); uint32_t red = 0; uint32_t green = 0; uint32_t blue = 0; uint32_t rgb_max = value; uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; uint32_t i = hue / 60; uint32_t diff = hue % 60; // RGB adjustment amount by hue uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; switch (i) { case 0: red = rgb_max; green = rgb_min + rgb_adj; blue = rgb_min; break; case 1: red = rgb_max - rgb_adj; green = rgb_max; blue = rgb_min; break; case 2: red = rgb_min; green = rgb_max; blue = rgb_min + rgb_adj; break; case 3: red = rgb_min; green = rgb_max - rgb_adj; blue = rgb_max; break; case 4: red = rgb_min + rgb_adj; green = rgb_min; blue = rgb_max; break; default: red = rgb_max; green = rgb_min; blue = rgb_max - rgb_adj; break; } return strip->set_pixel(strip, index, red, green, blue); } esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); return strip->set_pixel_rgbw(strip, index, red, green, blue, white); } esp_err_t led_strip_refresh(led_strip_handle_t strip) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); return strip->refresh(strip); } esp_err_t led_strip_clear(led_strip_handle_t strip) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); return strip->clear(strip); } esp_err_t led_strip_del(led_strip_handle_t strip) { ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); return strip->del(strip); } ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include "esp_log.h" #include "esp_check.h" #include "driver/rmt_tx.h" #include "led_strip.h" #include "led_strip_interface.h" #include "led_strip_rmt_encoder.h" #define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution #define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4 // the memory size of each RMT channel, in words (4 bytes) #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 #else #define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 #endif static const char *TAG = "led_strip_rmt"; typedef struct { led_strip_t base; rmt_channel_handle_t rmt_chan; rmt_encoder_handle_t strip_encoder; uint32_t strip_len; uint8_t bytes_per_pixel; uint8_t pixel_buf[]; } led_strip_rmt_obj; static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); uint32_t start = index * rmt_strip->bytes_per_pixel; // In thr order of GRB, as LED strip like WS2812 sends out pixels in this order rmt_strip->pixel_buf[start + 0] = green & 0xFF; rmt_strip->pixel_buf[start + 1] = red & 0xFF; rmt_strip->pixel_buf[start + 2] = blue & 0xFF; if (rmt_strip->bytes_per_pixel > 3) { rmt_strip->pixel_buf[start + 3] = 0; } return ESP_OK; } static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; // SK6812 component order is GRBW *buf_start = green & 0xFF; *++buf_start = red & 0xFF; *++buf_start = blue & 0xFF; *++buf_start = white & 0xFF; return ESP_OK; } static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); rmt_transmit_config_t tx_conf = { .loop_count = 0, }; ESP_RETURN_ON_ERROR(rmt_enable(rmt_strip->rmt_chan), TAG, "enable RMT channel failed"); ESP_RETURN_ON_ERROR(rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf), TAG, "transmit pixels by RMT failed"); ESP_RETURN_ON_ERROR(rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1), TAG, "flush RMT channel failed"); ESP_RETURN_ON_ERROR(rmt_disable(rmt_strip->rmt_chan), TAG, "disable RMT channel failed"); return ESP_OK; } static esp_err_t led_strip_rmt_clear(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); // Write zero to turn off all leds memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); return led_strip_rmt_refresh(strip); } static esp_err_t led_strip_rmt_del(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, "delete RMT channel failed"); ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, "delete strip encoder failed"); free(rmt_strip); return ESP_OK; } esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip) { led_strip_rmt_obj *rmt_strip = NULL; esp_err_t ret = ESP_OK; ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); uint8_t bytes_per_pixel = 3; if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { bytes_per_pixel = 4; } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { bytes_per_pixel = 3; } else { assert(false); } rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for rmt strip"); uint32_t resolution = rmt_config->resolution_hz ? rmt_config->resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION; // for backward compatibility, if the user does not set the clk_src, use the default value rmt_clock_source_t clk_src = RMT_CLK_SRC_DEFAULT; if (rmt_config->clk_src) { clk_src = rmt_config->clk_src; } size_t mem_block_symbols = LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; // override the default value if the user sets it if (rmt_config->mem_block_symbols) { mem_block_symbols = rmt_config->mem_block_symbols; } rmt_tx_channel_config_t rmt_chan_config = { .clk_src = clk_src, .gpio_num = led_config->strip_gpio_num, .mem_block_symbols = mem_block_symbols, .resolution_hz = resolution, .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, .flags.with_dma = rmt_config->flags.with_dma, .flags.invert_out = led_config->flags.invert_out, }; ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG, "create RMT TX channel failed"); led_strip_encoder_config_t strip_encoder_conf = { .resolution = resolution, .led_model = led_config->led_model }; ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed"); rmt_strip->bytes_per_pixel = bytes_per_pixel; rmt_strip->strip_len = led_config->max_leds; rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; rmt_strip->base.refresh = led_strip_rmt_refresh; rmt_strip->base.clear = led_strip_rmt_clear; rmt_strip->base.del = led_strip_rmt_del; *ret_strip = &rmt_strip->base; return ESP_OK; err: if (rmt_strip) { if (rmt_strip->rmt_chan) { rmt_del_channel(rmt_strip->rmt_chan); } if (rmt_strip->strip_encoder) { rmt_del_encoder(rmt_strip->strip_encoder); } free(rmt_strip); } return ret; } ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include "esp_log.h" #include "esp_check.h" #include "driver/rmt.h" #include "led_strip.h" #include "led_strip_interface.h" static const char *TAG = "led_strip_rmt"; #define WS2812_T0H_NS (300) #define WS2812_T0L_NS (900) #define WS2812_T1H_NS (900) #define WS2812_T1L_NS (300) #define SK6812_T0H_NS (300) #define SK6812_T0L_NS (900) #define SK6812_T1H_NS (600) #define SK6812_T1L_NS (600) #define LED_STRIP_RESET_MS (10) // the memory size of each RMT channel, in words (4 bytes) #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 #else #define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 #endif static uint32_t led_t0h_ticks = 0; static uint32_t led_t1h_ticks = 0; static uint32_t led_t0l_ticks = 0; static uint32_t led_t1l_ticks = 0; typedef struct { led_strip_t base; rmt_channel_t rmt_channel; uint32_t strip_len; uint8_t bytes_per_pixel; uint8_t buffer[0]; } led_strip_rmt_obj; static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num) { if (src == NULL || dest == NULL) { *translated_size = 0; *item_num = 0; return; } const rmt_item32_t bit0 = {{{ led_t0h_ticks, 1, led_t0l_ticks, 0 }}}; //Logical 0 const rmt_item32_t bit1 = {{{ led_t1h_ticks, 1, led_t1l_ticks, 0 }}}; //Logical 1 size_t size = 0; size_t num = 0; uint8_t *psrc = (uint8_t *)src; rmt_item32_t *pdest = dest; while (size < src_size && num < wanted_num) { for (int i = 0; i < 8; i++) { // MSB first if (*psrc & (1 << (7 - i))) { pdest->val = bit1.val; } else { pdest->val = bit0.val; } num++; pdest++; } size++; psrc++; } *translated_size = size; *item_num = num; } static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of the maximum number of leds"); uint32_t start = index * rmt_strip->bytes_per_pixel; // In thr order of GRB rmt_strip->buffer[start + 0] = green & 0xFF; rmt_strip->buffer[start + 1] = red & 0xFF; rmt_strip->buffer[start + 2] = blue & 0xFF; if (rmt_strip->bytes_per_pixel > 3) { rmt_strip->buffer[start + 3] = 0; } return ESP_OK; } static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_ERROR(rmt_write_sample(rmt_strip->rmt_channel, rmt_strip->buffer, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, true), TAG, "transmit RMT samples failed"); vTaskDelay(pdMS_TO_TICKS(LED_STRIP_RESET_MS)); return ESP_OK; } static esp_err_t led_strip_rmt_clear(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); // Write zero to turn off all LEDs memset(rmt_strip->buffer, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); return led_strip_rmt_refresh(strip); } static esp_err_t led_strip_rmt_del(led_strip_t *strip) { led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); ESP_RETURN_ON_ERROR(rmt_driver_uninstall(rmt_strip->rmt_channel), TAG, "uninstall RMT driver failed"); free(rmt_strip); return ESP_OK; } esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *dev_config, led_strip_handle_t *ret_strip) { led_strip_rmt_obj *rmt_strip = NULL; esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(led_config && dev_config && ret_strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, TAG, "invalid led_pixel_format"); ESP_RETURN_ON_FALSE(dev_config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA is not supported"); uint8_t bytes_per_pixel = 3; if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { bytes_per_pixel = 4; } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { bytes_per_pixel = 3; } else { assert(false); } // allocate memory for led_strip object rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); ESP_RETURN_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, TAG, "request memory for les_strip failed"); // install RMT channel driver rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->strip_gpio_num, dev_config->rmt_channel); // set the minimal clock division because the LED strip needs a high clock resolution config.clk_div = 2; uint8_t mem_block_num = 2; // override the default value if the user specify the mem block size if (dev_config->mem_block_symbols) { mem_block_num = (dev_config->mem_block_symbols + LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS / 2) / LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; } config.mem_block_num = mem_block_num; ESP_GOTO_ON_ERROR(rmt_config(&config), err, TAG, "RMT config failed"); ESP_GOTO_ON_ERROR(rmt_driver_install(config.channel, 0, 0), err, TAG, "RMT install failed"); uint32_t counter_clk_hz = 0; rmt_get_counter_clock((rmt_channel_t)dev_config->rmt_channel, &counter_clk_hz); // ns -> ticks float ratio = (float)counter_clk_hz / 1e9; if (led_config->led_model == LED_MODEL_WS2812) { led_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); led_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); led_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); led_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); } else if (led_config->led_model == LED_MODEL_SK6812) { led_t0h_ticks = (uint32_t)(ratio * SK6812_T0H_NS); led_t0l_ticks = (uint32_t)(ratio * SK6812_T0L_NS); led_t1h_ticks = (uint32_t)(ratio * SK6812_T1H_NS); led_t1l_ticks = (uint32_t)(ratio * SK6812_T1L_NS); } else { assert(false); } // adapter to translates the LES strip date frame into RMT symbols rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter); rmt_strip->bytes_per_pixel = bytes_per_pixel; rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel; rmt_strip->strip_len = led_config->max_leds; rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; rmt_strip->base.refresh = led_strip_rmt_refresh; rmt_strip->base.clear = led_strip_rmt_clear; rmt_strip->base.del = led_strip_rmt_del; *ret_strip = &rmt_strip->base; return ESP_OK; err: if (rmt_strip) { free(rmt_strip); } return ret; } ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c ================================================ /* * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_check.h" #include "led_strip_rmt_encoder.h" static const char *TAG = "led_rmt_encoder"; typedef struct { rmt_encoder_t base; rmt_encoder_t *bytes_encoder; rmt_encoder_t *copy_encoder; int state; rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; rmt_encode_state_t session_state = 0; rmt_encode_state_t state = 0; size_t encoded_symbols = 0; switch (led_encoder->state) { case 0: // send RGB data encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); if (session_state & RMT_ENCODING_COMPLETE) { led_encoder->state = 1; // switch to next state when current encoding session finished } if (session_state & RMT_ENCODING_MEM_FULL) { state |= RMT_ENCODING_MEM_FULL; goto out; // yield if there's no free space for encoding artifacts } // fall-through case 1: // send reset code encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, sizeof(led_encoder->reset_code), &session_state); if (session_state & RMT_ENCODING_COMPLETE) { led_encoder->state = 0; // back to the initial encoding session state |= RMT_ENCODING_COMPLETE; } if (session_state & RMT_ENCODING_MEM_FULL) { state |= RMT_ENCODING_MEM_FULL; goto out; // yield if there's no free space for encoding artifacts } } out: *ret_state = state; return encoded_symbols; } static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_del_encoder(led_encoder->bytes_encoder); rmt_del_encoder(led_encoder->copy_encoder); free(led_encoder); return ESP_OK; } static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_encoder_reset(led_encoder->bytes_encoder); rmt_encoder_reset(led_encoder->copy_encoder); led_encoder->state = 0; return ESP_OK; } esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) { esp_err_t ret = ESP_OK; rmt_led_strip_encoder_t *led_encoder = NULL; ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led model"); led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); led_encoder->base.encode = rmt_encode_led_strip; led_encoder->base.del = rmt_del_led_strip_encoder; led_encoder->base.reset = rmt_led_strip_encoder_reset; rmt_bytes_encoder_config_t bytes_encoder_config; if (config->led_model == LED_MODEL_SK6812) { bytes_encoder_config = (rmt_bytes_encoder_config_t) { .bit0 = { .level0 = 1, .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us .level1 = 0, .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us }, .bit1 = { .level0 = 1, .duration0 = 0.6 * config->resolution / 1000000, // T1H=0.6us .level1 = 0, .duration1 = 0.6 * config->resolution / 1000000, // T1L=0.6us }, .flags.msb_first = 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) }; } else if (config->led_model == LED_MODEL_WS2812) { // different led strip might have its own timing requirements, following parameter is for WS2812 bytes_encoder_config = (rmt_bytes_encoder_config_t) { .bit0 = { .level0 = 1, .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us .level1 = 0, .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us }, .bit1 = { .level0 = 1, .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us .level1 = 0, .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us }, .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 }; } else { assert(false); } ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); rmt_copy_encoder_config_t copy_encoder_config = {}; ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us led_encoder->reset_code = (rmt_symbol_word_t) { .level0 = 0, .duration0 = reset_ticks, .level1 = 0, .duration1 = reset_ticks, }; *ret_encoder = &led_encoder->base; return ESP_OK; err: if (led_encoder) { if (led_encoder->bytes_encoder) { rmt_del_encoder(led_encoder->bytes_encoder); } if (led_encoder->copy_encoder) { rmt_del_encoder(led_encoder->copy_encoder); } free(led_encoder); } return ret; } ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h ================================================ /* * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "driver/rmt_encoder.h" #include "led_strip_types.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Type of led strip encoder configuration */ typedef struct { uint32_t resolution; /*!< Encoder resolution, in Hz */ led_model_t led_model; /*!< LED model */ } led_strip_encoder_config_t; /** * @brief Create RMT encoder for encoding LED strip pixels into RMT symbols * * @param[in] config Encoder configuration * @param[out] ret_encoder Returned encoder handle * @return * - ESP_ERR_INVALID_ARG for any invalid arguments * - ESP_ERR_NO_MEM out of memory when creating led strip encoder * - ESP_OK if creating encoder successfully */ esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder); #ifdef __cplusplus } #endif ================================================ FILE: hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c ================================================ /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include "esp_log.h" #include "esp_check.h" #include "esp_rom_gpio.h" #include "soc/spi_periph.h" #include "led_strip.h" #include "led_strip_interface.h" #include "hal/spi_hal.h" #define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution #define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 #define SPI_BYTES_PER_COLOR_BYTE 3 #define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) static const char *TAG = "led_strip_spi"; typedef struct { led_strip_t base; spi_host_device_t spi_host; spi_device_handle_t spi_device; uint32_t strip_len; uint8_t bytes_per_pixel; uint8_t pixel_buf[]; } led_strip_spi_obj; // please make sure to zero-initialize the buf before calling this function static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) { // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 // So a color byte occupies 3 bytes of SPI. *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; *(buf + 1) |= BIT(0); *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); } static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) { led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); if (spi_strip->bytes_per_pixel > 3) { __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); } return ESP_OK; } static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) { led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; // SK6812 component order is GRBW memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); return ESP_OK; } static esp_err_t led_strip_spi_refresh(led_strip_t *strip) { led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); spi_transaction_t tx_conf; memset(&tx_conf, 0, sizeof(tx_conf)); tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; tx_conf.tx_buffer = spi_strip->pixel_buf; tx_conf.rx_buffer = NULL; ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); return ESP_OK; } static esp_err_t led_strip_spi_clear(led_strip_t *strip) { led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); //Write zero to turn off all leds memset(spi_strip->pixel_buf, 0, spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); uint8_t *buf = spi_strip->pixel_buf; for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; index++) { __led_strip_spi_bit(0, buf); buf += SPI_BYTES_PER_COLOR_BYTE; } return led_strip_spi_refresh(strip); } static esp_err_t led_strip_spi_del(led_strip_t *strip) { led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, "delete spi device failed"); ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, "free spi bus failed"); free(spi_strip); return ESP_OK; } esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip) { led_strip_spi_obj *spi_strip = NULL; esp_err_t ret = ESP_OK; ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); uint8_t bytes_per_pixel = 3; if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { bytes_per_pixel = 4; } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { bytes_per_pixel = 3; } else { assert(false); } uint32_t mem_caps = MALLOC_CAP_DEFAULT; if (spi_config->flags.with_dma) { // DMA buffer must be placed in internal SRAM mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; } spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); spi_strip->spi_host = spi_config->spi_bus; // for backward compatibility, if the user does not set the clk_src, use the default value spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; if (spi_config->clk_src) { clk_src = spi_config->clk_src; } spi_bus_config_t spi_bus_cfg = { .mosi_io_num = led_config->strip_gpio_num, //Only use MOSI to generate the signal, set -1 when other pins are not used. .miso_io_num = -1, .sclk_io_num = -1, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, }; ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); if (led_config->flags.invert_out == true) { esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false); } spi_device_interface_config_t spi_dev_cfg = { .clock_source = clk_src, .command_bits = 0, .address_bits = 0, .dummy_bits = 0, .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, .mode = 0, //set -1 when CS is not used .spics_io_num = -1, .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, }; ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device"); int clock_resolution_khz = 0; spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION ESP_GOTO_ON_FALSE(clock_resolution_khz == LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000, ESP_ERR_NOT_SUPPORTED, err, TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); spi_strip->bytes_per_pixel = bytes_per_pixel; spi_strip->strip_len = led_config->max_leds; spi_strip->base.set_pixel = led_strip_spi_set_pixel; spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; spi_strip->base.refresh = led_strip_spi_refresh; spi_strip->base.clear = led_strip_spi_clear; spi_strip->base.del = led_strip_spi_del; *ret_strip = &spi_strip->base; return ESP_OK; err: if (spi_strip) { if (spi_strip->spi_device) { spi_bus_remove_device(spi_strip->spi_device); } if (spi_strip->spi_host) { spi_bus_free(spi_strip->spi_host); } free(spi_strip); } return ret; } ================================================ FILE: hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt ================================================ idf_build_get_property(target IDF_TARGET) include(CMakePrintHelpers) set(tusb_src ${CMAKE_CURRENT_LIST_DIR}/../../../../../src) get_filename_component(tusb_src ${tusb_src} ABSOLUTE) include(${tusb_src}/CMakeLists.txt) string(TOUPPER OPT_MCU_${target} tusb_mcu) set(compile_definitions CFG_TUSB_MCU=${tusb_mcu} CFG_TUSB_OS=OPT_OS_FREERTOS BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) if (target STREQUAL esp32p4) # P4 change alignment to 64 (DCache line size) for possible DMA configuration list(APPEND compile_definitions CFG_TUD_MEM_ALIGN=__attribute__\(\(aligned\(64\)\)\) CFG_TUH_MEM_ALIGN=__attribute__\(\(aligned\(64\)\)\) ) endif () tinyusb_sources_get(srcs) list(APPEND srcs ${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c ${tusb_src}/portable/synopsys/dwc2/hcd_dwc2.c ${tusb_src}/portable/synopsys/dwc2/dwc2_common.c ) # use max3421 as host controller if (MAX3421_HOST STREQUAL "1") list(APPEND srcs ${tusb_src}/portable/analog/max3421/hcd_max3421.c) list(APPEND compile_definitions CFG_TUH_MAX3421=1) endif () if (DEFINED LOG) list(APPEND compile_definitions CFG_TUSB_DEBUG=${LOG}) if (LOG STREQUAL "4") # no inline for debug level 4 list(APPEND compile_definitions TU_ATTR_ALWAYS_INLINE=) endif () endif() if(DEFINED CFLAGS_CLI) separate_arguments(CFLAGS_CLI) list(APPEND compile_definitions ${CFLAGS_CLI}) endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${tusb_src} REQUIRES src PRIV_REQUIRES esp_mm ) target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions}) ================================================ FILE: hw/bsp/espressif/family.cmake ================================================ # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Device port default to Port1 for P4 (highspeed), Port0 for others (fullspeed) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE) if (IDF_TARGET STREQUAL "esp32p4") set(RHPORT_DEVICE 1) else () set(RHPORT_DEVICE 0) endif () endif() if (NOT DEFINED RHPORT_HOST) if (IDF_TARGET STREQUAL "esp32p4") set(RHPORT_HOST 1) else () set(RHPORT_HOST 0) endif () endif() if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig) include($ENV{IDF_PATH}/tools/cmake/project.cmake) ================================================ FILE: hw/bsp/f1c100s/README.md ================================================ # BSP support for F1Cx00s boards This folder contains necessary file and scripts to run TinyUSB examples on F1Cx00s boards. Currently tested on: - Lichee Pi Nano (F1C100s) - [Widora Tiny200 v2 (also called MangoPi-R3c)](https://mangopi.org/tiny200) ## Flashing There are two options to put your code into the MCU: `flash` and `exec`. Both modes require you to install [xfel](https://github.com/xboot/xfel) tool to your PATH. You must enter FEL mode before any operation can be done. To enter FEL mode, press BOOT button, then press RESET once, and release BOOT button. You will find VID/PID=1f3a:efe8 on your PC. Exec: `make BOARD=f1c100s exec` will just upload the image to the DDR ram and execute it. It will not touch anything in the SPI flash. Flash: `make BOARD=f1c100s flash` will write the image to SPI flash, and then reset the chip to execute it. ## TODO * Add F1C100s to `#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX` high speed MCU check in examples (maybe we should extract the logic?) ================================================ FILE: hw/bsp/f1c100s/boards/f1c100s/board.cmake ================================================ function(update_board TARGET) # nothing to do endfunction() ================================================ FILE: hw/bsp/f1c100s/boards/f1c100s/board.h ================================================ /* metadata: name: Lctech Pi F1C200s url: https://linux-sunxi.org/Lctech_Pi_F1C200s */ #ifndef BOARD_H #define BOARD_H // Nothing valuable here #endif ================================================ FILE: hw/bsp/f1c100s/boards/f1c100s/board.mk ================================================ # nothing to do ================================================ FILE: hw/bsp/f1c100s/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Sunxi */ #include #include #include #include #include "bsp/board_api.h" #include "board.h" extern void sys_uart_putc(char c); //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ static void timer_init(void); void board_init(void) { arch_local_irq_disable(); do_init_mem_pool(); f1c100s_intc_init(); timer_init(); printf("Timer INIT done\n"); arch_local_irq_enable(); } // No LED, no button void board_led_write(bool state) { (void) state; } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { int txsize = len; while (txsize--) { sys_uart_putc(*(uint8_t const*) buf); buf++; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; uint32_t tusb_time_millis_api(void) { return system_ticks; } static void timer_handler(void) { volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04); /* clear timer */ *temp_addr |= 0x01; system_ticks++; } static void timer_init(void) { uint32_t temp; volatile uint32_t* temp_addr; /* reload value */ temp = 12000000 / 1000; temp_addr = (uint32_t*) (0x01C20C00 + 0x14); *temp_addr = temp; /* continuous | /2 | 24Mhz | reload*/ temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); temp_addr = (uint32_t*) (0x01C20C00 + 0x10); *temp_addr &= 0xffffff00; *temp_addr |= temp; /* open timer irq */ temp = 0x01 << 0; temp_addr = (uint32_t*) (0x01C20C00); *temp_addr |= temp; /* set init value */ temp_addr = (uint32_t*) (0x01C20C00 + 0x18); *temp_addr = 0; /* begin run timer */ temp = 0x01 << 0; temp_addr = (uint32_t*) (0x01C20C00 + 0x10); *temp_addr |= temp; f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); } #else static void timer_init(void) { } #endif ================================================ FILE: hw/bsp/f1c100s/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/allwinner/f1c100s) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU arm926ej-s CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS F1C100S CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/f1c100s.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/machine/start.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/lib/malloc.c ${SDK_DIR}/lib/printf.c ${SDK_DIR}/lib/memcpy.S ${SDK_DIR}/lib/memset.S ${SDK_DIR}/machine/sys-uart.c ${SDK_DIR}/machine/exception.c ${SDK_DIR}/machine/sys-clock.c ${SDK_DIR}/machine/sys-copyself.c ${SDK_DIR}/machine/sys-dram.c ${SDK_DIR}/machine/sys-mmu.c ${SDK_DIR}/machine/sys-spi-flash.c ${SDK_DIR}/machine/f1c100s-intc.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __ARM32_ARCH__=5 __ARM926EJS__ ) target_compile_options(${BOARD_TARGET} PUBLIC -ffreestanding -std=gnu99 -mno-thumb-interwork -Wno-float-equal -Wno-unused-parameter -Wno-error=array-bounds ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_F1C100S) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/sunxi/dcd_sunxi_musb.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_libraries(${TARGET} PUBLIC gcc ) target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" "LINKER:--defsym=__bss_end__=__bss_end" "LINKER:--defsym=__bss_start__=__bss_start" "LINKER:--defsym=end=__bss_end" --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/f1c100s/family.mk ================================================ SDK_DIR = hw/mcu/allwinner/f1c100s include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= arm926ej-s #CFLAGS += \ # -march=armv5te \ # -mtune=arm926ej-s \ # -mfloat-abi=soft \ # -marm \ CFLAGS += \ -ffreestanding \ -std=gnu99 \ -mno-thumb-interwork \ -D__ARM32_ARCH__=5 \ -D__ARM926EJS__ \ -Wno-float-equal \ -Wno-unused-parameter \ -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ -Wno-error=array-bounds \ LD_FILE = ${SDK_DIR}/f1c100s.ld # TODO may skip nanolib LDFLAGS += \ -nostdlib -lgcc \ --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/sunxi/dcd_sunxi_musb.c \ ${SDK_DIR}/machine/sys-uart.c \ ${SDK_DIR}/machine/exception.c \ ${SDK_DIR}/machine/sys-clock.c \ ${SDK_DIR}/machine/sys-copyself.c \ ${SDK_DIR}/machine/sys-dram.c \ ${SDK_DIR}/machine/sys-mmu.c \ ${SDK_DIR}/machine/sys-spi-flash.c \ ${SDK_DIR}/machine/f1c100s-intc.c \ ${SDK_DIR}/lib/malloc.c \ ${SDK_DIR}/lib/printf.c SRC_S += \ ${SDK_DIR}/machine/start.S \ ${SDK_DIR}/lib/memcpy.S \ ${SDK_DIR}/lib/memset.S INC += \ $(TOP)/${SDK_DIR}/include \ $(TOP)/$(BOARD_PATH) # flash target using xfel flash: flash-xfel exec: $(BUILD)/$(PROJECT).bin xfel ddr xfel write 0x80000000 $< xfel exec 0x80000000 ================================================ FILE: hw/bsp/family_rules.mk ================================================ # --------------------------------------- # Common make rules for all examples # --------------------------------------- # Set all as default goal .DEFAULT_GOAL := all # ---------------- GNU Make Start ----------------------- # ESP32-Sx and RP2040 has its own CMake build system ifeq (,$(findstring $(FAMILY),espressif rp2040)) # --------------------------------------- # Rules # --------------------------------------- all: $(BUILD)/$(PROJECT).bin $(BUILD)/$(PROJECT).hex size uf2: $(BUILD)/$(PROJECT).uf2 # We set vpath to point to the top of the tree so that the source files # can be located. By following this scheme, it allows a single build rule # to be used to compile all .c files. vpath %.c . $(TOP) vpath %.s . $(TOP) vpath %.S . $(TOP) include ${TOP}/examples/build_system/make/toolchain/$(TOOLCHAIN)_rules.mk # --------------------------------------- # Compiler Flags # --------------------------------------- CFLAGS += $(addprefix -I,$(INC)) # Verbose mode ifeq ("$(V)","1") $(info CFLAGS $(CFLAGS) ) $(info ) $(info LDFLAGS $(LDFLAGS)) $(info ) $(info ASFLAGS $(ASFLAGS)) $(info ) endif OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) $(OBJ_DIRS): ifeq ($(CMDEXE),1) -@$(MKDIR) $(subst /,\,$@) else @$(MKDIR) -p $@ endif # UF2 generation, iMXRT need to strip to text only before conversion ifneq ($(FAMILY),imxrt) $(BUILD)/$(PROJECT).uf2: $(BUILD)/$(PROJECT).hex @echo CREATE $@ $(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $^ endif copy-artifact: $(BUILD)/$(PROJECT).bin $(BUILD)/$(PROJECT).hex $(BUILD)/$(PROJECT).uf2 endif # ---------------- GNU Make End ----------------------- .PHONY: clean clean: ifeq ($(CMDEXE),1) rd /S /Q $(subst /,\,$(BUILD)) else $(RM) -rf $(BUILD) endif # get depenecies .PHONY: get-deps get-deps: $(PYTHON) $(TOP)/tools/get_deps.py ${FAMILY} .PHONY: size size: $(BUILD)/$(PROJECT).elf -@echo '' @$(SIZE) $< -@echo '' # linkermap must be install previously at https://github.com/hathach/linkermap linkermap: $(BUILD)/$(PROJECT).elf @linkermap -v $<.map # --------------------------------------- # Flash Targets # --------------------------------------- # --------------- Jlink ----------------- ifeq ($(OS),Windows_NT) JLINKEXE = JLink.exe else JLINKEXE = JLinkExe endif # Jlink Interface JLINK_IF ?= swd # Jlink script $(BUILD)/$(BOARD).jlink: $(BUILD)/$(PROJECT).hex @echo halt > $@ @echo loadfile $^ >> $@ @echo r >> $@ @echo go >> $@ @echo exit >> $@ # Flash using jlink flash-jlink: $(BUILD)/$(BOARD).jlink $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $< # --------------- stm32 cube programmer ----------------- # Flash STM32 MCU using stlink with STM32 Cube Programmer CLI flash-stlink: $(BUILD)/$(PROJECT).elf STM32_Programmer_CLI --connect port=swd --write $< --go # --------------- xfel ----------------- $(BUILD)/$(PROJECT)-sunxi.bin: $(BUILD)/$(PROJECT).bin $(PYTHON) $(TOP)/tools/mksunxi.py $< $@ flash-xfel: $(BUILD)/$(PROJECT)-sunxi.bin xfel spinor write 0 $< xfel reset # --------------- pyocd ----------------- PYOCD_OPTION ?= flash-pyocd: $(BUILD)/$(PROJECT).hex pyocd flash -t $(PYOCD_TARGET) $(PYOCD_OPTION) $< #pyocd reset -t $(PYOCD_TARGET) # --------------- openocd ----------------- OPENOCD_OPTION ?= flash-openocd: $(BUILD)/$(PROJECT).elf openocd $(OPENOCD_OPTION) -c "program $< verify reset exit" # --------------- openocd-wch ----------------- # wch-linke is not supported yet in official openOCD yet. We need to either use # 1. download openocd as part of mounriver studio http://www.mounriver.com/download or # 2. compiled from https://github.com/hathach/riscv-openocd-wch or # https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz # with ./configure --disable-werror --enable-wlinke --enable-ch347=no OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd OPENOCD_WCH_OPTION ?= flash-openocd-wch: $(BUILD)/$(PROJECT).elf $(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit # --------------- wlink-rs ----------------- # flash with https://github.com/ch32-rs/wlink WLINK_RS ?= wlink flash-wlink-rs: $(BUILD)/$(PROJECT).elf $(WLINK_RS) flash $< # --------------- dfu-util ----------------- DFU_UTIL_OPTION ?= -a 0 flash-dfu-util: $(BUILD)/$(PROJECT).bin dfu-util -R $(DFU_UTIL_OPTION) -D $< # --------------- Black Magic ----------------- # This symlink is created by https://github.com/blacksphere/blackmagic/blob/master/driver/99-blackmagic.rules BMP ?= /dev/ttyBmpGdb flash-bmp: $(BUILD)/$(PROJECT).elf $(GDB) --batch -ex 'target extended-remote $(BMP)' -ex 'monitor swdp_scan' -ex 'attach 1' -ex load $< debug-bmp: $(BUILD)/$(PROJECT).elf $(GDB) -ex 'target extended-remote $(BMP)' -ex 'monitor swdp_scan' -ex 'attach 1' $< # --------------- TI Uniflash ----------------- DSLITE ?= dslite.sh flash-uniflash: $(BUILD)/$(PROJECT).hex ${DSLITE} ${UNIFLASH_OPTION} -f $< # Print out the value of a make variable. # https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile print-%: @echo $* = $($*) ================================================ FILE: hw/bsp/family_support.cmake ================================================ include_guard(GLOBAL) include(CMakePrintHelpers) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #set(CMAKE_C_STANDARD 11) # TOP is path to root directory set(TOP "${CMAKE_CURRENT_LIST_DIR}/../..") get_filename_component(TOP ${TOP} ABSOLUTE) set(UF2CONV_PY ${TOP}/tools/uf2/utils/uf2conv.py) set(LINKERMAP_PY ${TOP}/tools/linkermap/linkermap.py) set(METRICS_PY ${TOP}/tools/metrics.py) function(family_resolve_board BOARD_NAME BOARD_PATH_OUT) if ("${BOARD_NAME}" STREQUAL "") message(FATAL_ERROR "You must set BOARD (e.g. metro_m4_express, raspberry_pi_pico). Use -DBOARD=xxx on the cmake command line.") endif() file(GLOB _board_paths LIST_DIRECTORIES true RELATIVE ${TOP}/hw/bsp ${TOP}/hw/bsp/*/boards/* ) set(_hint_names "") foreach(_board_path ${_board_paths}) get_filename_component(_board_name ${_board_path} NAME) if (_board_name STREQUAL "${BOARD_NAME}") set(${BOARD_PATH_OUT} ${_board_path} PARENT_SCOPE) return() endif() string(FIND "${_board_name}" "${BOARD_NAME}" _pos) if (_pos EQUAL 0) list(APPEND _hint_names ${_board_name}) endif() endforeach() if (_hint_names) list(REMOVE_DUPLICATES _hint_names) list(SORT _hint_names) list(JOIN _hint_names ", " _hint_str) message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found. Boards with the same prefix:\n${_hint_str}") else() message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found under hw/bsp/*/boards") endif() endfunction() #------------------------------------------------------------- # Toolchain # Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= or ENV{CC}= #------------------------------------------------------------- function(detect_compiler COMPILER_PATH RESULT) string(FIND ${COMPILER_PATH} "iccarm" IS_IAR) string(FIND ${COMPILER_PATH} "clang" IS_CLANG) string(FIND ${COMPILER_PATH} "gcc" IS_GCC) if (NOT IS_IAR EQUAL -1) set(${RESULT} iar PARENT_SCOPE) elseif (NOT IS_CLANG EQUAL -1) set(${RESULT} clang PARENT_SCOPE) elseif (NOT IS_GCC EQUAL -1) set(${RESULT} gcc PARENT_SCOPE) endif () endfunction() # Detect toolchain based on CMAKE_C_COMPILER or ENV{CC} if (DEFINED CMAKE_C_COMPILER) detect_compiler(${CMAKE_C_COMPILER} TOOLCHAIN) elseif (DEFINED ENV{CC}) detect_compiler($ENV{CC} TOOLCHAIN) endif () if (NOT DEFINED TOOLCHAIN) set(TOOLCHAIN gcc) endif () set(WARN_FLAGS_GNU -Wall -Wextra -Werror -Wfatal-errors -Wdouble-promotion -Wstrict-prototypes -Wstrict-overflow -Werror-implicit-function-declaration -Wfloat-equal -Wundef -Wshadow -Wwrite-strings -Wsign-compare -Wmissing-format-attribute -Wunreachable-code -Wcast-align -Wcast-function-type -Wcast-qual -Wnull-dereference -Wuninitialized -Wunused -Wunused-function -Wreturn-type -Wredundant-decls -Wmissing-prototypes # -Wconversion ) set(WARN_FLAGS_Clang ${WARN_FLAGS_GNU}) set(WARN_FLAGS_IAR --warnings_are_errors --diag_suppress=Pa089 --diag_suppress=Pe236 ) # Optimization if (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Build type" FORCE) endif () #------------------------------------------------------------- # FAMILY and BOARD #------------------------------------------------------------- if (NOT DEFINED FAMILY) family_resolve_board("${BOARD}" BOARD_PATH) string(REPLACE "/" ";" BOARD_PATH ${BOARD_PATH}) list(GET BOARD_PATH 0 FAMILY) set(FAMILY ${FAMILY} CACHE STRING "Board family") endif () if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake) message(FATAL_ERROR "Family '${FAMILY}' is not known/supported") endif() if (NOT FAMILY STREQUAL rp2040) # enable LTO if supported skip rp2040 include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED) cmake_print_variables(IPO_SUPPORTED) if (IPO_SUPPORTED) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) endif() endif() if (NOT NO_WARN_RWX_SEGMENTS_SUPPORTED) set(NO_WARN_RWX_SEGMENTS_SUPPORTED 1) endif() #---------------------------------- # RTOS #---------------------------------- if (NOT DEFINED RTOS) set(RTOS noos CACHE STRING "RTOS") endif () if (RTOS STREQUAL zephyr) set(BOARD_ROOT ${TOP}/hw/bsp/${FAMILY}) set(ZEPHYR_BOARD_ALIASES ${CMAKE_CURRENT_LIST_DIR}/zephyr_board_aliases.cmake) find_package(Zephyr REQUIRED HINTS ${TOP}/zephyr) list(REMOVE_ITEM WARN_FLAGS_GNU -Wredundant-decls -Wundef -Wcast-align ) endif () #------------------------------------------------------------- # Functions #------------------------------------------------------------- # Filter example based on only.txt and skip.txt function(family_filter RESULT DIR) get_filename_component(DIR ${DIR} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) if (EXISTS "${DIR}/skip.txt") file(STRINGS "${DIR}/skip.txt" SKIPS_LINES) foreach(MCU IN LISTS FAMILY_MCUS) # For each line in only.txt foreach(_line ${SKIPS_LINES}) # If mcu:xxx exists for this mcu then skip if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") set(${RESULT} 0 PARENT_SCOPE) return() endif() endforeach() endforeach() endif () if (EXISTS "${DIR}/only.txt") file(STRINGS "${DIR}/only.txt" ONLYS_LINES) foreach(MCU IN LISTS FAMILY_MCUS) # For each line in only.txt foreach(_line ${ONLYS_LINES}) # If mcu:xxx exists for this mcu or board:xxx then include if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") set(${RESULT} 1 PARENT_SCOPE) return() endif() endforeach() endforeach() # Didn't find it in only file so don't build set(${RESULT} 0 PARENT_SCOPE) else() # only.txt not exist so build set(${RESULT} 1 PARENT_SCOPE) endif() endfunction() function(family_add_subdirectory DIR) family_filter(SHOULD_ADD "${DIR}") if (SHOULD_ADD) add_subdirectory(${DIR}) endif() endfunction() function(family_initialize_project PROJECT DIR) # set output suffix to .elf (skip espressif and rp2040) if(NOT FAMILY STREQUAL "espressif" AND NOT FAMILY STREQUAL "rp2040") set(CMAKE_EXECUTABLE_SUFFIX .elf PARENT_SCOPE) endif() family_filter(ALLOWED "${DIR}") if (NOT ALLOWED) get_filename_component(SHORT_NAME ${DIR} NAME) message(FATAL_ERROR "${SHORT_NAME} is not supported on FAMILY=${FAMILY}") endif() endfunction() # Add bloaty (https://github.com/google/bloaty/) target, required compile with -g (debug) function(family_add_bloaty TARGET) find_program(BLOATY_EXE bloaty) if (BLOATY_EXE STREQUAL BLOATY_EXE-NOTFOUND) return() endif () set(OPTION "--domain=vm -d compileunits,sections,symbols") if (DEFINED BLOATY_OPTION) string(APPEND OPTION " ${BLOATY_OPTION}") endif () separate_arguments(OPTION_LIST UNIX_COMMAND ${OPTION}) add_custom_target(${TARGET}-bloaty DEPENDS ${TARGET} COMMAND ${BLOATY_EXE} ${OPTION_LIST} $ VERBATIM) set_property(TARGET ${TARGET}-bloaty PROPERTY FOLDER ${TARGET}-group) # post build # add_custom_command(TARGET ${TARGET} POST_BUILD # COMMAND ${BLOATY_EXE} --csv ${OPTION_LIST} $ > ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_bloaty.csv # VERBATIM # ) endfunction() # Add linkermap target (https://github.com/hathach/linkermap) function(family_add_linkermap TARGET) set(OPTION "-j") if (DEFINED LINKERMAP_OPTION) string(APPEND OPTION " ${LINKERMAP_OPTION}") endif () separate_arguments(OPTION_LIST UNIX_COMMAND ${OPTION}) add_custom_target(${TARGET}-linkermap COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $.map VERBATIM ) set_property(TARGET ${TARGET}-linkermap PROPERTY FOLDER ${TARGET}-group) # post build add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $.map VERBATIM) endfunction() # Add membrowse target (installed with pip install membrowse) function(family_add_membrowse TARGET) find_program(MEMBROWSE_EXE membrowse) if (MEMBROWSE_EXE STREQUAL MEMBROWSE_EXE-NOTFOUND) # force anyway, bash login shell will find it from pip install path set(MEMBROWSE_EXE membrowse) endif () set(OPTION "") if (DEFINED MEMBROWSE_OPTION) string(APPEND OPTION " ${MEMBROWSE_OPTION}") endif () # For Ninja generator, extract all linker scripts from Ninja commands (with INCLUDE) and pass them to membrowse. if (CMAKE_GENERATOR MATCHES "Ninja") set(TARGET_ELF_PATH "$/$") set(MEMBROWSE_LD_SCRIPTS_CMD "ld_scripts=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?:-Wl,--script=|-T\\s*)\\K[A-Za-z0-9_./-]+\\.ld' | xargs)\"; \ all_ld_scripts=\"\"; \ pending_ld_scripts=\"$ld_scripts\"; \ while [ -n \"$pending_ld_scripts\" ]; do \ next_pending=\"\"; \ for script in $pending_ld_scripts; do \ case \" $all_ld_scripts \" in *\" $script \"*) continue ;; esac; \ all_ld_scripts=\"$all_ld_scripts $script\"; \ script_dir=$(dirname \"$script\"); \ include_scripts=$(grep -hoP '^\\s*INCLUDE\\s+[<\"]?\\K[^\">[:space:]]+\\.ld' \"$script\" 2>/dev/null | xargs); \ for include_script in $include_scripts; do \ resolved_script=\"\"; \ if [ -f \"$include_script\" ]; then \ resolved_script=\"$include_script\"; \ elif [ -f \"$script_dir/$include_script\" ]; then \ resolved_script=\"$script_dir/$include_script\"; \ fi; \ if [ -n \"$resolved_script\" ]; then \ case \" $all_ld_scripts $next_pending \" in *\" $resolved_script \"*) ;; *) next_pending=\"$next_pending $resolved_script\" ;; esac; \ fi; \ done; \ done; \ pending_ld_scripts=\"$(echo \"$next_pending\" | xargs)\"; \ done; \ ld_scripts=\"$(echo \"$all_ld_scripts\" | xargs)\"") set(MEMBROWSE_LD_DEFS_CMD "ld_symbols=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?<=--defsym[=,])[^[:space:]]+' | xargs)\"; \ ld_defs=\"\"; \ for symbol in $ld_symbols; do \ ld_defs=\"$ld_defs --def $symbol\"; \ done; \ ld_defs=\"$(echo \"$ld_defs\" | xargs)\"") set(MEMBROWSE_PREPARE_CMD "if [ -f \"${TARGET_ELF_PATH}\" ]; then \ ${MEMBROWSE_LD_SCRIPTS_CMD}; \ ${MEMBROWSE_LD_DEFS_CMD}; \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs\"; \ fi; \ else \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical\"; \ fi; \ fi; \ echo \"$MEMBROWSE_CMD\"") add_custom_target(${TARGET}-membrowse DEPENDS ${TARGET} COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=0 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\"" VERBATIM ) set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET}-group) add_custom_target(${TARGET}-membrowse-upload COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=1 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\"" VERBATIM ) if (NOT TARGET examples-membrowse-upload) add_custom_target(examples-membrowse-upload) endif () add_dependencies(examples-membrowse-upload ${TARGET}-membrowse-upload) set_property(TARGET ${TARGET}-membrowse-upload PROPERTY FOLDER ${TARGET}-group) endif () endfunction() #------------------------------------------------------------- # Common Target Configure # Most families use these settings except rp2040 and espressif #------------------------------------------------------------- function(family_add_board BOARD_TARGET) # empty function, should be redefined in FAMILY/family.cmake endfunction() # Add RTOS to example function(family_add_rtos TARGET RTOS) if (RTOS STREQUAL "freertos") if (NOT TARGET freertos_config) add_library(freertos_config INTERFACE) target_include_directories(freertos_config INTERFACE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${FAMILY}/FreeRTOSConfig) # add board definition to freertos_config mostly for SystemCoreClock target_link_libraries(freertos_config INTERFACE board_${BOARD}) endif() if (NOT TARGET freertos_kernel) add_subdirectory(${TOP}/lib/FreeRTOS-Kernel ${CMAKE_BINARY_DIR}/lib/freertos_kernel) endif () target_link_libraries(${TARGET} PUBLIC freertos_kernel) target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_FREERTOS) elseif (RTOS STREQUAL "threadx") if (NOT TARGET threadx) # Derive THREADX_ARCH from CMAKE_SYSTEM_CPU if not explicitly set if (NOT DEFINED THREADX_ARCH) string(REPLACE "-" "_" THREADX_ARCH ${CMAKE_SYSTEM_CPU}) endif () # Derive THREADX_TOOLCHAIN from TOOLCHAIN if not explicitly set if (NOT DEFINED THREADX_TOOLCHAIN) if (TOOLCHAIN STREQUAL "iar") set(THREADX_TOOLCHAIN "iar") elseif (TOOLCHAIN STREQUAL "clang") set(THREADX_TOOLCHAIN "ac6") else () set(THREADX_TOOLCHAIN "gnu") endif () endif () add_subdirectory(${TOP}/lib/threadx ${CMAKE_BINARY_DIR}/lib/threadx) endif () target_link_libraries(${TARGET} PUBLIC threadx) target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_THREADX) elseif (RTOS STREQUAL "zephyr") target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_OS=OPT_OS_ZEPHYR) target_include_directories(${TARGET} PUBLIC ${ZEPHYR_BASE}/include) endif () endfunction() # Add common configuration to example function(family_configure_common TARGET RTOS) # Add board target set(BOARD_TARGET board_${BOARD}) if (NOT RTOS STREQUAL zephyr) if (NOT TARGET ${BOARD_TARGET}) family_add_board(${BOARD_TARGET}) set_target_properties(${BOARD_TARGET} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib SKIP_LINTING ON # need cmake 4.2 ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_target_properties(${BOARD_TARGET} PROPERTIES COMPILE_OPTIONS -w) endif () endif () target_link_libraries(${TARGET} PUBLIC ${BOARD_TARGET}) endif () family_add_rtos(${TARGET} ${RTOS}) # Add BOARD_${BOARD} define string(TOUPPER ${BOARD} BOARD_UPPER) string(REPLACE "-" "_" BOARD_UPPER ${BOARD_UPPER}) target_compile_definitions(${TARGET} PUBLIC BOARD_${BOARD_UPPER} ) # compile define from command line if(DEFINED CFLAGS_CLI) separate_arguments(CFLAGS_CLI) target_compile_options(${TARGET} PUBLIC ${CFLAGS_CLI}) endif() # ETM Trace option if (TRACE_ETM STREQUAL "1") target_compile_definitions(${TARGET} PUBLIC TRACE_ETM) endif () # LOGGER option if (DEFINED LOGGER) string(TOUPPER ${LOGGER} LOGGER) target_compile_definitions(${TARGET} PUBLIC LOGGER_${LOGGER}) # Add segger rtt to example if(LOGGER STREQUAL "RTT") target_sources(${TARGET} PUBLIC ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c) target_include_directories(${TARGET} PUBLIC ${TOP}/lib/SEGGER_RTT/RTT) # target_compile_definitions(${TARGET} PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) set_source_files_properties(${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c PROPERTIES SKIP_LINTING ON) endif () else () target_compile_definitions(${TARGET} PUBLIC LOGGER_UART) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PRIVATE ${WARN_FLAGS_${CMAKE_C_COMPILER_ID}}) target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND NO_WARN_RWX_SEGMENTS_SUPPORTED AND (NOT RTOS STREQUAL zephyr)) target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") endif () elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_compile_options(${TARGET} PRIVATE $<$,$>:${WARN_FLAGS_IAR}>) target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") if (IAR_CSTAT) # link time analysis with C-STAT add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_C_ICSTAT} --db=${CMAKE_BINARY_DIR}/cstat.db link_analyze -- ${CMAKE_LINKER} $ COMMAND_EXPAND_LISTS ) # generate C-STAT report add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/cstat_report COMMAND ireport --db=${CMAKE_BINARY_DIR}/cstat.db --full --project ${TARGET} --output ${CMAKE_CURRENT_BINARY_DIR}/cstat_report/index.html ) endif () endif () if (NOT RTOS STREQUAL zephyr) # Analyze size with bloaty and linkermap family_add_bloaty(${TARGET}) family_add_linkermap(${TARGET}) family_add_membrowse(${TARGET}) endif () # run size after build # find_program(SIZE_EXE ${CMAKE_SIZE}) # if(NOT ${SIZE_EXE} STREQUAL SIZE_EXE-NOTFOUND) # add_custom_command(TARGET ${TARGET} POST_BUILD # COMMAND ${SIZE_EXE} $ # ) # endif () endfunction() # Add tinyusb to target function(family_add_tinyusb TARGET OPT_MCU) # tinyusb's CMakeLists.txt include(${TOP}/src/CMakeLists.txt) # Add TinyUSB sources, include and common define tinyusb_target_add(${TARGET}) target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_MCU=${OPT_MCU}) if (DEFINED LOG) target_compile_definitions(${TARGET} PUBLIC CFG_TUSB_DEBUG=${LOG}) if (LOG STREQUAL "4") # no inline for debug level 4 target_compile_definitions(${TARGET} PUBLIC TU_ATTR_ALWAYS_INLINE=) endif () endif() # use max3421 as host controller if (MAX3421_HOST STREQUAL "1") target_compile_definitions(${TARGET} PUBLIC CFG_TUH_MAX3421=1) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/analog/max3421/hcd_max3421.c ) endif () endfunction() # Add bin/hex output function(family_add_bin_hex TARGET) if (CMAKE_C_COMPILER_ID STREQUAL "IAR") add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} --bin $ $/${TARGET}.bin COMMAND ${CMAKE_OBJCOPY} --ihex $ $/${TARGET}.hex VERBATIM) else() add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Obinary $ $/${TARGET}.bin COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/${TARGET}.hex VERBATIM) endif() endfunction() # Add uf2 output function(family_add_uf2 TARGET FAMILY_ID) set(BIN_FILE $/${TARGET}.hex) add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} -c -o $/${TARGET}.uf2 ${BIN_FILE} VERBATIM) endfunction() #------------------------------------------------------- # Example Target Configure (Default rule) # These function can be redefined in FAMILY/family.cmake #-------------------------------------------------------- function(family_configure_example TARGET RTOS) # empty function, should be redefined in FAMILY/family.cmake endfunction() # Configure device example with RTOS function(family_configure_device_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) endfunction() # Configure host example with RTOS function(family_configure_host_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) endfunction() # Configure host + device example with RTOS function(family_configure_dual_usb_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) endfunction() function(family_example_missing_dependency TARGET DEPENDENCY) message(WARNING "${DEPENDENCY} submodule needed by ${TARGET} not found, please run 'python tools/get_deps.py ${DEPENDENCY}' to fetch it") endfunction() #---------------------------------- # Flashing target #---------------------------------- # Add flash jlink target function(family_flash_jlink TARGET) if (NOT DEFINED JLINKEXE) if(CMAKE_HOST_WIN32) set(JLINKEXE JLink.exe) else() set(JLINKEXE JLinkExe) endif() endif () if (NOT DEFINED JLINK_IF) set(JLINK_IF swd) endif () if (NOT DEFINED JLINK_OPTION) set(JLINK_OPTION "") endif () separate_arguments(OPTION_LIST UNIX_COMMAND ${JLINK_OPTION}) if (RTOS STREQUAL zephyr) set(BINARY_TARGET zephyr_final) set(NAME_TARGET ${CMAKE_PROJECT_NAME}) else () set(BINARY_TARGET ${TARGET}) set(NAME_TARGET ${TARGET}) endif () file(GENERATE OUTPUT $/${BINARY_TARGET}.jlink CONTENT "halt loadfile $ r go exit" ) add_custom_target(${NAME_TARGET}-jlink DEPENDS ${BINARY_TARGET} COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${BINARY_TARGET}.jlink VERBATIM ) set_property(TARGET ${NAME_TARGET}-jlink PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash stlink target function(family_flash_stlink TARGET) if (NOT DEFINED STM32_PROGRAMMER_CLI) set(STM32_PROGRAMMER_CLI STM32_Programmer_CLI) endif () add_custom_target(${TARGET}-stlink DEPENDS ${TARGET} COMMAND ${STM32_PROGRAMMER_CLI} --connect port=swd --write $ --go ) set_property(TARGET ${TARGET}-stlink PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash st-flash target function(family_flash_stflash TARGET) if (NOT DEFINED ST_FLASH) set(ST_FLASH st-flash) endif () add_custom_target(${TARGET}-stflash DEPENDS ${TARGET} COMMAND ${ST_FLASH} write $/${TARGET}.bin 0x8000000 ) set_property(TARGET ${TARGET}-stflash PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash openocd target function(family_flash_openocd TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD openocd) endif () if (NOT DEFINED OPENOCD_OPTION2) set(OPENOCD_OPTION2 "") endif () if (DEFINED OPENOCD_SERIAL) set(OPENOCD_OPTION "-c \"adapter serial ${OPENOCD_SERIAL}\" ${OPENOCD_OPTION}") endif () separate_arguments(OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION}) separate_arguments(OPTION_LIST2 UNIX_COMMAND ${OPENOCD_OPTION2}) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} COMMAND ${OPENOCD} -c "tcl_port disabled; gdb_port disabled" ${OPTION_LIST} -c "init; halt; program $" -c reset ${OPTION_LIST2} -c exit VERBATIM ) set_property(TARGET ${TARGET}-openocd PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash openocd-wch target # compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz function(family_flash_openocd_wch TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) endif () family_flash_openocd(${TARGET}) endfunction() # Add flash openocd adi (Analog Devices) target # included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd function(family_flash_openocd_adi TARGET) if (DEFINED MAXIM_PATH) # use openocd from msdk with MAXIM_PATH cmake variable first if the user specified it set(OPENOCD ${MAXIM_PATH}/Tools/OpenOCD/openocd) set(OPENOCD_OPTION2 "-s ${MAXIM_PATH}/Tools/OpenOCD/scripts") elseif (DEFINED ENV{MAXIM_PATH}) # use openocd from msdk with MAXIM_PATH environment variable. Normalize # since msdk can be Windows (MinGW) or Linux file(TO_CMAKE_PATH "$ENV{MAXIM_PATH}" MAXIM_PATH_NORM) set(OPENOCD ${MAXIM_PATH_NORM}/Tools/OpenOCD/openocd) set(OPENOCD_OPTION2 "-s ${MAXIM_PATH_NORM}/Tools/OpenOCD/scripts") else() # compiled from source if (NOT DEFINED OPENOCD_ADI_PATH) set(OPENOCD_ADI_PATH $ENV{HOME}/app/openocd_adi) endif () set(OPENOCD ${OPENOCD_ADI_PATH}/src/openocd) set(OPENOCD_OPTION2 "-s ${OPENOCD_ADI_PATH}/tcl") endif () family_flash_openocd(${TARGET}) endfunction() # Add flash openocd-nuvoton target # compiled from https://github.com/OpenNuvoton/OpenOCD-Nuvoton function(family_flash_openocd_nuvoton TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD $ENV{HOME}/app/OpenOCD-Nuvoton/src/openocd) set(OPENOCD_OPTION2 "-s $ENV{HOME}/app/OpenOCD-Nuvoton/tcl") endif () family_flash_openocd(${TARGET}) endfunction() # Add flash with https://github.com/ch32-rs/wlink function(family_flash_wlink_rs TARGET) if (NOT DEFINED WLINK_RS) set(WLINK_RS wlink) endif () add_custom_target(${TARGET}-wlink-rs DEPENDS ${TARGET} COMMAND ${WLINK_RS} flash $ ) set_property(TARGET ${TARGET}-wlink-rs PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash pycod target function(family_flash_pyocd TARGET) if (NOT DEFINED PYOC) set(PYOCD pyocd) endif () add_custom_target(${TARGET}-pyocd DEPENDS ${TARGET} COMMAND ${PYOCD} flash -t ${PYOCD_TARGET} $ ) set_property(TARGET ${TARGET}-pyocd PROPERTY FOLDER ${TARGET}-group) endfunction() # Flash with UF2 function(family_flash_uf2 TARGET FAMILY_ID) add_custom_target(${TARGET}-uf2 DEPENDS ${TARGET} COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} --deploy $/${TARGET}.uf2 ) set_property(TARGET ${TARGET}-uf2 PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash teensy_cli target function(family_flash_teensy TARGET) if (NOT DEFINED TEENSY_CLI) set(TEENSY_CLI teensy_loader_cli) endif () add_custom_target(${TARGET}-teensy DEPENDS ${TARGET} COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/${TARGET}.hex COMMAND ${TEENSY_CLI} --mcu=${TEENSY_MCU} -w -s $/${TARGET}.hex ) set_property(TARGET ${TARGET}-teensy PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash using NXP's LinkServer (redserver) # https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER function(family_flash_nxplink TARGET) if (NOT DEFINED LINKSERVER) set(LINKSERVER LinkServer) endif () # LinkServer has a bug that can only execute with full path otherwise it throws: # realpath error: No such file or directory execute_process(COMMAND which ${LINKSERVER} OUTPUT_VARIABLE LINKSERVER_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) add_custom_target(${TARGET}-nxplink DEPENDS ${TARGET} COMMAND ${LINKSERVER_PATH} flash ${NXPLINK_DEVICE} load $ ) set_property(TARGET ${TARGET}-nxplink PROPERTY FOLDER ${TARGET}-group) endfunction() function(family_flash_dfu_util TARGET OPTION) if (NOT DEFINED DFU_UTIL) set(DFU_UTIL dfu-util) endif () add_custom_target(${TARGET}-dfu-util DEPENDS ${TARGET} COMMAND ${DFU_UTIL} -R -d ${DFU_UTIL_VID_PID} -a 0 -D $/${TARGET}.bin VERBATIM ) set_property(TARGET ${TARGET}-dfu-util PROPERTY FOLDER ${TARGET}-group) endfunction() function(family_flash_msp430flasher TARGET) if (NOT DEFINED MSP430Flasher) set(MSP430FLASHER MSP430Flasher) endif () # set LD_LIBRARY_PATH to find libmsp430.so (directory containing MSP430Flasher) find_program(MSP430FLASHER_PATH MSP430Flasher) get_filename_component(MSP430FLASHER_PARENT_DIR "${MSP430FLASHER_PATH}" DIRECTORY) add_custom_target(${TARGET}-msp430flasher DEPENDS ${TARGET} COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR} ${MSP430FLASHER} -w $/${TARGET}.hex -z [VCC] ) set_property(TARGET ${TARGET}-msp430flasher PROPERTY FOLDER ${TARGET}-group) endfunction() function(family_flash_rfp TARGET) if (NOT DEFINED RFP_CLI) set(RFP_CLI rfp-cli) endif () add_custom_target(${TARGET}-rfp DEPENDS ${TARGET} COMMAND ${CMAKE_OBJCOPY} -O srec -I elf32-rx-be-ns $ $/${TARGET}.mot COMMAND ${RFP_CLI} -device ${RFP_DEVICE} -tool ${RFP_TOOL} -if fine -fo id FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -auth id FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -auto $/${TARGET}.mot VERBATIM ) set_property(TARGET ${TARGET}-rfp PROPERTY FOLDER ${TARGET}-group) endfunction() function(family_flash_uniflash TARGET) if (NOT DEFINED DSLITE) set(DSLITE dslite.sh) endif () separate_arguments(OPTION_LIST UNIX_COMMAND ${UNIFLASH_OPTION}) add_custom_target(${TARGET}-uniflash DEPENDS ${TARGET} COMMAND ${DSLITE} ${UNIFLASH_OPTION} -f $/${TARGET}.hex VERBATIM ) set_property(TARGET ${TARGET}-uniflash PROPERTY FOLDER ${TARGET}-group) endfunction() # Add flash ft9xx target need to remove kernal's ftdi_sio and bind D2XX drivers # sudo rmmod ftdi_sio && for i in 0 1 2 3; do sudo sh -c "echo 3-3.4:1.$i > /sys/bus/usb/drivers/ftdi_sio/unbind" 2>/dev/null; done function(family_flash_ft9xx TARGET) if (NOT DEFINED FT9XXPROG) set(FT9XXPROG FT9xxProg) endif () add_custom_target(${TARGET}-ft9xx DEPENDS ${TARGET} COMMAND ${FT9XXPROG} -f $/${TARGET}.bin ) set_property(TARGET ${TARGET}-ft9xx PROPERTY FOLDER ${TARGET}-group) endfunction() #---------------------------------- # Family specific #---------------------------------- # family specific: can override above functions include(${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake) if (NOT FAMILY_MCUS) set(FAMILY_MCUS ${FAMILY}) endif() # if use max3421 as host controller, expand FAMILY_MCUS to include max3421 if (MAX3421_HOST STREQUAL "1") set(FAMILY_MCUS ${FAMILY_MCUS} MAX3421) endif () # save it in case of re-inclusion set(FAMILY_MCUS ${FAMILY_MCUS} CACHE INTERNAL "") ================================================ FILE: hw/bsp/family_support.mk ================================================ # --------------------------------------- # Common make definition for all examples # --------------------------------------- # upper helper function to_upper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$(subst -,_,$(1)))))))))))))))))))))))))))) #------------------------------------------------------------- # Toolchain # Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang #------------------------------------------------------------- ifneq (,$(findstring clang,$(CC))) TOOLCHAIN = clang else ifneq (,$(findstring iccarm,$(CC))) TOOLCHAIN = iar else ifneq (,$(findstring gcc,$(CC))) TOOLCHAIN = gcc endif # Default to GCC ifndef TOOLCHAIN TOOLCHAIN = gcc endif #-------------- TOP and EXAMPLE_PATH ------------ # Set TOP to be the path to get from the current directory (where make was invoked) to the top of the tree. # $(lastword $(MAKEFILE_LIST)) returns the name of this makefile relative to where make was invoked. THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) # Set TOP to an absolute path TOP = $(abspath $(subst family_support.mk,../..,$(THIS_MAKEFILE))) # Set EXAMPLE_PATH to the relative path from TOP to the current directory, ie examples/device/cdc_msc EXAMPLE_PATH = $(subst $(TOP)/,,$(abspath .)) #-------------- Linux/Windows ------------ # Detect whether shell style is windows or not # https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069 ifeq '$(findstring ;,$(PATH))' ';' # PATH contains semicolon - so we're definitely on Windows. CMDEXE := 1 # makefile shell commands should use syntax for DOS CMD, not unix sh # Force DOS command shell on Windows. SHELL := cmd.exe endif ifeq ($(CMDEXE),1) CP = copy RM = del MKDIR = mkdir PYTHON = python else CP = cp RM = rm MKDIR = mkdir PYTHON = python3 endif # Build directory BUILD := _build/$(BOARD) PROJECT := $(notdir $(CURDIR)) #------------------------------------------------------------- # Family and Board #------------------------------------------------------------- BOARD_PATH := $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/*/boards/$(BOARD))) FAMILY := $(word 3, $(subst /, ,$(BOARD_PATH))) FAMILY_PATH = hw/bsp/$(FAMILY) ifeq ($(BOARD_PATH),) $(info You must provide a BOARD parameter with 'BOARD=') $(error Invalid BOARD specified) endif # Include Family and Board specific defs include $(TOP)/$(FAMILY_PATH)/family.mk SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c)) #------------------------------------------------------------- # Source files and compiler flags #------------------------------------------------------------- # tinyusb makefile include $(TOP)/src/tinyusb.mk SRC_C += $(TINYUSB_SRC_C) # Include all source C in family & board folder SRC_C += hw/bsp/board.c SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(BOARD_PATH)/*.c)) INC += \ $(TOP)/$(FAMILY_PATH) \ $(TOP)/src \ $(TOP)/hw \ BOARD_UPPER = $(call to_upper,$(BOARD)) CFLAGS += -DBOARD_$(BOARD_UPPER) ifdef CFLAGS_CLI CFLAGS += $(CFLAGS_CLI) endif # use max3421 as host controller ifeq (${MAX3421_HOST},1) SRC_C += src/portable/analog/max3421/hcd_max3421.c CFLAGS += -DCFG_TUH_MAX3421=1 endif # Log level is mapped to TUSB DEBUG option ifneq ($(LOG),) CFLAGS += -DCFG_TUSB_DEBUG=$(LOG) endif # Logger: default is uart, can be set to rtt or swo ifeq ($(LOGGER),rtt) CFLAGS += -DLOGGER_RTT #CFLAGS += -DSEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL INC += $(TOP)/lib/SEGGER_RTT/RTT SRC_C += lib/SEGGER_RTT/RTT/SEGGER_RTT.c endif ifeq ($(LOGGER),swo) CFLAGS += -DLOGGER_SWO else CFLAGS += -DLOGGER_UART endif # CPU specific flags ifdef CPU_CORE include ${TOP}/examples/build_system/make/cpu/$(CPU_CORE).mk endif # toolchain specific - select based on CPU architecture ifdef CPU_CORE ifneq (,$(filter cortex% arm%,$(CPU_CORE))) # ARM/Cortex architecture include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk else ifneq (,$(filter rv%,$(CPU_CORE))) # RISC-V architecture include ${TOP}/examples/build_system/make/toolchain/riscv_$(TOOLCHAIN).mk else $(error Unsupported CPU_CORE architecture: $(CPU_CORE). Must start with cortex, arm, or rv) endif else # Default to ARM if CPU_CORE not specified include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk endif #---------------------- FreeRTOS ----------------------- FREERTOS_SRC = lib/FreeRTOS-Kernel FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) ifeq ($(RTOS),freertos) SRC_C += \ $(FREERTOS_SRC)/list.c \ $(FREERTOS_SRC)/queue.c \ $(FREERTOS_SRC)/tasks.c \ $(FREERTOS_SRC)/timers.c \ $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) SRC_S += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) INC += \ $(TOP)/hw/bsp/$(FAMILY)/FreeRTOSConfig \ $(TOP)/$(FREERTOS_SRC)/include \ $(TOP)/$(FREERTOS_PORTABLE_SRC) CFLAGS += -DCFG_TUSB_OS=OPT_OS_FREERTOS # Suppress FreeRTOSConfig.h warnings CFLAGS_GCC += -Wno-error=redundant-decls # Suppress FreeRTOS source warnings CFLAGS_GCC += -Wno-error=cast-qual # FreeRTOS (lto + Os) linker issue LDFLAGS_GCC += -Wl,--undefined=vTaskSwitchContext endif #---------------- Helper ---------------- check_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2))))) __check_defined = \ $(if $(value $1),, \ $(error Undefined make flag: $1$(if $2, ($2)))) ================================================ FILE: hw/bsp/fomu/boards/fomu/board.cmake ================================================ function(update_board TARGET) # target_compile_definitions(${TARGET} PUBLIC # ) endfunction() ================================================ FILE: hw/bsp/fomu/boards/fomu/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: fomu url: https://tomu.im/fomu.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Place holder only #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/fomu/boards/fomu/board.mk ================================================ # place holder ================================================ FILE: hw/bsp/fomu/crt0-vexriscv.S ================================================ .global main .global isr .section .text.start .global _start _start: j crt_init .section .text .global trap_entry trap_entry: sw x1, - 1*4(sp) sw x5, - 2*4(sp) sw x6, - 3*4(sp) sw x7, - 4*4(sp) sw x10, - 5*4(sp) sw x11, - 6*4(sp) sw x12, - 7*4(sp) sw x13, - 8*4(sp) sw x14, - 9*4(sp) sw x15, -10*4(sp) sw x16, -11*4(sp) sw x17, -12*4(sp) sw x28, -13*4(sp) sw x29, -14*4(sp) sw x30, -15*4(sp) sw x31, -16*4(sp) addi sp,sp,-16*4 call isr lw x1 , 15*4(sp) lw x5, 14*4(sp) lw x6, 13*4(sp) lw x7, 12*4(sp) lw x10, 11*4(sp) lw x11, 10*4(sp) lw x12, 9*4(sp) lw x13, 8*4(sp) lw x14, 7*4(sp) lw x15, 6*4(sp) lw x16, 5*4(sp) lw x17, 4*4(sp) lw x28, 3*4(sp) lw x29, 2*4(sp) lw x30, 1*4(sp) lw x31, 0*4(sp) addi sp,sp,16*4 mret .text crt_init: la sp, _estack - 4 la a0, trap_entry csrw mtvec, a0 bss_init: la a0, _sbss la a1, _ebss + 4 bss_loop: beq a0,a1,bss_done sw zero,0(a0) add a0,a0,4 j bss_loop bss_done: /* Load DATA */ la t0, _etext la t1, _srelocate la t2, _erelocate + 4 3: lw t3, 0(t0) sw t3, 0(t1) /* _edata is aligned to 4 bytes. Use word-xfers. */ addi t0, t0, 4 addi t1, t1, 4 bltu t1, t2, 3b li a0, 0x880 //880 enable timer + external interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt) csrw mie,a0 call main infinite_loop: j infinite_loop ================================================ FILE: hw/bsp/fomu/dfu.py ================================================ #!/usr/bin/env python3 # Written by Antonio Galea - 2010/11/18 # Updated for DFU 1.1 by Sean Cross - 2020/03/31 # Distributed under Gnu LGPL 3.0 # see http://www.gnu.org/licenses/lgpl-3.0.txt import sys,struct,zlib,os from optparse import OptionParser DEFAULT_DEVICE="0x1209:0x5bf0" def named(tuple,names): return dict(zip(names.split(),tuple)) def consume(fmt,data,names): n = struct.calcsize(fmt) return named(struct.unpack(fmt,data[:n]),names),data[n:] def cstring(string): return string.split('\0',1)[0] def compute_crc(data): return 0xFFFFFFFF & -zlib.crc32(data) -1 def parse(file,dump_images=False): print ('File: "%s"' % file) data = open(file,'rb').read() crc = compute_crc(data[:-4]) data = data[len(data)-16:] suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') print ('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix) if crc != suffix['crc']: print ("CRC ERROR: computed crc32 is 0x%08x" % crc) data = data[16:] if data: print ("PARSE ERROR") def build(file,data,device=DEFAULT_DEVICE): # Parse the VID and PID from the `device` argument v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) # Generate the DFU suffix, consisting of these fields: # Field name | Length | Description # ================+=========+================================ # bcdDevice | 2 | The release number of this firmware (0xffff - don't care) # idProduct | 2 | PID of this device # idVendor | 2 | VID of this device # bcdDFU | 2 | Version of this DFU spec (0x01 0x00) # ucDfuSignature | 3 | The characters 'DFU', printed in reverse order # bLength | 1 | The length of this suffix (16 bytes) # dwCRC | 4 | A CRC32 of the data, including this suffix data += struct.pack('<4H3sB',0xffff,d,v,0x0100,b'UFD',16) crc = compute_crc(data) # Append the CRC32 of the entire block data += struct.pack(' #include #include "csr.h" #include "irq.h" #include "bsp/board_api.h" //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void fomu_error(uint32_t line) { (void)line; TU_BREAKPOINT(); } volatile uint32_t system_ticks = 0; static void timer_init(void) { int t; timer0_en_write(0); t = CONFIG_CLOCK_FREQUENCY / 1000; // 1000 kHz tick timer0_reload_write(t); timer0_load_write(t); timer0_en_write(1); timer0_ev_enable_write(1); timer0_ev_pending_write(1); irq_setmask(irq_getmask() | (1 << TIMER0_INTERRUPT)); } void isr(void) { unsigned int irqs; irqs = irq_pending() & irq_getmask(); #if CFG_TUD_ENABLED if (irqs & (1 << USB_INTERRUPT)) { tud_int_handler(0); } #endif if (irqs & (1 << TIMER0_INTERRUPT)) { system_ticks++; timer0_ev_pending_write(1); } } void board_init(void) { irq_setmask(0); irq_setie(1); timer_init(); return; } void board_led_write(bool state) { rgb_ctrl_write(0xff); rgb_raw_write(state); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { int32_t offset = 0; uint8_t const* buf8 = (uint8_t const*) buf; for (offset = 0; offset < len; offset++) { if (!(messible_status_read() & CSR_MESSIBLE_STATUS_FULL_OFFSET)) { messible_in_write(buf8[offset]); } } return len; } #if CFG_TUSB_OS == OPT_OS_NONE uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/fomu/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU rv32i-ilp32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS VALENTYUSB_EPTRI CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/fomu.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/crt0-vexriscv.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} INTERFACE) target_include_directories(${BOARD_TARGET} INTERFACE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_VALENTYUSB_EPTRI) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/valentyusb/eptri/dcd_eptri.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) endfunction() ================================================ FILE: hw/bsp/fomu/family.mk ================================================ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE = riscv-none-elf- CPU_CORE ?= rv32i-ilp32 CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI LDFLAGS_GCC += \ -nostdlib \ --specs=nosys.specs --specs=nano.specs \ # All source paths should be relative to the top level. LD_FILE = $(FAMILY_PATH)/fomu.ld SRC_C += src/portable/valentyusb/eptri/dcd_eptri.c SRC_S += $(FAMILY_PATH)/crt0-vexriscv.S INC += \ $(TOP)/$(FAMILY_PATH)/include # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # flash using dfu-util $(BUILD)/$(PROJECT).dfu: $(BUILD)/$(PROJECT).bin @echo "Create $@" python $(TOP)/$(FAMILY_PATH)/dfu.py -b $^ -D 0x1209:0x5bf0 $@ flash: $(BUILD)/$(PROJECT).dfu dfu-util -D $^ ================================================ FILE: hw/bsp/fomu/fomu.ld ================================================ OUTPUT_FORMAT("elf32-littleriscv") ENTRY(_start) __DYNAMIC = 0; MEMORY { csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 ram : ORIGIN = 0x10000000, LENGTH = 0x00020000 rom : ORIGIN = 0x20040000, LENGTH = 0x00200000 - 0x40000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _ftext = .; *(.text.start) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) } > rom . = ALIGN(4); _etext = .; /* End of text section */ .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(.sbss .sbss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/fomu/include/csr.h ================================================ //-------------------------------------------------------------------------------- // Auto-generated by Migen (f4fcd10) & LiteX (1425a68d) on 2019-11-12 19:41:49 //-------------------------------------------------------------------------------- #ifndef __GENERATED_CSR_H #define __GENERATED_CSR_H #include #ifdef CSR_ACCESSORS_DEFINED extern void csr_writeb(uint8_t value, unsigned long addr); extern uint8_t csr_readb(unsigned long addr); extern void csr_writew(uint16_t value, unsigned long addr); extern uint16_t csr_readw(unsigned long addr); extern void csr_writel(uint32_t value, unsigned long addr); extern uint32_t csr_readl(unsigned long addr); #else /* ! CSR_ACCESSORS_DEFINED */ #include #endif /* ! CSR_ACCESSORS_DEFINED */ /* ctrl */ #define CSR_CTRL_BASE 0xe0000000L #define CSR_CTRL_RESET_ADDR 0xe0000000L #define CSR_CTRL_RESET_SIZE 1 static inline unsigned char ctrl_reset_read(void) { unsigned char r = csr_readl(0xe0000000L); return r; } static inline void ctrl_reset_write(unsigned char value) { csr_writel(value, 0xe0000000L); } #define CSR_CTRL_SCRATCH_ADDR 0xe0000004L #define CSR_CTRL_SCRATCH_SIZE 4 static inline unsigned int ctrl_scratch_read(void) { unsigned int r = csr_readl(0xe0000004L); r <<= 8; r |= csr_readl(0xe0000008L); r <<= 8; r |= csr_readl(0xe000000cL); r <<= 8; r |= csr_readl(0xe0000010L); return r; } static inline void ctrl_scratch_write(unsigned int value) { csr_writel(value >> 24, 0xe0000004L); csr_writel(value >> 16, 0xe0000008L); csr_writel(value >> 8, 0xe000000cL); csr_writel(value, 0xe0000010L); } #define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L #define CSR_CTRL_BUS_ERRORS_SIZE 4 static inline unsigned int ctrl_bus_errors_read(void) { unsigned int r = csr_readl(0xe0000014L); r <<= 8; r |= csr_readl(0xe0000018L); r <<= 8; r |= csr_readl(0xe000001cL); r <<= 8; r |= csr_readl(0xe0000020L); return r; } /* messible */ #define CSR_MESSIBLE_BASE 0xe0008000L #define CSR_MESSIBLE_IN_ADDR 0xe0008000L #define CSR_MESSIBLE_IN_SIZE 1 static inline unsigned char messible_in_read(void) { unsigned char r = csr_readl(0xe0008000L); return r; } static inline void messible_in_write(unsigned char value) { csr_writel(value, 0xe0008000L); } #define CSR_MESSIBLE_OUT_ADDR 0xe0008004L #define CSR_MESSIBLE_OUT_SIZE 1 static inline unsigned char messible_out_read(void) { unsigned char r = csr_readl(0xe0008004L); return r; } #define CSR_MESSIBLE_STATUS_ADDR 0xe0008008L #define CSR_MESSIBLE_STATUS_SIZE 1 static inline unsigned char messible_status_read(void) { unsigned char r = csr_readl(0xe0008008L); return r; } #define CSR_MESSIBLE_STATUS_FULL_OFFSET 0 #define CSR_MESSIBLE_STATUS_FULL_SIZE 1 #define CSR_MESSIBLE_STATUS_HAVE_OFFSET 1 #define CSR_MESSIBLE_STATUS_HAVE_SIZE 1 /* picorvspi */ #define CSR_PICORVSPI_BASE 0xe0005000L #define CSR_PICORVSPI_CFG1_ADDR 0xe0005000L #define CSR_PICORVSPI_CFG1_SIZE 1 static inline unsigned char picorvspi_cfg1_read(void) { unsigned char r = csr_readl(0xe0005000L); return r; } static inline void picorvspi_cfg1_write(unsigned char value) { csr_writel(value, 0xe0005000L); } #define CSR_PICORVSPI_CFG1_BB_OUT_OFFSET 0 #define CSR_PICORVSPI_CFG1_BB_OUT_SIZE 4 #define CSR_PICORVSPI_CFG1_BB_CLK_OFFSET 4 #define CSR_PICORVSPI_CFG1_BB_CLK_SIZE 1 #define CSR_PICORVSPI_CFG1_BB_CS_OFFSET 5 #define CSR_PICORVSPI_CFG1_BB_CS_SIZE 1 #define CSR_PICORVSPI_CFG2_ADDR 0xe0005004L #define CSR_PICORVSPI_CFG2_SIZE 1 static inline unsigned char picorvspi_cfg2_read(void) { unsigned char r = csr_readl(0xe0005004L); return r; } static inline void picorvspi_cfg2_write(unsigned char value) { csr_writel(value, 0xe0005004L); } #define CSR_PICORVSPI_CFG2_BB_OE_OFFSET 0 #define CSR_PICORVSPI_CFG2_BB_OE_SIZE 4 #define CSR_PICORVSPI_CFG3_ADDR 0xe0005008L #define CSR_PICORVSPI_CFG3_SIZE 1 static inline unsigned char picorvspi_cfg3_read(void) { unsigned char r = csr_readl(0xe0005008L); return r; } static inline void picorvspi_cfg3_write(unsigned char value) { csr_writel(value, 0xe0005008L); } #define CSR_PICORVSPI_CFG3_RLAT_OFFSET 0 #define CSR_PICORVSPI_CFG3_RLAT_SIZE 4 #define CSR_PICORVSPI_CFG3_CRM_OFFSET 4 #define CSR_PICORVSPI_CFG3_CRM_SIZE 1 #define CSR_PICORVSPI_CFG3_QSPI_OFFSET 5 #define CSR_PICORVSPI_CFG3_QSPI_SIZE 1 #define CSR_PICORVSPI_CFG3_DDR_OFFSET 6 #define CSR_PICORVSPI_CFG3_DDR_SIZE 1 #define CSR_PICORVSPI_CFG4_ADDR 0xe000500cL #define CSR_PICORVSPI_CFG4_SIZE 1 static inline unsigned char picorvspi_cfg4_read(void) { unsigned char r = csr_readl(0xe000500cL); return r; } static inline void picorvspi_cfg4_write(unsigned char value) { csr_writel(value, 0xe000500cL); } #define CSR_PICORVSPI_CFG4_MEMIO_OFFSET 7 #define CSR_PICORVSPI_CFG4_MEMIO_SIZE 1 #define CSR_PICORVSPI_STAT1_ADDR 0xe0005010L #define CSR_PICORVSPI_STAT1_SIZE 1 static inline unsigned char picorvspi_stat1_read(void) { unsigned char r = csr_readl(0xe0005010L); return r; } #define CSR_PICORVSPI_STAT1_BB_IN_OFFSET 0 #define CSR_PICORVSPI_STAT1_BB_IN_SIZE 4 #define CSR_PICORVSPI_STAT2_ADDR 0xe0005014L #define CSR_PICORVSPI_STAT2_SIZE 1 static inline unsigned char picorvspi_stat2_read(void) { unsigned char r = csr_readl(0xe0005014L); return r; } #define CSR_PICORVSPI_STAT3_ADDR 0xe0005018L #define CSR_PICORVSPI_STAT3_SIZE 1 static inline unsigned char picorvspi_stat3_read(void) { unsigned char r = csr_readl(0xe0005018L); return r; } #define CSR_PICORVSPI_STAT4_ADDR 0xe000501cL #define CSR_PICORVSPI_STAT4_SIZE 1 static inline unsigned char picorvspi_stat4_read(void) { unsigned char r = csr_readl(0xe000501cL); return r; } /* reboot */ #define CSR_REBOOT_BASE 0xe0006000L #define CSR_REBOOT_CTRL_ADDR 0xe0006000L #define CSR_REBOOT_CTRL_SIZE 1 static inline unsigned char reboot_ctrl_read(void) { unsigned char r = csr_readl(0xe0006000L); return r; } static inline void reboot_ctrl_write(unsigned char value) { csr_writel(value, 0xe0006000L); } #define CSR_REBOOT_CTRL_IMAGE_OFFSET 0 #define CSR_REBOOT_CTRL_IMAGE_SIZE 2 #define CSR_REBOOT_CTRL_KEY_OFFSET 2 #define CSR_REBOOT_CTRL_KEY_SIZE 6 #define CSR_REBOOT_ADDR_ADDR 0xe0006004L #define CSR_REBOOT_ADDR_SIZE 4 static inline unsigned int reboot_addr_read(void) { unsigned int r = csr_readl(0xe0006004L); r <<= 8; r |= csr_readl(0xe0006008L); r <<= 8; r |= csr_readl(0xe000600cL); r <<= 8; r |= csr_readl(0xe0006010L); return r; } static inline void reboot_addr_write(unsigned int value) { csr_writel(value >> 24, 0xe0006004L); csr_writel(value >> 16, 0xe0006008L); csr_writel(value >> 8, 0xe000600cL); csr_writel(value, 0xe0006010L); } /* rgb */ #define CSR_RGB_BASE 0xe0006800L #define CSR_RGB_DAT_ADDR 0xe0006800L #define CSR_RGB_DAT_SIZE 1 static inline unsigned char rgb_dat_read(void) { unsigned char r = csr_readl(0xe0006800L); return r; } static inline void rgb_dat_write(unsigned char value) { csr_writel(value, 0xe0006800L); } #define CSR_RGB_ADDR_ADDR 0xe0006804L #define CSR_RGB_ADDR_SIZE 1 static inline unsigned char rgb_addr_read(void) { unsigned char r = csr_readl(0xe0006804L); return r; } static inline void rgb_addr_write(unsigned char value) { csr_writel(value, 0xe0006804L); } #define CSR_RGB_CTRL_ADDR 0xe0006808L #define CSR_RGB_CTRL_SIZE 1 static inline unsigned char rgb_ctrl_read(void) { unsigned char r = csr_readl(0xe0006808L); return r; } static inline void rgb_ctrl_write(unsigned char value) { csr_writel(value, 0xe0006808L); } #define CSR_RGB_CTRL_EXE_OFFSET 0 #define CSR_RGB_CTRL_EXE_SIZE 1 #define CSR_RGB_CTRL_CURREN_OFFSET 1 #define CSR_RGB_CTRL_CURREN_SIZE 1 #define CSR_RGB_CTRL_RGBLEDEN_OFFSET 2 #define CSR_RGB_CTRL_RGBLEDEN_SIZE 1 #define CSR_RGB_CTRL_RRAW_OFFSET 3 #define CSR_RGB_CTRL_RRAW_SIZE 1 #define CSR_RGB_CTRL_GRAW_OFFSET 4 #define CSR_RGB_CTRL_GRAW_SIZE 1 #define CSR_RGB_CTRL_BRAW_OFFSET 5 #define CSR_RGB_CTRL_BRAW_SIZE 1 #define CSR_RGB_RAW_ADDR 0xe000680cL #define CSR_RGB_RAW_SIZE 1 static inline unsigned char rgb_raw_read(void) { unsigned char r = csr_readl(0xe000680cL); return r; } static inline void rgb_raw_write(unsigned char value) { csr_writel(value, 0xe000680cL); } #define CSR_RGB_RAW_R_OFFSET 0 #define CSR_RGB_RAW_R_SIZE 1 #define CSR_RGB_RAW_G_OFFSET 1 #define CSR_RGB_RAW_G_SIZE 1 #define CSR_RGB_RAW_B_OFFSET 2 #define CSR_RGB_RAW_B_SIZE 1 /* timer0 */ #define CSR_TIMER0_BASE 0xe0002800L #define CSR_TIMER0_LOAD_ADDR 0xe0002800L #define CSR_TIMER0_LOAD_SIZE 4 static inline unsigned int timer0_load_read(void) { unsigned int r = csr_readl(0xe0002800L); r <<= 8; r |= csr_readl(0xe0002804L); r <<= 8; r |= csr_readl(0xe0002808L); r <<= 8; r |= csr_readl(0xe000280cL); return r; } static inline void timer0_load_write(unsigned int value) { csr_writel(value >> 24, 0xe0002800L); csr_writel(value >> 16, 0xe0002804L); csr_writel(value >> 8, 0xe0002808L); csr_writel(value, 0xe000280cL); } #define CSR_TIMER0_RELOAD_ADDR 0xe0002810L #define CSR_TIMER0_RELOAD_SIZE 4 static inline unsigned int timer0_reload_read(void) { unsigned int r = csr_readl(0xe0002810L); r <<= 8; r |= csr_readl(0xe0002814L); r <<= 8; r |= csr_readl(0xe0002818L); r <<= 8; r |= csr_readl(0xe000281cL); return r; } static inline void timer0_reload_write(unsigned int value) { csr_writel(value >> 24, 0xe0002810L); csr_writel(value >> 16, 0xe0002814L); csr_writel(value >> 8, 0xe0002818L); csr_writel(value, 0xe000281cL); } #define CSR_TIMER0_EN_ADDR 0xe0002820L #define CSR_TIMER0_EN_SIZE 1 static inline unsigned char timer0_en_read(void) { unsigned char r = csr_readl(0xe0002820L); return r; } static inline void timer0_en_write(unsigned char value) { csr_writel(value, 0xe0002820L); } #define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L #define CSR_TIMER0_UPDATE_VALUE_SIZE 1 static inline unsigned char timer0_update_value_read(void) { unsigned char r = csr_readl(0xe0002824L); return r; } static inline void timer0_update_value_write(unsigned char value) { csr_writel(value, 0xe0002824L); } #define CSR_TIMER0_VALUE_ADDR 0xe0002828L #define CSR_TIMER0_VALUE_SIZE 4 static inline unsigned int timer0_value_read(void) { unsigned int r = csr_readl(0xe0002828L); r <<= 8; r |= csr_readl(0xe000282cL); r <<= 8; r |= csr_readl(0xe0002830L); r <<= 8; r |= csr_readl(0xe0002834L); return r; } #define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L #define CSR_TIMER0_EV_STATUS_SIZE 1 static inline unsigned char timer0_ev_status_read(void) { unsigned char r = csr_readl(0xe0002838L); return r; } static inline void timer0_ev_status_write(unsigned char value) { csr_writel(value, 0xe0002838L); } #define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL #define CSR_TIMER0_EV_PENDING_SIZE 1 static inline unsigned char timer0_ev_pending_read(void) { unsigned char r = csr_readl(0xe000283cL); return r; } static inline void timer0_ev_pending_write(unsigned char value) { csr_writel(value, 0xe000283cL); } #define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L #define CSR_TIMER0_EV_ENABLE_SIZE 1 static inline unsigned char timer0_ev_enable_read(void) { unsigned char r = csr_readl(0xe0002840L); return r; } static inline void timer0_ev_enable_write(unsigned char value) { csr_writel(value, 0xe0002840L); } /* touch */ #define CSR_TOUCH_BASE 0xe0005800L #define CSR_TOUCH_O_ADDR 0xe0005800L #define CSR_TOUCH_O_SIZE 1 static inline unsigned char touch_o_read(void) { unsigned char r = csr_readl(0xe0005800L); return r; } static inline void touch_o_write(unsigned char value) { csr_writel(value, 0xe0005800L); } #define CSR_TOUCH_O_O_OFFSET 0 #define CSR_TOUCH_O_O_SIZE 4 #define CSR_TOUCH_OE_ADDR 0xe0005804L #define CSR_TOUCH_OE_SIZE 1 static inline unsigned char touch_oe_read(void) { unsigned char r = csr_readl(0xe0005804L); return r; } static inline void touch_oe_write(unsigned char value) { csr_writel(value, 0xe0005804L); } #define CSR_TOUCH_OE_OE_OFFSET 0 #define CSR_TOUCH_OE_OE_SIZE 4 #define CSR_TOUCH_I_ADDR 0xe0005808L #define CSR_TOUCH_I_SIZE 1 static inline unsigned char touch_i_read(void) { unsigned char r = csr_readl(0xe0005808L); return r; } #define CSR_TOUCH_I_I_OFFSET 0 #define CSR_TOUCH_I_I_SIZE 4 /* usb */ #define CSR_USB_BASE 0xe0004800L #define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L #define CSR_USB_PULLUP_OUT_SIZE 1 static inline unsigned char usb_pullup_out_read(void) { unsigned char r = csr_readl(0xe0004800L); return r; } static inline void usb_pullup_out_write(unsigned char value) { csr_writel(value, 0xe0004800L); } #define CSR_USB_ADDRESS_ADDR 0xe0004804L #define CSR_USB_ADDRESS_SIZE 1 static inline unsigned char usb_address_read(void) { unsigned char r = csr_readl(0xe0004804L); return r; } static inline void usb_address_write(unsigned char value) { csr_writel(value, 0xe0004804L); } #define CSR_USB_ADDRESS_ADDR_OFFSET 0 #define CSR_USB_ADDRESS_ADDR_SIZE 7 #define CSR_USB_NEXT_EV_ADDR 0xe0004808L #define CSR_USB_NEXT_EV_SIZE 1 static inline unsigned char usb_next_ev_read(void) { unsigned char r = csr_readl(0xe0004808L); return r; } #define CSR_USB_NEXT_EV_IN_OFFSET 0 #define CSR_USB_NEXT_EV_IN_SIZE 1 #define CSR_USB_NEXT_EV_OUT_OFFSET 1 #define CSR_USB_NEXT_EV_OUT_SIZE 1 #define CSR_USB_NEXT_EV_SETUP_OFFSET 2 #define CSR_USB_NEXT_EV_SETUP_SIZE 1 #define CSR_USB_NEXT_EV_RESET_OFFSET 3 #define CSR_USB_NEXT_EV_RESET_SIZE 1 #define CSR_USB_SETUP_DATA_ADDR 0xe000480cL #define CSR_USB_SETUP_DATA_SIZE 1 static inline unsigned char usb_setup_data_read(void) { unsigned char r = csr_readl(0xe000480cL); return r; } #define CSR_USB_SETUP_DATA_DATA_OFFSET 0 #define CSR_USB_SETUP_DATA_DATA_SIZE 8 #define CSR_USB_SETUP_CTRL_ADDR 0xe0004810L #define CSR_USB_SETUP_CTRL_SIZE 1 static inline unsigned char usb_setup_ctrl_read(void) { unsigned char r = csr_readl(0xe0004810L); return r; } static inline void usb_setup_ctrl_write(unsigned char value) { csr_writel(value, 0xe0004810L); } #define CSR_USB_SETUP_CTRL_RESET_OFFSET 5 #define CSR_USB_SETUP_CTRL_RESET_SIZE 1 #define CSR_USB_SETUP_STATUS_ADDR 0xe0004814L #define CSR_USB_SETUP_STATUS_SIZE 1 static inline unsigned char usb_setup_status_read(void) { unsigned char r = csr_readl(0xe0004814L); return r; } #define CSR_USB_SETUP_STATUS_EPNO_OFFSET 0 #define CSR_USB_SETUP_STATUS_EPNO_SIZE 4 #define CSR_USB_SETUP_STATUS_HAVE_OFFSET 4 #define CSR_USB_SETUP_STATUS_HAVE_SIZE 1 #define CSR_USB_SETUP_STATUS_PEND_OFFSET 5 #define CSR_USB_SETUP_STATUS_PEND_SIZE 1 #define CSR_USB_SETUP_STATUS_IS_IN_OFFSET 6 #define CSR_USB_SETUP_STATUS_IS_IN_SIZE 1 #define CSR_USB_SETUP_STATUS_DATA_OFFSET 7 #define CSR_USB_SETUP_STATUS_DATA_SIZE 1 #define CSR_USB_SETUP_EV_STATUS_ADDR 0xe0004818L #define CSR_USB_SETUP_EV_STATUS_SIZE 1 static inline unsigned char usb_setup_ev_status_read(void) { unsigned char r = csr_readl(0xe0004818L); return r; } static inline void usb_setup_ev_status_write(unsigned char value) { csr_writel(value, 0xe0004818L); } #define CSR_USB_SETUP_EV_PENDING_ADDR 0xe000481cL #define CSR_USB_SETUP_EV_PENDING_SIZE 1 static inline unsigned char usb_setup_ev_pending_read(void) { unsigned char r = csr_readl(0xe000481cL); return r; } static inline void usb_setup_ev_pending_write(unsigned char value) { csr_writel(value, 0xe000481cL); } #define CSR_USB_SETUP_EV_ENABLE_ADDR 0xe0004820L #define CSR_USB_SETUP_EV_ENABLE_SIZE 1 static inline unsigned char usb_setup_ev_enable_read(void) { unsigned char r = csr_readl(0xe0004820L); return r; } static inline void usb_setup_ev_enable_write(unsigned char value) { csr_writel(value, 0xe0004820L); } #define CSR_USB_IN_DATA_ADDR 0xe0004824L #define CSR_USB_IN_DATA_SIZE 1 static inline unsigned char usb_in_data_read(void) { unsigned char r = csr_readl(0xe0004824L); return r; } static inline void usb_in_data_write(unsigned char value) { csr_writel(value, 0xe0004824L); } #define CSR_USB_IN_DATA_DATA_OFFSET 0 #define CSR_USB_IN_DATA_DATA_SIZE 8 #define CSR_USB_IN_CTRL_ADDR 0xe0004828L #define CSR_USB_IN_CTRL_SIZE 1 static inline unsigned char usb_in_ctrl_read(void) { unsigned char r = csr_readl(0xe0004828L); return r; } static inline void usb_in_ctrl_write(unsigned char value) { csr_writel(value, 0xe0004828L); } #define CSR_USB_IN_CTRL_EPNO_OFFSET 0 #define CSR_USB_IN_CTRL_EPNO_SIZE 4 #define CSR_USB_IN_CTRL_RESET_OFFSET 5 #define CSR_USB_IN_CTRL_RESET_SIZE 1 #define CSR_USB_IN_CTRL_STALL_OFFSET 6 #define CSR_USB_IN_CTRL_STALL_SIZE 1 #define CSR_USB_IN_STATUS_ADDR 0xe000482cL #define CSR_USB_IN_STATUS_SIZE 1 static inline unsigned char usb_in_status_read(void) { unsigned char r = csr_readl(0xe000482cL); return r; } #define CSR_USB_IN_STATUS_IDLE_OFFSET 0 #define CSR_USB_IN_STATUS_IDLE_SIZE 1 #define CSR_USB_IN_STATUS_HAVE_OFFSET 4 #define CSR_USB_IN_STATUS_HAVE_SIZE 1 #define CSR_USB_IN_STATUS_PEND_OFFSET 5 #define CSR_USB_IN_STATUS_PEND_SIZE 1 #define CSR_USB_IN_EV_STATUS_ADDR 0xe0004830L #define CSR_USB_IN_EV_STATUS_SIZE 1 static inline unsigned char usb_in_ev_status_read(void) { unsigned char r = csr_readl(0xe0004830L); return r; } static inline void usb_in_ev_status_write(unsigned char value) { csr_writel(value, 0xe0004830L); } #define CSR_USB_IN_EV_PENDING_ADDR 0xe0004834L #define CSR_USB_IN_EV_PENDING_SIZE 1 static inline unsigned char usb_in_ev_pending_read(void) { unsigned char r = csr_readl(0xe0004834L); return r; } static inline void usb_in_ev_pending_write(unsigned char value) { csr_writel(value, 0xe0004834L); } #define CSR_USB_IN_EV_ENABLE_ADDR 0xe0004838L #define CSR_USB_IN_EV_ENABLE_SIZE 1 static inline unsigned char usb_in_ev_enable_read(void) { unsigned char r = csr_readl(0xe0004838L); return r; } static inline void usb_in_ev_enable_write(unsigned char value) { csr_writel(value, 0xe0004838L); } #define CSR_USB_OUT_DATA_ADDR 0xe000483cL #define CSR_USB_OUT_DATA_SIZE 1 static inline unsigned char usb_out_data_read(void) { unsigned char r = csr_readl(0xe000483cL); return r; } #define CSR_USB_OUT_DATA_DATA_OFFSET 0 #define CSR_USB_OUT_DATA_DATA_SIZE 8 #define CSR_USB_OUT_CTRL_ADDR 0xe0004840L #define CSR_USB_OUT_CTRL_SIZE 1 static inline unsigned char usb_out_ctrl_read(void) { unsigned char r = csr_readl(0xe0004840L); return r; } static inline void usb_out_ctrl_write(unsigned char value) { csr_writel(value, 0xe0004840L); } #define CSR_USB_OUT_CTRL_EPNO_OFFSET 0 #define CSR_USB_OUT_CTRL_EPNO_SIZE 4 #define CSR_USB_OUT_CTRL_ENABLE_OFFSET 4 #define CSR_USB_OUT_CTRL_ENABLE_SIZE 1 #define CSR_USB_OUT_CTRL_RESET_OFFSET 5 #define CSR_USB_OUT_CTRL_RESET_SIZE 1 #define CSR_USB_OUT_CTRL_STALL_OFFSET 6 #define CSR_USB_OUT_CTRL_STALL_SIZE 1 #define CSR_USB_OUT_STATUS_ADDR 0xe0004844L #define CSR_USB_OUT_STATUS_SIZE 1 static inline unsigned char usb_out_status_read(void) { unsigned char r = csr_readl(0xe0004844L); return r; } #define CSR_USB_OUT_STATUS_EPNO_OFFSET 0 #define CSR_USB_OUT_STATUS_EPNO_SIZE 4 #define CSR_USB_OUT_STATUS_HAVE_OFFSET 4 #define CSR_USB_OUT_STATUS_HAVE_SIZE 1 #define CSR_USB_OUT_STATUS_PEND_OFFSET 5 #define CSR_USB_OUT_STATUS_PEND_SIZE 1 #define CSR_USB_OUT_EV_STATUS_ADDR 0xe0004848L #define CSR_USB_OUT_EV_STATUS_SIZE 1 static inline unsigned char usb_out_ev_status_read(void) { unsigned char r = csr_readl(0xe0004848L); return r; } static inline void usb_out_ev_status_write(unsigned char value) { csr_writel(value, 0xe0004848L); } #define CSR_USB_OUT_EV_PENDING_ADDR 0xe000484cL #define CSR_USB_OUT_EV_PENDING_SIZE 1 static inline unsigned char usb_out_ev_pending_read(void) { unsigned char r = csr_readl(0xe000484cL); return r; } static inline void usb_out_ev_pending_write(unsigned char value) { csr_writel(value, 0xe000484cL); } #define CSR_USB_OUT_EV_ENABLE_ADDR 0xe0004850L #define CSR_USB_OUT_EV_ENABLE_SIZE 1 static inline unsigned char usb_out_ev_enable_read(void) { unsigned char r = csr_readl(0xe0004850L); return r; } static inline void usb_out_ev_enable_write(unsigned char value) { csr_writel(value, 0xe0004850L); } #define CSR_USB_OUT_ENABLE_STATUS_ADDR 0xe0004854L #define CSR_USB_OUT_ENABLE_STATUS_SIZE 1 static inline unsigned char usb_out_enable_status_read(void) { unsigned char r = csr_readl(0xe0004854L); return r; } #define CSR_USB_OUT_STALL_STATUS_ADDR 0xe0004858L #define CSR_USB_OUT_STALL_STATUS_SIZE 1 static inline unsigned char usb_out_stall_status_read(void) { unsigned char r = csr_readl(0xe0004858L); return r; } /* version */ #define CSR_VERSION_BASE 0xe0007000L #define CSR_VERSION_MAJOR_ADDR 0xe0007000L #define CSR_VERSION_MAJOR_SIZE 1 static inline unsigned char version_major_read(void) { unsigned char r = csr_readl(0xe0007000L); return r; } #define CSR_VERSION_MINOR_ADDR 0xe0007004L #define CSR_VERSION_MINOR_SIZE 1 static inline unsigned char version_minor_read(void) { unsigned char r = csr_readl(0xe0007004L); return r; } #define CSR_VERSION_REVISION_ADDR 0xe0007008L #define CSR_VERSION_REVISION_SIZE 1 static inline unsigned char version_revision_read(void) { unsigned char r = csr_readl(0xe0007008L); return r; } #define CSR_VERSION_GITREV_ADDR 0xe000700cL #define CSR_VERSION_GITREV_SIZE 4 static inline unsigned int version_gitrev_read(void) { unsigned int r = csr_readl(0xe000700cL); r <<= 8; r |= csr_readl(0xe0007010L); r <<= 8; r |= csr_readl(0xe0007014L); r <<= 8; r |= csr_readl(0xe0007018L); return r; } #define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL #define CSR_VERSION_GITEXTRA_SIZE 2 static inline unsigned short int version_gitextra_read(void) { unsigned short int r = csr_readl(0xe000701cL); r <<= 8; r |= csr_readl(0xe0007020L); return r; } #define CSR_VERSION_DIRTY_ADDR 0xe0007024L #define CSR_VERSION_DIRTY_SIZE 1 static inline unsigned char version_dirty_read(void) { unsigned char r = csr_readl(0xe0007024L); return r; } #define CSR_VERSION_DIRTY_DIRTY_OFFSET 0 #define CSR_VERSION_DIRTY_DIRTY_SIZE 1 #define CSR_VERSION_MODEL_ADDR 0xe0007028L #define CSR_VERSION_MODEL_SIZE 1 static inline unsigned char version_model_read(void) { unsigned char r = csr_readl(0xe0007028L); return r; } #define CSR_VERSION_MODEL_MODEL_OFFSET 0 #define CSR_VERSION_MODEL_MODEL_SIZE 8 #define CSR_VERSION_SEED_ADDR 0xe000702cL #define CSR_VERSION_SEED_SIZE 4 static inline unsigned int version_seed_read(void) { unsigned int r = csr_readl(0xe000702cL); r <<= 8; r |= csr_readl(0xe0007030L); r <<= 8; r |= csr_readl(0xe0007034L); r <<= 8; r |= csr_readl(0xe0007038L); return r; } /* constants */ #define TIMER0_INTERRUPT 2 static inline int timer0_interrupt_read(void) { return 2; } #define USB_INTERRUPT 3 static inline int usb_interrupt_read(void) { return 3; } #define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870 static inline int config_bitstream_sync_header1_read(void) { return 2123999870; } #define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630 static inline int config_bitstream_sync_header2_read(void) { return 2125109630; } #define CONFIG_CLOCK_FREQUENCY 12000000 static inline int config_clock_frequency_read(void) { return 12000000; } #define CONFIG_CPU_RESET_ADDR 0 static inline int config_cpu_reset_addr_read(void) { return 0; } #define CONFIG_CPU_TYPE "VEXRISCV" static inline const char * config_cpu_type_read(void) { return "VEXRISCV"; } #define CONFIG_CPU_TYPE_VEXRISCV 1 static inline int config_cpu_type_vexriscv_read(void) { return 1; } #define CONFIG_CPU_VARIANT "MIN" static inline const char * config_cpu_variant_read(void) { return "MIN"; } #define CONFIG_CPU_VARIANT_MIN 1 static inline int config_cpu_variant_min_read(void) { return 1; } #define CONFIG_CSR_ALIGNMENT 32 static inline int config_csr_alignment_read(void) { return 32; } #define CONFIG_CSR_DATA_WIDTH 8 static inline int config_csr_data_width_read(void) { return 8; } #endif ================================================ FILE: hw/bsp/fomu/include/hw/common.h ================================================ #ifndef _HW_COMMON_H_ #define _HW_COMMON_H_ #include static inline void csr_writeb(uint8_t value, uint32_t addr) { *((volatile uint8_t *)addr) = value; } static inline uint8_t csr_readb(uint32_t addr) { return *(volatile uint8_t *)addr; } static inline void csr_writew(uint16_t value, uint32_t addr) { *((volatile uint16_t *)addr) = value; } static inline uint16_t csr_readw(uint32_t addr) { return *(volatile uint16_t *)addr; } static inline void csr_writel(uint32_t value, uint32_t addr) { *((volatile uint32_t *)addr) = value; } static inline uint32_t csr_readl(uint32_t addr) { return *(volatile uint32_t *)addr; } #endif /* _HW_COMMON_H_ */ ================================================ FILE: hw/bsp/fomu/include/irq.h ================================================ #ifndef __IRQ_H #define __IRQ_H #ifdef __cplusplus extern "C" { #endif #define CSR_MSTATUS_MIE 0x8 #define CSR_IRQ_MASK 0xBC0 #define CSR_IRQ_PENDING 0xFC0 #define CSR_DCACHE_INFO 0xCC0 #define csrr(reg) ({ unsigned long __tmp; \ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ __tmp; }) #define csrw(reg, val) ({ \ if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ else \ asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) #define csrs(reg, bit) ({ \ if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ else \ asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) #define csrc(reg, bit) ({ \ if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ else \ asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) static inline unsigned int irq_getie(void) { return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; } static inline void irq_setie(unsigned int ie) { if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); } static inline unsigned int irq_getmask(void) { unsigned int mask; asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); return mask; } static inline void irq_setmask(unsigned int mask) { asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); } static inline unsigned int irq_pending(void) { unsigned int pending; asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); return pending; } #ifdef __cplusplus } #endif #endif /* __IRQ_H */ ================================================ FILE: hw/bsp/fomu/output_format.ld ================================================ OUTPUT_FORMAT("elf32-littleriscv") ================================================ FILE: hw/bsp/fomu/regions.ld ================================================ MEMORY { csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 sram : ORIGIN = 0x10000000, LENGTH = 0x00020000 rom : ORIGIN = 0x00000000, LENGTH = 0x00002000 } ================================================ FILE: hw/bsp/ft9xx/boards/mm900evxb/board.cmake ================================================ function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __FT900__ ) endfunction() ================================================ FILE: hw/bsp/ft9xx/boards/mm900evxb/board.h ================================================ /* * The MIT License (MIT) * * Copyright 2021 Bridgetek Pte Ltd * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MM900EVxB url: https://brtchip.com/product/mm900ev1b */ #ifndef BOARD_H_ #define BOARD_H_ // Note: This definition file covers all MM900EV1B, MM900EV2B, MM900EV3B, // MM900EV-Lite boards. // Each of these boards has an FT900 device. #ifdef __cplusplus extern "C" { #endif // UART to use on this board. #ifndef BOARD_UART #define BOARD_UART UART0 #endif // UART is on connector CN1. #ifndef BOARD_GPIO_UART0_TX #define BOARD_GPIO_UART0_TX 48 // Pin 4 of CN1. #endif #ifndef BOARD_GPIO_UART0_RX #define BOARD_GPIO_UART0_RX 49 // Pin 6 of CN1. #endif // LED is connected to pins 17 (signal) and 15 (GND) of CN1. #ifndef BOARD_GPIO_LED #define BOARD_GPIO_LED 35 #endif #ifndef BOARD_GPIO_LED_STATE_ON #define BOARD_GPIO_LED_STATE_ON 1 #endif // Button is connected to pins 13 (signal) and 15 (GND) of CN1. #ifndef BOARD_GPIO_BUTTON #define BOARD_GPIO_BUTTON 56 #endif // Button is pulled up and grounded for active. #ifndef BOARD_GPIO_BUTTON_STATE_ACTIVE #define BOARD_GPIO_BUTTON_STATE_ACTIVE 0 #endif // Enable the Remote Wakeup signalling. // Remote wakeup is wired to pin 40 of CN1. #ifndef BOARD_GPIO_REMOTE_WAKEUP #define BOARD_GPIO_REMOTE_WAKEUP 18 #endif // USB VBus signal is connected directly to the FT900. #ifndef BOARD_USBD_VBUS_DTC_PIN #define BOARD_USBD_VBUS_DTC_PIN 3 #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ft9xx/boards/mm900evxb/board.mk ================================================ CFLAGS += -D__FT900__ ================================================ FILE: hw/bsp/ft9xx/family.c ================================================ /* * The MIT License (MIT) * * Copyright 2021 Bridgetek Pte Ltd * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Bridgetek */ #include "bsp/board_api.h" #include "board.h" #include #include #if CFG_TUD_ENABLED int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detection for USB device. extern void ft9xx_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management #endif #ifdef BOARD_GPIO_REMOTE_WAKEUP void gpio_ISR(void); #endif void timer_ISR(void); volatile unsigned int timer_ms = 0; void board_pm_ISR(void); #define WELCOME_MSG "\x1B[2J\x1B[H" \ "MM900EVxB board\r\n" // Initialize on-board peripherals : led, button, uart and USB void board_init(void) { sys_reset_all(); // Enable the UART Device. sys_enable(sys_device_uart0); // Set BOARD_UART GPIO function pins for TXD and RXD. #ifdef BOARD_GPIO_UART_TX gpio_function(BOARD_GPIO_UART_TX, pad_uart0_txd); /* UART0 TXD */ #endif #ifdef BOARD_GPIO_UART_RX gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */ #endif uart_open(BOARD_UART, /* Device */ 1, /* Prescaler = 1 */ UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ uart_data_bits_8, /* No. Data Bits */ uart_parity_none, /* Parity */ uart_stop_bits_1); /* No. Stop Bits */ // Print out a welcome message. // Use sizeof to avoid pulling in strlen unnecessarily. board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); #ifdef BOARD_GPIO_LED gpio_function(BOARD_GPIO_LED, pad_func_0); gpio_idrive(BOARD_GPIO_LED, pad_drive_12mA); gpio_dir(BOARD_GPIO_LED, pad_dir_output); #endif #ifdef BOARD_GPIO_BUTTON gpio_function(BOARD_GPIO_BUTTON, pad_func_0); // Pull up if active low. Down if active high. gpio_pull(BOARD_GPIO_BUTTON, (BOARD_GPIO_BUTTON_STATE_ACTIVE == 0)?pad_pull_pullup:pad_pull_pulldown); gpio_dir(BOARD_GPIO_BUTTON, pad_dir_input); #endif sys_enable(sys_device_timer_wdt); /* Timer A = 1ms */ timer_prescaler(timer_select_a, 1000); timer_init(timer_select_a, 100, timer_direction_down, timer_prescaler_select_on, timer_mode_continuous); timer_enable_interrupt(timer_select_a); timer_start(timer_select_a); interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); // Setup VBUS detect GPIO. If the device is connected then this // will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG. gpio_interrupt_disable(BOARD_USBD_VBUS_DTC_PIN); gpio_function(BOARD_USBD_VBUS_DTC_PIN, pad_vbus_dtc); gpio_pull(BOARD_USBD_VBUS_DTC_PIN, pad_pull_pulldown); gpio_dir(BOARD_USBD_VBUS_DTC_PIN, pad_dir_input); interrupt_attach(interrupt_0, (int8_t)interrupt_0, board_pm_ISR); #ifdef BOARD_GPIO_REMOTE_WAKEUP // Configuring GPIO pin to wakeup. // Set up the wakeup pin. gpio_dir(BOARD_GPIO_REMOTE_WAKEUP, pad_dir_input); gpio_pull(BOARD_GPIO_REMOTE_WAKEUP, pad_pull_pullup); // Attach an interrupt handler. interrupt_attach(interrupt_gpio, (uint8_t)interrupt_gpio, gpio_ISR); gpio_interrupt_enable(BOARD_GPIO_REMOTE_WAKEUP, gpio_int_edge_falling); #endif uart_disable_interrupt(BOARD_UART, uart_interrupt_tx); uart_disable_interrupt(BOARD_UART, uart_interrupt_rx); // Enable all peripheral interrupts. interrupt_enable_globally(); TU_LOG1("MM900EV1B board setup complete\r\n"); }; void timer_ISR(void) { if (timer_is_interrupted(timer_select_a)) { timer_ms++; } } #ifdef BOARD_GPIO_REMOTE_WAKEUP void gpio_ISR(void) { if (gpio_is_interrupted(BOARD_GPIO_REMOTE_WAKEUP)) { } } #endif /* Power management ISR */ void board_pm_ISR(void) { uint16_t pmcfg = SYS->PMCFG_H; #if defined(__FT930__) if (pmcfg & MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND) { // Clear d2xx hw engine wakeup. SYS->PMCFG_H = MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND; } #endif if (pmcfg & MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND) { // Clear GPIO wakeup pending. SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; } #if defined(__FT900__) // USB device power management interrupts. if (pmcfg & (MASK_SYS_PMCFG_DEV_CONN_DEV | MASK_SYS_PMCFG_DEV_DIS_DEV | MASK_SYS_PMCFG_HOST_RST_DEV | MASK_SYS_PMCFG_HOST_RESUME_DEV) ) { #if CFG_TUD_ENABLED ft9xx_usbd_pm_ISR(pmcfg); #endif } #endif } #if CFG_TUD_ENABLED int8_t board_ft9xx_vbus(void) { return gpio_read(BOARD_USBD_VBUS_DTC_PIN); } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ // Turn LED on or off void board_led_write(bool state) { #ifdef BOARD_GPIO_LED gpio_write(BOARD_GPIO_LED, (state == 0)?(BOARD_GPIO_LED_STATE_ON?0:1):BOARD_GPIO_LED_STATE_ON); #endif } // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void) { uint32_t state = 0; #ifdef BOARD_GPIO_BUTTON state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0; #endif return state; } // Get characters from UART int board_uart_read(uint8_t *buf, int len) { int r = 0; #ifdef BOARD_UART if (uart_rx_has_data(BOARD_UART)) { r = uart_readn(BOARD_UART, (uint8_t *)buf, len); } #endif return r; } // Send characters to UART int board_uart_write(void const *buf, int len) { int r = 0; #ifdef BOARD_UART #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" // uart_writen does not have const for buffer parameter. r = uart_writen(BOARD_UART, (uint8_t *)((const void *)buf), len); #pragma GCC diagnostic pop #endif return r; } // Get current milliseconds uint32_t tusb_time_millis_api(void) { uint32_t safe_ms; CRITICAL_SECTION_BEGIN safe_ms = timer_ms; CRITICAL_SECTION_END return safe_ms; } // Restart the program // Called in the event of a watchdog timeout void chip_reboot(void) { // SOFT reset __asm__("call 0"); #if 0 // HARD reset // Initiates data transfer from Flash Memory to Data Memory (DBG_CMDF2D3) // followed by a system reboot dbg_memory_copy(0xfe, 0, 0, 255); #endif } ================================================ FILE: hw/bsp/ft9xx/family.cmake ================================================ include_guard() set(FT9XX_SDK ${TOP}/hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU ft32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/ft32_${TOOLCHAIN}.cmake) set(FAMILY_MCUS FT90X CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${FT9XX_SDK}/src/sys.c ${FT9XX_SDK}/src/interrupt.c ${FT9XX_SDK}/src/delay.c ${FT9XX_SDK}/src/timers.c ${FT9XX_SDK}/src/uart_simple.c ${FT9XX_SDK}/src/gpio.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${FT9XX_SDK}/include ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED ) target_compile_options(${BOARD_TARGET} PUBLIC -fmessage-length=0 ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_FT90X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/bridgetek/ft9xx/dcd_ft9xx.c ${FT9XX_SDK}/src/bootstrap.c ) set_source_files_properties(${FT9XX_SDK}/src/bootstrap.c PROPERTIES COMPILE_OPTIONS "-w") target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) target_compile_options(${TARGET} PUBLIC -Wno-error=shadow ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${TOP}/hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld" "LINKER:--entry=_start" ) endif () # Flashing family_add_bin_hex(${TARGET}) family_flash_ft9xx(${TARGET}) endfunction() ================================================ FILE: hw/bsp/ft9xx/family.mk ================================================ # GCC prefix for FT90X compile tools. CROSS_COMPILE = ft32-elf- SKIP_NANOLIB = 1 # Set to use FT90X prebuilt libraries. FT9XX_PREBUILT_LIBS = 0 ifeq ($(FT9XX_PREBUILT_LIBS),1) # If the FT90X toolchain is installed on Windows systems then the SDK # include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware INC += "$(FT9XX_SDK)/include" else # The submodule BRTSG-FOSS/ft90x-sdk contains header files and source # code for the Bridgetek SDK. This can be used instead of the prebuilt # library. # The SDK can be used to load specific files from the Bridgetek SDK. FT9XX_SDK = hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source INC += "$(TOP)/$(FT9XX_SDK)/include" endif include $(TOP)/$(BOARD_PATH)/board.mk # Add include files which are within the TinyUSB directory structure. INC += \ $(TOP)/$(BOARD_PATH) # Add required C Compiler flags for FT9XX. CFLAGS += \ -fvar-tracking \ -fvar-tracking-assignments \ -fmessage-length=0 \ -ffunction-sections \ -DCFG_TUSB_MCU=OPT_MCU_FT90X # Maximum USB device speed supported by the board CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration CFLAGS += -Wno-error=shadow # Set Linker flags. LD_FILE = hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld LDFLAGS += $(addprefix -L,$(LDINC)) \ -Xlinker --entry=_start \ -Wl,-lc # Additional Source files for FT90X. SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c # Linker library. ifneq ($(FT9XX_PREBUILT_LIBS),1) # Optionally add in files from the Bridgetek SDK instead of the prebuilt # library. These are the minimum required. SRC_C += $(FT9XX_SDK)/src/bootstrap.c SRC_C += $(FT9XX_SDK)/src/sys.c SRC_C += $(FT9XX_SDK)/src/interrupt.c SRC_C += $(FT9XX_SDK)/src/delay.c SRC_C += $(FT9XX_SDK)/src/timers.c SRC_C += $(FT9XX_SDK)/src/uart_simple.c SRC_C += $(FT9XX_SDK)/src/gpio.c else # Or if using the prebuilt libraries add them. LDFLAGS += -L"$(FT9XX_SDK)/lib" LIBS += -lft900 endif # Not required crt0 file for FT90X. Use compiler built-in file. #SRC_S += hw/mcu/bridgetek/ft9xx/scripts/crt0.S # Flash using FT9xxProg, need to remove kernal's ftdi_sio and bind D2XX drivers # sudo rmmod ftdi_sio && for i in 0 1 2 3; do sudo sh -c "echo 3-3.4:1.$i > /sys/bus/usb/drivers/ftdi_sio/unbind" 2>/dev/null; done FT9XXPROG ?= FT9xxProg flash: flash-ft9xx flash-ft9xx: $(BUILD)/$(PROJECT).bin $(FT9XXPROG) -f $< ================================================ FILE: hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake ================================================ set(JLINK_DEVICE gd32vf103cbt6) set(SDK_BSP_DIR ${SOC_DIR}/Board/gd32vf103c_longan_nano) set(LD_FILE_GNU ${SDK_BSP_DIR}/Source/GCC/gcc_gd32vf103xb_flashxip.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${SDK_BSP_DIR}/Source/gd32vf103c_longan_nano.c ) target_include_directories(${TARGET} PUBLIC ${SDK_BSP_DIR}/Include ) endfunction() ================================================ FILE: hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.h ================================================ /* metadata: name: Sipeed Longan Nano url: https://longan.sipeed.com/en/ */ #ifndef _NUCLEI_SDK_HAL_H #define _NUCLEI_SDK_HAL_H #include "gd32vf103c_longan_nano.h" // 4 bits for interrupt level, 0 for priority. // level 0 = lowest priority, level 15 = highest priority. #define __ECLIC_INTCTLBITS 4 #define __SYSTEM_CLOCK 72000000 #define HXTAL_VALUE ((uint32_t)8000000) #define SOC_DEBUG_UART GD32_COM0 #define DBG_KEY_UNLOCK 0x4B5A6978 #define DBG_CMD_RESET 0x1 #define DBG_KEY REG32(DBG + 0x0C) #define DBG_CMD REG32(DBG + 0x08) #endif ================================================ FILE: hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk ================================================ LONGAN_NANO_SDK_BSP = $(GD32VF103_SDK_SOC)/Board/gd32vf103c_longan_nano LINKER_SCRIPTS = $(LONGAN_NANO_SDK_BSP)/Source/GCC # All source paths should be relative to the top level. LD_FILE = $(LINKER_SCRIPTS)/gcc_gd32vf103xb_flashxip.ld # Longan Nano 128k ROM 32k RAM #LD_FILE = $(LINKER_SCRIPTS)/gcc_gd32vf103x8_flashxip.ld # Longan Nano Lite 64k ROM 20k RAM SRC_C += $(LONGAN_NANO_SDK_BSP)/Source/gd32vf103c_longan_nano.c INC += $(TOP)/$(LONGAN_NANO_SDK_BSP)/Include # Longan Nano 128k ROM 32k RAM JLINK_DEVICE = gd32vf103cbt6 ================================================ FILE: hw/bsp/gd32vf103/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: GigaDevice */ #include "drv_usb_hw.h" #include "drv_usb_dev.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBFS_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #define USB_NO_VBUS_PIN // According to GD32VF103 user manual clock tree: // Systick clock = AHB clock / 4. #define TIMER_TICKS ((SystemCoreClock / 4) / 1000) #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV SOC_DEBUG_UART #define LED_PIN LED_R void board_init(void) { /* Disable interrupts during init */ __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(TIMER_TICKS); #endif rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_GPIOC); rcu_periph_clock_enable(RCU_GPIOD); rcu_periph_clock_enable(RCU_AF); #ifdef BUTTON_PIN gpio_init(BUTTON_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, BUTTON_PIN); #endif #ifdef LED_PIN gd_led_init(LED_PIN); #endif #if defined(UART_DEV) gd_com_init(UART_DEV); #endif /* USB D+ and D- pins don't need to be configured. */ /* Configure VBUS Pin */ #ifndef USB_NO_VBUS_PIN gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_9); #endif /* This for ID line debug */ // gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10); /* Enable USB OTG clock */ usb_rcu_config(); /* Reset USB OTG peripheral */ rcu_periph_reset_enable(RCU_USBFSRST); rcu_periph_reset_disable(RCU_USBFSRST); /* Configure USBFS IRQ */ ECLIC_Register_IRQ(USBFS_IRQn, ECLIC_NON_VECTOR_INTERRUPT, ECLIC_POSTIVE_EDGE_TRIGGER, 3, 0, NULL); /* Retrieve otg core registers */ usb_gr* otg_core_regs = (usb_gr*)(USBFS_REG_BASE + USB_REG_OFFSET_CORE); #ifdef USB_NO_VBUS_PIN /* Disable VBUS sense*/ otg_core_regs->GCCFG |= GCCFG_VBUSIG | GCCFG_PWRON | GCCFG_VBUSBCEN; #else /* Enable VBUS sense via pin PA9 */ otg_core_regs->GCCFG |= GCCFG_VBUSIG | GCCFG_PWRON | GCCFG_VBUSBCEN; otg_core_regs->GCCFG &= ~GCCFG_VBUSIG; #endif /* Enable interrupts globally */ __enable_irq(); } void gd32vf103_reset(void) { /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST * register to generate a software reset request. * BUT instead two undocumented registers in the debug peripheral * that allow issuing a software reset. * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ DBG_KEY = DBG_KEY_UNLOCK; DBG_CMD = DBG_CMD_RESET; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { state ? gd_led_on(LED_PIN) : gd_led_off(LED_PIN); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == gpio_input_bit_get(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { #if defined(UART_DEV) int rxsize = len; while (rxsize--) { *(uint8_t*)buf = usart_read(UART_DEV); buf++; } return len; #else (void)buf; (void)len; return 0; #endif } int board_uart_write(void const* buf, int len) { #if defined(UART_DEV) int txsize = len; while (txsize--) { usart_write(UART_DEV, *(uint8_t const*)buf); buf++; } return len; #else (void)buf; (void)len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void eclic_mtip_handler(void) { system_ticks++; SysTick_Reload(TIMER_TICKS); } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char* file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ ================================================ FILE: hw/bsp/gd32vf103/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/gd/nuclei-sdk) set(SOC_DIR ${SDK_DIR}/SoC/gd32vf103) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS GD32VF103 CACHE INTERNAL "") set(JLINK_IF jtag) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) message(FATAL_ERROR "LD_FILE_GNU is not defined") endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SOC_DIR}/Common/Source/GCC/startup_gd32vf103.S ${SOC_DIR}/Common/Source/GCC/intexc_gd32vf103.S ) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_gd32vf103.c ${SOC_DIR}/Common/Source/Drivers/gd32vf103_rcu.c ${SOC_DIR}/Common/Source/Drivers/gd32vf103_gpio.c ${SOC_DIR}/Common/Source/Drivers/Usb/gd32vf103_usb_hw.c ${SOC_DIR}/Common/Source/Drivers/gd32vf103_usart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/NMSIS/Core/Include ${SOC_DIR}/Common/Include ${SOC_DIR}/Common/Include/Usb ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) target_compile_definitions(${BOARD_TARGET} PUBLIC DOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -mcmodel=medlow -mstrict-align ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_GD32VF103) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${SOC_DIR}/Common/Source/Stubs/sbrk.c ${SOC_DIR}/Common/Source/Stubs/close.c ${SOC_DIR}/Common/Source/Stubs/isatty.c ${SOC_DIR}/Common/Source/Stubs/fstat.c ${SOC_DIR}/Common/Source/Stubs/lseek.c ${SOC_DIR}/Common/Source/Stubs/read.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties( ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${SOC_DIR}/Common/Source/Stubs/sbrk.c ${SOC_DIR}/Common/Source/Stubs/close.c ${SOC_DIR}/Common/Source/Stubs/isatty.c ${SOC_DIR}/Common/Source/Stubs/fstat.c ${SOC_DIR}/Common/Source/Stubs/lseek.c ${SOC_DIR}/Common/Source/Stubs/read.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/gd32vf103/family.mk ================================================ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk # Nuclei-SDK paths GD32VF103_SDK_SOC = $(NUCLEI_SDK)/SoC/gd32vf103 GD32VF103_SDK_DRIVER = $(GD32VF103_SDK_SOC)/Common/Source/Drivers LIBC_STUBS = $(GD32VF103_SDK_SOC)/Common/Source/Stubs STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_GD32VF103 \ -DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_gpio.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_usart.c \ $(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \ $(LIBC_STUBS)/sbrk.c \ $(LIBC_STUBS)/close.c \ $(LIBC_STUBS)/isatty.c \ $(LIBC_STUBS)/fstat.c \ $(LIBC_STUBS)/lseek.c \ $(LIBC_STUBS)/read.c SRC_S += \ $(STARTUP_ASM)/startup_gd32vf103.S \ $(STARTUP_ASM)/intexc_gd32vf103.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(NUCLEI_SDK)/NMSIS/Core/Include \ $(TOP)/$(GD32VF103_SDK_SOC)/Common/Include \ $(TOP)/$(GD32VF103_SDK_SOC)/Common/Include/Usb # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # For flash-jlink target JLINK_IF = jtag # flash target ROM bootloader flash: $(BUILD)/$(PROJECT).bin dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< ================================================ FILE: hw/bsp/gd32vf103/system_gd32vf103.c ================================================ /*! \file system_gd32vf103.h \brief RISC-V Device Peripheral Access Layer Source File for GD32VF103 Device Series */ /* Copyright (c) 2020, GigaDevice Semiconductor Inc. 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. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 refers the RISC-V standard, some adjustments are made according to GigaDevice chips */ #include "board.h" /* system frequency define */ #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ #define __SYSTEM_CLOCK_HXTAL (HXTAL_VALUE) #if !defined(__SYSTEM_CLOCK) #define __SYSTEM_CLOCK 72000000 #endif #if __SYSTEM_CLOCK == 48000000 #define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL; static void system_clock_48m_hxtal(void); #elif __SYSTEM_CLOCK == 72000000 #define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; static void system_clock_72m_hxtal(void); #elif __SYSTEM_CLOCK == 96000000 #define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000) uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL; static void system_clock_96m_hxtal(void); #else #error No valid system clock configuration set! #endif /* configure the system clock */ static void system_clock_config(void); /*! \brief configure the system clock \param[in] none \param[out] none \retval none */ static void system_clock_config(void) { #if defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) system_clock_48m_hxtal(); #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) system_clock_72m_hxtal(); #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL) system_clock_96m_hxtal(); #endif /* __SYSTEM_CLOCK_HXTAL */ } /*! \brief setup the microcontroller system, initialize the system \param[in] none \param[out] none \retval none */ void SystemInit(void) { /* reset the RCC clock configuration to the default reset state */ /* enable IRC8M */ RCU_CTL |= RCU_CTL_IRC8MEN; /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */ RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL); /* reset HXTALEN, CKMEN, PLLEN bits */ RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN); /* Reset HXTALBPS bit */ RCU_CTL &= ~(RCU_CTL_HXTALBPS); /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4); RCU_CFG1 = 0x00000000U; /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */ RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN); /* disable all interrupts */ RCU_INT = 0x00FF0000U; /* Configure the System clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */ system_clock_config(); } /*! \brief update the SystemCoreClock with current core clock retrieved from cpu registers \param[in] none \param[out] none \retval none */ void SystemCoreClockUpdate(void) { uint32_t scss; uint32_t pllsel, predv0sel, pllmf, ck_src; uint32_t predv0, predv1, pll1mf; scss = GET_BITS(RCU_CFG0, 2, 3); switch (scss) { /* IRC8M is selected as CK_SYS */ case SEL_IRC8M: SystemCoreClock = IRC8M_VALUE; break; /* HXTAL is selected as CK_SYS */ case SEL_HXTAL: SystemCoreClock = HXTAL_VALUE; break; /* PLL is selected as CK_SYS */ case SEL_PLL: /* PLL clock source selection, HXTAL or IRC8M/2 */ pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL); if(RCU_PLLSRC_IRC8M_DIV2 == pllsel){ /* PLL clock source is IRC8M/2 */ ck_src = IRC8M_VALUE / 2U; }else{ /* PLL clock source is HXTAL */ ck_src = HXTAL_VALUE; predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL); /* source clock use PLL1 */ if(RCU_PREDV0SRC_CKPLL1 == predv0sel){ predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U; pll1mf = ((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U; if(17U == pll1mf){ pll1mf = 20U; } ck_src = (ck_src / predv1) * pll1mf; } predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U; ck_src /= predv0; } /* PLL multiplication factor */ pllmf = GET_BITS(RCU_CFG0, 18, 21); if((RCU_CFG0 & RCU_CFG0_PLLMF_4)){ pllmf |= 0x10U; } if(pllmf >= 15U){ pllmf += 1U; }else{ pllmf += 2U; } SystemCoreClock = ck_src * pllmf; if(15U == pllmf){ /* PLL source clock multiply by 6.5 */ SystemCoreClock = ck_src * 6U + ck_src / 2U; } break; /* IRC8M is selected as CK_SYS */ default: SystemCoreClock = IRC8M_VALUE; break; } } #if defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) /*! \brief configure the system clock to 48M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source \param[in] none \param[out] none \retval none */ static void system_clock_48m_hxtal(void) { uint32_t timeout = 0U; uint32_t stab_flag = 0U; /* enable HXTAL */ RCU_CTL |= RCU_CTL_HXTALEN; /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ do{ timeout++; stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); /* if fail */ if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ while(1){ } } /* HXTAL is stable */ /* AHB = SYSCLK */ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; /* APB2 = AHB/1 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; /* APB1 = AHB/2 */ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; /* CK_PLL = (CK_PREDIV0) * 12 = 48 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL12); if(HXTAL_VALUE==25000000){ /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); /* enable PLL1 */ RCU_CTL |= RCU_CTL_PLL1EN; /* wait till PLL1 is ready */ while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ } }else if(HXTAL_VALUE==8000000){ RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); } /* enable PLL */ RCU_CTL |= RCU_CTL_PLLEN; /* wait until PLL is stable */ while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ } /* select PLL as system clock */ RCU_CFG0 &= ~RCU_CFG0_SCS; RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* wait until PLL is selected as system clock */ while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ } } #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) /*! \brief configure the system clock to 72M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source \param[in] none \param[out] none \retval none */ static void system_clock_72m_hxtal(void) { uint32_t timeout = 0U; uint32_t stab_flag = 0U; /* enable HXTAL */ RCU_CTL |= RCU_CTL_HXTALEN; /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ do{ timeout++; stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); /* if fail */ if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ while(1){ } } /* HXTAL is stable */ /* AHB = SYSCLK */ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; /* APB2 = AHB/1 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; /* APB1 = AHB/2 */ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; /* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL18); if(HXTAL_VALUE==25000000){ /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); /* enable PLL1 */ RCU_CTL |= RCU_CTL_PLL1EN; /* wait till PLL1 is ready */ while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ } }else if(HXTAL_VALUE==8000000){ RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); } /* enable PLL */ RCU_CTL |= RCU_CTL_PLLEN; /* wait until PLL is stable */ while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ } /* select PLL as system clock */ RCU_CFG0 &= ~RCU_CFG0_SCS; RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* wait until PLL is selected as system clock */ while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ } } #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL) /*! \brief configure the system clock to 96M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source \param[in] none \param[out] none \retval none */ static void system_clock_96m_hxtal(void) { uint32_t timeout = 0U; uint32_t stab_flag = 0U; /* enable HXTAL */ RCU_CTL |= RCU_CTL_HXTALEN; /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ do{ timeout++; stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); /* if fail */ if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ while(1){ } } /* HXTAL is stable */ /* AHB = SYSCLK */ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; /* APB2 = AHB/1 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; /* APB1 = AHB/2 */ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; if(HXTAL_VALUE==25000000){ /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24); /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); /* enable PLL1 */ RCU_CTL |= RCU_CTL_PLL1EN; /* wait till PLL1 is ready */ while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ } }else if(HXTAL_VALUE==8000000){ /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24); RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); } /* enable PLL */ RCU_CTL |= RCU_CTL_PLLEN; /* wait until PLL is stable */ while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ } /* select PLL as system clock */ RCU_CFG0 &= ~RCU_CFG0_SCS; RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* wait until PLL is selected as system clock */ while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ } } #endif /** * \defgroup NMSIS_Core_IntExcNMI_Handling Interrupt and Exception and NMI Handling * \brief Functions for interrupt, exception and nmi handle available in system_.c. * \details * Nuclei provide a template for interrupt, exception and NMI handling. Silicon Vendor could adapat according * to their requirement. Silicon vendor could implement interface for different exception code and * replace current implementation. * * @{ */ /** \brief Max exception handler number, don't include the NMI(0xFFF) one */ #define MAX_SYSTEM_EXCEPTION_NUM 12 /** * \brief Store the exception handlers for each exception ID * \note * - This SystemExceptionHandlers are used to store all the handlers for all * the exception codes Nuclei N/NX core provided. * - Exception code 0 - 11, totally 12 exceptions are mapped to SystemExceptionHandlers[0:11] * - Exception for NMI is also re-routed to exception handling(exception code 0xFFF) in startup code configuration, the handler itself is mapped to SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] */ static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM + 1]; /** * \brief Exception Handler Function Typedef * \note * This typedef is only used internal in this system_gd32vf103.c file. * It is used to do type conversion for registered exception handler before calling it. */ typedef void (*EXC_HANDLER)(unsigned long mcause, unsigned long sp); /** * \brief System Default Exception Handler * \details * This function provided a default exception and NMI handling code for all exception ids. * By default, It will just print some information for debug, Vendor can customize it according to its requirements. */ static void system_default_exception_handler(unsigned long mcause, unsigned long sp) { /* TODO: Uncomment this if you have implement printf function */ /*printf("MCAUSE: 0x%lx\r\n", mcause); printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC)); printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));*/ while (1); } /** * \brief Initialize all the default core exception handlers * \details * The core exception handler for each exception id will be initialized to \ref system_default_exception_handler. * \note * Called in \ref _init function, used to initialize default exception handlers for all exception IDs */ static void Exception_Init(void) { for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM + 1; i++) { SystemExceptionHandlers[i] = (unsigned long)system_default_exception_handler; } } /** * \brief Register an exception handler for exception code EXCn * \details * * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will be registered into SystemExceptionHandlers[EXCn-1]. * * For EXCn == NMI_EXCn, it will be registered into SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]. * \param EXCn See \ref EXCn_Type * \param exc_handler The exception handler for this exception code EXCn */ void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler) { if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn != 0)) { SystemExceptionHandlers[EXCn] = exc_handler; } else if (EXCn == NMI_EXCn) { SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] = exc_handler; } } /** * \brief Get current exception handler for exception code EXCn * \details * * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will return SystemExceptionHandlers[EXCn-1]. * * For EXCn == NMI_EXCn, it will return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]. * \param EXCn See \ref EXCn_Type * \return Current exception handler for exception code EXCn, if not found, return 0. */ unsigned long Exception_Get_EXC(uint32_t EXCn) { if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn != 0)) { return SystemExceptionHandlers[EXCn]; } else if (EXCn == NMI_EXCn) { return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]; } else { return 0; } } /** * \brief Common NMI and Exception handler entry * \details * This function provided a command entry for NMI and exception. Silicon Vendor could modify * this template implementation according to requirement. * \remarks * - RISCV provided common entry for all types of exception. This is proposed code template * for exception entry function, Silicon Vendor could modify the implementation. * - For the core_exception_handler template, we provided exception register function \ref Exception_Register_EXC * which can help developer to register your exception handler for specific exception number. */ uint32_t core_exception_handler(unsigned long mcause, unsigned long sp) { uint32_t EXCn = (uint32_t)(mcause & 0X00000fff); EXC_HANDLER exc_handler; if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn > 0)) { exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn]; } else if (EXCn == NMI_EXCn) { exc_handler = (EXC_HANDLER)SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]; } else { exc_handler = (EXC_HANDLER)system_default_exception_handler; } if (exc_handler != NULL) { exc_handler(mcause, sp); } return 0; } /** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */ /** * \brief initialize eclic config * \details * Eclic need initialize after boot up, Vendor could also change the initialization * configuration. */ void ECLIC_Init(void) { /* TODO: Add your own initialization code here. This function will be called by main */ ECLIC_SetMth(0); ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS); } /** * \brief Initialize a specific IRQ and register the handler * \details * This function set vector mode, trigger mode and polarity, interrupt level and priority, * assign handler for specific IRQn. * \param [in] IRQn NMI interrupt handler address * \param [in] shv \ref ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and \ref ECLIC_VECTOR_INTERRUPT is vector mode * \param [in] trig_mode see \ref ECLIC_TRIGGER_Type * \param [in] lvl interrupt level * \param [in] priority interrupt priority * \param [in] handler interrupt handler, if NULL, handler will not be installed * \return -1 means invalid input parameter. 0 means successful. * \remarks * - This function use to configure specific eclic interrupt and register its interrupt handler and enable its interrupt. * - If the vector table is placed in read-only section(FLASHXIP mode), handler could not be installed */ int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void* handler) { if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \ || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER)) { return -1; } /* set interrupt vector mode */ ECLIC_SetShvIRQ(IRQn, shv); /* set interrupt trigger mode and polarity */ ECLIC_SetTrigIRQ(IRQn, trig_mode); /* set interrupt level */ ECLIC_SetLevelIRQ(IRQn, lvl); /* set interrupt priority */ ECLIC_SetPriorityIRQ(IRQn, priority); if (handler != NULL) { /* set interrupt handler entry to vector table */ ECLIC_SetVector(IRQn, (rv_csr_t)handler); } /* enable interrupt */ ECLIC_EnableIRQ(IRQn); return 0; } /** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */ /** * \brief early init function before main * \details * This function is executed right before main function. * For RISC-V gnu toolchain, _init function might not be called * by __libc_init_array function, so we defined a new function * to do initialization */ void _premain_init(void) { /* Initialize exception default handlers */ Exception_Init(); /* ECLIC initialization, mainly MTH and NLBIT */ ECLIC_Init(); } /** * \brief finish function after main * \param [in] status status code return from main * \details * This function is executed right after main function. * For RISC-V gnu toolchain, _fini function might not be called * by __libc_fini_array function, so we defined a new function * to do initialization */ void _postmain_fini(int status) { /* TODO: Add your own finishing code here, called after main */ } /** * \brief _init function called in __libc_init_array() * \details * This `__libc_init_array()` function is called during startup code, * user need to implement this function, otherwise when link it will * error init.c:(.text.__libc_init_array+0x26): undefined reference to `_init' * \note * Please use \ref _premain_init function now */ void _init(void) { /* Don't put any code here, please use _premain_init now */ } /** * \brief _fini function called in __libc_fini_array() * \details * This `__libc_fini_array()` function is called when exit main. * user need to implement this function, otherwise when link it will * error fini.c:(.text.__libc_fini_array+0x28): undefined reference to `_fini' * \note * Please use \ref _postmain_fini function now */ void _fini(void) { /* Don't put any code here, please use _postmain_fini now */ } /** @} */ /* End of Doxygen Group NMSIS_Core_SystemAndClock */ ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/board.c ================================================ /* * Copyright (c) 2025 HPMicro * SPDX-License-Identifier: BSD-3-Clause * */ #include "board.h" #include "pinmux.h" #include "hpm_pmp_drv.h" #include "hpm_pllctl_drv.h" #include "hpm_clock_drv.h" #include "hpm_sysctl_drv.h" #include "hpm_pcfg_drv.h" #include "hpm_uart_drv.h" #include "hpm_gpio_drv.h" /** * @brief FLASH configuration option definitions: * option[0]: * [31:16] 0xfcf9 - FLASH configuration option tag * [15:4] 0 - Reserved * [3:0] option words (exclude option[0]) * option[1]: * [31:28] Flash probe type * 0 - SFDP SDR / 1 - SFDP DDR * 2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address) * 4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V * 6 - OctaBus DDR (SPI -> OPI DDR) * 8 - Xccela DDR (SPI -> OPI DDR) * 10 - EcoXiP DDR (SPI -> OPI DDR) * [27:24] Command Pads after Power-on Reset * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI * [23:20] Command Pads after Configuring FLASH * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI * [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only) * 0 - Not needed * 1 - QE bit is at bit 6 in Status Register 1 * 2 - QE bit is at bit1 in Status Register 2 * 3 - QE bit is at bit7 in Status Register 2 * 4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31 * [15:8] Dummy cycles * 0 - Auto-probed / detected / default value * Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet * [7:4] Misc. * 0 - Not used * 1 - SPI mode * 2 - Internal loopback * 3 - External DQS * [3:0] Frequency option * 1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz * * option[2] (Effective only if the bit[3:0] in option[0] > 1) * [31:20] Reserved * [19:16] IO voltage * 0 - 3V / 1 - 1.8V * [15:12] Pin group * 0 - 1st group / 1 - 2nd group * [11:8] Connection selection * 0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively) * [7:0] Drive Strength * 0 - Default value * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports * JESD216) * [31:16] reserved * [15:12] Sector Erase Command Option, not required here * [11:8] Sector Size Option, not required here * [7:0] Flash Size Option * 0 - 4MB / 1 - 8MB / 2 - 16MB */ #if defined(FLASH_XIP) && FLASH_XIP __attribute__ ((section(".nor_cfg_option"), used)) const uint32_t option[4] = {0xfcf90002, 0x00000007, 0xE, 0x0}; #endif #if defined(FLASH_UF2) && FLASH_UF2 ATTR_PLACE_AT(".uf2_signature") __attribute__((used)) const uint32_t uf2_signature = BOARD_UF2_SIGNATURE; #endif /* static function declarations */ static void board_turnoff_rgb_led(void); static void init_uart_pins(UART_Type *ptr); static uint32_t board_init_uart_clock(UART_Type *ptr); static void init_gpio_pins(void); static void init_usb_pins(USB_Type *ptr); /* extern function definitions */ void board_init_clock(void) { uint32_t cpu0_freq = clock_get_frequency(clock_cpu0); if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) { /* Configure the External OSC ramp-up time: ~9ms */ pllctl_xtal_set_rampup_time(HPM_PLLCTL, 32UL * 1000UL * 9U); /* Select clock setting preset1 */ sysctl_clock_set_preset(HPM_SYSCTL, sysctl_preset_1); } /* Add clocks to group 0 */ clock_add_to_group(clock_cpu0, 0); clock_add_to_group(clock_mchtmr0, 0); clock_add_to_group(clock_axi0, 0); clock_add_to_group(clock_axi1, 0); clock_add_to_group(clock_axi2, 0); clock_add_to_group(clock_ahb, 0); clock_add_to_group(clock_xdma, 0); clock_add_to_group(clock_hdma, 0); clock_add_to_group(clock_xpi0, 0); clock_add_to_group(clock_xpi1, 0); clock_add_to_group(clock_ram0, 0); clock_add_to_group(clock_ram1, 0); clock_add_to_group(clock_lmm0, 0); clock_add_to_group(clock_lmm1, 0); clock_add_to_group(clock_gpio, 0); clock_add_to_group(clock_mot0, 0); clock_add_to_group(clock_mot1, 0); clock_add_to_group(clock_mot2, 0); clock_add_to_group(clock_mot3, 0); clock_add_to_group(clock_synt, 0); clock_add_to_group(clock_ptpc, 0); /* Connect Group0 to CPU0 */ clock_connect_group_to_cpu(0, 0); /* Add clocks to Group1 */ clock_add_to_group(clock_cpu1, 1); clock_add_to_group(clock_mchtmr1, 1); /* Connect Group1 to CPU1 */ clock_connect_group_to_cpu(1, 1); /* Bump up DCDC voltage to 1275mv */ pcfg_dcdc_set_voltage(HPM_PCFG, 1275); pcfg_dcdc_switch_to_dcm_mode(HPM_PCFG); if (status_success != pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ)) { printf("Failed to set pll0_clk0 to %ldHz\n", BOARD_CPU_FREQ); while (1) { } } clock_set_source_divider(clock_cpu0, clk_src_pll0_clk0, 1); clock_set_source_divider(clock_cpu1, clk_src_pll0_clk0, 1); clock_update_core_clock(); clock_set_source_divider(clock_ahb, clk_src_pll1_clk1, 2); /*200m hz*/ clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1); clock_set_source_divider(clock_mchtmr1, clk_src_osc24m, 1); } void board_init_pmp(void) { uint32_t start_addr; uint32_t end_addr; uint32_t length; pmp_entry_t pmp_entry[16] = {0}; uint8_t index = 0; /* Init noncachable memory */ extern uint32_t __noncacheable_start__[]; extern uint32_t __noncacheable_end__[]; start_addr = (uint32_t) __noncacheable_start__; end_addr = (uint32_t) __noncacheable_end__; length = end_addr - start_addr; if (length > 0) { /* Ensure the address and the length are power of 2 aligned */ assert((length & (length - 1U)) == 0U); assert((start_addr & (length - 1U)) == 0U); pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length); pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK); pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length); pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN); index++; } /* Init share memory */ extern uint32_t __share_mem_start__[]; extern uint32_t __share_mem_end__[]; start_addr = (uint32_t)__share_mem_start__; end_addr = (uint32_t)__share_mem_end__; length = end_addr - start_addr; if (length > 0) { /* Ensure the address and the length are power of 2 aligned */ assert((length & (length - 1U)) == 0U); assert((start_addr & (length - 1U)) == 0U); pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length); pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK); pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length); pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN); index++; } pmp_config(&pmp_entry[0], index); } void board_init_console(void) { uart_config_t config = {0}; uint32_t freq; /* uart needs to configure pin function before enabling clock, otherwise the level change of uart rx pin when configuring pin function will cause a wrong data to be received. And a uart rx dma request will be generated by default uart fifo dma trigger level. */ init_uart_pins((UART_Type *) BOARD_CONSOLE_UART_BASE); freq = board_init_uart_clock((UART_Type *)BOARD_CONSOLE_UART_BASE); uart_default_config((UART_Type *)BOARD_CONSOLE_UART_BASE, &config); config.src_freq_in_hz = freq; config.baudrate = BOARD_CONSOLE_UART_BAUDRATE; uart_init((UART_Type *)BOARD_CONSOLE_UART_BASE, &config); } void board_init_gpio_pins(void) { init_gpio_pins(); } void board_init_led_pins(void) { board_turnoff_rgb_led(); init_led_pins_as_gpio(); gpio_set_pin_output_with_initial(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, BOARD_LED_OFF_LEVEL); gpio_set_pin_output_with_initial(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, BOARD_LED_OFF_LEVEL); gpio_set_pin_output_with_initial(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, BOARD_LED_OFF_LEVEL); } void board_init_usb(USB_Type *ptr) { clock_name_t usb_clk = (ptr == HPM_USB0) ? clock_usb0 : clock_usb1; init_usb_pins(ptr); clock_add_to_group(usb_clk, 0); } /* static function definitions */ static void board_turnoff_rgb_led(void) { uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(BOARD_LED_OFF_LEVEL); HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_GPIO_B_11; HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12; HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_GPIO_B_13; HPM_IOC->PAD[IOC_PAD_PB11].PAD_CTL = pad_ctl; HPM_IOC->PAD[IOC_PAD_PB12].PAD_CTL = pad_ctl; HPM_IOC->PAD[IOC_PAD_PB13].PAD_CTL = pad_ctl; } static void init_uart_pins(UART_Type *ptr) { if (ptr == HPM_UART0) { init_uart0_pins(); } else if (ptr == HPM_UART2) { init_uart2_pins(); } else if (ptr == HPM_UART13) { init_uart13_pins(); } else if (ptr == HPM_PUART) { init_puart_pins(); } } static uint32_t board_init_uart_clock(UART_Type *ptr) { uint32_t freq = 0U; if (ptr == HPM_UART0) { clock_add_to_group(clock_uart0, 0); freq = clock_get_frequency(clock_uart0); } else if (ptr == HPM_UART6) { clock_add_to_group(clock_uart6, 0); freq = clock_get_frequency(clock_uart6); } else if (ptr == HPM_UART13) { clock_add_to_group(clock_uart13, 0); freq = clock_get_frequency(clock_uart13); } else if (ptr == HPM_UART14) { clock_add_to_group(clock_uart14, 0); freq = clock_get_frequency(clock_uart14); } else { /* Not supported */ } return freq; } static void init_gpio_pins(void) { init_gpio_pins_with_pull_up(); #ifdef USING_GPIO0_FOR_GPIOZ init_gpio_pins_using_gpio0(); #endif } static void init_usb_pins(USB_Type *ptr) { if (ptr == HPM_USB0) { init_usb0_pins(); } else if (ptr == HPM_USB1) { init_usb1_pins(); } } ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/board.cmake ================================================ set(MCU_VARIANT HPM6750xVMx) set(JLINK_DEVICE ${MCU_VARIANT}) set(JLINK_IF jtag) set(HPM_SOC ${SDK_DIR}/soc/HPM6700/HPM6750) set(HPM_IP_REGS ${SDK_DIR}/soc/HPM6700/ip) set(BOARD_FLASH_SIZE 16M) set(BOARD_STACK_SIZE 16K) set(BOARD_HEAP_SIZE 16K) set(HPM_PLLCTL_DRV_FILE hpm_pllctl_drv.c) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC BOARD_TUD_RHPORT=0 BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED BOARD_TUH_RHPORT=1 BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED ) endfunction() ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/board.h ================================================ /* * Copyright (c) 2021-2025 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * */ /* metadata: name: HPM6750EVK2 url: https://hpm-sdk.readthedocs.io/en/v1.6.0/boards/hpm6750evk2/README_en.html */ #ifndef _HPM_BOARD_H #define _HPM_BOARD_H #include #include "hpm_common.h" #include "hpm_soc.h" #include "hpm_soc_feature.h" #include "pinmux.h" #define BOARD_NAME "hpm6750evk2" #ifndef BOARD_RUNNING_CORE #define BOARD_RUNNING_CORE HPM_CORE0 #endif #define BOARD_CPU_FREQ (816000000UL) /* console section */ #if BOARD_RUNNING_CORE == HPM_CORE0 #define BOARD_CONSOLE_UART_BASE HPM_UART0 #define BOARD_CONSOLE_UART_CLK_NAME clock_uart0 #define BOARD_CONSOLE_UART_IRQ IRQn_UART0 #define BOARD_CONSOLE_UART_TX_DMA_REQ HPM_DMA_SRC_UART0_TX #define BOARD_CONSOLE_UART_RX_DMA_REQ HPM_DMA_SRC_UART0_RX #else #define BOARD_CONSOLE_UART_BASE HPM_UART13 #define BOARD_CONSOLE_UART_CLK_NAME clock_uart13 #define BOARD_CONSOLE_UART_IRQ IRQn_UART13 #define BOARD_CONSOLE_UART_TX_DMA_REQ HPM_DMA_SRC_UART13_TX #define BOARD_CONSOLE_UART_RX_DMA_REQ HPM_DMA_SRC_UART13_RX #endif #define BOARD_CONSOLE_UART_BAUDRATE (115200UL) /* sdram section */ #define BOARD_SDRAM_ADDRESS (0x40000000UL) #define BOARD_SDRAM_SIZE (32 * SIZE_1MB) #define BOARD_SDRAM_CS FEMC_SDRAM_CS0 #define BOARD_SDRAM_PORT_SIZE FEMC_SDRAM_PORT_SIZE_32_BITS #define BOARD_SDRAM_COLUMN_ADDR_BITS FEMC_SDRAM_COLUMN_ADDR_9_BITS #define BOARD_SDRAM_REFRESH_COUNT (8192UL) #define BOARD_SDRAM_REFRESH_IN_MS (64UL) #define BOARD_FLASH_BASE_ADDRESS (0x80000000UL) #define BOARD_FLASH_SIZE (16 << 20) /* gpio section */ #define BOARD_R_GPIO_CTRL HPM_GPIO0 #define BOARD_R_GPIO_INDEX GPIO_DI_GPIOB #define BOARD_R_GPIO_PIN 11 #define BOARD_G_GPIO_CTRL HPM_GPIO0 #define BOARD_G_GPIO_INDEX GPIO_DI_GPIOB #define BOARD_G_GPIO_PIN 12 #define BOARD_B_GPIO_CTRL HPM_GPIO0 #define BOARD_B_GPIO_INDEX GPIO_DI_GPIOB #define BOARD_B_GPIO_PIN 13 #define BOARD_LED_GPIO_CTRL HPM_GPIO0 #define BOARD_LED_GPIO_INDEX GPIO_DI_GPIOB #define BOARD_LED_GPIO_PIN 12 #define BOARD_LED_OFF_LEVEL 0 #define BOARD_LED_ON_LEVEL 1 #define BOARD_LED_TOGGLE_RGB 1 #define BOARD_APP_GPIO_INDEX GPIO_DI_GPIOZ #define BOARD_APP_GPIO_PIN 2 #define BOARD_BUTTON_PRESSED_VALUE 0 #define USING_GPIO0_FOR_GPIOZ #ifndef USING_GPIO0_FOR_GPIOZ #define BOARD_APP_GPIO_CTRL HPM_BGPIO #define BOARD_APP_GPIO_IRQ IRQn_BGPIO #else #define BOARD_APP_GPIO_CTRL HPM_GPIO0 #define BOARD_APP_GPIO_IRQ IRQn_GPIO0_Z #endif #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ void board_init_clock(void); void board_init_pmp(void); void board_init_console(void); void board_init_gpio_pins(void); void board_init_led_pins(void); void board_init_usb(USB_Type *ptr); void board_print_banner(void); void board_print_clock_freq(void); #if defined(__cplusplus) } #endif /* __cplusplus */ #endif /* _HPM_BOARD_H */ ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/board.mk ================================================ MCU_VARIANT = HPM6750xVMx JLINK_DEVICE = ${MCU_VARIANT} JLINK_IF = jtag HPM_SOC = $(SDK_DIR)/soc/HPM6700/HPM6750 HPM_IP_REGS = $(SDK_DIR)/soc/HPM6700/ip BOARD_FLASH_SIZE = 16M BOARD_STACK_SIZE = 16K BOARD_HEAP_SIZE = 16K BOARD_TUD_RHPORT = 0 BOARD_TUH_RHPORT = 1 HPM_PLLCTL_DRV_FILE = hpm_pllctl_drv.c ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.c ================================================ /* * Copyright (c) 2025 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * * * Automatically generated by HPM Pinmux Tool * * * Note: * PY and PZ IOs: if any SOC pin function needs to be routed to these IOs, * besides of IOC, PIOC/BIOC needs to be configured SOC_GPIO_X_xx, so that * expected SoC function can be enabled on these IOs. */ #include "pinmux.h" #include "board.h" #include "hpm_trgm_drv.h" /* PY port IO needs to configure PIOC as well */ void init_uart0_pins(void) { HPM_IOC->PAD[IOC_PAD_PY07].FUNC_CTL = IOC_PY07_FUNC_CTL_UART0_RXD; HPM_PIOC->PAD[IOC_PAD_PY07].FUNC_CTL = PIOC_PY07_FUNC_CTL_SOC_PY_07; HPM_IOC->PAD[IOC_PAD_PY06].FUNC_CTL = IOC_PY06_FUNC_CTL_UART0_TXD; HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_SOC_PY_06; } void init_uart2_pins(void) { HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PE16_FUNC_CTL_UART2_TXD; HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PE21_FUNC_CTL_UART2_RXD; } /* PZ port IO needs to configure BIOC as well */ void init_uart13_pins(void) { HPM_IOC->PAD[IOC_PAD_PZ08].FUNC_CTL = IOC_PZ08_FUNC_CTL_UART13_RXD; HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_SOC_PZ_08; HPM_IOC->PAD[IOC_PAD_PZ09].FUNC_CTL = IOC_PZ09_FUNC_CTL_UART13_TXD; HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_SOC_PZ_09; } void init_puart_pins(void) { HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_PUART_TXD; HPM_PIOC->PAD[IOC_PAD_PY07].FUNC_CTL = PIOC_PY07_FUNC_CTL_PUART_RXD; } /* * PZ port IO needs to configure BIOC as well. * PZ08 and PZ09 need pull up. * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_uart13_pins_as_gpio(void) { HPM_IOC->PAD[IOC_PAD_PZ08].FUNC_CTL = IOC_PZ08_FUNC_CTL_GPIO_Z_08; HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_SOC_PZ_08; HPM_IOC->PAD[IOC_PAD_PZ08].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); HPM_IOC->PAD[IOC_PAD_PZ09].FUNC_CTL = IOC_PZ09_FUNC_CTL_GPIO_Z_09; HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_SOC_PZ_09; } void init_lcd0_pins(void) { HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_DIS0_R_0; HPM_IOC->PAD[IOC_PAD_PB04].FUNC_CTL = IOC_PB04_FUNC_CTL_DIS0_R_1; HPM_IOC->PAD[IOC_PAD_PB00].FUNC_CTL = IOC_PB00_FUNC_CTL_DIS0_R_2; HPM_IOC->PAD[IOC_PAD_PA31].FUNC_CTL = IOC_PA31_FUNC_CTL_DIS0_R_3; HPM_IOC->PAD[IOC_PAD_PA26].FUNC_CTL = IOC_PA26_FUNC_CTL_DIS0_R_4; HPM_IOC->PAD[IOC_PAD_PA21].FUNC_CTL = IOC_PA21_FUNC_CTL_DIS0_R_5; HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = IOC_PA27_FUNC_CTL_DIS0_R_6; HPM_IOC->PAD[IOC_PAD_PA28].FUNC_CTL = IOC_PA28_FUNC_CTL_DIS0_R_7; HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_DIS0_G_0; HPM_IOC->PAD[IOC_PAD_PB01].FUNC_CTL = IOC_PB01_FUNC_CTL_DIS0_G_1; HPM_IOC->PAD[IOC_PAD_PA22].FUNC_CTL = IOC_PA22_FUNC_CTL_DIS0_G_2; HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_DIS0_G_3; HPM_IOC->PAD[IOC_PAD_PA29].FUNC_CTL = IOC_PA29_FUNC_CTL_DIS0_G_4; HPM_IOC->PAD[IOC_PAD_PA24].FUNC_CTL = IOC_PA24_FUNC_CTL_DIS0_G_5; HPM_IOC->PAD[IOC_PAD_PA30].FUNC_CTL = IOC_PA30_FUNC_CTL_DIS0_G_6; HPM_IOC->PAD[IOC_PAD_PA25].FUNC_CTL = IOC_PA25_FUNC_CTL_DIS0_G_7; HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_DIS0_B_0; HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_DIS0_B_1; HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_DIS0_B_2; HPM_IOC->PAD[IOC_PAD_PA16].FUNC_CTL = IOC_PA16_FUNC_CTL_DIS0_B_3; HPM_IOC->PAD[IOC_PAD_PA12].FUNC_CTL = IOC_PA12_FUNC_CTL_DIS0_B_4; HPM_IOC->PAD[IOC_PAD_PA17].FUNC_CTL = IOC_PA17_FUNC_CTL_DIS0_B_5; HPM_IOC->PAD[IOC_PAD_PA13].FUNC_CTL = IOC_PA13_FUNC_CTL_DIS0_B_6; HPM_IOC->PAD[IOC_PAD_PA18].FUNC_CTL = IOC_PA18_FUNC_CTL_DIS0_B_7; HPM_IOC->PAD[IOC_PAD_PA20].FUNC_CTL = IOC_PA20_FUNC_CTL_DIS0_CLK; HPM_IOC->PAD[IOC_PAD_PA15].FUNC_CTL = IOC_PA15_FUNC_CTL_DIS0_EN; HPM_IOC->PAD[IOC_PAD_PA19].FUNC_CTL = IOC_PA19_FUNC_CTL_DIS0_HSYNC; HPM_IOC->PAD[IOC_PAD_PA14].FUNC_CTL = IOC_PA14_FUNC_CTL_DIS0_VSYNC; /* PWM */ HPM_IOC->PAD[IOC_PAD_PB10].FUNC_CTL = IOC_PB10_FUNC_CTL_GPIO_B_10; /* RST */ HPM_IOC->PAD[IOC_PAD_PB16].FUNC_CTL = IOC_PB16_FUNC_CTL_GPIO_B_16; HPM_IOC->PAD[IOC_PAD_PZ00].FUNC_CTL = IOC_PZ00_FUNC_CTL_GPIO_Z_00; HPM_BIOC->PAD[IOC_PAD_PZ00].FUNC_CTL = BIOC_PZ00_FUNC_CTL_SOC_PZ_00; HPM_IOC->PAD[IOC_PAD_PZ00].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); } /* * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_cap_pins(void) { /* CAP_INT */ HPM_IOC->PAD[IOC_PAD_PB08].FUNC_CTL = IOC_PB08_FUNC_CTL_GPIO_B_08; HPM_IOC->PAD[IOC_PAD_PB08].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(1); /* CAP_RST */ HPM_IOC->PAD[IOC_PAD_PB09].FUNC_CTL = IOC_PB09_FUNC_CTL_GPIO_B_09; HPM_IOC->PAD[IOC_PAD_PB09].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(1); } /* PZ port IO needs to configure BIOC as well */ void init_i2c0_pins_as_gpio(void) { HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_GPIO_Z_11; HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11; HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_GPIO_Z_10; HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10; } /* PZ port IO needs to configure BIOC as well */ void init_i2c0_pins(void) { HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_I2C0_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11; HPM_IOC->PAD[IOC_PAD_PZ11].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1); HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_I2C0_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10; HPM_IOC->PAD[IOC_PAD_PZ10].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1); } void init_femc_pins(void) { HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_FEMC_DQ_16; HPM_IOC->PAD[IOC_PAD_PC00].FUNC_CTL = IOC_PC00_FUNC_CTL_FEMC_DQ_17; HPM_IOC->PAD[IOC_PAD_PB31].FUNC_CTL = IOC_PB31_FUNC_CTL_FEMC_DQ_18; HPM_IOC->PAD[IOC_PAD_PB30].FUNC_CTL = IOC_PB30_FUNC_CTL_FEMC_DQ_30; HPM_IOC->PAD[IOC_PAD_PB29].FUNC_CTL = IOC_PB29_FUNC_CTL_FEMC_DQ_31; HPM_IOC->PAD[IOC_PAD_PB28].FUNC_CTL = IOC_PB28_FUNC_CTL_FEMC_DQ_19; HPM_IOC->PAD[IOC_PAD_PB27].FUNC_CTL = IOC_PB27_FUNC_CTL_FEMC_DQ_20; HPM_IOC->PAD[IOC_PAD_PB26].FUNC_CTL = IOC_PB26_FUNC_CTL_FEMC_DQ_21; HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_FEMC_DQ_28; HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_FEMC_DQ_29; HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_FEMC_DQ_22; HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_FEMC_DQ_26; HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_FEMC_DQ_27; HPM_IOC->PAD[IOC_PAD_PB20].FUNC_CTL = IOC_PB20_FUNC_CTL_FEMC_DQ_23; HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_FEMC_DQ_24; HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_FEMC_DQ_25; HPM_IOC->PAD[IOC_PAD_PD13].FUNC_CTL = IOC_PD13_FUNC_CTL_FEMC_DQ_14; HPM_IOC->PAD[IOC_PAD_PD12].FUNC_CTL = IOC_PD12_FUNC_CTL_FEMC_DQ_15; HPM_IOC->PAD[IOC_PAD_PD10].FUNC_CTL = IOC_PD10_FUNC_CTL_FEMC_DQ_12; HPM_IOC->PAD[IOC_PAD_PD09].FUNC_CTL = IOC_PD09_FUNC_CTL_FEMC_DQ_13; HPM_IOC->PAD[IOC_PAD_PD08].FUNC_CTL = IOC_PD08_FUNC_CTL_FEMC_DQ_00; HPM_IOC->PAD[IOC_PAD_PD07].FUNC_CTL = IOC_PD07_FUNC_CTL_FEMC_DQ_10; HPM_IOC->PAD[IOC_PAD_PD06].FUNC_CTL = IOC_PD06_FUNC_CTL_FEMC_DQ_11; HPM_IOC->PAD[IOC_PAD_PD05].FUNC_CTL = IOC_PD05_FUNC_CTL_FEMC_DQ_01; HPM_IOC->PAD[IOC_PAD_PD04].FUNC_CTL = IOC_PD04_FUNC_CTL_FEMC_DQ_08; HPM_IOC->PAD[IOC_PAD_PD03].FUNC_CTL = IOC_PD03_FUNC_CTL_FEMC_DQ_09; HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_FEMC_DQ_04; HPM_IOC->PAD[IOC_PAD_PD01].FUNC_CTL = IOC_PD01_FUNC_CTL_FEMC_DQ_03; HPM_IOC->PAD[IOC_PAD_PD00].FUNC_CTL = IOC_PD00_FUNC_CTL_FEMC_DQ_02; HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_FEMC_DQ_07; HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_FEMC_DQ_06; HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_FEMC_DQ_05; /* SRAM #WE */ HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_FEMC_A_11; HPM_IOC->PAD[IOC_PAD_PC17].FUNC_CTL = IOC_PC17_FUNC_CTL_FEMC_A_09; HPM_IOC->PAD[IOC_PAD_PC15].FUNC_CTL = IOC_PC15_FUNC_CTL_FEMC_A_10; HPM_IOC->PAD[IOC_PAD_PC12].FUNC_CTL = IOC_PC12_FUNC_CTL_FEMC_A_08; HPM_IOC->PAD[IOC_PAD_PC11].FUNC_CTL = IOC_PC11_FUNC_CTL_FEMC_A_07; HPM_IOC->PAD[IOC_PAD_PC10].FUNC_CTL = IOC_PC10_FUNC_CTL_FEMC_A_06; HPM_IOC->PAD[IOC_PAD_PC09].FUNC_CTL = IOC_PC09_FUNC_CTL_FEMC_A_01; HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_FEMC_A_00; HPM_IOC->PAD[IOC_PAD_PC07].FUNC_CTL = IOC_PC07_FUNC_CTL_FEMC_A_05; HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_FEMC_A_04; HPM_IOC->PAD[IOC_PAD_PC05].FUNC_CTL = IOC_PC05_FUNC_CTL_FEMC_A_03; HPM_IOC->PAD[IOC_PAD_PC04].FUNC_CTL = IOC_PC04_FUNC_CTL_FEMC_A_02; /* SRAM #ADV */ HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_FEMC_BA1; HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_FEMC_BA0; HPM_IOC->PAD[IOC_PAD_PC16].FUNC_CTL = IOC_PC16_FUNC_CTL_FEMC_DQS | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_FEMC_CLK; HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_FEMC_CKE; HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_FEMC_CS_0; HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_FEMC_RAS; HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_FEMC_CAS; HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_FEMC_WE; /* SRAM #LB */ HPM_IOC->PAD[IOC_PAD_PC30].FUNC_CTL = IOC_PC30_FUNC_CTL_FEMC_DM_0; /* SRAM #UB */ HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_FEMC_DM_1; HPM_IOC->PAD[IOC_PAD_PC02].FUNC_CTL = IOC_PC02_FUNC_CTL_FEMC_DM_2; HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PC03_FUNC_CTL_FEMC_DM_3; /* SRAM #CE */ HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_FEMC_CS_1; /* SRAM #OE */ HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_FEMC_A_12; } /* * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_gpio_pins_with_pull_up(void) { HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12; HPM_IOC->PAD[IOC_PAD_PB12].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(0); } /* * PZ port IO needs to configure BIOC as well. * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_gpio_pins_using_gpio0(void) { HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_GPIO_Z_02; HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_SOC_PZ_02; HPM_IOC->PAD[IOC_PAD_PZ02].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); } /* * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_spi2_pins(void) { HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_SPI2_CSN; HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_SPI2_MOSI; HPM_IOC->PAD[IOC_PAD_PE30].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_SPI2_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PE27].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_SPI2_MISO; HPM_IOC->PAD[IOC_PAD_PE28].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; } /* * Errata: E00029:IOC PAD_CTL register write restrictions. * When the PE bit is 1, bit [3] must be set to 1, * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength). */ void init_spi2_pins_with_gpio_as_cs(void) { HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_SPI2_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PE27].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_SPI2_MISO; HPM_IOC->PAD[IOC_PAD_PE28].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_SPI2_MOSI; HPM_IOC->PAD[IOC_PAD_PE30].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08; HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_GPIO_E_31; HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); } void init_gptmr3_pins(void) { /* TMR3 compare 1 */ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_GPTMR3_COMP_1; } void init_gptmr4_pins(void) { /* TMR4 capture 1 */ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_GPTMR4_CAPT_1; } void init_gptmr5_pins(void) { /* TMR5 compare 2 */ HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10; /* TMR5 compare 3 */ HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_TRGM2_P_11; trgm_output_t trgm2_io_config0 = {0}; trgm2_io_config0.invert = 0; trgm2_io_config0.type = trgm_output_same_as_input; trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT2; trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P10, &trgm2_io_config0); trgm_enable_io_output(HPM_TRGM2, 1 << 10); trgm_output_t trgm2_io_config1 = {0}; trgm2_io_config1.invert = 0; trgm2_io_config1.type = trgm_output_same_as_input; trgm2_io_config1.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT3; trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P11, &trgm2_io_config1); trgm_enable_io_output(HPM_TRGM2, 1 << 11); } void init_hall_trgm_pins(void) { HPM_IOC->PAD[IOC_PAD_PD16].FUNC_CTL = IOC_PD16_FUNC_CTL_TRGM2_P_06; HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_TRGM2_P_07; HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_TRGM2_P_08; } void init_qei_trgm_pins(void) { HPM_IOC->PAD[IOC_PAD_PD19].FUNC_CTL = IOC_PD19_FUNC_CTL_TRGM2_P_09; HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10; } void init_i2s0_pins(void) { HPM_IOC->PAD[IOC_PAD_PF02].FUNC_CTL = IOC_PF02_FUNC_CTL_I2S0_RXD_2; HPM_IOC->PAD[IOC_PAD_PF03].FUNC_CTL = IOC_PF03_FUNC_CTL_I2S0_MCLK; HPM_IOC->PAD[IOC_PAD_PF04].FUNC_CTL = IOC_PF04_FUNC_CTL_I2S0_TXD_2; HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = IOC_PF06_FUNC_CTL_I2S0_BCLK; HPM_IOC->PAD[IOC_PAD_PF09].FUNC_CTL = IOC_PF09_FUNC_CTL_I2S0_FCLK; } /* PY port IO needs to configure PIOC */ void init_dao_pins(void) { HPM_IOC->PAD[IOC_PAD_PY08].FUNC_CTL = IOC_PY08_FUNC_CTL_DAOR_P; HPM_PIOC->PAD[IOC_PAD_PY08].FUNC_CTL = PIOC_PY08_FUNC_CTL_SOC_PY_08; HPM_IOC->PAD[IOC_PAD_PY09].FUNC_CTL = IOC_PY09_FUNC_CTL_DAOR_N; HPM_PIOC->PAD[IOC_PAD_PY09].FUNC_CTL = PIOC_PY09_FUNC_CTL_SOC_PY_09; } /* PY port IO needs to configure PIOC */ void init_pdm_pins(void) { HPM_IOC->PAD[IOC_PAD_PY10].FUNC_CTL = IOC_PY10_FUNC_CTL_PDM0_CLK; HPM_PIOC->PAD[IOC_PAD_PY10].FUNC_CTL = PIOC_PY10_FUNC_CTL_SOC_PY_10; HPM_IOC->PAD[IOC_PAD_PY11].FUNC_CTL = IOC_PY11_FUNC_CTL_PDM0_D_0; HPM_PIOC->PAD[IOC_PAD_PY11].FUNC_CTL = PIOC_PY11_FUNC_CTL_SOC_PY_11; } void init_vad_pins(void) { HPM_PIOC->PAD[IOC_PAD_PY10].FUNC_CTL = PIOC_PY10_FUNC_CTL_VAD_CLK; HPM_PIOC->PAD[IOC_PAD_PY11].FUNC_CTL = PIOC_PY11_FUNC_CTL_VAD_DAT; } void init_cam_pins(void) { /* configure rst pin function, PY port IO needs to configure PIOC */ HPM_IOC->PAD[IOC_PAD_PY05].FUNC_CTL = IOC_PY05_FUNC_CTL_GPIO_Y_05; HPM_PIOC->PAD[IOC_PAD_PY05].FUNC_CTL = PIOC_PY05_FUNC_CTL_SOC_PY_05; HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = IOC_PA07_FUNC_CTL_CAM0_D_2; HPM_IOC->PAD[IOC_PAD_PA03].FUNC_CTL = IOC_PA03_FUNC_CTL_CAM0_D_3; HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = IOC_PA08_FUNC_CTL_CAM0_D_4; HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_CAM0_D_5; HPM_IOC->PAD[IOC_PAD_PA00].FUNC_CTL = IOC_PA00_FUNC_CTL_CAM0_D_6; HPM_IOC->PAD[IOC_PAD_PA04].FUNC_CTL = IOC_PA04_FUNC_CTL_CAM0_D_7; HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_CAM0_D_8; HPM_IOC->PAD[IOC_PAD_PA02].FUNC_CTL = IOC_PA02_FUNC_CTL_CAM0_D_9; HPM_IOC->PAD[IOC_PAD_PA10].FUNC_CTL = IOC_PA10_FUNC_CTL_CAM0_XCLK; HPM_IOC->PAD[IOC_PAD_PA05].FUNC_CTL = IOC_PA05_FUNC_CTL_CAM0_HSYNC; HPM_IOC->PAD[IOC_PAD_PA06].FUNC_CTL = IOC_PA06_FUNC_CTL_CAM0_VSYNC; HPM_IOC->PAD[IOC_PAD_PA11].FUNC_CTL = IOC_PA11_FUNC_CTL_CAM0_PIXCLK; } void init_butn_pins(void) { HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_PBUTN; HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = BIOC_PZ03_FUNC_CTL_WBUTN; HPM_BIOC->PAD[IOC_PAD_PZ04].FUNC_CTL = BIOC_PZ04_FUNC_CTL_PLED; HPM_BIOC->PAD[IOC_PAD_PZ05].FUNC_CTL = BIOC_PZ05_FUNC_CTL_WLED; } void init_acmp_pins(void) { /* configure to ACMP_COMP_1(ALT16) function */ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_ACMP_COMP_1; /* configure to CMP1_INP7 function */ HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* configure to CMP1_INN6 function */ HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; } void init_enet0_pins(void) { HPM_IOC->PAD[IOC_PAD_PF00].FUNC_CTL = IOC_PF00_FUNC_CTL_GPIO_F_00; HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PE23_FUNC_CTL_ETH0_MDIO; HPM_IOC->PAD[IOC_PAD_PE22].FUNC_CTL = IOC_PE22_FUNC_CTL_ETH0_MDC; HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_ETH0_RXD_0; HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_ETH0_RXD_1; HPM_IOC->PAD[IOC_PAD_PE02].FUNC_CTL = IOC_PE02_FUNC_CTL_ETH0_RXD_2; HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_ETH0_RXD_3; HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_ETH0_RXCK; HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_ETH0_RXDV; HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_ETH0_TXD_0; HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_ETH0_TXD_1; HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_ETH0_TXD_2; HPM_IOC->PAD[IOC_PAD_PE05].FUNC_CTL = IOC_PE05_FUNC_CTL_ETH0_TXD_3; HPM_IOC->PAD[IOC_PAD_PE01].FUNC_CTL = IOC_PE01_FUNC_CTL_ETH0_TXCK; HPM_IOC->PAD[IOC_PAD_PE00].FUNC_CTL = IOC_PE00_FUNC_CTL_ETH0_TXEN; } void init_enet1_pins(void) { HPM_IOC->PAD[IOC_PAD_PE26].FUNC_CTL = IOC_PE26_FUNC_CTL_GPIO_E_26; HPM_IOC->PAD[IOC_PAD_PD11].FUNC_CTL = IOC_PD11_FUNC_CTL_ETH1_MDC; HPM_IOC->PAD[IOC_PAD_PD14].FUNC_CTL = IOC_PD14_FUNC_CTL_ETH1_MDIO; HPM_IOC->PAD[IOC_PAD_PE20].FUNC_CTL = IOC_PE20_FUNC_CTL_ETH1_RXD_0; HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_ETH1_RXD_1; HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_ETH1_RXDV; HPM_IOC->PAD[IOC_PAD_PE19].FUNC_CTL = IOC_PE19_FUNC_CTL_ETH1_TXD_0; HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_ETH1_TXD_1; HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_ETH1_TXEN; HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PE16_FUNC_CTL_ETH1_REFCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; } void init_pwm2_pins(void) { HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_PWM2_P_5; HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_PWM2_P_4; HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_PWM2_P_1; HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_PWM2_P_0; HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_PWM2_P_3; HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_PWM2_P_2; } void init_pwm3_pins(void) { HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_PWM3_P_6; HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_PWM3_P_7; } void init_adc12_pins(void) { /* ADC0.VIN11 */ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; } void init_adc16_pins(void) { /* ADC3.INA2 */ HPM_IOC->PAD[IOC_PAD_PE29].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; } void init_adc_bldc_pins(void) { /* ADC0.VINP7 */ HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC1.VINP10 */ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; /* ADC2.VINP11 */ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; } void init_usb0_pins(void) { HPM_IOC->PAD[IOC_PAD_PF10].FUNC_CTL = IOC_PF10_FUNC_CTL_USB0_ID; HPM_IOC->PAD[IOC_PAD_PF08].FUNC_CTL = IOC_PF08_FUNC_CTL_USB0_OC; } void init_usb1_pins(void) { HPM_IOC->PAD[IOC_PAD_PF07].FUNC_CTL = IOC_PF07_FUNC_CTL_USB1_ID; HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = IOC_PF05_FUNC_CTL_USB1_OC; } void init_can0_pins(void) { HPM_IOC->PAD[IOC_PAD_PB15].FUNC_CTL = IOC_PB15_FUNC_CTL_CAN0_TXD; HPM_IOC->PAD[IOC_PAD_PB17].FUNC_CTL = IOC_PB17_FUNC_CTL_CAN0_RXD; } void init_mcan0_transceiver_phy_pin(void) { HPM_IOC->PAD[IOC_PAD_PB14].FUNC_CTL = IOC_PB14_FUNC_CTL_GPIO_B_14; } void init_sdxc1_cmd_pin_enable_1v8_enable_opendrain(void) { /* SDXC1.CMD */ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(1); } void init_sdxc1_cmd_pin_enable_1v8_disable_opendrain(void) { /* SDXC1.CMD */ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(0); } void init_sdxc1_cmd_pin_disable_1v8_enable_opendrain(void) { /* SDXC1.CMD */ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(1); } void init_sdxc1_cmd_pin_disable_1v8_disable_opendrain(void) { /* SDXC1.CMD */ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(0); } void init_sdxc1_cd_pin(void) { /* SDXC1.CDN */ HPM_IOC->PAD[IOC_PAD_PD15].FUNC_CTL = IOC_PD15_FUNC_CTL_GPIO_D_15; HPM_IOC->PAD[IOC_PAD_PD15].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); } void init_sdxc1_clk_data_pins_enable_1v8(void) { /* SDXC1.CLK */ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK; HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA0 */ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0; HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); } void init_sdxc1_clk_data_pins_disable_1v8(void) { /* SDXC1.CLK */ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK; HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA0 */ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0; HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); } void init_sdxc1_clk_data_pins_width4_enable_1v8(void) { /* SDXC1.DATA1 */ HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_SDC1_DATA_1; HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA2 */ HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_SDC1_DATA_2; HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA3 */ HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_SDC1_DATA_3; HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.CLK */ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK; HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA0 */ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0; HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); } void init_sdxc1_clk_data_pins_width4_disable_1v8(void) { /* SDXC1.DATA1 */ HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_SDC1_DATA_1; HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA2 */ HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_SDC1_DATA_2; HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA3 */ HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_SDC1_DATA_3; HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.CLK */ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK; HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); /* SDXC1.DATA0 */ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0; HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1); } void init_sdxc1_pwr_pin(void) { HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_GPIO_C_20; HPM_IOC->PAD[IOC_PAD_PC20].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); } void init_clk_obs_pins(void) { HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_SYSCTL_CLK_OBS_0; } void init_rgb_pwm_pins(void) { /* Red */ HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_TRGM1_P_01; /* Green */ HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_TRGM0_P_06; /* BLUE */ HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_TRGM1_P_03; } void init_led_pins_as_gpio(void) { HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_GPIO_B_11; HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12; HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_GPIO_B_13; } void init_enet_pps_pins(void) { HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = IOC_PF05_FUNC_CTL_ETH0_EVTO_0; } void init_enet_pps_capture_pins(void) { HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_ETH0_EVTI_1; } void init_tamper_pins(void) { HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_TAMP_08 | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_TAMP_09; HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_TAMP_10; } /* for uart_rx_line_status case, need to a gpio pin to sent break signal */ void init_uart_break_signal_pin(void) { HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_GPIO_E_31; HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1); } void init_gptmr3_channel_pin_as_output(void) { HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_GPTMR3_COMP_1; } void init_gptmr4_channel_pin_as_capture(void) { HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_GPTMR4_CAPT_1; } void init_gptmr5_channel2_pin_as_output(void) { HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10; trgm_output_t trgm2_io_config0 = {0}; trgm2_io_config0.invert = 0; trgm2_io_config0.type = trgm_output_same_as_input; trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT2; trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P10, &trgm2_io_config0); trgm_enable_io_output(HPM_TRGM2, 1 << 10); } void init_gptmr5_channel3_pin_as_output(void) { HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_TRGM2_P_11; trgm_output_t trgm2_io_config0 = {0}; trgm2_io_config0.invert = 0; trgm2_io_config0.type = trgm_output_same_as_input; trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT3; trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P11, &trgm2_io_config0); trgm_enable_io_output(HPM_TRGM2, 1 << 11); } void init_clk_ref_pin(void) { HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_SOC_REF1; } void init_brownout_indicate_pin(void) { HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_GPIO_E_30; } void board_init_i2c_eeprom_pin(void) { HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_I2C0_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11; HPM_IOC->PAD[IOC_PAD_PZ11].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1); HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_I2C0_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK; HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10; HPM_IOC->PAD[IOC_PAD_PZ10].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1); } ================================================ FILE: hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.h ================================================ /* * Copyright (c) 2025 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * * * Automatically generated by HPM Pinmux Tool * * * Note: * PY and PZ IOs: if any SOC pin function needs to be routed to these IOs, * besides of IOC, PIOC/BIOC needs to be configured SOC_GPIO_X_xx, so that * expected SoC function can be enabled on these IOs. */ #ifndef HPM_PINMUX_H #define HPM_PINMUX_H #ifdef __cplusplus extern "C" { #endif void init_uart0_pins(void); void init_uart2_pins(void); void init_uart13_pins(void); void init_puart_pins(void); void init_uart13_pins_as_gpio(void); void init_lcd0_pins(void); void init_cap_pins(void); void init_i2c0_pins_as_gpio(void); void init_i2c0_pins(void); void init_femc_pins(void); void init_gpio_pins_with_pull_up(void); void init_gpio_pins_using_gpio0(void); void init_spi2_pins(void); void init_spi2_pins_with_gpio_as_cs(void); void init_gptmr3_pins(void); void init_gptmr4_pins(void); void init_gptmr5_pins(void); void init_hall_trgm_pins(void); void init_qei_trgm_pins(void); void init_i2s0_pins(void); void init_dao_pins(void); void init_pdm_pins(void); void init_vad_pins(void); void init_cam_pins(void); void init_butn_pins(void); void init_acmp_pins(void); void init_enet0_pins(void); void init_enet1_pins(void); void init_pwm2_pins(void); void init_pwm3_pins(void); void init_adc12_pins(void); void init_adc16_pins(void); void init_adc_bldc_pins(void); void init_usb0_pins(void); void init_usb1_pins(void); void init_can0_pins(void); void init_mcan0_transceiver_phy_pin(void); void init_sdxc1_cmd_pin_enable_1v8_enable_opendrain(void); void init_sdxc1_cmd_pin_enable_1v8_disable_opendrain(void); void init_sdxc1_cmd_pin_disable_1v8_enable_opendrain(void); void init_sdxc1_cmd_pin_disable_1v8_disable_opendrain(void); void init_sdxc1_cd_pin(void); void init_sdxc1_clk_data_pins_enable_1v8(void); void init_sdxc1_clk_data_pins_disable_1v8(void); void init_sdxc1_clk_data_pins_width4_enable_1v8(void); void init_sdxc1_clk_data_pins_width4_disable_1v8(void); void init_sdxc1_pwr_pin(void); void init_clk_obs_pins(void); void init_rgb_pwm_pins(void); void init_led_pins_as_gpio(void); void init_enet_pps_pins(void); void init_enet_pps_capture_pins(void); void init_tamper_pins(void); void init_uart_break_signal_pin(void); void init_gptmr3_channel_pin_as_output(void); void init_gptmr4_channel_pin_as_capture(void); void init_gptmr5_channel2_pin_as_output(void); void init_gptmr5_channel3_pin_as_output(void); void init_clk_ref_pin(void); void init_brownout_indicate_pin(void); void board_init_i2c_eeprom_pin(void); #ifdef __cplusplus } #endif #endif /* HPM_PINMUX_H */ ================================================ FILE: hw/bsp/hpmicro/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: HPMicro */ #include "bsp/board_api.h" #include "board.h" #include "hpm_clock_drv.h" #include "hpm_uart_drv.h" #include "hpm_gpio_drv.h" #include "hpm_romapi.h" //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ // Initialize on-board peripherals : led, button, uart and USB void board_init(void) { board_init_clock(); board_init_pmp(); board_init_usb(HPM_USB0); #ifdef HPM_USB1 board_init_usb(HPM_USB1); #endif board_init_console(); board_init_gpio_pins(); board_init_led_pins(); } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usb0) void isr_usb0(void) { tusb_int_handler(0, true); } #ifdef HPM_USB1_BASE SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usb1) void isr_usb1(void) { tusb_int_handler(1, true); } #endif void board_led_write(bool state) { if (state) { gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, BOARD_LED_ON_LEVEL); } else { gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, BOARD_LED_OFF_LEVEL); } } uint32_t board_button_read(void) { return (gpio_read_pin(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN) == BOARD_BUTTON_PRESSED_VALUE) ? 1 : 0; } // Get characters from UART. Return number of read bytes int board_uart_read(uint8_t *buf, int len) { int count = 0; hpm_stat_t status; while (count < len) { status = uart_try_receive_byte((UART_Type *)BOARD_CONSOLE_UART_BASE, (uint8_t *)&buf[count]); if (status == status_success) { count++; } else { break; } } return count; } // Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len) { uart_send_data((UART_Type *)BOARD_CONSOLE_UART_BASE, (uint8_t const *)buf, len); return len; } #if CFG_TUSB_OS == OPT_OS_NONE // Get current milliseconds, must be implemented when no RTOS is used uint32_t tusb_time_millis_api(void) { return (hpm_csr_get_core_cycle() / clock_get_core_clock_ticks_per_ms()); } #endif ================================================ FILE: hw/bsp/hpmicro/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/hpmicro/hpm_sdk) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up if (NOT DEFINED CMAKE_SYSTEM_CPU) set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") endif () set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) set(FAMILY_MCUS HPMICRO CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${HPM_SOC}/toolchains/gcc/flash_xip.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${HPM_SOC}/toolchains/gcc/start.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/pinmux.c ${HPM_SOC}/boot/hpm_bootheader.c ${HPM_SOC}/toolchains/gcc/initfini.c ${HPM_SOC}/toolchains/reset.c ${HPM_SOC}/toolchains/trap.c ${HPM_SOC}/system.c ${HPM_SOC}/hpm_sysctl_drv.c ${HPM_SOC}/hpm_clock_drv.c ${HPM_SOC}/hpm_otp_drv.c ${SDK_DIR}/arch/riscv/l1c/hpm_l1c_drv.c ${SDK_DIR}/drivers/src/hpm_gpio_drv.c ${SDK_DIR}/drivers/src/hpm_uart_drv.c ${SDK_DIR}/drivers/src/hpm_usb_drv.c ${SDK_DIR}/drivers/src/hpm_pcfg_drv.c ${SDK_DIR}/drivers/src/hpm_pmp_drv.c ${SDK_DIR}/drivers/src/${HPM_PLLCTL_DRV_FILE} ) target_compile_definitions(${BOARD_TARGET} PUBLIC FLASH_XIP [=[CFG_TUD_MEM_SECTION=__attribute__((section(".noncacheable.non_init")))]=] [=[CFG_TUH_MEM_SECTION=__attribute__((section(".noncacheable.non_init")))]=] ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board ${HPM_SOC} ${HPM_IP_REGS} ${HPM_SOC}/boot ${HPM_SOC}/toolchains ${HPM_SOC}/toolchains/gcc ${SDK_DIR}/arch ${SDK_DIR}/arch/riscv/intc ${SDK_DIR}/arch/riscv/l1c ${SDK_DIR}/drivers/inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_HPM) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${SDK_DIR}/utils/hpm_sbrk.c ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c ${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c ${TOP}/src/portable/ehci/ehci.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${TOP}/src/portable/chipidea/ci_hs ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs -Wl,--defsym,_flash_size=${BOARD_FLASH_SIZE} -Wl,--defsym,_stack_size=${BOARD_STACK_SIZE} -Wl,--defsym,_heap_size=${BOARD_HEAP_SIZE} ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -Wl,--defsym,_flash_size=${BOARD_FLASH_SIZE} -Wl,--defsym,_stack_size=${BOARD_STACK_SIZE} -Wl,--defsym,_heap_size=${BOARD_HEAP_SIZE} ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties( ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${SDK_DIR}/utils/hpm_sbrk.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-cast-align -Wno-discarded-qualifiers" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/hpmicro/family.mk ================================================ SDK_DIR = hw/mcu/hpmicro/hpm_sdk include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 # All source paths should be relative to the top level. LD_FILE = $(HPM_SOC)/toolchains/gcc/flash_xip.ld CFLAGS += \ -DFLASH_XIP \ -DCFG_TUSB_MCU=OPT_MCU_HPM \ -DCFG_TUD_MEM_SECTION='__attribute__((section(".noncacheable.non_init")))' \ -DCFG_TUH_MEM_SECTION='__attribute__((section(".noncacheable.non_init")))' ifdef BOARD_TUD_RHPORT CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT) CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED endif ifdef BOARD_TUH_RHPORT CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT) CFLAGS += -DBOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED endif # mcu driver cause following warnings CFLAGS += -Wno-error=cast-align -Wno-error=double-promotion -Wno-error=discarded-qualifiers \ -Wno-error=undef -Wno-error=unused-parameter -Wno-error=redundant-decls LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs LDFLAGS += -Wl,--defsym,_flash_size=$(BOARD_FLASH_SIZE) LDFLAGS += -Wl,--defsym,_stack_size=$(BOARD_STACK_SIZE) LDFLAGS += -Wl,--defsym,_heap_size=$(BOARD_HEAP_SIZE) SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ src/portable/chipidea/ci_hs/hcd_ci_hs.c \ src/portable/ehci/ehci.c \ ${BOARD_PATH}/board.c \ ${BOARD_PATH}/pinmux.c \ $(HPM_SOC)/boot/hpm_bootheader.c \ $(HPM_SOC)/toolchains/gcc/initfini.c \ $(HPM_SOC)/toolchains/reset.c \ $(HPM_SOC)/toolchains/trap.c \ $(HPM_SOC)/system.c \ $(HPM_SOC)/hpm_sysctl_drv.c \ $(HPM_SOC)/hpm_clock_drv.c \ $(HPM_SOC)/hpm_otp_drv.c \ $(SDK_DIR)/arch/riscv/l1c/hpm_l1c_drv.c \ $(SDK_DIR)/utils/hpm_sbrk.c \ $(SDK_DIR)/drivers/src/hpm_gpio_drv.c \ $(SDK_DIR)/drivers/src/hpm_uart_drv.c \ $(SDK_DIR)/drivers/src/hpm_usb_drv.c \ $(SDK_DIR)/drivers/src/hpm_pcfg_drv.c \ $(SDK_DIR)/drivers/src/hpm_pmp_drv.c \ $(SDK_DIR)/drivers/src/$(HPM_PLLCTL_DRV_FILE) \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/src/portable/chipidea/ci_hs \ $(TOP)/$(HPM_SOC) \ $(TOP)/$(HPM_IP_REGS) \ $(TOP)/$(HPM_SOC)/boot \ $(TOP)/$(HPM_SOC)/toolchains \ $(TOP)/$(HPM_SOC)/toolchains/gcc \ $(TOP)/$(SDK_DIR)/arch \ $(TOP)/$(SDK_DIR)/arch/riscv/intc \ $(TOP)/$(SDK_DIR)/arch/riscv/l1c \ $(TOP)/$(SDK_DIR)/drivers/inc \ SRC_S += $(HPM_SOC)/toolchains/gcc/start.S ================================================ FILE: hw/bsp/imxrt/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting the VDD_SOC to 1.25V. It is necessary to config CORE to 500Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Xbar1); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Init Enet PLL. */ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0); CLOCK_SetMux(kCLOCK_FlexspiSrcMux, 0); #endif /* Disable ADC_ACLK_EN clock gate. */ CCM->CSCMR2 &= ~CCM_CSCMR2_ADC_ACLK_EN_MASK; /* Set ADC_ACLK_PODF. */ CLOCK_SetDiv(kCLOCK_AdcDiv, 11); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); #endif /* Set periph clock source to use the USB1 PLL output (PLL3_SW_CLK) temporarily. */ /* Set Pll3 SW clock source to use the USB1 PLL output. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Set safe value of the AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 1); /* Set periph clock2 clock source to use the PLL3_SW_CLK. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set peripheral clock source (glitchless mux) to select the temporary core clock. */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 40000000UL /* Clock consumers of ADC_ALT_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL /* Clock consumers of CKIL_SYNC_CLK_ROOT output : CSU, EWM, GPT1, GPT2, KPP, PIT, RTWDOG, SNVS, SPDIF, TEMPMON, USB, WDOG1, WDOG2 */ #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL /* Clock consumers of CLKO1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL /* Clock consumers of CLKO2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG */ #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL /* Clock consumers of CLK_24M output : GPT1, GPT2 */ #define BOARD_BOOTCLOCKRUN_CORE_CLK_ROOT 500000000UL /* Clock consumers of CORE_CLK_ROOT output : ARM, FLEXSPI */ #define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL /* Clock consumers of ENET_500M_REF_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL /* Clock consumers of FLEXSPI_CLK_ROOT output : FLEXSPI */ #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : GPT1 */ #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : GPT2 */ #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL /* Clock consumers of IPG_CLK_ROOT output : ADC1, ADC_ETC, AIPSTZ1, AIPSTZ2, AOI, ARM, CCM, CSU, DCDC, DCP, DMA0, DMAMUX, EWM, FLEXIO1, FLEXRAM, FLEXSPI, GPC, GPIO1, GPIO2, GPIO5, IOMUXC, KPP, LPI2C1, LPI2C2, LPSPI1, LPSPI2, LPUART1, LPUART2, LPUART3, LPUART4, OCOTP, PWM1, RTWDOG, SAI1, SAI3, SNVS, SPDIF, SRC, TEMPMON, TRNG, USB, WDOG1, WDOG2, XBARA */ #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL /* Clock consumers of LPI2C_CLK_ROOT output : LPI2C1, LPI2C2 */ #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL /* Clock consumers of LPSPI_CLK_ROOT output : LPSPI1, LPSPI2 */ #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL /* Clock consumers of MQS_MCLK output : N/A */ #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL /* Clock consumers of PERCLK_CLK_ROOT output : GPT1, GPT2, PIT */ #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL /* Clock consumers of SAI1_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL /* Clock consumers of SAI3_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL /* Clock consumers of SPDIF0_CLK_ROOT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL /* Clock consumers of SPDIF0_EXTCLK_OUT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL /* Clock consumers of TRACE_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL /* Clock consumers of UART_CLK_ROOT output : LPUART1, LPUART2, LPUART3, LPUART4 */ #define BOARD_BOOTCLOCKRUN_USBPHY_CLK 480000000UL /* Clock consumers of USBPHY_CLK output : TEMPMON, USB */ /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Enet PLL set for BOARD_BootClockRUN configuration. */ extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v14.0 processor: MIMXRT1011xxxxx package_id: MIMXRT1011DAE5A mcu_data: ksdk2_0 processor_version: 14.0.0 board: MIMXRT1010-EVK external_user_signals: {} pin_labels: - {pin_num: '1', pin_signal: GPIO_11, label: GPIO_11, identifier: GPIO_11} - {pin_num: '10', pin_signal: GPIO_03, label: 'SAI1_RXD0/U10[16]', identifier: LED;USER_LED} - {pin_num: '4', pin_signal: GPIO_08, label: 'SAI1_MCLK/U10[11]', identifier: USER_BUTTON} power_domains: {NVCC_GPIO: '3.3'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '3', peripheral: LPUART1, signal: RXD, pin_signal: GPIO_09} - {pin_num: '2', peripheral: LPUART1, signal: TXD, pin_signal: GPIO_10} - {pin_num: '10', peripheral: GPIO1, signal: 'gpiomux_io, 03', pin_signal: GPIO_03, identifier: USER_LED, direction: OUTPUT} - {pin_num: '4', peripheral: GPIO1, signal: 'gpiomux_io, 08', pin_signal: GPIO_08, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_100K_Ohm} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* GPIO configuration of USER_LED on GPIO_03 (pin 10) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_03 (pin 10) */ GPIO_PinInit(GPIO1, 3U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on GPIO_08 (pin 4) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_08 (pin 4) */ GPIO_PinInit(GPIO1, 8U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_03_GPIOMUX_IO03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_08_GPIOMUX_IO08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_09_LPUART1_RXD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_10_LPUART1_TXD, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_08_GPIOMUX_IO08, 0xB0A0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK 0x08U /*!< Select GPIO1 or GPIO2: affected bits mask */ /* GPIO_09 (number 3), LPUART1_RXD/J56[2] */ /* Routed pin properties */ #define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITPINS_UART1_RXD_SIGNAL RXD /*!< Signal name */ /* GPIO_10 (number 2), LPUART1_TXD/J56[4] */ /* Routed pin properties */ #define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITPINS_UART1_TXD_SIGNAL TXD /*!< Signal name */ /* GPIO_03 (number 10), SAI1_RXD0/U10[16] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpiomux_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ /* GPIO_08 (number 4), SAI1_MCLK/U10[11] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpiomux_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 8U /*!< Signal channel */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board.cmake ================================================ set(MCU_FAMILY RT1010) set(MCU_VARIANT MIMXRT1011) set(JLINK_DEVICE MIMXRT1011xxx5A) set(PYOCD_TARGET mimxrt1010) set(NXPLINK_DEVICE MIMXRT1011xxxxx:EVK-MIMXRT1010) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1010_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1011DAE5A CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Metro M7 1011 url: https://www.adafruit.com/product/5600 */ #ifndef BOARD_M7_1011_H_ #define BOARD_M7_1011_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (8*1024*1024) // LED: IOMUXC_GPIO_03_GPIOMUX_IO03 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 1 // D8 as button: GPIO8 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_09_LPUART1_RXD, IOMUXC_GPIO_10_LPUART1_TXD #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1011DAE5A -DCFG_EXAMPLE_VIDEO_READONLY MCU_FAMILY = RT1010 MCU_VARIANT = MIMXRT1011 # LD file with uf2 LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = MIMXRT1011xxx5A # For flash-pyocd target PYOCD_TARGET = mimxrt1010 # flash using pyocd flash: flash-uf2 flash-uf2: $(BUILD)/$(PROJECT).uf2 @echo copying $< @$(CP) $< /media/$(USER)/METROM7BOOT ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/evkmimxrt1010_flexspi_nor_config.c ================================================ /* * Copyright 2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1010_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 24), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 64u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/evkmimxrt1010_flexspi_nor_config.h ================================================ /* * Copyright 2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.ld ================================================ /* ** ################################################################### ** Processors: MIMXRT1011CAE4A ** MIMXRT1011DAE5A ** ** Compiler: GNU C Compiler ** Reference manual: IMXRT1010RM Rev.0, 09/2019 ** Version: rev. 1.0, 2019-08-01 ** Build: b210709 ** ** Abstract: ** Linker file for the GNU C Compiler ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2021 NXP ** All rights reserved. ** ** SPDX-License-Identifier: BSD-3-Clause ** ** http: www.nxp.com ** mail: support@nxp.com ** ** ################################################################### */ /* Entry Point */ ENTRY(Reset_Handler) HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0; /* Specify the memory areas */ MEMORY { m_flash_config (RX) : ORIGIN = 0x60000400, LENGTH = 0x00000C00 m_ivt (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000 m_interrupts (RX) : ORIGIN = 0x6000C000, LENGTH = 0x00000400 m_text (RX) : ORIGIN = 0x6000C400, LENGTH = (8*1024*1024 - 0xC400) m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00008000 m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00008000 m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00010000 } /* Define output sections */ SECTIONS { __NCACHE_REGION_START = ORIGIN(m_data2); __NCACHE_REGION_SIZE = 0; .flash_config : { . = ALIGN(4); __FLASH_BASE = .; KEEP(* (.boot_hdr.conf)) /* flash config section */ . = ALIGN(4); } > m_flash_config ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config); .ivt : AT(ivt_begin) { . = ALIGN(4); KEEP(* (.boot_hdr.ivt)) /* ivt section */ KEEP(* (.boot_hdr.boot_data)) /* boot section */ KEEP(* (.boot_hdr.dcd_data)) /* dcd section */ . = ALIGN(4); } > m_ivt /* The startup code goes first into internal RAM */ .interrupts : { __VECTOR_TABLE = .; __Vectors = .; . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } > m_interrupts /* The program code and other data goes into internal RAM */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } > m_text .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } > m_text .ctors : { __CTOR_LIST__ = .; /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) __CTOR_END__ = .; } > m_text .dtors : { __DTOR_LIST__ = .; KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) __DTOR_END__ = .; } > m_text .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } > m_text .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } > m_text .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } > m_text __etext = .; /* define a global symbol at end of code */ __DATA_ROM = .; /* Symbol is used by startup for data initialization */ .interrupts_ram : { . = ALIGN(4); __VECTOR_RAM__ = .; __interrupts_ram_start__ = .; /* Create a global symbol at data start */ *(.m_interrupts_ram) /* This is a user defined section */ . += VECTOR_RAM_SIZE; . = ALIGN(4); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > m_data __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; .data : AT(__DATA_ROM) { . = ALIGN(4); __DATA_RAM = .; __data_start__ = .; /* create a global symbol at data start */ *(m_usb_dma_init_data) *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(DataQuickAccess) /* quick access data section */ KEEP(*(.jcr*)) . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ } > m_data __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__); /* Symbol is used by startup for TCM data initialization */ .ram_function : AT(__ram_function_flash_start) { . = ALIGN(32); __ram_function_start__ = .; *(CodeQuickAccess) . = ALIGN(128); __ram_function_end__ = .; } > m_qacode __NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__); .ncache.init : AT(__NDATA_ROM) { __noncachedata_start__ = .; /* create a global symbol at ncache data start */ *(NonCacheable.init) . = ALIGN(4); __noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */ } > m_data . = __noncachedata_init_end__; .ncache : { *(NonCacheable) . = ALIGN(4); __noncachedata_end__ = .; /* define a global symbol at ncache data end */ } > m_data __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") /* Uninitialized data section */ .bss : { /* This is used by the startup in order to initialize the .bss section */ . = ALIGN(4); __START_BSS = .; __bss_start__ = .; *(m_usb_dma_noninit_data) *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; __END_BSS = .; } > m_data .heap : { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; . += HEAP_SIZE; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > m_data .stack : { . = ALIGN(8); . += STACK_SIZE; } > m_data /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data) + LENGTH(m_data); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") } ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.mex ================================================ MIMXRT1011xxxxx MIMXRT1011DAE5A MIMXRT1010-EVK A ksdk2_0 true false false true false 14.0.0 Configures pin routing and optionally pin electrical features. true core0 true true true true true true 14.0.0 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/metro_m7_1011/ozone/metro_m7_1011.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Project.SetTraceSource ("Trace Pins"); Project.SetTraceTiming (50, 50, 50, 50); Project.SetDevice ("MIMXRT1011xxx4A"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("20 MHz"); Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd"); Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); Project.AddSvdFile ("./MIMXRT1011.svd"); // timing delay for trace pins in pico seconds, default is 2 nano seconds File.Open ("../../../../../../examples/cmake-build-metro-m7-1011-sd/device/cdc_msc/cdc_msc.elf"); } /********************************************************************* * * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging a RAM program on a Cortex-M target device * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // Exec.Reset(); // // VectorTableAddr = Elf.GetBaseAddr(); // // if (VectorTableAddr != 0xFFFFFFFF) { // // Util.Log("Resetting Program."); // // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetReset (void) { } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { // // Trace pin init is done by J-Link script file as J-Link script files are IDE independent // //Project.SetJLinkScript("./ST_STM32H743_Traceconfig.pex"); } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetDownload (void) { } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1011xxxxx package_id: MIMXRT1011DAE5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1010-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: ADC_ALT_CLK.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CORE_CLK_ROOT.outFreq, value: 500 MHz} - {id: ENET_500M_REF_CLK.outFreq, value: 500 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 132 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 125 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY_CLK.outFreq, value: 480 MHz} settings: - {id: CCM.ADC_ACLK_PODF.scale, value: '12', locked: true} - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.FLEXSPI_PODF.scale, value: '4', locked: true} - {id: CCM.IPG_PODF.scale, value: '4'} - {id: CCM.LPSPI_PODF.scale, value: '5'} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.PRE_PERIPH_CLK_SEL.sel, value: CCM_ANALOG.ENET_500M_REF_CLK} - {id: CCM.SAI1_CLK_SEL.sel, value: CCM_ANALOG.PLL3_PFD2_CLK} - {id: CCM.SAI3_CLK_SEL.sel, value: CCM_ANALOG.PLL3_PFD2_CLK} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM_ANALOG.PLL2.denom, value: '1'} - {id: CCM_ANALOG.PLL2.num, value: '0'} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD2_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD2_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL2_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '22', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL3_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL6_BYPASS.sel, value: CCM_ANALOG.PLL6} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = { .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting the VDD_SOC to 1.25V. It is necessary to config CORE to 500Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Xbar1); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Init Enet PLL. */ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0); CLOCK_SetMux(kCLOCK_FlexspiSrcMux, 0); #endif /* Disable ADC_ACLK_EN clock gate. */ CCM->CSCMR2 &= ~CCM_CSCMR2_ADC_ACLK_EN_MASK; /* Set ADC_ACLK_PODF. */ CLOCK_SetDiv(kCLOCK_AdcDiv, 11); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); #endif /* Set periph clock source to use the USB1 PLL output (PLL3_SW_CLK) temporarily. */ /* Set Pll3 SW clock source to use the USB1 PLL output. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Set safe value of the AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 1); /* Set periph clock2 clock source to use the PLL3_SW_CLK. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set peripheral clock source (glitchless mux) to select the temporary core clock. */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_CORE_CLK_ROOT 500000000UL #define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY_CLK 480000000UL /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Enet PLL set for BOARD_BootClockRUN configuration. */ extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1011xxxxx package_id: MIMXRT1011DAE5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1010-EVK external_user_signals: {} pin_labels: - {pin_num: '1', pin_signal: GPIO_11, label: GPIO_11, identifier: LED;USERLED;USER_LED} power_domains: {NVCC_GPIO: '3.3'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '70', peripheral: GPIO2, signal: 'gpio_io, 05', pin_signal: GPIO_SD_05, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_47K_Ohm} - {pin_num: '1', peripheral: GPIO1, signal: 'gpiomux_io, 11', pin_signal: GPIO_11, identifier: USER_LED, direction: OUTPUT} - {pin_num: '3', peripheral: LPUART1, signal: RXD, pin_signal: GPIO_09} - {pin_num: '2', peripheral: LPUART1, signal: TXD, pin_signal: GPIO_10} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* GPIO configuration of USER_LED on GPIO_11 (pin 1) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_11 (pin 1) */ GPIO_PinInit(GPIO1, 11U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on GPIO_SD_05 (pin 70) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_SD_05 (pin 70) */ GPIO_PinInit(GPIO2, 5U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_09_LPUART1_RXD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_10_LPUART1_TXD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_11_GPIOMUX_IO11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_05_GPIO2_IO05, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_05_GPIO2_IO05, 0x70A0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK 0x0820U /*!< Select GPIO1 or GPIO2: affected bits mask */ /* GPIO_SD_05 (number 70), USER_BUTTON */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 5U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 5U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 5U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 5U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 5U) /*!< PORT pin mask */ /* GPIO_11 (number 1), GPIO_11 */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpiomux_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 11U /*!< Signal channel */ /* GPIO_09 (number 3), LPUART1_RXD/J56[2] */ /* Routed pin properties */ #define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITPINS_UART1_RXD_SIGNAL RXD /*!< Signal name */ /* GPIO_10 (number 2), LPUART1_TXD/J56[4] */ /* Routed pin properties */ #define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITPINS_UART1_TXD_SIGNAL TXD /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board.cmake ================================================ set(MCU_FAMILY RT1010) set(MCU_VARIANT MIMXRT1011) set(JLINK_DEVICE MIMXRT1011xxx5A) set(PYOCD_TARGET mimxrt1010) set(NXPLINK_DEVICE MIMXRT1011xxxxx:EVK-MIMXRT1010) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1010_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1011DAE5A CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1010 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1010-evaluation-kit:MIMXRT1010-EVK */ #ifndef BOARD_MIMXRT1010_EVK_H_ #define BOARD_MIMXRT1010_EVK_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) // LED: IOMUXC_GPIO_11_GPIOMUX_IO11 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_GPIO_SD_05_GPIO2_IO05 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_09_LPUART1_RXD, IOMUXC_GPIO_10_LPUART1_TXD #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1011DAE5A -DCFG_EXAMPLE_VIDEO_READONLY MCU_FAMILY = RT1010 MCU_VARIANT = MIMXRT1011 # For flash-jlink target JLINK_DEVICE = MIMXRT1011xxx5A # For flash-pyocd target PYOCD_TARGET = mimxrt1010 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.c ================================================ /* * Copyright 2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1010_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h ================================================ /* * Copyright 2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1010_evk/mimxrt1010_evk.mex ================================================ MIMXRT1011xxxxx MIMXRT1011DAE5A MIMXRT1010-EVK A ksdk2_0 true false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v15.0 processor: MIMXRT1015xxxxx package_id: MIMXRT1015DAF5A mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1015-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 500 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: ENET_500M_REF_CLK.outFreq, value: 500 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 2160/11 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 125 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 352/3 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '1', locked: true} - {id: CCM.CLKO2_SEL.sel, value: CCM.LPI2C_CLK_ROOT} - {id: CCM.FLEXSPI_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.IPG_PODF.scale, value: '4'} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.PRE_PERIPH_CLK_SEL.sel, value: CCM.ARM_PODF} - {id: CCM.SEMC_PODF.scale, value: '2'} - {id: CCM.TRACE_PODF.scale, value: '3', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD2_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD2_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL2_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '22', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL3_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL6_BYPASS.sel, value: CCM_ANALOG.PLL6} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = { .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.25V. It is necessary to config AHB to 500Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 0); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 1); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 3); #endif /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 2); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 2); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Enet PLL. */ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(6); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 500000000UL /* Clock consumers of AHB_CLK_ROOT output : AIPSTZ1, AIPSTZ2, AIPSTZ3, AIPSTZ4, ARM, FLEXSPI */ #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL /* Clock consumers of CKIL_SYNC_CLK_ROOT output : CSU, EWM, GPT1, GPT2, KPP, PIT, RTWDOG, SNVS, SPDIF, TEMPMON, USB, WDOG1, WDOG2 */ #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL /* Clock consumers of CLKO1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL /* Clock consumers of CLKO2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG */ #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL /* Clock consumers of CLK_24M output : GPT1, GPT2 */ #define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL /* Clock consumers of ENET_500M_REF_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 196363636UL /* Clock consumers of FLEXSPI_CLK_ROOT output : FLEXSPI */ #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : GPT1 */ #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : GPT2 */ #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL /* Clock consumers of IPG_CLK_ROOT output : ADC1, ADC_ETC, AOI, ARM, BEE, CCM, CSU, DCDC, DCP, DMA0, DMAMUX, ENC1, EWM, FLEXIO1, FLEXRAM, FLEXSPI, GPC, GPIO1, GPIO2, GPIO3, GPIO5, IOMUXC, KPP, LPI2C1, LPI2C2, LPSPI1, LPSPI2, LPUART1, LPUART2, LPUART3, LPUART4, NVIC, OCOTP, PWM1, RTWDOG, SAI1, SAI2, SAI3, SNVS, SPDIF, SRC, TEMPMON, TMR1, TRNG, USB, WDOG1, WDOG2, XBARA, XBARB */ #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL /* Clock consumers of LPI2C_CLK_ROOT output : LPI2C1, LPI2C2 */ #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL /* Clock consumers of LPSPI_CLK_ROOT output : LPSPI1, LPSPI2 */ #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL /* Clock consumers of MQS_MCLK output : N/A */ #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL /* Clock consumers of PERCLK_CLK_ROOT output : GPT1, GPT2, PIT */ #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL /* Clock consumers of SAI1_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL /* Clock consumers of SAI2_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL /* Clock consumers of SAI2_MCLK1 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL /* Clock consumers of SAI2_MCLK2 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL /* Clock consumers of SAI2_MCLK3 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL /* Clock consumers of SAI3_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL /* Clock consumers of SPDIF0_CLK_ROOT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL /* Clock consumers of SPDIF0_EXTCLK_OUT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 117333333UL /* Clock consumers of TRACE_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL /* Clock consumers of UART_CLK_ROOT output : LPUART1, LPUART2, LPUART3, LPUART4 */ #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL /* Clock consumers of USBPHY1_CLK output : TEMPMON, USB */ /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Enet PLL set for BOARD_BootClockRUN configuration. */ extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: MIMXRT1015xxxxx package_id: MIMXRT1015DAF5A mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1015-EVK external_user_signals: {} pin_labels: - {pin_num: '21', pin_signal: GPIO_SD_B1_01, label: GPIO SD_B1_01, identifier: USER_LED} power_domains: {NVCC_GPIO: '3.3'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '1', peripheral: GPIO2, signal: 'gpio_io, 09', pin_signal: GPIO_EMC_09, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_47K_Ohm} - {pin_num: '21', peripheral: GPIO3, signal: 'gpio_io, 21', pin_signal: GPIO_SD_B1_01, direction: OUTPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* GPIO configuration of USER_BUTTON on GPIO_EMC_09 (pin 1) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_EMC_09 (pin 1) */ GPIO_PinInit(GPIO2, 9U, &USER_BUTTON_config); /* GPIO configuration of USER_LED on GPIO_SD_B1_01 (pin 21) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_SD_B1_01 (pin 21) */ GPIO_PinInit(GPIO3, 21U, &USER_LED_config); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_GPIO2_IO09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_GPIO3_IO21, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_09_GPIO2_IO09, 0x70B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '12', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: '11', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: '9', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} - {pin_num: '10', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} - {pin_num: '13', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} - {pin_num: '8', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '68', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07, slew_rate: Slow} - {pin_num: '72', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_06_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_06_LPUART1_TX, 0x10B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0x10B0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /* GPIO_EMC_09 (number 1), USER_BUTTON/SW4 */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 9U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 9U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 9U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 9U) /*!< PORT pin mask */ /* GPIO_SD_B1_01 (number 21), GPIO SD_B1_01 */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO3 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 21U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO3 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 21U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 21U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO3 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 21U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 21U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_SD_B1_07 (number 12), FlexSPI_CLK_A/U13[6] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_08 (number 11), FlexSPI_D0_A/U13[5] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_10 (number 9), FlexSPI_D1_A/U13[2] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_09 (number 10), FlexSPI_D2_A/U13[3] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_06 (number 13), FlexSPI_D3_A/U13[7] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_11 (number 8), FlexSPI_SS0/U13[1] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); /* GPIO_AD_B0_07 (number 68), LPUART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /* GPIO_AD_B0_06 (number 72), LPUART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board.cmake ================================================ set(MCU_FAMILY RT1015) set(MCU_VARIANT MIMXRT1015) set(JLINK_DEVICE MIMXRT1015DAF5A) set(PYOCD_TARGET mimxrt1015) set(NXPLINK_DEVICE MIMXRT1015xxxxx:EVK-MIMXRT1015) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1015_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1015DAF5A CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1015 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1015-EVK */ #ifndef BOARD_MIMXRT1015_EVK_H_ #define BOARD_MIMXRT1015_EVK_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) // LED #define LED_PINMUX IOMUXC_GPIO_SD_B1_01_GPIO3_IO21 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button #define BUTTON_PINMUX IOMUXC_GPIO_EMC_09_GPIO2_IO09 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT #define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX #define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1015DAF5A -DCFG_EXAMPLE_VIDEO_READONLY MCU_FAMILY = RT1015 MCU_VARIANT = MIMXRT1015 # For flash-jlink target JLINK_DEVICE = MIMXRT1015DAF5A # For flash-pyocd target PYOCD_TARGET = mimxrt1015 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.c ================================================ /* * Copyright 2018-2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1015_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h ================================================ /* * Copyright 2018-2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_133MHz = 7, kFlexSpiSerialClk_166MHz = 8, kFlexSpiSerialClk_200MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1015_evk/mimxrt1015_evk.mex ================================================ MIMXRT1015xxxxx MIMXRT1015DAF5A MIMXRT1015-EVK B ksdk2_0 true false true false 24.12.10 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true 24.12.10 true INPUT true OUTPUT true INPUT true OUTPUT true true true N/A 13.0.2 N/A ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1021xxxxx package_id: MIMXRT1021DAG5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1020-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 500 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: ENET_500M_REF_CLK.outFreq, value: 500 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 132 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 125 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 176 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 176 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '1', locked: true} - {id: CCM.FLEXSPI_PODF.scale, value: '4', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL2_PFD2_CLK} - {id: CCM.IPG_PODF.scale, value: '4'} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.PRE_PERIPH_CLK_SEL.sel, value: CCM.ARM_PODF} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM.USDHC1_PODF.scale, value: '3', locked: true} - {id: CCM.USDHC2_PODF.scale, value: '3', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD2_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD2_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL2_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '22', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL3_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL6_BYPASS.sel, value: CCM_ANALOG.PLL6} - {id: CCM_ANALOG_PLL_ENET_ENABLE_CFG, value: Disabled} - {id: CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_CFG, value: Disabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = { .enableClkOutput = false, /* Disable the PLL providing the ENET 125MHz reference clock */ .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */ .enableClkOutput25M = false, /* Disable the PLL providing the ENET 25MHz reference clock */ .loopDivider = 1, /* Set frequency of ethernet reference clock to 50 MHz */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.25V. It is necessary to config AHB to 500Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 0); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 2); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 2); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 2); #endif /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Enet PLL. */ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(3); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ #if defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK; #elif defined(IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK) /* Backward compatibility for original bitfield name */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; #else #error "Neither IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK nor IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK is defined." #endif /* defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) */ /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 500000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 62500000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 176000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 176000000UL /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Enet PLL set for BOARD_BootClockRUN configuration. */ extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1021xxxxx package_id: MIMXRT1021DAG5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1020-EVK external_user_signals: {} pin_labels: - {pin_num: '52', pin_signal: WAKEUP, label: USER_BUTTON, identifier: USER_BUTTON} - {pin_num: '106', pin_signal: GPIO_AD_B0_05, label: 'JTAG_nTRST/J16[3]/USER_LED/J17[5]', identifier: USER_LED} power_domains: {NVCC_GPIO: '3.3'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '52', peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} - {pin_num: '106', peripheral: GPIO1, signal: 'gpio_io, 05', pin_signal: GPIO_AD_B0_05, direction: OUTPUT, pull_keeper_select: Keeper} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* GPIO configuration of USER_LED on GPIO_AD_B0_05 (pin 106) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_B0_05 (pin 106) */ GPIO_PinInit(GPIO1, 5U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP (pin 52) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP (pin 52) */ GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05, 0U); IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05, 0x50A0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07} - {pin_num: '105', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_06_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDRAMPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '142', peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_16} - {pin_num: '141', peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_17} - {pin_num: '140', peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_18} - {pin_num: '139', peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_19} - {pin_num: '138', peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_20} - {pin_num: '136', peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_22} - {pin_num: '137', peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_21} - {pin_num: '133', peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_23} - {pin_num: '132', peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_24} - {pin_num: '131', peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_25} - {pin_num: '143', peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_15} - {pin_num: '130', peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_26} - {pin_num: '129', peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_27} - {pin_num: '2', peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_13} - {pin_num: '1', peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_14} - {pin_num: '7', peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_10} - {pin_num: '127', peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_29} - {pin_num: '126', peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_30} - {pin_num: '3', peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_12} - {pin_num: '8', peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_09} - {pin_num: '4', peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_11} - {pin_num: '128', peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_28} - {pin_num: '125', peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_31} - {pin_num: '9', peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} - {pin_num: '117', peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_39} - {pin_num: '118', peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_38} - {pin_num: '119', peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_37} - {pin_num: '120', peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_36} - {pin_num: '122', peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_34} - {pin_num: '121', peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_35} - {pin_num: '123', peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_33} - {pin_num: '124', peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_32} - {pin_num: '10', peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} - {pin_num: '12', peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} - {pin_num: '13', peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} - {pin_num: '14', peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} - {pin_num: '15', peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} - {pin_num: '16', peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} - {pin_num: '17', peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} - {pin_num: '18', peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDRAMPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDRAMPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_WE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_CAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_RAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_CS0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_BA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_BA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_ADDR05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_ADDR06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_ADDR08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_ADDR09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_ADDR11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_ADDR12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_DQS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CKE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DM01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DATA15, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCANPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '32', peripheral: CAN1, signal: RX, pin_signal: GPIO_SD_B1_01} - {pin_num: '33', peripheral: CAN1, signal: TX, pin_signal: GPIO_SD_B1_00} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCANPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCANPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXCAN1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXCAN1_RX, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENETPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_AD_B0_11} - {pin_num: '84', peripheral: GPIO1, signal: 'gpio_io, 22', pin_signal: GPIO_AD_B1_06} - {pin_num: '107', peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} - {pin_num: '100', peripheral: ENET, signal: enet_tx_clk, pin_signal: GPIO_AD_B0_08} - {pin_num: '95', peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_AD_B0_13} - {pin_num: '93', peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_AD_B0_15} - {pin_num: '94', peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_AD_B0_14} - {pin_num: '96', peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_AD_B0_12} - {pin_num: '99', peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_AD_B0_09} - {pin_num: '98', peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_AD_B0_10} - {pin_num: '116', peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_40} - {pin_num: '115', peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_41} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENETPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENETPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_08_ENET_TX_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_ENET_RDATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_ENET_RDATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_ENET_RX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_ENET_RX_ER, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_ENET_TX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_ENET_TDATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_ENET_TDATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDIO, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDC, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '45', peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_03} - {pin_num: '46', peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_02} - {pin_num: '43', peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_04} - {pin_num: '42', peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_05} - {pin_num: '48', peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_00} - {pin_num: '47', peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_01} - {pin_num: '41', peripheral: GPIO3, signal: 'gpio_io, 19', pin_signal: GPIO_SD_B0_06} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_DATA3, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_06_GPIO3_IO19, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '24', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: '23', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: '21', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} - {pin_num: '22', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} - {pin_num: '25', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} - {pin_num: '19', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, 0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /* WAKEUP (number 52), USER_BUTTON */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ /* GPIO_AD_B0_05 (number 106), JTAG_nTRST/J16[3]/USER_LED/J17[5] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 5U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 5U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 5U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 5U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 5U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_07 (number 101), UART1_RXD/J17[4] */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /* GPIO_AD_B0_06 (number 105), UART1_TXD/J17[6] */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_EMC_16 (number 142), SEMC_A0/U14[23]/BOOT_MODE[0] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_17 (number 141), SEMC_A1/U14[24]/BOOT_MODE[1] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_18 (number 140), SEMC_A2/U14[25]/BT_CFG[0] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_19 (number 139), SEMC_A3/U14[26]/BT_CFG[1] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_20 (number 138), SEMC_A4/U14[29]/BT_CFG[2] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_22 (number 136), SEMC_A6/U14[31]/BT_CFG[4] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_21 (number 137), SEMC_A5/U14[30]/BT_CFG[3] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_23 (number 133), SEMC_A7/U14[32]/BT_CFG[5] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_24 (number 132), SEMC_A8/U14[33]/BT_CFG[6] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_25 (number 131), SEMC_A9/U14[34]/BT_CFG[7] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_15 (number 143), SEMC_A10/U14[22] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_26 (number 130), SEMC_A11/U14[35]/BT_CFG[8] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_27 (number 129), SEMC_A12/U14[36]/BT_CFG[9] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_13 (number 2), SEMC_BA0/U14[20] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_14 (number 1), SEMC_BA1/U14[21] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_10 (number 7), SEMC_CAS/U14[17] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ /* GPIO_EMC_29 (number 127), SEMC_CKE/U14[37] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ /* GPIO_EMC_30 (number 126), SEMC_CLK/U14[38] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ /* GPIO_EMC_12 (number 3), SEMC_CS0/U14[19] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_09 (number 8), SEMC_WE/U14[16] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ /* GPIO_EMC_11 (number 4), SEMC_RAS/U14[18] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ /* GPIO_EMC_28 (number 128), SEMC_DQS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ /* GPIO_EMC_31 (number 125), SEMC_DM1/U14[39] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_08 (number 9), SEMC_DM0/U14[15] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_39 (number 117), SEMC_D15/U14[53] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_EMC_38 (number 118), SEMC_D14/U14[51] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_EMC_37 (number 119), SEMC_D13/U14[50] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_EMC_36 (number 120), SEMC_D12/U14[48] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_34 (number 122), SEMC_D10/U14[45] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_35 (number 121), SEMC_D11/U14[47] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_33 (number 123), SEMC_D9/U14[44] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_32 (number 124), SEMC_D8/U14[42] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_07 (number 10), SEMC_D7/U14[13] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_06 (number 12), SEMC_D6/U14[11] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_05 (number 13), SEMC_D5/U14[10] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_04 (number 14), SEMC_D4/U14[8] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_03 (number 15), SEMC_D3/U14[7] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_02 (number 16), SEMC_D2/U14[5] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_01 (number 17), SEMC_D1/U14[4] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_00 (number 18), SEMC_D0/U14[2] */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDRAMPins(void); /* GPIO_SD_B1_01 (number 32), CAN1_RX/U9[4] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN1_RX_PERIPHERAL CAN1 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN1_RX_SIGNAL RX /*!< Signal name */ /* GPIO_SD_B1_00 (number 33), CAN1_TX/U9[1] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN1_TX_PERIPHERAL CAN1 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN1_TX_SIGNAL TX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCANPins(void); /* GPIO_AD_B0_11 (number 97), ENET_CRS_DV/U11[18]/J19[3] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ /* GPIO_AD_B1_06 (number 84), ENET_INT/U11[21]/J17[8] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_INT_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_INT_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITENETPINS_ENET_INT_CHANNEL 22U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITENETPINS_ENET_INT_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITENETPINS_ENET_INT_GPIO_PIN 22U /*!< GPIO pin number */ #define BOARD_INITENETPINS_ENET_INT_GPIO_PIN_MASK (1U << 22U) /*!< GPIO pin mask */ #define BOARD_INITENETPINS_ENET_INT_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITENETPINS_ENET_INT_PIN 22U /*!< PORT pin number */ #define BOARD_INITENETPINS_ENET_INT_PIN_MASK (1U << 22U) /*!< PORT pin mask */ /* GPIO_AD_B0_04 (number 107), JTAG_TDO/J16[13]/ENET_RST/U11[32] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RST_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RST_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RST_CHANNEL 4U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITENETPINS_ENET_RST_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITENETPINS_ENET_RST_GPIO_PIN 4U /*!< GPIO pin number */ #define BOARD_INITENETPINS_ENET_RST_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ #define BOARD_INITENETPINS_ENET_RST_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITENETPINS_ENET_RST_PIN 4U /*!< PORT pin number */ #define BOARD_INITENETPINS_ENET_RST_PIN_MASK (1U << 4U) /*!< PORT pin mask */ /* GPIO_AD_B0_08 (number 100), ENET_TX_CLK/U11[9] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_tx_clk /*!< Signal name */ /* GPIO_AD_B0_13 (number 95), ENET_TXEN/U11[23]/J19[5] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ /* GPIO_AD_B0_15 (number 93), ENET_TXD1/U11[25]/J19[2] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_AD_B0_14 (number 94), ENET_TXD0/U11[24]/J17[7] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_AD_B0_12 (number 96), ENET_RXER/U11[20]/J19[4] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ /* GPIO_AD_B0_09 (number 99), ENET_RXD1/U11[15]/J17[3] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_AD_B0_10 (number 98), ENET_RXD0/U11[16]/J19[6] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_40 (number 116), ENET_MDIO/U11[11] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ /* GPIO_EMC_41 (number 115), ENET_MDC/U11[12] */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENETPins(void); /* GPIO_SD_B0_03 (number 45), SD1_CLK/J15[5] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /* GPIO_SD_B0_02 (number 46), SD1_CMD/J15[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_04 (number 43), SD1_D0/J15[7] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_05 (number 42), SD1_D1/J15[8] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_00 (number 48), SD1_D2/J15[1] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_01 (number 47), SD1_D3/J15[2] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_06 (number 41), SD_CD_SW/J15[9] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PERIPHERAL GPIO3 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD_CD_SW_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD_CD_SW_CHANNEL 19U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO GPIO3 /*!< GPIO peripheral base pointer */ #define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO_PIN 19U /*!< GPIO pin number */ #define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO_PIN_MASK (1U << 19U) /*!< GPIO pin mask */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PORT GPIO3 /*!< PORT peripheral base pointer */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PIN 19U /*!< PORT pin number */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PIN_MASK (1U << 19U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_07 (number 24), FlexSPI_CLK/U13[6] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_08 (number 23), FlexSPI_D0_A/U13[5] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_10 (number 21), FlexSPI_D1_A/U13[2] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_09 (number 22), FlexSPI_D2_A/U13[3] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_06 (number 25), FlexSPI_D3_A/U13[7] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_11 (number 19), FlexSPI_SS0/U13[1] */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board.cmake ================================================ set(MCU_FAMILY RT1020) set(MCU_VARIANT MIMXRT1021) set(JLINK_DEVICE MIMXRT1021xxx5A) set(PYOCD_TARGET mimxrt1020) set(NXPLINK_DEVICE MIMXRT1021xxxxx:EVK-MIMXRT1020) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1020_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1021DAG5A ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1020 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1020-EVK */ #ifndef BOARD_MIMXRT1020_EVK_H_ #define BOARD_MIMXRT1020_EVK_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x800000U) // LED: IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_07_LPUART1_RX, IOMUXC_GPIO_AD_B0_06_LPUART1_TX #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1021DAG5A MCU_FAMILY = RT1020 MCU_VARIANT = MIMXRT1021 # For flash-jlink target JLINK_DEVICE = MIMXRT1021xxx5A # For flash-pyocd target PYOCD_TARGET = mimxrt1020 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.c ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1020_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_133MHz = 7, kFlexSpiSerialClk_166MHz = 8, kFlexSpiSerialClk_200MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1020_evk/mimxrt1020_evk.mex ================================================ MIMXRT1021xxxxx MIMXRT1021DAG5A MIMXRT1020-EVK A3 ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 13.0.2 c_array 13.0.2 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1024xxxxx package_id: MIMXRT1024DAG5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1024-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 500 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: ENET_500M_REF_CLK.outFreq, value: 500 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 132 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 62.5 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 125 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 62.5 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 176 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 176 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '1', locked: true} - {id: CCM.FLEXSPI_PODF.scale, value: '4', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL2_PFD2_CLK} - {id: CCM.IPG_PODF.scale, value: '4'} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.PRE_PERIPH_CLK_SEL.sel, value: CCM.ARM_PODF} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM.USDHC1_PODF.scale, value: '3', locked: true} - {id: CCM.USDHC2_PODF.scale, value: '3', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD2_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD2_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL2_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL2_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '22', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL3_PFD3_DIV.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD3_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL6_BYPASS.sel, value: CCM_ANALOG.PLL6} - {id: CCM_ANALOG_PLL_ENET_ENABLE_CFG, value: Disabled} - {id: CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_CFG, value: Disabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = { .enableClkOutput = false, /* Disable the PLL providing the ENET 125MHz reference clock */ .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */ .enableClkOutput25M = false, /* Disable the PLL providing the ENET 25MHz reference clock */ .loopDivider = 1, /* Set frequency of ethernet reference clock to 50 MHz */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.25V. It is necessary to config AHB to 500Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 0); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 2); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 2); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 2); #endif /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Enet PLL. */ CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(3); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ #if defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK; #elif defined(IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK) /* Backward compatibility for original bitfield name */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; #else #error "Neither IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK nor IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK is defined." #endif /* defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) */ /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 500000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 62500000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 176000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 176000000UL /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Enet PLL set for BOARD_BootClockRUN configuration. */ extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1024xxxxx package_id: MIMXRT1024DAG5A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1024-EVK pin_labels: - {pin_num: '52', pin_signal: WAKEUP, label: USER_BUTTON, identifier: USER_BUTTON} - {pin_num: '82', pin_signal: GPIO_AD_B1_08, label: 'UART_TX/USER_LED/J17[4]', identifier: USER_LED} power_domains: {NVCC_GPIO: '3.3'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); /* GPIO_AD_B1_00~GPIO_AD_B1_05 can only be configured as flexspi function. Note that it can't be modified here */ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_FLEXSPI_A_DATA03,1U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_FLEXSPI_A_SCLK,1U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_02_FLEXSPI_A_DATA00,1U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_03_FLEXSPI_A_DATA02,1U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_FLEXSPI_A_DATA01,1U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_FLEXSPI_A_SS0_B,1U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '52', peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} - {pin_num: '82', peripheral: GPIO1, signal: 'gpio_io, 24', pin_signal: GPIO_AD_B1_08, direction: OUTPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* iomuxc_snvs clock (iomuxc_snvs_clk_enable): 0x03U */ /* GPIO configuration of USER_LED on GPIO_AD_B1_08 (pin 82) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_B1_08 (pin 82) */ GPIO_PinInit(GPIO1, 24U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP (pin 52) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP (pin 52) */ GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_08_GPIO1_IO24, /* GPIO_AD_B1_08 is configured as GPIO1_IO24 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_SNVS_WAKEUP_GPIO5_IO00, /* WAKEUP is configured as GPIO5_IO00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07} - {pin_num: '105', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_06_LPUART1_TX, /* GPIO_AD_B0_06 is configured as LPUART1_TX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_07_LPUART1_RX, /* GPIO_AD_B0_07 is configured as LPUART1_RX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDRAMPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '142', peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_16} - {pin_num: '141', peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_17} - {pin_num: '140', peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_18} - {pin_num: '139', peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_19} - {pin_num: '138', peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_20} - {pin_num: '136', peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_22} - {pin_num: '137', peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_21} - {pin_num: '133', peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_23} - {pin_num: '132', peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_24} - {pin_num: '131', peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_25} - {pin_num: '143', peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_15} - {pin_num: '130', peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_26} - {pin_num: '129', peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_27} - {pin_num: '2', peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_13} - {pin_num: '1', peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_14} - {pin_num: '7', peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_10} - {pin_num: '127', peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_29} - {pin_num: '126', peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_30} - {pin_num: '3', peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_12} - {pin_num: '8', peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_09} - {pin_num: '4', peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_11} - {pin_num: '128', peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_28} - {pin_num: '125', peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_31} - {pin_num: '9', peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} - {pin_num: '117', peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_39} - {pin_num: '118', peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_38} - {pin_num: '119', peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_37} - {pin_num: '120', peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_36} - {pin_num: '122', peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_34} - {pin_num: '121', peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_35} - {pin_num: '123', peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_33} - {pin_num: '124', peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_32} - {pin_num: '10', peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} - {pin_num: '12', peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} - {pin_num: '13', peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} - {pin_num: '14', peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} - {pin_num: '15', peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} - {pin_num: '16', peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} - {pin_num: '17', peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} - {pin_num: '18', peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDRAMPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDRAMPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 is configured as SEMC_DATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_01_SEMC_DATA01, /* GPIO_EMC_01 is configured as SEMC_DATA01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_02_SEMC_DATA02, /* GPIO_EMC_02 is configured as SEMC_DATA02 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_03_SEMC_DATA03, /* GPIO_EMC_03 is configured as SEMC_DATA03 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_04_SEMC_DATA04, /* GPIO_EMC_04 is configured as SEMC_DATA04 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_05_SEMC_DATA05, /* GPIO_EMC_05 is configured as SEMC_DATA05 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_06_SEMC_DATA06, /* GPIO_EMC_06 is configured as SEMC_DATA06 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_07_SEMC_DATA07, /* GPIO_EMC_07 is configured as SEMC_DATA07 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_08_SEMC_DM00, /* GPIO_EMC_08 is configured as SEMC_DM00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_09_SEMC_WE, /* GPIO_EMC_09 is configured as SEMC_WE */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_10_SEMC_CAS, /* GPIO_EMC_10 is configured as SEMC_CAS */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_11_SEMC_RAS, /* GPIO_EMC_11 is configured as SEMC_RAS */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_12_SEMC_CS0, /* GPIO_EMC_12 is configured as SEMC_CS0 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_13_SEMC_BA0, /* GPIO_EMC_13 is configured as SEMC_BA0 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_14_SEMC_BA1, /* GPIO_EMC_14 is configured as SEMC_BA1 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_15_SEMC_ADDR10, /* GPIO_EMC_15 is configured as SEMC_ADDR10 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_16_SEMC_ADDR00, /* GPIO_EMC_16 is configured as SEMC_ADDR00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_17_SEMC_ADDR01, /* GPIO_EMC_17 is configured as SEMC_ADDR01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_18_SEMC_ADDR02, /* GPIO_EMC_18 is configured as SEMC_ADDR02 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_19_SEMC_ADDR03, /* GPIO_EMC_19 is configured as SEMC_ADDR03 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_20_SEMC_ADDR04, /* GPIO_EMC_20 is configured as SEMC_ADDR04 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_21_SEMC_ADDR05, /* GPIO_EMC_21 is configured as SEMC_ADDR05 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_22_SEMC_ADDR06, /* GPIO_EMC_22 is configured as SEMC_ADDR06 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_23_SEMC_ADDR07, /* GPIO_EMC_23 is configured as SEMC_ADDR07 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_24_SEMC_ADDR08, /* GPIO_EMC_24 is configured as SEMC_ADDR08 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_25_SEMC_ADDR09, /* GPIO_EMC_25 is configured as SEMC_ADDR09 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_26_SEMC_ADDR11, /* GPIO_EMC_26 is configured as SEMC_ADDR11 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_27_SEMC_ADDR12, /* GPIO_EMC_27 is configured as SEMC_ADDR12 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_28_SEMC_DQS, /* GPIO_EMC_28 is configured as SEMC_DQS */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_29_SEMC_CKE, /* GPIO_EMC_29 is configured as SEMC_CKE */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_30_SEMC_CLK, /* GPIO_EMC_30 is configured as SEMC_CLK */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_31_SEMC_DM01, /* GPIO_EMC_31 is configured as SEMC_DM01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_32_SEMC_DATA08, /* GPIO_EMC_32 is configured as SEMC_DATA08 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_33_SEMC_DATA09, /* GPIO_EMC_33 is configured as SEMC_DATA09 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_34_SEMC_DATA10, /* GPIO_EMC_34 is configured as SEMC_DATA10 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_35_SEMC_DATA11, /* GPIO_EMC_35 is configured as SEMC_DATA11 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_36_SEMC_DATA12, /* GPIO_EMC_36 is configured as SEMC_DATA12 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_37_SEMC_DATA13, /* GPIO_EMC_37 is configured as SEMC_DATA13 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_38_SEMC_DATA14, /* GPIO_EMC_38 is configured as SEMC_DATA14 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_39_SEMC_DATA15, /* GPIO_EMC_39 is configured as SEMC_DATA15 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCANPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '32', peripheral: CAN1, signal: RX, pin_signal: GPIO_SD_B1_01} - {pin_num: '33', peripheral: CAN1, signal: TX, pin_signal: GPIO_SD_B1_00} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCANPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCANPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_00_FLEXCAN1_TX, /* GPIO_SD_B1_00 is configured as FLEXCAN1_TX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_01_FLEXCAN1_RX, /* GPIO_SD_B1_01 is configured as FLEXCAN1_RX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENETPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_AD_B0_11} - {pin_num: '84', peripheral: GPIO1, signal: 'gpio_io, 22', pin_signal: GPIO_AD_B1_06} - {pin_num: '107', peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} - {pin_num: '100', peripheral: ENET, signal: enet_tx_clk, pin_signal: GPIO_AD_B0_08} - {pin_num: '95', peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_AD_B0_13} - {pin_num: '93', peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_AD_B0_15} - {pin_num: '94', peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_AD_B0_14} - {pin_num: '96', peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_AD_B0_12} - {pin_num: '99', peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_AD_B0_09} - {pin_num: '98', peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_AD_B0_10} - {pin_num: '116', peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_40} - {pin_num: '115', peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_41} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENETPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENETPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, /* GPIO_AD_B0_04 is configured as GPIO1_IO04 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_08_ENET_TX_CLK, /* GPIO_AD_B0_08 is configured as ENET_TX_CLK */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_09_ENET_RDATA01, /* GPIO_AD_B0_09 is configured as ENET_RDATA01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_10_ENET_RDATA00, /* GPIO_AD_B0_10 is configured as ENET_RDATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_11_ENET_RX_EN, /* GPIO_AD_B0_11 is configured as ENET_RX_EN */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_12_ENET_RX_ER, /* GPIO_AD_B0_12 is configured as ENET_RX_ER */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_13_ENET_TX_EN, /* GPIO_AD_B0_13 is configured as ENET_TX_EN */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_14_ENET_TDATA00, /* GPIO_AD_B0_14 is configured as ENET_TDATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_15_ENET_TDATA01, /* GPIO_AD_B0_15 is configured as ENET_TDATA01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, /* GPIO_AD_B1_06 is configured as GPIO1_IO22 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_40_ENET_MDIO, /* GPIO_EMC_40 is configured as ENET_MDIO */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_41_ENET_MDC, /* GPIO_EMC_41 is configured as ENET_MDC */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '45', peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_03} - {pin_num: '46', peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_02} - {pin_num: '43', peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_04} - {pin_num: '42', peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_05} - {pin_num: '48', peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_00} - {pin_num: '47', peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_01} - {pin_num: '41', peripheral: GPIO3, signal: 'gpio_io, 19', pin_signal: GPIO_SD_B0_06} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_00_USDHC1_DATA2, /* GPIO_SD_B0_00 is configured as USDHC1_DATA2 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_01_USDHC1_DATA3, /* GPIO_SD_B0_01 is configured as USDHC1_DATA3 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_02_USDHC1_CMD, /* GPIO_SD_B0_02 is configured as USDHC1_CMD */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_03_USDHC1_CLK, /* GPIO_SD_B0_03 is configured as USDHC1_CLK */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_04_USDHC1_DATA0, /* GPIO_SD_B0_04 is configured as USDHC1_DATA0 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_05_USDHC1_DATA1, /* GPIO_SD_B0_05 is configured as USDHC1_DATA1 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B0_06_GPIO3_IO19, /* GPIO_SD_B0_06 is configured as GPIO3_IO19 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '24', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: '23', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: '21', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} - {pin_num: '22', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} - {pin_num: '25', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} - {pin_num: '19', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, /* GPIO_SD_B1_06 is configured as FLEXSPI_A_DATA03 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPI_A_SCLK */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPI_A_DATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, /* GPIO_SD_B1_09 is configured as FLEXSPI_A_DATA02 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, /* GPIO_SD_B1_10 is configured as FLEXSPI_A_DATA01 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, /* GPIO_SD_B1_11 is configured as FLEXSPI_A_SS0_B */ 0U); /* Software Input On Field: Input Path is determined by functionality */ } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /* Define the flexspi macro. Note that it can't be modified here */ #define IOMUXC_GPIO_AD_B1_00_FLEXSPI_A_DATA03 0x401F80FCU, 0x1U, 0x401F8374U, 0x1U, 0x401F8270U #define IOMUXC_GPIO_AD_B1_01_FLEXSPI_A_SCLK 0x401F8100U, 0x1U, 0x401F8378U, 0x1U, 0x401F8274U #define IOMUXC_GPIO_AD_B1_02_FLEXSPI_A_DATA00 0x401F8104U, 0x1U, 0x401F8368U, 0x1U, 0x401F8278U #define IOMUXC_GPIO_AD_B1_03_FLEXSPI_A_DATA02 0x401F8108U, 0x1U, 0x401F8370U, 0x1U, 0x401F827CU #define IOMUXC_GPIO_AD_B1_04_FLEXSPI_A_DATA01 0x401F810CU, 0x1U, 0x401F836CU, 0x1U, 0x401F8280U #define IOMUXC_GPIO_AD_B1_05_FLEXSPI_A_SS0_B 0x401F8110U, 0x1U, 0, 0, 0x401F8284U /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /* WAKEUP (number 52), USER_BUTTON */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO device name: GPIO5 */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT device name: GPIO5 */ #define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< GPIO5 pin index: 0 */ /* GPIO_AD_B1_08 (number 82), UART_TX/USER_LED/J17[4] */ #define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ #define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT device name: GPIO1 */ #define BOARD_INITPINS_USER_LED_PIN 24U /*!< GPIO1 pin index: 24 */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_07 (number 101), UART1_RXD/J17[8] */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< LPUART1 signal: RX */ /* GPIO_AD_B0_06 (number 105), UART1_TXD/J17[12] */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< LPUART1 signal: TX */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_EMC_16 (number 142), SEMC_A0/U14[23]/BOOT_MODE[0] */ #define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< SEMC ADDR channel: 00 */ /* GPIO_EMC_17 (number 141), SEMC_A1/U14[24]/BOOT_MODE[1] */ #define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< SEMC ADDR channel: 01 */ /* GPIO_EMC_18 (number 140), SEMC_A2/U14[25]/BT_CFG[0] */ #define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< SEMC ADDR channel: 02 */ /* GPIO_EMC_19 (number 139), SEMC_A3/U14[26]/BT_CFG[1] */ #define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< SEMC ADDR channel: 03 */ /* GPIO_EMC_20 (number 138), SEMC_A4/U14[29]/BT_CFG[2] */ #define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< SEMC ADDR channel: 04 */ /* GPIO_EMC_22 (number 136), SEMC_A6/U14[31]/BT_CFG[4] */ #define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< SEMC ADDR channel: 06 */ /* GPIO_EMC_21 (number 137), SEMC_A5/U14[30]/BT_CFG[3] */ #define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< SEMC ADDR channel: 05 */ /* GPIO_EMC_23 (number 133), SEMC_A7/U14[32]/BT_CFG[5] */ #define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< SEMC ADDR channel: 07 */ /* GPIO_EMC_24 (number 132), SEMC_A8/U14[33]/BT_CFG[6] */ #define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< SEMC ADDR channel: 08 */ /* GPIO_EMC_25 (number 131), SEMC_A9/U14[34]/BT_CFG[7] */ #define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< SEMC ADDR channel: 09 */ /* GPIO_EMC_15 (number 143), SEMC_A10/U14[22] */ #define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< SEMC ADDR channel: 10 */ /* GPIO_EMC_26 (number 130), SEMC_A11/U14[35]/BT_CFG[8] */ #define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< SEMC ADDR channel: 11 */ /* GPIO_EMC_27 (number 129), SEMC_A12/U14[36]/BT_CFG[9] */ #define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< SEMC signal: ADDR */ #define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< SEMC ADDR channel: 12 */ /* GPIO_EMC_13 (number 2), SEMC_BA0/U14[20] */ #define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< SEMC signal: BA */ #define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< SEMC BA channel: 0 */ /* GPIO_EMC_14 (number 1), SEMC_BA1/U14[21] */ #define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< SEMC signal: BA */ #define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< SEMC BA channel: 1 */ /* GPIO_EMC_10 (number 7), SEMC_CAS/U14[17] */ #define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< SEMC signal: semc_cas */ /* GPIO_EMC_29 (number 127), SEMC_CKE/U14[37] */ #define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< SEMC signal: semc_cke */ /* GPIO_EMC_30 (number 126), SEMC_CLK/U14[38] */ #define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< SEMC signal: semc_clk */ /* GPIO_EMC_12 (number 3), SEMC_CS0/U14[19] */ #define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< SEMC signal: CS */ #define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< SEMC CS channel: 0 */ /* GPIO_EMC_09 (number 8), SEMC_WE/U14[16] */ #define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< SEMC signal: semc_we */ /* GPIO_EMC_11 (number 4), SEMC_RAS/U14[18] */ #define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< SEMC signal: semc_ras */ /* GPIO_EMC_28 (number 128), SAI3_MCLK */ #define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< SEMC signal: semc_dqs */ /* GPIO_EMC_31 (number 125), SEMC_DM1/U14[39] */ #define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< SEMC signal: DM */ #define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< SEMC DM channel: 1 */ /* GPIO_EMC_08 (number 9), SEMC_DM0/U14[15] */ #define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< SEMC signal: DM */ #define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< SEMC DM channel: 0 */ /* GPIO_EMC_39 (number 117), SEMC_D15/U14[53] */ #define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< SEMC DATA channel: 15 */ /* GPIO_EMC_38 (number 118), SEMC_D14/U14[51] */ #define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< SEMC DATA channel: 14 */ /* GPIO_EMC_37 (number 119), SEMC_D13/U14[50] */ #define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< SEMC DATA channel: 13 */ /* GPIO_EMC_36 (number 120), SEMC_D12/U14[48] */ #define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< SEMC DATA channel: 12 */ /* GPIO_EMC_34 (number 122), SEMC_D10/U14[45] */ #define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< SEMC DATA channel: 10 */ /* GPIO_EMC_35 (number 121), SEMC_D11/U14[47] */ #define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< SEMC DATA channel: 11 */ /* GPIO_EMC_33 (number 123), SEMC_D9/U14[44] */ #define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< SEMC DATA channel: 09 */ /* GPIO_EMC_32 (number 124), SEMC_D8/U14[42] */ #define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< SEMC DATA channel: 08 */ /* GPIO_EMC_07 (number 10), SEMC_D7/U14[13] */ #define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< SEMC DATA channel: 07 */ /* GPIO_EMC_06 (number 12), SEMC_D6/U14[11] */ #define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< SEMC DATA channel: 06 */ /* GPIO_EMC_05 (number 13), SEMC_D5/U14[10] */ #define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< SEMC DATA channel: 05 */ /* GPIO_EMC_04 (number 14), SEMC_D4/U14[8] */ #define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< SEMC DATA channel: 04 */ /* GPIO_EMC_03 (number 15), SEMC_D3/U14[7] */ #define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< SEMC DATA channel: 03 */ /* GPIO_EMC_02 (number 16), SEMC_D2/U14[5] */ #define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< SEMC DATA channel: 02 */ /* GPIO_EMC_01 (number 17), SEMC_D1/U14[4] */ #define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< SEMC DATA channel: 01 */ /* GPIO_EMC_00 (number 18), SEMC_D0/U14[2] */ #define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Device name: SEMC */ #define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< SEMC signal: DATA */ #define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< SEMC DATA channel: 00 */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDRAMPins(void); /* GPIO_SD_B1_01 (number 32), CAN1_RX/U9[4] */ #define BOARD_INITCANPINS_CAN1_RX_PERIPHERAL CAN1 /*!< Device name: CAN1 */ #define BOARD_INITCANPINS_CAN1_RX_SIGNAL RX /*!< CAN1 signal: RX */ /* GPIO_SD_B1_00 (number 33), CAN1_TX/U9[1] */ #define BOARD_INITCANPINS_CAN1_TX_PERIPHERAL CAN1 /*!< Device name: CAN1 */ #define BOARD_INITCANPINS_CAN1_TX_SIGNAL TX /*!< CAN1 signal: TX */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCANPins(void); /* GPIO_AD_B0_11 (number 97), ENET_CRS_DV/U11[18]/J19[6] */ #define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< ENET signal: enet_rx_en */ /* GPIO_AD_B1_06 (number 84), ENET_INT/U11[21]/J17[16] */ #define BOARD_INITENETPINS_ENET_INT_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ #define BOARD_INITENETPINS_ENET_INT_PORT GPIO1 /*!< PORT device name: GPIO1 */ #define BOARD_INITENETPINS_ENET_INT_PIN 22U /*!< GPIO1 pin index: 22 */ /* GPIO_AD_B0_04 (number 107), JTAG_TDO/ENET_RST/U11[32] */ #define BOARD_INITENETPINS_ENET_RST_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ #define BOARD_INITENETPINS_ENET_RST_PORT GPIO1 /*!< PORT device name: GPIO1 */ #define BOARD_INITENETPINS_ENET_RST_PIN 4U /*!< GPIO1 pin index: 4 */ /* GPIO_AD_B0_08 (number 100), ENET_TX_REF_CLK/U11[9] */ #define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_tx_clk /*!< ENET signal: enet_tx_clk */ /* GPIO_AD_B0_13 (number 95), ENET_TXEN/U11[23]/J19[10] */ #define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< ENET signal: enet_tx_en */ /* GPIO_AD_B0_15 (number 93), ENET_TXD1/U11[25]/J19[4] */ #define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< ENET signal: enet_tx_data */ #define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< ENET enet_tx_data channel: 1 */ /* GPIO_AD_B0_14 (number 94), ENET_TXD0/U11[24]/J17[14] */ #define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< ENET signal: enet_tx_data */ #define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< ENET enet_tx_data channel: 0 */ /* GPIO_AD_B0_12 (number 96), ENET_RXER/U11[20]/J19[8] */ #define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< ENET signal: enet_rx_er */ /* GPIO_AD_B0_09 (number 99), ENET_RXD1/U11[15]/J17[6] */ #define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< ENET signal: enet_rx_data */ #define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< ENET enet_rx_data channel: 1 */ /* GPIO_AD_B0_10 (number 98), ENET_RXD0/U11[16]/J19[12] */ #define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< ENET signal: enet_rx_data */ #define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< ENET enet_rx_data channel: 0 */ /* GPIO_EMC_40 (number 116), ENET_MDIO/U11[11] */ #define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< ENET signal: enet_mdio */ /* GPIO_EMC_41 (number 115), ENET_MDC/U11[12] */ #define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Device name: ENET */ #define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< ENET signal: enet_mdc */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENETPins(void); /* GPIO_SD_B0_03 (number 45), SD1_CLK/J15[5] */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< USDHC1 signal: usdhc_clk */ /* GPIO_SD_B0_02 (number 46), SD1_CMD/J15[3] */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< USDHC1 signal: usdhc_cmd */ /* GPIO_SD_B0_04 (number 43), SD1_D0/J15[7] */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< USDHC1 usdhc_data channel: 0 */ /* GPIO_SD_B0_05 (number 42), SD1_D1/J15[8] */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< USDHC1 usdhc_data channel: 1 */ /* GPIO_SD_B0_00 (number 48), SD1_D2/J15[1] */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< USDHC1 usdhc_data channel: 2 */ /* GPIO_SD_B0_01 (number 47), SD1_D3/J15[2] */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< USDHC1 usdhc_data channel: 3 */ /* GPIO_SD_B0_06 (number 41), SD_CD_SW/J15[9] */ #define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO GPIO3 /*!< GPIO device name: GPIO3 */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PORT GPIO3 /*!< PORT device name: GPIO3 */ #define BOARD_INITUSDHCPINS_SD_CD_SW_PIN 19U /*!< GPIO3 pin index: 19 */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_07 (number 24), SAI3_TX_SYNC */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< FLEXSPI signal: FLEXSPI_A_SCLK */ /* GPIO_SD_B1_08 (number 23), SAI3_TXD */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< FLEXSPI signal: FLEXSPI_A_DATA0 */ /* GPIO_SD_B1_10 (number 21), SD_PWREN */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< FLEXSPI signal: FLEXSPI_A_DATA1 */ /* GPIO_SD_B1_09 (number 22), AUD_INT */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< FLEXSPI signal: FLEXSPI_A_DATA2 */ /* GPIO_SD_B1_06 (number 25), SAI3_TX_BCLK */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< FLEXSPI signal: FLEXSPI_A_DATA3 */ /* GPIO_SD_B1_11 (number 19), SAI3_RXD */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< FLEXSPI signal: FLEXSPI_A_SS0_B */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board.cmake ================================================ set(MCU_FAMILY RT1020) set(MCU_VARIANT MIMXRT1024) set(JLINK_DEVICE MIMXRT1024xxx5A) set(PYOCD_TARGET mimxrt1024) set(NXPLINK_DEVICE MIMXRT1024xxxxx:MIMXRT1024-EVK) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1024_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1024DAG5A CFG_EXAMPLE_VIDEO_READONLY #-Wno-error=array-bounds ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1024 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1024-evaluation-kit:MIMXRT1024-EVK */ #ifndef BOARD_MIMXRT1024_EVK_H_ #define BOARD_MIMXRT1024_EVK_H_ // required since iMXRT MCUX-SDK include this file for board size // RT1020-EVK #define BOARD_FLASH_SIZE (0x800000U) #define BOARD_FLASH_SIZE (0x400000U) // builtin flash of RT1024 // LED: IOMUXC_GPIO_AD_B1_08_GPIO1_IO24 #define LED_PORT BOARD_INITPINS_USER_LED_GPIO #define LED_PIN BOARD_INITPINS_USER_LED_PIN #define LED_STATE_ON 1 // SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_PIN #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_07_LPUART1_RX, IOMUXC_GPIO_AD_B0_06_LPUART1_TX #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1024DAG5A MCU_FAMILY = RT1020 MCU_VARIANT = MIMXRT1024 # warnings caused by mcu driver CFLAGS += -Wno-error=array-bounds # For flash-jlink target JLINK_DEVICE = MIMXRT1024xxx5A # For flash-pyocd target PYOCD_TARGET = mimxrt1024 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/evkmimxrt1024_flexspi_nor_config.c ================================================ /* * Copyright 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1024_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"), used)) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally, .csHoldTime = 3u, .csSetupTime = 3u, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_60MHz, .sflashA1Size = 4u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 64u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/evkmimxrt1024_flexspi_nor_config.h ================================================ /* * Copyright 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1024_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1024_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.1. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_133MHz = 7, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1024_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1024_evk/mimxrt1024_evk.mex ================================================ MIMXRT1024xxxxx MIMXRT1024DAG5A MIMXRT1024-EVK B1 ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true Configures pin routing and optionally pin electrical features. core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 13.0.2 c_array 13.0.2 N/A ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1052xxxxB package_id: MIMXRT1052DVL6B mcu_data: ksdk2_0 processor_version: 13.0.2 board: IMXRT1050-EVKB * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 600 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 12 MHz} - {id: ENET_125M_CLK.outFreq, value: 2.4 MHz} - {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 160 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 150 MHz} - {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: LVDS1_CLK.outFreq, value: 1.2 GHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz} - {id: PLL7_MAIN_CLK.outFreq, value: 480 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USBPHY2_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_PODF.scale, value: '3', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM.PLL3_SW_CLK_SEL} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1} - {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true} - {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL5.denom, value: '1'} - {id: CCM_ANALOG.PLL5.div, value: '40'} - {id: CCM_ANALOG.PLL5.num, value: '0'} - {id: CCM_ANALOG.PLL5_BYPASS.sel, value: CCM_ANALOG.PLL5_POST_DIV} - {id: CCM_ANALOG.PLL5_POST_DIV.scale, value: '2'} - {id: CCM_ANALOG.PLL7_BYPASS.sel, value: CCM_ANALOG.PLL7} - {id: CCM_ANALOG.VIDEO_DIV.scale, value: '4'} - {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_VIDEO_POWERDOWN_CFG, value: 'No'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 40, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .postDivider = 8, /* Divider after PLL */ .numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); CLOCK_DisableClock(kCLOCK_Xbar3); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 1); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 1); #endif /* Disable CSI clock gate. */ CLOCK_DisableClock(kCLOCK_Csi); /* Set CSI_PODF. */ CLOCK_SetDiv(kCLOCK_CsiDiv, 1); /* Set Csi clock source. */ CLOCK_SetMux(kCLOCK_CsiMux, 0); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable LCDIF clock gate. */ CLOCK_DisableClock(kCLOCK_LcdPixel); /* Set LCDIF_PRED. */ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); /* Set LCDIF_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); /* Set Lcdif pre clock source. */ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Disable Flexio2 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio2); /* Set FLEXIO2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); /* Set FLEXIO2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); /* Set Flexio2 clock source. */ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init ARM PLL. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Video PLL. */ uint32_t pllVideo; /* Disable Video PLL output before initial Video PLL. */ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; /* Bypass PLL first */ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(0); CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(0); CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(1); pllVideo = (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK |CCM_ANALOG_PLL_VIDEO_DIV_SELECT(40); pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(3); CCM_ANALOG->PLL_VIDEO = pllVideo; while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) { } /* Disable bypass for Video PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllVideo, 0); /* DeInit Enet PLL. */ CLOCK_DeinitEnetPll(); /* Bypass Enet PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1); /* Set Enet output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1); /* Enable Enet output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; /* Enable Enet25M output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; /* Init Usb2 PLL. */ CLOCK_InitUsb2Pll(&usb2PllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set lvds1 clock source. */ CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ #if defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK; #elif defined(IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK) /* Backward compatibility for original bitfield name */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; #else #error "Neither IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK nor IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK is defined." #endif /* defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) */ /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 160000000UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL #define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL /*! @brief Arm PLL set for BOARD_BootClockRUN configuration. */ extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Usb2 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Video PLL set for BOARD_BootClockRUN configuration. */ extern const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1052xxxxB package_id: MIMXRT1052DVL6B mcu_data: ksdk2_0 processor_version: 13.0.2 board: IMXRT1050-EVKB pin_labels: - {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} - {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ GPIO_PinInit(GPIO1, 9U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP (pin L6) */ GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); IOMUXC_SetPinConfig(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0x01B0A0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TXD, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TXD, 0x10B0U); #else IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, 0x10B0U); #else IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); #endif } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDRAMPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} - {pin_num: C7, peripheral: SEMC, signal: 'CSX, 0', pin_signal: GPIO_EMC_41} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDRAMPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDRAMPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DA00, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DA01, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DA02, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DA03, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DA04, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DA05, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DA06, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DA07, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); #endif IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DA08, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DA09, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DA10, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DA11, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DA12, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DA13, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DA14, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DA15, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); #endif IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_SEMC_CSX0, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_SEMC_CSX00, 0U); #endif } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCSIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCSIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCSIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLCDPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLCDPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitLCDPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCANPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCANPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCANPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENETPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENETPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENETPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitHyperFlashPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} - {pin_num: L5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA3, pin_signal: GPIO_SD_B1_00} - {pin_num: M5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA2, pin_signal: GPIO_SD_B1_01} - {pin_num: M3, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA1, pin_signal: GPIO_SD_B1_02} - {pin_num: M4, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA0, pin_signal: GPIO_SD_B1_03} - {pin_num: P2, peripheral: FLEXSPI, signal: FLEXSPI_B_SCLK, pin_signal: GPIO_SD_B1_04} - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitHyperFlashPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitHyperFlashPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPIB_DATA03, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPIB_DATA02, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPIB_DATA01, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPIB_DATA00, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPIB_SCLK, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); #endif #if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3, 0U); #else IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); #endif } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ /* WAKEUP (coord L6), SD_PWREN */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_12 (coord K14), UART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_13 (coord L14), UART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_EMC_09 (coord C2), SEMC_A0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_10 (coord G1), SEMC_A1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_11 (coord G3), SEMC_A2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_12 (coord H1), SEMC_A3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_13 (coord A6), SEMC_A4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_14 (coord B6), SEMC_A5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_15 (coord B1), SEMC_A6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_16 (coord A5), SEMC_A7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_17 (coord A4), SEMC_A8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_18 (coord B2), SEMC_A9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_23 (coord G2), SEMC_A10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_19 (coord B4), SEMC_A11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_20 (coord A3), SEMC_A12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_21 (coord C1), SEMC_BA0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_22 (coord F1), SEMC_BA1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_24 (coord D3), SEMC_CAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ /* GPIO_EMC_27 (coord A2), SEMC_CKE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ /* GPIO_EMC_26 (coord B3), SEMC_CLK */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ /* GPIO_EMC_00 (coord E3), SEMC_D0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_01 (coord F3), SEMC_D1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_02 (coord F4), SEMC_D2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_03 (coord G4), SEMC_D3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_04 (coord F2), SEMC_D4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_05 (coord G5), SEMC_D5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_06 (coord H5), SEMC_D6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_07 (coord H4), SEMC_D7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_30 (coord C6), SEMC_D8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_31 (coord C5), SEMC_D9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_32 (coord D5), SEMC_D10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_33 (coord C4), SEMC_D11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_34 (coord D4), SEMC_D12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_35 (coord E5), SEMC_D13 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_EMC_36 (coord C3), SEMC_D14 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_EMC_37 (coord E4), SEMC_D15 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_EMC_08 (coord H3), SEMC_DM0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_38 (coord D6), SEMC_DM1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_25 (coord D2), SEMC_RAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ /* GPIO_EMC_28 (coord D1), SEMC_WE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ /* GPIO_EMC_41 (coord C7), ENET_MDIO */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_ENET_MDIO_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_ENET_MDIO_SIGNAL CSX /*!< Signal name */ #define BOARD_INITSDRAMPINS_ENET_MDIO_CHANNEL 0U /*!< Signal channel */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDRAMPins(void); /* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ /* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ /* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ /* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ /* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ /* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ /* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ #define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCSIPins(void); /* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_B0_00 (coord D7), LCDIF_CLK */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ /* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_B1_00 (coord A11), LCDIF_D12 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_B1_01 (coord B11), LCDIF_D13 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_B1_02 (coord C11), LCDIF_D14 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_B1_03 (coord D11), LCDIF_D15 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ /* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ /* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ /* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ /* Routed pin properties */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLCDPins(void); /* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCANPins(void); /* GPIO_EMC_40 (coord A7), ENET_MDC */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ /* GPIO_EMC_41 (coord C7), ENET_MDIO */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ /* GPIO_B1_10 (coord B13), ENET_TX_CLK */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ /* GPIO_B1_04 (coord E12), ENET_RXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_05 (coord D12), ENET_RXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_06 (coord C12), ENET_CRS_DV */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ /* GPIO_B1_11 (coord C13), ENET_RXER */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ /* GPIO_B1_07 (coord B12), ENET_TXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_08 (coord A12), ENET_TXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_09 (coord A13), ENET_TXEN */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENETPins(void); /* GPIO_SD_B0_05 (coord J2), SD1_D3 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_04 (coord H2), SD1_D2 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_00 (coord L5), FlexSPI_D3_B */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_B_SIGNAL FLEXSPI_B_DATA3 /*!< Signal name */ /* GPIO_SD_B1_01 (coord M5), FlexSPI_D2_B */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_B_SIGNAL FLEXSPI_B_DATA2 /*!< Signal name */ /* GPIO_SD_B1_02 (coord M3), FlexSPI_D1_B */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_B_SIGNAL FLEXSPI_B_DATA1 /*!< Signal name */ /* GPIO_SD_B1_03 (coord M4), FlexSPI_D0_B */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_B_SIGNAL FLEXSPI_B_DATA0 /*!< Signal name */ /* GPIO_SD_B1_04 (coord P2), FlexSPI_CLK_B */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_B_SIGNAL FLEXSPI_B_SCLK /*!< Signal name */ /* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ /* Routed pin properties */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITHYPERFLASHPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitHyperFlashPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board.cmake ================================================ set(MCU_FAMILY RT1050) set(MCU_VARIANT MIMXRT1052) set(JLINK_DEVICE MIMXRT1052xxxxB) set(PYOCD_TARGET mimxrt1050) set(NXPLINK_DEVICE MIMXRT1052xxxxB:EVK-MIMXRT1050) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkbimxrt1050_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1052DVL6B BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1050 Evaluation Kit revB url: https://www.nxp.com/part/IMXRT1050-EVKB */ #ifndef BOARD_MIMXRT1050_EVKB_H_ #define BOARD_MIMXRT1050_EVKB_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x4000000U) // LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, IOMUXC_GPIO_AD_B0_12_LPUART1_TXD #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1052DVL6B MCU_FAMILY = RT1050 MCU_VARIANT = MIMXRT1052 JLINK_DEVICE = MIMXRT1052xxxxB # For flash-pyocd target PYOCD_TARGET = mimxrt1050 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.c ================================================ /* * Copyright 2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkbimxrt1050_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t hyperflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, .columnAddressWidth = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .controllerMiscOption = (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, .sflashA1Size = 64u * 1024u * 1024u, .dataValidTime = {16u, 16u}, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18), FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06), FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), }, }, .pageSize = 512u, .sectorSize = 256u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = true, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h ================================================ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ #define __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_133MHz = 7, kFlexSpiSerialClk_166MHz = 8, kFlexSpiSerialClk_200MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1050_evkb/mimxrt1050_evkb.mex ================================================ MIMXRT1052xxxxB MIMXRT1052DVL6B IMXRT1050-EVKB A ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 kELCDIF_CurFrameDoneInterruptEnable 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 600 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 12 MHz} - {id: ENET2_125M_CLK.outFreq, value: 1.2 MHz} - {id: ENET_125M_CLK.outFreq, value: 2.4 MHz} - {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI2_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 150 MHz} - {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: LVDS1_CLK.outFreq, value: 1.2 GHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz} - {id: PLL7_MAIN_CLK.outFreq, value: 480 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USBPHY2_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.FLEXSPI_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.LCDIF_PODF.scale, value: '4', locked: true} - {id: CCM.LCDIF_PRED.scale, value: '2', locked: true} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1} - {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true} - {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL5.denom, value: '1'} - {id: CCM_ANALOG.PLL5.div, value: '31', locked: true} - {id: CCM_ANALOG.PLL5.num, value: '0'} - {id: CCM_ANALOG.PLL5_BYPASS.sel, value: CCM_ANALOG.PLL5_POST_DIV} - {id: CCM_ANALOG.PLL5_POST_DIV.scale, value: '2', locked: true} - {id: CCM_ANALOG.PLL7_BYPASS.sel, value: CCM_ANALOG.PLL7} - {id: CCM_ANALOG.VIDEO_DIV.scale, value: '4', locked: true} - {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_VIDEO_POWERDOWN_CFG, value: 'No'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 31, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .postDivider = 8, /* Divider after PLL */ .numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); CLOCK_DisableClock(kCLOCK_Xbar3); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 1); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 3); #endif /* Disable Flexspi2 clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi2); /* Set FLEXSPI2_PODF. */ CLOCK_SetDiv(kCLOCK_Flexspi2Div, 1); /* Set Flexspi2 clock source. */ CLOCK_SetMux(kCLOCK_Flexspi2Mux, 1); /* Disable CSI clock gate. */ CLOCK_DisableClock(kCLOCK_Csi); /* Set CSI_PODF. */ CLOCK_SetDiv(kCLOCK_CsiDiv, 1); /* Set Csi clock source. */ CLOCK_SetMux(kCLOCK_CsiMux, 0); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can3); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); CLOCK_DisableClock(kCLOCK_Can3S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable LCDIF clock gate. */ CLOCK_DisableClock(kCLOCK_LcdPixel); /* Set LCDIF_PRED. */ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); /* Set LCDIF_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); /* Set Lcdif pre clock source. */ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Disable Flexio2 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio2); /* Set FLEXIO2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); /* Set FLEXIO2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); /* Set Flexio2 clock source. */ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init ARM PLL. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Video PLL. */ uint32_t pllVideo; /* Disable Video PLL output before initial Video PLL. */ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; /* Bypass PLL first */ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(0); CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(0); CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(1); pllVideo = (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK |CCM_ANALOG_PLL_VIDEO_DIV_SELECT(31); pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(3); CCM_ANALOG->PLL_VIDEO = pllVideo; while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) { } /* Disable bypass for Video PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllVideo, 0); /* DeInit Enet PLL. */ CLOCK_DeinitEnetPll(); /* Bypass Enet PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1); /* Set Enet output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1); /* Enable Enet output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; /* Set Enet2 output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(0); /* Enable Enet2 output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET2_REF_EN_MASK; /* Enable Enet25M output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; /* Init Usb2 PLL. */ CLOCK_InitUsb2Pll(&usb2PllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set lvds1 clock source. */ CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; /* Set ENET2 Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET2_TX_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL #define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET2_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL #define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL /*! @brief Arm PLL set for BOARD_BootClockRUN configuration. */ extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Usb2 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Video PLL set for BOARD_BootClockRUN configuration. */ extern const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK pin_labels: - {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} - {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ GPIO_PinInit(GPIO1, 9U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP (pin L6) */ GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDRAMPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} - {pin_num: E1, peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_29} - {pin_num: B7, peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_39} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDRAMPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDRAMPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CS0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DQS, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCSIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCSIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCSIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLCDPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} - {pin_num: M11, peripheral: GPIO1, signal: 'gpio_io, 02', pin_signal: GPIO_AD_B0_02} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLCDPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitLCDPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCANPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCANPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCANPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENETPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENETPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENETPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x0200U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ /* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ /* WAKEUP (coord L6), SD_PWREN */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_12 (coord K14), UART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_13 (coord L14), UART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_EMC_09 (coord C2), SEMC_A0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_10 (coord G1), SEMC_A1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_11 (coord G3), SEMC_A2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_12 (coord H1), SEMC_A3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_13 (coord A6), SEMC_A4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_14 (coord B6), SEMC_A5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_15 (coord B1), SEMC_A6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_16 (coord A5), SEMC_A7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_17 (coord A4), SEMC_A8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_18 (coord B2), SEMC_A9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_23 (coord G2), SEMC_A10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_19 (coord B4), SEMC_A11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_20 (coord A3), SEMC_A12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_21 (coord C1), SEMC_BA0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_22 (coord F1), SEMC_BA1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_24 (coord D3), SEMC_CAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ /* GPIO_EMC_27 (coord A2), SEMC_CKE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ /* GPIO_EMC_26 (coord B3), SEMC_CLK */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ /* GPIO_EMC_00 (coord E3), SEMC_D0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_01 (coord F3), SEMC_D1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_02 (coord F4), SEMC_D2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_03 (coord G4), SEMC_D3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_04 (coord F2), SEMC_D4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_05 (coord G5), SEMC_D5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_06 (coord H5), SEMC_D6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_07 (coord H4), SEMC_D7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_30 (coord C6), SEMC_D8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_31 (coord C5), SEMC_D9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_32 (coord D5), SEMC_D10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_33 (coord C4), SEMC_D11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_34 (coord D4), SEMC_D12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_35 (coord E5), SEMC_D13 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_EMC_36 (coord C3), SEMC_D14 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_EMC_37 (coord E4), SEMC_D15 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_EMC_08 (coord H3), SEMC_DM0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_38 (coord D6), SEMC_DM1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_25 (coord D2), SEMC_RAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ /* GPIO_EMC_28 (coord D1), SEMC_WE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ /* GPIO_EMC_29 (coord E1), SEMC_CS0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_39 (coord B7), SEMC_DQS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDRAMPins(void); #define BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x10U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ /* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ /* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ /* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ /* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ /* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ /* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ /* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ #define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCSIPins(void); #define BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x04U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ #define BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x80000000U /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ /* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_B0_00 (coord D7), LCDIF_CLK */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ /* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_B1_00 (coord A11), LCDIF_D12 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_B1_01 (coord B11), LCDIF_D13 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_B1_02 (coord C11), LCDIF_D14 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_B1_03 (coord D11), LCDIF_D15 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ /* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ /* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ /* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ /* Routed pin properties */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLCDPins(void); /* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCANPins(void); /* GPIO_EMC_40 (coord A7), ENET_MDC */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ /* GPIO_EMC_41 (coord C7), ENET_MDIO */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ /* GPIO_B1_10 (coord B13), ENET_TX_CLK */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ /* GPIO_B1_04 (coord E12), ENET_RXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_05 (coord D12), ENET_RXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_06 (coord C12), ENET_CRS_DV */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ /* GPIO_B1_11 (coord C13), ENET_RXER */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ /* GPIO_B1_07 (coord B12), ENET_TXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_08 (coord A12), ENET_TXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_09 (coord A13), ENET_TXEN */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENETPins(void); /* GPIO_SD_B0_05 (coord J2), SD1_D3 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_04 (coord H2), SD1_D2 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /* GPIO_B1_14 (coord C14), SD0_VSELECT */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board.cmake ================================================ set(MCU_FAMILY RT1060) set(MCU_VARIANT MIMXRT1062) set(JLINK_DEVICE MIMXRT1062xxx6A) #set(JLINK_OPTION "-USB 000726129165") set(PYOCD_TARGET mimxrt1060) set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1060_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1062DVL6A BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1060 Evaluation Kit revB url: https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1060-EVKB */ #ifndef BOARD_MIMXRT1060_EVKB_H_ #define BOARD_MIMXRT1060_EVKB_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x800000U) // LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1062DVL6A MCU_FAMILY = RT1060 MCU_VARIANT = MIMXRT1062 # For flash-jlink target JLINK_DEVICE = MIMXRT1062xxx6A # For flash-pyocd target PYOCD_TARGET = mimxrt1060 BOARD_TUD_RHPORT = 0 BOARD_TUH_RHPORT = 1 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.c ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1060_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.h ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, kFlexSpiSerialClk_166MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1060_evk/mimxrt1060_evk.mex ================================================ MIMXRT1062xxxxA MIMXRT1062DVL6A MIMXRT1060-EVK A2 ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 kELCDIF_CurFrameDoneInterruptEnable 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v15.0 processor: MIMXRT1064xxxxA package_id: MIMXRT1064DVL6A mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1064-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 600 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 12 MHz} - {id: ENET2_125M_CLK.outFreq, value: 1.2 MHz} - {id: ENET_125M_CLK.outFreq, value: 2.4 MHz} - {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI2_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 150 MHz} - {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: LVDS1_CLK.outFreq, value: 1.2 GHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz} - {id: PLL7_MAIN_CLK.outFreq, value: 480 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USBPHY2_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.FLEXSPI_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.LCDIF_PODF.scale, value: '4', locked: true} - {id: CCM.LCDIF_PRED.scale, value: '2', locked: true} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1} - {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true} - {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD1_DIV.scale, value: '16', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL5.denom, value: '1'} - {id: CCM_ANALOG.PLL5.div, value: '31', locked: true} - {id: CCM_ANALOG.PLL5.num, value: '0'} - {id: CCM_ANALOG.PLL5_BYPASS.sel, value: CCM_ANALOG.PLL5_POST_DIV} - {id: CCM_ANALOG.PLL5_POST_DIV.scale, value: '2', locked: true} - {id: CCM_ANALOG.PLL7_BYPASS.sel, value: CCM_ANALOG.PLL7} - {id: CCM_ANALOG.VIDEO_DIV.scale, value: '4', locked: true} - {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_VIDEO_POWERDOWN_CFG, value: 'No'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 31, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .postDivider = 8, /* Divider after PLL */ .numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); CLOCK_DisableClock(kCLOCK_Xbar3); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 1); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 3); /* In SDK projects, external flash (configured by FLEXSPI2) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI2 clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI2, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi2 clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi2); /* Set FLEXSPI2_PODF. */ CLOCK_SetDiv(kCLOCK_Flexspi2Div, 1); /* Set Flexspi2 clock source. */ CLOCK_SetMux(kCLOCK_Flexspi2Mux, 1); #endif /* Disable CSI clock gate. */ CLOCK_DisableClock(kCLOCK_Csi); /* Set CSI_PODF. */ CLOCK_SetDiv(kCLOCK_CsiDiv, 1); /* Set Csi clock source. */ CLOCK_SetMux(kCLOCK_CsiMux, 0); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can3); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); CLOCK_DisableClock(kCLOCK_Can3S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable LCDIF clock gate. */ CLOCK_DisableClock(kCLOCK_LcdPixel); /* Set LCDIF_PRED. */ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); /* Set LCDIF_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); /* Set Lcdif pre clock source. */ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Disable Flexio2 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio2); /* Set FLEXIO2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); /* Set FLEXIO2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); /* Set Flexio2 clock source. */ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init ARM PLL. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); #endif /* In SDK projects, external flash (configured by FLEXSPI2) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI2 clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI2, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Video PLL. */ uint32_t pllVideo; /* Disable Video PLL output before initial Video PLL. */ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; /* Bypass PLL first */ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(0); CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(0); CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(1); pllVideo = (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK |CCM_ANALOG_PLL_VIDEO_DIV_SELECT(31); pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(3); CCM_ANALOG->PLL_VIDEO = pllVideo; while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) { } /* Disable bypass for Video PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllVideo, 0); /* DeInit Enet PLL. */ CLOCK_DeinitEnetPll(); /* Bypass Enet PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1); /* Set Enet output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1); /* Enable Enet output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; /* Set Enet2 output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(0); /* Enable Enet2 output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET2_REF_EN_MASK; /* Enable Enet25M output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; /* Init Usb2 PLL. */ CLOCK_InitUsb2Pll(&usb2PllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set lvds1 clock source. */ CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; /* Set ENET2 Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET2_TX_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL /* Clock consumers of AHB_CLK_ROOT output : AIPSTZ1, AIPSTZ2, AIPSTZ3, AIPSTZ4, ARM, FLEXIO3, FLEXSPI, FLEXSPI2, GPIO6, GPIO7, GPIO8, GPIO9 */ #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL /* Clock consumers of CAN_CLK_ROOT output : CAN1, CAN2, CAN3 */ #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL /* Clock consumers of CKIL_SYNC_CLK_ROOT output : CSU, EWM, GPT1, GPT2, KPP, PIT, RTWDOG, SNVS, SPDIF, TEMPMON, TSC, USB1, USB2, WDOG1, WDOG2 */ #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL /* Clock consumers of CLKO1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL /* Clock consumers of CLKO2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG */ #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL /* Clock consumers of CLK_24M output : GPT1, GPT2 */ #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL /* Clock consumers of CSI_CLK_ROOT output : CSI */ #define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL /* Clock consumers of ENET2_125M_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET2_REF_CLK 0UL /* Clock consumers of ENET2_REF_CLK output : ENET2 */ #define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 0UL /* Clock consumers of ENET2_TX_CLK output : ENET2 */ #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL /* Clock consumers of ENET_125M_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL /* Clock consumers of ENET_25M_REF_CLK output : ENET, ENET2 */ #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL /* Clock consumers of ENET_REF_CLK output : ENET */ #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL /* Clock consumers of ENET_TX_CLK output : ENET */ #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL /* Clock consumers of FLEXIO2_CLK_ROOT output : FLEXIO2, FLEXIO3 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL /* Clock consumers of FLEXSPI2_CLK_ROOT output : FLEXSPI2 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL /* Clock consumers of FLEXSPI_CLK_ROOT output : FLEXSPI */ #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : GPT1 */ #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : GPT2 */ #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL /* Clock consumers of IPG_CLK_ROOT output : ADC1, ADC2, ADC_ETC, AOI1, AOI2, ARM, BEE, CAN1, CAN2, CAN3, CCM, CMP1, CMP2, CMP3, CMP4, CSI, CSU, DCDC, DCP, DMA0, DMAMUX, ENC1, ENC2, ENC3, ENC4, ENET, ENET2, EWM, FLEXIO1, FLEXIO2, FLEXIO3, FLEXRAM, FLEXSPI, FLEXSPI2, GPC, GPIO1, GPIO10, GPIO2, GPIO3, GPIO4, GPIO5, IOMUXC, KPP, LCDIF, LPI2C1, LPI2C2, LPI2C3, LPI2C4, LPSPI1, LPSPI2, LPSPI3, LPSPI4, LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8, NVIC, OCOTP, PMU, PWM1, PWM2, PWM3, PWM4, PXP, ROMC, RTWDOG, SAI1, SAI2, SAI3, SNVS, SPDIF, SRC, TEMPMON, TMR1, TMR2, TMR3, TMR4, TRNG, TSC, USB1, USB2, USDHC1, USDHC2, WDOG1, WDOG2, XBARA1, XBARB2, XBARB3 */ #define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL /* Clock consumers of LCDIF_CLK_ROOT output : LCDIF */ #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL /* Clock consumers of LPI2C_CLK_ROOT output : LPI2C1, LPI2C2, LPI2C3, LPI2C4 */ #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL /* Clock consumers of LPSPI_CLK_ROOT output : LPSPI1, LPSPI2, LPSPI3, LPSPI4 */ #define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL /* Clock consumers of LVDS1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL /* Clock consumers of MQS_MCLK output : N/A */ #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL /* Clock consumers of PERCLK_CLK_ROOT output : GPT1, GPT2, PIT */ #define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 480000000UL /* Clock consumers of PLL7_MAIN_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL /* Clock consumers of SAI1_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL /* Clock consumers of SAI2_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL /* Clock consumers of SAI2_MCLK1 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL /* Clock consumers of SAI2_MCLK2 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL /* Clock consumers of SAI2_MCLK3 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL /* Clock consumers of SAI3_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL /* Clock consumers of SEMC_CLK_ROOT output : SEMC */ #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL /* Clock consumers of SPDIF0_CLK_ROOT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL /* Clock consumers of SPDIF0_EXTCLK_OUT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL /* Clock consumers of TRACE_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL /* Clock consumers of UART_CLK_ROOT output : LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 */ #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL /* Clock consumers of USBPHY1_CLK output : TEMPMON, USB1 */ #define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 480000000UL /* Clock consumers of USBPHY2_CLK output : USB2 */ #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL /* Clock consumers of USDHC1_CLK_ROOT output : USDHC1 */ #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL /* Clock consumers of USDHC2_CLK_ROOT output : USDHC2 */ /*! @brief Arm PLL set for BOARD_BootClockRUN configuration. */ extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Usb2 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Video PLL set for BOARD_BootClockRUN configuration. */ extern const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: MIMXRT1064xxxxA package_id: MIMXRT1064DVL6A mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1064-EVK pin_labels: - {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} - {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ GPIO_PinInit(GPIO1, 9U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP (pin L6) */ GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDRAMPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} - {pin_num: E1, peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_29} - {pin_num: B7, peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_39} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDRAMPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDRAMPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CS0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DQS, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCSIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCSIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCSIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLCDPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} - {pin_num: M11, peripheral: GPIO1, signal: 'gpio_io, 02', pin_signal: GPIO_AD_B0_02} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLCDPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitLCDPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) ); IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitCANPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitCANPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitCANPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENETPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENETPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENETPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x0200U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ /* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ /* WAKEUP (coord L6), SD_PWREN */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_12 (coord K14), UART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_13 (coord L14), UART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_EMC_09 (coord C2), SEMC_A0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_10 (coord G1), SEMC_A1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_11 (coord G3), SEMC_A2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_12 (coord H1), SEMC_A3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_13 (coord A6), SEMC_A4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_14 (coord B6), SEMC_A5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_15 (coord B1), SEMC_A6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_16 (coord A5), SEMC_A7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_17 (coord A4), SEMC_A8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_18 (coord B2), SEMC_A9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_23 (coord G2), SEMC_A10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_19 (coord B4), SEMC_A11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_20 (coord A3), SEMC_A12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_21 (coord C1), SEMC_BA0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_22 (coord F1), SEMC_BA1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_24 (coord D3), SEMC_CAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ /* GPIO_EMC_27 (coord A2), SEMC_CKE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ /* GPIO_EMC_26 (coord B3), SEMC_CLK */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ /* GPIO_EMC_00 (coord E3), SEMC_D0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_01 (coord F3), SEMC_D1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_02 (coord F4), SEMC_D2 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_EMC_03 (coord G4), SEMC_D3 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_EMC_04 (coord F2), SEMC_D4 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_EMC_05 (coord G5), SEMC_D5 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_EMC_06 (coord H5), SEMC_D6 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_EMC_07 (coord H4), SEMC_D7 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_EMC_30 (coord C6), SEMC_D8 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_EMC_31 (coord C5), SEMC_D9 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_EMC_32 (coord D5), SEMC_D10 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_EMC_33 (coord C4), SEMC_D11 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_EMC_34 (coord D4), SEMC_D12 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_EMC_35 (coord E5), SEMC_D13 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_EMC_36 (coord C3), SEMC_D14 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_EMC_37 (coord E4), SEMC_D15 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_EMC_08 (coord H3), SEMC_DM0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_38 (coord D6), SEMC_DM1 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ /* GPIO_EMC_25 (coord D2), SEMC_RAS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ /* GPIO_EMC_28 (coord D1), SEMC_WE */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ /* GPIO_EMC_29 (coord E1), SEMC_CS0 */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ #define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ /* GPIO_EMC_39 (coord B7), SEMC_DQS */ /* Routed pin properties */ #define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ #define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDRAMPins(void); #define BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x10U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ /* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ /* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ /* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ /* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ /* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ /* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ /* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ /* Routed pin properties */ #define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ #define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ #define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ #define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCSIPins(void); #define BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x04U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ #define BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x80000000U /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ /* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_B0_00 (coord D7), LCDIF_CLK */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ /* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ /* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ /* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ /* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ /* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ /* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ /* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ /* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ /* GPIO_B1_00 (coord A11), LCDIF_D12 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ /* GPIO_B1_01 (coord B11), LCDIF_D13 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ /* GPIO_B1_02 (coord C11), LCDIF_D14 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ /* GPIO_B1_03 (coord D11), LCDIF_D15 */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ #define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ /* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ /* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ /* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ /* Routed pin properties */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ #define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ /* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ /* Routed pin properties */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ #define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLCDPins(void); /* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ /* Routed pin properties */ #define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ #define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitCANPins(void); /* GPIO_EMC_40 (coord A7), ENET_MDC */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ /* GPIO_EMC_41 (coord C7), ENET_MDIO */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ /* GPIO_B1_10 (coord B13), ENET_TX_CLK */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ /* GPIO_B1_04 (coord E12), ENET_RXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_05 (coord D12), ENET_RXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_06 (coord C12), ENET_CRS_DV */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ /* GPIO_B1_11 (coord C13), ENET_RXER */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ /* GPIO_B1_07 (coord B12), ENET_TXD0 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ /* GPIO_B1_08 (coord A12), ENET_TXD1 */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ #define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ /* GPIO_B1_09 (coord A13), ENET_TXEN */ /* Routed pin properties */ #define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ #define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENETPins(void); /* GPIO_SD_B0_05 (coord J2), SD1_D3 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_04 (coord H2), SD1_D2 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /* GPIO_B1_14 (coord C14), SD0_VSELECT */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board.cmake ================================================ set(MCU_FAMILY RT1064) set(MCU_VARIANT MIMXRT1064) set(JLINK_DEVICE MIMXRT1064xxx6A) set(PYOCD_TARGET mimxrt1064) set(NXPLINK_DEVICE MIMXRT1064xxxxA:EVK-MIMXRT1064) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1064_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1064DVL6A BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1064 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1064-EVK */ #ifndef BOARD_MIMXRT1064_EVKB_H_ #define BOARD_MIMXRT1064_EVKB_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x400000U) // LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1064DVL6A MCU_FAMILY = RT1064 MCU_VARIANT = MIMXRT1064 # For flash-jlink target JLINK_DEVICE = MIMXRT1064xxx6A # For flash-pyocd target PYOCD_TARGET = mimxrt1064 BOARD_TUD_RHPORT = 0 BOARD_TUH_RHPORT = 1 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkmimxrt1064_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"), used)) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.h ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, kFlexSpiSerialClk_166MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1064_evk/mimxrt1064_evk.mex ================================================ MIMXRT1064xxxxA MIMXRT1064DVL6A MIMXRT1064-EVK 1 ksdk2_0 true false true false 24.12.10 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true 24.12.10 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 kCSI_HsyncActiveHigh kCSI_VsyncActiveLow kELCDIF_CurFrameDoneInterruptEnable 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetRootClock() to configure corresponding module clock source and divider. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v15.0 processor: MIMXRT1176xxxxx package_id: MIMXRT1176DVMAA mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1170-EVKB * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" #include "fsl_dcdc.h" #include "fsl_pmu.h" #include "fsl_clock.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) /* This function should not run from SDRAM since it will change SEMC configuration. */ AT_QUICKACCESS_SECTION_CODE(void UpdateSemcClock(void)); void UpdateSemcClock(void) { /* Enable self-refresh mode and update semc clock root to 200MHz. */ SEMC->IPCMD = 0xA55A000D; while ((SEMC->INTR & 0x3) == 0) ; SEMC->INTR = 0x3; SEMC->DCCR = 0x0B; /* * Currently we are using SEMC parameter which fit both 166MHz and 200MHz, only * need to change the SEMC clock root here. If customer is using their own DCD and * want to switch from 166MHz to 200MHz, extra SEMC configuration might need to be * adjusted here to fine tune the SDRAM performance */ CCM->CLOCK_ROOT[kCLOCK_Root_Semc].CONTROL = 0x602; } #endif #endif /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: ACMP_CLK_ROOT.outFreq, value: 24 MHz} - {id: ADC1_CLK_ROOT.outFreq, value: 24 MHz} - {id: ADC2_CLK_ROOT.outFreq, value: 24 MHz} - {id: ARM_PLL_CLK.outFreq, value: 996 MHz} - {id: ASRC_CLK_ROOT.outFreq, value: 24 MHz} - {id: AXI_CLK_ROOT.outFreq, value: 996 MHz} - {id: BUS_CLK_ROOT.outFreq, value: 240 MHz} - {id: BUS_LPSR_CLK_ROOT.outFreq, value: 160 MHz} - {id: CAN1_CLK_ROOT.outFreq, value: 24 MHz} - {id: CAN2_CLK_ROOT.outFreq, value: 24 MHz} - {id: CAN3_CLK_ROOT.outFreq, value: 24 MHz} - {id: CCM_CLKO1_CLK_ROOT.outFreq, value: 24 MHz} - {id: CCM_CLKO2_CLK_ROOT.outFreq, value: 24 MHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CSI2_CLK_ROOT.outFreq, value: 24 MHz} - {id: CSI2_ESC_CLK_ROOT.outFreq, value: 24 MHz} - {id: CSI2_UI_CLK_ROOT.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 24 MHz} - {id: CSSYS_CLK_ROOT.outFreq, value: 24 MHz} - {id: CSTRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: ELCDIF_CLK_ROOT.outFreq, value: 24 MHz} - {id: EMV1_CLK_ROOT.outFreq, value: 24 MHz} - {id: EMV2_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET1_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET2_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET_1G_TX_CLK.outFreq, value: 24 MHz} - {id: ENET_25M_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET_QOS_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET_TIMER1_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET_TIMER2_CLK_ROOT.outFreq, value: 24 MHz} - {id: ENET_TIMER3_CLK_ROOT.outFreq, value: 24 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 24 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 24 MHz} - {id: FLEXSPI1_CLK_ROOT.outFreq, value: 24 MHz} - {id: FLEXSPI2_CLK_ROOT.outFreq, value: 24 MHz} - {id: GC355_CLK_ROOT.outFreq, value: 492.0000125 MHz} - {id: GPT1_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: GPT2_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: GPT3_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT3_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: GPT4_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT4_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: GPT5_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT5_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: GPT6_CLK_ROOT.outFreq, value: 24 MHz} - {id: GPT6_ipg_clk_highfreq.outFreq, value: 24 MHz} - {id: LCDIFV2_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C1_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C2_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C3_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C4_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C5_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPI2C6_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI1_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI2_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI3_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI4_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI5_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPSPI6_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART10_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART11_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART12_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART1_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART2_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART3_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART4_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART5_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART6_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART7_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART8_CLK_ROOT.outFreq, value: 24 MHz} - {id: LPUART9_CLK_ROOT.outFreq, value: 24 MHz} - {id: M4_CLK_ROOT.outFreq, value: 4320/11 MHz} - {id: M4_SYSTICK_CLK_ROOT.outFreq, value: 24 MHz} - {id: M7_CLK_ROOT.outFreq, value: 996 MHz} - {id: M7_SYSTICK_CLK_ROOT.outFreq, value: 100 kHz} - {id: MIC_CLK_ROOT.outFreq, value: 24 MHz} - {id: MIPI_DSI_TX_CLK_ESC_ROOT.outFreq, value: 24 MHz} - {id: MIPI_ESC_CLK_ROOT.outFreq, value: 24 MHz} - {id: MIPI_REF_CLK_ROOT.outFreq, value: 24 MHz} - {id: MQS_CLK_ROOT.outFreq, value: 24 MHz} - {id: MQS_MCLK.outFreq, value: 24 MHz} - {id: OSC_24M.outFreq, value: 24 MHz} - {id: OSC_32K.outFreq, value: 32.768 kHz} - {id: OSC_RC_16M.outFreq, value: 16 MHz} - {id: OSC_RC_400M.outFreq, value: 400 MHz} - {id: OSC_RC_48M.outFreq, value: 48 MHz} - {id: OSC_RC_48M_DIV2.outFreq, value: 24 MHz} - {id: PLL_VIDEO_CLK.outFreq, value: 984.000025 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 24 MHz} - {id: SAI1_MCLK1.outFreq, value: 24 MHz} - {id: SAI1_MCLK3.outFreq, value: 24 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 24 MHz} - {id: SAI2_MCLK1.outFreq, value: 24 MHz} - {id: SAI2_MCLK3.outFreq, value: 24 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 24 MHz} - {id: SAI3_MCLK1.outFreq, value: 24 MHz} - {id: SAI3_MCLK3.outFreq, value: 24 MHz} - {id: SAI4_CLK_ROOT.outFreq, value: 24 MHz} - {id: SAI4_MCLK1.outFreq, value: 24 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 198 MHz} - {id: SPDIF_CLK_ROOT.outFreq, value: 24 MHz} - {id: SYS_PLL2_CLK.outFreq, value: 528 MHz} - {id: SYS_PLL2_PFD0_CLK.outFreq, value: 352 MHz} - {id: SYS_PLL2_PFD1_CLK.outFreq, value: 594 MHz} - {id: SYS_PLL2_PFD2_CLK.outFreq, value: 396 MHz} - {id: SYS_PLL2_PFD3_CLK.outFreq, value: 297 MHz} - {id: SYS_PLL3_CLK.outFreq, value: 480 MHz} - {id: SYS_PLL3_DIV2_CLK.outFreq, value: 240 MHz} - {id: SYS_PLL3_PFD0_CLK.outFreq, value: 8640/13 MHz} - {id: SYS_PLL3_PFD1_CLK.outFreq, value: 8640/17 MHz} - {id: SYS_PLL3_PFD2_CLK.outFreq, value: 270 MHz} - {id: SYS_PLL3_PFD3_CLK.outFreq, value: 4320/11 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 24 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 24 MHz} settings: - {id: CoreBusClockRootsInitializationConfig, value: selectedCore} - {id: SOCDomainVoltage, value: OD} - {id: ANADIG_OSC_OSC_24M_CTRL_LP_EN_CFG, value: Low} - {id: ANADIG_OSC_OSC_24M_CTRL_OSC_EN_CFG, value: Enabled} - {id: ANADIG_PLL.PLL_AUDIO_BYPASS.sel, value: ANADIG_OSC.OSC_24M} - {id: ANADIG_PLL.PLL_VIDEO.denom, value: '960000'} - {id: ANADIG_PLL.PLL_VIDEO.div, value: '41'} - {id: ANADIG_PLL.PLL_VIDEO.num, value: '1'} - {id: ANADIG_PLL.SYS_PLL1_BYPASS.sel, value: ANADIG_OSC.OSC_24M} - {id: ANADIG_PLL.SYS_PLL2.denom, value: '268435455'} - {id: ANADIG_PLL.SYS_PLL2.div, value: '22'} - {id: ANADIG_PLL.SYS_PLL2.num, value: '0'} - {id: ANADIG_PLL.SYS_PLL2_SS_DIV.scale, value: '268435455'} - {id: ANADIG_PLL.SYS_PLL3_PFD3_DIV.scale, value: '22', locked: true} - {id: ANADIG_PLL.SYS_PLL3_PFD3_MUL.scale, value: '18', locked: true} - {id: ANADIG_PLL_ARM_PLL_CTRL_POWERUP_CFG, value: Enabled} - {id: ANADIG_PLL_PLL_AUDIO_CTRL_GATE_CFG, value: Disabled} - {id: ANADIG_PLL_PLL_VIDEO_CTRL0_POWERUP_CFG, value: Enabled} - {id: ANADIG_PLL_SYS_PLL1_CTRL0_POWERUP_CFG, value: Disabled} - {id: ANADIG_PLL_SYS_PLL1_CTRL_GATE_CFG, value: Disabled} - {id: ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_CFG, value: Enabled} - {id: ANADIG_PLL_SYS_PLL3_CTRL_POWERUP_CFG, value: Enabled} - {id: ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_DIV2_CFG, value: Enabled} - {id: CCM.CLOCK_ROOT0.MUX.sel, value: ANADIG_PLL.ARM_PLL_CLK} - {id: CCM.CLOCK_ROOT1.MUX.sel, value: ANADIG_PLL.SYS_PLL3_PFD3_CLK} - {id: CCM.CLOCK_ROOT2.DIV.scale, value: '2'} - {id: CCM.CLOCK_ROOT2.MUX.sel, value: ANADIG_PLL.SYS_PLL3_CLK} - {id: CCM.CLOCK_ROOT25.DIV.scale, value: '22'} - {id: CCM.CLOCK_ROOT25.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} - {id: CCM.CLOCK_ROOT26.DIV.scale, value: '22'} - {id: CCM.CLOCK_ROOT26.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} - {id: CCM.CLOCK_ROOT3.DIV.scale, value: '3'} - {id: CCM.CLOCK_ROOT3.MUX.sel, value: ANADIG_PLL.SYS_PLL3_CLK} - {id: CCM.CLOCK_ROOT4.DIV.scale, value: '3'} - {id: CCM.CLOCK_ROOT4.MUX.sel, value: ANADIG_PLL.SYS_PLL2_PFD1_CLK} - {id: CCM.CLOCK_ROOT6.DIV.scale, value: '4'} - {id: CCM.CLOCK_ROOT6.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} - {id: CCM.CLOCK_ROOT68.DIV.scale, value: '2'} - {id: CCM.CLOCK_ROOT68.MUX.sel, value: ANADIG_PLL.PLL_VIDEO_CLK} - {id: CCM.CLOCK_ROOT8.DIV.scale, value: '240'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ #ifndef SKIP_POWER_ADJUSTMENT #if __CORTEX_M == 7 #define BYPASS_LDO_LPSR 1 #define SKIP_LDO_ADJUSTMENT 1 #elif __CORTEX_M == 4 #define SKIP_DCDC_ADJUSTMENT 1 #define SKIP_FBB_ENABLE 1 #endif #endif const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .postDivider = kCLOCK_PllPostDiv2, /* Post divider, 0 - DIV by 2, 1 - DIV by 4, 2 - DIV by 8, 3 - DIV by 1 */ .loopDivider = 166, /* PLL Loop divider, Fout = Fin * ( loopDivider / ( 2 * postDivider ) ) */ }; const clock_sys_pll2_config_t sysPll2Config_BOARD_BootClockRUN = { .mfd = 268435455, /* Denominator of spread spectrum */ .ss = NULL, /* Spread spectrum parameter */ .ssEnable = false, /* Enable spread spectrum or not */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 41, /* PLL Loop divider, valid range for DIV_SELECT divider value: 27 ~ 54. */ .postDivider = 0, /* Divider after PLL, should only be 1, 2, 4, 8, 16, 32 */ .numerator = 1, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 960000, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .ss = NULL, /* Spread spectrum parameter */ .ssEnable = false, /* Enable spread spectrum or not */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { clock_root_config_t rootCfg = {0}; #if !defined(SKIP_DCDC_CONFIGURATION) || (!SKIP_DCDC_CONFIGURATION) /* Set DCDC to DCM mode to improve the efficiency for light loading in run mode and transient performance with a big loading step. */ DCDC_BootIntoDCM(DCDC); #if !defined(SKIP_DCDC_ADJUSTMENT) || (!SKIP_DCDC_ADJUSTMENT) if((OCOTP->FUSEN[16].FUSE == 0x57AC5969U) && ((OCOTP->FUSEN[17].FUSE & 0xFFU) == 0x0BU)) { DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_1P0BuckTarget1P15V); } else { /* Set 1.125V for production samples to align with data sheet requirement */ DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_1P0BuckTarget1P125V); } #endif /* SKIP_DCDC_ADJUSTMENT */ #endif /* SKIP_DCDC_CONFIGURATION */ #if !defined(SKIP_FBB_ENABLE) || (!SKIP_FBB_ENABLE) /* Check if FBB need to be enabled in OverDrive(OD) mode */ if(((OCOTP->FUSEN[7].FUSE & 0x10U) >> 4U) != 1) { PMU_EnableBodyBias(ANADIG_PMU, kPMU_FBB_CM7, true); } else { PMU_EnableBodyBias(ANADIG_PMU, kPMU_FBB_CM7, false); } #endif #if defined(BYPASS_LDO_LPSR) && BYPASS_LDO_LPSR PMU_StaticEnableLpsrAnaLdoBypassMode(ANADIG_LDO_SNVS, true); PMU_StaticEnableLpsrDigLdoBypassMode(ANADIG_LDO_SNVS, true); #endif #if !defined(SKIP_LDO_ADJUSTMENT) || (!SKIP_LDO_ADJUSTMENT) pmu_static_lpsr_ana_ldo_config_t lpsrAnaConfig; pmu_static_lpsr_dig_config_t lpsrDigConfig; if((ANADIG_LDO_SNVS->PMU_LDO_LPSR_ANA & ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK) == 0UL) { PMU_StaticGetLpsrAnaLdoDefaultConfig(&lpsrAnaConfig); PMU_StaticLpsrAnaLdoInit(ANADIG_LDO_SNVS, &lpsrAnaConfig); } if((ANADIG_LDO_SNVS->PMU_LDO_LPSR_DIG & ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK) == 0UL) { PMU_StaticGetLpsrDigLdoDefaultConfig(&lpsrDigConfig); lpsrDigConfig.targetVoltage = kPMU_LpsrDigTargetStableVoltage1P117V; PMU_StaticLpsrDigLdoInit(ANADIG_LDO_SNVS, &lpsrDigConfig); } #endif /* Config CLK_1M */ CLOCK_OSC_Set1MHzOutputBehavior(kCLOCK_1MHzOutEnableFreeRunning1Mhz); /* Init OSC RC 16M */ ANADIG_OSC->OSC_16M_CTRL |= ANADIG_OSC_OSC_16M_CTRL_EN_IRC4M16M_MASK; /* Init OSC RC 400M */ CLOCK_OSC_EnableOscRc400M(); /* Init OSC RC 48M */ CLOCK_OSC_EnableOsc48M(true); CLOCK_OSC_EnableOsc48MDiv2(true); /* Config OSC 24M */ ANADIG_OSC->OSC_24M_CTRL |= ANADIG_OSC_OSC_24M_CTRL_OSC_EN(1) | ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN(0) | ANADIG_OSC_OSC_24M_CTRL_BYPASS_CLK(0) | ANADIG_OSC_OSC_24M_CTRL_LP_EN(1) | ANADIG_OSC_OSC_24M_CTRL_OSC_24M_GATE(0); /* Wait for 24M OSC to be stable. */ while (ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK != (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK)) { } /* Switch core M7 clock root to OscRC48MDiv2 first */ #if __CORTEX_M == 7 rootCfg.mux = kCLOCK_M7_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg); #endif /* Switch core M7 systick clock root to OscRC48MDiv2 first */ #if __CORTEX_M == 7 rootCfg.mux = kCLOCK_M7_SYSTICK_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M7_Systick, &rootCfg); #endif /* Switch core M4 clock root to OscRC48MDiv2 first */ #if __CORTEX_M == 4 rootCfg.mux = kCLOCK_M4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M4, &rootCfg); #endif /* Switch the Bus_Lpsr clock root to OscRC48MDiv2 first */ #if __CORTEX_M == 4 rootCfg.mux = kCLOCK_BUS_LPSR_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Bus_Lpsr, &rootCfg); #endif /* * if DCD is used, please make sure the clock source of SEMC is not changed in the following PLL/PFD configuration code. */ /* Init Arm Pll. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* Bypass Sys Pll1. */ CLOCK_SetPllBypass(kCLOCK_PllSys1, true); /* DeInit Sys Pll1. */ CLOCK_DeinitSysPll1(); /* Init Sys Pll2. */ CLOCK_InitSysPll2(&sysPll2Config_BOARD_BootClockRUN); /* Init System Pll2 pfd0. */ CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd0, 27); /* Init System Pll2 pfd1. */ CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd1, 16); /* Init System Pll2 pfd2. */ CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd2, 24); /* Init System Pll2 pfd3. */ CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd3, 32); /* Init Sys Pll3. */ CLOCK_InitSysPll3(); /* Init System Pll3 pfd0. */ CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd0, 13); /* Init System Pll3 pfd1. */ CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd1, 17); /* Init System Pll3 pfd2. */ CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd2, 32); /* Init System Pll3 pfd3. */ CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd3, 22); /* Bypass Audio Pll. */ CLOCK_SetPllBypass(kCLOCK_PllAudio, true); /* DeInit Audio Pll. */ CLOCK_DeinitAudioPll(); /* Init Video Pll. */ CLOCK_InitVideoPll(&videoPllConfig_BOARD_BootClockRUN); /* Module clock root configurations. */ /* Configure M7 using ARM_PLL_CLK */ #if __CORTEX_M == 7 rootCfg.mux = kCLOCK_M7_ClockRoot_MuxArmPllOut; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg); #endif /* Configure M4 using SYS_PLL3_PFD3_CLK */ #if __CORTEX_M == 4 rootCfg.mux = kCLOCK_M4_ClockRoot_MuxSysPll3Pfd3; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M4, &rootCfg); #endif /* Configure BUS using SYS_PLL3_CLK */ rootCfg.mux = kCLOCK_BUS_ClockRoot_MuxSysPll3Out; rootCfg.div = 2; CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg); /* Configure BUS_LPSR using SYS_PLL3_CLK */ rootCfg.mux = kCLOCK_BUS_LPSR_ClockRoot_MuxSysPll3Out; rootCfg.div = 3; CLOCK_SetRootClock(kCLOCK_Root_Bus_Lpsr, &rootCfg); /* Configure SEMC using SYS_PLL2_PFD1_CLK */ #ifndef SKIP_SEMC_INIT rootCfg.mux = kCLOCK_SEMC_ClockRoot_MuxSysPll2Pfd1; rootCfg.div = 3; CLOCK_SetRootClock(kCLOCK_Root_Semc, &rootCfg); #endif #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) UpdateSemcClock(); #endif #endif /* Configure CSSYS using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CSSYS_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Cssys, &rootCfg); /* Configure CSTRACE using SYS_PLL2_CLK */ rootCfg.mux = kCLOCK_CSTRACE_ClockRoot_MuxSysPll2Out; rootCfg.div = 4; CLOCK_SetRootClock(kCLOCK_Root_Cstrace, &rootCfg); /* Configure M4_SYSTICK using OSC_RC_48M_DIV2 */ #if __CORTEX_M == 4 rootCfg.mux = kCLOCK_M4_SYSTICK_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_M4_Systick, &rootCfg); #endif /* Configure M7_SYSTICK using OSC_RC_48M_DIV2 */ #if __CORTEX_M == 7 rootCfg.mux = kCLOCK_M7_SYSTICK_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 240; CLOCK_SetRootClock(kCLOCK_Root_M7_Systick, &rootCfg); #endif /* Configure ADC1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ADC1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Adc1, &rootCfg); /* Configure ADC2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ADC2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Adc2, &rootCfg); /* Configure ACMP using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ACMP_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Acmp, &rootCfg); /* Configure FLEXIO1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_FLEXIO1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Flexio1, &rootCfg); /* Configure FLEXIO2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_FLEXIO2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Flexio2, &rootCfg); /* Configure GPT1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt1, &rootCfg); /* Configure GPT2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt2, &rootCfg); /* Configure GPT3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt3, &rootCfg); /* Configure GPT4 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt4, &rootCfg); /* Configure GPT5 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT5_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt5, &rootCfg); /* Configure GPT6 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_GPT6_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Gpt6, &rootCfg); /* Configure FLEXSPI1 using OSC_RC_48M_DIV2 */ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) || defined(FLEXSPI_IN_USE)) rootCfg.mux = kCLOCK_FLEXSPI1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg); #endif /* Configure FLEXSPI2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_FLEXSPI2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Flexspi2, &rootCfg); /* Configure CAN1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CAN1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Can1, &rootCfg); /* Configure CAN2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CAN2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Can2, &rootCfg); /* Configure CAN3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CAN3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Can3, &rootCfg); /* Configure LPUART1 using SYS_PLL2_CLK */ rootCfg.mux = kCLOCK_LPUART1_ClockRoot_MuxSysPll2Out; rootCfg.div = 22; CLOCK_SetRootClock(kCLOCK_Root_Lpuart1, &rootCfg); /* Configure LPUART2 using SYS_PLL2_CLK */ rootCfg.mux = kCLOCK_LPUART2_ClockRoot_MuxSysPll2Out; rootCfg.div = 22; CLOCK_SetRootClock(kCLOCK_Root_Lpuart2, &rootCfg); /* Configure LPUART3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart3, &rootCfg); /* Configure LPUART4 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart4, &rootCfg); /* Configure LPUART5 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART5_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart5, &rootCfg); /* Configure LPUART6 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART6_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart6, &rootCfg); /* Configure LPUART7 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART7_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart7, &rootCfg); /* Configure LPUART8 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART8_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart8, &rootCfg); /* Configure LPUART9 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART9_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart9, &rootCfg); /* Configure LPUART10 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART10_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart10, &rootCfg); /* Configure LPUART11 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART11_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart11, &rootCfg); /* Configure LPUART12 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPUART12_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpuart12, &rootCfg); /* Configure LPI2C1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c1, &rootCfg); /* Configure LPI2C2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c2, &rootCfg); /* Configure LPI2C3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c3, &rootCfg); /* Configure LPI2C4 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c4, &rootCfg); /* Configure LPI2C5 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C5_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c5, &rootCfg); /* Configure LPI2C6 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPI2C6_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpi2c6, &rootCfg); /* Configure LPSPI1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi1, &rootCfg); /* Configure LPSPI2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi2, &rootCfg); /* Configure LPSPI3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi3, &rootCfg); /* Configure LPSPI4 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi4, &rootCfg); /* Configure LPSPI5 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI5_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi5, &rootCfg); /* Configure LPSPI6 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI6_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lpspi6, &rootCfg); /* Configure EMV1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_EMV1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Emv1, &rootCfg); /* Configure EMV2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_EMV2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Emv2, &rootCfg); /* Configure ENET1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet1, &rootCfg); /* Configure ENET2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg); /* Configure ENET_QOS using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET_QOS_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet_Qos, &rootCfg); /* Configure ENET_25M using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET_25M_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet_25m, &rootCfg); /* Configure ENET_TIMER1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET_TIMER1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer1, &rootCfg); /* Configure ENET_TIMER2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET_TIMER2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer2, &rootCfg); /* Configure ENET_TIMER3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ENET_TIMER3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer3, &rootCfg); /* Configure USDHC1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_USDHC1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Usdhc1, &rootCfg); /* Configure USDHC2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_USDHC2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Usdhc2, &rootCfg); /* Configure ASRC using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_ASRC_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Asrc, &rootCfg); /* Configure MQS using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_MQS_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Mqs, &rootCfg); /* Configure MIC using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_MIC_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Mic, &rootCfg); /* Configure SPDIF using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_SPDIF_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Spdif, &rootCfg); /* Configure SAI1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_SAI1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Sai1, &rootCfg); /* Configure SAI2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_SAI2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Sai2, &rootCfg); /* Configure SAI3 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_SAI3_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Sai3, &rootCfg); /* Configure SAI4 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_SAI4_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Sai4, &rootCfg); /* Configure GC355 using PLL_VIDEO_CLK */ rootCfg.mux = kCLOCK_GC355_ClockRoot_MuxVideoPllOut; rootCfg.div = 2; CLOCK_SetRootClock(kCLOCK_Root_Gc355, &rootCfg); /* Configure LCDIF using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LCDIF_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lcdif, &rootCfg); /* Configure LCDIFV2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LCDIFV2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Lcdifv2, &rootCfg); /* Configure MIPI_REF using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_MIPI_REF_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Mipi_Ref, &rootCfg); /* Configure MIPI_ESC using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_MIPI_ESC_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Mipi_Esc, &rootCfg); /* Configure CSI2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CSI2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Csi2, &rootCfg); /* Configure CSI2_ESC using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CSI2_ESC_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Csi2_Esc, &rootCfg); /* Configure CSI2_UI using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CSI2_UI_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Csi2_Ui, &rootCfg); /* Configure CSI using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CSI_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Csi, &rootCfg); /* Configure CKO1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CKO1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Cko1, &rootCfg); /* Configure CKO2 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_CKO2_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 1; CLOCK_SetRootClock(kCLOCK_Root_Cko2, &rootCfg); /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 3); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR4 &= ~IOMUXC_GPR_GPR4_ENET_REF_CLK_DIR_MASK; /* Set ENET_1G Tx clock source. */ IOMUXC_GPR->GPR5 = ((IOMUXC_GPR->GPR5 & ~IOMUXC_GPR_GPR5_ENET1G_TX_CLK_SEL_MASK) | IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK); /* Set ENET_1G Ref clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_ENET1G_REF_CLK_DIR_MASK; /* Set ENET_QOS Tx clock source. */ IOMUXC_GPR->GPR6 &= ~IOMUXC_GPR_GPR6_ENET_QOS_RGMII_EN_MASK; /* Set ENET_QOS Ref clock source. */ IOMUXC_GPR->GPR6 &= ~IOMUXC_GPR_GPR6_ENET_QOS_REF_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR22 &= ~IOMUXC_GPR_GPR22_REF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR23 &= ~IOMUXC_GPR_GPR23_REF_1M_CLK_GPT2_MASK; /* Set GPT3 High frequency reference clock source. */ IOMUXC_GPR->GPR24 &= ~IOMUXC_GPR_GPR24_REF_1M_CLK_GPT3_MASK; /* Set GPT4 High frequency reference clock source. */ IOMUXC_GPR->GPR25 &= ~IOMUXC_GPR_GPR25_REF_1M_CLK_GPT4_MASK; /* Set GPT5 High frequency reference clock source. */ IOMUXC_GPR->GPR26 &= ~IOMUXC_GPR_GPR26_REF_1M_CLK_GPT5_MASK; /* Set GPT6 High frequency reference clock source. */ IOMUXC_GPR->GPR27 &= ~IOMUXC_GPR_GPR27_REF_1M_CLK_GPT6_MASK; #if __CORTEX_M == 7 SystemCoreClock = CLOCK_GetRootClockFreq(kCLOCK_Root_M7); #else SystemCoreClock = CLOCK_GetRootClockFreq(kCLOCK_Root_M4); #endif } ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #if __CORTEX_M == 7 #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 996000000UL /*!< CM7 Core clock frequency: 996000000Hz */ #else #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 392727272UL /*!< CM4 Core clock frequency: 392727272Hz */ #endif /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_ACMP_CLK_ROOT 24000000UL /* Clock consumers of ACMP_CLK_ROOT output : CMP1, CMP2, CMP3, CMP4 */ #define BOARD_BOOTCLOCKRUN_ADC1_CLK_ROOT 24000000UL /* Clock consumers of ADC1_CLK_ROOT output : LPADC1 */ #define BOARD_BOOTCLOCKRUN_ADC2_CLK_ROOT 24000000UL /* Clock consumers of ADC2_CLK_ROOT output : LPADC2 */ #define BOARD_BOOTCLOCKRUN_ARM_PLL_CLK 996000000UL /* Clock consumers of ARM_PLL_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_ASRC_CLK_ROOT 24000000UL /* Clock consumers of ASRC_CLK_ROOT output : ASRC */ #define BOARD_BOOTCLOCKRUN_AXI_CLK_ROOT 996000000UL /* Clock consumers of AXI_CLK_ROOT output : FLEXRAM */ #define BOARD_BOOTCLOCKRUN_BUS_CLK_ROOT 240000000UL /* Clock consumers of BUS_CLK_ROOT output : ADC_ETC, AOI1, AOI2, CAAM, CAN1, CAN2, CM7_GPIO2, CM7_GPIO3, CMP1, CMP2, CMP3, CMP4, CSI, DAC, DMA0, DMAMUX0, DSI_HOST, EMVSIM1, EMVSIM2, ENC1, ENC2, ENC3, ENC4, ENET, ENET_1G, ENET_QOS, EWM, FLEXIO1, FLEXIO2, FLEXSPI1, FLEXSPI2, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, IEE_APC, IEE__IEE_RT1170, IOMUXC, IOMUXC_GPR, KPP, LCDIF, LCDIFV2, LPADC1, LPADC2, LPI2C1, LPI2C2, LPI2C3, LPI2C4, LPSPI1, LPSPI2, LPSPI3, LPSPI4, LPUART1, LPUART10, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8, LPUART9, MECC1, MECC2, MIPI_CSI2RX, PIT1, PWM1, PWM2, PWM3, PWM4, PXP, RTWDOG3, SAI1, SAI2, SAI3, SPDIF, TMR1, TMR2, TMR3, TMR4, USBPHY1, USBPHY2, USB_OTG1, USB_OTG2, USDHC1, USDHC2, WDOG1, WDOG2, XBARA1, XBARB2, XBARB3, XECC_FLEXSPI1, XECC_FLEXSPI2, XECC_SEMC, XRDC2_D0, XRDC2_D1 */ #define BOARD_BOOTCLOCKRUN_BUS_LPSR_CLK_ROOT 160000000UL /* Clock consumers of BUS_LPSR_CLK_ROOT output : CAN3, GPIO10, GPIO11, GPIO12, GPIO7, GPIO8, GPIO9, IOMUXC_LPSR, LPI2C5, LPI2C6, LPSPI5, LPSPI6, LPUART11, LPUART12, MUA, MUB, PDM, PIT2, RDC, RTWDOG4, SAI4, SNVS, XRDC2_D0, XRDC2_D1 */ #define BOARD_BOOTCLOCKRUN_CAN1_CLK_ROOT 24000000UL /* Clock consumers of CAN1_CLK_ROOT output : CAN1 */ #define BOARD_BOOTCLOCKRUN_CAN2_CLK_ROOT 24000000UL /* Clock consumers of CAN2_CLK_ROOT output : CAN2 */ #define BOARD_BOOTCLOCKRUN_CAN3_CLK_ROOT 24000000UL /* Clock consumers of CAN3_CLK_ROOT output : CAN3 */ #define BOARD_BOOTCLOCKRUN_CCM_CLKO1_CLK_ROOT 24000000UL /* Clock consumers of CCM_CLKO1_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_CCM_CLKO2_CLK_ROOT 24000000UL /* Clock consumers of CCM_CLKO2_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG3, RTWDOG4 */ #define BOARD_BOOTCLOCKRUN_CSI2_CLK_ROOT 24000000UL /* Clock consumers of CSI2_CLK_ROOT output : MIPI_CSI2RX */ #define BOARD_BOOTCLOCKRUN_CSI2_ESC_CLK_ROOT 24000000UL /* Clock consumers of CSI2_ESC_CLK_ROOT output : MIPI_CSI2RX */ #define BOARD_BOOTCLOCKRUN_CSI2_UI_CLK_ROOT 24000000UL /* Clock consumers of CSI2_UI_CLK_ROOT output : MIPI_CSI2RX */ #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 24000000UL /* Clock consumers of CSI_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_CSSYS_CLK_ROOT 24000000UL /* Clock consumers of CSSYS_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_CSTRACE_CLK_ROOT 132000000UL /* Clock consumers of CSTRACE_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_ELCDIF_CLK_ROOT 24000000UL /* Clock consumers of ELCDIF_CLK_ROOT output : LCDIF */ #define BOARD_BOOTCLOCKRUN_EMV1_CLK_ROOT 24000000UL /* Clock consumers of EMV1_CLK_ROOT output : EMVSIM1 */ #define BOARD_BOOTCLOCKRUN_EMV2_CLK_ROOT 24000000UL /* Clock consumers of EMV2_CLK_ROOT output : EMVSIM2 */ #define BOARD_BOOTCLOCKRUN_ENET1_CLK_ROOT 24000000UL /* Clock consumers of ENET1_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET2_CLK_ROOT 24000000UL /* Clock consumers of ENET2_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET_1G_REF_CLK 0UL /* Clock consumers of ENET_1G_REF_CLK output : ENET_1G */ #define BOARD_BOOTCLOCKRUN_ENET_1G_TX_CLK 24000000UL /* Clock consumers of ENET_1G_TX_CLK output : ENET_1G */ #define BOARD_BOOTCLOCKRUN_ENET_25M_CLK_ROOT 24000000UL /* Clock consumers of ENET_25M_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET_QOS_CLK_ROOT 24000000UL /* Clock consumers of ENET_QOS_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_ENET_QOS_REF_CLK 0UL /* Clock consumers of ENET_QOS_REF_CLK output : ENET_QOS */ #define BOARD_BOOTCLOCKRUN_ENET_QOS_TX_CLK 0UL /* Clock consumers of ENET_QOS_TX_CLK output : ENET_QOS */ #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL /* Clock consumers of ENET_REF_CLK output : ENET */ #define BOARD_BOOTCLOCKRUN_ENET_TIMER1_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER1_CLK_ROOT output : ENET */ #define BOARD_BOOTCLOCKRUN_ENET_TIMER2_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER2_CLK_ROOT output : ENET_1G */ #define BOARD_BOOTCLOCKRUN_ENET_TIMER3_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER3_CLK_ROOT output : ENET_QOS */ #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL /* Clock consumers of ENET_TX_CLK output : ENET */ #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 24000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 24000000UL /* Clock consumers of FLEXIO2_CLK_ROOT output : FLEXIO2 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI1_CLK_ROOT 24000000UL /* Clock consumers of FLEXSPI1_CLK_ROOT output : FLEXSPI1 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 24000000UL /* Clock consumers of FLEXSPI2_CLK_ROOT output : FLEXSPI2 */ #define BOARD_BOOTCLOCKRUN_GC355_CLK_ROOT 492000012UL /* Clock consumers of GC355_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT1_CLK_ROOT 24000000UL /* Clock consumers of GPT1_CLK_ROOT output : GPT1 */ #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT2_CLK_ROOT 24000000UL /* Clock consumers of GPT2_CLK_ROOT output : GPT2 */ #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT3_CLK_ROOT 24000000UL /* Clock consumers of GPT3_CLK_ROOT output : GPT3 */ #define BOARD_BOOTCLOCKRUN_GPT3_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT3_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT4_CLK_ROOT 24000000UL /* Clock consumers of GPT4_CLK_ROOT output : GPT4 */ #define BOARD_BOOTCLOCKRUN_GPT4_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT4_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT5_CLK_ROOT 24000000UL /* Clock consumers of GPT5_CLK_ROOT output : GPT5 */ #define BOARD_BOOTCLOCKRUN_GPT5_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT5_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_GPT6_CLK_ROOT 24000000UL /* Clock consumers of GPT6_CLK_ROOT output : GPT6 */ #define BOARD_BOOTCLOCKRUN_GPT6_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT6_ipg_clk_highfreq output : N/A */ #define BOARD_BOOTCLOCKRUN_LCDIFV2_CLK_ROOT 24000000UL /* Clock consumers of LCDIFV2_CLK_ROOT output : LCDIFV2 */ #define BOARD_BOOTCLOCKRUN_LPI2C1_CLK_ROOT 24000000UL /* Clock consumers of LPI2C1_CLK_ROOT output : LPI2C1 */ #define BOARD_BOOTCLOCKRUN_LPI2C2_CLK_ROOT 24000000UL /* Clock consumers of LPI2C2_CLK_ROOT output : LPI2C2 */ #define BOARD_BOOTCLOCKRUN_LPI2C3_CLK_ROOT 24000000UL /* Clock consumers of LPI2C3_CLK_ROOT output : LPI2C3 */ #define BOARD_BOOTCLOCKRUN_LPI2C4_CLK_ROOT 24000000UL /* Clock consumers of LPI2C4_CLK_ROOT output : LPI2C4 */ #define BOARD_BOOTCLOCKRUN_LPI2C5_CLK_ROOT 24000000UL /* Clock consumers of LPI2C5_CLK_ROOT output : LPI2C5 */ #define BOARD_BOOTCLOCKRUN_LPI2C6_CLK_ROOT 24000000UL /* Clock consumers of LPI2C6_CLK_ROOT output : LPI2C6 */ #define BOARD_BOOTCLOCKRUN_LPSPI1_CLK_ROOT 24000000UL /* Clock consumers of LPSPI1_CLK_ROOT output : LPSPI1 */ #define BOARD_BOOTCLOCKRUN_LPSPI2_CLK_ROOT 24000000UL /* Clock consumers of LPSPI2_CLK_ROOT output : LPSPI2 */ #define BOARD_BOOTCLOCKRUN_LPSPI3_CLK_ROOT 24000000UL /* Clock consumers of LPSPI3_CLK_ROOT output : LPSPI3 */ #define BOARD_BOOTCLOCKRUN_LPSPI4_CLK_ROOT 24000000UL /* Clock consumers of LPSPI4_CLK_ROOT output : LPSPI4 */ #define BOARD_BOOTCLOCKRUN_LPSPI5_CLK_ROOT 24000000UL /* Clock consumers of LPSPI5_CLK_ROOT output : LPSPI5 */ #define BOARD_BOOTCLOCKRUN_LPSPI6_CLK_ROOT 24000000UL /* Clock consumers of LPSPI6_CLK_ROOT output : LPSPI6 */ #define BOARD_BOOTCLOCKRUN_LPUART10_CLK_ROOT 24000000UL /* Clock consumers of LPUART10_CLK_ROOT output : LPUART10 */ #define BOARD_BOOTCLOCKRUN_LPUART11_CLK_ROOT 24000000UL /* Clock consumers of LPUART11_CLK_ROOT output : LPUART11 */ #define BOARD_BOOTCLOCKRUN_LPUART12_CLK_ROOT 24000000UL /* Clock consumers of LPUART12_CLK_ROOT output : LPUART12 */ #define BOARD_BOOTCLOCKRUN_LPUART1_CLK_ROOT 24000000UL /* Clock consumers of LPUART1_CLK_ROOT output : LPUART1 */ #define BOARD_BOOTCLOCKRUN_LPUART2_CLK_ROOT 24000000UL /* Clock consumers of LPUART2_CLK_ROOT output : LPUART2 */ #define BOARD_BOOTCLOCKRUN_LPUART3_CLK_ROOT 24000000UL /* Clock consumers of LPUART3_CLK_ROOT output : LPUART3 */ #define BOARD_BOOTCLOCKRUN_LPUART4_CLK_ROOT 24000000UL /* Clock consumers of LPUART4_CLK_ROOT output : LPUART4 */ #define BOARD_BOOTCLOCKRUN_LPUART5_CLK_ROOT 24000000UL /* Clock consumers of LPUART5_CLK_ROOT output : LPUART5 */ #define BOARD_BOOTCLOCKRUN_LPUART6_CLK_ROOT 24000000UL /* Clock consumers of LPUART6_CLK_ROOT output : LPUART6 */ #define BOARD_BOOTCLOCKRUN_LPUART7_CLK_ROOT 24000000UL /* Clock consumers of LPUART7_CLK_ROOT output : LPUART7 */ #define BOARD_BOOTCLOCKRUN_LPUART8_CLK_ROOT 24000000UL /* Clock consumers of LPUART8_CLK_ROOT output : LPUART8 */ #define BOARD_BOOTCLOCKRUN_LPUART9_CLK_ROOT 24000000UL /* Clock consumers of LPUART9_CLK_ROOT output : LPUART9 */ #define BOARD_BOOTCLOCKRUN_M4_CLK_ROOT 392727272UL /* Clock consumers of M4_CLK_ROOT output : ARM, DMA1, DMAMUX1, SSARC_HP, SSARC_LP, XRDC2_D0, XRDC2_D1 */ #define BOARD_BOOTCLOCKRUN_M4_SYSTICK_CLK_ROOT 24000000UL /* Clock consumers of M4_SYSTICK_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_M7_CLK_ROOT 996000000UL /* Clock consumers of M7_CLK_ROOT output : ARM */ #define BOARD_BOOTCLOCKRUN_M7_SYSTICK_CLK_ROOT 100000UL /* Clock consumers of M7_SYSTICK_CLK_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_MIC_CLK_ROOT 24000000UL /* Clock consumers of MIC_CLK_ROOT output : ASRC, PDM, SPDIF */ #define BOARD_BOOTCLOCKRUN_MIPI_DSI_TX_CLK_ESC_ROOT 24000000UL /* Clock consumers of MIPI_DSI_TX_CLK_ESC_ROOT output : N/A */ #define BOARD_BOOTCLOCKRUN_MIPI_ESC_CLK_ROOT 24000000UL /* Clock consumers of MIPI_ESC_CLK_ROOT output : DSI_HOST */ #define BOARD_BOOTCLOCKRUN_MIPI_REF_CLK_ROOT 24000000UL /* Clock consumers of MIPI_REF_CLK_ROOT output : DSI_HOST */ #define BOARD_BOOTCLOCKRUN_MQS_CLK_ROOT 24000000UL /* Clock consumers of MQS_CLK_ROOT output : ASRC */ #define BOARD_BOOTCLOCKRUN_MQS_MCLK 24000000UL /* Clock consumers of MQS_MCLK output : N/A */ #define BOARD_BOOTCLOCKRUN_OSC_24M 24000000UL /* Clock consumers of OSC_24M output : SPDIF, TMPSNS, USBPHY1, USBPHY2 */ #define BOARD_BOOTCLOCKRUN_OSC_32K 32768UL /* Clock consumers of OSC_32K output : GPIO13, RTWDOG3, RTWDOG4 */ #define BOARD_BOOTCLOCKRUN_OSC_RC_16M 16000000UL /* Clock consumers of OSC_RC_16M output : CCM, DCDC, EWM, GPT1, GPT2, GPT3, GPT4, GPT5, GPT6, SSARC_LP */ #define BOARD_BOOTCLOCKRUN_OSC_RC_400M 400000000UL /* Clock consumers of OSC_RC_400M output : N/A */ #define BOARD_BOOTCLOCKRUN_OSC_RC_48M 48000000UL /* Clock consumers of OSC_RC_48M output : N/A */ #define BOARD_BOOTCLOCKRUN_OSC_RC_48M_DIV2 24000000UL /* Clock consumers of OSC_RC_48M_DIV2 output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_AUDIO_CLK 0UL /* Clock consumers of PLL_AUDIO_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_AUDIO_SS_MODULATION 0UL /* Clock consumers of PLL_AUDIO_SS_MODULATION output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_AUDIO_SS_RANGE 0UL /* Clock consumers of PLL_AUDIO_SS_RANGE output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_VIDEO_CLK 984000025UL /* Clock consumers of PLL_VIDEO_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_VIDEO_SS_MODULATION 0UL /* Clock consumers of PLL_VIDEO_SS_MODULATION output : N/A */ #define BOARD_BOOTCLOCKRUN_PLL_VIDEO_SS_RANGE 0UL /* Clock consumers of PLL_VIDEO_SS_RANGE output : N/A */ #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 24000000UL /* Clock consumers of SAI1_CLK_ROOT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 24000000UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 0UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 24000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 24000000UL /* Clock consumers of SAI2_CLK_ROOT output : ASRC */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 24000000UL /* Clock consumers of SAI2_MCLK1 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL /* Clock consumers of SAI2_MCLK2 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 24000000UL /* Clock consumers of SAI2_MCLK3 output : SAI2 */ #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 24000000UL /* Clock consumers of SAI3_CLK_ROOT output : ASRC, SPDIF */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 24000000UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 24000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ #define BOARD_BOOTCLOCKRUN_SAI4_CLK_ROOT 24000000UL /* Clock consumers of SAI4_CLK_ROOT output : ASRC, SPDIF */ #define BOARD_BOOTCLOCKRUN_SAI4_MCLK1 24000000UL /* Clock consumers of SAI4_MCLK1 output : SAI4 */ #define BOARD_BOOTCLOCKRUN_SAI4_MCLK2 0UL /* Clock consumers of SAI4_MCLK2 output : SAI4 */ #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 198000000UL /* Clock consumers of SEMC_CLK_ROOT output : SEMC, XECC_FLEXSPI1, XECC_FLEXSPI2, XECC_SEMC, XRDC2_D0, XRDC2_D1 */ #define BOARD_BOOTCLOCKRUN_SPDIF_CLK_ROOT 24000000UL /* Clock consumers of SPDIF_CLK_ROOT output : SPDIF */ #define BOARD_BOOTCLOCKRUN_SPDIF_EXTCLK_OUT 0UL /* Clock consumers of SPDIF_EXTCLK_OUT output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL1_CLK 0UL /* Clock consumers of SYS_PLL1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL1_DIV2_CLK 0UL /* Clock consumers of SYS_PLL1_DIV2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL1_DIV5_CLK 0UL /* Clock consumers of SYS_PLL1_DIV5_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL1_SS_MODULATION 0UL /* Clock consumers of SYS_PLL1_SS_MODULATION output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL1_SS_RANGE 0UL /* Clock consumers of SYS_PLL1_SS_RANGE output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_CLK 528000000UL /* Clock consumers of SYS_PLL2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD0_CLK 352000000UL /* Clock consumers of SYS_PLL2_PFD0_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD1_CLK 594000000UL /* Clock consumers of SYS_PLL2_PFD1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD2_CLK 396000000UL /* Clock consumers of SYS_PLL2_PFD2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD3_CLK 297000000UL /* Clock consumers of SYS_PLL2_PFD3_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_SS_MODULATION 0UL /* Clock consumers of SYS_PLL2_SS_MODULATION output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL2_SS_RANGE 0UL /* Clock consumers of SYS_PLL2_SS_RANGE output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_CLK 480000000UL /* Clock consumers of SYS_PLL3_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_DIV2_CLK 240000000UL /* Clock consumers of SYS_PLL3_DIV2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD0_CLK 664615384UL /* Clock consumers of SYS_PLL3_PFD0_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD1_CLK 508235294UL /* Clock consumers of SYS_PLL3_PFD1_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD2_CLK 270000000UL /* Clock consumers of SYS_PLL3_PFD2_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD3_CLK 392727272UL /* Clock consumers of SYS_PLL3_PFD3_CLK output : N/A */ #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 24000000UL /* Clock consumers of USDHC1_CLK_ROOT output : USDHC1 */ #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 24000000UL /* Clock consumers of USDHC2_CLK_ROOT output : USDHC2 */ /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: MIMXRT1176xxxxx package_id: MIMXRT1176DVMAA mcu_data: ksdk2_0 processor_version: 24.12.10 board: MIMXRT1170-EVKB external_user_signals: {} pin_labels: - {pin_num: M13, pin_signal: GPIO_AD_04, label: 'SIM1_PD/J44[C8]/USER_LED_CTL1/J9[8]/J25[7]', identifier: SIM1_PD;LED;USER_LED} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: cm7, enableClock: 'true'} - pin_list: - {pin_num: M13, peripheral: GPIO9, signal: 'gpio_io, 03', pin_signal: GPIO_AD_04, identifier: USER_LED, direction: OUTPUT, pull_up_down_config: Pull_Down, pull_keeper_select: Keeper} - {pin_num: T8, peripheral: GPIO13, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT, pull_up_down_config: Pull_Up} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins, assigned for the Cortex-M7F core. * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */ /* GPIO configuration of USER_LED on GPIO_AD_04 (pin M13) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_AD_04 (pin M13) */ GPIO_PinInit(GPIO9, 3U, &USER_LED_config); /* GPIO configuration of USER_BUTTON on WAKEUP_DIG (pin T8) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on WAKEUP_DIG (pin T8) */ GPIO_PinInit(GPIO13, 0U, &USER_BUTTON_config); IOMUXC_SetPinMux( IOMUXC_GPIO_AD_04_GPIO9_IO03, /* GPIO_AD_04 is configured as GPIO9_IO03 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_WAKEUP_DIG_GPIO13_IO00, /* WAKEUP_DIG is configured as GPIO13_IO00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_04_GPIO9_IO03, /* GPIO_AD_04 PAD functional properties : */ 0x02U); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: high drive strength Pull / Keep Select Field: Pull Disable Pull Up / Down Config. Field: Weak pull down Open Drain Field: Disabled Domain write protection: Both cores are allowed Domain write protection lock: Neither of DWP bits is locked */ IOMUXC_SetPinConfig( IOMUXC_WAKEUP_DIG_GPIO13_IO00, /* WAKEUP_DIG PAD functional properties : */ 0x0EU); /* Pull / Keep Select Field: Pull Enable Pull Up / Down Config. Field: Weak pull up Open Drain SNVS Field: Disabled Domain write protection: Both cores are allowed Domain write protection lock: Neither of DWP bits is locked */ } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm7, enableClock: 'true'} - pin_list: - {pin_num: L13, peripheral: LPUART1, signal: TXD, pin_signal: GPIO_AD_24, pull_keeper_select: Keeper, slew_rate: Slow} - {pin_num: M15, peripheral: LPUART1, signal: RXD, pin_signal: GPIO_AD_25, pull_keeper_select: Keeper, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins, assigned for the Cortex-M7F core. * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_24 is configured as LPUART1_TXD */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 is configured as LPUART1_RXD */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_24 PAD functional properties : */ 0x02U); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: high drive strength Pull / Keep Select Field: Pull Disable Pull Up / Down Config. Field: Weak pull down Open Drain Field: Disabled Domain write protection: Both cores are allowed Domain write protection lock: Neither of DWP bits is locked */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 PAD functional properties : */ 0x02U); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: high drive strength Pull / Keep Select Field: Pull Disable Pull Up / Down Config. Field: Weak pull down Open Drain Field: Disabled Domain write protection: Both cores are allowed Domain write protection lock: Neither of DWP bits is locked */ } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /* GPIO_AD_04 (coord M13), SIM1_PD/J44[C8]/USER_LED_CTL1/J9[8]/J25[7] */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO9 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO9 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_INIT_GPIO_VALUE 0U /*!< GPIO output initial state */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ /* WAKEUP (coord T8), USER_BUTTON/SW7 */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO13 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO13 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* Function assigned for the Cortex-M7F */ /* GPIO_AD_24 (coord L13), LPUART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_LPUART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_LPUART1_TXD_SIGNAL TXD /*!< Signal name */ /* GPIO_AD_25 (coord M15), LPUART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_LPUART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_LPUART1_RXD_SIGNAL RXD /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M7F */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board.cmake ================================================ set(MCU_FAMILY RT1170) set(MCU_VARIANT MIMXRT1176) if (M4 STREQUAL "1") set(MCU_CORE _cm4) set(JLINK_CORE _M4) set(LD_FILE_GNU ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx${MCU_CORE}_ram.ld) set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") else () set(MCU_CORE _cm7) set(JLINK_CORE _M7) endif() set(JLINK_DEVICE MIMXRT1176xxxA${JLINK_CORE}) set(PYOCD_TARGET mimxrt1170${MCU_CORE}) set(NXPLINK_DEVICE MIMXRT1176xxxxx:MIMXRT1170-EVK) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkbmimxrt1170_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1176DVMAA${MCU_CORE} BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: i.MX RT1070 Evaluation Kit url: https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1170-evaluation-kit:MIMXRT1170-EVKB */ #ifndef BOARD_MIMXRT1170_EVKB_H_ #define BOARD_MIMXRT1170_EVKB_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) // LED: IOMUXC_GPIO_AD_04_GPIO9_IO03 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button: IOMUXC_WAKEUP_DIG_GPIO13_IO00 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX #define UART_PORT LPUART1 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_LPUART10_CLK_ROOT //-------------------------------------------------------------------- // MPU configuration //-------------------------------------------------------------------- #if __CORTEX_M == 7 static inline void BOARD_ConfigMPU(void) { #if defined(__CC_ARM) || defined(__ARMCC_VERSION) extern uint32_t Image$$RW_m_ncache$$Base[]; /* RW_m_ncache_unused is a auxiliary region which is used to get the whole size of noncache section */ extern uint32_t Image$$RW_m_ncache_unused$$Base[]; extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[]; uint32_t nonCacheStart = (uint32_t) Image$$RW_m_ncache$$Base; uint32_t size = ((uint32_t) Image$$RW_m_ncache_unused$$Base == nonCacheStart) ? 0 : ((uint32_t) Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart); #elif defined(__MCUXPRESSO) #if defined(__USE_SHMEM) extern uint32_t __base_rpmsg_sh_mem; extern uint32_t __top_rpmsg_sh_mem; uint32_t nonCacheStart = (uint32_t) (&__base_rpmsg_sh_mem); uint32_t size = (uint32_t) (&__top_rpmsg_sh_mem) - nonCacheStart; #else extern uint32_t __base_NCACHE_REGION; extern uint32_t __top_NCACHE_REGION; uint32_t nonCacheStart = (uint32_t) (&__base_NCACHE_REGION); uint32_t size = (uint32_t) (&__top_NCACHE_REGION) - nonCacheStart; #endif #elif defined(__ICCARM__) || defined(__GNUC__) extern uint32_t __NCACHE_REGION_START[]; extern uint32_t __NCACHE_REGION_SIZE[]; uint32_t nonCacheStart = (uint32_t) __NCACHE_REGION_START; uint32_t size = (uint32_t) __NCACHE_REGION_SIZE; #endif volatile uint32_t i = 0; #if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT /* Disable I cache and D cache */ if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR)) { SCB_DisableICache(); } #endif #if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR)) { SCB_DisableDCache(); } #endif /* Disable MPU */ ARM_MPU_Disable(); /* MPU configure: * Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, * SubRegionDisable, Size) * API in mpu_armv7.h. * param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches * disabled. * param AccessPermission Data access permissions, allows you to configure read/write access for User and * Privileged mode. * Use MACROS defined in mpu_armv7.h: * ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO * Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes. * TypeExtField IsShareable IsCacheable IsBufferable Memory Attribute Shareability Cache * 0 x 0 0 Strongly Ordered shareable * 0 x 0 1 Device shareable * 0 0 1 0 Normal not shareable Outer and inner write * through no write allocate * 0 0 1 1 Normal not shareable Outer and inner write * back no write allocate * 0 1 1 0 Normal shareable Outer and inner write * through no write allocate * 0 1 1 1 Normal shareable Outer and inner write * back no write allocate * 1 0 0 0 Normal not shareable outer and inner * noncache * 1 1 0 0 Normal shareable outer and inner * noncache * 1 0 1 1 Normal not shareable outer and inner write * back write/read acllocate * 1 1 1 1 Normal shareable outer and inner write * back write/read acllocate * 2 x 0 0 Device not shareable * Above are normal use settings, if your want to see more details or want to config different inner/outer cache * policy. * please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide * param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled. * param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in * mpu_armv7.h. */ /* * Add default region to deny access to whole address space to workaround speculative prefetch. * Refer to Arm errata 1013783-B for more details. * */ /* Region 0 setting: Instruction access disabled, No data access permission. */ MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U); MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB); /* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); /* Region 2 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); /* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB); /* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); #if defined(CACHE_MODE_WRITE_THROUGH) && CACHE_MODE_WRITE_THROUGH /* Region 6 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_1MB); /* Region 7 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(7, 0x20300000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_512KB); #else /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_1MB); /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(7, 0x20300000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512KB); #endif #if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) /* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back. */ MPU->RBAR = ARM_MPU_RBAR(8, 0x30000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_16MB); #endif #ifdef USE_SDRAM #if defined(CACHE_MODE_WRITE_THROUGH) && CACHE_MODE_WRITE_THROUGH /* Region 9 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(9, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_64MB); #else /* Region 9 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(9, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64MB); #endif #endif while ((size >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(nonCacheStart % size)); assert(size == (uint32_t) (1 << i)); assert(i >= 5); /* Region 10 setting: Memory with Normal type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(10, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1); } /* Region 11 setting: Memory with Device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(11, 0x40000000); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_16MB); /* Region 12 setting: Memory with Device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(12, 0x41000000); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB); /* Region 13 setting: Memory with Device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(13, 0x41400000); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB); /* Region 14 setting: Memory with Device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(14, 0x41800000); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB); /* Region 15 setting: Memory with Device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(15, 0x42000000); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB); /* Enable MPU */ ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk); /* Enable I cache and D cache */ #if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT SCB_EnableDCache(); #endif #if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT SCB_EnableICache(); #endif } #elif __CORTEX_M == 4 static void BOARD_ConfigMPU(void) { #if defined(__CC_ARM) || defined(__ARMCC_VERSION) extern uint32_t Image$$RW_m_ncache$$Base[]; /* RW_m_ncache_unused is a auxiliary region which is used to get the whole size of noncache section */ extern uint32_t Image$$RW_m_ncache_unused$$Base[]; extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[]; uint32_t nonCacheStart = (uint32_t) Image$$RW_m_ncache$$Base; uint32_t nonCacheSize = ((uint32_t) Image$$RW_m_ncache_unused$$Base == nonCacheStart) ? 0 : ((uint32_t) Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart); #elif defined(__MCUXPRESSO) extern uint32_t __base_NCACHE_REGION; extern uint32_t __top_NCACHE_REGION; uint32_t nonCacheStart = (uint32_t) (&__base_NCACHE_REGION); uint32_t nonCacheSize = (uint32_t) (&__top_NCACHE_REGION) - nonCacheStart; #elif defined(__ICCARM__) || defined(__GNUC__) extern uint32_t __NCACHE_REGION_START[]; extern uint32_t __NCACHE_REGION_SIZE[]; uint32_t nonCacheStart = (uint32_t) __NCACHE_REGION_START; uint32_t nonCacheSize = (uint32_t) __NCACHE_REGION_SIZE; #endif #if defined(__USE_SHMEM) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) extern uint32_t Image$$RPMSG_SH_MEM$$Base[]; /* RPMSG_SH_MEM_unused is a auxiliary region which is used to get the whole size of RPMSG_SH_MEM section */ extern uint32_t Image$$RPMSG_SH_MEM_unused$$Base[]; extern uint32_t Image$$RPMSG_SH_MEM_unused$$ZI$$Limit[]; uint32_t rpmsgShmemStart = (uint32_t) Image$$RPMSG_SH_MEM$$Base; uint32_t rpmsgShmemSize = (uint32_t) Image$$RPMSG_SH_MEM_unused$$ZI$$Limit - rpmsgShmemStart; #elif defined(__MCUXPRESSO) extern uint32_t __base_rpmsg_sh_mem; extern uint32_t __top_rpmsg_sh_mem; uint32_t rpmsgShmemStart = (uint32_t) (&__base_rpmsg_sh_mem); uint32_t rpmsgShmemSize = (uint32_t) (&__top_rpmsg_sh_mem) - rpmsgShmemStart; #elif defined(__ICCARM__) || defined(__GNUC__) extern uint32_t __RPMSG_SH_MEM_START[]; extern uint32_t __RPMSG_SH_MEM_SIZE[]; uint32_t rpmsgShmemStart = (uint32_t) __RPMSG_SH_MEM_START; uint32_t rpmsgShmemSize = (uint32_t) __RPMSG_SH_MEM_SIZE; #endif #endif uint32_t i = 0; /* Only config non-cacheable region on system bus */ assert(nonCacheStart >= 0x20000000); /* Disable code bus cache */ if (LMEM_PCCCR_ENCACHE_MASK == (LMEM_PCCCR_ENCACHE_MASK & LMEM->PCCCR)) { /* Enable the processor code bus to push all modified lines. */ LMEM->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK; /* Wait until the cache command completes. */ while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U) { } /* As a precaution clear the bits to avoid inadvertently re-running this command. */ LMEM->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK); /* Now disable the cache. */ LMEM->PCCCR &= ~LMEM_PCCCR_ENCACHE_MASK; } /* Disable system bus cache */ if (LMEM_PSCCR_ENCACHE_MASK == (LMEM_PSCCR_ENCACHE_MASK & LMEM->PSCCR)) { /* Enable the processor system bus to push all modified lines. */ LMEM->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK; /* Wait until the cache command completes. */ while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U) { } /* As a precaution clear the bits to avoid inadvertently re-running this command. */ LMEM->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK); /* Now disable the cache. */ LMEM->PSCCR &= ~LMEM_PSCCR_ENCACHE_MASK; } /* Disable MPU */ ARM_MPU_Disable(); #if defined(CACHE_MODE_WRITE_THROUGH) && CACHE_MODE_WRITE_THROUGH /* Region 0 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(0, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_1MB); /* Region 1 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(1, 0x20300000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_512KB); /* Region 2 setting: Memory with Normal type, not shareable, write through */ MPU->RBAR = ARM_MPU_RBAR(2, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_64MB); while ((nonCacheSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(nonCacheStart % nonCacheSize)); assert(nonCacheSize == (uint32_t) (1 << i)); assert(i >= 5); /* Region 3 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(3, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #if defined(__USE_SHMEM) i = 0; while ((rpmsgShmemSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(rpmsgShmemStart % rpmsgShmemSize)); assert(rpmsgShmemSize == (uint32_t) (1 << i)); assert(i >= 5); /* Region 4 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(4, rpmsgShmemStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #endif #else while ((nonCacheSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(nonCacheStart % nonCacheSize)); assert(nonCacheSize == (uint32_t) (1 << i)); assert(i >= 5); /* Region 0 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(0, nonCacheStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #if defined(__USE_SHMEM) i = 0; while ((rpmsgShmemSize >> i) > 0x1U) { i++; } if (i != 0) { /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ assert(!(rpmsgShmemStart % rpmsgShmemSize)); assert(rpmsgShmemSize == (uint32_t) (1 << i)); assert(i >= 5); /* Region 1 setting: Memory with device type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(1, rpmsgShmemStart); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, i - 1); } #endif #endif /* Enable MPU */ ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk); /* Enables the processor system bus to invalidate all lines in both ways. and Initiate the processor system bus cache command. */ LMEM->PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK; /* Wait until the cache command completes */ while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U) { } /* As a precaution clear the bits to avoid inadvertently re-running this command. */ LMEM->PSCCR &= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK); /* Now enable the system bus cache. */ LMEM->PSCCR |= LMEM_PSCCR_ENCACHE_MASK; /* Enables the processor code bus to invalidate all lines in both ways. and Initiate the processor code bus code cache command. */ LMEM->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK; /* Wait until the cache command completes. */ while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U) { } /* As a precaution clear the bits to avoid inadvertently re-running this command. */ LMEM->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK); /* Now enable the code bus cache. */ LMEM->PCCCR |= LMEM_PCCCR_ENCACHE_MASK; } #endif #endif ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/board.mk ================================================ MCU_FAMILY = RT1170 MCU_VARIANT = MIMXRT1176 ifeq ($(M4), 1) MCU_CORE = _cm4 JLINK_CORE = _M4 CPU_CORE = cortex-m4 LD_FILE ?= $(MCU_DIR)/gcc/$(MCU_VARIANT)xxxxx${MCU_CORE}_ram.ld else MCU_CORE = _cm7 JLINK_CORE = _M7 endif CFLAGS += -DCPU_MIMXRT1176DVMAA$(MCU_CORE) # For flash-jlink target JLINK_DEVICE = MIMXRT1176xxxA$(JLINK_CORE) # For flash-pyocd target PYOCD_TARGET = mimxrt1170$(MCU_CORE) BOARD_TUD_RHPORT = 0 BOARD_TUH_RHPORT = 1 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.c ================================================ /* * Copyright 2018-2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "evkbmimxrt1170_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"), used)) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .controllerMiscOption = 0x10, .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, .sflashA1Size = 64u * 1024u * 1024u, .lookupTable = { // Read LUTs [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEC, RADDR_SDR, FLEXSPI_4PAD, 0x20), [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), // Read Status LUTs [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04), // Write Enable LUTs [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0), // Erase Sector LUTs [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x21, RADDR_SDR, FLEXSPI_1PAD, 0x20), // Erase Block LUTs [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18), // Pape Program LUTs [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x12, RADDR_SDR, FLEXSPI_1PAD, 0x20), [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), // Erase Chip LUTs [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .ipcmdSerialClkFreq = 0x1, .blockSize = 64u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.h ================================================ /* * Copyright 2018-2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ #define __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.1. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_80MHz = 4, kFlexSpiSerialClk_100MHz = 5, kFlexSpiSerialClk_120MHz = 6, kFlexSpiSerialClk_133MHz = 7, kFlexSpiSerialClk_166MHz = 8, kFlexSpiSerialClk_200MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t isDataOrderSwapped; //!< The data order is swapped in OPI DDR mode uint8_t reserved0; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t FlashStateCtx; //!< Flash State Context after being configured uint32_t reserve2[10]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/mimxrt1170_evkb/mimxrt1170_evkb.mex ================================================ MIMXRT1176xxxxx MIMXRT1176DVMAA MIMXRT1170-EVKB ksdk2_0 Configuration imported from evkbmimxrt1170_dev_cdc_vcom_lite_bm_cm7 true false true false 24.12.10 Configures pin routing and optionally pin electrical features. true cm7 true true true true Configures pin routing and optionally pin electrical features. true cm7 true true true true 24.12.10 true INPUT true OUTPUT true INPUT true OUTPUT true true true true true true true true true true true 13.0.2 c_array true 2.5.1 13.0.2 0 true true N/A ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 600 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 12 MHz} - {id: ENET2_125M_CLK.outFreq, value: 1.2 MHz} - {id: ENET_125M_CLK.outFreq, value: 2.4 MHz} - {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI2_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 150 MHz} - {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: LVDS1_CLK.outFreq, value: 1.2 GHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz} - {id: PLL7_MAIN_CLK.outFreq, value: 480 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USBPHY2_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.FLEXSPI_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.LCDIF_PODF.scale, value: '4', locked: true} - {id: CCM.LCDIF_PRED.scale, value: '2', locked: true} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1} - {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true} - {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL5.denom, value: '1'} - {id: CCM_ANALOG.PLL5.div, value: '31', locked: true} - {id: CCM_ANALOG.PLL5.num, value: '0'} - {id: CCM_ANALOG.PLL5_BYPASS.sel, value: CCM_ANALOG.PLL5_POST_DIV} - {id: CCM_ANALOG.PLL5_POST_DIV.scale, value: '2', locked: true} - {id: CCM_ANALOG.PLL7_BYPASS.sel, value: CCM_ANALOG.PLL7} - {id: CCM_ANALOG.VIDEO_DIV.scale, value: '4', locked: true} - {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_VIDEO_POWERDOWN_CFG, value: 'No'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 31, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .postDivider = 8, /* Divider after PLL */ .numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); CLOCK_DisableClock(kCLOCK_Xbar3); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 1); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 3); #endif /* Disable Flexspi2 clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi2); /* Set FLEXSPI2_PODF. */ CLOCK_SetDiv(kCLOCK_Flexspi2Div, 1); /* Set Flexspi2 clock source. */ CLOCK_SetMux(kCLOCK_Flexspi2Mux, 1); /* Disable CSI clock gate. */ CLOCK_DisableClock(kCLOCK_Csi); /* Set CSI_PODF. */ CLOCK_SetDiv(kCLOCK_CsiDiv, 1); /* Set Csi clock source. */ CLOCK_SetMux(kCLOCK_CsiMux, 0); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can3); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); CLOCK_DisableClock(kCLOCK_Can3S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable LCDIF clock gate. */ CLOCK_DisableClock(kCLOCK_LcdPixel); /* Set LCDIF_PRED. */ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); /* Set LCDIF_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); /* Set Lcdif pre clock source. */ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Disable Flexio2 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio2); /* Set FLEXIO2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); /* Set FLEXIO2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); /* Set Flexio2 clock source. */ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init ARM PLL. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Video PLL. */ uint32_t pllVideo; /* Disable Video PLL output before initial Video PLL. */ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; /* Bypass PLL first */ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(0); CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(0); CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(1); pllVideo = (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK |CCM_ANALOG_PLL_VIDEO_DIV_SELECT(31); pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(3); CCM_ANALOG->PLL_VIDEO = pllVideo; while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) { } /* Disable bypass for Video PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllVideo, 0); /* DeInit Enet PLL. */ CLOCK_DeinitEnetPll(); /* Bypass Enet PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1); /* Set Enet output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1); /* Enable Enet output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; /* Set Enet2 output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(0); /* Enable Enet2 output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET2_REF_EN_MASK; /* Enable Enet25M output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; /* Init Usb2 PLL. */ CLOCK_InitUsb2Pll(&usb2PllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set lvds1 clock source. */ CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; /* Set ENET2 Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET2_TX_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL #define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET2_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL #define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL /*! @brief Arm PLL set for BOARD_BootClockRUN configuration. */ extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Usb2 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Video PLL set for BOARD_BootClockRUN configuration. */ extern const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK pin_labels: - {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: USER_BUTTON} - {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: USER_LED} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: D8, peripheral: GPIO2, signal: 'gpio_io, 03', pin_signal: GPIO_B0_03, direction: OUTPUT} - {pin_num: E7, peripheral: GPIO2, signal: 'gpio_io, 01', pin_signal: GPIO_B0_01, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* GPIO configuration of USER_BUTTON on GPIO_B0_01 (pin E7) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_B0_01 (pin E7) */ GPIO_PinInit(GPIO2, 1U, &USER_BUTTON_config); /* GPIO configuration of USER_LED on GPIO_B0_03 (pin D8) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_B0_03 (pin D8) */ GPIO_PinInit(GPIO2, 3U, &USER_LED_config); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_GPIO2_IO03, 0U); IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0xB0B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x0AU /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ /* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 3U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 3U) /*!< PORT pin mask */ /* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 1U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 1U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 1U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 1U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 1U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_12 (coord K14), UART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_13 (coord L14), UART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_SD_B0_05 (coord J2), SD1_D3 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_04 (coord H2), SD1_D2 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /* GPIO_B1_14 (coord C14), SD0_VSELECT */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board.cmake ================================================ set(MCU_FAMILY RT1060) set(MCU_VARIANT MIMXRT1062) set(JLINK_DEVICE MIMXRT1062xxx6A) set(PYOCD_TARGET mimxrt1060) set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/teensy40_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1062DVL6A BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() # flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli # Make sure it is in your PATH # flash: $(BUILD)/$(PROJECT).hex # teensy_loader_cli --mcu=imxrt1062 -v -w $< ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Teensy 4.0 url: https://www.pjrc.com/store/teensy40.html */ #ifndef BOARD_H_ #define BOARD_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (2 * 1024 * 1024) // LED D13: IOMUXC_GPIO_B0_03_GPIO2_IO03 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // no button D12: IOMUXC_GPIO_B0_01_GPIO2_IO01 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART D0, D1: IOMUXC_GPIO_AD_B0_03_LPUART6_RX, IOMUXC_GPIO_AD_B0_02_LPUART6_TX #define UART_PORT LPUART6 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1062DVL6A MCU_FAMILY = RT1060 MCU_VARIANT = MIMXRT1062 # For flash-jlink target JLINK_DEVICE = MIMXRT1062xxx6A # flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli # Make sure it is in your PATH flash: $(BUILD)/$(PROJECT).hex teensy_loader_cli --mcu=imxrt1062 -v -w $< ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/teensy40.mex ================================================ MIMXRT1062xxxxA MIMXRT1062DVL6A MIMXRT1060-EVK A2 ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 kELCDIF_CurFrameDoneInterruptEnable 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.c ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "teensy40_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 2u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.h ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ #define __TEENSY40_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, kFlexSpiSerialClk_166MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board/clock_config.c ================================================ /* * How to setup clock using clock driver functions: * * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. * * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. * * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. * * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. * * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. * */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" #include "fsl_iomuxc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: AHB_CLK_ROOT.outFreq, value: 600 MHz} - {id: CAN_CLK_ROOT.outFreq, value: 40 MHz} - {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} - {id: CLK_1M.outFreq, value: 1 MHz} - {id: CLK_24M.outFreq, value: 24 MHz} - {id: CSI_CLK_ROOT.outFreq, value: 12 MHz} - {id: ENET2_125M_CLK.outFreq, value: 1.2 MHz} - {id: ENET_125M_CLK.outFreq, value: 2.4 MHz} - {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz} - {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz} - {id: FLEXSPI2_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: FLEXSPI_CLK_ROOT.outFreq, value: 1440/11 MHz} - {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz} - {id: IPG_CLK_ROOT.outFreq, value: 150 MHz} - {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz} - {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} - {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} - {id: LVDS1_CLK.outFreq, value: 1.2 GHz} - {id: MQS_MCLK.outFreq, value: 1080/17 MHz} - {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz} - {id: PLL7_MAIN_CLK.outFreq, value: 480 MHz} - {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} - {id: SAI1_MCLK3.outFreq, value: 30 MHz} - {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI2_MCLK3.outFreq, value: 30 MHz} - {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} - {id: SAI3_MCLK3.outFreq, value: 30 MHz} - {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz} - {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} - {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} - {id: UART_CLK_ROOT.outFreq, value: 80 MHz} - {id: USBPHY1_CLK.outFreq, value: 480 MHz} - {id: USBPHY2_CLK.outFreq, value: 480 MHz} - {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz} - {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz} settings: - {id: CCM.AHB_PODF.scale, value: '1', locked: true} - {id: CCM.ARM_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI2_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.FLEXSPI_PODF.scale, value: '2', locked: true} - {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK} - {id: CCM.LCDIF_PODF.scale, value: '4', locked: true} - {id: CCM.LCDIF_PRED.scale, value: '2', locked: true} - {id: CCM.LPSPI_PODF.scale, value: '5', locked: true} - {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} - {id: CCM.SEMC_PODF.scale, value: '8'} - {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} - {id: CCM.TRACE_PODF.scale, value: '4', locked: true} - {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1} - {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true} - {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true} - {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true} - {id: CCM_ANALOG.PLL2.num, value: '0', locked: true} - {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} - {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} - {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} - {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} - {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} - {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} - {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} - {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true} - {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} - {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} - {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} - {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} - {id: CCM_ANALOG.PLL4.denom, value: '50'} - {id: CCM_ANALOG.PLL4.div, value: '47'} - {id: CCM_ANALOG.PLL5.denom, value: '1'} - {id: CCM_ANALOG.PLL5.div, value: '31', locked: true} - {id: CCM_ANALOG.PLL5.num, value: '0'} - {id: CCM_ANALOG.PLL5_BYPASS.sel, value: CCM_ANALOG.PLL5_POST_DIV} - {id: CCM_ANALOG.PLL5_POST_DIV.scale, value: '2', locked: true} - {id: CCM_ANALOG.PLL7_BYPASS.sel, value: CCM_ANALOG.PLL7} - {id: CCM_ANALOG.VIDEO_DIV.scale, value: '4', locked: true} - {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_EN_USB_CLKS_OUT_CFG, value: Enabled} - {id: CCM_ANALOG_PLL_USB2_POWER_CFG, value: 'Yes'} - {id: CCM_ANALOG_PLL_VIDEO_POWERDOWN_CFG, value: 'No'} sources: - {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = { .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ .numerator = 0, /* 30 bit numerator of fractional loop divider */ .denominator = 1, /* 30 bit denominator of fractional loop divider */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN = { .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = { .loopDivider = 31, /* PLL loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .postDivider = 8, /* Divider after PLL */ .numerator = 0, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .denominator = 1, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Init RTC OSC clock frequency. */ CLOCK_SetRtcXtalFreq(32768U); /* Enable 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; /* Use free 1MHz clock output. */ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; /* Set XTAL 24MHz clock frequency. */ CLOCK_SetXtalFreq(24000000U); /* Enable XTAL 24MHz clock source. */ CLOCK_InitExternalClk(0); /* Enable internal RC. */ CLOCK_InitRcOsc24M(); /* Switch clock source to external OSC. */ CLOCK_SwitchOsc(kCLOCK_XtalOsc); /* Set Oscillator ready counter value. */ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); /* Waiting for DCDC_STS_DC_OK bit is asserted */ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) { } /* Set AHB_PODF. */ CLOCK_SetDiv(kCLOCK_AhbDiv, 0); /* Disable IPG clock gate. */ CLOCK_DisableClock(kCLOCK_Adc1); CLOCK_DisableClock(kCLOCK_Adc2); CLOCK_DisableClock(kCLOCK_Xbar1); CLOCK_DisableClock(kCLOCK_Xbar2); CLOCK_DisableClock(kCLOCK_Xbar3); /* Set IPG_PODF. */ CLOCK_SetDiv(kCLOCK_IpgDiv, 3); /* Set ARM_PODF. */ CLOCK_SetDiv(kCLOCK_ArmDiv, 1); /* Set PERIPH_CLK2_PODF. */ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); /* Disable PERCLK clock gate. */ CLOCK_DisableClock(kCLOCK_Gpt1); CLOCK_DisableClock(kCLOCK_Gpt1S); CLOCK_DisableClock(kCLOCK_Gpt2); CLOCK_DisableClock(kCLOCK_Gpt2S); CLOCK_DisableClock(kCLOCK_Pit); /* Set PERCLK_PODF. */ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); /* Disable USDHC1 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc1); /* Set USDHC1_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); /* Set Usdhc1 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); /* Disable USDHC2 clock gate. */ CLOCK_DisableClock(kCLOCK_Usdhc2); /* Set USDHC2_PODF. */ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); /* Set Usdhc2 clock source. */ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT /* Disable Semc clock gate. */ CLOCK_DisableClock(kCLOCK_Semc); /* Set SEMC_PODF. */ CLOCK_SetDiv(kCLOCK_SemcDiv, 7); /* Set Semc alt clock source. */ CLOCK_SetMux(kCLOCK_SemcAltMux, 0); /* Set Semc clock source. */ CLOCK_SetMux(kCLOCK_SemcMux, 0); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Disable Flexspi clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi); /* Set FLEXSPI_PODF. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); /* Set Flexspi clock source. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 3); #endif /* Disable Flexspi2 clock gate. */ CLOCK_DisableClock(kCLOCK_FlexSpi2); /* Set FLEXSPI2_PODF. */ CLOCK_SetDiv(kCLOCK_Flexspi2Div, 1); /* Set Flexspi2 clock source. */ CLOCK_SetMux(kCLOCK_Flexspi2Mux, 1); /* Disable CSI clock gate. */ CLOCK_DisableClock(kCLOCK_Csi); /* Set CSI_PODF. */ CLOCK_SetDiv(kCLOCK_CsiDiv, 1); /* Set Csi clock source. */ CLOCK_SetMux(kCLOCK_CsiMux, 0); /* Disable LPSPI clock gate. */ CLOCK_DisableClock(kCLOCK_Lpspi1); CLOCK_DisableClock(kCLOCK_Lpspi2); CLOCK_DisableClock(kCLOCK_Lpspi3); CLOCK_DisableClock(kCLOCK_Lpspi4); /* Set LPSPI_PODF. */ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); /* Set Lpspi clock source. */ CLOCK_SetMux(kCLOCK_LpspiMux, 2); /* Disable TRACE clock gate. */ CLOCK_DisableClock(kCLOCK_Trace); /* Set TRACE_PODF. */ CLOCK_SetDiv(kCLOCK_TraceDiv, 3); /* Set Trace clock source. */ CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Disable SAI1 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai1); /* Set SAI1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); /* Set SAI1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai1Div, 1); /* Set Sai1 clock source. */ CLOCK_SetMux(kCLOCK_Sai1Mux, 0); /* Disable SAI2 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai2); /* Set SAI2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3); /* Set SAI2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai2Div, 1); /* Set Sai2 clock source. */ CLOCK_SetMux(kCLOCK_Sai2Mux, 0); /* Disable SAI3 clock gate. */ CLOCK_DisableClock(kCLOCK_Sai3); /* Set SAI3_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); /* Set SAI3_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Sai3Div, 1); /* Set Sai3 clock source. */ CLOCK_SetMux(kCLOCK_Sai3Mux, 0); /* Disable Lpi2c clock gate. */ CLOCK_DisableClock(kCLOCK_Lpi2c1); CLOCK_DisableClock(kCLOCK_Lpi2c2); CLOCK_DisableClock(kCLOCK_Lpi2c3); /* Set LPI2C_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); /* Set Lpi2c clock source. */ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); /* Disable CAN clock gate. */ CLOCK_DisableClock(kCLOCK_Can1); CLOCK_DisableClock(kCLOCK_Can2); CLOCK_DisableClock(kCLOCK_Can3); CLOCK_DisableClock(kCLOCK_Can1S); CLOCK_DisableClock(kCLOCK_Can2S); CLOCK_DisableClock(kCLOCK_Can3S); /* Set CAN_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_CanDiv, 1); /* Set Can clock source. */ CLOCK_SetMux(kCLOCK_CanMux, 2); /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); CLOCK_DisableClock(kCLOCK_Lpuart3); CLOCK_DisableClock(kCLOCK_Lpuart4); CLOCK_DisableClock(kCLOCK_Lpuart5); CLOCK_DisableClock(kCLOCK_Lpuart6); CLOCK_DisableClock(kCLOCK_Lpuart7); CLOCK_DisableClock(kCLOCK_Lpuart8); /* Set UART_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set Uart clock source. */ CLOCK_SetMux(kCLOCK_UartMux, 0); /* Disable LCDIF clock gate. */ CLOCK_DisableClock(kCLOCK_LcdPixel); /* Set LCDIF_PRED. */ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); /* Set LCDIF_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); /* Set Lcdif pre clock source. */ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); /* Disable SPDIF clock gate. */ CLOCK_DisableClock(kCLOCK_Spdif); /* Set SPDIF0_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); /* Set SPDIF0_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); /* Set Spdif clock source. */ CLOCK_SetMux(kCLOCK_SpdifMux, 3); /* Disable Flexio1 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio1); /* Set FLEXIO1_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); /* Set FLEXIO1_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); /* Set Flexio1 clock source. */ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); /* Disable Flexio2 clock gate. */ CLOCK_DisableClock(kCLOCK_Flexio2); /* Set FLEXIO2_CLK_PRED. */ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); /* Set FLEXIO2_CLK_PODF. */ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); /* Set Flexio2 clock source. */ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); /* Set Pll3 sw clock source. */ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); /* Init ARM PLL. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ #ifndef SKIP_SYSCLK_INIT #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." #endif /* Init System PLL. */ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); /* Init System pfd0. */ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); /* Init System pfd1. */ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); /* Init System pfd2. */ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); /* Init System pfd3. */ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); #endif /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ #if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) /* Init Usb1 PLL. */ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); /* Init Usb1 pfd0. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); /* Init Usb1 pfd1. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); /* Init Usb1 pfd2. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); /* Init Usb1 pfd3. */ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); #endif /* DeInit Audio PLL. */ CLOCK_DeinitAudioPll(); /* Bypass Audio PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); /* Set divider for Audio PLL. */ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; /* Enable Audio PLL output. */ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; /* Init Video PLL. */ uint32_t pllVideo; /* Disable Video PLL output before initial Video PLL. */ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; /* Bypass PLL first */ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(0); CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(0); CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(1); pllVideo = (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK |CCM_ANALOG_PLL_VIDEO_DIV_SELECT(31); pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(3); CCM_ANALOG->PLL_VIDEO = pllVideo; while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) { } /* Disable bypass for Video PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllVideo, 0); /* DeInit Enet PLL. */ CLOCK_DeinitEnetPll(); /* Bypass Enet PLL. */ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1); /* Set Enet output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1); /* Enable Enet output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; /* Set Enet2 output divider. */ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(0); /* Enable Enet2 output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET2_REF_EN_MASK; /* Enable Enet25M output. */ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; /* Init Usb2 PLL. */ CLOCK_InitUsb2Pll(&usb2PllConfig_BOARD_BootClockRUN); /* Set preperiph clock source. */ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); /* Set periph clock source. */ CLOCK_SetMux(kCLOCK_PeriphMux, 0); /* Set periph clock2 clock source. */ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); /* Set per clock source. */ CLOCK_SetMux(kCLOCK_PerclkMux, 0); /* Set lvds1 clock source. */ CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); /* Set clock out1 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); /* Set clock out1 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); /* Set clock out2 divider. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); /* Set clock out2 source. */ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); /* Set clock out1 drives clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; /* Disable clock out1. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; /* Disable clock out2. */ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; /* Set SAI1 MCLK1 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); /* Set SAI1 MCLK2 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); /* Set SAI1 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); /* Set SAI2 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; /* Set ENET2 Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET2_TX_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board/clock_config.h ================================================ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL #define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL #define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL #define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL #define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL #define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL #define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL #define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET2_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL #define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL #define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL #define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL #define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL #define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL #define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL #define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL #define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL #define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL #define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL #define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL #define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL #define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL #define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL #define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL #define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL #define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL #define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL #define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 480000000UL #define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL #define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL /*! @brief Arm PLL set for BOARD_BootClockRUN configuration. */ extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; /*! @brief Usb2 PLL set for BOARD_BootClockRUN configuration. */ extern const clock_usb_pll_config_t usb2PllConfig_BOARD_BootClockRUN; /*! @brief Sys PLL for BOARD_BootClockRUN configuration. */ extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; /*! @brief Video PLL set for BOARD_BootClockRUN configuration. */ extern const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MIMXRT1062xxxxA package_id: MIMXRT1062DVL6A mcu_data: ksdk2_0 processor_version: 13.0.2 board: MIMXRT1060-EVK pin_labels: - {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: USER_BUTTON} - {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: USER_LED} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ #include "fsl_common.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: D8, peripheral: GPIO2, signal: 'gpio_io, 03', pin_signal: GPIO_B0_03, direction: OUTPUT} - {pin_num: E7, peripheral: GPIO2, signal: 'gpio_io, 01', pin_signal: GPIO_B0_01, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* GPIO configuration of USER_BUTTON on GPIO_B0_01 (pin E7) */ gpio_pin_config_t USER_BUTTON_config = { .direction = kGPIO_DigitalInput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_B0_01 (pin E7) */ GPIO_PinInit(GPIO2, 1U, &USER_BUTTON_config); /* GPIO configuration of USER_LED on GPIO_B0_03 (pin D8) */ gpio_pin_config_t USER_LED_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 0U, .interruptMode = kGPIO_NoIntmode }; /* Initialize GPIO functionality on GPIO_B0_03 (pin D8) */ GPIO_PinInit(GPIO2, 3U, &USER_LED_config); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_GPIO2_IO03, 0U); IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & (~(BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) ); IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0xB0B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSDHCPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSDHCPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSDHCPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); } /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitQSPIPins: - options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitQSPIPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitQSPIPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x0AU /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ /* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ /* Routed pin properties */ #define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_LED_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_LED_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_LED_PIN 3U /*!< PORT pin number */ #define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 3U) /*!< PORT pin mask */ /* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ /* Routed pin properties */ #define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ #define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ #define BOARD_INITPINS_USER_BUTTON_CHANNEL 1U /*!< Signal channel */ /* Symbols to be used with GPIO driver */ #define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 1U /*!< GPIO pin number */ #define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 1U) /*!< GPIO pin mask */ #define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ #define BOARD_INITPINS_USER_BUTTON_PIN 1U /*!< PORT pin number */ #define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 1U) /*!< PORT pin mask */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /* GPIO_AD_B0_12 (coord K14), UART1_TXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ /* GPIO_AD_B0_13 (coord L14), UART1_RXD */ /* Routed pin properties */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ #define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* GPIO_SD_B0_05 (coord J2), SD1_D3 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ /* GPIO_SD_B0_04 (coord H2), SD1_D2 */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ /* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ /* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ #define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ /* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ /* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ /* GPIO_B1_14 (coord C14), SD0_VSELECT */ /* Routed pin properties */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ #define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSDHCPins(void); /* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ /* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ /* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ /* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ /* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ /* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ /* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ /* Routed pin properties */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ #define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitQSPIPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board.cmake ================================================ set(MCU_FAMILY RT1060) set(MCU_VARIANT MIMXRT1062) set(JLINK_DEVICE MIMXRT1062xxx6A) set(PYOCD_TARGET mimxrt1060) set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/teensy41_flexspi_nor_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MIMXRT1062DVL6A BOARD_TUD_RHPORT=0 BOARD_TUH_RHPORT=1 ) endfunction() # flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli # Make sure it is in your PATH # flash: $(BUILD)/$(PROJECT).hex # teensy_loader_cli --mcu=imxrt1062 -v -w $< ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Teensy 4.1 url: https://www.pjrc.com/store/teensy41.html */ #ifndef BOARD_H_ #define BOARD_H_ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (8 * 1024 * 1024) // LED D13: IOMUXC_GPIO_B0_03_GPIO2_IO03 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // no button D12: IOMUXC_GPIO_B0_01_GPIO2_IO01 #define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL #define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 // UART D0, D1: IOMUXC_GPIO_AD_B0_03_LPUART6_RX, IOMUXC_GPIO_AD_B0_02_LPUART6_TX #define UART_PORT LPUART6 #define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT static inline void BOARD_ConfigMPU(void) { } #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/board.mk ================================================ CFLAGS += -DCPU_MIMXRT1062DVL6A MCU_FAMILY = RT1060 MCU_VARIANT = MIMXRT1062 # For flash-jlink target JLINK_DEVICE = MIMXRT1062xxx6A # flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli # Make sure it is in your PATH flash: $(BUILD)/$(PROJECT).hex teensy_loader_cli --mcu=imxrt1062 -v -w $< ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/teensy41.mex ================================================ MIMXRT1062xxxxA MIMXRT1062DVL6A MIMXRT1060-EVK A2 ksdk2_0 false false false true false 13.0.2 Configures pin routing and optionally pin electrical features. true core0 true true true true true Configures pin routing and optionally pin electrical features. true core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true Configures pin routing and optionally pin electrical features. false core0 true true true true 13.0.2 true INPUT true OUTPUT true INPUT true OUTPUT true true true 0.0.0 13.0.2 kELCDIF_CurFrameDoneInterruptEnable 0.0.0 ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.c ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "teensy41_flexspi_nor_config.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.xip_board" #endif /******************************************************************************* * Code ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) __attribute__((section(".boot_hdr.conf"))) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz, .sflashA1Size = 8u * 1024u * 1024u, .lookupTable = { // Read LUTs FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 256u * 1024u, .isUniformBlockSize = false, }; #endif /* XIP_BOOT_HEADER_ENABLE */ ================================================ FILE: hw/bsp/imxrt/boards/teensy_41/teensy41_flexspi_nor_config.h ================================================ /* * Copyright 2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ #define __TEENSY40_FLEXSPI_NOR_CONFIG__ #include #include #include "fsl_common.h" /*! @name Driver version */ /*@{*/ /*! @brief XIP_BOARD driver version 2.0.0. */ #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*@}*/ /* FLEXSPI memory config block related definitions */ #define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 #define FLEXSPI_CFG_BLK_SIZE (512) /* FLEXSPI Feature related definitions */ #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 /* Lookup table related definitions */ #define CMD_INDEX_READ 0 #define CMD_INDEX_READSTATUS 1 #define CMD_INDEX_WRITEENABLE 2 #define CMD_INDEX_WRITE 4 #define CMD_LUT_SEQ_IDX_READ 0 #define CMD_LUT_SEQ_IDX_READSTATUS 1 #define CMD_LUT_SEQ_IDX_WRITEENABLE 3 #define CMD_LUT_SEQ_IDX_WRITE 9 #define CMD_SDR 0x01 #define CMD_DDR 0x21 #define RADDR_SDR 0x02 #define RADDR_DDR 0x22 #define CADDR_SDR 0x03 #define CADDR_DDR 0x23 #define MODE1_SDR 0x04 #define MODE1_DDR 0x24 #define MODE2_SDR 0x05 #define MODE2_DDR 0x25 #define MODE4_SDR 0x06 #define MODE4_DDR 0x26 #define MODE8_SDR 0x07 #define MODE8_DDR 0x27 #define WRITE_SDR 0x08 #define WRITE_DDR 0x28 #define READ_SDR 0x09 #define READ_DDR 0x29 #define LEARN_SDR 0x0A #define LEARN_DDR 0x2A #define DATSZ_SDR 0x0B #define DATSZ_DDR 0x2B #define DUMMY_SDR 0x0C #define DUMMY_DDR 0x2C #define DUMMY_RWDS_SDR 0x0D #define DUMMY_RWDS_DDR 0x2D #define JMP_ON_CS 0x1F #define STOP 0 #define FLEXSPI_1PAD 0 #define FLEXSPI_2PAD 1 #define FLEXSPI_4PAD 2 #define FLEXSPI_8PAD 3 #define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_75MHz = 4, kFlexSpiSerialClk_80MHz = 5, kFlexSpiSerialClk_100MHz = 6, kFlexSpiSerialClk_120MHz = 7, kFlexSpiSerialClk_133MHz = 8, kFlexSpiSerialClk_166MHz = 9, } flexspi_serial_clk_freq_t; //!@brief FlexSPI clock configuration type enum { kFlexSpiClk_SDR, //!< Clock configure for SDR mode kFlexSpiClk_DDR, //!< Clock configurat for DDR mode }; //!@brief FlexSPI Read Sample Clock Source definition typedef enum _FlashReadSampleClkSource { kFlexSPIReadSampleClk_LoopbackInternally = 0, kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, } flexspi_read_sample_clk_t; //!@brief Misc feature bit definitions enum { kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. }; //!@brief Flash Type Definition enum { kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs }; //!@brief Flash Pad Definitions enum { kSerialFlash_1Pad = 1, kSerialFlash_2Pads = 2, kSerialFlash_4Pads = 4, kSerialFlash_8Pads = 8, }; //!@brief FlexSPI LUT Sequence structure typedef struct _lut_sequence { uint8_t seqNum; //!< Sequence Number, valid number: 1-16 uint8_t seqId; //!< Sequence Index, valid number: 0-15 uint16_t reserved; } flexspi_lut_seq_t; //!@brief Flash Configuration Command Type enum { kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode kDeviceConfigCmdType_Reset, //!< Reset device command }; //!@brief FlexSPI Memory Configuration Block typedef struct _FlexSPIConfig { uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For //! Serial NAND, need to refer to datasheet uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, //! Generic configuration, etc. uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for //! DPI/QPI/OPI switch or reset command flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt //! sequence number, [31:16] Reserved uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe flexspi_lut_seq_t configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more //! details uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot //! Chapter for more details uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - //! busy flag is 0 when flash device is busy uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use } flexspi_mem_config_t; /* */ #define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 #define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 #define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 #define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 #define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 #define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 #define NOR_CMD_INDEX_DUMMY 6 //!< 6 #define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 #define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk /* * Serial NOR configuration block */ typedef struct _flexspi_nor_config { flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI uint32_t pageSize; //!< Page size of Serial NOR uint32_t sectorSize; //!< Sector size of Serial NOR uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command uint8_t isUniformBlockSize; //!< Sector/Block size is the same uint8_t reserved0[2]; //!< Reserved for future use uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution uint32_t blockSize; //!< Block size uint32_t reserve2[11]; //!< Reserved for future use } flexspi_nor_config_t; #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ ================================================ FILE: hw/bsp/imxrt/debug.jlinkscript ================================================ int SetupTarget(void) { JLINK_ExecCommand("SetRTTSearchRanges 0x20000000 0x40000"); return 0; } ================================================ FILE: hw/bsp/imxrt/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "board/clock_config.h" #include "board/pin_mux.h" #include "board.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "fsl_clock.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_iomuxc.h" #include "fsl_lpuart.h" #include "fsl_ocotp.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif /* --- Note about USB buffer RAM --- For M7 core it's recommended to put USB buffer in DTCM for better performance (flexspi_nor linker default) Otherwise you have to put the buffer in a non-cacheable section by configurate MPU manually or using BOARD_ConfigMPU(): - Define CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable"))) - (IAR only) Change __NCACHE_REGION_SIZE in linker script to cover the size of non-cacheable section, multiple of 2^N For secondary M4 core, the USB controller doesn't support transfer from DTCM so OCRAM must be used: - __NCACHE_REGION_SIZE is defined by the linker script by default - Define CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable"))) */ // needed by fsl_flexspi_nor_boot TU_ATTR_USED const uint8_t dcd_data[] = {0x00}; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // unify naming convention #if !defined(USBPHY1) && defined(USBPHY) #define USBPHY1 USBPHY #endif static void init_usb_phy(uint8_t usb_id) { USBPHY_Type *usb_phy; if (usb_id == 0) { usb_phy = USBPHY1; CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, BOARD_XTAL0_CLK_HZ); CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, BOARD_XTAL0_CLK_HZ); } #ifdef USBPHY2 else if (usb_id == 1) { usb_phy = USBPHY2; CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, BOARD_XTAL0_CLK_HZ); CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, BOARD_XTAL0_CLK_HZ); } #endif else { return; } // Enable PHY support for Low speed device + LS via FS Hub usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; // Enable all power for normal operation // TODO may not be needed since it is called within CLOCK_EnableUsbhs0PhyPllClock() usb_phy->PWD = 0; // TX Timing uint32_t phytx = usb_phy->TX; phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); usb_phy->TX = phytx; } void board_init(void) { // make sure the dcache is on. #if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT if (SCB_CCR_DC_Msk != (SCB_CCR_DC_Msk & SCB->CCR)) { SCB_EnableDCache(); } #endif BOARD_InitBootPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); BOARD_ConfigMPU(); // defined in board.h #ifdef TRACE_ETM //CLOCK_EnableClock(kCLOCK_Trace); #endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #ifdef USBPHY2 NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #endif board_led_write(true); // UART lpuart_config_t uart_config; LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; if (kStatus_Success != LPUART_Init(UART_PORT, &uart_config, UART_CLK_ROOT)) { // failed to init uart, probably baudrate is not supported // TU_BREAKPOINT(); } //------------- USB -------------// // Note: RT105x RT106x and later have dual USB controllers. init_usb_phy(0);// USB0 #ifdef USBPHY2 init_usb_phy(1);// USB1 #endif } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB_OTG1_IRQHandler(void) { tusb_int_handler(0, true); } void USB_OTG2_IRQHandler(void) { tusb_int_handler(1, true); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; #if FSL_FEATURE_OCOTP_HAS_TIMING_CTRL OCOTP_Init(OCOTP, CLOCK_GetFreq(kCLOCK_IpgClk)); #else OCOTP_Init(OCOTP, 0u); #endif // Reads shadow registers 0x01 - 0x04 (Configuration and Manufacturing Info) // into 8 bit wide destination, avoiding punning. for (int i = 0; i < 4; ++i) { uint32_t wr = OCOTP_ReadFuseShadowRegister(OCOTP, i + 1); for (int j = 0; j < 4; j++) { id[i * 4 + j] = wr & 0xff; wr >>= 8; } } OCOTP_Deinit(OCOTP); return 16; } int board_uart_read(uint8_t *buf, int len) { int count = 0; while (count < len) { uint8_t const rx_count = LPUART_GetRxFifoCount(UART_PORT); if (!rx_count) { // clear all error flag if any uint32_t status_flags = LPUART_GetStatusFlags(UART_PORT); status_flags &= (kLPUART_RxOverrunFlag | kLPUART_ParityErrorFlag | kLPUART_FramingErrorFlag | kLPUART_NoiseErrorFlag); LPUART_ClearStatusFlags(UART_PORT, status_flags); break; } for (int i = 0; i < rx_count; i++) { buf[count] = LPUART_ReadByte(UART_PORT); count++; } } return count; } int board_uart_write(void const *buf, int len) { LPUART_WriteBlocking(UART_PORT, (uint8_t const *) buf, len); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifdef __clang__ void _exit(int __status) { (void) __status; while (1) {} } #endif ================================================ FILE: hw/bsp/imxrt/family.cmake ================================================ include_guard() set(MCUX_CORE ${TOP}/hw/mcu/nxp/mcuxsdk-core) set(MCUX_DEVICES ${TOP}/hw/mcu/nxp/mcux-devices-rt) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(MCU_VARIANT_WITH_CORE ${MCU_VARIANT}${MCU_CORE}) # toolchain set up if (NOT DEFINED CMAKE_SYSTEM_CPU) set(CMAKE_SYSTEM_CPU cortex-m7 CACHE INTERNAL "System Processor") endif () set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS MIMXRT1XXX CACHE INTERNAL "") # XIP boot files: some devices reference RT1052's xip (see each device's xip/CMakeLists.txt) if (MCU_FAMILY STREQUAL "RT1064") set(XIP_DIR ${MCUX_DEVICES}/RT1064/MIMXRT1064/xip) elseif (MCU_FAMILY STREQUAL "RT1170") set(XIP_DIR ${MCUX_DEVICES}/RT1170/MIMXRT1176/xip) else() # RT1010, RT1015, RT1020, RT1050, RT1060 all use RT1052's xip set(XIP_DIR ${MCUX_DEVICES}/RT1050/MIMXRT1052/xip) endif() #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx${MCU_CORE}_flexspi_nor.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/iar/${MCU_VARIANT}xxxxx${MCU_CORE}_flexspi_nor.icf) endif () set(STARTUP_FILE_GNU ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT_WITH_CORE}.S) set(STARTUP_FILE_IAR ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/iar/startup_${MCU_VARIANT_WITH_CORE}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/pin_mux.c # mcuxsdk-core drivers ${MCUX_CORE}/drivers/common/fsl_common.c ${MCUX_CORE}/drivers/common/fsl_common_arm.c ${MCUX_CORE}/drivers/igpio/fsl_gpio.c ${MCUX_CORE}/drivers/lpspi/fsl_lpspi.c ${MCUX_CORE}/drivers/lpuart/fsl_lpuart.c ${MCUX_CORE}/drivers/ocotp/fsl_ocotp.c # device specific ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/system_${MCU_VARIANT_WITH_CORE}.c ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/fsl_clock.c ) # Additional drivers in subdirectories (RT1170 power/anatop_ai) if (MCU_FAMILY STREQUAL "RT1170") target_sources(${BOARD_TARGET} PRIVATE ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/power/fsl_dcdc.c ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/power/fsl_pmu.c ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/anatop_ai/fsl_anatop_ai.c ) endif() if (NOT M4 STREQUAL "1") target_compile_definitions(${BOARD_TARGET} PUBLIC XIP_EXTERNAL_FLASH=1 XIP_BOOT_HEADER_ENABLE=1 ) endif () target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board ${CMSIS_DIR}/CMSIS/Core/Include # device specific ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT} ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers ${MCUX_DEVICES}/${MCU_FAMILY}/periph # mcuxsdk-core drivers ${MCUX_CORE}/drivers/common ${MCUX_CORE}/drivers/igpio ${MCUX_CORE}/drivers/lpspi ${MCUX_CORE}/drivers/lpuart ${MCUX_CORE}/drivers/ocotp ) # Include power/anatop_ai driver directories if they exist foreach(SUBDIR power anatop_ai) if(EXISTS ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/${SUBDIR}) target_include_directories(${BOARD_TARGET} PUBLIC ${MCUX_DEVICES}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/${SUBDIR} ) endif() endforeach() update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_MIMXRT1XXX) target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c ${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c ${TOP}/src/portable/ehci/ehci.c ${XIP_DIR}/fsl_flexspi_nor_boot.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${XIP_DIR} ) target_compile_definitions(${TARGET} PUBLIC __START=main # required with -nostartfiles __STARTUP_CLEAR_BSS [=[CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable")))]=] ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PRIVATE "LINKER:--script=${LD_FILE_GNU}") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PRIVATE "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) #family_flash_pyocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/imxrt/family.mk ================================================ UF2_FAMILY_ID = 0x4fb2d5bd MCUX_CORE = hw/mcu/nxp/mcuxsdk-core MCUX_DEVICES = hw/mcu/nxp/mcux-devices-rt include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m7 MCU_VARIANT_WITH_CORE = ${MCU_VARIANT}${MCU_CORE} MCU_DIR = $(MCUX_DEVICES)/$(MCU_FAMILY)/$(MCU_VARIANT) # XIP boot files: some devices reference RT1052's xip (see each device's xip/CMakeLists.txt) ifeq ($(MCU_FAMILY),RT1064) XIP_DIR = $(MCUX_DEVICES)/RT1064/MIMXRT1064/xip else ifeq ($(MCU_FAMILY),RT1170) XIP_DIR = $(MCUX_DEVICES)/RT1170/MIMXRT1176/xip else # RT1010, RT1015, RT1020, RT1050, RT1060 all use RT1052's xip XIP_DIR = $(MCUX_DEVICES)/RT1050/MIMXRT1052/xip endif CFLAGS += \ -D__START=main \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT1XXX \ -DCFG_TUSB_MEM_SECTION='__attribute__((section("NonCacheable")))' \ ifneq ($(M4), 1) CFLAGS += \ -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 endif ifdef BOARD_TUD_RHPORT CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT) endif ifdef BOARD_TUH_RHPORT CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT) endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough -Wno-error=redundant-decls LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. LD_FILE ?= $(MCU_DIR)/gcc/$(MCU_VARIANT)xxxxx${MCU_CORE}_flexspi_nor.ld # TODO for net_lwip_webserver example, but may not needed !! LDFLAGS += \ -Wl,--defsym,__stack_size__=0x800 \ SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ src/portable/chipidea/ci_hs/hcd_ci_hs.c \ src/portable/ehci/ehci.c \ ${BOARD_PATH}/board/clock_config.c \ ${BOARD_PATH}/board/pin_mux.c \ $(MCU_DIR)/system_$(MCU_VARIANT_WITH_CORE).c \ $(XIP_DIR)/fsl_flexspi_nor_boot.c \ $(MCU_DIR)/drivers/fsl_clock.c \ $(MCUX_CORE)/drivers/common/fsl_common.c \ $(MCUX_CORE)/drivers/common/fsl_common_arm.c \ $(MCUX_CORE)/drivers/igpio/fsl_gpio.c \ $(MCUX_CORE)/drivers/lpuart/fsl_lpuart.c \ $(MCUX_CORE)/drivers/ocotp/fsl_ocotp.c \ # Optional drivers: RT1170 power/anatop_ai subdirectories ifneq (,$(wildcard ${TOP}/${MCU_DIR}/drivers/power/fsl_dcdc.c)) SRC_C += \ ${MCU_DIR}/drivers/power/fsl_dcdc.c \ ${MCU_DIR}/drivers/power/fsl_pmu.c \ ${MCU_DIR}/drivers/anatop_ai/fsl_anatop_ai.c INC += \ $(TOP)/$(MCU_DIR)/drivers/power \ $(TOP)/$(MCU_DIR)/drivers/anatop_ai endif INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(MCUX_DEVICES)/$(MCU_FAMILY)/periph \ $(TOP)/$(MCUX_CORE)/drivers/common \ $(TOP)/$(MCUX_CORE)/drivers/igpio \ $(TOP)/$(MCUX_CORE)/drivers/lpuart \ $(TOP)/$(MCUX_CORE)/drivers/ocotp \ $(TOP)/$(XIP_DIR) \ SRC_S += $(MCU_DIR)/gcc/startup_$(MCU_VARIANT_WITH_CORE).S # UF2 generation, iMXRT need to strip to text only before conversion APPLICATION_ADDR = 0x6000C000 $(BUILD)/$(PROJECT).uf2: $(BUILD)/$(PROJECT).elf @echo CREATE $@ @$(OBJCOPY) -O binary -R .flash_config -R .ivt $^ $(BUILD)/$(PROJECT)-textonly.bin $(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -b $(APPLICATION_ADDR) -c -o $@ $(BUILD)/$(PROJECT)-textonly.bin ================================================ FILE: hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); } /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN outputs: - {id: Bus_clock.outFreq, value: 60 MHz} - {id: CLKOUT.outFreq, value: 40 MHz} - {id: Core_clock.outFreq, value: 120 MHz, locked: true, accuracy: '0.001'} - {id: ENET1588TSCLK.outFreq, value: 50 MHz} - {id: Flash_clock.outFreq, value: 24 MHz} - {id: FlexBus_clock.outFreq, value: 40 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGFFCLK.outFreq, value: 1.5625 MHz} - {id: MCGIRCLK.outFreq, value: 2 MHz} - {id: OSCERCLK.outFreq, value: 50 MHz} - {id: PLLFLLCLK.outFreq, value: 120 MHz} - {id: RMIICLK.outFreq, value: 50 MHz} - {id: SDHCCLK.outFreq, value: 50 MHz} - {id: System_clock.outFreq, value: 120 MHz} - {id: TRACECLKIN.outFreq, value: 120 MHz} - {id: USB48MCLK.outFreq, value: 48 MHz} settings: - {id: MCGMode, value: PEE} - {id: CLKOUTConfig, value: 'yes'} - {id: ENETTimeSrcConfig, value: 'yes'} - {id: MCG.FRDIV.scale, value: '32'} - {id: MCG.IRCS.sel, value: MCG.FCRDIV} - {id: MCG.IREFS.sel, value: MCG.FRDIV} - {id: MCG.PLLS.sel, value: MCG.PLL} - {id: MCG.PRDIV.scale, value: '15'} - {id: MCG.VDIV.scale, value: '36'} - {id: MCG_C1_IRCLKEN_CFG, value: Enabled} - {id: MCG_C2_RANGE0_CFG, value: Very_high} - {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} - {id: OSC_CR_ERCLKEN_CFG, value: Enabled} - {id: RMIISrcConfig, value: 'yes'} - {id: RTCCLKOUTConfig, value: 'yes'} - {id: RTC_CR_OSCE_CFG, value: Enabled} - {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} - {id: SDHCClkConfig, value: 'yes'} - {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} - {id: SIM.OUTDIV2.scale, value: '2'} - {id: SIM.OUTDIV3.scale, value: '3'} - {id: SIM.OUTDIV4.scale, value: '5'} - {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} - {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} - {id: SIM.SDHCSRCSEL.sel, value: OSC.OSCERCLK} - {id: SIM.TIMESRCSEL.sel, value: OSC.OSCERCLK} - {id: SIM.USBDIV.scale, value: '5'} - {id: SIM.USBFRAC.scale, value: '2'} - {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} - {id: TraceClkConfig, value: 'yes'} - {id: USBClkConfig, value: 'yes'} sources: - {id: OSC.OSC.outFreq, value: 50 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const mcg_config_t mcgConfig_BOARD_BootClockRUN = { .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ .drs = kMCG_DrsLow, /* Low frequency range */ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ .pll0Config = { .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ .prdiv = 0xeU, /* PLL Reference divider: divided by 15 */ .vdiv = 0xcU, /* VCO divider: multiplied by 36 */ }, }; const sim_clock_config_t simConfig_BOARD_BootClockRUN = { .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ }; const osc_config_t oscConfig_BOARD_BootClockRUN = { .freq = 50000000U, /* Oscillator frequency: 50000000Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeExt, /* Use external clock */ .oscerConfig = { .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ } }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Initializes OSC0 according to board configuration. */ CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); /* Configure the Internal Reference clock (MCGIRCLK). */ CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, mcgConfig_BOARD_BootClockRUN.ircs, mcgConfig_BOARD_BootClockRUN.fcrdiv); /* Configure FLL external reference divider (FRDIV). */ CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); /* Set MCG to PEE mode. */ CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, kMCG_PllClkSelPll0, &mcgConfig_BOARD_BootClockRUN.pll0Config); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; /* Enable USB FS clock. */ CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); /* Set enet timestamp clock source. */ CLOCK_SetEnetTime0Clock(SIM_ENET_1588T_CLK_SEL_OSCERCLK_CLK); /* Set RMII clock source. */ CLOCK_SetRmii0Clock(SIM_ENET_RMII_CLK_SEL_EXTAL_CLK); /* Set SDHC clock source. */ CLOCK_SetSdhc0Clock(SIM_SDHC_CLK_SEL_OSCERCLK_CLK); /* Set CLKOUT source. */ CLOCK_SetClkOutClock(SIM_CLKOUT_SEL_FLEXBUS_CLK); /* Set debug trace clock source. */ CLOCK_SetTraceClock(SIM_TRACE_CLK_SEL_CORE_SYSTEM_CLK); } /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockVLPR outputs: - {id: Bus_clock.outFreq, value: 4 MHz} - {id: Core_clock.outFreq, value: 4 MHz, locked: true, accuracy: '0.001'} - {id: Flash_clock.outFreq, value: 800 kHz} - {id: FlexBus_clock.outFreq, value: 4 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: System_clock.outFreq, value: 4 MHz} settings: - {id: MCGMode, value: BLPI} - {id: powerMode, value: VLPR} - {id: MCG.CLKS.sel, value: MCG.IRCS} - {id: MCG.FCRDIV.scale, value: '1'} - {id: MCG.FRDIV.scale, value: '32'} - {id: MCG.IRCS.sel, value: MCG.FCRDIV} - {id: MCG_C2_RANGE0_CFG, value: Very_high} - {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} - {id: RTC_CR_OSCE_CFG, value: Enabled} - {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} - {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} - {id: SIM.OUTDIV3.scale, value: '1'} - {id: SIM.OUTDIV4.scale, value: '5'} - {id: SIM.PLLFLLSEL.sel, value: IRC48M.IRC48MCLK} - {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} sources: - {id: OSC.OSC.outFreq, value: 50 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockVLPR configuration ******************************************************************************/ const mcg_config_t mcgConfig_BOARD_BootClockVLPR = { .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */ .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ .drs = kMCG_DrsLow, /* Low frequency range */ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ .pll0Config = { .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ .vdiv = 0x0U, /* VCO divider: multiplied by 24 */ }, }; const sim_clock_config_t simConfig_BOARD_BootClockVLPR = { .pllFllSel = SIM_PLLFLLSEL_IRC48MCLK_CLK, /* PLLFLL select: IRC48MCLK clock */ .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /5 */ }; const osc_config_t oscConfig_BOARD_BootClockVLPR = { .freq = 0U, /* Oscillator frequency: 0Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeExt, /* Use external clock */ .oscerConfig = { .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ } }; /******************************************************************************* * Code for BOARD_BootClockVLPR configuration ******************************************************************************/ void BOARD_BootClockVLPR(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Set MCG to BLPI mode. */ CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv, mcgConfig_BOARD_BootClockVLPR.ircs, mcgConfig_BOARD_BootClockVLPR.irclkEnableMode); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); /* Set VLPR power mode. */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) SMC_SetPowerModeVlpr(SMC, false); #else SMC_SetPowerModeVlpr(SMC); #endif while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) { } /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; } ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 50000000U /*!< Board xtal0 frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ /*! @brief MCG set for BOARD_BootClockRUN configuration. */ extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; /*! @brief SIM module set for BOARD_BootClockRUN configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; /*! @brief OSC set for BOARD_BootClockRUN configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockVLPR configuration ******************************************************************************/ #define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ /*! @brief MCG set for BOARD_BootClockVLPR configuration. */ extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; /*! @brief SIM module set for BOARD_BootClockVLPR configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; /*! @brief OSC set for BOARD_BootClockVLPR configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockVLPR; /******************************************************************************* * API for BOARD_BootClockVLPR configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockVLPR(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v14.0 processor: MK64FN1M0xxx12 package_id: MK64FN1M0VLL12 mcu_data: ksdk2_0 processor_version: 14.0.0 board: FRDM-K64F * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitButtons(); BOARD_InitLEDs(); BOARD_InitDEBUG_UART(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitButtons: - options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: SW2, direction: INPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '38', peripheral: GPIOA, signal: 'GPIO, 4', pin_signal: PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b, direction: INPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitButtons * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitButtons(void) { /* Port A Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortA); /* Port C Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortC); gpio_pin_config_t SW3_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PTA4 (pin 38) */ GPIO_PinInit(BOARD_SW3_GPIO, BOARD_SW3_PIN, &SW3_config); gpio_pin_config_t SW2_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PTC6 (pin 78) */ GPIO_PinInit(BOARD_SW2_GPIO, BOARD_SW2_PIN, &SW2_config); const port_pin_config_t SW3 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTA4 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA4 (pin 38) is configured as PTA4 */ PORT_SetPinConfig(BOARD_SW3_PORT, BOARD_SW3_PIN, &SW3); const port_pin_config_t SW2 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTC6 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTC6 (pin 78) is configured as PTC6 */ PORT_SetPinConfig(BOARD_SW2_PORT, BOARD_SW2_PIN, &SW2); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDs: - options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '67', peripheral: GPIOB, signal: 'GPIO, 21', pin_signal: PTB21/SPI2_SCK/FB_AD30/CMP1_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '68', peripheral: GPIOB, signal: 'GPIO, 22', pin_signal: PTB22/SPI2_SOUT/FB_AD29/CMP2_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '33', peripheral: GPIOE, signal: 'GPIO, 26', pin_signal: PTE26/ENET_1588_CLKIN/UART4_CTS_b/RTC_CLKOUT/USB_CLKIN, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDs * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitLEDs(void) { /* Port B Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortB); /* Port E Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortE); gpio_pin_config_t LED_BLUE_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PTB21 (pin 67) */ GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_PIN, &LED_BLUE_config); gpio_pin_config_t LED_RED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PTB22 (pin 68) */ GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_PIN, &LED_RED_config); gpio_pin_config_t LED_GREEN_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PTE26 (pin 33) */ GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_PIN, &LED_GREEN_config); const port_pin_config_t LED_BLUE = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Slow slew rate is configured */ kPORT_SlowSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTB21 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB21 (pin 67) is configured as PTB21 */ PORT_SetPinConfig(BOARD_LED_BLUE_PORT, BOARD_LED_BLUE_PIN, &LED_BLUE); const port_pin_config_t LED_RED = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Slow slew rate is configured */ kPORT_SlowSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTB22 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB22 (pin 68) is configured as PTB22 */ PORT_SetPinConfig(BOARD_LED_RED_PORT, BOARD_LED_RED_PIN, &LED_RED); const port_pin_config_t LED_GREEN = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Slow slew rate is configured */ kPORT_SlowSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTE26 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE26 (pin 33) is configured as PTE26 */ PORT_SetPinConfig(BOARD_LED_GREEN_PORT, BOARD_LED_GREEN_PIN, &LED_GREEN); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UART: - options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '63', peripheral: UART0, signal: TX, pin_signal: PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FB_AD16/EWM_OUT_b, direction: OUTPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '62', peripheral: UART0, signal: RX, pin_signal: PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FB_AD17/EWM_IN, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UART * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UART(void) { /* Port B Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortB); const port_pin_config_t DEBUG_UART_RX = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as UART0_RX */ kPORT_MuxAlt3, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB16 (pin 62) is configured as UART0_RX */ PORT_SetPinConfig(BOARD_DEBUG_UART_RX_PORT, BOARD_DEBUG_UART_RX_PIN, &DEBUG_UART_RX); const port_pin_config_t DEBUG_UART_TX = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as UART0_TX */ kPORT_MuxAlt3, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB17 (pin 63) is configured as UART0_TX */ PORT_SetPinConfig(BOARD_DEBUG_UART_TX_PORT, BOARD_DEBUG_UART_TX_PIN, &DEBUG_UART_TX); SIM->SOPT5 = ((SIM->SOPT5 & /* Mask bits to zero which are setting */ (~(SIM_SOPT5_UART0TXSRC_MASK))) /* UART 0 transmit data source select: UART0_TX pin. */ | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitOSC: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '50', peripheral: OSC, signal: EXTAL0, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: EXTAL0, slew_rate: no_init, open_drain: no_init, drive_strength: no_init, pull_select: no_init, pull_enable: no_init, passive_filter: no_init} - {pin_num: '29', peripheral: RTC, signal: EXTAL32, pin_signal: EXTAL32} - {pin_num: '28', peripheral: RTC, signal: XTAL32, pin_signal: XTAL32} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitOSC * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitOSC(void) { /* Port A Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortA); /* PORTA18 (pin 50) is configured as EXTAL0 */ PORT_SetPinMux(BOARD_EXTAL0_PORT, BOARD_EXTAL0_PIN, kPORT_PinDisabledOrAnalog); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitACCEL: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '32', peripheral: I2C0, signal: SDA, pin_signal: ADC0_SE18/PTE25/UART4_RX/I2C0_SDA/EWM_IN, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '31', peripheral: I2C0, signal: SCL, pin_signal: ADC0_SE17/PTE24/UART4_TX/I2C0_SCL/EWM_OUT_b, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: ACCEL_INT1, direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '85', peripheral: GPIOC, signal: 'GPIO, 13', pin_signal: PTC13/UART4_CTS_b/FB_AD26, direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitACCEL * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitACCEL(void) { /* Port C Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortC); /* Port E Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortE); gpio_pin_config_t ACCEL_INT1_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PTC6 (pin 78) */ GPIO_PinInit(BOARD_ACCEL_INT1_GPIO, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1_config); gpio_pin_config_t ACCEL_INT2_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PTC13 (pin 85) */ GPIO_PinInit(BOARD_ACCEL_INT2_GPIO, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2_config); const port_pin_config_t ACCEL_INT2 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is enabled */ kPORT_OpenDrainEnable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTC13 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTC13 (pin 85) is configured as PTC13 */ PORT_SetPinConfig(BOARD_ACCEL_INT2_PORT, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2); const port_pin_config_t ACCEL_INT1 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is enabled */ kPORT_OpenDrainEnable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTC6 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTC6 (pin 78) is configured as PTC6 */ PORT_SetPinConfig(BOARD_ACCEL_INT1_PORT, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1); const port_pin_config_t ACCEL_SCL = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is enabled */ kPORT_OpenDrainEnable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as I2C0_SCL */ kPORT_MuxAlt5, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE24 (pin 31) is configured as I2C0_SCL */ PORT_SetPinConfig(BOARD_ACCEL_SCL_PORT, BOARD_ACCEL_SCL_PIN, &ACCEL_SCL); const port_pin_config_t ACCEL_SDA = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is enabled */ kPORT_OpenDrainEnable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as I2C0_SDA */ kPORT_MuxAlt5, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE25 (pin 32) is configured as I2C0_SDA */ PORT_SetPinConfig(BOARD_ACCEL_SDA_PORT, BOARD_ACCEL_SDA_PIN, &ACCEL_SDA); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitENET: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '54', peripheral: ENET, signal: RMII_MDC, pin_signal: ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '53', peripheral: ENET, signal: RMII_MDIO, pin_signal: ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '43', peripheral: ENET, signal: RMII_RXD0, pin_signal: CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2C2_SDA/I2S0_TX_FS/FTM1_QD_PHB, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '42', peripheral: ENET, signal: RMII_RXD1, pin_signal: CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2C2_SCL/I2S0_TXD0/FTM1_QD_PHA, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '39', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '46', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '47', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '45', peripheral: ENET, signal: RMII_TXEN, pin_signal: PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '44', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2C2_SCL/I2S0_RX_BCLK/I2S0_TXD1, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} - {pin_num: '50', peripheral: ENET, signal: RMII_CLKIN, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: RMII_RXCLK, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitENET * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitENET(void) { /* Port A Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortA); /* Port B Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortB); const port_pin_config_t RMII0_RXD1 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_RXD1 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA12 (pin 42) is configured as RMII0_RXD1 */ PORT_SetPinConfig(BOARD_RMII0_RXD1_PORT, BOARD_RMII0_RXD1_PIN, &RMII0_RXD1); const port_pin_config_t RMII0_RXD0 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_RXD0 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA13 (pin 43) is configured as RMII0_RXD0 */ PORT_SetPinConfig(BOARD_RMII0_RXD0_PORT, BOARD_RMII0_RXD0_PIN, &RMII0_RXD0); const port_pin_config_t RMII0_CRS_DV = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_CRS_DV */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA14 (pin 44) is configured as RMII0_CRS_DV */ PORT_SetPinConfig(BOARD_RMII0_CRS_DV_PORT, BOARD_RMII0_CRS_DV_PIN, &RMII0_CRS_DV); const port_pin_config_t RMII0_TXEN = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_TXEN */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA15 (pin 45) is configured as RMII0_TXEN */ PORT_SetPinConfig(BOARD_RMII0_TXEN_PORT, BOARD_RMII0_TXEN_PIN, &RMII0_TXEN); const port_pin_config_t RMII0_TXD0 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_TXD0 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA16 (pin 46) is configured as RMII0_TXD0 */ PORT_SetPinConfig(BOARD_RMII0_TXD0_PORT, BOARD_RMII0_TXD0_PIN, &RMII0_TXD0); const port_pin_config_t RMII0_TXD1 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_TXD1 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA17 (pin 47) is configured as RMII0_TXD1 */ PORT_SetPinConfig(BOARD_RMII0_TXD1_PORT, BOARD_RMII0_TXD1_PIN, &RMII0_TXD1); const port_pin_config_t RMII_RXCLK = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as EXTAL0 */ kPORT_PinDisabledOrAnalog, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA18 (pin 50) is configured as EXTAL0 */ PORT_SetPinConfig(BOARD_RMII_RXCLK_PORT, BOARD_RMII_RXCLK_PIN, &RMII_RXCLK); const port_pin_config_t RMII0_RXER = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_RXER */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTA5 (pin 39) is configured as RMII0_RXER */ PORT_SetPinConfig(BOARD_RMII0_RXER_PORT, BOARD_RMII0_RXER_PIN, &RMII0_RXER); const port_pin_config_t RMII0_MDIO = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is enabled */ kPORT_OpenDrainEnable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_MDIO */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB0 (pin 53) is configured as RMII0_MDIO */ PORT_SetPinConfig(BOARD_RMII0_MDIO_PORT, BOARD_RMII0_MDIO_PIN, &RMII0_MDIO); const port_pin_config_t RMII0_MDC = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as RMII0_MDC */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTB1 (pin 54) is configured as RMII0_MDC */ PORT_SetPinConfig(BOARD_RMII0_MDC_PORT, BOARD_RMII0_MDC_PIN, &RMII0_MDC); SIM->SOPT2 = ((SIM->SOPT2 & /* Mask bits to zero which are setting */ (~(SIM_SOPT2_RMIISRC_MASK))) /* RMII clock source select: EXTAL clock. */ | SIM_SOPT2_RMIISRC(SOPT2_RMIISRC_EXTAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSDHC: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '1', peripheral: SDHC, signal: 'DATA, 1', pin_signal: ADC1_SE4a/PTE0/SPI1_PCS1/UART1_TX/SDHC0_D1/TRACE_CLKOUT/I2C1_SDA/RTC_CLKOUT, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '2', peripheral: SDHC, signal: 'DATA, 0', pin_signal: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/SDHC0_D0/TRACE_D3/I2C1_SCL/SPI1_SIN, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '3', peripheral: SDHC, signal: DCLK, pin_signal: ADC0_DP2/ADC1_SE6a/PTE2/LLWU_P1/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK/TRACE_D2, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '4', peripheral: SDHC, signal: CMD, pin_signal: ADC0_DM2/ADC1_SE7a/PTE3/SPI1_SIN/UART1_RTS_b/SDHC0_CMD/TRACE_D1/SPI1_SOUT, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '5', peripheral: SDHC, signal: 'DATA, 3', pin_signal: PTE4/LLWU_P2/SPI1_PCS0/UART3_TX/SDHC0_D3/TRACE_D0, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '6', peripheral: SDHC, signal: 'DATA, 2', pin_signal: PTE5/SPI1_PCS2/UART3_RX/SDHC0_D2/FTM3_CH0, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} - {pin_num: '7', peripheral: GPIOE, signal: 'GPIO, 6', pin_signal: PTE6/SPI1_PCS3/UART3_CTS_b/I2S0_MCLK/FTM3_CH1/USB_SOF_OUT, direction: INPUT, slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: enable, passive_filter: disable} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSDHC * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSDHC(void) { /* Port E Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortE); gpio_pin_config_t SDHC_CD_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PTE6 (pin 7) */ GPIO_PinInit(BOARD_SDHC_CD_GPIO, BOARD_SDHC_CD_PIN, &SDHC_CD_config); const port_pin_config_t SDHC0_D1 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_D1 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE0 (pin 1) is configured as SDHC0_D1 */ PORT_SetPinConfig(BOARD_SDHC0_D1_PORT, BOARD_SDHC0_D1_PIN, &SDHC0_D1); const port_pin_config_t SDHC0_D0 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_D0 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE1 (pin 2) is configured as SDHC0_D0 */ PORT_SetPinConfig(BOARD_SDHC0_D0_PORT, BOARD_SDHC0_D0_PIN, &SDHC0_D0); const port_pin_config_t SDHC0_DCLK = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_DCLK */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE2 (pin 3) is configured as SDHC0_DCLK */ PORT_SetPinConfig(BOARD_SDHC0_DCLK_PORT, BOARD_SDHC0_DCLK_PIN, &SDHC0_DCLK); const port_pin_config_t SDHC0_CMD = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_CMD */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE3 (pin 4) is configured as SDHC0_CMD */ PORT_SetPinConfig(BOARD_SDHC0_CMD_PORT, BOARD_SDHC0_CMD_PIN, &SDHC0_CMD); const port_pin_config_t SDHC0_D3 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_D3 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE4 (pin 5) is configured as SDHC0_D3 */ PORT_SetPinConfig(BOARD_SDHC0_D3_PORT, BOARD_SDHC0_D3_PIN, &SDHC0_D3); const port_pin_config_t SDHC0_D2 = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* High drive strength is configured */ kPORT_HighDriveStrength, /* Pin is configured as SDHC0_D2 */ kPORT_MuxAlt4, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE5 (pin 6) is configured as SDHC0_D2 */ PORT_SetPinConfig(BOARD_SDHC0_D2_PORT, BOARD_SDHC0_D2_PIN, &SDHC0_D2); const port_pin_config_t SDHC_CD = {/* Internal pull-down resistor is enabled */ kPORT_PullDown, /* Slow slew rate is configured */ kPORT_SlowSlewRate, /* Passive filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PTE6 */ kPORT_MuxAsGpio, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORTE6 (pin 7) is configured as PTE6 */ PORT_SetPinConfig(BOARD_SDHC_CD_PORT, BOARD_SDHC_CD_PIN, &SDHC_CD); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSB: - options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '10', peripheral: USB0, signal: DP, pin_signal: USB0_DP} - {pin_num: '11', peripheral: USB0, signal: DM, pin_signal: USB0_DM} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSB * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitUSB(void) { } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /*! @brief Direction type */ typedef enum _pin_mux_direction { kPIN_MUX_DirectionInput = 0U, /* Input direction */ kPIN_MUX_DirectionOutput = 1U, /* Output direction */ kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ } pin_mux_direction_t; /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); /*! @name PORTC6 (number 78), U8[11]/SW2 @{ */ /* Routed pin properties */ #define BOARD_SW2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ #define BOARD_SW2_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_SW2_CHANNEL 6 /*!<@brief Signal channel */ #define BOARD_SW2_PIN_NAME PTC6 /*!<@brief Routed pin name */ #define BOARD_SW2_LABEL "U8[11]/SW2" /*!<@brief Label */ #define BOARD_SW2_NAME "SW2" /*!<@brief Identifier */ #define BOARD_SW2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_SW2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ #define BOARD_SW2_GPIO_PIN 6U /*!<@brief GPIO pin number */ #define BOARD_SW2_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_SW2_PORT PORTC /*!<@brief PORT peripheral base pointer */ #define BOARD_SW2_PIN 6U /*!<@brief PORT pin number */ #define BOARD_SW2_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA4 (number 38), SW3 @{ */ /* Routed pin properties */ #define BOARD_SW3_PERIPHERAL GPIOA /*!<@brief Peripheral name */ #define BOARD_SW3_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_SW3_CHANNEL 4 /*!<@brief Signal channel */ #define BOARD_SW3_PIN_NAME PTA4 /*!<@brief Routed pin name */ #define BOARD_SW3_LABEL "SW3" /*!<@brief Label */ #define BOARD_SW3_NAME "SW3" /*!<@brief Identifier */ #define BOARD_SW3_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_SW3_GPIO GPIOA /*!<@brief GPIO peripheral base pointer */ #define BOARD_SW3_GPIO_PIN 4U /*!<@brief GPIO pin number */ #define BOARD_SW3_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_SW3_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_SW3_PIN 4U /*!<@brief PORT pin number */ #define BOARD_SW3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitButtons(void); /*! @name PORTB21 (number 67), D12[3]/LEDRGB_BLUE @{ */ /* Routed pin properties */ #define BOARD_LED_BLUE_PERIPHERAL GPIOB /*!<@brief Peripheral name */ #define BOARD_LED_BLUE_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_LED_BLUE_CHANNEL 21 /*!<@brief Signal channel */ #define BOARD_LED_BLUE_PIN_NAME PTB21 /*!<@brief Routed pin name */ #define BOARD_LED_BLUE_LABEL "D12[3]/LEDRGB_BLUE" /*!<@brief Label */ #define BOARD_LED_BLUE_NAME "LED_BLUE" /*!<@brief Identifier */ #define BOARD_LED_BLUE_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_LED_BLUE_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ #define BOARD_LED_BLUE_GPIO_PIN 21U /*!<@brief GPIO pin number */ #define BOARD_LED_BLUE_GPIO_PIN_MASK (1U << 21U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_LED_BLUE_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_LED_BLUE_PIN 21U /*!<@brief PORT pin number */ #define BOARD_LED_BLUE_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTB22 (number 68), D12[1]/LEDRGB_RED @{ */ /* Routed pin properties */ #define BOARD_LED_RED_PERIPHERAL GPIOB /*!<@brief Peripheral name */ #define BOARD_LED_RED_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_LED_RED_CHANNEL 22 /*!<@brief Signal channel */ #define BOARD_LED_RED_PIN_NAME PTB22 /*!<@brief Routed pin name */ #define BOARD_LED_RED_LABEL "D12[1]/LEDRGB_RED" /*!<@brief Label */ #define BOARD_LED_RED_NAME "LED_RED" /*!<@brief Identifier */ #define BOARD_LED_RED_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_LED_RED_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ #define BOARD_LED_RED_GPIO_PIN 22U /*!<@brief GPIO pin number */ #define BOARD_LED_RED_GPIO_PIN_MASK (1U << 22U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_LED_RED_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_LED_RED_PIN 22U /*!<@brief PORT pin number */ #define BOARD_LED_RED_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE26 (number 33), J2[1]/D12[4]/LEDRGB_GREEN @{ */ /* Routed pin properties */ #define BOARD_LED_GREEN_PERIPHERAL GPIOE /*!<@brief Peripheral name */ #define BOARD_LED_GREEN_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_LED_GREEN_CHANNEL 26 /*!<@brief Signal channel */ #define BOARD_LED_GREEN_PIN_NAME PTE26 /*!<@brief Routed pin name */ #define BOARD_LED_GREEN_LABEL "J2[1]/D12[4]/LEDRGB_GREEN" /*!<@brief Label */ #define BOARD_LED_GREEN_NAME "LED_GREEN" /*!<@brief Identifier */ #define BOARD_LED_GREEN_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_LED_GREEN_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ #define BOARD_LED_GREEN_GPIO_PIN 26U /*!<@brief GPIO pin number */ #define BOARD_LED_GREEN_GPIO_PIN_MASK (1U << 26U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_LED_GREEN_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_LED_GREEN_PIN 26U /*!<@brief PORT pin number */ #define BOARD_LED_GREEN_PIN_MASK (1U << 26U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDs(void); #define SOPT5_UART0TXSRC_UART_TX 0x00u /*!<@brief UART 0 transmit data source select: UART0_TX pin */ /*! @name PORTB17 (number 63), U10[1]/UART0_TX @{ */ /* Routed pin properties */ #define BOARD_DEBUG_UART_TX_PERIPHERAL UART0 /*!<@brief Peripheral name */ #define BOARD_DEBUG_UART_TX_SIGNAL TX /*!<@brief Signal name */ #define BOARD_DEBUG_UART_TX_PIN_NAME UART0_TX /*!<@brief Routed pin name */ #define BOARD_DEBUG_UART_TX_LABEL "U10[1]/UART0_TX" /*!<@brief Label */ #define BOARD_DEBUG_UART_TX_NAME "DEBUG_UART_TX" /*!<@brief Identifier */ #define BOARD_DEBUG_UART_TX_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ /* Symbols to be used with PORT driver */ #define BOARD_DEBUG_UART_TX_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_DEBUG_UART_TX_PIN 17U /*!<@brief PORT pin number */ #define BOARD_DEBUG_UART_TX_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTB16 (number 62), U7[4]/UART0_RX @{ */ /* Routed pin properties */ #define BOARD_DEBUG_UART_RX_PERIPHERAL UART0 /*!<@brief Peripheral name */ #define BOARD_DEBUG_UART_RX_SIGNAL RX /*!<@brief Signal name */ #define BOARD_DEBUG_UART_RX_PIN_NAME UART0_RX /*!<@brief Routed pin name */ #define BOARD_DEBUG_UART_RX_LABEL "U7[4]/UART0_RX" /*!<@brief Label */ #define BOARD_DEBUG_UART_RX_NAME "DEBUG_UART_RX" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_DEBUG_UART_RX_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_DEBUG_UART_RX_PIN 16U /*!<@brief PORT pin number */ #define BOARD_DEBUG_UART_RX_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UART(void); /*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK @{ */ /* Routed pin properties */ #define BOARD_EXTAL0_PERIPHERAL OSC /*!<@brief Peripheral name */ #define BOARD_EXTAL0_SIGNAL EXTAL0 /*!<@brief Signal name */ #define BOARD_EXTAL0_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ #define BOARD_EXTAL0_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ #define BOARD_EXTAL0_NAME "EXTAL0" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_EXTAL0_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_EXTAL0_PIN 18U /*!<@brief PORT pin number */ #define BOARD_EXTAL0_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ /* @} */ /*! @name EXTAL32 (number 29), Y3[2]/EXTAL32_RTC @{ */ /* Routed pin properties */ #define BOARD_ETAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ #define BOARD_ETAL32K_SIGNAL EXTAL32 /*!<@brief Signal name */ #define BOARD_ETAL32K_PIN_NAME EXTAL32 /*!<@brief Routed pin name */ #define BOARD_ETAL32K_LABEL "Y3[2]/EXTAL32_RTC" /*!<@brief Label */ #define BOARD_ETAL32K_NAME "ETAL32K" /*!<@brief Identifier */ /* @} */ /*! @name XTAL32 (number 28), Y3[1]/XTAL32_RTC @{ */ /* Routed pin properties */ #define BOARD_XTAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ #define BOARD_XTAL32K_SIGNAL XTAL32 /*!<@brief Signal name */ #define BOARD_XTAL32K_PIN_NAME XTAL32 /*!<@brief Routed pin name */ #define BOARD_XTAL32K_LABEL "Y3[1]/XTAL32_RTC" /*!<@brief Label */ #define BOARD_XTAL32K_NAME "XTAL32K" /*!<@brief Identifier */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitOSC(void); /*! @name PORTE25 (number 32), J2[18]/U8[6]/I2C0_SDA @{ */ /* Routed pin properties */ #define BOARD_ACCEL_SDA_PERIPHERAL I2C0 /*!<@brief Peripheral name */ #define BOARD_ACCEL_SDA_SIGNAL SDA /*!<@brief Signal name */ #define BOARD_ACCEL_SDA_PIN_NAME I2C0_SDA /*!<@brief Routed pin name */ #define BOARD_ACCEL_SDA_LABEL "J2[18]/U8[6]/I2C0_SDA" /*!<@brief Label */ #define BOARD_ACCEL_SDA_NAME "ACCEL_SDA" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_ACCEL_SDA_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_ACCEL_SDA_PIN 25U /*!<@brief PORT pin number */ #define BOARD_ACCEL_SDA_PIN_MASK (1U << 25U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE24 (number 31), J2[20]/U8[4]/I2C0_SCL @{ */ /* Routed pin properties */ #define BOARD_ACCEL_SCL_PERIPHERAL I2C0 /*!<@brief Peripheral name */ #define BOARD_ACCEL_SCL_SIGNAL SCL /*!<@brief Signal name */ #define BOARD_ACCEL_SCL_PIN_NAME I2C0_SCL /*!<@brief Routed pin name */ #define BOARD_ACCEL_SCL_LABEL "J2[20]/U8[4]/I2C0_SCL" /*!<@brief Label */ #define BOARD_ACCEL_SCL_NAME "ACCEL_SCL" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_ACCEL_SCL_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_ACCEL_SCL_PIN 24U /*!<@brief PORT pin number */ #define BOARD_ACCEL_SCL_PIN_MASK (1U << 24U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTC6 (number 78), U8[11]/SW2 @{ */ /* Routed pin properties */ #define BOARD_ACCEL_INT1_PERIPHERAL GPIOC /*!<@brief Peripheral name */ #define BOARD_ACCEL_INT1_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_ACCEL_INT1_CHANNEL 6 /*!<@brief Signal channel */ #define BOARD_ACCEL_INT1_PIN_NAME PTC6 /*!<@brief Routed pin name */ #define BOARD_ACCEL_INT1_LABEL "U8[11]/SW2" /*!<@brief Label */ #define BOARD_ACCEL_INT1_NAME "ACCEL_INT1" /*!<@brief Identifier */ #define BOARD_ACCEL_INT1_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_ACCEL_INT1_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ #define BOARD_ACCEL_INT1_GPIO_PIN 6U /*!<@brief GPIO pin number */ #define BOARD_ACCEL_INT1_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_ACCEL_INT1_PORT PORTC /*!<@brief PORT peripheral base pointer */ #define BOARD_ACCEL_INT1_PIN 6U /*!<@brief PORT pin number */ #define BOARD_ACCEL_INT1_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTC13 (number 85), U8[9] @{ */ /* Routed pin properties */ #define BOARD_ACCEL_INT2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ #define BOARD_ACCEL_INT2_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_ACCEL_INT2_CHANNEL 13 /*!<@brief Signal channel */ #define BOARD_ACCEL_INT2_PIN_NAME PTC13 /*!<@brief Routed pin name */ #define BOARD_ACCEL_INT2_LABEL "U8[9]" /*!<@brief Label */ #define BOARD_ACCEL_INT2_NAME "ACCEL_INT2" /*!<@brief Identifier */ #define BOARD_ACCEL_INT2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_ACCEL_INT2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ #define BOARD_ACCEL_INT2_GPIO_PIN 13U /*!<@brief GPIO pin number */ #define BOARD_ACCEL_INT2_GPIO_PIN_MASK (1U << 13U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_ACCEL_INT2_PORT PORTC /*!<@brief PORT peripheral base pointer */ #define BOARD_ACCEL_INT2_PIN 13U /*!<@brief PORT pin number */ #define BOARD_ACCEL_INT2_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitACCEL(void); #define SOPT2_RMIISRC_EXTAL 0x00u /*!<@brief RMII clock source select: EXTAL clock */ /*! @name PORTB1 (number 54), U13[11]/RMII0_MDC @{ */ /* Routed pin properties */ #define BOARD_RMII0_MDC_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_MDC_SIGNAL RMII_MDC /*!<@brief Signal name */ #define BOARD_RMII0_MDC_PIN_NAME RMII0_MDC /*!<@brief Routed pin name */ #define BOARD_RMII0_MDC_LABEL "U13[11]/RMII0_MDC" /*!<@brief Label */ #define BOARD_RMII0_MDC_NAME "RMII0_MDC" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_MDC_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_MDC_PIN 1U /*!<@brief PORT pin number */ #define BOARD_RMII0_MDC_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTB0 (number 53), U13[10]/RMII0_MDIO @{ */ /* Routed pin properties */ #define BOARD_RMII0_MDIO_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_MDIO_SIGNAL RMII_MDIO /*!<@brief Signal name */ #define BOARD_RMII0_MDIO_PIN_NAME RMII0_MDIO /*!<@brief Routed pin name */ #define BOARD_RMII0_MDIO_LABEL "U13[10]/RMII0_MDIO" /*!<@brief Label */ #define BOARD_RMII0_MDIO_NAME "RMII0_MDIO" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_MDIO_PORT PORTB /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_MDIO_PIN 0U /*!<@brief PORT pin number */ #define BOARD_RMII0_MDIO_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA13 (number 43), U13[13]/RMII0_RXD_0 @{ */ /* Routed pin properties */ #define BOARD_RMII0_RXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_RXD0_SIGNAL RMII_RXD0 /*!<@brief Signal name */ #define BOARD_RMII0_RXD0_PIN_NAME RMII0_RXD0 /*!<@brief Routed pin name */ #define BOARD_RMII0_RXD0_LABEL "U13[13]/RMII0_RXD_0" /*!<@brief Label */ #define BOARD_RMII0_RXD0_NAME "RMII0_RXD0" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_RXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_RXD0_PIN 13U /*!<@brief PORT pin number */ #define BOARD_RMII0_RXD0_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA12 (number 42), U13[12]/RMII0_RXD_1 @{ */ /* Routed pin properties */ #define BOARD_RMII0_RXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_RXD1_SIGNAL RMII_RXD1 /*!<@brief Signal name */ #define BOARD_RMII0_RXD1_PIN_NAME RMII0_RXD1 /*!<@brief Routed pin name */ #define BOARD_RMII0_RXD1_LABEL "U13[12]/RMII0_RXD_1" /*!<@brief Label */ #define BOARD_RMII0_RXD1_NAME "RMII0_RXD1" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_RXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_RXD1_PIN 12U /*!<@brief PORT pin number */ #define BOARD_RMII0_RXD1_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA5 (number 39), U13[17]/RMII0_RXER @{ */ /* Routed pin properties */ #define BOARD_RMII0_RXER_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_RXER_SIGNAL RMII_RXER /*!<@brief Signal name */ #define BOARD_RMII0_RXER_PIN_NAME RMII0_RXER /*!<@brief Routed pin name */ #define BOARD_RMII0_RXER_LABEL "U13[17]/RMII0_RXER" /*!<@brief Label */ #define BOARD_RMII0_RXER_NAME "RMII0_RXER" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_RXER_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_RXER_PIN 5U /*!<@brief PORT pin number */ #define BOARD_RMII0_RXER_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA16 (number 46), U13[20]/RMII0_TXD0 @{ */ /* Routed pin properties */ #define BOARD_RMII0_TXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_TXD0_SIGNAL RMII_TXD0 /*!<@brief Signal name */ #define BOARD_RMII0_TXD0_PIN_NAME RMII0_TXD0 /*!<@brief Routed pin name */ #define BOARD_RMII0_TXD0_LABEL "U13[20]/RMII0_TXD0" /*!<@brief Label */ #define BOARD_RMII0_TXD0_NAME "RMII0_TXD0" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_TXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_TXD0_PIN 16U /*!<@brief PORT pin number */ #define BOARD_RMII0_TXD0_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA17 (number 47), U13[21]/RMII0_TXD1 @{ */ /* Routed pin properties */ #define BOARD_RMII0_TXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_TXD1_SIGNAL RMII_TXD1 /*!<@brief Signal name */ #define BOARD_RMII0_TXD1_PIN_NAME RMII0_TXD1 /*!<@brief Routed pin name */ #define BOARD_RMII0_TXD1_LABEL "U13[21]/RMII0_TXD1" /*!<@brief Label */ #define BOARD_RMII0_TXD1_NAME "RMII0_TXD1" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_TXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_TXD1_PIN 17U /*!<@brief PORT pin number */ #define BOARD_RMII0_TXD1_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA15 (number 45), U13[19]/RMII0_TXEN @{ */ /* Routed pin properties */ #define BOARD_RMII0_TXEN_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_TXEN_SIGNAL RMII_TXEN /*!<@brief Signal name */ #define BOARD_RMII0_TXEN_PIN_NAME RMII0_TXEN /*!<@brief Routed pin name */ #define BOARD_RMII0_TXEN_LABEL "U13[19]/RMII0_TXEN" /*!<@brief Label */ #define BOARD_RMII0_TXEN_NAME "RMII0_TXEN" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_TXEN_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_TXEN_PIN 15U /*!<@brief PORT pin number */ #define BOARD_RMII0_TXEN_PIN_MASK (1U << 15U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA14 (number 44), U13[15]/RMII0_CRS_DV @{ */ /* Routed pin properties */ #define BOARD_RMII0_CRS_DV_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII0_CRS_DV_SIGNAL RMII_CRS_DV /*!<@brief Signal name */ #define BOARD_RMII0_CRS_DV_PIN_NAME RMII0_CRS_DV /*!<@brief Routed pin name */ #define BOARD_RMII0_CRS_DV_LABEL "U13[15]/RMII0_CRS_DV" /*!<@brief Label */ #define BOARD_RMII0_CRS_DV_NAME "RMII0_CRS_DV" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII0_CRS_DV_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII0_CRS_DV_PIN 14U /*!<@brief PORT pin number */ #define BOARD_RMII0_CRS_DV_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK @{ */ /* Routed pin properties */ #define BOARD_RMII_RXCLK_PERIPHERAL ENET /*!<@brief Peripheral name */ #define BOARD_RMII_RXCLK_SIGNAL RMII_CLKIN /*!<@brief Signal name */ #define BOARD_RMII_RXCLK_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ #define BOARD_RMII_RXCLK_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ #define BOARD_RMII_RXCLK_NAME "RMII_RXCLK" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_RMII_RXCLK_PORT PORTA /*!<@brief PORT peripheral base pointer */ #define BOARD_RMII_RXCLK_PIN 18U /*!<@brief PORT pin number */ #define BOARD_RMII_RXCLK_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitENET(void); /*! @name PORTE0 (number 1), J15[P8]/SDHC0_D1 @{ */ /* Routed pin properties */ #define BOARD_SDHC0_D1_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_D1_SIGNAL DATA /*!<@brief Signal name */ #define BOARD_SDHC0_D1_CHANNEL 1 /*!<@brief Signal channel */ #define BOARD_SDHC0_D1_PIN_NAME SDHC0_D1 /*!<@brief Routed pin name */ #define BOARD_SDHC0_D1_LABEL "J15[P8]/SDHC0_D1" /*!<@brief Label */ #define BOARD_SDHC0_D1_NAME "SDHC0_D1" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_D1_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_D1_PIN 0U /*!<@brief PORT pin number */ #define BOARD_SDHC0_D1_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE1 (number 2), J15[P7]/SDHC0_D0 @{ */ /* Routed pin properties */ #define BOARD_SDHC0_D0_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_D0_SIGNAL DATA /*!<@brief Signal name */ #define BOARD_SDHC0_D0_CHANNEL 0 /*!<@brief Signal channel */ #define BOARD_SDHC0_D0_PIN_NAME SDHC0_D0 /*!<@brief Routed pin name */ #define BOARD_SDHC0_D0_LABEL "J15[P7]/SDHC0_D0" /*!<@brief Label */ #define BOARD_SDHC0_D0_NAME "SDHC0_D0" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_D0_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_D0_PIN 1U /*!<@brief PORT pin number */ #define BOARD_SDHC0_D0_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE2 (number 3), J15[P5]/SDHC0_DCLK @{ */ /* Routed pin properties */ #define BOARD_SDHC0_DCLK_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_DCLK_SIGNAL DCLK /*!<@brief Signal name */ #define BOARD_SDHC0_DCLK_PIN_NAME SDHC0_DCLK /*!<@brief Routed pin name */ #define BOARD_SDHC0_DCLK_LABEL "J15[P5]/SDHC0_DCLK" /*!<@brief Label */ #define BOARD_SDHC0_DCLK_NAME "SDHC0_DCLK" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_DCLK_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_DCLK_PIN 2U /*!<@brief PORT pin number */ #define BOARD_SDHC0_DCLK_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE3 (number 4), J15[P3]/SDHC0_CMD @{ */ /* Routed pin properties */ #define BOARD_SDHC0_CMD_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_CMD_SIGNAL CMD /*!<@brief Signal name */ #define BOARD_SDHC0_CMD_PIN_NAME SDHC0_CMD /*!<@brief Routed pin name */ #define BOARD_SDHC0_CMD_LABEL "J15[P3]/SDHC0_CMD" /*!<@brief Label */ #define BOARD_SDHC0_CMD_NAME "SDHC0_CMD" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_CMD_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_CMD_PIN 3U /*!<@brief PORT pin number */ #define BOARD_SDHC0_CMD_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE4 (number 5), J15[P2]/SDHC0_D3 @{ */ /* Routed pin properties */ #define BOARD_SDHC0_D3_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_D3_SIGNAL DATA /*!<@brief Signal name */ #define BOARD_SDHC0_D3_CHANNEL 3 /*!<@brief Signal channel */ #define BOARD_SDHC0_D3_PIN_NAME SDHC0_D3 /*!<@brief Routed pin name */ #define BOARD_SDHC0_D3_LABEL "J15[P2]/SDHC0_D3" /*!<@brief Label */ #define BOARD_SDHC0_D3_NAME "SDHC0_D3" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_D3_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_D3_PIN 4U /*!<@brief PORT pin number */ #define BOARD_SDHC0_D3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE5 (number 6), J15[P1]/SDHC0_D2 @{ */ /* Routed pin properties */ #define BOARD_SDHC0_D2_PERIPHERAL SDHC /*!<@brief Peripheral name */ #define BOARD_SDHC0_D2_SIGNAL DATA /*!<@brief Signal name */ #define BOARD_SDHC0_D2_CHANNEL 2 /*!<@brief Signal channel */ #define BOARD_SDHC0_D2_PIN_NAME SDHC0_D2 /*!<@brief Routed pin name */ #define BOARD_SDHC0_D2_LABEL "J15[P1]/SDHC0_D2" /*!<@brief Label */ #define BOARD_SDHC0_D2_NAME "SDHC0_D2" /*!<@brief Identifier */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC0_D2_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC0_D2_PIN 5U /*!<@brief PORT pin number */ #define BOARD_SDHC0_D2_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORTE6 (number 7), J15[G1]/SD_CARD_DETECT @{ */ /* Routed pin properties */ #define BOARD_SDHC_CD_PERIPHERAL GPIOE /*!<@brief Peripheral name */ #define BOARD_SDHC_CD_SIGNAL GPIO /*!<@brief Signal name */ #define BOARD_SDHC_CD_CHANNEL 6 /*!<@brief Signal channel */ #define BOARD_SDHC_CD_PIN_NAME PTE6 /*!<@brief Routed pin name */ #define BOARD_SDHC_CD_LABEL "J15[G1]/SD_CARD_DETECT" /*!<@brief Label */ #define BOARD_SDHC_CD_NAME "SDHC_CD" /*!<@brief Identifier */ #define BOARD_SDHC_CD_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ /* Symbols to be used with GPIO driver */ #define BOARD_SDHC_CD_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ #define BOARD_SDHC_CD_GPIO_PIN 6U /*!<@brief GPIO pin number */ #define BOARD_SDHC_CD_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_SDHC_CD_PORT PORTE /*!<@brief PORT peripheral base pointer */ #define BOARD_SDHC_CD_PIN 6U /*!<@brief PORT pin number */ #define BOARD_SDHC_CD_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSDHC(void); /*! @name USB0_DP (number 10), J22[3]/K64_MICRO_USB_DP @{ */ /* Routed pin properties */ #define BOARD_USB_DP_PERIPHERAL USB0 /*!<@brief Peripheral name */ #define BOARD_USB_DP_SIGNAL DP /*!<@brief Signal name */ #define BOARD_USB_DP_PIN_NAME USB0_DP /*!<@brief Routed pin name */ #define BOARD_USB_DP_LABEL "J22[3]/K64_MICRO_USB_DP" /*!<@brief Label */ #define BOARD_USB_DP_NAME "USB_DP" /*!<@brief Identifier */ /* @} */ /*! @name USB0_DM (number 11), J22[2]/K64_MICRO_USB_DN @{ */ /* Routed pin properties */ #define BOARD_USB_DM_PERIPHERAL USB0 /*!<@brief Peripheral name */ #define BOARD_USB_DM_SIGNAL DM /*!<@brief Signal name */ #define BOARD_USB_DM_PIN_NAME USB0_DM /*!<@brief Routed pin name */ #define BOARD_USB_DM_LABEL "J22[2]/K64_MICRO_USB_DN" /*!<@brief Label */ #define BOARD_USB_DM_NAME "USB_DM" /*!<@brief Identifier */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSB(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake ================================================ set(MCU_VARIANT MK64F12) set(JLINK_DEVICE MK64FN1M0xxx12) set(PYOCD_TARGET k64f) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FN1M0xxx12_flash.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/pin_mux.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/clock_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MK64FN1M0VMD12 ) endfunction() ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. */ /* metadata: name: Freedom K64F url: https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F */ #ifndef BOARD_H #define BOARD_H //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // LED #define LED_PORT BOARD_LED_RED_GPIO #define LED_PIN BOARD_LED_RED_GPIO_PIN #define LED_STATE_ON 0 // Button #define BUTTON_PORT BOARD_SW2_GPIO #define BUTTON_PIN BOARD_SW2_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV UART0 #define UART_CLOCK CLOCK_GetFreq(UART0_CLK_SRC) #endif ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/board.mk ================================================ MCU_VARIANT = MK64F12 CFLAGS += \ -DCPU_MK64FN1M0VMD12 \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=format -Wno-error=redundant-decls SRC_C += \ $(BOARD_PATH)/board/clock_config.c \ $(BOARD_PATH)/board/pin_mux.c \ LD_FILE = ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FN1M0xxx12_flash.ld # For flash-jlink target JLINK_DEVICE = MK64FN1M0xxx12 # For flash-pyocd target PYOCD_TARGET = k64f ================================================ FILE: hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex ================================================ MK64FN1M0xxx12 MK64FN1M0VLL12 FRDM-K64F E1 ksdk2_0 true true false true false 14.0.0 Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true Configures pin routing and optionally pin electrical features. true BOARD_ core0 true true true true Configures pin routing and optionally pin electrical features. true BOARD_ core0 true true true true Configures pin routing and optionally pin electrical features. true BOARD_ core0 true true true true Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true true true true Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true true true true Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true true true Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true true true true Configures pin routing and optionally pin electrical features. false BOARD_ core0 true true true 14.0.0 true INPUT true false true true false 0.0.0 true 2.8.0 14.0.0 true true true 0 true true 0.0.0 ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to setup clock using clock driver functions: * * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock * and flash clock are in allowed range during clock mode switch. * * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. * * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and * internal reference clock(MCGIRCLK). Follow the steps to setup: * * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. * * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig * explicitly to setup MCGIRCLK. * * 3). Don't need to configure FLL explicitly, because if target mode is FLL * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, * if the target mode is not FLL mode, the FLL is disabled. * * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. * * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v11.0 processor: MK64FX512xxx12 package_id: MK64FX512VLQ12 mcu_data: ksdk2_0 processor_version: 13.0.1 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ #define MCG_IRCLK_DISABLE 0U /*!< MCGIRCLK disabled */ #define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ #define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ #define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ #define SIM_PLLFLLSEL_MCGPLLCLK_CLK 1U /*!< PLLFLL select: MCGPLLCLK clock */ #define SIM_USB_CLK_120000000HZ 120000000U /*!< Input SIM frequency for USB: 120000000Hz */ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* * Code ******************************************************************************/ /*FUNCTION********************************************************************** * * Function Name : CLOCK_CONFIG_SetFllExtRefDiv * Description : Configure FLL external reference divider (FRDIV). * Param frdiv : The value to set FRDIV. * *END**************************************************************************/ static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) { MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); } /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: Bus_clock.outFreq, value: 60 MHz} - {id: Core_clock.outFreq, value: 120 MHz} - {id: Flash_clock.outFreq, value: 24 MHz} - {id: FlexBus_clock.outFreq, value: 40 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGFFCLK.outFreq, value: 500 kHz} - {id: PLLFLLCLK.outFreq, value: 120 MHz} - {id: System_clock.outFreq, value: 120 MHz} - {id: USB48MCLK.outFreq, value: 48 MHz} settings: - {id: MCGMode, value: PEE} - {id: MCG.FRDIV.scale, value: '32'} - {id: MCG.IREFS.sel, value: MCG.FRDIV} - {id: MCG.PLLS.sel, value: MCG.PLL} - {id: MCG.PRDIV.scale, value: '4'} - {id: MCG.VDIV.scale, value: '30'} - {id: MCG_C2_RANGE0_CFG, value: Very_high} - {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} - {id: MCG_C5_PLLCLKEN0_CFG, value: Enabled} - {id: RTC_CR_CLKO_CFG, value: Disabled} - {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} - {id: SIM.OUTDIV2.scale, value: '2'} - {id: SIM.OUTDIV3.scale, value: '3'} - {id: SIM.OUTDIV4.scale, value: '5'} - {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} - {id: SIM.USBDIV.scale, value: '5'} - {id: SIM.USBFRAC.scale, value: '2'} - {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} - {id: USBClkConfig, value: 'yes'} sources: - {id: OSC.OSC.outFreq, value: 16 MHz, enabled: true} - {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const mcg_config_t mcgConfig_BOARD_BootClockRUN = { .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ .drs = kMCG_DrsLow, /* Low frequency range */ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ .pll0Config = { .enableMode = kMCG_PllEnableIndependent,/* MCGPLLCLK enabled independent of MCG clock mode, MCGPLLCLK disabled in STOP mode */ .prdiv = 0x3U, /* PLL Reference divider: divided by 4 */ .vdiv = 0x6U, /* VCO divider: multiplied by 30 */ }, }; const sim_clock_config_t simConfig_BOARD_BootClockRUN = { .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ }; const osc_config_t oscConfig_BOARD_BootClockRUN = { .freq = 16000000U, /* Oscillator frequency: 16000000Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeExt, /* Use external clock */ .oscerConfig = { .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ } }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Initializes OSC0 according to board configuration. */ CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); /* Configure FLL external reference divider (FRDIV). */ CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); /* Set MCG to PEE mode. */ CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, kMCG_PllClkSelPll0, &mcgConfig_BOARD_BootClockRUN.pll0Config); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; /* Enable USB FS clock. */ CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); } ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal0 frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ /*! @brief MCG set for BOARD_BootClockRUN configuration. */ extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; /*! @brief SIM module set for BOARD_BootClockRUN configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; /*! @brief OSC set for BOARD_BootClockRUN configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v13.1 processor: MK64FX512xxx12 package_id: MK64FX512VLQ12 mcu_data: ksdk2_0 processor_version: 13.0.1 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - {pin_num: '110', peripheral: GPIOC, signal: 'GPIO, 5', pin_signal: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FB_AD10/CMP0_OUT/FTM0_CH2} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { /* Port C Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortC); /* PORTC5 (pin 110) is configured as PTC5 */ PORT_SetPinMux(PORTC, 5U, kPORT_MuxAsGpio); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board.cmake ================================================ set(MCU_VARIANT MK64F12) set(JLINK_DEVICE MK64FX512xxx12) set(TEENSY_MCU TEENSY35) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FX512xxx12_flash.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/pin_mux.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/clock_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_MK64FX512VMD12 ) endfunction() ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. */ /* metadata: name: Teensy 3.5 url: https://www.pjrc.com/store/teensy35.html */ #ifndef BOARD_H #define BOARD_H //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // LED #define LED_PORT GPIOC #define LED_PIN 5 #define LED_STATE_ON 1 // Button // UART //#define UART_PORT UART0 //#define UART_PIN_CLOCK kCLOCK_PortA //#define UART_PIN_PORT PORTA //#define UART_PIN_RX 1u //#define UART_PIN_TX 2u //#define UART_PIN_FUNCTION kPORT_MuxAlt2 //#define SOPT5_UART0RXSRC_UART_RX 0x00u /*!< UART0 receive data source select: UART0_RX pin */ //#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!< UART0 transmit data source select: UART0_TX pin */ #endif ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/board.mk ================================================ MCU_VARIANT = MK64F12 CFLAGS += \ -DCPU_MK64FX512VMD12 \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=format -Wno-error=redundant-decls SRC_C += \ $(BOARD_PATH)/board/clock_config.c \ $(BOARD_PATH)/board/pin_mux.c \ LD_FILE = ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FX512xxx12_flash.ld # For flash-jlink target JLINK_DEVICE = MK64FX512xxx12 # For flash-pyocd target PYOCD_TARGET = k64f # flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli flash: $(BUILD)/$(PROJECT).hex teensy_loader_cli --mcu=TEENSY35 -v -w $< ================================================ FILE: hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex ================================================ MK64FX512xxx12 MK64FX512VLQ12 ksdk2_0 true false false true false 13.0.1 Configures pin routing and optionally pin electrical features. true core0 true true true 13.0.1 true INPUT true true N/A 13.0.1 N/A ================================================ FILE: hw/bsp/kinetis_k/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2020, Koji Kitayama * * 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. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "board.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_clock.h" #include "fsl_uart.h" #include "fsl_sysmpu.h" #include "board/clock_config.h" #include "board/pin_mux.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED tuh_int_handler(0); #endif #if CFG_TUD_ENABLED tud_int_handler(0); #endif } void board_init(void) { BOARD_InitBootPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); SYSMPU_Enable(SYSMPU, 0); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif // LED gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; GPIO_PinInit(LED_PORT, LED_PIN, &led_config); board_led_write(false); #if defined(BUTTON_PORT) && defined(BUTTON_PIN) gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); #endif #ifdef UART_DEV const uart_config_t uart_config = { .baudRate_Bps = 115200UL, .parityMode = kUART_ParityDisabled, .stopBitCount = kUART_OneStopBit, .txFifoWatermark = 0U, .rxFifoWatermark = 1U, .idleType = kUART_IdleTypeStartBit, .enableTx = true, .enableRx = true }; UART_Init(UART_DEV, &uart_config, UART_CLOCK); #endif // USB // USB clock is configured in BOARD_BootClockRUN() } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { #if defined(BUTTON_PORT) && defined(BUTTON_PIN) return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); #else return 0; #endif } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; #ifdef UART_DEV // Read blocking will block until there is data // UART_ReadBlocking(UART_DEV, buf, len); // return len; return 0; #else return 0; #endif } int board_uart_write(void const *buf, int len) { (void) buf; (void) len; #ifdef UART_DEV UART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; #else return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/kinetis_k/family.cmake ================================================ include_guard() if (NOT BOARD) message(FATAL_ERROR "BOARD not specified") endif () set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS KINETIS_K CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/drivers/gpio/fsl_gpio.c ${SDK_DIR}/drivers/uart/fsl_uart.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_DIR}/CMSIS/Core/Include ${SDK_DIR}/devices/${MCU_VARIANT} ${SDK_DIR}/devices/${MCU_VARIANT}/drivers ${SDK_DIR}/drivers/common ${SDK_DIR}/drivers/gpio ${SDK_DIR}/drivers/port ${SDK_DIR}/drivers/smc ${SDK_DIR}/drivers/sysmpu ${SDK_DIR}/drivers/uart ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.c ${TOP}/src/portable/nxp/khci/hcd_khci.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_teensy(${TARGET}) endfunction() ================================================ FILE: hw/bsp/kinetis_k/family.mk ================================================ SDK_DIR = hw/mcu/nxp/mcux-sdk MCU_DIR = $(SDK_DIR)/devices/${MCU_VARIANT} include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ LDFLAGS += \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ $(MCU_DIR)/system_${MCU_VARIANT}.c \ $(MCU_DIR)/drivers/fsl_clock.c \ $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ $(SDK_DIR)/drivers/uart/fsl_uart.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/gpio \ $(TOP)/$(SDK_DIR)/drivers/port \ $(TOP)/$(SDK_DIR)/drivers/smc \ $(TOP)/$(SDK_DIR)/drivers/sysmpu \ $(TOP)/$(SDK_DIR)/drivers/uart \ SRC_S += ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S ================================================ FILE: hw/bsp/kinetis_k32l/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #else #define configASSERT( x ) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); } /*FUNCTION********************************************************************** * * Function Name : CLOCK_CONFIG_FircSafeConfig * Description : This function is used to safely configure FIRC clock. * In default out of reset, the CPU is clocked from FIRC(IRC48M). * Before setting FIRC, change to use SIRC as system clock, * then configure FIRC. After FIRC is set, change back to use FIRC * in case SIRC need to be configured. * Param fircConfig : FIRC configuration. * *END**************************************************************************/ static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) { scg_sys_clk_config_t curConfig; const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, .div1 = kSCG_AsyncClkDisable, .div3 = kSCG_AsyncClkDivBy2, .range = kSCG_SircRangeHigh}; scg_sys_clk_config_t sysClkSafeConfigSource = { .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved1 = 0, .reserved2 = 0, .reserved3 = 0, #endif .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved4 = 0, #endif .src = kSCG_SysClkSrcSirc, /* System clock source */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved5 = 0, #endif }; /* Init Sirc. */ CLOCK_InitSirc(&scgSircConfig); /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); /* Wait for clock source switch finished. */ do { CLOCK_GetCurSysClkConfig(&curConfig); } while (curConfig.src != sysClkSafeConfigSource.src); /* Init Firc. */ CLOCK_InitFirc(fircConfig); /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); /* Wait for clock source switch finished. */ do { CLOCK_GetCurSysClkConfig(&curConfig); } while (curConfig.src != sysClkSafeConfigSource.src); } /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: Core_clock.outFreq, value: 48 MHz} - {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} - {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: OSC32KCLK.outFreq, value: 32.768 kHz} - {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} - {id: SIRC_CLK.outFreq, value: 8 MHz} - {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} - {id: SOSCER_CLK.outFreq, value: 32.768 kHz} - {id: SOSC_CLK.outFreq, value: 32.768 kHz} - {id: Slow_clock.outFreq, value: 24 MHz} - {id: System_clock.outFreq, value: 48 MHz} settings: - {id: SCG.FIRCDIV1.scale, value: '1', locked: true} - {id: SCG.FIRCDIV3.scale, value: '1', locked: true} - {id: SCG.SIRCDIV3.scale, value: '2', locked: true} - {id: SCG.SOSCDIV3.scale, value: '1', locked: true} - {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} - {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} - {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} sources: - {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = { .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved1 = 0, .reserved2 = 0, .reserved3 = 0, #endif .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved4 = 0, #endif .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved5 = 0, #endif }; const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = { .freq = 32768U, /* System Oscillator frequency: 32768Hz */ .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ }; const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = { .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ }; const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = { .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ .trimConfig = NULL, /* Fast IRC Trim disabled */ }; const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = { .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ .prediv = 0, /* Divided by 1 */ .mult = 0, /* Multiply Factor is 16 */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { scg_sys_clk_config_t curConfig; /* Init SOSC according to board configuration. */ CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); /* Set the XTAL0 frequency based on board settings. */ CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); /* Init FIRC. */ CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); /* Init SIRC. */ CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); /* Set SCG to FIRC mode. */ CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); /* Wait for clock source switch finished. */ do { CLOCK_GetCurSysClkConfig(&curConfig); } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } /******************************************************************************* ********************* Configuration BOARD_BootClockHSRUN ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockHSRUN outputs: - {id: CLKOUT.outFreq, value: 8 MHz} - {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} - {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} - {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: OSC32KCLK.outFreq, value: 32.768 kHz} - {id: PLLDIV1_CLK.outFreq, value: 96 MHz} - {id: PLLDIV3_CLK.outFreq, value: 96 MHz} - {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} - {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} - {id: SIRC_CLK.outFreq, value: 8 MHz} - {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} - {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} - {id: SOSCER_CLK.outFreq, value: 32.768 kHz} - {id: SOSC_CLK.outFreq, value: 32.768 kHz} - {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} - {id: System_clock.outFreq, value: 96 MHz} settings: - {id: SCGMode, value: SPLL} - {id: powerMode, value: HSRUN} - {id: CLKOUTConfig, value: 'yes'} - {id: SCG.DIVSLOW.scale, value: '4'} - {id: SCG.FIRCDIV1.scale, value: '1', locked: true} - {id: SCG.FIRCDIV3.scale, value: '1', locked: true} - {id: SCG.PREDIV.scale, value: '4'} - {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} - {id: SCG.SIRCDIV1.scale, value: '1', locked: true} - {id: SCG.SIRCDIV3.scale, value: '1', locked: true} - {id: SCG.SOSCDIV1.scale, value: '1', locked: true} - {id: SCG.SOSCDIV3.scale, value: '1', locked: true} - {id: SCG.SPLLDIV1.scale, value: '1', locked: true} - {id: SCG.SPLLDIV3.scale, value: '1', locked: true} - {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} - {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} - {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} - {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} - {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} sources: - {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockHSRUN configuration ******************************************************************************/ const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = { .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved1 = 0, .reserved2 = 0, .reserved3 = 0, #endif .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved4 = 0, #endif .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved5 = 0, #endif }; const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = { .freq = 32768U, /* System Oscillator frequency: 32768Hz */ .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ }; const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = { .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ }; const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = { .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ .trimConfig = NULL, /* Fast IRC Trim disabled */ }; const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = { .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ .prediv = 3, /* Divided by 4 */ .mult = 0, /* Multiply Factor is 16 */ }; /******************************************************************************* * Code for BOARD_BootClockHSRUN configuration ******************************************************************************/ void BOARD_BootClockHSRUN(void) { scg_sys_clk_config_t curConfig; /* Init SOSC according to board configuration. */ CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); /* Set the XTAL0 frequency based on board settings. */ CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); /* Init FIRC. */ CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); /* Init SIRC. */ CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); /* Init SysPll. */ CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); /* Set HSRUN power mode. */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); SMC_SetPowerModeHsrun(SMC); while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) { } /* Set SCG to SPLL mode. */ CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); /* Wait for clock source switch finished. */ do { CLOCK_GetCurSysClkConfig(&curConfig); } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; /* Set SCG CLKOUT selection. */ CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); } /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockVLPR outputs: - {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: SIRC_CLK.outFreq, value: 8 MHz} - {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} - {id: System_clock.outFreq, value: 8 MHz} settings: - {id: SCGMode, value: SIRC} - {id: powerMode, value: VLPR} - {id: SCG.DIVSLOW.scale, value: '8'} - {id: SCG.SCSSEL.sel, value: SCG.SIRC} - {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} sources: - {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockVLPR configuration ******************************************************************************/ const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = { .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved1 = 0, .reserved2 = 0, .reserved3 = 0, #endif .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved4 = 0, #endif .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ #if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) .reserved5 = 0, #endif }; const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = { .freq = 0U, /* System Oscillator frequency: 0Hz */ .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ .workMode = kSCG_SysOscModeExt, /* Use external clock */ }; const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = { .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ }; const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = { .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ .trimConfig = NULL, /* Fast IRC Trim disabled */ }; const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = { .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ .prediv = 0, /* Divided by 1 */ .mult = 0, /* Multiply Factor is 16 */ }; /******************************************************************************* * Code for BOARD_BootClockVLPR configuration ******************************************************************************/ void BOARD_BootClockVLPR(void) { /* Init FIRC. */ CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); /* Init SIRC. */ CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); /* Allow SMC all power modes. */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); /* Set VLPR power mode. */ SMC_SetPowerModeVlpr(SMC); while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) { } /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; } ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/clock_config.h ================================================ /* * Copyright 2019 ,2021 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ /*! @brief SCG set for BOARD_BootClockRUN configuration. */ extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; /*! @brief System OSC set for BOARD_BootClockRUN configuration. */ extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; /*! @brief SIRC set for BOARD_BootClockRUN configuration. */ extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; /*! @brief FIRC set for BOARD_BootClockRUN configuration. */ extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; /*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. */ /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************* Configuration BOARD_BootClockHSRUN ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockHSRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /*! @brief SCG set for BOARD_BootClockHSRUN configuration. */ extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; /*! @brief System OSC set for BOARD_BootClockHSRUN configuration. */ extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; /*! @brief SIRC set for BOARD_BootClockHSRUN configuration. */ extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; /*! @brief FIRC set for BOARD_BootClockHSRUN configuration. */ extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; /*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. */ /******************************************************************************* * API for BOARD_BootClockHSRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockHSRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockVLPR configuration ******************************************************************************/ #define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ /*! @brief SCG set for BOARD_BootClockVLPR configuration. */ extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; /*! @brief System OSC set for BOARD_BootClockVLPR configuration. */ extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; /*! @brief SIRC set for BOARD_BootClockVLPR configuration. */ extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; /*! @brief FIRC set for BOARD_BootClockVLPR configuration. */ extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; /*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. */ /******************************************************************************* * API for BOARD_BootClockVLPR configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockVLPR(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake ================================================ set(MCU_VARIANT K32L2B31A) set(MCU_CORE ${MCU_VARIANT}) set(JLINK_DEVICE K32L2B31xxxxA) set(PYOCD_TARGET K32L2B) set(LD_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_K32L2B31VLH0A ) target_include_directories(${TARGET} PUBLIC ${MCUX_DEVICES}/K32L/periph2 ) endfunction() ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Freedom K32L2B3 url: https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 */ #ifndef BOARD_H_ #define BOARD_H_ #include "fsl_device_registers.h" #define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M // LED #define LED_PIN_CLOCK kCLOCK_PortD #define LED_GPIO GPIOD #define LED_PORT PORTD #define LED_PIN 5 #define LED_STATE_ON 0 // SW3 button1 #define BUTTON_PIN_CLOCK kCLOCK_PortC #define BUTTON_GPIO GPIOC #define BUTTON_PORT PORTC #define BUTTON_PIN 3 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_PORT LPUART0 #define UART_PIN_CLOCK kCLOCK_PortA #define UART_PIN_PORT PORTA #define UART_PIN_RX 1u #define UART_PIN_TX 2u #define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */ #define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */ #define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) static inline void BOARD_InitBootPins(void) { /* PORTA1 (pin 23) is configured as LPUART0_RX */ PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); /* PORTA2 (pin 24) is configured as LPUART0_TX */ PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); SIM->SOPT5 = ((SIM->SOPT5 & /* Mask bits to zero which are setting */ (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); BOARD_BootClockRUN(); SystemCoreClockUpdate(); CLOCK_SetLpuart0Clock(1); } #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk ================================================ MCU_VARIANT = K32L2B31A CFLAGS += -DCPU_K32L2B31VLH0A # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/gcc/K32L2B31xxxxA_flash.ld INC += \ $(TOP)/$(MCUX_DEVICES)/K32L/periph2 SRC_C += \ $(BOARD_PATH)/clock_config.c # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA # For flash-pyocd target PYOCD_TARGET = K32L2B # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2b/clock_config.c ================================================ /* * Copyright 2019 ,2021 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to setup clock using clock driver functions: * * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock * and flash clock are in allowed range during clock mode switch. * * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. * * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. * * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v7.0 processor: K32L2B31xxxxA package_id: K32L2B31VLH0A mcu_data: ksdk2_0 processor_version: 9.0.0 board: FRDM-K32L2B * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_smc.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ #define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ #define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ #define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ /******************************************************************************* * Variables ******************************************************************************/ /* System clock frequency. */ //extern uint32_t SystemCoreClock; /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockRUN(); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockRUN called_from_default_init: true outputs: - {id: Bus_clock.outFreq, value: 24 MHz} - {id: Core_clock.outFreq, value: 48 MHz} - {id: Flash_clock.outFreq, value: 24 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGIRCLK.outFreq, value: 8 MHz} - {id: MCGPCLK.outFreq, value: 48 MHz} - {id: System_clock.outFreq, value: 48 MHz} settings: - {id: MCGMode, value: HIRC} - {id: MCG.CLKS.sel, value: MCG.HIRC} - {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} - {id: MCG_C2_RANGE0_CFG, value: Very_high} - {id: MCG_MC_HIRCEN_CFG, value: Enabled} - {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} - {id: OSC_CR_ERCLKEN_CFG, value: Enabled} - {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} - {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} - {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} - {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} - {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} - {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} - {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} - {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} sources: - {id: MCG.HIRC.outFreq, value: 48 MHz} - {id: OSC.OSC.outFreq, value: 32 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ .hircEnableInNotHircMode = true, /* HIRC source is enabled */ }; const sim_clock_config_t simConfig_BOARD_BootClockRUN = { .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ }; const osc_config_t oscConfig_BOARD_BootClockRUN = { .freq = 0U, /* Oscillator frequency: 0Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ .oscerConfig = { .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ } }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Set MCG to HIRC mode. */ CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockVLPR outputs: - {id: Bus_clock.outFreq, value: 1 MHz} - {id: Core_clock.outFreq, value: 2 MHz} - {id: Flash_clock.outFreq, value: 1 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGIRCLK.outFreq, value: 2 MHz} - {id: System_clock.outFreq, value: 2 MHz} settings: - {id: MCGMode, value: LIRC2M} - {id: powerMode, value: VLPR} - {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} - {id: RTCCLKOUTConfig, value: 'yes'} - {id: SIM.OUTDIV4.scale, value: '2', locked: true} - {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} sources: - {id: MCG.LIRC.outFreq, value: 2 MHz} - {id: OSC.OSC.outFreq, value: 32.768 kHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockVLPR configuration ******************************************************************************/ const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = { .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 MHz clock selected */ .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ .hircEnableInNotHircMode = false, /* HIRC source is not enabled */ }; const sim_clock_config_t simConfig_BOARD_BootClockVLPR = { .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ }; const osc_config_t oscConfig_BOARD_BootClockVLPR = { .freq = 0U, /* Oscillator frequency: 0Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ .oscerConfig = { .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ } }; /******************************************************************************* * Code for BOARD_BootClockVLPR configuration ******************************************************************************/ void BOARD_BootClockVLPR(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Set MCG to LIRC2M mode. */ CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); /* Set VLPR power mode. */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) SMC_SetPowerModeVlpr(SMC, false); #else SMC_SetPowerModeVlpr(SMC); #endif while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) { } /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; } ================================================ FILE: hw/bsp/kinetis_k32l/boards/frdm_k32l2b/clock_config.h ================================================ /* * Copyright 2019 ,2021 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ /*! @brief MCG lite set for BOARD_BootClockRUN configuration. */ extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; /*! @brief SIM module set for BOARD_BootClockRUN configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; /*! @brief OSC set for BOARD_BootClockRUN configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockVLPR configuration ******************************************************************************/ #define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ /*! @brief MCG lite set for BOARD_BootClockVLPR configuration. */ extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; /*! @brief SIM module set for BOARD_BootClockVLPR configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; /*! @brief OSC set for BOARD_BootClockVLPR configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockVLPR; /******************************************************************************* * API for BOARD_BootClockVLPR configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockVLPR(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/board.cmake ================================================ set(MCU_VARIANT K32L2B31A) set(MCU_CORE ${MCU_VARIANT}) set(JLINK_DEVICE K32L2B31xxxxA) set(PYOCD_TARGET K32L2B) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c ) target_compile_definitions(${TARGET} PUBLIC CPU_K32L2B31VLH0A ) target_include_directories(${TARGET} PUBLIC ${MCUX_DEVICES}/K32L/periph2 ) endfunction() ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Kuiic url: https://github.com/nxf58843/kuiic */ #ifndef BOARD_H_ #define BOARD_H_ #include "fsl_device_registers.h" #define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M // LED #define LED_PIN_CLOCK kCLOCK_PortA #define LED_GPIO GPIOA #define LED_PORT PORTA #define LED_PIN 2 #define LED_STATE_ON 1 // UART #define UART_PORT LPUART1 #define UART_PIN_RX 3u #define UART_PIN_TX 0u #define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) static inline void BOARD_InitBootPins(void) { /* PORTC3 is configured as LPUART0_RX */ PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); /* PORTA2 (pin 24) is configured as LPUART0_TX */ PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); SIM->SOPT5 = ((SIM->SOPT5 & /* Mask bits to zero which are setting */ (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); CLOCK_SetLpuart1Clock(1); } #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/board.mk ================================================ MCU_VARIANT = K32L2B31A CFLAGS += -DCPU_K32L2B31VLH0A # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/kuiic.ld INC += \ $(TOP)/$(MCUX_DEVICES)/K32L/periph2 SRC_C += \ $(BOARD_PATH)/clock_config.c # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA # For flash-pyocd target PYOCD_TARGET = K32L2B # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/clock_config.c ================================================ #include "clock_config.h" #include "fsl_clock.h" /******************************************************************************* * Variables ******************************************************************************/ /* System clock frequency. */ // extern uint32_t SystemCoreClock; /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ .hircEnableInNotHircMode = true, /* HIRC source is enabled */ }; const sim_clock_config_t simConfig_BOARD_BootClockRUN = { .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Set MCG to HIRC mode. */ CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/clock_config.h ================================================ #ifndef CLOCK_CONFIG_H #define CLOCK_CONFIG_H /******************************************************************************* * Definitions ******************************************************************************/ #define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ #define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ #define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ void BOARD_BootClockRUN(void); #endif ================================================ FILE: hw/bsp/kinetis_k32l/boards/kuiic/kuiic.ld ================================================ /* ** ################################################################### ** Processors: K32L2B31VFM0A ** K32L2B31VFT0A ** K32L2B31VLH0A ** K32L2B31VMP0A ** ** Compiler: GNU C Compiler ** Reference manual: K32L2B3xRM, Rev.0, July 2019 ** Version: rev. 1.0, 2019-07-30 ** Build: b190930 ** ** Abstract: ** Linker file for the GNU C Compiler ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2019 NXP ** All rights reserved. ** ** SPDX-License-Identifier: BSD-3-Clause ** ** http: www.nxp.com ** mail: support@nxp.com ** ** ################################################################### */ /* Entry Point */ ENTRY(Reset_Handler) HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; /* Specify the memory areas */ MEMORY { m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 } /* Define output sections */ SECTIONS { /* The startup code goes first into internal flash */ .interrupts : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } > m_interrupts .flash_config : { . = ALIGN(4); KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ . = ALIGN(4); } > m_flash_config /* The program code and other data goes into internal flash */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } > m_text .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } > m_text .ctors : { __CTOR_LIST__ = .; /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) __CTOR_END__ = .; } > m_text .dtors : { __DTOR_LIST__ = .; KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) __DTOR_END__ = .; } > m_text .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } > m_text .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } > m_text .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } > m_text __etext = .; /* define a global symbol at end of code */ __DATA_ROM = .; /* Symbol is used by startup for data initialization */ /* reserve MTB memory at the beginning of m_data */ .mtb : /* MTB buffer address as defined by the hardware */ { . = ALIGN(8); _mtb_start = .; KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ . = ALIGN(8); _mtb_end = .; } > m_data .data : AT(__DATA_ROM) { . = ALIGN(4); __DATA_RAM = .; __data_start__ = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ KEEP(*(.jcr*)) . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ } > m_data __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") /* Uninitialized data section */ .bss : { /* This is used by the startup in order to initialize the .bss section */ . = ALIGN(4); __START_BSS = .; __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; __END_BSS = .; } > m_data .heap : { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; . += HEAP_SIZE; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > m_data .stack : { . = ALIGN(8); . += STACK_SIZE; } > m_data /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data) + LENGTH(m_data); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") } ================================================ FILE: hw/bsp/kinetis_k32l/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2020, Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_clock.h" #include "fsl_lpuart.h" #include "clock_config.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { tud_int_handler(0); } void board_init(void) { /* Enable port clocks for GPIO pins */ CLOCK_EnableClock(kCLOCK_PortA); CLOCK_EnableClock(kCLOCK_PortB); CLOCK_EnableClock(kCLOCK_PortC); CLOCK_EnableClock(kCLOCK_PortD); CLOCK_EnableClock(kCLOCK_PortE); BOARD_InitBootPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); #ifdef BUTTON_PIN gpio_pin_config_t button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); const port_pin_config_t BUTTON_CFG = { kPORT_PullUp, kPORT_FastSlewRate, kPORT_PassiveFilterDisable, #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN kPORT_OpenDrainDisable, #endif kPORT_LowDriveStrength, kPORT_MuxAsGpio, #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK kPORT_UnlockRegister #endif }; PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); #endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif lpuart_config_t uart_config; LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ); // USB CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { #ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); #else return 0; #endif } int board_uart_read(uint8_t* buf, int len) { #if 0 /* Use this version if want the LED to blink during BOARD=board_test, without having to hit a key. */ if( 0U != (kLPUART_RxDataRegFullFlag & LPUART_GetStatusFlags( UART_PORT )) ) { LPUART_ReadBlocking(UART_PORT, buf, len); return len; } return( 0 ); #else /* Wait for 'len' characters to come in */ LPUART_ReadBlocking(UART_PORT, buf, len); return len; #endif } int board_uart_write(void const* buf, int len) { LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/kinetis_k32l/family.cmake ================================================ include_guard() set(MCUX_CORE ${TOP}/hw/mcu/nxp/mcuxsdk-core) set(MCUX_DEVICES ${TOP}/hw/mcu/nxp/mcux-devices-kinetis) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver ${MCUX_CORE}/drivers/gpio/fsl_gpio.c ${MCUX_CORE}/drivers/common/fsl_common_arm.c ${MCUX_CORE}/drivers/lpuart/fsl_lpuart.c # mcu ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/system_${MCU_VARIANT}.c ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/drivers/fsl_clock.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_DIR}/CMSIS/Core/Include ${MCUX_CORE}/drivers/common ${MCUX_CORE}/drivers/gpio ${MCUX_CORE}/drivers/lpuart ${MCUX_CORE}/drivers/port ${MCUX_CORE}/drivers/smc ${MCUX_DEVICES}/K32L/${MCU_VARIANT} ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/drivers ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K32L) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/khci/dcd_khci.c ${TOP}/src/portable/nxp/khci/hcd_khci.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles ) set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_flash_jlink(${TARGET}) family_add_bin_hex(${TARGET}) family_flash_teensy(${TARGET}) endfunction() ================================================ FILE: hw/bsp/kinetis_k32l/family.mk ================================================ UF2_FAMILY_ID = 0x7f83e793 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus MCUX_CORE = hw/mcu/nxp/mcuxsdk-core MCUX_DEVICES = hw/mcu/nxp/mcux-devices-kinetis CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L LDFLAGS_GCC += \ -nostartfiles \ -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/system_$(MCU_VARIANT).c \ $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(MCUX_CORE)/drivers/gpio/fsl_gpio.c \ $(MCUX_CORE)/drivers/lpuart/fsl_lpuart.c \ $(MCUX_CORE)/drivers/common/fsl_common_arm.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(MCUX_DEVICES)/K32L/$(MCU_VARIANT) \ $(TOP)/$(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/drivers \ $(TOP)/$(MCUX_CORE)/drivers/common \ $(TOP)/$(MCUX_CORE)/drivers/gpio \ $(TOP)/$(MCUX_CORE)/drivers/lpuart \ $(TOP)/$(MCUX_CORE)/drivers/port \ $(TOP)/$(MCUX_CORE)/drivers/smc SRC_S += $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/gcc/startup_$(MCU_VARIANT).S ================================================ FILE: hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); } /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** !!Configuration name: BOARD_BootClockRUN outputs: - {id: Bus_clock.outFreq, value: 24 MHz} - {id: Core_clock.outFreq, value: 48 MHz, locked: true, accuracy: '0.001'} - {id: ERCLK32K.outFreq, value: 1 kHz} - {id: Flash_clock.outFreq, value: 24 MHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGIRCLK.outFreq, value: 32.768 kHz} - {id: OSCERCLK.outFreq, value: 8 MHz} - {id: PLLFLLCLK.outFreq, value: 48 MHz} - {id: System_clock.outFreq, value: 48 MHz} settings: - {id: MCGMode, value: PEE} - {id: MCG.FCRDIV.scale, value: '1', locked: true} - {id: MCG.FRDIV.scale, value: '32'} - {id: MCG.IREFS.sel, value: MCG.FRDIV} - {id: MCG.PLLS.sel, value: MCG.PLL} - {id: MCG.PRDIV.scale, value: '2', locked: true} - {id: MCG.VDIV.scale, value: '24', locked: true} - {id: MCG_C1_IRCLKEN_CFG, value: Enabled} - {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} - {id: MCG_C2_RANGE0_CFG, value: High} - {id: MCG_C2_RANGE0_FRDIV_CFG, value: High} - {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} - {id: OSC_CR_ERCLKEN_CFG, value: Enabled} - {id: SIM.CLKOUTSEL.sel, value: SIM.OUTDIV4} - {id: SIM.OSC32KSEL.sel, value: PMC.LPOCLK} - {id: SIM.OUTDIV1.scale, value: '2'} - {id: SIM.PLLFLLSEL.sel, value: SIM.MCGPLLCLK_DIV2} - {id: SIM.TPMSRCSEL.sel, value: SIM.PLLFLLSEL} - {id: SIM.UART0SRCSEL.sel, value: SIM.PLLFLLSEL} - {id: SIM.USBSRCSEL.sel, value: SIM.PLLFLLSEL} sources: - {id: OSC.OSC.outFreq, value: 8 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ /******************************************************************************* * Variables for BOARD_BootClockRUN configuration ******************************************************************************/ const mcg_config_t mcgConfig_BOARD_BootClockRUN = { .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ .drs = kMCG_DrsLow, /* Low frequency range */ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ .pll0Config = { .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ .prdiv = 0x1U, /* PLL Reference divider: divided by 2 */ .vdiv = 0x0U, /* VCO divider: multiplied by 24 */ }, }; const sim_clock_config_t simConfig_BOARD_BootClockRUN = { .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ .clkdiv1 = 0x10010000U, /* SIM_CLKDIV1 - OUTDIV1: /2, OUTDIV4: /2 */ }; const osc_config_t oscConfig_BOARD_BootClockRUN = { .freq = 8000000U, /* Oscillator frequency: 8000000Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ .oscerConfig = { .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ } }; /******************************************************************************* * Code for BOARD_BootClockRUN configuration ******************************************************************************/ void BOARD_BootClockRUN(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Initializes OSC0 according to board configuration. */ CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); /* Configure FLL external reference divider (FRDIV). */ CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); /* Set MCG to PEE mode. */ CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &mcgConfig_BOARD_BootClockRUN.pll0Config); /* Configure the Internal Reference clock (MCGIRCLK). */ CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, mcgConfig_BOARD_BootClockRUN.ircs, mcgConfig_BOARD_BootClockRUN.fcrdiv); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; } /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** !!Configuration name: BOARD_BootClockVLPR outputs: - {id: Bus_clock.outFreq, value: 800 kHz} - {id: Core_clock.outFreq, value: 4 MHz} - {id: ERCLK32K.outFreq, value: 1 kHz} - {id: Flash_clock.outFreq, value: 800 kHz} - {id: LPO_clock.outFreq, value: 1 kHz} - {id: MCGIRCLK.outFreq, value: 4 MHz} - {id: System_clock.outFreq, value: 4 MHz} settings: - {id: MCGMode, value: BLPI} - {id: powerMode, value: VLPR} - {id: MCG.CLKS.sel, value: MCG.IRCS} - {id: MCG.FCRDIV.scale, value: '1', locked: true} - {id: MCG.FRDIV.scale, value: '32'} - {id: MCG.IRCS.sel, value: MCG.FCRDIV} - {id: MCG_C1_IRCLKEN_CFG, value: Enabled} - {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} - {id: MCG_C2_RANGE0_CFG, value: High} - {id: MCG_C2_RANGE0_FRDIV_CFG, value: High} - {id: SIM.OSC32KSEL.sel, value: PMC.LPOCLK} - {id: SIM.OUTDIV4.scale, value: '5'} sources: - {id: OSC.OSC.outFreq, value: 8 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ /******************************************************************************* * Variables for BOARD_BootClockVLPR configuration ******************************************************************************/ const mcg_config_t mcgConfig_BOARD_BootClockVLPR = { .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */ .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ .drs = kMCG_DrsLow, /* Low frequency range */ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ .pll0Config = { .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ .vdiv = 0x0U, /* VCO divider: multiplied by 24 */ }, }; const sim_clock_config_t simConfig_BOARD_BootClockVLPR = { .pllFllSel = SIM_PLLFLLSEL_MCGFLLCLK_CLK, /* PLLFLL select: MCGFLLCLK clock */ .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /5 */ }; const osc_config_t oscConfig_BOARD_BootClockVLPR = { .freq = 0U, /* Oscillator frequency: 0Hz */ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ .oscerConfig = { .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ } }; /******************************************************************************* * Code for BOARD_BootClockVLPR configuration ******************************************************************************/ void BOARD_BootClockVLPR(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); /* Set MCG to BLPI mode. */ CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv, mcgConfig_BOARD_BootClockVLPR.ircs, mcgConfig_BOARD_BootClockVLPR.irclkEnableMode); /* Set the clock configuration in SIM module. */ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); /* Set VLPR power mode. */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) SMC_SetPowerModeVlpr(SMC, false); #else SMC_SetPowerModeVlpr(SMC); #endif while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) { } /* Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; } ================================================ FILE: hw/bsp/kinetis_kl/boards/frdm_kl25z/clock_config.h ================================================ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * o 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. * * o Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #define BOARD_XTAL0_CLK_HZ 8000000U /*!< Board xtal0 frequency in Hz */ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ /*! @brief MCG set for BOARD_BootClockRUN configuration. */ extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; /*! @brief SIM module set for BOARD_BootClockRUN configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; /*! @brief OSC set for BOARD_BootClockRUN configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************* Configuration BOARD_BootClockVLPR *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockVLPR configuration ******************************************************************************/ #define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ /*! @brief MCG set for BOARD_BootClockVLPR configuration. */ extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; /*! @brief SIM module set for BOARD_BootClockVLPR configuration. */ extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; /*! @brief OSC set for BOARD_BootClockVLPR configuration. */ extern const osc_config_t oscConfig_BOARD_BootClockVLPR; /******************************************************************************* * API for BOARD_BootClockVLPR configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockVLPR(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/kinetis_kl/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2020, Koji Kitayama * * 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. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "board.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_clock.h" #include "fsl_lpsci.h" #include "clock_config.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); #endif } void board_init(void) { BOARD_BootClockRUN(); SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif // LED CLOCK_EnableClock(LED_PIN_CLOCK); PORT_SetPinMux(LED_PIN_PORT, LED_PIN, LED_PIN_FUNCTION); gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; GPIO_PinInit(LED_PORT, LED_PIN, &led_config); board_led_write(false); #if defined(BUTTON_PORT) && defined(BUTTON_PIN) // Button CLOCK_EnableClock(BUTTON_PIN_CLOCK); port_pin_config_t button_port = { .pullSelect = kPORT_PullUp, .mux = BUTTON_PIN_FUNCTION, }; PORT_SetPinConfig(BUTTON_PIN_PORT, BUTTON_PIN, &button_port); gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); #endif // UART CLOCK_EnableClock(UART_PIN_CLOCK); PORT_SetPinMux(UART_PIN_PORT, UART_PIN_RX, UART_PIN_FUNCTION); PORT_SetPinMux(UART_PIN_PORT, UART_PIN_TX, UART_PIN_FUNCTION); SIM->SOPT5 = ((SIM->SOPT5 & (~(SIM_SOPT5_UART0TXSRC_MASK | SIM_SOPT5_UART0RXSRC_MASK))) | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX) | SIM_SOPT5_UART0RXSRC(SOPT5_UART0RXSRC_UART_RX) ); lpsci_config_t uart_config; CLOCK_SetLpsci0Clock(1); LPSCI_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; LPSCI_Init(UART_PORT, &uart_config, CLOCK_GetPllFllSelClkFreq()); // USB CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { #if defined(BUTTON_PORT) && defined(BUTTON_PIN) return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); #endif return 0; } int board_uart_read(uint8_t* buf, int len) { LPSCI_ReadBlocking(UART_PORT, buf, len); return len; } int board_uart_write(void const * buf, int len) { LPSCI_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/kinetis_kl/family.cmake ================================================ include_guard() if (NOT BOARD) message(FATAL_ERROR "BOARD not specified") endif () set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/drivers/gpio/fsl_gpio.c ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c ${SDK_DIR}/drivers/uart/fsl_uart.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_DIR}/CMSIS/Core/Include ${SDK_DIR}/devices/${MCU_VARIANT} ${SDK_DIR}/devices/${MCU_VARIANT}/drivers ${SDK_DIR}/drivers/common ${SDK_DIR}/drivers/gpio ${SDK_DIR}/drivers/lpsci ${SDK_DIR}/drivers/port ${SDK_DIR}/drivers/smc ${SDK_DIR}/drivers/uart ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_KL) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.c ${TOP}/src/portable/nxp/khci/hcd_khci.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/kinetis_kl/family.mk ================================================ SDK_DIR = hw/mcu/nxp/mcux-sdk MCU_DIR = $(SDK_DIR)/devices/$(MCU) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_KL \ LDFLAGS += \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 LDFLAGS_GCC += \ -nostartfiles \ -specs=nosys.specs -specs=nano.specs \ SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ $(MCU_DIR)/system_$(MCU).c \ $(MCU_DIR)/drivers/fsl_clock.c \ $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ $(SDK_DIR)/drivers/lpsci/fsl_lpsci.c \ $(SDK_DIR)/drivers/uart/fsl_uart.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/gpio \ $(TOP)/$(SDK_DIR)/drivers/lpsci \ $(TOP)/$(SDK_DIR)/drivers/port \ $(TOP)/$(SDK_DIR)/drivers/smc \ $(TOP)/$(SDK_DIR)/drivers/uart \ ================================================ FILE: hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld ================================================ /* ** ################################################################### ** Processors: MKL25Z128VFM4 ** MKL25Z128VFT4 ** MKL25Z128VLH4 ** MKL25Z128VLK4 ** ** Compiler: GNU C Compiler ** Reference manual: KL25P80M48SF0RM, Rev.3, Sep 2012 ** Version: rev. 2.5, 2015-02-19 ** Build: b170214 ** ** Abstract: ** Linker file for the GNU C Compiler ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** ** o Redistributions of source code must retain the above copyright notice, this list ** of conditions and the following disclaimer. ** ** o 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. ** ** o Neither the name of the copyright holder nor the names of its ** contributors may be used to endorse or promote products derived from this ** software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ** http: www.nxp.com ** mail: support@nxp.com ** ** ################################################################### */ /* Entry Point */ ENTRY(Reset_Handler) HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0200 : 0x0; /* Specify the memory areas */ MEMORY { m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000200 m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010 m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0 m_data (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000 } /* Define output sections */ SECTIONS { /* The startup code goes first into internal flash */ .interrupts : { __VECTOR_TABLE = .; . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } > m_interrupts .flash_config : { . = ALIGN(4); KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ . = ALIGN(4); } > m_flash_config /* The program code and other data goes into internal flash */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } > m_text .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } > m_text .ctors : { __CTOR_LIST__ = .; /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) __CTOR_END__ = .; } > m_text .dtors : { __DTOR_LIST__ = .; KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) __DTOR_END__ = .; } > m_text .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } > m_text .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } > m_text .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } > m_text __etext = .; /* define a global symbol at end of code */ __DATA_ROM = .; /* Symbol is used by startup for data initialization */ /* reserve MTB memory at the beginning of m_data */ .mtb : /* MTB buffer address as defined by the hardware */ { . = ALIGN(8); _mtb_start = .; KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ . = ALIGN(8); _mtb_end = .; } > m_data .interrupts_ram : { . = ALIGN(4); __VECTOR_RAM__ = .; __interrupts_ram_start__ = .; /* Create a global symbol at data start */ *(.m_interrupts_ram) /* This is a user defined section */ . += M_VECTOR_RAM_SIZE; . = ALIGN(4); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > m_data __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; .data : AT(__DATA_ROM) { . = ALIGN(4); __DATA_RAM = .; __data_start__ = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ KEEP(*(.jcr*)) . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ } > m_data __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") /* Uninitialized data section */ .bss : { /* This is used by the startup in order to initialize the .bss section */ . = ALIGN(4); __START_BSS = .; __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; __END_BSS = .; } > m_data .heap : { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; . += HEAP_SIZE; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > m_data .stack : { . = ALIGN(8); . += STACK_SIZE; } > m_data /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data) + LENGTH(m_data); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") } ================================================ FILE: hw/bsp/kinetis_kl/gcc/startup_MKL25Z4.S ================================================ /* ---------------------------------------------------------------------------------------*/ /* @file: startup_MKL25Z4.s */ /* @purpose: CMSIS Cortex-M0P Core Device Startup File */ /* MKL25Z4 */ /* @version: 2.5 */ /* @date: 2015-2-19 */ /* @build: b170112 */ /* ---------------------------------------------------------------------------------------*/ /* */ /* Copyright (c) 1997 - 2016, Freescale Semiconductor, Inc. */ /* Copyright 2016 - 2017 NXP */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ /* o Redistributions of source code must retain the above copyright notice, this list */ /* of conditions and the following disclaimer. */ /* */ /* o 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. */ /* */ /* o Neither the name of the copyright holder nor the names of its */ /* contributors may be used to endorse or promote products derived from this */ /* software without specific prior written permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ /*****************************************************************************/ /* Version: GCC for ARM Embedded Processors */ /*****************************************************************************/ .syntax unified .arch armv6-m .section .isr_vector, "a" .align 2 .globl __isr_vector __isr_vector: .long __StackTop /* Top of Stack */ .long Reset_Handler /* Reset Handler */ .long NMI_Handler /* NMI Handler*/ .long HardFault_Handler /* Hard Fault Handler*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long SVC_Handler /* SVCall Handler*/ .long 0 /* Reserved*/ .long 0 /* Reserved*/ .long PendSV_Handler /* PendSV Handler*/ .long SysTick_Handler /* SysTick Handler*/ /* External Interrupts*/ .long DMA0_IRQHandler /* DMA channel 0 transfer complete*/ .long DMA1_IRQHandler /* DMA channel 1 transfer complete*/ .long DMA2_IRQHandler /* DMA channel 2 transfer complete*/ .long DMA3_IRQHandler /* DMA channel 3 transfer complete*/ .long Reserved20_IRQHandler /* Reserved interrupt*/ .long FTFA_IRQHandler /* Command complete and read collision*/ .long LVD_LVW_IRQHandler /* Low-voltage detect, low-voltage warning*/ .long LLWU_IRQHandler /* Low leakage wakeup Unit*/ .long I2C0_IRQHandler /* I2C0 interrupt*/ .long I2C1_IRQHandler /* I2C1 interrupt*/ .long SPI0_IRQHandler /* SPI0 single interrupt vector for all sources*/ .long SPI1_IRQHandler /* SPI1 single interrupt vector for all sources*/ .long UART0_IRQHandler /* UART0 status and error*/ .long UART1_IRQHandler /* UART1 status and error*/ .long UART2_IRQHandler /* UART2 status and error*/ .long ADC0_IRQHandler /* ADC0 interrupt*/ .long CMP0_IRQHandler /* CMP0 interrupt*/ .long TPM0_IRQHandler /* TPM0 single interrupt vector for all sources*/ .long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/ .long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/ .long RTC_IRQHandler /* RTC alarm*/ .long RTC_Seconds_IRQHandler /* RTC seconds*/ .long PIT_IRQHandler /* PIT interrupt*/ .long Reserved39_IRQHandler /* Reserved interrupt*/ .long USB0_IRQHandler /* USB0 interrupt*/ .long DAC0_IRQHandler /* DAC0 interrupt*/ .long TSI0_IRQHandler /* TSI0 interrupt*/ .long MCG_IRQHandler /* MCG interrupt*/ .long LPTMR0_IRQHandler /* LPTMR0 interrupt*/ .long Reserved45_IRQHandler /* Reserved interrupt*/ .long PORTA_IRQHandler /* PORTA Pin detect*/ .long PORTD_IRQHandler /* PORTD Pin detect*/ .size __isr_vector, . - __isr_vector /* Flash Configuration */ .section .FlashConfig, "a" .long 0xFFFFFFFF .long 0xFFFFFFFF .long 0xFFFFFFFF .long 0xFFFFFFFE .text .thumb /* Reset Handler */ .thumb_func .align 2 .globl Reset_Handler .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: cpsid i /* Mask interrupts */ .equ VTOR, 0xE000ED08 ldr r0, =VTOR ldr r1, =__isr_vector str r1, [r0] ldr r2, [r1] msr msp, r2 #ifndef __NO_SYSTEM_INIT ldr r0,=SystemInit blx r0 #endif /* Loop to copy data from read only memory to RAM. The ranges * of copy from/to are specified by following symbols evaluated in * linker script. * __etext: End of code section, i.e., begin of data sections to copy from. * __data_start__/__data_end__: RAM address range that data should be * copied to. Both must be aligned to 4 bytes boundary. */ ldr r1, =__etext ldr r2, =__data_start__ ldr r3, =__data_end__ subs r3, r2 ble .LC0 .LC1: subs r3, 4 ldr r0, [r1,r3] str r0, [r2,r3] bgt .LC1 .LC0: #ifdef __STARTUP_CLEAR_BSS /* This part of work usually is done in C library startup code. Otherwise, * define this macro to enable it in this startup. * * Loop to zero out BSS section, which uses following symbols * in linker script: * __bss_start__: start of BSS section. Must align to 4 * __bss_end__: end of BSS section. Must align to 4 */ ldr r1, =__bss_start__ ldr r2, =__bss_end__ subs r2, r1 ble .LC3 movs r0, 0 .LC2: str r0, [r1, r2] subs r2, 4 bge .LC2 .LC3: #endif cpsie i /* Unmask interrupts */ #ifndef __START #define __START _start #endif #ifndef __ATOLLIC__ ldr r0,=__START blx r0 #else ldr r0,=__libc_init_array blx r0 ldr r0,=main bx r0 #endif .pool .size Reset_Handler, . - Reset_Handler .align 1 .thumb_func .weak DefaultISR .type DefaultISR, %function DefaultISR: ldr r0, =DefaultISR bx r0 .size DefaultISR, . - DefaultISR .align 1 .thumb_func .weak NMI_Handler .type NMI_Handler, %function NMI_Handler: ldr r0,=NMI_Handler bx r0 .size NMI_Handler, . - NMI_Handler .align 1 .thumb_func .weak HardFault_Handler .type HardFault_Handler, %function HardFault_Handler: ldr r0,=HardFault_Handler bx r0 .size HardFault_Handler, . - HardFault_Handler .align 1 .thumb_func .weak SVC_Handler .type SVC_Handler, %function SVC_Handler: ldr r0,=SVC_Handler bx r0 .size SVC_Handler, . - SVC_Handler .align 1 .thumb_func .weak PendSV_Handler .type PendSV_Handler, %function PendSV_Handler: ldr r0,=PendSV_Handler bx r0 .size PendSV_Handler, . - PendSV_Handler .align 1 .thumb_func .weak SysTick_Handler .type SysTick_Handler, %function SysTick_Handler: ldr r0,=SysTick_Handler bx r0 .size SysTick_Handler, . - SysTick_Handler .align 1 .thumb_func .weak DMA0_IRQHandler .type DMA0_IRQHandler, %function DMA0_IRQHandler: ldr r0,=DMA0_DriverIRQHandler bx r0 .size DMA0_IRQHandler, . - DMA0_IRQHandler .align 1 .thumb_func .weak DMA1_IRQHandler .type DMA1_IRQHandler, %function DMA1_IRQHandler: ldr r0,=DMA1_DriverIRQHandler bx r0 .size DMA1_IRQHandler, . - DMA1_IRQHandler .align 1 .thumb_func .weak DMA2_IRQHandler .type DMA2_IRQHandler, %function DMA2_IRQHandler: ldr r0,=DMA2_DriverIRQHandler bx r0 .size DMA2_IRQHandler, . - DMA2_IRQHandler .align 1 .thumb_func .weak DMA3_IRQHandler .type DMA3_IRQHandler, %function DMA3_IRQHandler: ldr r0,=DMA3_DriverIRQHandler bx r0 .size DMA3_IRQHandler, . - DMA3_IRQHandler .align 1 .thumb_func .weak I2C0_IRQHandler .type I2C0_IRQHandler, %function I2C0_IRQHandler: ldr r0,=I2C0_DriverIRQHandler bx r0 .size I2C0_IRQHandler, . - I2C0_IRQHandler .align 1 .thumb_func .weak I2C1_IRQHandler .type I2C1_IRQHandler, %function I2C1_IRQHandler: ldr r0,=I2C1_DriverIRQHandler bx r0 .size I2C1_IRQHandler, . - I2C1_IRQHandler .align 1 .thumb_func .weak SPI0_IRQHandler .type SPI0_IRQHandler, %function SPI0_IRQHandler: ldr r0,=SPI0_DriverIRQHandler bx r0 .size SPI0_IRQHandler, . - SPI0_IRQHandler .align 1 .thumb_func .weak SPI1_IRQHandler .type SPI1_IRQHandler, %function SPI1_IRQHandler: ldr r0,=SPI1_DriverIRQHandler bx r0 .size SPI1_IRQHandler, . - SPI1_IRQHandler .align 1 .thumb_func .weak UART0_IRQHandler .type UART0_IRQHandler, %function UART0_IRQHandler: ldr r0,=UART0_DriverIRQHandler bx r0 .size UART0_IRQHandler, . - UART0_IRQHandler .align 1 .thumb_func .weak UART1_IRQHandler .type UART1_IRQHandler, %function UART1_IRQHandler: ldr r0,=UART1_DriverIRQHandler bx r0 .size UART1_IRQHandler, . - UART1_IRQHandler .align 1 .thumb_func .weak UART2_IRQHandler .type UART2_IRQHandler, %function UART2_IRQHandler: ldr r0,=UART2_DriverIRQHandler bx r0 .size UART2_IRQHandler, . - UART2_IRQHandler /* Macro to define default handlers. Default handler * will be weak symbol and just dead loops. They can be * overwritten by other handlers */ .macro def_irq_handler handler_name .weak \handler_name .set \handler_name, DefaultISR .endm /* Exception Handlers */ def_irq_handler DMA0_DriverIRQHandler def_irq_handler DMA1_DriverIRQHandler def_irq_handler DMA2_DriverIRQHandler def_irq_handler DMA3_DriverIRQHandler def_irq_handler Reserved20_IRQHandler def_irq_handler FTFA_IRQHandler def_irq_handler LVD_LVW_IRQHandler def_irq_handler LLWU_IRQHandler def_irq_handler I2C0_DriverIRQHandler def_irq_handler I2C1_DriverIRQHandler def_irq_handler SPI0_DriverIRQHandler def_irq_handler SPI1_DriverIRQHandler def_irq_handler UART0_DriverIRQHandler def_irq_handler UART1_DriverIRQHandler def_irq_handler UART2_DriverIRQHandler def_irq_handler ADC0_IRQHandler def_irq_handler CMP0_IRQHandler def_irq_handler TPM0_IRQHandler def_irq_handler TPM1_IRQHandler def_irq_handler TPM2_IRQHandler def_irq_handler RTC_IRQHandler def_irq_handler RTC_Seconds_IRQHandler def_irq_handler PIT_IRQHandler def_irq_handler Reserved39_IRQHandler def_irq_handler USB0_IRQHandler def_irq_handler DAC0_IRQHandler def_irq_handler TSI0_IRQHandler def_irq_handler MCG_IRQHandler def_irq_handler LPTMR0_IRQHandler def_irq_handler Reserved45_IRQHandler def_irq_handler PORTA_IRQHandler def_irq_handler PORTD_IRQHandler .end ================================================ FILE: hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #else #define configASSERT( x ) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlash128 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash128 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash128 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash128 __exidx_end = .; _etext = .; /* DATA section for RamUsb2 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamUsb2) *(.data.$RAM2) *(.data.$RamUsb2) *(.data.$RAM2.*) *(.data.$RamUsb2.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamUsb2 AT>MFlash128 /* MAIN DATA SECTION */ .uninit_RESERVED (NOLOAD) : { . = ALIGN(4) ; KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc8 /* Main DATA section (RamLoc8) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc8 AT>MFlash128 /* BSS section for RamUsb2 */ .bss_RAM2 : { . = ALIGN(4) ; PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2) *(.bss.$RamUsb2) *(.bss.$RAM2.*) *(.bss.$RamUsb2.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamUsb2 /* MAIN BSS SECTION */ .bss : { . = ALIGN(4) ; _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); } > RamLoc8 /* NOINIT section for RamUsb2 */ .noinit_RAM2 (NOLOAD) : { . = ALIGN(4) ; *(.noinit.$RAM2) *(.noinit.$RamUsb2) *(.noinit.$RAM2.*) *(.noinit.$RamUsb2.*) . = ALIGN(4) ; } > RamUsb2 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): { . = ALIGN(4) ; _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc8 PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc8 - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (( DEFINED(NMI_Handler) ? NMI_Handler : M0_NMI_Handler ) + 1) + (( DEFINED(HardFault_Handler) ? HardFault_Handler : M0_HardFault_Handler ) + 1) ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake ================================================ set(LPC_FAMILY 11u6x) set(JLINK_DEVICE LPC11U68) set(PYOCD_TARGET LPC11U68) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc11u68.ld) function(update_board TARGET) target_sources(${TARGET} PRIVATE ${SDK_DIR}/src/gpio_${LPC_FAMILY}.c ${SDK_DIR}/src/syscon_${LPC_FAMILY}.c ) endfunction() ================================================ FILE: hw/bsp/lpc11/boards/lpcxpresso11u68/board.h ================================================ /* metadata: name: LPCXpresso11U68 url: https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 */ #ifndef BOARD_H #define BOARD_H #define LED_PORT 2 #define LED_PIN 17 #define LED_STATE_ON 0 // Wake up Switch #define BUTTON_PORT 0 #define BUTTON_PIN 16 #define BUTTON_STATE_ACTIVE 0 /* System oscillator rate and RTC oscillator rate */ const uint32_t OscRateIn = 12000000; const uint32_t RTCOscRateIn = 32768; /* Pin muxing table, only items that need changing from their default pin state are in this table. Not every pin is mapped. */ static const PINMUX_GRP_T pinmuxing[] = { {0, 3, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // USB VBUS {0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 RX {0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 TX {2, 0, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALIN {2, 1, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALOUT }; #endif ================================================ FILE: hw/bsp/lpc11/boards/lpcxpresso11u68/board.mk ================================================ MCU = 11u6x MCU_DRV = 11u6x CFLAGS += \ -DCORE_M0PLUS \ -D__VTOR_PRESENT=0 \ -DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM3")))' \ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/lpc11u68.ld # For flash-jlink target JLINK_DEVICE = LPC11U68 PYOCD_TARGET = lpc11u68 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc11/boards/lpcxpresso11u68/lpc11u68.ld ================================================ /* * GENERATED FILE - DO NOT EDIT * (c) Code Red Technologies Ltd, 2008-2013 * (c) NXP Semiconductors 2013-2019 * Generated linker script file for LPC11U68 * Created from linkscript.ldt by FMCreateLinkLibraries * Using Freemarker v2.3.23 * MCUXpresso IDE v10.2.1 [Build 795] [2018-07-25] on May 14, 2019 4:55:54 PM */ MEMORY { /* Define each memory region */ MFlash256 (rx) : ORIGIN = 0x0, LENGTH = 0x40000 /* 256K bytes (alias Flash) */ Ram0_32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM) */ Ram1_2 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x800 /* 2K bytes (alias RAM2) */ Ram2USB_2 (rwx) : ORIGIN = 0x20004000, LENGTH = 0x800 /* 2K bytes (alias RAM3) */ } /* Define a symbol for the top of each memory region */ __base_MFlash256 = 0x0 ; /* MFlash256 */ __base_Flash = 0x0 ; /* Flash */ __top_MFlash256 = 0x0 + 0x40000 ; /* 256K bytes */ __top_Flash = 0x0 + 0x40000 ; /* 256K bytes */ __base_Ram0_32 = 0x10000000 ; /* Ram0_32 */ __base_RAM = 0x10000000 ; /* RAM */ __top_Ram0_32 = 0x10000000 + 0x8000 ; /* 32K bytes */ __top_RAM = 0x10000000 + 0x8000 ; /* 32K bytes */ __base_Ram1_2 = 0x20000000 ; /* Ram1_2 */ __base_RAM2 = 0x20000000 ; /* RAM2 */ __top_Ram1_2 = 0x20000000 + 0x800 ; /* 2K bytes */ __top_RAM2 = 0x20000000 + 0x800 ; /* 2K bytes */ __base_Ram2USB_2 = 0x20004000 ; /* Ram2USB_2 */ __base_RAM3 = 0x20004000 ; /* RAM3 */ __top_Ram2USB_2 = 0x20004000 + 0x800 ; /* 2K bytes */ __top_RAM3 = 0x20004000 + 0x800 ; /* 2K bytes */ ENTRY(ResetISR) SECTIONS { /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); LONG(LOADADDR(.data_RAM3)); LONG( ADDR(.data_RAM3)); LONG( SIZEOF(.data_RAM3)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); LONG( ADDR(.bss_RAM3)); LONG( SIZEOF(.bss_RAM3)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) } > MFlash256 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash256 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash256 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash256 __exidx_end = .; _etext = .; /* possible MTB section for Ram1_2 */ .mtb_buffer_RAM2 (NOLOAD) : { KEEP(*(.mtb.$RAM2*)) KEEP(*(.mtb.$Ram1_2*)) } > Ram1_2 /* DATA section for Ram1_2 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$Ram1_2) *(.data.$RAM2*) *(.data.$Ram1_2*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > Ram1_2 AT>MFlash256 /* possible MTB section for Ram2USB_2 */ .mtb_buffer_RAM3 (NOLOAD) : { KEEP(*(.mtb.$RAM3*)) KEEP(*(.mtb.$Ram2USB_2*)) } > Ram2USB_2 /* DATA section for Ram2USB_2 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$Ram2USB_2) *(.data.$RAM3*) *(.data.$Ram2USB_2*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; } > Ram2USB_2 AT>MFlash256 /* MAIN DATA SECTION */ /* Default MTB section */ .mtb_buffer_default (NOLOAD) : { KEEP(*(.mtb*)) } > Ram0_32 .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > Ram0_32 /* Main DATA section (Ram0_32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > Ram0_32 AT>MFlash256 /* BSS section for Ram1_2 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$Ram1_2*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > Ram1_2 /* BSS section for Ram2USB_2 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; *(.bss.$RAM3*) *(.bss.$Ram2USB_2*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; } > Ram2USB_2 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); } > Ram0_32 /* NOINIT section for Ram1_2 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$Ram1_2*) . = ALIGN(4) ; } > Ram1_2 /* NOINIT section for Ram2USB_2 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM3*) *(.noinit.$Ram2USB_2*) . = ALIGN(4) ; } > Ram2USB_2 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > Ram0_32 PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_Ram0_32 - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (( DEFINED(NMI_Handler) ? NMI_Handler : M0_NMI_Handler ) + 1) + (( DEFINED(HardFault_Handler) ? HardFault_Handler : M0_HardFault_Handler ) + 1) ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc11/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" extern void USB_IRQHandler(void); extern void SysTick_Handler(void); void SystemInit(void); //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ // Invoked by startup code void SystemInit(void) { /* Enable IOCON clock */ Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); for (uint32_t i = 0; i < (sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); i++) { Chip_IOCON_PinMuxSet(LPC_IOCON, pinmuxing[i].port, pinmuxing[i].pin, pinmuxing[i].modefunc); } Chip_SetupXtalClocking(); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO); // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); // USB: Setup PLL clock, and power Chip_USB_Init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { if ( max_len < 16 ) return 0; uint32_t* id32 = (uint32_t*) (uintptr_t) id; id32[0] = Chip_IAP_ReadUID(); return 4; } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/lpc11/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) if (LPC_FAMILY STREQUAL 11xx) set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc11uxx/lpc_chip_11uxx) else() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc${LPC_FAMILY}/lpc_chip_${LPC_FAMILY}) endif() # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC11UXX CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc${LPC_FAMILY}.c ${SDK_DIR}/src/chip_${LPC_FAMILY}.c ${SDK_DIR}/src/clock_${LPC_FAMILY}.c ${SDK_DIR}/src/iap.c ${SDK_DIR}/src/iocon_${LPC_FAMILY}.c ${SDK_DIR}/src/sysinit_${LPC_FAMILY}.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN __VTOR_PRESENT=0 CORE_M0 CORE_M0PLUS CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) set_target_properties(${BOARD_TARGET} PROPERTIES COMPILE_FLAGS "-Wno-incompatible-pointer-types") endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC11UXX) #---------- Port Specific ---------- # These files are built for each example since it depends on example's tusb_config.h target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ) target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${TARGET} PUBLIC -nostdlib -Wno-error=incompatible-pointer-types ) target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc11/family.mk ================================================ MCU_DIR = hw/mcu/nxp/lpcopen/lpc$(MCU)/lpc_chip_$(MCU) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -flto \ -nostdlib \ -D__USE_LPCOPEN \ -DCFG_TUSB_MCU=OPT_MCU_LPC11UXX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' # mcu driver cause following warnings CFLAGS += \ -Wno-error=incompatible-pointer-types \ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(MCU_DIR)/../gcc/cr_startup_lpc$(MCU_DRV).c \ $(MCU_DIR)/src/chip_$(MCU_DRV).c \ $(MCU_DIR)/src/clock_$(MCU_DRV).c \ $(MCU_DIR)/src/iap.c \ $(MCU_DIR)/src/iocon_$(MCU_DRV).c \ $(MCU_DIR)/src/sysinit_$(MCU_DRV).c ifeq ($(MCU),11u6x) SRC_C += \ $(MCU_DIR)/src/gpio_$(MCU_DRV).c \ $(MCU_DIR)/src/syscon_$(MCU_DRV).c \ else SRC_C += \ $(MCU_DIR)/src/gpio_$(MCU_DRV)_1.c \ $(MCU_DIR)/src/sysctl_$(MCU_DRV).c endif INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc \ # For flash-jlink target JLINK_DEVICE = LPC11U68 ================================================ FILE: hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #else #define configASSERT( x ) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlash64 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash64 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash64 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash64 __exidx_end = .; _etext = .; /* DATA section for RamUsb2 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamUsb2) *(.data.$RAM2*) *(.data.$RamUsb2*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamUsb2 AT>MFlash64 /* DATA section for RamPeriph2 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamPeriph2) *(.data.$RAM3*) *(.data.$RamPeriph2*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; } > RamPeriph2 AT>MFlash64 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc8 /* Main DATA section (RamLoc8) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc8 AT>MFlash64 /* BSS section for RamUsb2 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamUsb2*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamUsb2 /* BSS section for RamPeriph2 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; *(.bss.$RAM3*) *(.bss.$RamPeriph2*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; } > RamPeriph2 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); } > RamLoc8 /* NOINIT section for RamUsb2 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamUsb2*) . = ALIGN(4) ; } > RamUsb2 /* NOINIT section for RamPeriph2 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM3*) *(.noinit.$RamPeriph2*) . = ALIGN(4) ; } > RamPeriph2 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc8 PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc8 - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc13/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "chip.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } // Invoked by startup code void SystemInit(void) { /* Enable IOCON clock */ Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); Chip_SetupXtalClocking(); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO_PORT); // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED_PORT, LED_PIN); // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); // USB: Setup PLL clock, and power Chip_USB_Init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } ================================================ FILE: hw/bsp/lpc13/family.cmake ================================================ include_guard() set(LPC_FAMILY 13xx) set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc${LPC_FAMILY}/lpc_chip_${LPC_FAMILY}) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC13XX CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc${LPC_FAMILY}.c ${SDK_DIR}/src/chip_${LPC_FAMILY}.c ${SDK_DIR}/src/clock_${LPC_FAMILY}.c ${SDK_DIR}/src/gpio_${LPC_FAMILY}_1.c ${SDK_DIR}/src/iocon_${LPC_FAMILY}.c ${SDK_DIR}/src/sysctl_${LPC_FAMILY}.c ${SDK_DIR}/src/sysinit_${LPC_FAMILY}.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN __VTOR_PRESENT=0 CORE_M3 CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC13XX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc13/family.mk ================================================ MCU_DIR = hw/mcu/nxp/lpcopen/lpc13xx/lpc_chip_13xx include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ -nostdlib \ -DCORE_M3 \ -D__USE_LPCOPEN \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_LPC13XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # startup.c and lpc_types.h cause following errors CFLAGS += -Wno-error=strict-prototypes -Wno-error=redundant-decls # caused by freeRTOS port !! CFLAGS += -Wno-error=maybe-uninitialized SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(MCU_DIR)/../gcc/cr_startup_lpc13xx.c \ $(MCU_DIR)/src/chip_13xx.c \ $(MCU_DIR)/src/clock_13xx.c \ $(MCU_DIR)/src/gpio_13xx_1.c \ $(MCU_DIR)/src/iocon_13xx.c \ $(MCU_DIR)/src/sysctl_13xx.c \ $(MCU_DIR)/src/sysinit_13xx.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc ================================================ FILE: hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #else #define configASSERT( x ) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlash256 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash256 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash256 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash256 __exidx_end = .; _etext = .; /* DATA section for Ram1_16 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$Ram1_16) *(.data.$RAM2) *(.data.$Ram1_16) *(.data.$RAM2.*) *(.data.$Ram1_16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > Ram1_16 AT>MFlash256 /* DATA section for Ram2_4 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$Ram2_4) *(.data.$RAM3) *(.data.$Ram2_4) *(.data.$RAM3.*) *(.data.$Ram2_4.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; } > Ram2_4 AT>MFlash256 /* MAIN DATA SECTION */ .uninit_RESERVED (NOLOAD) : { . = ALIGN(4) ; KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > Ram0_16 /* Main DATA section (Ram0_16) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > Ram0_16 AT>MFlash256 /* BSS section for Ram1_16 */ .bss_RAM2 : { . = ALIGN(4) ; PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2) *(.bss.$Ram1_16) *(.bss.$RAM2.*) *(.bss.$Ram1_16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > Ram1_16 /* BSS section for Ram2_4 */ .bss_RAM3 : { . = ALIGN(4) ; PROVIDE(__start_bss_RAM3 = .) ; *(.bss.$RAM3) *(.bss.$Ram2_4) *(.bss.$RAM3.*) *(.bss.$Ram2_4.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; } > Ram2_4 /* MAIN BSS SECTION */ .bss : { . = ALIGN(4) ; _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); } > Ram0_16 /* NOINIT section for Ram1_16 */ .noinit_RAM2 (NOLOAD) : { . = ALIGN(4) ; *(.noinit.$RAM2) *(.noinit.$Ram1_16) *(.noinit.$RAM2.*) *(.noinit.$Ram1_16.*) . = ALIGN(4) ; } > Ram1_16 /* NOINIT section for Ram2_4 */ .noinit_RAM3 (NOLOAD) : { . = ALIGN(4) ; *(.noinit.$RAM3) *(.noinit.$Ram2_4) *(.noinit.$RAM3.*) *(.noinit.$Ram2_4.*) . = ALIGN(4) ; } > Ram2_4 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): { . = ALIGN(4) ; _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > Ram0_16 PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_Ram0_16 - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc15/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ /* System oscillator rate and RTC oscillator rate */ const uint32_t OscRateIn = XTAL_OscRateIn; const uint32_t RTCOscRateIn = XTAL_RTCOscRateIn; // Invoked by startup code void SystemInit(void) { Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SRAM1); Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SRAM2); Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM); Chip_SYSCTL_PeriphReset(RESET_IOCON); board_lpc15_pinmux_swm_init(); Chip_SetupXtalClocking(); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO); // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); // UART Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false); Chip_UART_Init(UART_PORT); Chip_UART_ConfigData(UART_PORT, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1); Chip_UART_SetBaud(UART_PORT, CFG_BOARD_UART_BAUDRATE); Chip_UART_Enable(UART_PORT); Chip_UART_TXEnable(UART_PORT); // USB: Setup PLL clock, and power Chip_USB_Init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { return Chip_UART_SendBlocking(UART_PORT, buf, len); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/lpc15/family.cmake ================================================ include_guard() set(LPC_FAMILY 15xx) set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc${LPC_FAMILY}/lpc_chip_${LPC_FAMILY}) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC15XX CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc${LPC_FAMILY}.c ${SDK_DIR}/src/chip_${LPC_FAMILY}.c ${SDK_DIR}/src/clock_${LPC_FAMILY}.c ${SDK_DIR}/src/gpio_${LPC_FAMILY}.c ${SDK_DIR}/src/iocon_${LPC_FAMILY}.c ${SDK_DIR}/src/swm_${LPC_FAMILY}.c ${SDK_DIR}/src/sysctl_${LPC_FAMILY}.c ${SDK_DIR}/src/sysinit_${LPC_FAMILY}.c ${SDK_DIR}/src/uart_${LPC_FAMILY}.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN #__VTOR_PRESENT=0 CORE_M3 CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC15XX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc15/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ -nostdlib \ -DCORE_M3 \ -D__USE_LPCOPEN \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_LPC15XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=cast-qual MCU_DIR = hw/mcu/nxp/lpcopen/lpc15xx/lpc_chip_15xx SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(MCU_DIR)/../gcc/cr_startup_lpc15xx.c \ $(MCU_DIR)/src/chip_15xx.c \ $(MCU_DIR)/src/clock_15xx.c \ $(MCU_DIR)/src/gpio_15xx.c \ $(MCU_DIR)/src/iocon_15xx.c \ $(MCU_DIR)/src/swm_15xx.c \ $(MCU_DIR)/src/sysctl_15xx.c \ $(MCU_DIR)/src/sysinit_15xx.c \ $(MCU_DIR)/src/uart_15xx.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc ================================================ FILE: hw/bsp/lpc17/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "chip.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlash512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash512 __exidx_end = .; _etext = .; /* DATA section for RamAHB32 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamAHB32) *(.data.$RAM2*) *(.data.$RamAHB32*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamAHB32 AT>MFlash512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc32 AT>MFlash512 /* BSS section for RamAHB32 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamAHB32*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamAHB32 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; /* PROVIDE(end = .);*/ } > RamLoc32 /* NOINIT section for RamAHB32 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamAHB32*) . = ALIGN(4) ; } > RamAHB32 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc17/boards/mbed1768/board.cmake ================================================ set(MCU_VARIANT LPC1768) set(JLINK_DEVICE LPC1768) set(PYOCD_TARGET LPC1768) set(NXPLINK_DEVICE LPC1768:LPC1768) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc1768.ld) function(update_board TARGET) # nothing to do endfunction() ================================================ FILE: hw/bsp/lpc17/boards/mbed1768/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: mbed 1768 url: https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1700-arm-cortex-m3/arm-mbed-lpc1768-board:OM11043 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT 1 #define LED_PIN 18 #define LED_STATE_ON 1 // JOYSTICK_DOWN if using LPCXpresso Base Board #define BUTTON_PORT 0 #define BUTTON_PIN 15 #define BUTTON_STATE_ACTIVE 0 #define BOARD_UART_PORT LPC_UART3 /* System oscillator rate and RTC oscillator rate */ const uint32_t OscRateIn = 10000000; const uint32_t RTCOscRateIn = 32768; // Pin muxing configuration static const PINMUX_GRP_T pinmuxing[] = { {LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, {BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, }; static const PINMUX_GRP_T pin_usb_mux[] = { {0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+ {0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D- {2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect {1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode) {1, 22, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PWRD // VBUS is not connected on this board, so leave the pin at default setting. // Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2); // USB VBUS }; #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc17/boards/mbed1768/board.mk ================================================ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/lpc1768.ld # For flash-jlink target JLINK_DEVICE = LPC1768 PYOCD_TARGET = lpc1768 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc17/boards/mbed1768/lpc1768.ld ================================================ /* * GENERATED FILE - DO NOT EDIT * (c) Code Red Technologies Ltd, 2008-2013 * (c) NXP Semiconductors 2013-2019 * Generated linker script file for LPC1769 * Created from linkscript.ldt by FMCreateLinkLibraries * Using Freemarker v2.3.23 * MCUXpresso IDE v10.2.1 [Build 795] [2018-07-25] on May 14, 2019 6:39:29 PM */ MEMORY { /* Define each memory region */ MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM) */ RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32K bytes (alias RAM2) */ } /* Define a symbol for the top of each memory region */ __base_MFlash512 = 0x0 ; /* MFlash512 */ __base_Flash = 0x0 ; /* Flash */ __top_MFlash512 = 0x0 + 0x80000 ; /* 512K bytes */ __top_Flash = 0x0 + 0x80000 ; /* 512K bytes */ __base_RamLoc32 = 0x10000000 ; /* RamLoc32 */ __base_RAM = 0x10000000 ; /* RAM */ __top_RamLoc32 = 0x10000000 + 0x8000 ; /* 32K bytes */ __top_RAM = 0x10000000 + 0x8000 ; /* 32K bytes */ __base_RamAHB32 = 0x2007c000 ; /* RamAHB32 */ __base_RAM2 = 0x2007c000 ; /* RAM2 */ __top_RamAHB32 = 0x2007c000 + 0x8000 ; /* 32K bytes */ __top_RAM2 = 0x2007c000 + 0x8000 ; /* 32K bytes */ ENTRY(ResetISR) SECTIONS { /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) } > MFlash512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash512 __exidx_end = .; _etext = .; /* DATA section for RamAHB32 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamAHB32) *(.data.$RAM2*) *(.data.$RamAHB32*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamAHB32 AT>MFlash512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc32 AT>MFlash512 /* BSS section for RamAHB32 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamAHB32*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamAHB32 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; /* PROVIDE(end = .);*/ } > RamLoc32 /* NOINIT section for RamAHB32 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamAHB32*) . = ALIGN(4) ; } > RamAHB32 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc17/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "chip.h" #include "bsp/board_api.h" #include "board.h" // Invoked by startup code void SystemInit(void) { #ifdef __USE_LPCOPEN extern void (* const g_pfnVectors[])(void); unsigned int* pSCB_VTOR = (unsigned int*) 0xE000ED08; *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif Chip_IOCON_Init(LPC_IOCON); Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); Chip_SetupXtalClocking(); Chip_SYSCTL_SetFLASHAccess(FLASHTIM_100MHZ_CPU); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif Chip_GPIO_Init(LPC_GPIO); Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); #if 0 //------------- UART -------------// PINSEL_CFG_Type PinCfg = { .Portnum = 0, .Pinnum = 0, // TXD is P0.0 .Funcnum = 2, .OpenDrain = 0, .Pinmode = 0 }; PINSEL_ConfigPin(&PinCfg); PinCfg.Portnum = 0; PinCfg.Pinnum = 1; // RXD is P0.1 PINSEL_ConfigPin(&PinCfg); UART_CFG_Type UARTConfigStruct; UART_ConfigStructInit(&UARTConfigStruct); UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE; UART_Init(BOARD_UART_PORT, &UARTConfigStruct); UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit #endif //------------- USB -------------// Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T)); Chip_USB_Init(); enum { USBCLK_DEVCIE = 0x12, // AHB + Device USBCLK_HOST = 0x19, // AHB + Host + OTG // 0x1B // Host + Device + OTG + AHB }; #if CFG_TUD_ENABLED uint32_t const clk_en = USBCLK_DEVCIE; #else uint32_t const clk_en = USBCLK_HOST; #endif LPC_USB->OTGClkCtrl = clk_en; while ((LPC_USB->OTGClkSt & clk_en) != clk_en) {} #if CFG_TUH_ENABLED // set portfunc to host !!! LPC_USB->StCtrl = 0x3; // should be 1 #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { // return UART_ReceiveByte(BOARD_UART_PORT); (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { // UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { #if CFG_TUD_ENABLED tud_int_handler(0); #endif #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif } #endif ================================================ FILE: hw/bsp/lpc17/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC175X_6X CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc175x_6x.c ${SDK_DIR}/src/chip_17xx_40xx.c ${SDK_DIR}/src/clock_17xx_40xx.c ${SDK_DIR}/src/gpio_17xx_40xx.c ${SDK_DIR}/src/iocon_17xx_40xx.c ${SDK_DIR}/src/sysctl_17xx_40xx.c ${SDK_DIR}/src/sysinit_17xx_40xx.c ${SDK_DIR}/src/uart_17xx_40xx.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN CORE_M3 RTC_EV_SUPPORT=0 ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC175X_6X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c ${TOP}/src/portable/ohci/ohci.c ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc17/family.mk ================================================ MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ -nostdlib \ -DCORE_M3 \ -D__USE_LPCOPEN \ -DCFG_TUSB_MCU=OPT_MCU_LPC175X_6X \ -DRTC_EV_SUPPORT=0 # lpc_types.h cause following errors CFLAGS_GCC += -Wno-error=strict-prototypes -Wno-error=cast-qual # caused by freeRTOS port !! CFLAGS += -Wno-error=maybe-uninitialized LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ $(MCU_DIR)/src/gpio_17xx_40xx.c \ $(MCU_DIR)/src/iocon_17xx_40xx.c \ $(MCU_DIR)/src/sysctl_17xx_40xx.c \ $(MCU_DIR)/src/sysinit_17xx_40xx.c \ $(MCU_DIR)/src/uart_17xx_40xx.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ ================================================ FILE: hw/bsp/lpc18/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "chip.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlashB512 /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); LONG(LOADADDR(.data_RAM3)); LONG( ADDR(.data_RAM3)); LONG( SIZEOF(.data_RAM3)); LONG(LOADADDR(.data_RAM4)); LONG( ADDR(.data_RAM4)); LONG( SIZEOF(.data_RAM4)); LONG(LOADADDR(.data_RAM5)); LONG( ADDR(.data_RAM5)); LONG( SIZEOF(.data_RAM5)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); LONG( ADDR(.bss_RAM3)); LONG( SIZEOF(.bss_RAM3)); LONG( ADDR(.bss_RAM4)); LONG( SIZEOF(.bss_RAM4)); LONG( ADDR(.bss_RAM5)); LONG( SIZEOF(.bss_RAM5)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) } > MFlashA512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlashA512 .ARM.exidx : ALIGN(4) { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > MFlashA512 _etext = .; /* DATA section for RamLoc40 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; PROVIDE(__start_data_RamLoc40 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamLoc40) *(.data.$RAM2) *(.data.$RamLoc40) *(.data.$RAM2.*) *(.data.$RamLoc40.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; PROVIDE(__end_data_RamLoc40 = .) ; } > RamLoc40 AT>MFlashA512 /* DATA section for RamAHB32 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; PROVIDE(__start_data_RamAHB32 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamAHB32) *(.data.$RAM3) *(.data.$RamAHB32) *(.data.$RAM3.*) *(.data.$RamAHB32.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; PROVIDE(__end_data_RamAHB32 = .) ; } > RamAHB32 AT>MFlashA512 /* DATA section for RamAHB16 */ .data_RAM4 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM4 = .) ; PROVIDE(__start_data_RamAHB16 = .) ; *(.ramfunc.$RAM4) *(.ramfunc.$RamAHB16) *(.data.$RAM4) *(.data.$RamAHB16) *(.data.$RAM4.*) *(.data.$RamAHB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM4 = .) ; PROVIDE(__end_data_RamAHB16 = .) ; } > RamAHB16 AT>MFlashA512 /* DATA section for RamAHB_ETB16 */ .data_RAM5 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM5 = .) ; PROVIDE(__start_data_RamAHB_ETB16 = .) ; *(.ramfunc.$RAM5) *(.ramfunc.$RamAHB_ETB16) *(.data.$RAM5) *(.data.$RamAHB_ETB16) *(.data.$RAM5.*) *(.data.$RamAHB_ETB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM5 = .) ; PROVIDE(__end_data_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT>MFlashA512 /* MAIN DATA SECTION */ .uninit_RESERVED (NOLOAD) : ALIGN(4) { _start_uninit_RESERVED = .; KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 AT> RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; PROVIDE(__start_data_RAM = .) ; PROVIDE(__start_data_RamLoc32 = .) ; *(vtable) *(.ramfunc*) KEEP(*(CodeQuickAccess)) KEEP(*(DataQuickAccess)) *(RamFunction) *(.data*) . = ALIGN(4) ; _edata = . ; PROVIDE(__end_data_RAM = .) ; PROVIDE(__end_data_RamLoc32 = .) ; } > RamLoc32 AT>MFlashA512 /* BSS section for RamLoc40 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; PROVIDE(__start_bss_RamLoc40 = .) ; *(.bss.$RAM2) *(.bss.$RamLoc40) *(.bss.$RAM2.*) *(.bss.$RamLoc40.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; PROVIDE(__end_bss_RamLoc40 = .) ; } > RamLoc40 AT> RamLoc40 /* BSS section for RamAHB32 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; PROVIDE(__start_bss_RamAHB32 = .) ; *(.bss.$RAM3) *(.bss.$RamAHB32) *(.bss.$RAM3.*) *(.bss.$RamAHB32.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; PROVIDE(__end_bss_RamAHB32 = .) ; } > RamAHB32 AT> RamAHB32 /* BSS section for RamAHB16 */ .bss_RAM4 : ALIGN(4) { PROVIDE(__start_bss_RAM4 = .) ; PROVIDE(__start_bss_RamAHB16 = .) ; *(.bss.$RAM4) *(.bss.$RamAHB16) *(.bss.$RAM4.*) *(.bss.$RamAHB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM4 = .) ; PROVIDE(__end_bss_RamAHB16 = .) ; } > RamAHB16 AT> RamAHB16 /* BSS section for RamAHB_ETB16 */ .bss_RAM5 : ALIGN(4) { PROVIDE(__start_bss_RAM5 = .) ; PROVIDE(__start_bss_RamAHB_ETB16 = .) ; *(.bss.$RAM5) *(.bss.$RamAHB_ETB16) *(.bss.$RAM5.*) *(.bss.$RamAHB_ETB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM5 = .) ; PROVIDE(__end_bss_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; PROVIDE(__start_bss_RAM = .) ; PROVIDE(__start_bss_RamLoc32 = .) ; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; /* PROVIDE(end = .);*/ } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc40 /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM2 = .) ; PROVIDE(__start_noinit_RamLoc40 = .) ; *(.noinit.$RAM2) *(.noinit.$RamLoc40) *(.noinit.$RAM2.*) *(.noinit.$RamLoc40.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM2 = .) ; PROVIDE(__end_noinit_RamLoc40 = .) ; } > RamLoc40 AT> RamLoc40 /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM3 = .) ; PROVIDE(__start_noinit_RamAHB32 = .) ; *(.noinit.$RAM3) *(.noinit.$RamAHB32) *(.noinit.$RAM3.*) *(.noinit.$RamAHB32.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM3 = .) ; PROVIDE(__end_noinit_RamAHB32 = .) ; } > RamAHB32 AT> RamAHB32 /* NOINIT section for RamAHB16 */ .noinit_RAM4 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM4 = .) ; PROVIDE(__start_noinit_RamAHB16 = .) ; *(.noinit.$RAM4) *(.noinit.$RamAHB16) *(.noinit.$RAM4.*) *(.noinit.$RamAHB16.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM4 = .) ; PROVIDE(__end_noinit_RamAHB16 = .) ; } > RamAHB16 AT> RamAHB16 /* NOINIT section for RamAHB_ETB16 */ .noinit_RAM5 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM5 = .) ; PROVIDE(__start_noinit_RamAHB_ETB16 = .) ; *(.noinit.$RAM5) *(.noinit.$RamAHB_ETB16) *(.noinit.$RAM5.*) *(.noinit.$RamAHB_ETB16.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM5 = .) ; PROVIDE(__end_noinit_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; PROVIDE(__start_noinit_RAM = .) ; PROVIDE(__start_noinit_RamLoc32 = .) ; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; PROVIDE(__end_noinit_RAM = .) ; PROVIDE(__end_noinit_RamLoc32 = .) ; } > RamLoc32 AT> RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ /* PROVIDE(__valid_user_code_checksum = 0 -*/ /* (_vStackTop*/ /* + (ResetISR + 1)*/ /* + (NMI_Handler + 1)*/ /* + (HardFault_Handler + 1)*/ /* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ /* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ /* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ /* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc18/boards/mcb1800/board.cmake ================================================ set(MCU_VARIANT LPC1857) set(JLINK_DEVICE LPC1857) set(PYOCD_TARGET LPC1857) set(NXPLINK_DEVICE LPC1857:MCB1857) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc1857.ld) function(update_board TARGET) # nothing to do endfunction() ================================================ FILE: hw/bsp/lpc18/boards/mcb1800/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Keil MCB1800 url: https://www.keil.com/arm/mcb1800/ */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // PD_10 #define LED_PORT 6 #define LED_PIN 24 // P4_0 #define BUTTON_PORT 2 #define BUTTON_PIN 0 #define UART_DEV LPC_USART3 static inline void board_lpc18_pinmux(void) { const PINMUX_GRP_T pinmuxing[] = { // ETM Trace #ifdef TRACE_ETM { 0xF, 4, SCU_MODE_FUNC2 | SCU_MODE_HIGHSPEEDSLEW_EN }, { 0xF, 5, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN }, { 0xF, 6, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN }, { 0xF, 7, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN }, { 0xF, 8, SCU_MODE_FUNC3 | SCU_MODE_HIGHSPEEDSLEW_EN }, #endif // LEDs { 0xD, 10, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4) }, { 0xD, 11, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4 | SCU_MODE_PULLDOWN) }, { 0xD, 12, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4 | SCU_MODE_PULLDOWN) }, { 0xD, 13, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4 | SCU_MODE_PULLDOWN) }, { 0xD, 14, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC4 | SCU_MODE_PULLDOWN) }, { 0x9, 0, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLDOWN) }, { 0x9, 1, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLDOWN) }, { 0x9, 2, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLDOWN) }, // Button { 0x4, 0, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLUP) }, // UART { 2, 3, SCU_MODE_PULLDOWN | SCU_MODE_FUNC2 }, { 2, 4, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC2 }, // USB0 { 0x6, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC1 }, // P6_3 USB0_PWR_EN, USB0 VBus function { 0x9, 5, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC2 }, // P9_5 USB1_VBUS_EN, USB1 VBus function { 0x2, 5, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC2 }, // P2_5 USB1_VBUS, MUST CONFIGURE THIS SIGNAL FOR USB1 NORMAL OPERATION }; Chip_SCU_SetPinMuxing(pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); /* Pin clock mux values, re-used structure, value in first index is meaningless */ const PINMUX_GRP_T pinclockmuxing[] = { { 0, 0, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, { 0, 1, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, { 0, 2, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, { 0, 3, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, }; /* Clock pins only, group field not used */ for (uint32_t i = 0; i < (sizeof(pinclockmuxing) / sizeof(pinclockmuxing[0])); i++) { Chip_SCU_ClockPinMuxSet(pinclockmuxing[i].pinnum, pinclockmuxing[i].modefunc); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc18/boards/mcb1800/board.mk ================================================ LD_FILE = $(BOARD_PATH)/lpc1857.ld # For flash-jlink target JLINK_DEVICE = LPC1857 # flash using jlink flash: flash-jlink ================================================ FILE: hw/bsp/lpc18/boards/mcb1800/lpc1857.ld ================================================ /* * GENERATED FILE - DO NOT EDIT * (c) Code Red Technologies Ltd, 2008-2013 * (c) NXP Semiconductors 2013-2019 * Generated linker script file for LPC1857 * Created from linkscript.ldt by FMCreateLinkLibraries * Using Freemarker v2.3.23 * MCUXpresso IDE v10.2.1 [Build 795] [2018-07-25] on May 15, 2019 1:01:52 PM */ MEMORY { /* Define each memory region */ MFlashA512 (rx) : ORIGIN = 0x1a000000, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ MFlashB512 (rx) : ORIGIN = 0x1b000000, LENGTH = 0x80000 /* 512K bytes (alias Flash2) */ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM) */ RamLoc40 (rwx) : ORIGIN = 0x10080000, LENGTH = 0xa000 /* 40K bytes (alias RAM2) */ RamAHB32 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32K bytes (alias RAM3) */ RamAHB16 (rwx) : ORIGIN = 0x20008000, LENGTH = 0x4000 /* 16K bytes (alias RAM4) */ RamAHB_ETB16 (rwx) : ORIGIN = 0x2000c000, LENGTH = 0x4000 /* 16K bytes (alias RAM5) */ } /* Define a symbol for the top of each memory region */ __base_MFlashA512 = 0x1a000000 ; /* MFlashA512 */ __base_Flash = 0x1a000000 ; /* Flash */ __top_MFlashA512 = 0x1a000000 + 0x80000 ; /* 512K bytes */ __top_Flash = 0x1a000000 + 0x80000 ; /* 512K bytes */ __base_MFlashB512 = 0x1b000000 ; /* MFlashB512 */ __base_Flash2 = 0x1b000000 ; /* Flash2 */ __top_MFlashB512 = 0x1b000000 + 0x80000 ; /* 512K bytes */ __top_Flash2 = 0x1b000000 + 0x80000 ; /* 512K bytes */ __base_RamLoc32 = 0x10000000 ; /* RamLoc32 */ __base_RAM = 0x10000000 ; /* RAM */ __top_RamLoc32 = 0x10000000 + 0x8000 ; /* 32K bytes */ __top_RAM = 0x10000000 + 0x8000 ; /* 32K bytes */ __base_RamLoc40 = 0x10080000 ; /* RamLoc40 */ __base_RAM2 = 0x10080000 ; /* RAM2 */ __top_RamLoc40 = 0x10080000 + 0xa000 ; /* 40K bytes */ __top_RAM2 = 0x10080000 + 0xa000 ; /* 40K bytes */ __base_RamAHB32 = 0x20000000 ; /* RamAHB32 */ __base_RAM3 = 0x20000000 ; /* RAM3 */ __top_RamAHB32 = 0x20000000 + 0x8000 ; /* 32K bytes */ __top_RAM3 = 0x20000000 + 0x8000 ; /* 32K bytes */ __base_RamAHB16 = 0x20008000 ; /* RamAHB16 */ __base_RAM4 = 0x20008000 ; /* RAM4 */ __top_RamAHB16 = 0x20008000 + 0x4000 ; /* 16K bytes */ __top_RAM4 = 0x20008000 + 0x4000 ; /* 16K bytes */ __base_RamAHB_ETB16 = 0x2000c000 ; /* RamAHB_ETB16 */ __base_RAM5 = 0x2000c000 ; /* RAM5 */ __top_RamAHB_ETB16 = 0x2000c000 + 0x4000 ; /* 16K bytes */ __top_RAM5 = 0x2000c000 + 0x4000 ; /* 16K bytes */ ENTRY(ResetISR) SECTIONS { .text_Flash2 : ALIGN(4) { FILL(0xff) *(.text_Flash2*) /* for compatibility with previous releases */ *(.text_MFlashB512*) /* for compatibility with previous releases */ *(.text.$Flash2*) *(.text.$MFlashB512*) *(.rodata.$Flash2*) *(.rodata.$MFlashB512*) } > MFlashB512 /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); LONG(LOADADDR(.data_RAM3)); LONG( ADDR(.data_RAM3)); LONG( SIZEOF(.data_RAM3)); LONG(LOADADDR(.data_RAM4)); LONG( ADDR(.data_RAM4)); LONG( SIZEOF(.data_RAM4)); LONG(LOADADDR(.data_RAM5)); LONG( ADDR(.data_RAM5)); LONG( SIZEOF(.data_RAM5)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); LONG( ADDR(.bss_RAM3)); LONG( SIZEOF(.bss_RAM3)); LONG( ADDR(.bss_RAM4)); LONG( SIZEOF(.bss_RAM4)); LONG( ADDR(.bss_RAM5)); LONG( SIZEOF(.bss_RAM5)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) } > MFlashA512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlashA512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlashA512 __exidx_end = .; _etext = .; /* DATA section for RamLoc40 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamLoc40) *(.data.$RAM2*) *(.data.$RamLoc40*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamLoc40 AT>MFlashA512 /* DATA section for RamAHB32 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamAHB32) *(.data.$RAM3*) *(.data.$RamAHB32*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; } > RamAHB32 AT>MFlashA512 /* DATA section for RamAHB16 */ .data_RAM4 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM4 = .) ; *(.ramfunc.$RAM4) *(.ramfunc.$RamAHB16) *(.data.$RAM4*) *(.data.$RamAHB16*) . = ALIGN(4) ; PROVIDE(__end_data_RAM4 = .) ; } > RamAHB16 AT>MFlashA512 /* DATA section for RamAHB_ETB16 */ .data_RAM5 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM5 = .) ; *(.ramfunc.$RAM5) *(.ramfunc.$RamAHB_ETB16) *(.data.$RAM5*) *(.data.$RamAHB_ETB16*) . = ALIGN(4) ; PROVIDE(__end_data_RAM5 = .) ; } > RamAHB_ETB16 AT>MFlashA512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc32 AT>MFlashA512 /* BSS section for RamLoc40 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamLoc40*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamLoc40 /* BSS section for RamAHB32 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; *(.bss.$RAM3*) *(.bss.$RamAHB32*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; } > RamAHB32 /* BSS section for RamAHB16 */ .bss_RAM4 : ALIGN(4) { PROVIDE(__start_bss_RAM4 = .) ; *(.bss.$RAM4*) *(.bss.$RamAHB16*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM4 = .) ; } > RamAHB16 /* BSS section for RamAHB_ETB16 */ .bss_RAM5 : ALIGN(4) { PROVIDE(__start_bss_RAM5 = .) ; *(.bss.$RAM5*) *(.bss.$RamAHB_ETB16*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; /* PROVIDE(end = .); */ } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamLoc40*) . = ALIGN(4) ; } > RamLoc40 /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc40 /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM3*) *(.noinit.$RamAHB32*) . = ALIGN(4) ; } > RamAHB32 /* NOINIT section for RamAHB16 */ .noinit_RAM4 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM4*) *(.noinit.$RamAHB16*) . = ALIGN(4) ; } > RamAHB16 /* NOINIT section for RamAHB_ETB16 */ .noinit_RAM5 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM5*) *(.noinit.$RamAHB_ETB16*) . = ALIGN(4) ; } > RamAHB_ETB16 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ /* PROVIDE(__valid_user_code_checksum = 0 -*/ /* (_vStackTop*/ /* + (ResetISR + 1)*/ /* + (NMI_Handler + 1)*/ /* + (HardFault_Handler + 1)*/ /* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ /* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ /* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ /* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Project.AddSvdFile ("Cortex-M3.svd"); Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC18xx.svd"); Project.SetDevice ("LPC1857"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("50 MHz"); Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); //File.Open ("../../../../../../examples/cmake-build-mcb1800/device/cdc_msc/cdc_msc.elf"); File.Open ("../../../../../../examples/cmake-build-mcb1800/host/cdc_msc_hid/cdc_msc_hid.elf"); } /********************************************************************* * * BeforeTargetConnect * ********************************************************************** */ void BeforeTargetConnect (void) { // // Trace pin init is done by J-Link script file as J-Link script files are IDE independent // // Project.SetJLinkScript("./NXP_LPC1857JET256_TraceExample.pex"); } ================================================ FILE: hw/bsp/lpc18/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "chip.h" #include "bsp/board_api.h" #include "board.h" extern void USB0_IRQHandler(void); extern void USB1_IRQHandler(void); extern void SysTick_Handler(void); void SystemInit(void); //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { tusb_int_handler(0, true); } void USB1_IRQHandler(void) { tusb_int_handler(1, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ /* System configuration variables used by chip driver */ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; // Invoked by startup code void SystemInit(void) { #ifdef __USE_LPCOPEN extern void (*const g_pfnVectors[])(void); unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif board_lpc18_pinmux(); #ifdef TRACE_ETM // Trace clock is limited to 60MHz, limit CPU clock to 120MHz Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true); #else // CPU clock max to 180 Mhz Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true); #endif } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO_PORT); // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED_PORT, LED_PIN); // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); //------------- UART -------------// Chip_UART_Init(UART_DEV); Chip_UART_SetBaud(UART_DEV, CFG_BOARD_UART_BAUDRATE); Chip_UART_ConfigData(UART_DEV, UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS); Chip_UART_TXEnable(UART_DEV); //------------- USB -------------// Chip_USB0_Init(); Chip_USB1_Init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } int board_uart_write(void const *buf, int len) { uint8_t const *buf8 = (uint8_t const *) buf; for (int i = 0; i < len; i++) { while ((Chip_UART_ReadLineStatus(UART_DEV) & UART_LSR_THRE) == 0) {} Chip_UART_SendByte(UART_DEV, buf8[i]); } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/lpc18/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC18XX CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc18xx.c ${SDK_DIR}/src/chip_18xx_43xx.c ${SDK_DIR}/src/clock_18xx_43xx.c ${SDK_DIR}/src/gpio_18xx_43xx.c ${SDK_DIR}/src/sysinit_18xx_43xx.c ${SDK_DIR}/src/uart_18xx_43xx.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN CORE_M3 ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${SDK_DIR}/inc/config_18xx ${CMSIS_5}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC18XX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c ${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c ${TOP}/src/portable/ehci/ehci.c ) target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc18/family.mk ================================================ MCU_DIR = hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ -nostdlib \ -DCORE_M3 \ -D__USE_LPCOPEN \ -DCFG_TUSB_MCU=OPT_MCU_LPC18XX # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=unused-parameter -Wno-error=cast-qual LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ src/portable/chipidea/ci_hs/hcd_ci_hs.c \ src/portable/ehci/ehci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc18xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ $(MCU_DIR)/src/clock_18xx_43xx.c \ $(MCU_DIR)/src/gpio_18xx_43xx.c \ $(MCU_DIR)/src/sysinit_18xx_43xx.c \ $(MCU_DIR)/src/uart_18xx_43xx.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc \ $(TOP)/$(MCU_DIR)/inc/config_18xx \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ ================================================ FILE: hw/bsp/lpc40/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "chip.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 5 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlash512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlash512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlash512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlash512 __exidx_end = .; _etext = .; /* DATA section for RamPeriph32 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamPeriph32) *(.data.$RAM2*) *(.data.$RamPeriph32*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamPeriph32 AT>MFlash512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc64 /* Main DATA section (RamLoc64) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc64 AT>MFlash512 /* BSS section for RamPeriph32 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamPeriph32*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamPeriph32 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; /* PROVIDE(end = .);*/ } > RamLoc64 /* NOINIT section for RamPeriph32 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamPeriph32*) . = ALIGN(4) ; } > RamPeriph32 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc64 /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc64 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc64 - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc40/boards/ea4088_quickstart/ozone/ea4088_quickstart.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Edit.SysVar (VAR_POWER_SAMPLING_SPEED, FREQ_100_KHZ); Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC408x_7x_v0.7.svd"); Project.SetDevice ("LPC4088"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("50 MHz"); Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); // User settings File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-ea4088-quickstart/cdc_msc.elf"); } /********************************************************************* * * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging a RAM program on a Cortex-M target device * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // Exec.Reset(); // // VectorTableAddr = Elf.GetBaseAddr(); // // if (VectorTableAddr != 0xFFFFFFFF) { // // Util.Log("Resetting Program."); // // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetReset (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetDownload (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} ================================================ FILE: hw/bsp/lpc40/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "chip.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { #if CFG_TUD_ENABLED tud_int_handler(0); #endif #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // Invoked by startup code void SystemInit(void) { #ifdef __USE_LPCOPEN extern void (*const g_pfnVectors[])(void); unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; *pSCB_VTOR = (unsigned int) g_pfnVectors; #if __FPU_USED == 1 fpuInit(); #endif #endif // __USE_LPCOPEN Chip_IOCON_Init(LPC_IOCON); Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); #ifdef TRACE_ETM const PINMUX_GRP_T trace_pinmux[] = { {2, 2, IOCON_FUNC5 | IOCON_FASTSLEW_EN }, {2, 3, IOCON_FUNC5 | IOCON_FASTSLEW_EN }, {2, 4, IOCON_FUNC5 | IOCON_FASTSLEW_EN }, {2, 5, IOCON_FUNC5 | IOCON_FASTSLEW_EN }, {2, 6, IOCON_FUNC5 | IOCON_FASTSLEW_EN }, }; Chip_IOCON_SetPinMuxing(LPC_IOCON, trace_pinmux, sizeof(trace_pinmux) / sizeof(PINMUX_GRP_T)); #endif /* CPU clock source starts with IRC */ /* Enable PBOOST for CPU clock over 100MHz */ Chip_SYSCTL_EnableBoost(); Chip_SetupXtalClocking(); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO); // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); // UART //------------- USB -------------// // Port1 as Host, Port2: Device Chip_USB_Init(); enum { USBCLK_DEVCIE = 0x12, // AHB + Device USBCLK_HOST = 0x19, // AHB + OTG + Host USBCLK_ALL = 0x1B // Host + Device + OTG + AHB }; LPC_USB->OTGClkCtrl = USBCLK_ALL; while ( (LPC_USB->OTGClkSt & USBCLK_ALL) != USBCLK_ALL ) {} // set portfunc: USB1 = host, USB2 = device LPC_USB->StCtrl = 0x3; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { return BUTTON_ACTIV_STATE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t *buf, int len) { //return UART_ReceiveByte(BOARD_UART_PORT); (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { //UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/lpc40/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC40XX CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/../gcc/cr_startup_lpc40xx.c ${SDK_DIR}/src/chip_17xx_40xx.c ${SDK_DIR}/src/clock_17xx_40xx.c ${SDK_DIR}/src/fpu_init.c ${SDK_DIR}/src/gpio_17xx_40xx.c ${SDK_DIR}/src/iocon_17xx_40xx.c ${SDK_DIR}/src/sysctl_17xx_40xx.c ${SDK_DIR}/src/sysinit_17xx_40xx.c ${SDK_DIR}/src/uart_17xx_40xx.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN CORE_M4 CFG_TUSB_MEM_SECTION=__attribute__\(\(section\(\".data.$RAM2\"\)\)\) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC40XX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c ${TOP}/src/portable/ohci/ohci.c ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc40/family.mk ================================================ MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -flto \ -nostdlib \ -DCORE_M4 \ -D__USE_LPCOPEN \ -DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \ -DCFG_TUSB_MCU=OPT_MCU_LPC40XX # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=cast-qual LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ src/portable/ohci/ohci.c \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ $(MCU_DIR)/src/fpu_init.c \ $(MCU_DIR)/src/gpio_17xx_40xx.c \ $(MCU_DIR)/src/iocon_17xx_40xx.c \ $(MCU_DIR)/src/sysctl_17xx_40xx.c \ $(MCU_DIR)/src/sysinit_17xx_40xx.c \ $(MCU_DIR)/src/uart_17xx_40xx.c \ INC += \ $(TOP)/$(MCU_DIR)/inc \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(BOARD_PATH) ================================================ FILE: hw/bsp/lpc43/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "chip.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< MFlashB512 /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); LONG(LOADADDR(.data_RAM3)); LONG( ADDR(.data_RAM3)); LONG( SIZEOF(.data_RAM3)); LONG(LOADADDR(.data_RAM4)); LONG( ADDR(.data_RAM4)); LONG( SIZEOF(.data_RAM4)); LONG(LOADADDR(.data_RAM5)); LONG( ADDR(.data_RAM5)); LONG( SIZEOF(.data_RAM5)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); LONG( ADDR(.bss_RAM3)); LONG( SIZEOF(.bss_RAM3)); LONG( ADDR(.bss_RAM4)); LONG( SIZEOF(.bss_RAM4)); LONG( ADDR(.bss_RAM5)); LONG( SIZEOF(.bss_RAM5)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) } > MFlashA512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlashA512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlashA512 __exidx_end = .; _etext = .; /* DATA section for RamLoc40 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamLoc40) *(.data.$RAM2*) *(.data.$RamLoc40*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; } > RamLoc40 AT>MFlashA512 /* DATA section for RamAHB32 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamAHB32) *(.data.$RAM3*) *(.data.$RamAHB32*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; } > RamAHB32 AT>MFlashA512 /* DATA section for RamAHB16 */ .data_RAM4 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM4 = .) ; *(.ramfunc.$RAM4) *(.ramfunc.$RamAHB16) *(.data.$RAM4*) *(.data.$RamAHB16*) . = ALIGN(4) ; PROVIDE(__end_data_RAM4 = .) ; } > RamAHB16 AT>MFlashA512 /* DATA section for RamAHB_ETB16 */ .data_RAM5 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM5 = .) ; *(.ramfunc.$RAM5) *(.ramfunc.$RamAHB_ETB16) *(.data.$RAM5*) *(.data.$RamAHB_ETB16*) . = ALIGN(4) ; PROVIDE(__end_data_RAM5 = .) ; } > RamAHB_ETB16 AT>MFlashA512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4) ; _edata = . ; } > RamLoc32 AT>MFlashA512 /* BSS section for RamLoc40 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; *(.bss.$RAM2*) *(.bss.$RamLoc40*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; } > RamLoc40 /* BSS section for RamAHB32 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; *(.bss.$RAM3*) *(.bss.$RamAHB32*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; } > RamAHB32 /* BSS section for RamAHB16 */ .bss_RAM4 : ALIGN(4) { PROVIDE(__start_bss_RAM4 = .) ; *(.bss.$RAM4*) *(.bss.$RamAHB16*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM4 = .) ; } > RamAHB16 /* BSS section for RamAHB_ETB16 */ .bss_RAM5 : ALIGN(4) { PROVIDE(__start_bss_RAM5 = .) ; *(.bss.$RAM5*) *(.bss.$RamAHB_ETB16*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; /* PROVIDE(end = .); */ } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamLoc40*) . = ALIGN(4) ; } > RamLoc40 /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc40 /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM3*) *(.noinit.$RamAHB32*) . = ALIGN(4) ; } > RamAHB32 /* NOINIT section for RamAHB16 */ .noinit_RAM4 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM4*) *(.noinit.$RamAHB16*) . = ALIGN(4) ; } > RamAHB16 /* NOINIT section for RamAHB_ETB16 */ .noinit_RAM5 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM5*) *(.noinit.$RamAHB_ETB16*) . = ALIGN(4) ; } > RamAHB_ETB16 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ /* PROVIDE(__valid_user_code_checksum = 0 -*/ /* (_vStackTop*/ /* + (ResetISR + 1)*/ /* + (NMI_Handler + 1)*/ /* + (HardFault_Handler + 1)*/ /* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ /* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ /* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ /* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc43/boards/ea4357/pca9532.c ================================================ /***************************************************************************** * * Copyright(C) 2011, Embedded Artists AB * All rights reserved. * ****************************************************************************** * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * products. This software is supplied "AS IS" without any warranties. * Embedded Artists AB assumes no responsibility or liability for the * use of the software, conveys no license or title under any patent, * copyright, or mask work right to the product. Embedded Artists AB * reserves the right to make changes in the software without * notification. Embedded Artists AB also make no representation or * warranty that such application will be suitable for the specified * use without further testing or modification. *****************************************************************************/ /* * NOTE: I2C must have been initialized before calling any functions in this * file. */ /****************************************************************************** * Includes *****************************************************************************/ //#include "board.h" #include "chip.h" #include "pca9532.h" /****************************************************************************** * Defines and typedefs *****************************************************************************/ #define I2C_PORT (LPC_I2C0) #define LS_MODE_ON 0x01 #define LS_MODE_BLINK0 0x02 #define LS_MODE_BLINK1 0x03 /****************************************************************************** * External global variables *****************************************************************************/ /****************************************************************************** * Local variables *****************************************************************************/ static uint16_t blink0Shadow = 0; static uint16_t blink1Shadow = 0; static uint16_t ledStateShadow = 0; /****************************************************************************** * Local Functions *****************************************************************************/ static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len) { I2CM_XFER_T i2cData; i2cData.slaveAddr = addr; i2cData.options = 0; i2cData.status = 0; i2cData.txBuff = buf; i2cData.txSz = len; i2cData.rxBuff = NULL; i2cData.rxSz = 0; if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) { return ERROR; } return SUCCESS; } static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len) { I2CM_XFER_T i2cData; i2cData.slaveAddr = addr; i2cData.options = 0; i2cData.status = 0; i2cData.txBuff = NULL; i2cData.txSz = 0; i2cData.rxBuff = buf; i2cData.rxSz = len; if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) { return ERROR; } return SUCCESS; } static void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode) { #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 ) int i = 0; for (i = 0; i < 4; i++) { ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0) | (IS_LED_SET(0x0002, states)*mode << 2) | (IS_LED_SET(0x0004, states)*mode << 4) | (IS_LED_SET(0x0008, states)*mode << 6) ); states >>= 4; } } static void setLeds(void) { uint8_t buf[5]; uint8_t ls[4] = {0,0,0,0}; uint16_t states = ledStateShadow; /* LEDs in On/Off state */ setLsStates(states, ls, LS_MODE_ON); /* set the LEDs that should blink */ setLsStates(blink0Shadow, ls, LS_MODE_BLINK0); setLsStates(blink1Shadow, ls, LS_MODE_BLINK1); buf[0] = PCA9532_LS0 | PCA9532_AUTO_INC; buf[1] = ls[0]; buf[2] = ls[1]; buf[3] = ls[2]; buf[4] = ls[3]; I2CWrite(PCA9532_I2C_ADDR, buf, 5); } /****************************************************************************** * Public Functions *****************************************************************************/ /****************************************************************************** * * Description: * Initialize the PCA9532 Device * *****************************************************************************/ void pca9532_init (void) { /* nothing to initialize */ } /****************************************************************************** * * Description: * Get the LED states * * Params: * [in] shadow - TRUE if the states should be retrieved from the shadow * variables. The shadow variable are updated when any * of setLeds, setBlink0Leds and/or setBlink1Leds are * called. * * FALSE if the state should be retrieved from the PCA9532 * device. A blinkin LED may be reported as on or off * depending on the state when calling the function. * * Returns: * A mask where a 1 indicates that a LED is on (or blinking). * *****************************************************************************/ uint16_t pca9532_getLedState (uint32_t shadow) { uint8_t buf[2]; uint16_t ret = 0; if (shadow) { /* a blink LED is reported as on*/ ret = (ledStateShadow | blink0Shadow | blink1Shadow); } else { /* * A blinking LED may be reported as on or off depending on * its state when reading the Input register. */ buf[0] = PCA9532_INPUT0; I2CWrite(PCA9532_I2C_ADDR, buf, 1); I2CRead(PCA9532_I2C_ADDR, buf, 1); ret = buf[0]; buf[0] = PCA9532_INPUT1; I2CWrite(PCA9532_I2C_ADDR, buf, 1); I2CRead(PCA9532_I2C_ADDR, buf, 1); ret |= (buf[0] << 8); /* invert since LEDs are active low */ ret = ((~ret) & 0xFFFF); } return (ret & ~PCA9532_NOT_USED); } /****************************************************************************** * * Description: * Set LED states (on or off). * * Params: * [in] ledOnMask - The LEDs that should be turned on. This mask has * priority over ledOffMask * [in] ledOffMask - The LEDs that should be turned off. * *****************************************************************************/ void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask) { /* turn off leds */ ledStateShadow &= (~(ledOffMask) & 0xffff); /* ledOnMask has priority over ledOffMask */ ledStateShadow |= ledOnMask; /* turn off blinking */ blink0Shadow &= (~(ledOffMask) & 0xffff); blink1Shadow &= (~(ledOffMask) & 0xffff); setLeds(); } /****************************************************************************** * * Description: * Set the blink period for PWM0. Valid values are 0 - 255 where 0 * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz. * * Params: * [in] period - the period for pwm0 * *****************************************************************************/ void pca9532_setBlink0Period(uint8_t period) { uint8_t buf[2]; buf[0] = PCA9532_PSC0; buf[1] = period; I2CWrite(PCA9532_I2C_ADDR, buf, 2); } /****************************************************************************** * * Description: * Set the duty cycle for PWM0. Valid values are 0 - 100. 25 means the LED * is on 25% of the period. * * Params: * [in] duty - duty cycle * *****************************************************************************/ void pca9532_setBlink0Duty(uint8_t duty) { uint8_t buf[2]; uint32_t tmp = duty; if (tmp > 100) { tmp = 100; } tmp = (256 * tmp)/100; buf[0] = PCA9532_PWM0; buf[1] = tmp; I2CWrite(PCA9532_I2C_ADDR, buf, 2); } /****************************************************************************** * * Description: * Set the LEDs that should blink with rate and duty cycle from PWM0. * Blinking is turned off with pca9532_setLeds. * * Params: * [in] ledMask - LEDs that should blink. * *****************************************************************************/ void pca9532_setBlink0Leds(uint16_t ledMask) { blink0Shadow |= ledMask; setLeds(); } /****************************************************************************** * * Description: * Set the blink period for PWM1. Valid values are 0 - 255 where 0 * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz. * * Params: * [in] period - The period for PWM1 * *****************************************************************************/ void pca9532_setBlink1Period(uint8_t period) { uint8_t buf[2]; buf[0] = PCA9532_PSC1; buf[1] = period; I2CWrite(PCA9532_I2C_ADDR, buf, 2); } /****************************************************************************** * * Description: * Set the duty cycle for PWM1. Valid values are 0 - 100. 25 means the LED * is on 25% of the period. * * Params: * [in] duty - duty cycle. * *****************************************************************************/ void pca9532_setBlink1Duty(uint8_t duty) { uint8_t buf[2]; uint32_t tmp = duty; if (tmp > 100) { tmp = 100; } tmp = (256 * tmp)/100; buf[0] = PCA9532_PWM1; buf[1] = tmp; I2CWrite(PCA9532_I2C_ADDR, buf, 2); } /****************************************************************************** * * Description: * Set the LEDs that should blink with rate and duty cycle from PWM1. * Blinking is turned off with pca9532_setLeds. * * Params: * [in] ledMask - LEDs that should blink. * *****************************************************************************/ void pca9532_setBlink1Leds(uint16_t ledMask) { blink1Shadow |= ledMask; setLeds(); } ================================================ FILE: hw/bsp/lpc43/boards/ea4357/pca9532.h ================================================ /***************************************************************************** * * Copyright(C) 2011, Embedded Artists AB * All rights reserved. * ****************************************************************************** * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * products. This software is supplied "AS IS" without any warranties. * Embedded Artists AB assumes no responsibility or liability for the * use of the software, conveys no license or title under any patent, * copyright, or mask work right to the product. Embedded Artists AB * reserves the right to make changes in the software without * notification. Embedded Artists AB also make no representation or * warranty that such application will be suitable for the specified * use without further testing or modification. *****************************************************************************/ #ifndef __PCA9532C_H #define __PCA9532C_H #define PCA9532_I2C_ADDR (0xC0>>1) #define PCA9532_INPUT0 0x00 #define PCA9532_INPUT1 0x01 #define PCA9532_PSC0 0x02 #define PCA9532_PWM0 0x03 #define PCA9532_PSC1 0x04 #define PCA9532_PWM1 0x05 #define PCA9532_LS0 0x06 #define PCA9532_LS1 0x07 #define PCA9532_LS2 0x08 #define PCA9532_LS3 0x09 #define PCA9532_AUTO_INC 0x10 /* * The Keys on the base board are mapped to LED0 -> LED3 on * the PCA9532. */ #define KEY1 0x0001 #define KEY2 0x0002 #define KEY3 0x0004 #define KEY4 0x0008 #define KEY_MASK 0x000F /* * MMC Card Detect and MMC Write Protect are mapped to LED4 * and LED5 on the PCA9532. Please note that WP is active low. */ #define MMC_CD 0x0010 #define MMC_WP 0x0020 #define MMC_MASK 0x30 /* NOTE: LED6 and LED7 on PCA9532 are not connected to anything */ #define PCA9532_NOT_USED 0xC0 /* * Below are the LED constants to use when enabling/disabling a LED. * The LED names are the names printed on the base board and not * the names from the PCA9532 device. base_LED1 -> LED8 on PCA9532, * base_LED2 -> LED9, and so on. */ #define LED1 0x0100 #define LED2 0x0200 #define LED3 0x0400 #define LED4 0x0800 #define LED5 0x1000 #define LED6 0x2000 #define LED7 0x4000 #define LED8 0x8000 #define LED_MASK 0xFF00 void pca9532_init (void); uint16_t pca9532_getLedState (uint32_t shadow); void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask); void pca9532_setBlink0Period(uint8_t period); void pca9532_setBlink0Duty(uint8_t duty); void pca9532_setBlink0Leds(uint16_t ledMask); void pca9532_setBlink1Period(uint8_t period); void pca9532_setBlink1Duty(uint8_t duty); void pca9532_setBlink1Leds(uint16_t ledMask); #endif /* end __PCA9532C_H */ /**************************************************************************** ** End Of File *****************************************************************************/ ================================================ FILE: hw/bsp/lpc43/boards/lpcxpresso43s67/board.cmake ================================================ set(MCU_VARIANT LPC43S67_M4) set(JLINK_DEVICE LPC43S67_M4) set(PYOCD_TARGET LPC43S67) set(NXPLINK_DEVICE LPC43S67:LPCXPRESSO43S67) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc4367.ld) function(update_board TARGET) # nothing to do endfunction() ================================================ FILE: hw/bsp/lpc43/boards/lpcxpresso43s67/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: LPCXpresso43S67 url: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso43s67-development-board:OM13084 */ #ifndef _BOARD_LPCXPRESSO43S67_H_ #define _BOARD_LPCXPRESSO43S67_H_ // Note: For USB Host demo, install JP4 // WARNING: don't install JP4 when running as device #ifdef __cplusplus extern "C" { #endif // LED Red #define LED_PORT 3 #define LED_PIN 7 #define LED_STATE_ON 0 // ISP Button (SW2) #define BUTTON_PORT 0 #define BUTTON_PIN 7 #define BUTTON_STATE_ACTIVE 0 #define UART_DEV LPC_USART0 static const PINMUX_GRP_T pinmuxing[] = { // LEDs P6_11 as GPIO3[7] { 0x6, 11, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC0 }, // Button P2_7 as GPIO0[7] { 0x2, 7, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC0 }, // UART { 0x06, 4, SCU_MODE_PULLDOWN | SCU_MODE_FUNC2 }, { 0x02, 1, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1 }, // USB0 //{ 0x6, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC1 }, // P6_3 USB0_PWR_EN, USB0 VBus function // USB 1 //{ 0x9, 5, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC2 }, // P9_5 USB1_VBUS_EN, USB1 VBus function //{ 0x2, 5, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC2 }, // P2_5 USB1_VBUS, MUST CONFIGURE THIS SIGNAL FOR USB1 NORMAL OPERATION {0x2, 5, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC4 }, }; #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc43/boards/lpcxpresso43s67/board.mk ================================================ LD_FILE = $(BOARD_PATH)/lpc4367.ld # For flash-jlink target JLINK_DEVICE = LPC43S67_M4 flash: flash-jlink ================================================ FILE: hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld ================================================ /* * GENERATED FILE - DO NOT EDIT * Copyright (c) 2008-2013 Code Red Technologies Ltd, * Copyright 2015, 2018-2019 NXP * (c) NXP Semiconductors 2013-2023 * Generated linker script file for LPC4337 * Created from linkscript.ldt by FMCreateLinkLibraries * Using Freemarker v2.3.30 * MCUXpresso IDE v11.7.1 [Build 9221] [2023-03-28] on Aug 14, 2023, 3:36:29 PM */ MEMORY { /* Define each memory region */ MFlashA512 (rx) : ORIGIN = 0x1a000000, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ MFlashB512 (rx) : ORIGIN = 0x1b000000, LENGTH = 0x80000 /* 512K bytes (alias Flash2) */ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM) */ RamLoc40 (rwx) : ORIGIN = 0x10080000, LENGTH = 0xa000 /* 40K bytes (alias RAM2) */ RamAHB32 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32K bytes (alias RAM3) */ RamAHB16 (rwx) : ORIGIN = 0x20008000, LENGTH = 0x4000 /* 16K bytes (alias RAM4) */ RamAHB_ETB16 (rwx) : ORIGIN = 0x2000c000, LENGTH = 0x4000 /* 16K bytes (alias RAM5) */ } /* Define a symbol for the top of each memory region */ __base_MFlashA512 = 0x1a000000 ; /* MFlashA512 */ __base_Flash = 0x1a000000 ; /* Flash */ __top_MFlashA512 = 0x1a000000 + 0x80000 ; /* 512K bytes */ __top_Flash = 0x1a000000 + 0x80000 ; /* 512K bytes */ __base_MFlashB512 = 0x1b000000 ; /* MFlashB512 */ __base_Flash2 = 0x1b000000 ; /* Flash2 */ __top_MFlashB512 = 0x1b000000 + 0x80000 ; /* 512K bytes */ __top_Flash2 = 0x1b000000 + 0x80000 ; /* 512K bytes */ __base_RamLoc32 = 0x10000000 ; /* RamLoc32 */ __base_RAM = 0x10000000 ; /* RAM */ __top_RamLoc32 = 0x10000000 + 0x8000 ; /* 32K bytes */ __top_RAM = 0x10000000 + 0x8000 ; /* 32K bytes */ __base_RamLoc40 = 0x10080000 ; /* RamLoc40 */ __base_RAM2 = 0x10080000 ; /* RAM2 */ __top_RamLoc40 = 0x10080000 + 0xa000 ; /* 40K bytes */ __top_RAM2 = 0x10080000 + 0xa000 ; /* 40K bytes */ __base_RamAHB32 = 0x20000000 ; /* RamAHB32 */ __base_RAM3 = 0x20000000 ; /* RAM3 */ __top_RamAHB32 = 0x20000000 + 0x8000 ; /* 32K bytes */ __top_RAM3 = 0x20000000 + 0x8000 ; /* 32K bytes */ __base_RamAHB16 = 0x20008000 ; /* RamAHB16 */ __base_RAM4 = 0x20008000 ; /* RAM4 */ __top_RamAHB16 = 0x20008000 + 0x4000 ; /* 16K bytes */ __top_RAM4 = 0x20008000 + 0x4000 ; /* 16K bytes */ __base_RamAHB_ETB16 = 0x2000c000 ; /* RamAHB_ETB16 */ __base_RAM5 = 0x2000c000 ; /* RAM5 */ __top_RamAHB_ETB16 = 0x2000c000 + 0x4000 ; /* 16K bytes */ __top_RAM5 = 0x2000c000 + 0x4000 ; /* 16K bytes */ ENTRY(ResetISR) SECTIONS { .text_Flash2 : ALIGN(4) { FILL(0xff) *(.text_Flash2) /* for compatibility with previous releases */ *(.text_MFlashB512) /* for compatibility with previous releases */ *(.text.$Flash2) *(.text.$MFlashB512) *(.text_Flash2.*) /* for compatibility with previous releases */ *(.text_MFlashB512.*) /* for compatibility with previous releases */ *(.text.$Flash2.*) *(.text.$MFlashB512.*) *(.rodata.$Flash2) *(.rodata.$MFlashB512) *(.rodata.$Flash2.*) *(.rodata.$MFlashB512.*) } > MFlashB512 /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.) ; KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); LONG(LOADADDR(.data_RAM3)); LONG( ADDR(.data_RAM3)); LONG( SIZEOF(.data_RAM3)); LONG(LOADADDR(.data_RAM4)); LONG( ADDR(.data_RAM4)); LONG( SIZEOF(.data_RAM4)); LONG(LOADADDR(.data_RAM5)); LONG( ADDR(.data_RAM5)); LONG( SIZEOF(.data_RAM5)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); LONG( ADDR(.bss_RAM3)); LONG( SIZEOF(.bss_RAM3)); LONG( ADDR(.bss_RAM4)); LONG( SIZEOF(.bss_RAM4)); LONG( ADDR(.bss_RAM5)); LONG( SIZEOF(.bss_RAM5)); __bss_section_table_end = .; __section_table_end = . ; /* End of Global Section Table */ *(.after_vectors*) *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlashA512 .ARM.exidx : ALIGN(4) { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > MFlashA512 _etext = .; /* DATA section for RamLoc40 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; PROVIDE(__start_data_RamLoc40 = .) ; *(.ramfunc.$RAM2) *(.ramfunc.$RamLoc40) *(.data.$RAM2) *(.data.$RamLoc40) *(.data.$RAM2.*) *(.data.$RamLoc40.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; PROVIDE(__end_data_RamLoc40 = .) ; } > RamLoc40 AT>MFlashA512 /* DATA section for RamAHB32 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; PROVIDE(__start_data_RamAHB32 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamAHB32) *(.data.$RAM3) *(.data.$RamAHB32) *(.data.$RAM3.*) *(.data.$RamAHB32.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; PROVIDE(__end_data_RamAHB32 = .) ; } > RamAHB32 AT>MFlashA512 /* DATA section for RamAHB16 */ .data_RAM4 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM4 = .) ; PROVIDE(__start_data_RamAHB16 = .) ; *(.ramfunc.$RAM4) *(.ramfunc.$RamAHB16) *(.data.$RAM4) *(.data.$RamAHB16) *(.data.$RAM4.*) *(.data.$RamAHB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM4 = .) ; PROVIDE(__end_data_RamAHB16 = .) ; } > RamAHB16 AT>MFlashA512 /* DATA section for RamAHB_ETB16 */ .data_RAM5 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM5 = .) ; PROVIDE(__start_data_RamAHB_ETB16 = .) ; *(.ramfunc.$RAM5) *(.ramfunc.$RamAHB_ETB16) *(.data.$RAM5) *(.data.$RamAHB_ETB16) *(.data.$RAM5.*) *(.data.$RamAHB_ETB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM5 = .) ; PROVIDE(__end_data_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT>MFlashA512 /* MAIN DATA SECTION */ .uninit_RESERVED (NOLOAD) : ALIGN(4) { _start_uninit_RESERVED = .; KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; } > RamLoc32 AT> RamLoc32 /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; PROVIDE(__start_data_RAM = .) ; PROVIDE(__start_data_RamLoc32 = .) ; *(vtable) *(.ramfunc*) KEEP(*(CodeQuickAccess)) KEEP(*(DataQuickAccess)) *(RamFunction) *(.data*) . = ALIGN(4) ; _edata = . ; PROVIDE(__end_data_RAM = .) ; PROVIDE(__end_data_RamLoc32 = .) ; } > RamLoc32 AT>MFlashA512 /* BSS section for RamLoc40 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .) ; PROVIDE(__start_bss_RamLoc40 = .) ; *(.bss.$RAM2) *(.bss.$RamLoc40) *(.bss.$RAM2.*) *(.bss.$RamLoc40.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; PROVIDE(__end_bss_RamLoc40 = .) ; } > RamLoc40 AT> RamLoc40 /* BSS section for RamAHB32 */ .bss_RAM3 : ALIGN(4) { PROVIDE(__start_bss_RAM3 = .) ; PROVIDE(__start_bss_RamAHB32 = .) ; *(.bss.$RAM3) *(.bss.$RamAHB32) *(.bss.$RAM3.*) *(.bss.$RamAHB32.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; PROVIDE(__end_bss_RamAHB32 = .) ; } > RamAHB32 AT> RamAHB32 /* BSS section for RamAHB16 */ .bss_RAM4 : ALIGN(4) { PROVIDE(__start_bss_RAM4 = .) ; PROVIDE(__start_bss_RamAHB16 = .) ; *(.bss.$RAM4) *(.bss.$RamAHB16) *(.bss.$RAM4.*) *(.bss.$RamAHB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM4 = .) ; PROVIDE(__end_bss_RamAHB16 = .) ; } > RamAHB16 AT> RamAHB16 /* BSS section for RamAHB_ETB16 */ .bss_RAM5 : ALIGN(4) { PROVIDE(__start_bss_RAM5 = .) ; PROVIDE(__start_bss_RamAHB_ETB16 = .) ; *(.bss.$RAM5) *(.bss.$RamAHB_ETB16) *(.bss.$RAM5.*) *(.bss.$RamAHB_ETB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM5 = .) ; PROVIDE(__end_bss_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; PROVIDE(__start_bss_RAM = .) ; PROVIDE(__start_bss_RamLoc32 = .) ; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; /* PROVIDE(end = .);*/ } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; __heap_base = .; __end = .; PROVIDE(end = .); PROVIDE(_end = .); PROVIDE(__end__ = .); KEEP(*(.heap*)) __HeapLimit = .; __heap_limit = .; __heap_end = .; } > RamLoc40 /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM2 = .) ; PROVIDE(__start_noinit_RamLoc40 = .) ; *(.noinit.$RAM2) *(.noinit.$RamLoc40) *(.noinit.$RAM2.*) *(.noinit.$RamLoc40.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM2 = .) ; PROVIDE(__end_noinit_RamLoc40 = .) ; } > RamLoc40 AT> RamLoc40 /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM3 = .) ; PROVIDE(__start_noinit_RamAHB32 = .) ; *(.noinit.$RAM3) *(.noinit.$RamAHB32) *(.noinit.$RAM3.*) *(.noinit.$RamAHB32.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM3 = .) ; PROVIDE(__end_noinit_RamAHB32 = .) ; } > RamAHB32 AT> RamAHB32 /* NOINIT section for RamAHB16 */ .noinit_RAM4 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM4 = .) ; PROVIDE(__start_noinit_RamAHB16 = .) ; *(.noinit.$RAM4) *(.noinit.$RamAHB16) *(.noinit.$RAM4.*) *(.noinit.$RamAHB16.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM4 = .) ; PROVIDE(__end_noinit_RamAHB16 = .) ; } > RamAHB16 AT> RamAHB16 /* NOINIT section for RamAHB_ETB16 */ .noinit_RAM5 (NOLOAD) : ALIGN(4) { PROVIDE(__start_noinit_RAM5 = .) ; PROVIDE(__start_noinit_RamAHB_ETB16 = .) ; *(.noinit.$RAM5) *(.noinit.$RamAHB_ETB16) *(.noinit.$RAM5.*) *(.noinit.$RamAHB_ETB16.*) . = ALIGN(4) ; PROVIDE(__end_noinit_RAM5 = .) ; PROVIDE(__end_noinit_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; PROVIDE(__start_noinit_RAM = .) ; PROVIDE(__start_noinit_RamLoc32 = .) ; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; PROVIDE(__end_noinit_RAM = .) ; PROVIDE(__end_noinit_RamLoc32 = .) ; } > RamLoc32 AT> RamLoc32 /* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ /* PROVIDE(__valid_user_code_checksum = 0 -*/ /* (_vStackTop*/ /* + (ResetISR + 1)*/ /* + (NMI_Handler + 1)*/ /* + (HardFault_Handler + 1)*/ /* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ /* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ /* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ /* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that * these will need extending to give a complete picture with * complex images (e.g multiple Flash banks). */ _image_start = LOADADDR(.text); _image_end = LOADADDR(.data) + SIZEOF(.data); _image_size = _image_end - _image_start; } ================================================ FILE: hw/bsp/lpc43/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" /* System configuration variables used by chip driver */ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; extern void USB0_IRQHandler(void); extern void USB1_IRQHandler(void); extern void SysTick_Handler(void); void SystemInit(void); /*------------------------------------------------------------------*/ /* BOARD API *------------------------------------------------------------------*/ // Invoked by startup code void SystemInit(void) { #ifdef __USE_LPCOPEN unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; #ifdef __ICCARM__ extern void *__vector_table; *pSCB_VTOR = (unsigned int) &__vector_table; #elif defined(__ARMCC_VERSION) extern void *__Vectors; *pSCB_VTOR = (unsigned int) &__Vectors; #else // other compoiler using cr_startup_lpc43xx.c extern void (* const g_pfnVectors[])(void); *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif #if __FPU_USED == 1 fpuInit(); #endif #endif /* Setup system level pin muxing */ Chip_SCU_SetPinMuxing(pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); // /* Clock pins only, group field not used */ // for ( int i = 0; i < (int) (sizeof(pinclockmuxing) / sizeof(pinclockmuxing[0])); i++ ) { // Chip_SCU_ClockPinMuxSet(pinclockmuxing[i].pinnum, pinclockmuxing[i].modefunc); // } Chip_SetupXtalClocking(); } void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif Chip_GPIO_Init(LPC_GPIO_PORT); #ifdef __PCA9532C_H // LED via pca9532 I2C Chip_SCU_I2C0PinConfig(I2C0_STANDARD_FAST_MODE); Chip_I2C_Init(I2C0); Chip_I2C_SetClockRate(I2C0, 100000); Chip_I2C_SetMasterEventHandler(I2C0, Chip_I2C_EventHandlerPolling); pca9532_init(); #else Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED_PORT, LED_PIN); #endif // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); //------------- UART -------------// Chip_UART_Init(UART_DEV); Chip_UART_SetBaud(UART_DEV, CFG_BOARD_UART_BAUDRATE); Chip_UART_ConfigData(UART_DEV, UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS); Chip_UART_TXEnable(UART_DEV); //------------- USB -------------// enum { USBMODE_DEVICE = 2, USBMODE_HOST = 3 }; enum { USBMODE_VBUS_LOW = 0, USBMODE_VBUS_HIGH = 1 }; /* From EA4357 user manual * * USB0 Device operation: * - Insert jumpers in position 1-2 in JP17/JP18/JP19. * - GPIO28 controls USB connect functionality * - LED32 lights when the USB Device is connected. SJ4 has pads 1-2 shorted by default. * - LED33 is controlled by GPIO27 and signals USB-up state. GPIO54 is used for VBUS * sensing. * * USB0 Host operation: * - insert jumpers in position 2-3 in JP17/JP18/JP19. * - USB Host power is controlled via distribution switch U20 (found in schematic page 11). * - Signal GPIO26 is active low and enables +5V on VBUS2. * - LED35 light whenever +5V is present on VBUS2. * - GPIO55 is connected to status feedback from the distribution switch. * - GPIO54 is used for VBUS sensing. 15Kohm pull-down resistors are always active * * Note: * - Insert jumpers in position 2-3 in JP17/JP18/JP19 * - Insert jumpers in JP31 (OTG) */ Chip_USB0_Init(); /* From EA4357 user manual * * For USB1 Device: * - a 1.5Kohm pull-up resistor is needed on the USB DP data signal. There are two methods to create this. * JP15 is inserted and the pull-up resistor is always enabled. Alternatively, the pull-up resistor is activated * inside the USB OTG chip (U31), and this has to be done via the I2C interface of GPIO52/GPIO53. In the latter case, * JP15 shall not be inserted. * - J19 is the connector to use when USB Device is used. Normally it should be a USB-B connector for * creating a USB Device interface, but the mini-AB connector can also be used in this case. The status * of VBUS can be read via U31. * - JP16 shall not be inserted. * * For USB1 Host: * - 15Kohm pull-down resistors are needed on the USB data signals. These are activated inside the USB OTG chip (U31), * and this has to be done via the I2C interface of GPIO52/GPIO53. * - J20 is the connector to use when USB Host is used. In order to provide +5V to the external USB * device connected to this connector (J20), channel A of U20 must be enabled. It is enabled by default * since SJ5 is normally connected between pin 1-2. * - LED34 lights green when +5V is available on J20. * - JP15 shall not be inserted. JP16 has no effect */ Chip_USB1_Init(); #ifdef _BOARD_EA4357_H // USB0 Vbus Power: P2_3 on EA4357 channel B U20 GPIO26 active low (base board) Chip_SCU_PinMuxSet(2, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC7); #endif #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 0 // P9_5 (GPIO5[18]) (GPIO28 on oem base) as USB connect, active low. Chip_SCU_PinMuxSet(9, 5, SCU_MODE_PULLDOWN | SCU_MODE_FUNC4); Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 18); #endif // USB1 Power: EA4357 channel A U20 is enabled by SJ5 connected to pad 1-2, no more action required // TODO Remove R170, R171, solder a pair of 15K to USB1 D+/D- to test with USB1 Host } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { tusb_int_handler(0, true); } void USB1_IRQHandler(void) { tusb_int_handler(1, true); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef __PCA9532C_H if ( state ) { pca9532_setLeds(LED1, 0); } else { pca9532_setLeds(0, LED1); } #else Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state ? LED_STATE_ON : !LED_STATE_ON); #endif } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { if ( max_len < 16 ) return 0; uint32_t* id32 = (uint32_t*) (uintptr_t) id; Chip_IAP_ReadUID(id32); return 16; } int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } int board_uart_write(void const *buf, int len) { uint8_t const *buf8 = (uint8_t const *) buf; for ( int i = 0; i < len; i++ ) { while ( (Chip_UART_ReadLineStatus(UART_DEV) & UART_LSR_THRE) == 0 ) {} Chip_UART_SendByte(UART_DEV, buf8[i]); } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/lpc43/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC43XX CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${SDK_DIR}/../gcc/cr_startup_lpc43xx.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${SDK_DIR}/../iar/iar_startup_lpc18xx43xx.s) set(LD_FILE_IAR ${SDK_DIR}/../iar/linker/lpc18xx_43xx_ldscript_iflash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/src/chip_18xx_43xx.c ${SDK_DIR}/src/clock_18xx_43xx.c ${SDK_DIR}/src/fpu_init.c ${SDK_DIR}/src/gpio_18xx_43xx.c ${SDK_DIR}/src/iap_18xx_43xx.c ${SDK_DIR}/src/sysinit_18xx_43xx.c ${SDK_DIR}/src/uart_18xx_43xx.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN CORE_M4 ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${SDK_DIR}/inc/config_43xx ${CMSIS_5}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) # warning by LPCOpen if (TOOLCHAIN STREQUAL "gcc" OR TOOLCHAIN STREQUAL "clang") set_target_properties(${BOARD_TARGET} PROPERTIES COMPILE_FLAGS -Wno-error=incompatible-pointer-types) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC43XX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c ${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c ${TOP}/src/portable/ehci/ehci.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc43/family.mk ================================================ SDK_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx include ${TOP}/${BOARD_PATH}/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -DCORE_M4 \ -D__USE_LPCOPEN \ -DCFG_TUSB_MCU=OPT_MCU_LPC43XX # mcu driver cause following warnings CFLAGS_GCC += \ -flto \ -nostdlib \ -Wno-error=unused-parameter \ -Wno-error=cast-qual \ -Wno-error=incompatible-pointer-types \ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ src/portable/chipidea/ci_hs/hcd_ci_hs.c \ src/portable/ehci/ehci.c \ ${SDK_DIR}/../gcc/cr_startup_lpc43xx.c \ ${SDK_DIR}/src/chip_18xx_43xx.c \ ${SDK_DIR}/src/clock_18xx_43xx.c \ ${SDK_DIR}/src/fpu_init.c \ ${SDK_DIR}/src/gpio_18xx_43xx.c \ ${SDK_DIR}/src/iap_18xx_43xx.c \ ${SDK_DIR}/src/sysinit_18xx_43xx.c \ ${SDK_DIR}/src/uart_18xx_43xx.c \ INC += \ $(TOP)/$(BOARD_PATH) \ ${TOP}/${SDK_DIR}/inc \ ${TOP}/${SDK_DIR}/inc/config_43xx \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ ================================================ FILE: hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 2 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif GPIO_PortInit(GPIO, LED_PORT); GPIO_PortInit(GPIO, BUTTON_PORT); // LED gpio_pin_config_t const led_config = {kGPIO_DigitalOutput, 0}; GPIO_PinInit(GPIO, LED_PORT, LED_PIN, &led_config); board_led_write(true); // Button gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(GPIO, BUTTON_PORT, BUTTON_PIN, &button_config); // USB const uint32_t port1_pin6_config = ( IOCON_PIO_FUNC7 | /* Pin is configured as USB0_VBUS */ IOCON_PIO_MODE_INACT | /* No addition pin function */ IOCON_PIO_INV_DI | /* Input function is not inverted */ IOCON_PIO_DIGITAL_EN | /* Enables digital function */ IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ ); IOCON_PinMuxSet(IOCON, 1, 6, port1_pin6_config); /* PORT1 PIN6 (coords: 26) is configured as USB0_VBUS */ POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*Turn on USB Phy */ CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); /* enable USB IP clock */ } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { // active low return 1 - GPIO_PinRead(GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/lpc51/family.cmake ================================================ include_guard() set(MCUX_DIR ${TOP}/hw/mcu/nxp/mcuxsdk-core) set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-devices-lpc) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC51 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/gcc/${MCU_VARIANT}_flash.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/iar/${MCU_VARIANT}_flash.icf) endif () if (NOT DEFINED STARTUP_FILE_IAR) set(STARTUP_FILE_IAR ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/iar/startup_${MCU_VARIANT}.s) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver ${MCUX_DIR}/drivers/lpc_gpio/fsl_gpio.c ${MCUX_DIR}/drivers/flexcomm/fsl_flexcomm.c ${MCUX_DIR}/drivers/flexcomm/usart/fsl_usart.c # mcu ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/system_${MCU_VARIANT}.c ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/drivers/fsl_reset.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${TOP}/lib/sct_neopixel # driver ${MCUX_DIR}/drivers/common ${MCUX_DIR}/drivers/common ${MCUX_DIR}/drivers/flexcomm ${MCUX_DIR}/drivers/flexcomm/usart ${MCUX_DIR}/drivers/lpc_iocon ${MCUX_DIR}/drivers/lpc_gpio # mcu ${SDK_DIR}/LPC51U68/${MCU_VARIANT} ${SDK_DIR}/LPC51U68/${MCU_VARIANT}/drivers ${CMSIS_DIR}/CMSIS/Core/Include ${SDK_DIR}/LPC51U68/periph ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) __STARTUP_CLEAR_BSS ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC51) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) #family_flash_pyocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc51/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus MCUX_DIR = /hw/mcu/nxp/mcuxsdk-core SDK_DIR = /hw/mcu/nxp/mcux-devices-lpc CFLAGS += \ -flto \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC51UXX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ # All source paths should be relative to the top level. LD_FILE = $(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/gcc/$(MCU_VARIANT)_flash.ld SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/system_$(MCU_VARIANT).c \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/drivers/fsl_power.c \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/drivers/fsl_reset.c \ $(TOP)/$(MCUX_DIR)/drivers/lpc_gpio/fsl_gpio.c \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/fsl_flexcomm.c \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/usart/fsl_usart.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT) \ $(TOP)/$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/drivers \ $(TOP)/$(SDK_DIR)/LPC51U68/periph \ $(TOP)/$(MCUX_DIR)/drivers/common \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/usart \ $(TOP)/$(MCUX_DIR)/drivers/lpc_iocon \ $(TOP)/$(MCUX_DIR)/drivers/lpc_gpio SRC_S += $(TOP)$(SDK_DIR)/LPC51U68/$(MCU_VARIANT)/gcc/startup_$(MCU_VARIANT).S ================================================ FILE: hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif // Init all GPIO ports 54114 only has 2 ports. GPIO_PortInit(GPIO, LED_PORT); GPIO_PortInit(GPIO, BUTTON_PORT); // LED IOCON_PinMuxSet(IOCON, LED_PORT, LED_PIN, IOCON_PIO_DIG_FUNC0_EN); gpio_pin_config_t const led_config = { kGPIO_DigitalOutput, 0}; GPIO_PinInit(GPIO, LED_PORT, LED_PIN, &led_config); board_led_write(0); // Button IOCON_PinMuxSet(IOCON, BUTTON_PORT, BUTTON_PIN, IOCON_PIO_DIG_FUNC0_EN | IOCON_PIO_MODE_PULLUP); gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; GPIO_PinInit(GPIO, BUTTON_PORT, BUTTON_PIN, &button_config); #ifdef UART_DEV // UART IOCON_PinMuxSet(IOCON, UART_RX_PINMUX); IOCON_PinMuxSet(IOCON, UART_TX_PINMUX); // Enable UART when debug log is on CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0); usart_config_t uart_config; USART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; USART_Init(UART_DEV, &uart_config, 12000000); #endif #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT // LPC546xx and LPC540xx has OTG 1 FS + 1 HS rhports #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0) /* PORT0 PIN22 configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, USB0_VBUS_PINMUX); // Port0 is Full Speed POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB Phy */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); CLOCK_AttachClk(kFRO_HF_to_USB0_CLK); if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) { /*According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbhsl0); /* enable usb0 host clock */ USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbhsl0); /* disable usb0 host clock */ CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); } else { #ifdef USBFS_POWER_PORT /* Configure USB0 Power Switch Pin */ IOCON_PinMuxSet(IOCON, USBFS_POWER_PORT, USBFS_POWER_PIN, IOCON_PIO_DIG_FUNC0_EN); gpio_pin_config_t const power_pin_config = {kGPIO_DigitalOutput, USBFS_POWER_STATE_ON}; GPIO_PinInit(GPIO, USBFS_POWER_PORT, USBFS_POWER_PIN, &power_pin_config); #endif CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbSrcFro, CLOCK_GetFroHfFreq()); USBFSH->PORTMODE &= ~USBFSH_PORTMODE_DEV_ENABLE_MASK; } #endif #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) // Port1 is High Speed /* Turn on USB1 Phy */ POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* reset the IP to make sure it's in reset state. */ RESET_PeripheralReset(kUSB1H_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1D_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn); if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) { /* According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbh1); // enable usb0 host clock USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK; // Put PHY powerdown under software control USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbh1); // disable usb0 host clock /* enable USB Device clock */ CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUsbPll, 0U); } else { #ifdef USBHS_POWER_PORT /* Configure USB1 Power Switch Pin */ IOCON_PinMuxSet(IOCON, USBHS_POWER_PORT, USBHS_POWER_PIN, IOCON_PIO_DIG_FUNC0_EN); gpio_pin_config_t const power_pin_config = {kGPIO_DigitalOutput, USBHS_POWER_STATE_ON}; GPIO_PinInit(GPIO, USBHS_POWER_PORT, USBHS_POWER_PIN, &power_pin_config); #endif CLOCK_EnableUsbhs0HostClock(kCLOCK_UsbSrcUsbPll, 0U); } #endif #else IOCON_PinMuxSet(IOCON, USB0_VBUS_PINMUX); // LPC5411x series only has full speed device POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); // Turn on USB Phy CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); /* enable USB IP clock */ #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { // active low return BUTTON_STATE_ACTIVE == GPIO_PinRead(GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/lpc54/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC54 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- # default device port to USB1 highspeed, host to USB0 fullspeed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif () # port 0 is fullspeed, port 1 is highspeed set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/iar/${MCU_CORE}_flash.icf) endif () if (NOT DEFINED STARTUP_FILE_IAR) set(STARTUP_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/iar/startup_${MCU_CORE}.s) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c ${SDK_DIR}/drivers/common/fsl_common_arm.c ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c ${SDK_DIR}/drivers/flexcomm/usart/fsl_usart.c # mcu ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${TOP}/lib/sct_neopixel # driver ${SDK_DIR}/drivers/common ${SDK_DIR}/drivers/flexcomm ${SDK_DIR}/drivers/flexcomm/usart ${SDK_DIR}/drivers/lpc_iocon ${SDK_DIR}/drivers/lpc_gpio ${SDK_DIR}/drivers/lpuart ${SDK_DIR}/drivers/sctimer # mcu ${SDK_DIR}/devices/${MCU_VARIANT} ${SDK_DIR}/devices/${MCU_VARIANT}/drivers ${CMSIS_DIR}/CMSIS/Core/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} __STARTUP_CLEAR_BSS ) # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM if (RHPORT_DEVICE EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC [=[CFG_TUD_MEM_SECTION=__attribute__((section("m_usb_global")))]=] ) endif () if (RHPORT_HOST EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC [=[CFG_TUH_MEM_SECTION=__attribute__((section("m_usb_global")))]=] CFG_TUH_USBIP_IP3516=1 ) endif () update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC54) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (RHPORT_HOST EQUAL 0) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/ohci/ohci.c ) elseif (RHPORT_HOST EQUAL 1) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles "LINKER:--defsym=__stack_size__=0x1000" "LINKER:--defsym=__heap_size__=0" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" "LINKER:--config_def=__stack_size__=0x1000" "LINKER:--config_def=__heap_size__=0" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) #family_flash_pyocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc54/family.mk ================================================ SDK_DIR = hw/mcu/nxp/mcux-sdk include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) CFLAGS += \ -flto \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC54XXX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ ifeq ($(PORT), 1) $(info "PORT1 High Speed") CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED CFLAGS += -DBOARD_TUD_RHPORT=1 # LPC55 Highspeed Port1 can only write to USB_SRAM region CFLAGS += -DCFG_TUSB_MEM_SECTION='__attribute__((section("m_usb_global")))' else $(info "PORT0 Full Speed") endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(MCU_DIR)/system_$(MCU_CORE).c \ $(MCU_DIR)/drivers/fsl_clock.c \ $(MCU_DIR)/drivers/fsl_power.c \ $(MCU_DIR)/drivers/fsl_reset.c \ $(SDK_DIR)/drivers/lpc_gpio/fsl_gpio.c \ $(SDK_DIR)/drivers/flexcomm/fsl_flexcomm.c \ $(SDK_DIR)/drivers/flexcomm/usart/fsl_usart.c \ $(SDK_DIR)/drivers/common/fsl_common_arm.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/drivers \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/flexcomm \ $(TOP)/$(SDK_DIR)/drivers/flexcomm/usart \ $(TOP)/$(SDK_DIR)/drivers/lpc_iocon \ $(TOP)/$(SDK_DIR)/drivers/lpc_gpio SRC_S += $(MCU_DIR)/gcc/startup_$(MCU_CORE).S ================================================ FILE: hw/bsp/lpc54/iar/LPC54608_flash.icf ================================================ /* ** ################################################################### ** Processors: LPC54608J512BD208 ** LPC54608J512ET180 ** ** Compiler: IAR ANSI C/C++ Compiler for ARM ** Reference manual: LPC546xx User manual Rev.1.9 5 June 2017 ** Version: rev. 1.2, 2017-06-08 ** Build: b241125 ** ** Abstract: ** Linker file for the IAR ANSI C/C++ Compiler for ARM ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2024 NXP ** SPDX-License-Identifier: BSD-3-Clause ** ** http: www.nxp.com ** mail: support@nxp.com ** ** ################################################################### */ define symbol m_interrupts_start = 0x00000000; define symbol m_interrupts_end = 0x000003FF; define symbol m_text_start = 0x00000400; define symbol m_text_end = 0x0007FFFF; define symbol m_data_start = 0x20000000; define symbol m_data_end = 0x20027FFF; define symbol m_usb_sram_start = 0x40100000; define symbol m_usb_sram_end = 0x40101FFF; /* USB BDT size */ define symbol usb_bdt_size = 0x0; /* Sizes */ if (isdefinedsymbol(__stack_size__)) { define symbol __size_cstack__ = __stack_size__; } else { define symbol __size_cstack__ = 0x0400; } if (isdefinedsymbol(__heap_size__)) { define symbol __size_heap__ = __heap_size__; } else { define symbol __size_heap__ = 0x0400; } define memory mem with size = 4G; define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] | mem:[from m_text_start to m_text_end]; define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; define block CSTACK with alignment = 8, size = __size_cstack__ { }; define block HEAP with alignment = 8, size = __size_heap__ { }; define block RW { readwrite }; define block ZI { zi }; /* regions for USB */ define region USB_BDT_region = mem:[from m_usb_sram_start to m_usb_sram_start + usb_bdt_size - 1]; define region USB_SRAM_region = mem:[from m_usb_sram_start + usb_bdt_size to m_usb_sram_end]; place in USB_BDT_region { section m_usb_bdt }; place in USB_SRAM_region { section m_usb_global }; initialize by copy { readwrite, section .textrw }; if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) { /* Required in a multi-threaded application */ initialize by copy with packing = none { section __DLIB_PERTHREAD }; } do not initialize { section .noinit, section m_usb_bdt, section m_usb_global }; place at address mem: m_interrupts_start { readonly section .intvec }; place in TEXT_region { readonly }; place in DATA_region { block RW }; place in DATA_region { block ZI }; place in DATA_region { last block HEAP }; place in CSTACK_region { block CSTACK }; ================================================ FILE: hw/bsp/lpc54/iar/LPC54628_flash.icf ================================================ /* ** ################################################################### ** Processor: LPC54628J512ET180 ** Compiler: IAR ANSI C/C++ Compiler for ARM ** Reference manual: LPC546xx User manual Rev.1.9 5 June 2017 ** Version: rev. 1.2, 2017-06-08 ** Build: b241125 ** ** Abstract: ** Linker file for the IAR ANSI C/C++ Compiler for ARM ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2024 NXP ** SPDX-License-Identifier: BSD-3-Clause ** ** http: www.nxp.com ** mail: support@nxp.com ** ** ################################################################### */ define symbol m_interrupts_start = 0x00000000; define symbol m_interrupts_end = 0x000003FF; define symbol m_text_start = 0x00000400; define symbol m_text_end = 0x0007FFFF; define symbol m_data_start = 0x20000000; define symbol m_data_end = 0x20027FFF; define symbol m_usb_sram_start = 0x40100000; define symbol m_usb_sram_end = 0x40101FFF; /* USB BDT size */ define symbol usb_bdt_size = 0x0; /* Sizes */ if (isdefinedsymbol(__stack_size__)) { define symbol __size_cstack__ = __stack_size__; } else { define symbol __size_cstack__ = 0x0400; } if (isdefinedsymbol(__heap_size__)) { define symbol __size_heap__ = __heap_size__; } else { define symbol __size_heap__ = 0x0400; } define memory mem with size = 4G; define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] | mem:[from m_text_start to m_text_end]; define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; define block CSTACK with alignment = 8, size = __size_cstack__ { }; define block HEAP with alignment = 8, size = __size_heap__ { }; define block RW { readwrite }; define block ZI { zi }; /* regions for USB */ define region USB_BDT_region = mem:[from m_usb_sram_start to m_usb_sram_start + usb_bdt_size - 1]; define region USB_SRAM_region = mem:[from m_usb_sram_start + usb_bdt_size to m_usb_sram_end]; place in USB_BDT_region { section m_usb_bdt }; place in USB_SRAM_region { section m_usb_global }; initialize by copy { readwrite, section .textrw }; if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) { /* Required in a multi-threaded application */ initialize by copy with packing = none { section __DLIB_PERTHREAD }; } do not initialize { section .noinit, section m_usb_bdt, section m_usb_global }; place at address mem: m_interrupts_start { readonly section .intvec }; place in TEXT_region { readonly }; place in DATA_region { block RW }; place in DATA_region { block ZI }; place in DATA_region { last block HEAP }; place in CSTACK_region { block CSTACK }; ================================================ FILE: hw/bsp/lpc54/iar/startup_LPC54608.s ================================================ ; ------------------------------------------------------------------------- ; @file: startup_LPC54608.s ; @purpose: CMSIS Cortex-M4 Core Device Startup File ; LPC54608 ; @version: 2.0 ; @date: 2024-10-29 ; @build: b250521 ; ------------------------------------------------------------------------- ; ; Copyright 1997-2016 Freescale Semiconductor, Inc. ; Copyright 2016-2025 NXP ; SPDX-License-Identifier: BSD-3-Clause ; ; The modules in this file are included in the libraries, and may be replaced ; by any user-defined modules that define the PUBLIC symbol _program_start or ; a user defined start symbol. ; To override the cstartup defined in the library, simply add your modified ; version to the workbench project. ; ; The vector table is normally located at address 0. ; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. ; The name "__vector_table" has special meaning for C-SPY: ; it is where the SP start value is found, and the NVIC vector ; table register (VTOR) is initialized to this address if != 0. ; ; Cortex-M version ; MODULE ?cstartup ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start EXTERN SystemInit PUBLIC __vector_table PUBLIC __vector_table_0x1c PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size DATA __iar_init$$done: ; The vector table is not needed ; until after copy initialization is done __vector_table DCD sfe(CSTACK) DCD Reset_Handler DCD NMI_Handler ;NMI Handler DCD HardFault_Handler ;Hard Fault Handler DCD MemManage_Handler ;MPU Fault Handler DCD BusFault_Handler ;Bus Fault Handler DCD UsageFault_Handler ;Usage Fault Handler __vector_table_0x1c DCD 0 ;Reserved DCD 0xFFFFFFFF ;ECRP DCD 0 ;Reserved DCD 0 ;Reserved DCD SVC_Handler ;SVCall Handler DCD DebugMon_Handler ;Debug Monitor Handler DCD 0 ;Reserved DCD PendSV_Handler ;PendSV Handler DCD SysTick_Handler ;SysTick Handler ;External Interrupts DCD WDT_BOD_IRQHandler ;Windowed watchdog timer, Brownout detect DCD DMA0_IRQHandler ;DMA controller DCD GINT0_IRQHandler ;GPIO group 0 DCD GINT1_IRQHandler ;GPIO group 1 DCD PIN_INT0_IRQHandler ;Pin interrupt 0 or pattern match engine slice 0 DCD PIN_INT1_IRQHandler ;Pin interrupt 1or pattern match engine slice 1 DCD PIN_INT2_IRQHandler ;Pin interrupt 2 or pattern match engine slice 2 DCD PIN_INT3_IRQHandler ;Pin interrupt 3 or pattern match engine slice 3 DCD UTICK0_IRQHandler ;Micro-tick Timer DCD MRT0_IRQHandler ;Multi-rate timer DCD CTIMER0_IRQHandler ;Standard counter/timer CTIMER0 DCD CTIMER1_IRQHandler ;Standard counter/timer CTIMER1 DCD SCT0_IRQHandler ;SCTimer/PWM DCD CTIMER3_IRQHandler ;Standard counter/timer CTIMER3 DCD FLEXCOMM0_IRQHandler ;Flexcomm Interface 0 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM1_IRQHandler ;Flexcomm Interface 1 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM2_IRQHandler ;Flexcomm Interface 2 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM3_IRQHandler ;Flexcomm Interface 3 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM4_IRQHandler ;Flexcomm Interface 4 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM5_IRQHandler ;Flexcomm Interface 5 (USART, SPI, I2C,, FLEXCOMM) DCD FLEXCOMM6_IRQHandler ;Flexcomm Interface 6 (USART, SPI, I2C, I2S,, FLEXCOMM) DCD FLEXCOMM7_IRQHandler ;Flexcomm Interface 7 (USART, SPI, I2C, I2S,, FLEXCOMM) DCD ADC0_SEQA_IRQHandler ;ADC0 sequence A completion. DCD ADC0_SEQB_IRQHandler ;ADC0 sequence B completion. DCD ADC0_THCMP_IRQHandler ;ADC0 threshold compare and error. DCD DMIC0_IRQHandler ;Digital microphone and DMIC subsystem DCD HWVAD0_IRQHandler ;Hardware Voice Activity Detector DCD USB0_NEEDCLK_IRQHandler ;USB Activity Wake-up Interrupt DCD USB0_IRQHandler ;USB device DCD RTC_IRQHandler ;RTC alarm and wake-up interrupts DCD Reserved46_IRQHandler ;Reserved interrupt DCD Reserved47_IRQHandler ;Reserved interrupt DCD PIN_INT4_IRQHandler ;Pin interrupt 4 or pattern match engine slice 4 int DCD PIN_INT5_IRQHandler ;Pin interrupt 5 or pattern match engine slice 5 int DCD PIN_INT6_IRQHandler ;Pin interrupt 6 or pattern match engine slice 6 int DCD PIN_INT7_IRQHandler ;Pin interrupt 7 or pattern match engine slice 7 int DCD CTIMER2_IRQHandler ;Standard counter/timer CTIMER2 DCD CTIMER4_IRQHandler ;Standard counter/timer CTIMER4 DCD RIT_IRQHandler ;Repetitive Interrupt Timer DCD SPIFI0_IRQHandler ;SPI flash interface DCD FLEXCOMM8_IRQHandler ;Flexcomm Interface 8 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM9_IRQHandler ;Flexcomm Interface 9 (USART, SPI, I2C, FLEXCOMM) DCD SDIO_IRQHandler ;SD/MMC DCD CAN0_IRQ0_IRQHandler ;CAN0 interrupt0 DCD CAN0_IRQ1_IRQHandler ;CAN0 interrupt1 DCD CAN1_IRQ0_IRQHandler ;CAN1 interrupt0 DCD CAN1_IRQ1_IRQHandler ;CAN1 interrupt1 DCD USB1_IRQHandler ;USB1 interrupt DCD USB1_NEEDCLK_IRQHandler ;USB1 activity DCD ETHERNET_IRQHandler ;Ethernet DCD ETHERNET_PMT_IRQHandler ;Ethernet power management interrupt DCD ETHERNET_MACLP_IRQHandler ;Ethernet MAC interrupt DCD EEPROM_IRQHandler ;EEPROM interrupt DCD LCD_IRQHandler ;LCD interrupt DCD SHA_IRQHandler ;SHA interrupt DCD SMARTCARD0_IRQHandler ;Smart card 0 interrupt DCD SMARTCARD1_IRQHandler ;Smart card 1 interrupt __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Default interrupt handlers. ;; THUMB PUBWEAK Reset_Handler SECTION .text:CODE:REORDER:NOROOT(2) Reset_Handler MOVS r0,#56 LDR r1, =0x40000220 STR r0, [r1] ;Enable SRAM clock used by Stack LDR R0, =SystemInit BLX R0 LDR R0, =__iar_program_start BX R0 PUBWEAK NMI_Handler SECTION .text:CODE:REORDER:NOROOT(1) NMI_Handler B . PUBWEAK HardFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) HardFault_Handler B . PUBWEAK MemManage_Handler SECTION .text:CODE:REORDER:NOROOT(1) MemManage_Handler B . PUBWEAK BusFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) BusFault_Handler B . PUBWEAK UsageFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) UsageFault_Handler B . PUBWEAK SVC_Handler SECTION .text:CODE:REORDER:NOROOT(1) SVC_Handler B . PUBWEAK DebugMon_Handler SECTION .text:CODE:REORDER:NOROOT(1) DebugMon_Handler B . PUBWEAK PendSV_Handler SECTION .text:CODE:REORDER:NOROOT(1) PendSV_Handler B . PUBWEAK SysTick_Handler SECTION .text:CODE:REORDER:NOROOT(1) SysTick_Handler B . PUBWEAK WDT_BOD_IRQHandler PUBWEAK WDT_BOD_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) WDT_BOD_IRQHandler LDR R0, =WDT_BOD_DriverIRQHandler BX R0 PUBWEAK DMA0_IRQHandler PUBWEAK DMA0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) DMA0_IRQHandler LDR R0, =DMA0_DriverIRQHandler BX R0 PUBWEAK GINT0_IRQHandler PUBWEAK GINT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) GINT0_IRQHandler LDR R0, =GINT0_DriverIRQHandler BX R0 PUBWEAK GINT1_IRQHandler PUBWEAK GINT1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) GINT1_IRQHandler LDR R0, =GINT1_DriverIRQHandler BX R0 PUBWEAK PIN_INT0_IRQHandler PUBWEAK PIN_INT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT0_IRQHandler LDR R0, =PIN_INT0_DriverIRQHandler BX R0 PUBWEAK PIN_INT1_IRQHandler PUBWEAK PIN_INT1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT1_IRQHandler LDR R0, =PIN_INT1_DriverIRQHandler BX R0 PUBWEAK PIN_INT2_IRQHandler PUBWEAK PIN_INT2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT2_IRQHandler LDR R0, =PIN_INT2_DriverIRQHandler BX R0 PUBWEAK PIN_INT3_IRQHandler PUBWEAK PIN_INT3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT3_IRQHandler LDR R0, =PIN_INT3_DriverIRQHandler BX R0 PUBWEAK UTICK0_IRQHandler PUBWEAK UTICK0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) UTICK0_IRQHandler LDR R0, =UTICK0_DriverIRQHandler BX R0 PUBWEAK MRT0_IRQHandler PUBWEAK MRT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) MRT0_IRQHandler LDR R0, =MRT0_DriverIRQHandler BX R0 PUBWEAK CTIMER0_IRQHandler PUBWEAK CTIMER0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER0_IRQHandler LDR R0, =CTIMER0_DriverIRQHandler BX R0 PUBWEAK CTIMER1_IRQHandler PUBWEAK CTIMER1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER1_IRQHandler LDR R0, =CTIMER1_DriverIRQHandler BX R0 PUBWEAK SCT0_IRQHandler PUBWEAK SCT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SCT0_IRQHandler LDR R0, =SCT0_DriverIRQHandler BX R0 PUBWEAK CTIMER3_IRQHandler PUBWEAK CTIMER3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER3_IRQHandler LDR R0, =CTIMER3_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM0_IRQHandler PUBWEAK FLEXCOMM0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM0_IRQHandler LDR R0, =FLEXCOMM0_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM1_IRQHandler PUBWEAK FLEXCOMM1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM1_IRQHandler LDR R0, =FLEXCOMM1_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM2_IRQHandler PUBWEAK FLEXCOMM2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM2_IRQHandler LDR R0, =FLEXCOMM2_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM3_IRQHandler PUBWEAK FLEXCOMM3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM3_IRQHandler LDR R0, =FLEXCOMM3_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM4_IRQHandler PUBWEAK FLEXCOMM4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM4_IRQHandler LDR R0, =FLEXCOMM4_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM5_IRQHandler PUBWEAK FLEXCOMM5_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM5_IRQHandler LDR R0, =FLEXCOMM5_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM6_IRQHandler PUBWEAK FLEXCOMM6_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM6_IRQHandler LDR R0, =FLEXCOMM6_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM7_IRQHandler PUBWEAK FLEXCOMM7_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM7_IRQHandler LDR R0, =FLEXCOMM7_DriverIRQHandler BX R0 PUBWEAK ADC0_SEQA_IRQHandler PUBWEAK ADC0_SEQA_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_SEQA_IRQHandler LDR R0, =ADC0_SEQA_DriverIRQHandler BX R0 PUBWEAK ADC0_SEQB_IRQHandler PUBWEAK ADC0_SEQB_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_SEQB_IRQHandler LDR R0, =ADC0_SEQB_DriverIRQHandler BX R0 PUBWEAK ADC0_THCMP_IRQHandler PUBWEAK ADC0_THCMP_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_THCMP_IRQHandler LDR R0, =ADC0_THCMP_DriverIRQHandler BX R0 PUBWEAK DMIC0_IRQHandler PUBWEAK DMIC0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) DMIC0_IRQHandler LDR R0, =DMIC0_DriverIRQHandler BX R0 PUBWEAK HWVAD0_IRQHandler PUBWEAK HWVAD0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) HWVAD0_IRQHandler LDR R0, =HWVAD0_DriverIRQHandler BX R0 PUBWEAK USB0_NEEDCLK_IRQHandler PUBWEAK USB0_NEEDCLK_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB0_NEEDCLK_IRQHandler LDR R0, =USB0_NEEDCLK_DriverIRQHandler BX R0 PUBWEAK USB0_IRQHandler PUBWEAK USB0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB0_IRQHandler LDR R0, =USB0_DriverIRQHandler BX R0 PUBWEAK RTC_IRQHandler PUBWEAK RTC_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) RTC_IRQHandler LDR R0, =RTC_DriverIRQHandler BX R0 PUBWEAK Reserved46_IRQHandler PUBWEAK Reserved46_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) Reserved46_IRQHandler LDR R0, =Reserved46_DriverIRQHandler BX R0 PUBWEAK Reserved47_IRQHandler PUBWEAK Reserved47_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) Reserved47_IRQHandler LDR R0, =Reserved47_DriverIRQHandler BX R0 PUBWEAK PIN_INT4_IRQHandler PUBWEAK PIN_INT4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT4_IRQHandler LDR R0, =PIN_INT4_DriverIRQHandler BX R0 PUBWEAK PIN_INT5_IRQHandler PUBWEAK PIN_INT5_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT5_IRQHandler LDR R0, =PIN_INT5_DriverIRQHandler BX R0 PUBWEAK PIN_INT6_IRQHandler PUBWEAK PIN_INT6_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT6_IRQHandler LDR R0, =PIN_INT6_DriverIRQHandler BX R0 PUBWEAK PIN_INT7_IRQHandler PUBWEAK PIN_INT7_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT7_IRQHandler LDR R0, =PIN_INT7_DriverIRQHandler BX R0 PUBWEAK CTIMER2_IRQHandler PUBWEAK CTIMER2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER2_IRQHandler LDR R0, =CTIMER2_DriverIRQHandler BX R0 PUBWEAK CTIMER4_IRQHandler PUBWEAK CTIMER4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER4_IRQHandler LDR R0, =CTIMER4_DriverIRQHandler BX R0 PUBWEAK RIT_IRQHandler PUBWEAK RIT_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) RIT_IRQHandler LDR R0, =RIT_DriverIRQHandler BX R0 PUBWEAK SPIFI0_IRQHandler PUBWEAK SPIFI0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SPIFI0_IRQHandler LDR R0, =SPIFI0_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM8_IRQHandler PUBWEAK FLEXCOMM8_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM8_IRQHandler LDR R0, =FLEXCOMM8_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM9_IRQHandler PUBWEAK FLEXCOMM9_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM9_IRQHandler LDR R0, =FLEXCOMM9_DriverIRQHandler BX R0 PUBWEAK SDIO_IRQHandler PUBWEAK SDIO_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SDIO_IRQHandler LDR R0, =SDIO_DriverIRQHandler BX R0 PUBWEAK CAN0_IRQ0_IRQHandler PUBWEAK CAN0_IRQ0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN0_IRQ0_IRQHandler LDR R0, =CAN0_IRQ0_DriverIRQHandler BX R0 PUBWEAK CAN0_IRQ1_IRQHandler PUBWEAK CAN0_IRQ1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN0_IRQ1_IRQHandler LDR R0, =CAN0_IRQ1_DriverIRQHandler BX R0 PUBWEAK CAN1_IRQ0_IRQHandler PUBWEAK CAN1_IRQ0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN1_IRQ0_IRQHandler LDR R0, =CAN1_IRQ0_DriverIRQHandler BX R0 PUBWEAK CAN1_IRQ1_IRQHandler PUBWEAK CAN1_IRQ1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN1_IRQ1_IRQHandler LDR R0, =CAN1_IRQ1_DriverIRQHandler BX R0 PUBWEAK USB1_IRQHandler PUBWEAK USB1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB1_IRQHandler LDR R0, =USB1_DriverIRQHandler BX R0 PUBWEAK USB1_NEEDCLK_IRQHandler PUBWEAK USB1_NEEDCLK_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB1_NEEDCLK_IRQHandler LDR R0, =USB1_NEEDCLK_DriverIRQHandler BX R0 PUBWEAK ETHERNET_IRQHandler PUBWEAK ETHERNET_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_IRQHandler LDR R0, =ETHERNET_DriverIRQHandler BX R0 PUBWEAK ETHERNET_PMT_IRQHandler PUBWEAK ETHERNET_PMT_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_PMT_IRQHandler LDR R0, =ETHERNET_PMT_DriverIRQHandler BX R0 PUBWEAK ETHERNET_MACLP_IRQHandler PUBWEAK ETHERNET_MACLP_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_MACLP_IRQHandler LDR R0, =ETHERNET_MACLP_DriverIRQHandler BX R0 PUBWEAK EEPROM_IRQHandler PUBWEAK EEPROM_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) EEPROM_IRQHandler LDR R0, =EEPROM_DriverIRQHandler BX R0 PUBWEAK LCD_IRQHandler PUBWEAK LCD_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) LCD_IRQHandler LDR R0, =LCD_DriverIRQHandler BX R0 PUBWEAK SHA_IRQHandler PUBWEAK SHA_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SHA_IRQHandler LDR R0, =SHA_DriverIRQHandler BX R0 PUBWEAK SMARTCARD0_IRQHandler PUBWEAK SMARTCARD0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SMARTCARD0_IRQHandler LDR R0, =SMARTCARD0_DriverIRQHandler BX R0 PUBWEAK SMARTCARD1_IRQHandler PUBWEAK SMARTCARD1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SMARTCARD1_IRQHandler LDR R0, =SMARTCARD1_DriverIRQHandler BX R0 WDT_BOD_DriverIRQHandler DMA0_DriverIRQHandler GINT0_DriverIRQHandler GINT1_DriverIRQHandler PIN_INT0_DriverIRQHandler PIN_INT1_DriverIRQHandler PIN_INT2_DriverIRQHandler PIN_INT3_DriverIRQHandler UTICK0_DriverIRQHandler MRT0_DriverIRQHandler CTIMER0_DriverIRQHandler CTIMER1_DriverIRQHandler SCT0_DriverIRQHandler CTIMER3_DriverIRQHandler FLEXCOMM0_DriverIRQHandler FLEXCOMM1_DriverIRQHandler FLEXCOMM2_DriverIRQHandler FLEXCOMM3_DriverIRQHandler FLEXCOMM4_DriverIRQHandler FLEXCOMM5_DriverIRQHandler FLEXCOMM6_DriverIRQHandler FLEXCOMM7_DriverIRQHandler ADC0_SEQA_DriverIRQHandler ADC0_SEQB_DriverIRQHandler ADC0_THCMP_DriverIRQHandler DMIC0_DriverIRQHandler HWVAD0_DriverIRQHandler USB0_NEEDCLK_DriverIRQHandler USB0_DriverIRQHandler RTC_DriverIRQHandler Reserved46_DriverIRQHandler Reserved47_DriverIRQHandler PIN_INT4_DriverIRQHandler PIN_INT5_DriverIRQHandler PIN_INT6_DriverIRQHandler PIN_INT7_DriverIRQHandler CTIMER2_DriverIRQHandler CTIMER4_DriverIRQHandler RIT_DriverIRQHandler SPIFI0_DriverIRQHandler FLEXCOMM8_DriverIRQHandler FLEXCOMM9_DriverIRQHandler SDIO_DriverIRQHandler CAN0_IRQ0_DriverIRQHandler CAN0_IRQ1_DriverIRQHandler CAN1_IRQ0_DriverIRQHandler CAN1_IRQ1_DriverIRQHandler USB1_DriverIRQHandler USB1_NEEDCLK_DriverIRQHandler ETHERNET_DriverIRQHandler ETHERNET_PMT_DriverIRQHandler ETHERNET_MACLP_DriverIRQHandler EEPROM_DriverIRQHandler LCD_DriverIRQHandler SHA_DriverIRQHandler SMARTCARD0_DriverIRQHandler SMARTCARD1_DriverIRQHandler DefaultISR B . END ================================================ FILE: hw/bsp/lpc54/iar/startup_LPC54628.s ================================================ ; ------------------------------------------------------------------------- ; @file: startup_LPC54628.s ; @purpose: CMSIS Cortex-M4 Core Device Startup File ; LPC54628 ; @version: 2.0 ; @date: 2024-10-29 ; @build: b250521 ; ------------------------------------------------------------------------- ; ; Copyright 1997-2016 Freescale Semiconductor, Inc. ; Copyright 2016-2025 NXP ; SPDX-License-Identifier: BSD-3-Clause ; ; The modules in this file are included in the libraries, and may be replaced ; by any user-defined modules that define the PUBLIC symbol _program_start or ; a user defined start symbol. ; To override the cstartup defined in the library, simply add your modified ; version to the workbench project. ; ; The vector table is normally located at address 0. ; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. ; The name "__vector_table" has special meaning for C-SPY: ; it is where the SP start value is found, and the NVIC vector ; table register (VTOR) is initialized to this address if != 0. ; ; Cortex-M version ; MODULE ?cstartup ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start EXTERN SystemInit PUBLIC __vector_table PUBLIC __vector_table_0x1c PUBLIC __Vectors PUBLIC __Vectors_End PUBLIC __Vectors_Size DATA __iar_init$$done: ; The vector table is not needed ; until after copy initialization is done __vector_table DCD sfe(CSTACK) DCD Reset_Handler DCD NMI_Handler ;NMI Handler DCD HardFault_Handler ;Hard Fault Handler DCD MemManage_Handler ;MPU Fault Handler DCD BusFault_Handler ;Bus Fault Handler DCD UsageFault_Handler ;Usage Fault Handler __vector_table_0x1c DCD 0 ;Reserved DCD 0xFFFFFFFF ;ECRP DCD 0 ;Reserved DCD 0 ;Reserved DCD SVC_Handler ;SVCall Handler DCD DebugMon_Handler ;Debug Monitor Handler DCD 0 ;Reserved DCD PendSV_Handler ;PendSV Handler DCD SysTick_Handler ;SysTick Handler ;External Interrupts DCD WDT_BOD_IRQHandler ;Windowed watchdog timer, Brownout detect DCD DMA0_IRQHandler ;DMA controller DCD GINT0_IRQHandler ;GPIO group 0 DCD GINT1_IRQHandler ;GPIO group 1 DCD PIN_INT0_IRQHandler ;Pin interrupt 0 or pattern match engine slice 0 DCD PIN_INT1_IRQHandler ;Pin interrupt 1or pattern match engine slice 1 DCD PIN_INT2_IRQHandler ;Pin interrupt 2 or pattern match engine slice 2 DCD PIN_INT3_IRQHandler ;Pin interrupt 3 or pattern match engine slice 3 DCD UTICK0_IRQHandler ;Micro-tick Timer DCD MRT0_IRQHandler ;Multi-rate timer DCD CTIMER0_IRQHandler ;Standard counter/timer CTIMER0 DCD CTIMER1_IRQHandler ;Standard counter/timer CTIMER1 DCD SCT0_IRQHandler ;SCTimer/PWM DCD CTIMER3_IRQHandler ;Standard counter/timer CTIMER3 DCD FLEXCOMM0_IRQHandler ;Flexcomm Interface 0 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM1_IRQHandler ;Flexcomm Interface 1 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM2_IRQHandler ;Flexcomm Interface 2 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM3_IRQHandler ;Flexcomm Interface 3 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM4_IRQHandler ;Flexcomm Interface 4 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM5_IRQHandler ;Flexcomm Interface 5 (USART, SPI, I2C,, FLEXCOMM) DCD FLEXCOMM6_IRQHandler ;Flexcomm Interface 6 (USART, SPI, I2C, I2S,, FLEXCOMM) DCD FLEXCOMM7_IRQHandler ;Flexcomm Interface 7 (USART, SPI, I2C, I2S,, FLEXCOMM) DCD ADC0_SEQA_IRQHandler ;ADC0 sequence A completion. DCD ADC0_SEQB_IRQHandler ;ADC0 sequence B completion. DCD ADC0_THCMP_IRQHandler ;ADC0 threshold compare and error. DCD DMIC0_IRQHandler ;Digital microphone and DMIC subsystem DCD HWVAD0_IRQHandler ;Hardware Voice Activity Detector DCD USB0_NEEDCLK_IRQHandler ;USB Activity Wake-up Interrupt DCD USB0_IRQHandler ;USB device DCD RTC_IRQHandler ;RTC alarm and wake-up interrupts DCD Reserved46_IRQHandler ;Reserved interrupt DCD Reserved47_IRQHandler ;Reserved interrupt DCD PIN_INT4_IRQHandler ;Pin interrupt 4 or pattern match engine slice 4 int DCD PIN_INT5_IRQHandler ;Pin interrupt 5 or pattern match engine slice 5 int DCD PIN_INT6_IRQHandler ;Pin interrupt 6 or pattern match engine slice 6 int DCD PIN_INT7_IRQHandler ;Pin interrupt 7 or pattern match engine slice 7 int DCD CTIMER2_IRQHandler ;Standard counter/timer CTIMER2 DCD CTIMER4_IRQHandler ;Standard counter/timer CTIMER4 DCD RIT_IRQHandler ;Repetitive Interrupt Timer DCD SPIFI0_IRQHandler ;SPI flash interface DCD FLEXCOMM8_IRQHandler ;Flexcomm Interface 8 (USART, SPI, I2C, FLEXCOMM) DCD FLEXCOMM9_IRQHandler ;Flexcomm Interface 9 (USART, SPI, I2C, FLEXCOMM) DCD SDIO_IRQHandler ;SD/MMC DCD CAN0_IRQ0_IRQHandler ;CAN0 interrupt0 DCD CAN0_IRQ1_IRQHandler ;CAN0 interrupt1 DCD CAN1_IRQ0_IRQHandler ;CAN1 interrupt0 DCD CAN1_IRQ1_IRQHandler ;CAN1 interrupt1 DCD USB1_IRQHandler ;USB1 interrupt DCD USB1_NEEDCLK_IRQHandler ;USB1 activity DCD ETHERNET_IRQHandler ;Ethernet DCD ETHERNET_PMT_IRQHandler ;Ethernet power management interrupt DCD ETHERNET_MACLP_IRQHandler ;Ethernet MAC interrupt DCD EEPROM_IRQHandler ;EEPROM interrupt DCD LCD_IRQHandler ;LCD interrupt DCD SHA_IRQHandler ;SHA interrupt DCD SMARTCARD0_IRQHandler ;Smart card 0 interrupt DCD SMARTCARD1_IRQHandler ;Smart card 1 interrupt __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Default interrupt handlers. ;; THUMB PUBWEAK Reset_Handler SECTION .text:CODE:REORDER:NOROOT(2) Reset_Handler MOVS r0,#56 LDR r1, =0x40000220 STR r0, [r1] ;Enable SRAM clock used by Stack LDR R0, =SystemInit BLX R0 LDR R0, =__iar_program_start BX R0 PUBWEAK NMI_Handler SECTION .text:CODE:REORDER:NOROOT(1) NMI_Handler B . PUBWEAK HardFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) HardFault_Handler B . PUBWEAK MemManage_Handler SECTION .text:CODE:REORDER:NOROOT(1) MemManage_Handler B . PUBWEAK BusFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) BusFault_Handler B . PUBWEAK UsageFault_Handler SECTION .text:CODE:REORDER:NOROOT(1) UsageFault_Handler B . PUBWEAK SVC_Handler SECTION .text:CODE:REORDER:NOROOT(1) SVC_Handler B . PUBWEAK DebugMon_Handler SECTION .text:CODE:REORDER:NOROOT(1) DebugMon_Handler B . PUBWEAK PendSV_Handler SECTION .text:CODE:REORDER:NOROOT(1) PendSV_Handler B . PUBWEAK SysTick_Handler SECTION .text:CODE:REORDER:NOROOT(1) SysTick_Handler B . PUBWEAK WDT_BOD_IRQHandler PUBWEAK WDT_BOD_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) WDT_BOD_IRQHandler LDR R0, =WDT_BOD_DriverIRQHandler BX R0 PUBWEAK DMA0_IRQHandler PUBWEAK DMA0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) DMA0_IRQHandler LDR R0, =DMA0_DriverIRQHandler BX R0 PUBWEAK GINT0_IRQHandler PUBWEAK GINT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) GINT0_IRQHandler LDR R0, =GINT0_DriverIRQHandler BX R0 PUBWEAK GINT1_IRQHandler PUBWEAK GINT1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) GINT1_IRQHandler LDR R0, =GINT1_DriverIRQHandler BX R0 PUBWEAK PIN_INT0_IRQHandler PUBWEAK PIN_INT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT0_IRQHandler LDR R0, =PIN_INT0_DriverIRQHandler BX R0 PUBWEAK PIN_INT1_IRQHandler PUBWEAK PIN_INT1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT1_IRQHandler LDR R0, =PIN_INT1_DriverIRQHandler BX R0 PUBWEAK PIN_INT2_IRQHandler PUBWEAK PIN_INT2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT2_IRQHandler LDR R0, =PIN_INT2_DriverIRQHandler BX R0 PUBWEAK PIN_INT3_IRQHandler PUBWEAK PIN_INT3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT3_IRQHandler LDR R0, =PIN_INT3_DriverIRQHandler BX R0 PUBWEAK UTICK0_IRQHandler PUBWEAK UTICK0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) UTICK0_IRQHandler LDR R0, =UTICK0_DriverIRQHandler BX R0 PUBWEAK MRT0_IRQHandler PUBWEAK MRT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) MRT0_IRQHandler LDR R0, =MRT0_DriverIRQHandler BX R0 PUBWEAK CTIMER0_IRQHandler PUBWEAK CTIMER0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER0_IRQHandler LDR R0, =CTIMER0_DriverIRQHandler BX R0 PUBWEAK CTIMER1_IRQHandler PUBWEAK CTIMER1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER1_IRQHandler LDR R0, =CTIMER1_DriverIRQHandler BX R0 PUBWEAK SCT0_IRQHandler PUBWEAK SCT0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SCT0_IRQHandler LDR R0, =SCT0_DriverIRQHandler BX R0 PUBWEAK CTIMER3_IRQHandler PUBWEAK CTIMER3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER3_IRQHandler LDR R0, =CTIMER3_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM0_IRQHandler PUBWEAK FLEXCOMM0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM0_IRQHandler LDR R0, =FLEXCOMM0_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM1_IRQHandler PUBWEAK FLEXCOMM1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM1_IRQHandler LDR R0, =FLEXCOMM1_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM2_IRQHandler PUBWEAK FLEXCOMM2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM2_IRQHandler LDR R0, =FLEXCOMM2_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM3_IRQHandler PUBWEAK FLEXCOMM3_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM3_IRQHandler LDR R0, =FLEXCOMM3_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM4_IRQHandler PUBWEAK FLEXCOMM4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM4_IRQHandler LDR R0, =FLEXCOMM4_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM5_IRQHandler PUBWEAK FLEXCOMM5_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM5_IRQHandler LDR R0, =FLEXCOMM5_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM6_IRQHandler PUBWEAK FLEXCOMM6_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM6_IRQHandler LDR R0, =FLEXCOMM6_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM7_IRQHandler PUBWEAK FLEXCOMM7_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM7_IRQHandler LDR R0, =FLEXCOMM7_DriverIRQHandler BX R0 PUBWEAK ADC0_SEQA_IRQHandler PUBWEAK ADC0_SEQA_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_SEQA_IRQHandler LDR R0, =ADC0_SEQA_DriverIRQHandler BX R0 PUBWEAK ADC0_SEQB_IRQHandler PUBWEAK ADC0_SEQB_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_SEQB_IRQHandler LDR R0, =ADC0_SEQB_DriverIRQHandler BX R0 PUBWEAK ADC0_THCMP_IRQHandler PUBWEAK ADC0_THCMP_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ADC0_THCMP_IRQHandler LDR R0, =ADC0_THCMP_DriverIRQHandler BX R0 PUBWEAK DMIC0_IRQHandler PUBWEAK DMIC0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) DMIC0_IRQHandler LDR R0, =DMIC0_DriverIRQHandler BX R0 PUBWEAK HWVAD0_IRQHandler PUBWEAK HWVAD0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) HWVAD0_IRQHandler LDR R0, =HWVAD0_DriverIRQHandler BX R0 PUBWEAK USB0_NEEDCLK_IRQHandler PUBWEAK USB0_NEEDCLK_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB0_NEEDCLK_IRQHandler LDR R0, =USB0_NEEDCLK_DriverIRQHandler BX R0 PUBWEAK USB0_IRQHandler PUBWEAK USB0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB0_IRQHandler LDR R0, =USB0_DriverIRQHandler BX R0 PUBWEAK RTC_IRQHandler PUBWEAK RTC_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) RTC_IRQHandler LDR R0, =RTC_DriverIRQHandler BX R0 PUBWEAK Reserved46_IRQHandler PUBWEAK Reserved46_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) Reserved46_IRQHandler LDR R0, =Reserved46_DriverIRQHandler BX R0 PUBWEAK Reserved47_IRQHandler PUBWEAK Reserved47_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) Reserved47_IRQHandler LDR R0, =Reserved47_DriverIRQHandler BX R0 PUBWEAK PIN_INT4_IRQHandler PUBWEAK PIN_INT4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT4_IRQHandler LDR R0, =PIN_INT4_DriverIRQHandler BX R0 PUBWEAK PIN_INT5_IRQHandler PUBWEAK PIN_INT5_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT5_IRQHandler LDR R0, =PIN_INT5_DriverIRQHandler BX R0 PUBWEAK PIN_INT6_IRQHandler PUBWEAK PIN_INT6_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT6_IRQHandler LDR R0, =PIN_INT6_DriverIRQHandler BX R0 PUBWEAK PIN_INT7_IRQHandler PUBWEAK PIN_INT7_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) PIN_INT7_IRQHandler LDR R0, =PIN_INT7_DriverIRQHandler BX R0 PUBWEAK CTIMER2_IRQHandler PUBWEAK CTIMER2_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER2_IRQHandler LDR R0, =CTIMER2_DriverIRQHandler BX R0 PUBWEAK CTIMER4_IRQHandler PUBWEAK CTIMER4_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CTIMER4_IRQHandler LDR R0, =CTIMER4_DriverIRQHandler BX R0 PUBWEAK RIT_IRQHandler PUBWEAK RIT_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) RIT_IRQHandler LDR R0, =RIT_DriverIRQHandler BX R0 PUBWEAK SPIFI0_IRQHandler PUBWEAK SPIFI0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SPIFI0_IRQHandler LDR R0, =SPIFI0_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM8_IRQHandler PUBWEAK FLEXCOMM8_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM8_IRQHandler LDR R0, =FLEXCOMM8_DriverIRQHandler BX R0 PUBWEAK FLEXCOMM9_IRQHandler PUBWEAK FLEXCOMM9_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) FLEXCOMM9_IRQHandler LDR R0, =FLEXCOMM9_DriverIRQHandler BX R0 PUBWEAK SDIO_IRQHandler PUBWEAK SDIO_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SDIO_IRQHandler LDR R0, =SDIO_DriverIRQHandler BX R0 PUBWEAK CAN0_IRQ0_IRQHandler PUBWEAK CAN0_IRQ0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN0_IRQ0_IRQHandler LDR R0, =CAN0_IRQ0_DriverIRQHandler BX R0 PUBWEAK CAN0_IRQ1_IRQHandler PUBWEAK CAN0_IRQ1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN0_IRQ1_IRQHandler LDR R0, =CAN0_IRQ1_DriverIRQHandler BX R0 PUBWEAK CAN1_IRQ0_IRQHandler PUBWEAK CAN1_IRQ0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN1_IRQ0_IRQHandler LDR R0, =CAN1_IRQ0_DriverIRQHandler BX R0 PUBWEAK CAN1_IRQ1_IRQHandler PUBWEAK CAN1_IRQ1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) CAN1_IRQ1_IRQHandler LDR R0, =CAN1_IRQ1_DriverIRQHandler BX R0 PUBWEAK USB1_IRQHandler PUBWEAK USB1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB1_IRQHandler LDR R0, =USB1_DriverIRQHandler BX R0 PUBWEAK USB1_NEEDCLK_IRQHandler PUBWEAK USB1_NEEDCLK_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) USB1_NEEDCLK_IRQHandler LDR R0, =USB1_NEEDCLK_DriverIRQHandler BX R0 PUBWEAK ETHERNET_IRQHandler PUBWEAK ETHERNET_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_IRQHandler LDR R0, =ETHERNET_DriverIRQHandler BX R0 PUBWEAK ETHERNET_PMT_IRQHandler PUBWEAK ETHERNET_PMT_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_PMT_IRQHandler LDR R0, =ETHERNET_PMT_DriverIRQHandler BX R0 PUBWEAK ETHERNET_MACLP_IRQHandler PUBWEAK ETHERNET_MACLP_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) ETHERNET_MACLP_IRQHandler LDR R0, =ETHERNET_MACLP_DriverIRQHandler BX R0 PUBWEAK EEPROM_IRQHandler PUBWEAK EEPROM_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) EEPROM_IRQHandler LDR R0, =EEPROM_DriverIRQHandler BX R0 PUBWEAK LCD_IRQHandler PUBWEAK LCD_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) LCD_IRQHandler LDR R0, =LCD_DriverIRQHandler BX R0 PUBWEAK SHA_IRQHandler PUBWEAK SHA_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SHA_IRQHandler LDR R0, =SHA_DriverIRQHandler BX R0 PUBWEAK SMARTCARD0_IRQHandler PUBWEAK SMARTCARD0_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SMARTCARD0_IRQHandler LDR R0, =SMARTCARD0_DriverIRQHandler BX R0 PUBWEAK SMARTCARD1_IRQHandler PUBWEAK SMARTCARD1_DriverIRQHandler SECTION .text:CODE:REORDER:NOROOT(2) SMARTCARD1_IRQHandler LDR R0, =SMARTCARD1_DriverIRQHandler BX R0 WDT_BOD_DriverIRQHandler DMA0_DriverIRQHandler GINT0_DriverIRQHandler GINT1_DriverIRQHandler PIN_INT0_DriverIRQHandler PIN_INT1_DriverIRQHandler PIN_INT2_DriverIRQHandler PIN_INT3_DriverIRQHandler UTICK0_DriverIRQHandler MRT0_DriverIRQHandler CTIMER0_DriverIRQHandler CTIMER1_DriverIRQHandler SCT0_DriverIRQHandler CTIMER3_DriverIRQHandler FLEXCOMM0_DriverIRQHandler FLEXCOMM1_DriverIRQHandler FLEXCOMM2_DriverIRQHandler FLEXCOMM3_DriverIRQHandler FLEXCOMM4_DriverIRQHandler FLEXCOMM5_DriverIRQHandler FLEXCOMM6_DriverIRQHandler FLEXCOMM7_DriverIRQHandler ADC0_SEQA_DriverIRQHandler ADC0_SEQB_DriverIRQHandler ADC0_THCMP_DriverIRQHandler DMIC0_DriverIRQHandler HWVAD0_DriverIRQHandler USB0_NEEDCLK_DriverIRQHandler USB0_DriverIRQHandler RTC_DriverIRQHandler Reserved46_DriverIRQHandler Reserved47_DriverIRQHandler PIN_INT4_DriverIRQHandler PIN_INT5_DriverIRQHandler PIN_INT6_DriverIRQHandler PIN_INT7_DriverIRQHandler CTIMER2_DriverIRQHandler CTIMER4_DriverIRQHandler RIT_DriverIRQHandler SPIFI0_DriverIRQHandler FLEXCOMM8_DriverIRQHandler FLEXCOMM9_DriverIRQHandler SDIO_DriverIRQHandler CAN0_IRQ0_DriverIRQHandler CAN0_IRQ1_DriverIRQHandler CAN1_IRQ0_DriverIRQHandler CAN1_IRQ1_DriverIRQHandler USB1_DriverIRQHandler USB1_NEEDCLK_DriverIRQHandler ETHERNET_DriverIRQHandler ETHERNET_PMT_DriverIRQHandler ETHERNET_MACLP_DriverIRQHandler EEPROM_DriverIRQHandler LCD_DriverIRQHandler SHA_DriverIRQHandler SMARTCARD0_DriverIRQHandler SMARTCARD1_DriverIRQHandler DefaultISR B . END ================================================ FILE: hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< m_core1_image /* NOINIT section for rpmsg_sh_mem */ .noinit_rpmsg_sh_mem (NOLOAD) : ALIGN(4) { __RPMSG_SH_MEM_START__ = .; *(.noinit.$rpmsg_sh_mem*) . = ALIGN(4) ; __RPMSG_SH_MEM_END__ = .; } > rpmsg_sh_mem /* The startup code goes first into internal flash */ .interrupts : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } > m_interrupts /* The program code and other data goes into internal flash */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); } > m_text .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } > m_text .ctors : { __CTOR_LIST__ = .; /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) __CTOR_END__ = .; } > m_text .dtors : { __DTOR_LIST__ = .; KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) __DTOR_END__ = .; } > m_text .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } > m_text .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } > m_text .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } > m_text __etext = .; /* define a global symbol at end of code */ __DATA_ROM = .; /* Symbol is used by startup for data initialization */ .data : AT(__DATA_ROM) { . = ALIGN(4); __DATA_RAM = .; __data_start__ = .; /* create a global symbol at data start */ *(.ramfunc*) /* for functions in ram */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ KEEP(*(.jcr*)) . = ALIGN(4); __data_end__ = .; /* define a global symbol at data end */ } > m_data __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") /* Uninitialized data section */ .bss : { /* This is used by the startup in order to initialize the .bss section */ . = ALIGN(4); __START_BSS = .; __bss_start__ = .; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; __END_BSS = .; } > m_data .heap : { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; . += HEAP_SIZE; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > m_data .stack : { . = ALIGN(8); . += STACK_SIZE; } > m_data m_usb_bdt (NOLOAD) : { . = ALIGN(512); *(m_usb_bdt) } > m_usb_sram m_usb_global (NOLOAD) : { *(m_usb_global) } > m_usb_sram /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data) + LENGTH(m_data); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") } ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/clock_config.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to set up clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v18.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_power.h" #include "fsl_clock.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: System_clock.outFreq, value: 12 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; #endif } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF96M outputs: - {id: System_clock.outFreq, value: 96 MHz} settings: - {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} - {id: SYSCON.MAINCLKSELA.sel, value: ANACTRL.fro_hf_clk} sources: - {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF96M configuration ******************************************************************************/ void BOARD_BootClockFROHF96M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: System_clock.outFreq, value: 100 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), .pllndec = SYSCON_PLL0NDEC_NDIV(4U), .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 100000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: FXCOM0_clock.outFreq, value: 48 MHz} - {id: System_clock.outFreq, value: 144 MHz} - {id: USB0_clock.outFreq, value: 48 MHz} - {id: USB1_PHY_clock.outFreq, value: 16 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: PLL1_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_PLL_USB_OUT, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.FCCLKSEL0.sel, value: SYSCON.PLL0DIV} - {id: SYSCON.FRGCTRL0_DIV.scale, value: '400'} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL1_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0DIV.scale, value: '2'} - {id: SYSCON.PLL0M_MULT.scale, value: '150', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '8', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '2', locked: true} - {id: SYSCON.PLL1CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL1M_MULT.scale, value: '18'} - {id: SYSCON.PLL1_PDEC.scale, value: '2'} - {id: SYSCON.USB0CLKDIV.scale, value: '3'} - {id: SYSCON.USB0CLKSEL.sel, value: SYSCON.MAINCLKSELB} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; /* Enable clk_in to HS USB */ POWER_SetVoltageForFreq(144000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(144000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(8U), .pllpdec = SYSCON_PLL0PDEC_PDIV(1U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(150U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 150000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up PLL1 */ CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL1); /* Ensure PLL is on */ const pll_setup_t pll1Setup = { .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(11U) | SYSCON_PLL1CTRL_SELP(5U), .pllndec = SYSCON_PLL1NDEC_NDIV(1U), .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), .pllmdec = SYSCON_PLL1MDEC_MDIV(18U), .pllRate = 144000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ /*!< Set up dividers */ #if FSL_CLOCK_DRIVER_VERSION >= MAKE_VERSION(2, 3, 4) CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 144U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #else CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 37120U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #endif CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true); /*!< Reset USB0CLKDIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 3U, false); /*!< Set USB0CLKDIV divider to value 3 */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); /*!< Reset PLL0DIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 2U, false); /*!< Set PLL0DIV divider to value 2 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ CLOCK_AttachClk(kMAIN_CLK_to_USB0_CLK); /*!< Switch USB0_CLK to MAIN_CLK */ CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM0); /*!< Switch FLEXCOMM0 to PLL0_DIV */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; #endif } ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/clock_config.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO12M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFRO12M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFRO12M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFRO12M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFRO12M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO12M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFRO12M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO12M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFROHF96M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFROHF96M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFROHF96M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFROHF96M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFROHF96M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFROHF96M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTEM_CLOCK 96000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFROHF96M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFROHF96M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFROHF96M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFROHF96M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL100M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL100M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL100M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL100M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL100M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL100M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTEM_CLOCK 100000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL100M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL100M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL100M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL100M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL150M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL150M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM0_CLOCK 48000000UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL150M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL150M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL150M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL150M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTEM_CLOCK 144000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL150M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL150M_USB0_CLOCK 48000000UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL150M_USB1_PHY_CLOCK 16000000UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL150M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/peripherals.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v15.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 functionalGroups: - name: BOARD_InitPeripherals_cm33_core0 UUID: 61d0725d-b300-49cb-9c66-b5edfbf8ffc1 called_from_default_init: true selectedCore: cm33_core0 - name: BOARD_InitPeripherals_cm33_core1 UUID: e2041cd4-ebb6-45a5-807f-e0c2dc047d48 selectedCore: cm33_core1 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'system' - type_id: 'system' - global_system_definitions: - user_definitions: '' - user_includes: '' - global_init: '' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'uart_cmsis_common' - type_id: 'uart_cmsis_common' - global_USART_CMSIS_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'gpio_adapter_common' - type_id: 'gpio_adapter_common' - global_gpio_adapter_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "peripherals.h" /*********************************************************************************************************************** * BOARD_InitPeripherals_cm33_core0 functional group **********************************************************************************************************************/ /*********************************************************************************************************************** * DEBUG_UART initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'DEBUG_UART' - type: 'flexcomm_usart' - mode: 'polling' - custom_name_enabled: 'true' - type_id: 'flexcomm_usart_2.2.0' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'FLEXCOMM0' - config_sets: - usartConfig_t: - usartConfig: - clockSource: 'FXCOMFunctionClock' - clockSourceFreq: 'ClocksTool_DefaultInit' - baudRate_Bps: '115200' - syncMode: 'kUSART_SyncModeDisabled' - parityMode: 'kUSART_ParityDisabled' - stopBitCount: 'kUSART_OneStopBit' - bitCountPerChar: 'kUSART_8BitsPerChar' - loopback: 'false' - txWatermark: 'kUSART_TxFifo0' - rxWatermark: 'kUSART_RxFifo1' - enableRx: 'true' - enableTx: 'true' - clockPolarity: 'kUSART_RxSampleOnFallingEdge' - enableContinuousSCLK: 'false' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ const usart_config_t DEBUG_UART_config = { .baudRate_Bps = 115200UL, .syncMode = kUSART_SyncModeDisabled, .parityMode = kUSART_ParityDisabled, .stopBitCount = kUSART_OneStopBit, .bitCountPerChar = kUSART_8BitsPerChar, .loopback = false, .txWatermark = kUSART_TxFifo0, .rxWatermark = kUSART_RxFifo1, .enableRx = true, .enableTx = true, .enableMode32k = false, .clockPolarity = kUSART_RxSampleOnFallingEdge, .enableContinuousSCLK = false }; static void DEBUG_UART_init(void) { /* Reset FLEXCOMM device */ RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn); USART_Init(DEBUG_UART_PERIPHERAL, &DEBUG_UART_config, DEBUG_UART_CLOCK_SOURCE); } /*********************************************************************************************************************** * NVIC initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'NVIC' - type: 'nvic' - mode: 'general' - custom_name_enabled: 'false' - type_id: 'nvic' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'NVIC' - config_sets: - nvic: - interrupt_table: [] - interrupts: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /* Empty initialization function (commented out) static void NVIC_init(void) { } */ /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void) { /* Initialize components */ DEBUG_UART_init(); } /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void) { BOARD_InitPeripherals_cm33_core0(); } ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/peripherals.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PERIPHERALS_H_ #define _PERIPHERALS_H_ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "fsl_common.h" #include "fsl_reset.h" #include "fsl_usart.h" #include "fsl_clock.h" #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /* Definitions for BOARD_InitPeripherals_cm33_core0 functional group */ /* Definition of peripheral ID */ #define DEBUG_UART_PERIPHERAL ((USART_Type *)FLEXCOMM0) /* Definition of the clock source frequency */ #define DEBUG_UART_CLOCK_SOURCE 48000000UL /*********************************************************************************************************************** * Global variables **********************************************************************************************************************/ extern const usart_config_t DEBUG_UART_config; /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void); /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void); #if defined(__cplusplus) } #endif #endif /* _PERIPHERALS_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/pin_mux.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 pin_labels: - {pin_num: '7', pin_signal: PIO0_1/FC3_CTS_SDA_SSEL0/CT_INP0/SCT_GPI1/SD1_CLK/CMP0_OUT/SECURE_GPIO0_1, label: 'P18[2]/SD1_CLK', identifier: LED} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_gpio.h" #include "fsl_iocon.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitDEBUG_UARTPins(); BOARD_InitUSBPins(); BOARD_InitLEDsPins(); BOARD_InitBUTTONsPins(); BOARD_InitPins_Core0(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '92', peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_29/FC0_RXD_SDA_MOSI_DATA/SD1_D2/CTIMER2_MAT3/SCT0_OUT8/CMP0_OUT/PLU_OUT2/SECURE_GPIO0_29, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '94', peripheral: FLEXCOMM0, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_30/FC0_TXD_SCL_MISO_WS/SD1_D3/CTIMER0_MAT0/SCT0_OUT9/SECURE_GPIO0_30, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitDEBUG_UARTPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_UART_RX = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN29 (coords: 92) is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN, DEBUG_UART_RX); const uint32_t DEBUG_UART_TX = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN30 (coords: 94) is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN, DEBUG_UART_TX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '13', peripheral: SWD, signal: SWCLK, pin_signal: PIO0_11/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT2/FREQME_GPIO_CLK_A/SWCLK/SECURE_GPIO0_11/ADC0_9, mode: pullDown, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '12', peripheral: SWD, signal: SWDIO, pin_signal: PIO0_12/FC3_TXD_SCL_MISO_WS/SD1_BACKEND_PWR/FREQME_GPIO_CLK_B/SCT_GPI7/SD0_POW_EN/SWDIO/FC6_TXD_SCL_MISO_WS/SECURE_GPIO0_12/ADC0_10, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '21', peripheral: SWD, signal: SWO, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: DEBUG_SWD_SWO, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitSWD_DEBUGPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_SWD_SWO = (/* Pin is configured as SWO */ IOCON_PIO_FUNC6 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT0 PIN10 (coords: 21) is configured as SWO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN, DEBUG_SWD_SWO); if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } else { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } else { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSBPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: USBFSH, signal: USB_DP, pin_signal: USB0_DP} - {pin_num: '98', peripheral: USBFSH, signal: USB_DM, pin_signal: USB0_DM} - {pin_num: '78', peripheral: USBFSH, signal: USB_VBUS, pin_signal: PIO0_22/FC6_TXD_SCL_MISO_WS/UTICK_CAP1/CT_INP15/SCT0_OUT3/USB0_VBUS/SD1_D0/PLU_OUT7/SECURE_GPIO0_22, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '35', peripheral: USBHSH, signal: USB_DM, pin_signal: USB1_DM} - {pin_num: '34', peripheral: USBHSH, signal: USB_DP, pin_signal: USB1_DP} - {pin_num: '36', peripheral: USBHSH, signal: USB_VBUS, pin_signal: USB1_VBUS} - {pin_num: '65', peripheral: USBHSH, signal: USB_OVERCURRENTN, pin_signal: PIO1_30/FC7_TXD_SCL_MISO_WS/SD0_D7/SCT_GPI7/USB1_OVERCURRENTN/USB1_LEDN/PLU_IN1, mode: pullUp} - {pin_num: '66', peripheral: USBFSH, signal: USB_OVERCURRENTN, pin_signal: PIO0_28/FC0_SCK/SD1_CMD/CT_INP11/SCT0_OUT7/USB0_OVERCURRENTN/PLU_OUT1/SECURE_GPIO0_28, mode: pullUp} - {pin_num: '67', peripheral: USBFSH, signal: USB_PORTPWRN, pin_signal: PIO1_12/FC6_SCK/CTIMER1_MAT1/USB0_PORTPWRN/HS_SPI_SSEL2, mode: pullUp} - {pin_num: '80', peripheral: USBHSH, signal: USB_PORTPWRN, pin_signal: PIO1_29/FC7_RXD_SDA_MOSI_DATA/SD0_D6/SCT_GPI6/USB1_PORTPWRN/USB1_FRAME/PLU_IN2, mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSBPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitUSBPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t USB0_VBUS = (/* Pin is configured as USB0_VBUS */ IOCON_PIO_FUNC7 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN22 (coords: 78) is configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, BOARD_INITUSBPINS_USB0_VBUS_PORT, BOARD_INITUSBPINS_USB0_VBUS_PIN, USB0_VBUS); IOCON->PIO[0][28] = ((IOCON->PIO[0][28] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT028 (pin 66) is configured as USB0_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO0_28_FUNC_ALT7) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO0_28_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_28_DIGIMODE_DIGITAL)); IOCON->PIO[1][12] = ((IOCON->PIO[1][12] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT112 (pin 67) is configured as USB0_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_12_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_12_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_12_DIGIMODE_DIGITAL)); IOCON->PIO[1][29] = ((IOCON->PIO[1][29] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT129 (pin 80) is configured as USB1_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_29_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_29_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_29_DIGIMODE_DIGITAL)); IOCON->PIO[1][30] = ((IOCON->PIO[1][30] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT130 (pin 65) is configured as USB1_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO1_30_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_30_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_30_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '7', peripheral: GPIO, signal: 'PIO0, 1', pin_signal: PIO0_1/FC3_CTS_SDA_SSEL0/CT_INP0/SCT_GPI1/SD1_CLK/CMP0_OUT/SECURE_GPIO0_1, direction: OUTPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitLEDsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_Gpio0); gpio_pin_config_t LED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO0_1 (pin 7) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_GPIO, BOARD_INITLEDSPINS_LED_PORT, BOARD_INITLEDSPINS_LED_PIN, &LED_config); IOCON->PIO[0][1] = ((IOCON->PIO[0][1] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT01 (pin 7) is configured as PIO0_1. */ | IOCON_PIO_FUNC(PIO0_1_FUNC_ALT0) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_1_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitBUTTONsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '88', peripheral: GPIO, signal: 'PIO0, 5', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '32', peripheral: SYSCON, signal: RESET, pin_signal: RESETN} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBUTTONsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitBUTTONsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_Gpio0); gpio_pin_config_t S1_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO0_5 (pin 88) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S1_GPIO, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, &S1_config); const uint32_t S1 = (/* Pin is configured as PIO0_5 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN5 (coords: 88) is configured as PIO0_5 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, S1); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins_Core0: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins_Core0 * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitPins_Core0(void) { } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitI2SPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '91', peripheral: SYSCON, signal: MCLK, pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '76', peripheral: FLEXCOMM7, signal: SCK, pin_signal: PIO0_21/FC3_RTS_SCL_SSEL1/UTICK_CAP3/CTIMER3_MAT3/SCT_GPI3/FC7_SCK/PLU_CLKIN/SECURE_GPIO0_21, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '74', peripheral: FLEXCOMM7, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_20/FC3_CTS_SDA_SSEL0/CTIMER1_MAT1/CT_INP15/SCT_GPI2/FC7_RXD_SDA_MOSI_DATA/HS_SPI_SSEL0/PLU_IN5/SECURE_GPIO0_20/FC4_TXD_SCL_MISO_WS, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '90', peripheral: FLEXCOMM7, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_19/FC4_RTS_SCL_SSEL1/UTICK_CAP0/CTIMER0_MAT2/SCT0_OUT2/FC7_TXD_SCL_MISO_WS/PLU_IN4/SECURE_GPIO0_19, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '21', peripheral: FLEXCOMM6, signal: SCK, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: FC6_I2S_CLK, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '2', peripheral: FLEXCOMM6, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_13/FC6_RXD_SDA_MOSI_DATA/CT_INP6/USB0_OVERCURRENTN/USB0_FRAME/SD0_CARD_DET_N, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '87', peripheral: FLEXCOMM6, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_16/FC6_TXD_SCL_MISO_WS/CTIMER1_MAT3/SD0_CMD, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitI2SPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitI2SPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t FC6_I2S_CLK = (/* Pin is configured as FC6_SCK */ IOCON_PIO_FUNC1 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN10 (coords: 21) is configured as FC6_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_CLK_PORT, BOARD_INITI2SPINS_FC6_I2S_CLK_PIN, FC6_I2S_CLK); const uint32_t FC7_I2S_WS = (/* Pin is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN19 (coords: 90) is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_WS_PORT, BOARD_INITI2SPINS_FC7_I2S_WS_PIN, FC7_I2S_WS); const uint32_t FC7_I2S_TX = (/* Pin is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN20 (coords: 74) is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_TX_PORT, BOARD_INITI2SPINS_FC7_I2S_TX_PIN, FC7_I2S_TX); const uint32_t FC7_I2S_SCK = (/* Pin is configured as FC7_SCK */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN21 (coords: 76) is configured as FC7_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_SCK_PORT, BOARD_INITI2SPINS_FC7_I2S_SCK_PIN, FC7_I2S_SCK); const uint32_t FC6_I2S_RX = (/* Pin is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN13 (coords: 2) is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_RX_PORT, BOARD_INITI2SPINS_FC6_I2S_RX_PIN, FC6_I2S_RX); const uint32_t FC6_I2S_WS = (/* Pin is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN16 (coords: 87) is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_WS_PORT, BOARD_INITI2SPINS_FC6_I2S_WS_PIN, FC6_I2S_WS); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SCL_PORT, BOARD_INITI2SPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SDA_PORT, BOARD_INITI2SPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); const uint32_t MCLK = (/* Pin is configured as MCLK */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN31 (coords: 91) is configured as MCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_MCLK_PORT, BOARD_INITI2SPINS_MCLK_PIN, MCLK); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitACCELPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '58', peripheral: GPIO, signal: 'PIO1, 19', pin_signal: PIO1_19/SCT0_OUT7/CTIMER3_MAT1/SCT_GPI7/FC4_SCK/PLU_OUT1/ACMPVREF, direction: INPUT, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitACCELPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitACCELPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t ACCL_INTR_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_19 (pin 58) */ GPIO_PinInit(BOARD_INITACCELPINS_ACCL_INTR_GPIO, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, &ACCL_INTR_config); const uint32_t ACCL_INTR = (/* Pin is configured as PIO1_19 */ IOCON_PIO_FUNC0 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT1 PIN19 (coords: 58) is configured as PIO1_19 */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, ACCL_INTR); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SCL_PORT, BOARD_INITACCELPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SDA_PORT, BOARD_INITACCELPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board/pin_mux.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_29 (number 92), P8[2]/U6[13]/FC0_USART_RXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN 29U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN_MASK (1U << 29U) /* @} */ /*! @name PIO0_30 (number 94), P8[3]/U6[12]/FC0_USART_TXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN 30U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN_MASK (1U << 30U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_ASW_DIS_EN 0x00u /*!<@brief Analog switch is closed (enabled), only for A0 version */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC6 0x06u /*!<@brief Selects pin function 6 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLDOWN 0x10u /*!<@brief Selects pull-down function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_11 (number 13), U14[4]/SWDCLK_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN 11U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 11U) /* @} */ /*! @name PIO0_12 (number 12), U15[4]/D7/P7[2]/IF_SWDIO @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN 12U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 12U) /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN 10U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN_MASK (1U << 10U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Enables digital function */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*! * @brief Selects pin function 7 */ #define IOCON_PIO_FUNC7 0x07u /*! * @brief Input function is not inverted */ #define IOCON_PIO_INV_DI 0x00u /*! * @brief No addition pin function */ #define IOCON_PIO_MODE_INACT 0x00u /*! * @brief Open drain is disabled */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*! * @brief Standard mode, output slew rate control is enabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_28_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 7. */ #define PIO0_28_FUNC_ALT7 0x07u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO0_28_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_12_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_12_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_12_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_29_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_29_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_29_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_30_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_30_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_30_MODE_PULL_UP 0x02u /*! @name PIO0_22 (number 78), P10[1]/USB0_VBUS @{ */ #define BOARD_INITUSBPINS_USB0_VBUS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN 22U /*!<@brief PORT pin number */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSBPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define PIO0_1_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_1_FUNC_ALT0 0x00u /*!<@brief Selects pin function.: Alternative connection 0. */ /*! @name PIO0_1 (number 7), P18[2]/SD1_CLK @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_INIT_GPIO_VALUE 0U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_GPIO_PIN_MASK (1U << 1U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_PIN 1U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_5 (number 88), S1/J10[1]/U3[12]/P17[8]/P7[7]/U11[4]/P0_5-ISP1 @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S1_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_GPIO_PIN_MASK (1U << 5U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S1_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_PIN 5U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S1_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitBUTTONsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins_Core0(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_FUNC2 0x02u /*!<@brief Selects pin function 2 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_FUNC7 0x07u /*!<@brief Selects pin function 7 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_31 (number 91), P19[7]/P19[8]/PLU_IN0/GPIO @{ */ #define BOARD_INITI2SPINS_MCLK_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_MCLK_PIN 31U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_MCLK_PIN_MASK (1U << 31U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_21 (number 76), P17[14]/FC7_I2S_SCK @{ */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_20 (number 74), P17[10]/FC7_I2S_TX @{ */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_19 (number 90), P17[12]/FC7_I2S_WS @{ */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN 10U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_13 (number 2), P17[20]/FC6_I2S_RX @{ */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN 13U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_16 (number 87), P18[17]/SD1_PWR_EN @{ */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN 16U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitI2SPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_19 (number 58), U7[3]/P18[14]/PLU_OUT1/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */ #define BOARD_INITACCELPINS_ACCL_INTR_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitACCELPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board.cmake ================================================ set(MCU_VARIANT LPC55S69) set(MCU_CORE LPC55S69_cm33_core0) set(JLINK_DEVICE LPC55S69) set(PYOCD_TARGET LPC55S69) set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/LPC55S69_cm33_core0_uf2.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S69JBD100_cm33_core0 ) endfunction() ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Double M33 Express url: https://www.crowdsupply.com/steiert-solutions/double-m33-express */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT BOARD_INITLEDSPINS_LED_PORT #define LED_PIN BOARD_INITLEDSPINS_LED_PIN #define LED_STATE_ON 1 // WAKE button #define BUTTON_PORT BOARD_INITBUTTONSPINS_S1_PORT #define BUTTON_PIN BOARD_INITBUTTONSPINS_S1_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV USART0 // XTAL #define XTAL0_CLK_HZ (16 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/board.mk ================================================ MCU_VARIANT = LPC55S69 MCU_CORE = LPC55S69_cm33_core0 RHPORT_DEVICE ?= 1 CFLAGS += -DCPU_LPC55S69JBD100_cm33_core0 LD_FILE = $(BOARD_PATH)/LPC55S69_cm33_core0_uf2.ld SRC_C += \ $(TOP)/$(BOARD_PATH)/board/clock_config.c \ $(TOP)/$(BOARD_PATH)/board/pin_mux.c \ $(TOP)/$(BOARD_PATH)/board/peripherals.c INC += $(TOP)/$(BOARD_PATH)/board JLINK_DEVICE = LPC55S69 PYOCD_TARGET = LPC55S69 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc55/boards/double_m33_express/double_m33_express.mex ================================================ LPC55S69 LPC55S69JBD100 LPCXpresso55S69 A2 ksdk2_0 true false /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ true true true false 25.09.10 Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true Configures pin routing and optionally pin electrical features. true cm33_core1 true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true 25.09.10 true true true true true true false true true true true true true false true INPUT true OUTPUT true true true true true true false true INPUT true OUTPUT true true true true true true true 0.0.0 true 2.2.0 true 25.09.10 0 true true 0.0.0 ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/LPCXpresso55S28.mex ================================================ LPC55S28 LPC55S28JBD100 LPCXpresso55S28 A2 ksdk2_0 true false /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ true true true false 25.09.10 Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true 25.09.10 true true true false true true true false true INPUT true OUTPUT true true true false true INPUT true OUTPUT true true true true N/A true 2.2.0 true 25.09.10 0 true true N/A ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/clock_config.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to set up clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v18.0 processor: LPC55S28 package_id: LPC55S28JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S28 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_power.h" #include "fsl_clock.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: System_clock.outFreq, value: 12 MHz} settings: - {id: PLL1_Mode, value: Normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; #endif } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF96M outputs: - {id: System_clock.outFreq, value: 96 MHz} settings: - {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} - {id: SYSCON.MAINCLKSELA.sel, value: ANACTRL.fro_hf_clk} sources: - {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF96M configuration ******************************************************************************/ void BOARD_BootClockFROHF96M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: System_clock.outFreq, value: 100 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), .pllndec = SYSCON_PLL0NDEC_NDIV(4U), .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 100000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: FXCOM0_clock.outFreq, value: 48 MHz} - {id: SYSTICK0_clock.outFreq, value: 144 MHz} - {id: System_clock.outFreq, value: 144 MHz} - {id: USB0_clock.outFreq, value: 48 MHz} - {id: USB1_PHY_clock.outFreq, value: 16 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: PLL1_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_PLL_USB_OUT, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.FCCLKSEL0.sel, value: SYSCON.PLL0DIV} - {id: SYSCON.FRGCTRL0_DIV.scale, value: '400'} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL1_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0DIV.scale, value: '2'} - {id: SYSCON.PLL0M_MULT.scale, value: '150', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '8', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '2', locked: true} - {id: SYSCON.PLL1CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL1M_MULT.scale, value: '18'} - {id: SYSCON.PLL1_PDEC.scale, value: '2'} - {id: SYSCON.SYSTICKCLKSEL0.sel, value: SYSCON.SYSTICKCLKDIV0} - {id: SYSCON.USB0CLKDIV.scale, value: '3'} - {id: SYSCON.USB0CLKSEL.sel, value: SYSCON.MAINCLKSELB} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; /* Enable clk_in to HS USB */ POWER_SetVoltageForFreq(144000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(144000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(8U), .pllpdec = SYSCON_PLL0PDEC_PDIV(1U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(150U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 150000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up PLL1 */ CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL1); /* Ensure PLL is on */ const pll_setup_t pll1Setup = { .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(11U) | SYSCON_PLL1CTRL_SELP(5U), .pllndec = SYSCON_PLL1NDEC_NDIV(1U), .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), .pllmdec = SYSCON_PLL1MDEC_MDIV(18U), .pllRate = 144000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivSystickClk0, 0U, true); /*!< Reset SYSTICKCLKDIV0 divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivSystickClk0, 1U, false); /*!< Set SYSTICKCLKDIV0 divider to value 1 */ #if FSL_CLOCK_DRIVER_VERSION >= MAKE_VERSION(2, 3, 4) CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 144U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #else CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 37120U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #endif CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true); /*!< Reset USB0CLKDIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 3U, false); /*!< Set USB0CLKDIV divider to value 3 */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); /*!< Reset PLL0DIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 2U, false); /*!< Set PLL0DIV divider to value 2 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ CLOCK_AttachClk(kMAIN_CLK_to_USB0_CLK); /*!< Switch USB0_CLK to MAIN_CLK */ CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM0); /*!< Switch FLEXCOMM0 to PLL0_DIV */ CLOCK_AttachClk(kSYSTICK_DIV0_to_SYSTICK0); /*!< Switch SYSTICK0 to SYSTICK_DIV0 */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; #endif } ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/clock_config.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO12M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFRO12M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFRO12M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFRO12M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFRO12M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO12M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFRO12M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO12M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFROHF96M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFROHF96M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFROHF96M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFROHF96M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFROHF96M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFROHF96M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTEM_CLOCK 96000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFROHF96M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFROHF96M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFROHF96M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFROHF96M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL100M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL100M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL100M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL100M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL100M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL100M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTEM_CLOCK 100000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL100M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL100M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL100M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL100M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL150M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL150M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM0_CLOCK 48000000UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL150M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL150M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL150M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL150M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK0_CLOCK 144000000UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTEM_CLOCK 144000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL150M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL150M_USB0_CLOCK 48000000UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL150M_USB1_PHY_CLOCK 16000000UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL150M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/peripherals.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v15.0 processor: LPC55S28 package_id: LPC55S28JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S28 functionalGroups: - name: BOARD_InitPeripherals UUID: 61d0725d-b300-49cb-9c66-b5edfbf8ffc1 called_from_default_init: true selectedCore: cm33_core0 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'system' - type_id: 'system_54b53072540eeeb8f8e9343e71f28176' - global_system_definitions: - user_definitions: '' - user_includes: '' - global_init: '' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'uart_cmsis_common' - type_id: 'uart_cmsis_common' - global_USART_CMSIS_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'gpio_adapter_common' - type_id: 'gpio_adapter_common' - global_gpio_adapter_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "peripherals.h" /*********************************************************************************************************************** * BOARD_InitPeripherals functional group **********************************************************************************************************************/ /*********************************************************************************************************************** * DEBUG_UART initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'DEBUG_UART' - type: 'flexcomm_usart' - mode: 'polling' - custom_name_enabled: 'true' - type_id: 'flexcomm_usart_2.2.0' - functional_group: 'BOARD_InitPeripherals' - peripheral: 'FLEXCOMM0' - config_sets: - usartConfig_t: - usartConfig: - clockSource: 'FXCOMFunctionClock' - clockSourceFreq: 'ClocksTool_DefaultInit' - baudRate_Bps: '115200' - syncMode: 'kUSART_SyncModeDisabled' - parityMode: 'kUSART_ParityDisabled' - stopBitCount: 'kUSART_OneStopBit' - bitCountPerChar: 'kUSART_8BitsPerChar' - loopback: 'false' - txWatermark: 'kUSART_TxFifo0' - rxWatermark: 'kUSART_RxFifo1' - enableRx: 'true' - enableTx: 'true' - clockPolarity: 'kUSART_RxSampleOnFallingEdge' - enableContinuousSCLK: 'false' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ const usart_config_t DEBUG_UART_config = { .baudRate_Bps = 115200UL, .syncMode = kUSART_SyncModeDisabled, .parityMode = kUSART_ParityDisabled, .stopBitCount = kUSART_OneStopBit, .bitCountPerChar = kUSART_8BitsPerChar, .loopback = false, .txWatermark = kUSART_TxFifo0, .rxWatermark = kUSART_RxFifo1, .enableRx = true, .enableTx = true, .enableMode32k = false, .clockPolarity = kUSART_RxSampleOnFallingEdge, .enableContinuousSCLK = false }; static void DEBUG_UART_init(void) { /* Reset FLEXCOMM device */ RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn); USART_Init(DEBUG_UART_PERIPHERAL, &DEBUG_UART_config, DEBUG_UART_CLOCK_SOURCE); } /*********************************************************************************************************************** * NVIC initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'NVIC' - type: 'nvic' - mode: 'general' - custom_name_enabled: 'false' - type_id: 'nvic' - functional_group: 'BOARD_InitPeripherals' - peripheral: 'NVIC' - config_sets: - nvic: - interrupt_table: [] - interrupts: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /* Empty initialization function (commented out) static void NVIC_init(void) { } */ /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals(void) { /* Initialize components */ DEBUG_UART_init(); } /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void) { BOARD_InitPeripherals(); } ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/peripherals.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PERIPHERALS_H_ #define _PERIPHERALS_H_ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "fsl_common.h" #include "fsl_reset.h" #include "fsl_usart.h" #include "fsl_clock.h" #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /* Definitions for BOARD_InitPeripherals functional group */ /* Definition of peripheral ID */ #define DEBUG_UART_PERIPHERAL ((USART_Type *)FLEXCOMM0) /* Definition of the clock source frequency */ #define DEBUG_UART_CLOCK_SOURCE 48000000UL /*********************************************************************************************************************** * Global variables **********************************************************************************************************************/ extern const usart_config_t DEBUG_UART_config; /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals(void); /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void); #if defined(__cplusplus) } #endif #endif /* _PERIPHERALS_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/pin_mux.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: LPC55S28 package_id: LPC55S28JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S28 external_user_signals: {} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_gpio.h" #include "fsl_iocon.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitDEBUG_UARTPins(); BOARD_InitUSBPins(); BOARD_InitLEDsPins(); BOARD_InitBUTTONsPins(); BOARD_InitPins_Core0(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '92', peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_29/FC0_RXD_SDA_MOSI_DATA/SD1_D2/CTIMER2_MAT3/SCT0_OUT8/CMP0_OUT/PLU_OUT2/SECURE_GPIO0_29, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '94', peripheral: FLEXCOMM0, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_30/FC0_TXD_SCL_MISO_WS/SD1_D3/CTIMER0_MAT0/SCT0_OUT9/SECURE_GPIO0_30, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitDEBUG_UARTPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_UART_RX = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN29 (coords: 92) is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN, DEBUG_UART_RX); const uint32_t DEBUG_UART_TX = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN30 (coords: 94) is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN, DEBUG_UART_TX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '13', peripheral: SWD, signal: SWCLK, pin_signal: PIO0_11/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT2/FREQME_GPIO_CLK_A/SWCLK/SECURE_GPIO0_11/ADC0_9, mode: pullDown, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '12', peripheral: SWD, signal: SWDIO, pin_signal: PIO0_12/FC3_TXD_SCL_MISO_WS/SD1_BACKEND_PWR/FREQME_GPIO_CLK_B/SCT_GPI7/SD0_POW_EN/SWDIO/FC6_TXD_SCL_MISO_WS/SECURE_GPIO0_12/ADC0_10, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '21', peripheral: SWD, signal: SWO, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: DEBUG_SWD_SWO, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitSWD_DEBUGPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_SWD_SWO = (/* Pin is configured as SWO */ IOCON_PIO_FUNC6 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT0 PIN10 (coords: 21) is configured as SWO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN, DEBUG_SWD_SWO); const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSBPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: USBFSH, signal: USB_DP, pin_signal: USB0_DP} - {pin_num: '98', peripheral: USBFSH, signal: USB_DM, pin_signal: USB0_DM} - {pin_num: '78', peripheral: USBFSH, signal: USB_VBUS, pin_signal: PIO0_22/FC6_TXD_SCL_MISO_WS/UTICK_CAP1/CT_INP15/SCT0_OUT3/USB0_VBUS/SD1_D0/PLU_OUT7/SECURE_GPIO0_22, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '35', peripheral: USBHSH, signal: USB_DM, pin_signal: USB1_DM} - {pin_num: '34', peripheral: USBHSH, signal: USB_DP, pin_signal: USB1_DP} - {pin_num: '36', peripheral: USBHSH, signal: USB_VBUS, pin_signal: USB1_VBUS} - {pin_num: '80', peripheral: USBHSH, signal: USB_PORTPWRN, pin_signal: PIO1_29/FC7_RXD_SDA_MOSI_DATA/SD0_D6/SCT_GPI6/USB1_PORTPWRN/USB1_FRAME/PLU_IN2, mode: pullUp} - {pin_num: '67', peripheral: USBFSH, signal: USB_PORTPWRN, pin_signal: PIO1_12/FC6_SCK/CTIMER1_MAT1/USB0_PORTPWRN/HS_SPI_SSEL2, mode: pullUp} - {pin_num: '66', peripheral: USBFSH, signal: USB_OVERCURRENTN, pin_signal: PIO0_28/FC0_SCK/SD1_CMD/CT_INP11/SCT0_OUT7/USB0_OVERCURRENTN/PLU_OUT1/SECURE_GPIO0_28, mode: pullUp} - {pin_num: '65', peripheral: USBHSH, signal: USB_OVERCURRENTN, pin_signal: PIO1_30/FC7_TXD_SCL_MISO_WS/SD0_D7/SCT_GPI7/USB1_OVERCURRENTN/USB1_LEDN/PLU_IN1, mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSBPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitUSBPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t USB0_VBUS = (/* Pin is configured as USB0_VBUS */ IOCON_PIO_FUNC7 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN22 (coords: 78) is configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, BOARD_INITUSBPINS_USB0_VBUS_PORT, BOARD_INITUSBPINS_USB0_VBUS_PIN, USB0_VBUS); IOCON->PIO[0][28] = ((IOCON->PIO[0][28] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT028 (pin 66) is configured as USB0_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO0_28_FUNC_ALT7) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO0_28_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_28_DIGIMODE_DIGITAL)); IOCON->PIO[1][12] = ((IOCON->PIO[1][12] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT112 (pin 67) is configured as USB0_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_12_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_12_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_12_DIGIMODE_DIGITAL)); IOCON->PIO[1][29] = ((IOCON->PIO[1][29] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT129 (pin 80) is configured as USB1_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_29_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_29_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_29_DIGIMODE_DIGITAL)); IOCON->PIO[1][30] = ((IOCON->PIO[1][30] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT130 (pin 65) is configured as USB1_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO1_30_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_30_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_30_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '1', peripheral: GPIO, signal: 'PIO1, 4', pin_signal: PIO1_4/FC0_SCK/SD0_D0/CTIMER2_MAT1/SCT0_OUT0/FREQME_GPIO_CLK_A, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '5', peripheral: GPIO, signal: 'PIO1, 6', pin_signal: PIO1_6/FC0_TXD_SCL_MISO_WS/SD0_D3/CTIMER2_MAT1/SCT_GPI3, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '9', peripheral: GPIO, signal: 'PIO1, 7', pin_signal: PIO1_7/FC0_RTS_SCL_SSEL1/SD0_D1/CTIMER2_MAT2/SCT_GPI4, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitLEDsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t LED_BLUE_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_4 (pin 1) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_BLUE_GPIO, BOARD_INITLEDSPINS_LED_BLUE_PORT, BOARD_INITLEDSPINS_LED_BLUE_PIN, &LED_BLUE_config); gpio_pin_config_t LED_RED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_6 (pin 5) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_RED_GPIO, BOARD_INITLEDSPINS_LED_RED_PORT, BOARD_INITLEDSPINS_LED_RED_PIN, &LED_RED_config); gpio_pin_config_t LED_GREEN_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_7 (pin 9) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_GREEN_GPIO, BOARD_INITLEDSPINS_LED_GREEN_PORT, BOARD_INITLEDSPINS_LED_GREEN_PIN, &LED_GREEN_config); const uint32_t LED_BLUE = (/* Pin is configured as PIO1_4 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN4 (coords: 1) is configured as PIO1_4 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_BLUE_PORT, BOARD_INITLEDSPINS_LED_BLUE_PIN, LED_BLUE); const uint32_t LED_RED = (/* Pin is configured as PIO1_6 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN6 (coords: 5) is configured as PIO1_6 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_RED_PORT, BOARD_INITLEDSPINS_LED_RED_PIN, LED_RED); const uint32_t LED_GREEN = (/* Pin is configured as PIO1_7 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN7 (coords: 9) is configured as PIO1_7 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_GREEN_PORT, BOARD_INITLEDSPINS_LED_GREEN_PIN, LED_GREEN); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitBUTTONsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '88', peripheral: GPIO, signal: 'PIO0, 5', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '64', peripheral: GPIO, signal: 'PIO1, 18', pin_signal: PIO1_18/SD1_POW_EN/SCT0_OUT5/PLU_OUT0, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '10', peripheral: GPIO, signal: 'PIO1, 9', pin_signal: PIO1_9/FC1_SCK/CT_INP4/SCT0_OUT2/FC4_CTS_SDA_SSEL0/ADC0_12, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '32', peripheral: SYSCON, signal: RESET, pin_signal: RESETN} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBUTTONsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitBUTTONsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_Gpio0); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t S1_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO0_5 (pin 88) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S1_GPIO, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, &S1_config); gpio_pin_config_t S3_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_9 (pin 10) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S3_GPIO, BOARD_INITBUTTONSPINS_S3_PORT, BOARD_INITBUTTONSPINS_S3_PIN, &S3_config); gpio_pin_config_t S2_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_18 (pin 64) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S2_GPIO, BOARD_INITBUTTONSPINS_S2_PORT, BOARD_INITBUTTONSPINS_S2_PIN, &S2_config); const uint32_t S1 = (/* Pin is configured as PIO0_5 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN5 (coords: 88) is configured as PIO0_5 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, S1); const uint32_t S2 = (/* Pin is configured as PIO1_18 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN18 (coords: 64) is configured as PIO1_18 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S2_PORT, BOARD_INITBUTTONSPINS_S2_PIN, S2); const uint32_t S3 = (/* Pin is configured as PIO1_9 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT1 PIN9 (coords: 10) is configured as PIO1_9 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S3_PORT, BOARD_INITBUTTONSPINS_S3_PIN, S3); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins_Core0: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins_Core0 * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitPins_Core0(void) { } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitI2SPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '91', peripheral: SYSCON, signal: MCLK, pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '76', peripheral: FLEXCOMM7, signal: SCK, pin_signal: PIO0_21/FC3_RTS_SCL_SSEL1/UTICK_CAP3/CTIMER3_MAT3/SCT_GPI3/FC7_SCK/PLU_CLKIN/SECURE_GPIO0_21, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '74', peripheral: FLEXCOMM7, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_20/FC3_CTS_SDA_SSEL0/CTIMER1_MAT1/CT_INP15/SCT_GPI2/FC7_RXD_SDA_MOSI_DATA/HS_SPI_SSEL0/PLU_IN5/SECURE_GPIO0_20/FC4_TXD_SCL_MISO_WS, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '90', peripheral: FLEXCOMM7, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_19/FC4_RTS_SCL_SSEL1/UTICK_CAP0/CTIMER0_MAT2/SCT0_OUT2/FC7_TXD_SCL_MISO_WS/PLU_IN4/SECURE_GPIO0_19, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '21', peripheral: FLEXCOMM6, signal: SCK, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: FC6_I2S_CLK, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '2', peripheral: FLEXCOMM6, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_13/FC6_RXD_SDA_MOSI_DATA/CT_INP6/USB0_OVERCURRENTN/USB0_FRAME/SD0_CARD_DET_N, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '87', peripheral: FLEXCOMM6, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_16/FC6_TXD_SCL_MISO_WS/CTIMER1_MAT3/SD0_CMD, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitI2SPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitI2SPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t FC6_I2S_CLK = (/* Pin is configured as FC6_SCK */ IOCON_PIO_FUNC1 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN10 (coords: 21) is configured as FC6_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_CLK_PORT, BOARD_INITI2SPINS_FC6_I2S_CLK_PIN, FC6_I2S_CLK); const uint32_t FC7_I2S_WS = (/* Pin is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN19 (coords: 90) is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_WS_PORT, BOARD_INITI2SPINS_FC7_I2S_WS_PIN, FC7_I2S_WS); const uint32_t FC7_I2S_TX = (/* Pin is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN20 (coords: 74) is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_TX_PORT, BOARD_INITI2SPINS_FC7_I2S_TX_PIN, FC7_I2S_TX); const uint32_t FC7_I2S_SCK = (/* Pin is configured as FC7_SCK */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN21 (coords: 76) is configured as FC7_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_SCK_PORT, BOARD_INITI2SPINS_FC7_I2S_SCK_PIN, FC7_I2S_SCK); const uint32_t FC6_I2S_RX = (/* Pin is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN13 (coords: 2) is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_RX_PORT, BOARD_INITI2SPINS_FC6_I2S_RX_PIN, FC6_I2S_RX); const uint32_t FC6_I2S_WS = (/* Pin is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN16 (coords: 87) is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_WS_PORT, BOARD_INITI2SPINS_FC6_I2S_WS_PIN, FC6_I2S_WS); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SCL_PORT, BOARD_INITI2SPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SDA_PORT, BOARD_INITI2SPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); const uint32_t MCLK = (/* Pin is configured as MCLK */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN31 (coords: 91) is configured as MCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_MCLK_PORT, BOARD_INITI2SPINS_MCLK_PIN, MCLK); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitACCELPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '58', peripheral: GPIO, signal: 'PIO1, 19', pin_signal: PIO1_19/SCT0_OUT7/CTIMER3_MAT1/SCT_GPI7/FC4_SCK/PLU_OUT1/ACMPVREF, direction: INPUT, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitACCELPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitACCELPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t ACCL_INTR_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_19 (pin 58) */ GPIO_PinInit(BOARD_INITACCELPINS_ACCL_INTR_GPIO, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, &ACCL_INTR_config); const uint32_t ACCL_INTR = (/* Pin is configured as PIO1_19 */ IOCON_PIO_FUNC0 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT1 PIN19 (coords: 58) is configured as PIO1_19 */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, ACCL_INTR); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SCL_PORT, BOARD_INITACCELPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SDA_PORT, BOARD_INITACCELPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board/pin_mux.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_29 (number 92), P8[2]/U6[13]/FC0_USART_RXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN 29U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN_MASK (1U << 29U) /* @} */ /*! @name PIO0_30 (number 94), P8[3]/U6[12]/FC0_USART_TXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN 30U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN_MASK (1U << 30U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC6 0x06u /*!<@brief Selects pin function 6 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLDOWN 0x10u /*!<@brief Selects pull-down function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_11 (number 13), U14[4]/SWDCLK_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN 11U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 11U) /* @} */ /*! @name PIO0_12 (number 12), U15[4]/D7/P7[2]/IF_SWDIO @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN 12U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 12U) /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN 10U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN_MASK (1U << 10U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Enables digital function */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*! * @brief Selects pin function 7 */ #define IOCON_PIO_FUNC7 0x07u /*! * @brief Input function is not inverted */ #define IOCON_PIO_INV_DI 0x00u /*! * @brief No addition pin function */ #define IOCON_PIO_MODE_INACT 0x00u /*! * @brief Open drain is disabled */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*! * @brief Standard mode, output slew rate control is enabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_28_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 7. */ #define PIO0_28_FUNC_ALT7 0x07u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO0_28_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_12_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_12_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_12_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_29_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_29_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_29_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_30_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_30_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_30_MODE_PULL_UP 0x02u /*! @name PIO0_22 (number 78), P10[1]/USB0_VBUS @{ */ #define BOARD_INITUSBPINS_USB0_VBUS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN 22U /*!<@brief PORT pin number */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSBPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_4 (number 1), R78/P18[5]/LEDR/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_BLUE_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN 4U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_6 (number 5), R80/P18[9]/LEDB/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_RED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_RED_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_PIN 6U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_RED_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_7 (number 9), R79/P18[7]/LEDG/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN_MASK (1U << 7U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_GREEN_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN 7U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN_MASK (1U << 7U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_5 (number 88), S1/J10[1]/U3[12]/P17[8]/P7[7]/U11[4]/P0_5-ISP1 @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S1_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_GPIO_PIN_MASK (1U << 5U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S1_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_PIN 5U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S1_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_18 (number 64), S2/P18[16]/P24[2]/WAKE/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S2_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S2_GPIO_PIN_MASK (1U << 18U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S2_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S2_PIN 18U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S2_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_9 (number 10), S3/P18[1]/PIO1_9_GPIO_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S3_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S3_GPIO_PIN_MASK (1U << 9U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S3_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S3_PIN 9U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S3_PIN_MASK (1U << 9U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitBUTTONsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins_Core0(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_FUNC2 0x02u /*!<@brief Selects pin function 2 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_FUNC7 0x07u /*!<@brief Selects pin function 7 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_31 (number 91), P19[7]/P19[8]/PLU_IN0/GPIO @{ */ #define BOARD_INITI2SPINS_MCLK_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_MCLK_PIN 31U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_MCLK_PIN_MASK (1U << 31U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_21 (number 76), P17[14]/FC7_I2S_SCK @{ */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_20 (number 74), P17[10]/FC7_I2S_TX @{ */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_19 (number 90), P17[12]/FC7_I2S_WS @{ */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN 10U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_13 (number 2), P17[20]/FC6_I2S_RX @{ */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN 13U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_16 (number 87), P18[17]/SD1_PWR_EN @{ */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN 16U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitI2SPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_19 (number 58), U7[3]/P18[14]/PLU_OUT1/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */ #define BOARD_INITACCELPINS_ACCL_INTR_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitACCELPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board.cmake ================================================ set(MCU_VARIANT LPC55S28) set(MCU_CORE LPC55S28) set(MCU_DRIVER_VARIANT LPC55S69) set(JLINK_DEVICE LPC55S28) set(JLINK_OPTION "-USB 000727031389") set(PYOCD_TARGET LPC55S28) set(NXPLINK_DEVICE LPC55S28:LPCXpresso55S28) # device fullspeed, host highspeed set(RHPORT_DEVICE 0) set(RHPORT_HOST 1) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S28JBD100 ) endfunction() ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: LPCXpresso55s28 url: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s28-development-board:LPC55S28-EVK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED: use red LED from generated pin_mux #define LED_PORT BOARD_INITLEDSPINS_LED_RED_PORT #define LED_PIN BOARD_INITLEDSPINS_LED_RED_PIN #define LED_STATE_ON 0 // WAKE button: use S2 from generated pin_mux #define BUTTON_PORT BOARD_INITBUTTONSPINS_S2_PORT #define BUTTON_PIN BOARD_INITBUTTONSPINS_S2_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV USART0 // XTAL #define XTAL0_CLK_HZ (16 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s28/board.mk ================================================ MCU_VARIANT = LPC55S28 MCU_CORE = LPC55S28 MCU_DRIVER_VARIANT = LPC55S69 # device fullspeed, host highspeed RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 1 CFLAGS += -DCPU_LPC55S28JBD100 SRC_C += \ $(TOP)/$(BOARD_PATH)/board/clock_config.c \ $(TOP)/$(BOARD_PATH)/board/pin_mux.c \ $(TOP)/$(BOARD_PATH)/board/peripherals.c INC += $(TOP)/$(BOARD_PATH)/board JLINK_DEVICE = LPC55S28 PYOCD_TARGET = LPC55S28 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/LPCXpresso55S69.mex ================================================ LPC55S69 LPC55S69JBD100 LPCXpresso55S69 A2 ksdk2_0 true false /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ true true true false 25.09.10 Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true Configures pin routing and optionally pin electrical features. true cm33_core1 true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true 25.09.10 true true true true true true false true true true true true true false true INPUT true OUTPUT true true true true true true false true INPUT true OUTPUT true true true true true true true 0.0.0 true 2.2.0 true 25.09.10 0 true true 0.0.0 ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/clock_config.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to set up clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v18.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_power.h" #include "fsl_clock.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: System_clock.outFreq, value: 12 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; #endif } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF96M outputs: - {id: System_clock.outFreq, value: 96 MHz} settings: - {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} - {id: SYSCON.MAINCLKSELA.sel, value: ANACTRL.fro_hf_clk} sources: - {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF96M configuration ******************************************************************************/ void BOARD_BootClockFROHF96M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: System_clock.outFreq, value: 100 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), .pllndec = SYSCON_PLL0NDEC_NDIV(4U), .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 100000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: FXCOM0_clock.outFreq, value: 48 MHz} - {id: System_clock.outFreq, value: 144 MHz} - {id: USB0_clock.outFreq, value: 48 MHz} - {id: USB1_PHY_clock.outFreq, value: 16 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: PLL1_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_PLL_USB_OUT, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.FCCLKSEL0.sel, value: SYSCON.PLL0DIV} - {id: SYSCON.FRGCTRL0_DIV.scale, value: '400'} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL1_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0DIV.scale, value: '2'} - {id: SYSCON.PLL0M_MULT.scale, value: '150', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '8', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '2', locked: true} - {id: SYSCON.PLL1CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL1M_MULT.scale, value: '18'} - {id: SYSCON.PLL1_PDEC.scale, value: '2'} - {id: SYSCON.USB0CLKDIV.scale, value: '3'} - {id: SYSCON.USB0CLKSEL.sel, value: SYSCON.MAINCLKSELB} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; /* Enable clk_in to HS USB */ POWER_SetVoltageForFreq(144000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(144000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(8U), .pllpdec = SYSCON_PLL0PDEC_PDIV(1U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(150U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 150000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up PLL1 */ CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL1); /* Ensure PLL is on */ const pll_setup_t pll1Setup = { .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(11U) | SYSCON_PLL1CTRL_SELP(5U), .pllndec = SYSCON_PLL1NDEC_NDIV(1U), .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), .pllmdec = SYSCON_PLL1MDEC_MDIV(18U), .pllRate = 144000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ /*!< Set up dividers */ #if FSL_CLOCK_DRIVER_VERSION >= MAKE_VERSION(2, 3, 4) CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 144U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #else CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 37120U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #endif CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true); /*!< Reset USB0CLKDIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 3U, false); /*!< Set USB0CLKDIV divider to value 3 */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); /*!< Reset PLL0DIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 2U, false); /*!< Set PLL0DIV divider to value 2 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ CLOCK_AttachClk(kMAIN_CLK_to_USB0_CLK); /*!< Switch USB0_CLK to MAIN_CLK */ CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM0); /*!< Switch FLEXCOMM0 to PLL0_DIV */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; #endif } ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/clock_config.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO12M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFRO12M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFRO12M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFRO12M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFRO12M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO12M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFRO12M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO12M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFROHF96M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFROHF96M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFROHF96M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFROHF96M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFROHF96M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFROHF96M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTEM_CLOCK 96000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFROHF96M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFROHF96M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFROHF96M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFROHF96M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL100M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL100M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL100M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL100M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL100M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL100M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTEM_CLOCK 100000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL100M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL100M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL100M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL100M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL150M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL150M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM0_CLOCK 48000000UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL150M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL150M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL150M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL150M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTEM_CLOCK 144000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL150M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL150M_USB0_CLOCK 48000000UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL150M_USB1_PHY_CLOCK 16000000UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL150M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/peripherals.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v15.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 functionalGroups: - name: BOARD_InitPeripherals_cm33_core0 UUID: 61d0725d-b300-49cb-9c66-b5edfbf8ffc1 called_from_default_init: true selectedCore: cm33_core0 - name: BOARD_InitPeripherals_cm33_core1 UUID: e2041cd4-ebb6-45a5-807f-e0c2dc047d48 selectedCore: cm33_core1 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'system' - type_id: 'system' - global_system_definitions: - user_definitions: '' - user_includes: '' - global_init: '' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'uart_cmsis_common' - type_id: 'uart_cmsis_common' - global_USART_CMSIS_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'gpio_adapter_common' - type_id: 'gpio_adapter_common' - global_gpio_adapter_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "peripherals.h" /*********************************************************************************************************************** * BOARD_InitPeripherals_cm33_core0 functional group **********************************************************************************************************************/ /*********************************************************************************************************************** * DEBUG_UART initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'DEBUG_UART' - type: 'flexcomm_usart' - mode: 'polling' - custom_name_enabled: 'true' - type_id: 'flexcomm_usart_2.2.0' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'FLEXCOMM0' - config_sets: - usartConfig_t: - usartConfig: - clockSource: 'FXCOMFunctionClock' - clockSourceFreq: 'ClocksTool_DefaultInit' - baudRate_Bps: '115200' - syncMode: 'kUSART_SyncModeDisabled' - parityMode: 'kUSART_ParityDisabled' - stopBitCount: 'kUSART_OneStopBit' - bitCountPerChar: 'kUSART_8BitsPerChar' - loopback: 'false' - txWatermark: 'kUSART_TxFifo0' - rxWatermark: 'kUSART_RxFifo1' - enableRx: 'true' - enableTx: 'true' - clockPolarity: 'kUSART_RxSampleOnFallingEdge' - enableContinuousSCLK: 'false' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ const usart_config_t DEBUG_UART_config = { .baudRate_Bps = 115200UL, .syncMode = kUSART_SyncModeDisabled, .parityMode = kUSART_ParityDisabled, .stopBitCount = kUSART_OneStopBit, .bitCountPerChar = kUSART_8BitsPerChar, .loopback = false, .txWatermark = kUSART_TxFifo0, .rxWatermark = kUSART_RxFifo1, .enableRx = true, .enableTx = true, .enableMode32k = false, .clockPolarity = kUSART_RxSampleOnFallingEdge, .enableContinuousSCLK = false }; static void DEBUG_UART_init(void) { /* Reset FLEXCOMM device */ RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn); USART_Init(DEBUG_UART_PERIPHERAL, &DEBUG_UART_config, DEBUG_UART_CLOCK_SOURCE); } /*********************************************************************************************************************** * NVIC initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'NVIC' - type: 'nvic' - mode: 'general' - custom_name_enabled: 'false' - type_id: 'nvic' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'NVIC' - config_sets: - nvic: - interrupt_table: [] - interrupts: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /* Empty initialization function (commented out) static void NVIC_init(void) { } */ /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void) { /* Initialize components */ DEBUG_UART_init(); } /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void) { BOARD_InitPeripherals_cm33_core0(); } ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/peripherals.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PERIPHERALS_H_ #define _PERIPHERALS_H_ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "fsl_common.h" #include "fsl_reset.h" #include "fsl_usart.h" #include "fsl_clock.h" #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /* Definitions for BOARD_InitPeripherals_cm33_core0 functional group */ /* Definition of peripheral ID */ #define DEBUG_UART_PERIPHERAL ((USART_Type *)FLEXCOMM0) /* Definition of the clock source frequency */ #define DEBUG_UART_CLOCK_SOURCE 48000000UL /*********************************************************************************************************************** * Global variables **********************************************************************************************************************/ extern const usart_config_t DEBUG_UART_config; /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void); /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void); #if defined(__cplusplus) } #endif #endif /* _PERIPHERALS_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/pin_mux.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_gpio.h" #include "fsl_iocon.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitDEBUG_UARTPins(); BOARD_InitUSBPins(); BOARD_InitLEDsPins(); BOARD_InitBUTTONsPins(); BOARD_InitPins_Core0(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '92', peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_29/FC0_RXD_SDA_MOSI_DATA/SD1_D2/CTIMER2_MAT3/SCT0_OUT8/CMP0_OUT/PLU_OUT2/SECURE_GPIO0_29, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '94', peripheral: FLEXCOMM0, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_30/FC0_TXD_SCL_MISO_WS/SD1_D3/CTIMER0_MAT0/SCT0_OUT9/SECURE_GPIO0_30, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitDEBUG_UARTPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_UART_RX = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN29 (coords: 92) is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN, DEBUG_UART_RX); const uint32_t DEBUG_UART_TX = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN30 (coords: 94) is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN, DEBUG_UART_TX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '13', peripheral: SWD, signal: SWCLK, pin_signal: PIO0_11/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT2/FREQME_GPIO_CLK_A/SWCLK/SECURE_GPIO0_11/ADC0_9, mode: pullDown, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '12', peripheral: SWD, signal: SWDIO, pin_signal: PIO0_12/FC3_TXD_SCL_MISO_WS/SD1_BACKEND_PWR/FREQME_GPIO_CLK_B/SCT_GPI7/SD0_POW_EN/SWDIO/FC6_TXD_SCL_MISO_WS/SECURE_GPIO0_12/ADC0_10, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '21', peripheral: SWD, signal: SWO, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: DEBUG_SWD_SWO, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitSWD_DEBUGPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_SWD_SWO = (/* Pin is configured as SWO */ IOCON_PIO_FUNC6 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT0 PIN10 (coords: 21) is configured as SWO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN, DEBUG_SWD_SWO); if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } else { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } else { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSBPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: USBFSH, signal: USB_DP, pin_signal: USB0_DP} - {pin_num: '98', peripheral: USBFSH, signal: USB_DM, pin_signal: USB0_DM} - {pin_num: '78', peripheral: USBFSH, signal: USB_VBUS, pin_signal: PIO0_22/FC6_TXD_SCL_MISO_WS/UTICK_CAP1/CT_INP15/SCT0_OUT3/USB0_VBUS/SD1_D0/PLU_OUT7/SECURE_GPIO0_22, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '35', peripheral: USBHSH, signal: USB_DM, pin_signal: USB1_DM} - {pin_num: '34', peripheral: USBHSH, signal: USB_DP, pin_signal: USB1_DP} - {pin_num: '36', peripheral: USBHSH, signal: USB_VBUS, pin_signal: USB1_VBUS} - {pin_num: '65', peripheral: USBHSH, signal: USB_OVERCURRENTN, pin_signal: PIO1_30/FC7_TXD_SCL_MISO_WS/SD0_D7/SCT_GPI7/USB1_OVERCURRENTN/USB1_LEDN/PLU_IN1, mode: pullUp} - {pin_num: '66', peripheral: USBFSH, signal: USB_OVERCURRENTN, pin_signal: PIO0_28/FC0_SCK/SD1_CMD/CT_INP11/SCT0_OUT7/USB0_OVERCURRENTN/PLU_OUT1/SECURE_GPIO0_28, mode: pullUp} - {pin_num: '67', peripheral: USBFSH, signal: USB_PORTPWRN, pin_signal: PIO1_12/FC6_SCK/CTIMER1_MAT1/USB0_PORTPWRN/HS_SPI_SSEL2, mode: pullUp} - {pin_num: '80', peripheral: USBHSH, signal: USB_PORTPWRN, pin_signal: PIO1_29/FC7_RXD_SDA_MOSI_DATA/SD0_D6/SCT_GPI6/USB1_PORTPWRN/USB1_FRAME/PLU_IN2, mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSBPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitUSBPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t USB0_VBUS = (/* Pin is configured as USB0_VBUS */ IOCON_PIO_FUNC7 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN22 (coords: 78) is configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, BOARD_INITUSBPINS_USB0_VBUS_PORT, BOARD_INITUSBPINS_USB0_VBUS_PIN, USB0_VBUS); IOCON->PIO[0][28] = ((IOCON->PIO[0][28] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT028 (pin 66) is configured as USB0_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO0_28_FUNC_ALT7) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO0_28_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_28_DIGIMODE_DIGITAL)); IOCON->PIO[1][12] = ((IOCON->PIO[1][12] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT112 (pin 67) is configured as USB0_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_12_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_12_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_12_DIGIMODE_DIGITAL)); IOCON->PIO[1][29] = ((IOCON->PIO[1][29] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT129 (pin 80) is configured as USB1_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_29_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_29_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_29_DIGIMODE_DIGITAL)); IOCON->PIO[1][30] = ((IOCON->PIO[1][30] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT130 (pin 65) is configured as USB1_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO1_30_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_30_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_30_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '1', peripheral: GPIO, signal: 'PIO1, 4', pin_signal: PIO1_4/FC0_SCK/SD0_D0/CTIMER2_MAT1/SCT0_OUT0/FREQME_GPIO_CLK_A, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '5', peripheral: GPIO, signal: 'PIO1, 6', pin_signal: PIO1_6/FC0_TXD_SCL_MISO_WS/SD0_D3/CTIMER2_MAT1/SCT_GPI3, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '9', peripheral: GPIO, signal: 'PIO1, 7', pin_signal: PIO1_7/FC0_RTS_SCL_SSEL1/SD0_D1/CTIMER2_MAT2/SCT_GPI4, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitLEDsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t LED_BLUE_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_4 (pin 1) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_BLUE_GPIO, BOARD_INITLEDSPINS_LED_BLUE_PORT, BOARD_INITLEDSPINS_LED_BLUE_PIN, &LED_BLUE_config); gpio_pin_config_t LED_RED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_6 (pin 5) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_RED_GPIO, BOARD_INITLEDSPINS_LED_RED_PORT, BOARD_INITLEDSPINS_LED_RED_PIN, &LED_RED_config); gpio_pin_config_t LED_GREEN_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO1_7 (pin 9) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_GREEN_GPIO, BOARD_INITLEDSPINS_LED_GREEN_PORT, BOARD_INITLEDSPINS_LED_GREEN_PIN, &LED_GREEN_config); const uint32_t LED_BLUE = (/* Pin is configured as PIO1_4 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN4 (coords: 1) is configured as PIO1_4 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_BLUE_PORT, BOARD_INITLEDSPINS_LED_BLUE_PIN, LED_BLUE); const uint32_t LED_RED = (/* Pin is configured as PIO1_6 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN6 (coords: 5) is configured as PIO1_6 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_RED_PORT, BOARD_INITLEDSPINS_LED_RED_PIN, LED_RED); const uint32_t LED_GREEN = (/* Pin is configured as PIO1_7 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN7 (coords: 9) is configured as PIO1_7 */ IOCON_PinMuxSet(IOCON, BOARD_INITLEDSPINS_LED_GREEN_PORT, BOARD_INITLEDSPINS_LED_GREEN_PIN, LED_GREEN); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitBUTTONsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '88', peripheral: GPIO, signal: 'PIO0, 5', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '64', peripheral: GPIO, signal: 'PIO1, 18', pin_signal: PIO1_18/SD1_POW_EN/SCT0_OUT5/PLU_OUT0, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '10', peripheral: GPIO, signal: 'PIO1, 9', pin_signal: PIO1_9/FC1_SCK/CT_INP4/SCT0_OUT2/FC4_CTS_SDA_SSEL0/ADC0_12, direction: INPUT, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '32', peripheral: SYSCON, signal: RESET, pin_signal: RESETN} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBUTTONsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitBUTTONsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_Gpio0); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t S1_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO0_5 (pin 88) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S1_GPIO, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, &S1_config); gpio_pin_config_t S3_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_9 (pin 10) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S3_GPIO, BOARD_INITBUTTONSPINS_S3_PORT, BOARD_INITBUTTONSPINS_S3_PIN, &S3_config); gpio_pin_config_t S2_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_18 (pin 64) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_S2_GPIO, BOARD_INITBUTTONSPINS_S2_PORT, BOARD_INITBUTTONSPINS_S2_PIN, &S2_config); const uint32_t S1 = (/* Pin is configured as PIO0_5 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN5 (coords: 88) is configured as PIO0_5 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S1_PORT, BOARD_INITBUTTONSPINS_S1_PIN, S1); const uint32_t S2 = (/* Pin is configured as PIO1_18 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN18 (coords: 64) is configured as PIO1_18 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S2_PORT, BOARD_INITBUTTONSPINS_S2_PIN, S2); if (Chip_GetVersion()==1) { const uint32_t S3 = (/* Pin is configured as PIO1_9 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT1 PIN9 (coords: 10) is configured as PIO1_9 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S3_PORT, BOARD_INITBUTTONSPINS_S3_PIN, S3); } else { const uint32_t S3 = (/* Pin is configured as PIO1_9 */ IOCON_PIO_FUNC0 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT1 PIN9 (coords: 10) is configured as PIO1_9 */ IOCON_PinMuxSet(IOCON, BOARD_INITBUTTONSPINS_S3_PORT, BOARD_INITBUTTONSPINS_S3_PIN, S3); } } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins_Core0: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins_Core0 * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitPins_Core0(void) { } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitI2SPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '91', peripheral: SYSCON, signal: MCLK, pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '76', peripheral: FLEXCOMM7, signal: SCK, pin_signal: PIO0_21/FC3_RTS_SCL_SSEL1/UTICK_CAP3/CTIMER3_MAT3/SCT_GPI3/FC7_SCK/PLU_CLKIN/SECURE_GPIO0_21, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '74', peripheral: FLEXCOMM7, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_20/FC3_CTS_SDA_SSEL0/CTIMER1_MAT1/CT_INP15/SCT_GPI2/FC7_RXD_SDA_MOSI_DATA/HS_SPI_SSEL0/PLU_IN5/SECURE_GPIO0_20/FC4_TXD_SCL_MISO_WS, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '90', peripheral: FLEXCOMM7, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_19/FC4_RTS_SCL_SSEL1/UTICK_CAP0/CTIMER0_MAT2/SCT0_OUT2/FC7_TXD_SCL_MISO_WS/PLU_IN4/SECURE_GPIO0_19, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '21', peripheral: FLEXCOMM6, signal: SCK, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: FC6_I2S_CLK, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '2', peripheral: FLEXCOMM6, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_13/FC6_RXD_SDA_MOSI_DATA/CT_INP6/USB0_OVERCURRENTN/USB0_FRAME/SD0_CARD_DET_N, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '87', peripheral: FLEXCOMM6, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_16/FC6_TXD_SCL_MISO_WS/CTIMER1_MAT3/SD0_CMD, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitI2SPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitI2SPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t FC6_I2S_CLK = (/* Pin is configured as FC6_SCK */ IOCON_PIO_FUNC1 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN10 (coords: 21) is configured as FC6_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_CLK_PORT, BOARD_INITI2SPINS_FC6_I2S_CLK_PIN, FC6_I2S_CLK); const uint32_t FC7_I2S_WS = (/* Pin is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN19 (coords: 90) is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_WS_PORT, BOARD_INITI2SPINS_FC7_I2S_WS_PIN, FC7_I2S_WS); const uint32_t FC7_I2S_TX = (/* Pin is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN20 (coords: 74) is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_TX_PORT, BOARD_INITI2SPINS_FC7_I2S_TX_PIN, FC7_I2S_TX); const uint32_t FC7_I2S_SCK = (/* Pin is configured as FC7_SCK */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN21 (coords: 76) is configured as FC7_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_SCK_PORT, BOARD_INITI2SPINS_FC7_I2S_SCK_PIN, FC7_I2S_SCK); const uint32_t FC6_I2S_RX = (/* Pin is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN13 (coords: 2) is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_RX_PORT, BOARD_INITI2SPINS_FC6_I2S_RX_PIN, FC6_I2S_RX); const uint32_t FC6_I2S_WS = (/* Pin is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN16 (coords: 87) is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_WS_PORT, BOARD_INITI2SPINS_FC6_I2S_WS_PIN, FC6_I2S_WS); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SCL_PORT, BOARD_INITI2SPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SDA_PORT, BOARD_INITI2SPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); const uint32_t MCLK = (/* Pin is configured as MCLK */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN31 (coords: 91) is configured as MCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_MCLK_PORT, BOARD_INITI2SPINS_MCLK_PIN, MCLK); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitACCELPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '58', peripheral: GPIO, signal: 'PIO1, 19', pin_signal: PIO1_19/SCT0_OUT7/CTIMER3_MAT1/SCT_GPI7/FC4_SCK/PLU_OUT1/ACMPVREF, direction: INPUT, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitACCELPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitACCELPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t ACCL_INTR_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_19 (pin 58) */ GPIO_PinInit(BOARD_INITACCELPINS_ACCL_INTR_GPIO, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, &ACCL_INTR_config); const uint32_t ACCL_INTR = (/* Pin is configured as PIO1_19 */ IOCON_PIO_FUNC0 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT1 PIN19 (coords: 58) is configured as PIO1_19 */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, ACCL_INTR); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SCL_PORT, BOARD_INITACCELPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SDA_PORT, BOARD_INITACCELPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board/pin_mux.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_29 (number 92), P8[2]/U6[13]/FC0_USART_RXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN 29U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN_MASK (1U << 29U) /* @} */ /*! @name PIO0_30 (number 94), P8[3]/U6[12]/FC0_USART_TXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN 30U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN_MASK (1U << 30U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_ASW_DIS_EN 0x00u /*!<@brief Analog switch is closed (enabled), only for A0 version */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC6 0x06u /*!<@brief Selects pin function 6 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLDOWN 0x10u /*!<@brief Selects pull-down function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_11 (number 13), U14[4]/SWDCLK_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN 11U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 11U) /* @} */ /*! @name PIO0_12 (number 12), U15[4]/D7/P7[2]/IF_SWDIO @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN 12U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 12U) /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN 10U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN_MASK (1U << 10U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Enables digital function */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*! * @brief Selects pin function 7 */ #define IOCON_PIO_FUNC7 0x07u /*! * @brief Input function is not inverted */ #define IOCON_PIO_INV_DI 0x00u /*! * @brief No addition pin function */ #define IOCON_PIO_MODE_INACT 0x00u /*! * @brief Open drain is disabled */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*! * @brief Standard mode, output slew rate control is enabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_28_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 7. */ #define PIO0_28_FUNC_ALT7 0x07u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO0_28_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_12_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_12_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_12_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_29_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_29_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_29_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_30_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_30_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_30_MODE_PULL_UP 0x02u /*! @name PIO0_22 (number 78), P10[1]/USB0_VBUS @{ */ #define BOARD_INITUSBPINS_USB0_VBUS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN 22U /*!<@brief PORT pin number */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSBPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_4 (number 1), R78/P18[5]/LEDR/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_BLUE_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN 4U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_6 (number 5), R80/P18[9]/LEDB/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_RED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_RED_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_PIN 6U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_RED_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_7 (number 9), R79/P18[7]/LEDG/PWM_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN_MASK (1U << 7U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_GREEN_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN 7U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN_MASK (1U << 7U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DIS_EN 0x00u /*!<@brief Analog switch is closed (enabled), only for A0 version */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_5 (number 88), S1/J10[1]/U3[12]/P17[8]/P7[7]/U11[4]/P0_5-ISP1 @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S1_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_GPIO_PIN_MASK (1U << 5U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S1_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S1_PIN 5U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S1_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_18 (number 64), S2/P18[16]/P24[2]/WAKE/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S2_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S2_GPIO_PIN_MASK (1U << 18U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S2_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S2_PIN 18U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S2_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_9 (number 10), S3/P18[1]/PIO1_9_GPIO_ARD @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_S3_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S3_GPIO_PIN_MASK (1U << 9U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_S3_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_S3_PIN 9U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_S3_PIN_MASK (1U << 9U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitBUTTONsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins_Core0(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_FUNC2 0x02u /*!<@brief Selects pin function 2 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_FUNC7 0x07u /*!<@brief Selects pin function 7 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_31 (number 91), P19[7]/P19[8]/PLU_IN0/GPIO @{ */ #define BOARD_INITI2SPINS_MCLK_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_MCLK_PIN 31U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_MCLK_PIN_MASK (1U << 31U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_21 (number 76), P17[14]/FC7_I2S_SCK @{ */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_20 (number 74), P17[10]/FC7_I2S_TX @{ */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_19 (number 90), P17[12]/FC7_I2S_WS @{ */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN 10U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_13 (number 2), P17[20]/FC6_I2S_RX @{ */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN 13U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_16 (number 87), P18[17]/SD1_PWR_EN @{ */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN 16U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitI2SPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_19 (number 58), U7[3]/P18[14]/PLU_OUT1/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */ #define BOARD_INITACCELPINS_ACCL_INTR_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitACCELPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board.cmake ================================================ set(MCU_VARIANT LPC55S69) set(MCU_CORE LPC55S69_cm33_core0) set(JLINK_DEVICE LPC55S69_M33_0) set(JLINK_OPTION "-USB 000727648789") set(PYOCD_TARGET LPC55S69) set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69) # device highspeed, host fullspeed set(RHPORT_DEVICE 1) set(RHPORT_HOST 0) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S69JBD100_cm33_core0 ) endfunction() ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: LPCXpresso55s69 url: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s69-development-board:LPC55S69-EVK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED: use red LED from generated pin_mux #define LED_PORT BOARD_INITLEDSPINS_LED_RED_PORT #define LED_PIN BOARD_INITLEDSPINS_LED_RED_PIN #define LED_STATE_ON 0 // WAKE button: use S2 from generated pin_mux #define BUTTON_PORT BOARD_INITBUTTONSPINS_S2_PORT #define BUTTON_PIN BOARD_INITBUTTONSPINS_S2_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV USART0 // XTAL #define XTAL0_CLK_HZ (16 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc55/boards/lpcxpresso55s69/board.mk ================================================ MCU_VARIANT = LPC55S69 MCU_CORE = LPC55S69_cm33_core0 # device highspeed, host fullspeed RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 CFLAGS += -DCPU_LPC55S69JBD100_cm33_core0 SRC_C += \ $(TOP)/$(BOARD_PATH)/board/clock_config.c \ $(TOP)/$(BOARD_PATH)/board/pin_mux.c \ $(TOP)/$(BOARD_PATH)/board/peripherals.c INC += $(TOP)/$(BOARD_PATH)/board JLINK_DEVICE = LPC55S69 PYOCD_TARGET = LPC55S69 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/clock_config.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to set up clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v18.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_power.h" #include "fsl_clock.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: System_clock.outFreq, value: 12 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; #endif } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF96M outputs: - {id: System_clock.outFreq, value: 96 MHz} settings: - {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} - {id: SYSCON.MAINCLKSELA.sel, value: ANACTRL.fro_hf_clk} sources: - {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF96M configuration ******************************************************************************/ void BOARD_BootClockFROHF96M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: System_clock.outFreq, value: 100 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), .pllndec = SYSCON_PLL0NDEC_NDIV(4U), .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 100000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; #endif } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: FXCOM0_clock.outFreq, value: 48 MHz} - {id: System_clock.outFreq, value: 144 MHz} - {id: USB0_clock.outFreq, value: 48 MHz} - {id: USB1_PHY_clock.outFreq, value: 16 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: PLL1_Mode, value: Normal} - {id: ENABLE_CLKIN_ENA, value: Enabled} - {id: ENABLE_PLL_USB_OUT, value: Enabled} - {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} - {id: SYSCON.FCCLKSEL0.sel, value: SYSCON.PLL0DIV} - {id: SYSCON.FRGCTRL0_DIV.scale, value: '400'} - {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL1_BYPASS} - {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL0DIV.scale, value: '2'} - {id: SYSCON.PLL0M_MULT.scale, value: '150', locked: true} - {id: SYSCON.PLL0N_DIV.scale, value: '8', locked: true} - {id: SYSCON.PLL0_PDEC.scale, value: '2', locked: true} - {id: SYSCON.PLL1CLKSEL.sel, value: SYSCON.CLK_IN_EN} - {id: SYSCON.PLL1M_MULT.scale, value: '18'} - {id: SYSCON.PLL1_PDEC.scale, value: '2'} - {id: SYSCON.USB0CLKDIV.scale, value: '3'} - {id: SYSCON.USB0CLKSEL.sel, value: SYSCON.MAINCLKSELB} sources: - {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { #ifndef SDK_SECONDARY_CORE /*!< Set up the clock sources */ /*!< Configure FRO192M */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ /*!< Configure XTAL32M */ POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; /* Enable clk_in to HS USB */ POWER_SetVoltageForFreq(144000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ CLOCK_SetFLASHAccessCyclesForFreq(144000000U); /*!< Set FLASH wait states for core */ /*!< Set up PLL */ CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(8U), .pllpdec = SYSCON_PLL0PDEC_PDIV(1U), .pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(150U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 150000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ /*!< Set up PLL1 */ CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */ POWER_DisablePD(kPDRUNCFG_PD_PLL1); /* Ensure PLL is on */ const pll_setup_t pll1Setup = { .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(11U) | SYSCON_PLL1CTRL_SELP(5U), .pllndec = SYSCON_PLL1NDEC_NDIV(1U), .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), .pllmdec = SYSCON_PLL1MDEC_MDIV(18U), .pllRate = 144000000U, .flags = PLL_SETUPFLAG_WAITLOCK }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ /*!< Set up dividers */ #if FSL_CLOCK_DRIVER_VERSION >= MAKE_VERSION(2, 3, 4) CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 144U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #else CLOCK_SetClkDiv(kCLOCK_DivFlexFrg0, 37120U, false); /*!< Set DIV to value 0xFF and MULT to value 144U in related FLEXFRGCTRL register */ #endif CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 0U, true); /*!< Reset USB0CLKDIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 3U, false); /*!< Set USB0CLKDIV divider to value 3 */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); /*!< Reset PLL0DIV divider counter and halt it */ CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 2U, false); /*!< Set PLL0DIV divider to value 2 */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ CLOCK_AttachClk(kMAIN_CLK_to_USB0_CLK); /*!< Switch USB0_CLK to MAIN_CLK */ CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM0); /*!< Switch FLEXCOMM0 to PLL0_DIV */ /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; #endif } ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/clock_config.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO12M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFRO12M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFRO12M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFRO12M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFRO12M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFRO12M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFRO12M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO12M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFRO12M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFRO12M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO12M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF96M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFROHF96M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKFROHF96M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKFROHF96M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKFROHF96M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKFROHF96M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKFROHF96M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKFROHF96M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKFROHF96M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKFROHF96M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKFROHF96M_SYSTEM_CLOCK 96000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKFROHF96M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFROHF96M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKFROHF96M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKFROHF96M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFROHF96M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockFROHF96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL100M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL100M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL100M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM0_CLOCK 0UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL100M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL100M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL100M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL100M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL100M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL100M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL100M_SYSTEM_CLOCK 100000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL100M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL100M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL100M_USB1_PHY_CLOCK 0UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL100M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL100M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKPLL150M_ASYNCADC_CLOCK 0UL /* Clock consumers of ASYNCADC_clock output : ADC0 */ #define BOARD_BOOTCLOCKPLL150M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER3_CLOCK 0UL /* Clock consumers of CTIMER3_clock output : CTIMER3 */ #define BOARD_BOOTCLOCKPLL150M_CTIMER4_CLOCK 0UL /* Clock consumers of CTIMER4_clock output : CTIMER4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM0_CLOCK 48000000UL /* Clock consumers of FXCOM0_clock output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM1_CLOCK 0UL /* Clock consumers of FXCOM1_clock output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM2_CLOCK 0UL /* Clock consumers of FXCOM2_clock output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM3_CLOCK 0UL /* Clock consumers of FXCOM3_clock output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM4_CLOCK 0UL /* Clock consumers of FXCOM4_clock output : FLEXCOMM4 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM5_CLOCK 0UL /* Clock consumers of FXCOM5_clock output : FLEXCOMM5 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM6_CLOCK 0UL /* Clock consumers of FXCOM6_clock output : FLEXCOMM6 */ #define BOARD_BOOTCLOCKPLL150M_FXCOM7_CLOCK 0UL /* Clock consumers of FXCOM7_clock output : FLEXCOMM7 */ #define BOARD_BOOTCLOCKPLL150M_HSLSPI_CLOCK 0UL /* Clock consumers of HSLSPI_clock output : FLEXCOMM8 */ #define BOARD_BOOTCLOCKPLL150M_MCLK_CLOCK 0UL /* Clock consumers of MCLK_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_OSC32KHZ_CLOCK 0UL /* Clock consumers of OSC32KHZ_clock output : FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_OSTIMER32KHZ_CLOCK 0UL /* Clock consumers of OSTIMER32KHZ_clock output : OSTIMER */ #define BOARD_BOOTCLOCKPLL150M_PLUCLKIN_CLOCK 0UL /* Clock consumers of PLUCLKIN_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_12MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_12MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_PLU_GLITCH_1MHZ_CLOCK 0UL /* Clock consumers of PLU_GLITCH_1MHz_clock output : PLU */ #define BOARD_BOOTCLOCKPLL150M_RTC1HZ_CLOCK 0UL /* Clock consumers of RTC1HZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_RTC1KHZ_CLOCK 0UL /* Clock consumers of RTC1KHZ_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SCT_CLOCK 0UL /* Clock consumers of SCT_clock output : SCT0 */ #define BOARD_BOOTCLOCKPLL150M_SDIO_CLOCK 0UL /* Clock consumers of SDIO_clock output : SDIF */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK0_CLOCK 0UL /* Clock consumers of SYSTICK0_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTICK1_CLOCK 0UL /* Clock consumers of SYSTICK1_clock output : N/A */ #define BOARD_BOOTCLOCKPLL150M_SYSTEM_CLOCK 144000000UL /* Clock consumers of System_clock output : ADC0, ANACTRL, CASPER, CRC_ENGINE, CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4, DMA0, DMA1, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM8, GINT0, GINT1, GPIO, INPUTMUX, IOCON, MAILBOX, MRT0, OSTIMER, PINT, PLU, PUF, SCT0, SDIF, SECGPIO, SECPINT, SWD, SYSCTL, USB0, USBFSH, USBHSD, USBHSH, USBPHY, UTICK0, WWDT */ #define BOARD_BOOTCLOCKPLL150M_TRACE_CLOCK 0UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKPLL150M_USB0_CLOCK 48000000UL /* Clock consumers of USB0_clock output : USB0, USBFSH */ #define BOARD_BOOTCLOCKPLL150M_USB1_PHY_CLOCK 16000000UL /* Clock consumers of USB1_PHY_clock output : USBHSD, USBHSH, USBPHY */ #define BOARD_BOOTCLOCKPLL150M_UTICK_CLOCK 0UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKPLL150M_WDT_CLOCK 0UL /* Clock consumers of WDT_clock output : WWDT */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/peripherals.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v15.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 functionalGroups: - name: BOARD_InitPeripherals_cm33_core0 UUID: 61d0725d-b300-49cb-9c66-b5edfbf8ffc1 called_from_default_init: true selectedCore: cm33_core0 - name: BOARD_InitPeripherals_cm33_core1 UUID: e2041cd4-ebb6-45a5-807f-e0c2dc047d48 selectedCore: cm33_core1 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'system' - type_id: 'system' - global_system_definitions: - user_definitions: '' - user_includes: '' - global_init: '' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'uart_cmsis_common' - type_id: 'uart_cmsis_common' - global_USART_CMSIS_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* component: - type: 'gpio_adapter_common' - type_id: 'gpio_adapter_common' - global_gpio_adapter_common: - quick_selection: 'default' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "peripherals.h" /*********************************************************************************************************************** * BOARD_InitPeripherals_cm33_core0 functional group **********************************************************************************************************************/ /*********************************************************************************************************************** * DEBUG_UART initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'DEBUG_UART' - type: 'flexcomm_usart' - mode: 'polling' - custom_name_enabled: 'true' - type_id: 'flexcomm_usart_2.2.0' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'FLEXCOMM0' - config_sets: - usartConfig_t: - usartConfig: - clockSource: 'FXCOMFunctionClock' - clockSourceFreq: 'ClocksTool_DefaultInit' - baudRate_Bps: '115200' - syncMode: 'kUSART_SyncModeDisabled' - parityMode: 'kUSART_ParityDisabled' - stopBitCount: 'kUSART_OneStopBit' - bitCountPerChar: 'kUSART_8BitsPerChar' - loopback: 'false' - txWatermark: 'kUSART_TxFifo0' - rxWatermark: 'kUSART_RxFifo1' - enableRx: 'true' - enableTx: 'true' - clockPolarity: 'kUSART_RxSampleOnFallingEdge' - enableContinuousSCLK: 'false' * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ const usart_config_t DEBUG_UART_config = { .baudRate_Bps = 115200UL, .syncMode = kUSART_SyncModeDisabled, .parityMode = kUSART_ParityDisabled, .stopBitCount = kUSART_OneStopBit, .bitCountPerChar = kUSART_8BitsPerChar, .loopback = false, .txWatermark = kUSART_TxFifo0, .rxWatermark = kUSART_RxFifo1, .enableRx = true, .enableTx = true, .enableMode32k = false, .clockPolarity = kUSART_RxSampleOnFallingEdge, .enableContinuousSCLK = false }; static void DEBUG_UART_init(void) { /* Reset FLEXCOMM device */ RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn); USART_Init(DEBUG_UART_PERIPHERAL, &DEBUG_UART_config, DEBUG_UART_CLOCK_SOURCE); } /*********************************************************************************************************************** * NVIC initialization code **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'NVIC' - type: 'nvic' - mode: 'general' - custom_name_enabled: 'false' - type_id: 'nvic' - functional_group: 'BOARD_InitPeripherals_cm33_core0' - peripheral: 'NVIC' - config_sets: - nvic: - interrupt_table: [] - interrupts: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /* Empty initialization function (commented out) static void NVIC_init(void) { } */ /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void) { /* Initialize components */ DEBUG_UART_init(); } /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void) { BOARD_InitPeripherals_cm33_core0(); } ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/peripherals.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PERIPHERALS_H_ #define _PERIPHERALS_H_ /*********************************************************************************************************************** * Included files **********************************************************************************************************************/ #include "fsl_common.h" #include "fsl_reset.h" #include "fsl_usart.h" #include "fsl_clock.h" #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ /* Definitions for BOARD_InitPeripherals_cm33_core0 functional group */ /* Definition of peripheral ID */ #define DEBUG_UART_PERIPHERAL ((USART_Type *)FLEXCOMM0) /* Definition of the clock source frequency */ #define DEBUG_UART_CLOCK_SOURCE 48000000UL /*********************************************************************************************************************** * Global variables **********************************************************************************************************************/ extern const usart_config_t DEBUG_UART_config; /*********************************************************************************************************************** * Initialization functions **********************************************************************************************************************/ void BOARD_InitPeripherals_cm33_core0(void); /*********************************************************************************************************************** * BOARD_InitBootPeripherals function **********************************************************************************************************************/ void BOARD_InitBootPeripherals(void); #if defined(__cplusplus) } #endif #endif /* _PERIPHERALS_H_ */ ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/pin_mux.c ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: LPC55S69 package_id: LPC55S69JBD100 mcu_data: ksdk2_0 processor_version: 25.09.10 board: LPCXpresso55S69 expansion_headers: - id: lpc_style_arduino name: LPCXpresso V3 (Arduino compatible) connectors: - id: C1 name: P16 pins: - {id: 8, name: 3.3V, external_signal_types: power_supply_3.3V} - {id: 10, name: RESET, pin_num: '32', pin_signal: RESETN} - {id: 12, name: 3.3V, external_signal_types: power_supply_3.3V} - {id: 14, name: 5V, external_signal_types: power_supply_5V} - {id: 16, name: GND, external_signal_types: ground} - {id: 18, name: GND, external_signal_types: ground} - {id: 20, name: 5V, external_signal_types: power_supply_5V} - id: C2 name: P17 pins: - {id: 1, name: D15, pin_num: '4', pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2} - {id: 3, name: D14, pin_num: '30', pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3} - {id: 5, name: 3.3V, external_signal_types: power_supply_3.3V} - {id: 6, pin_num: '93', pin_signal: PIO1_11/FC1_TXD_SCL_MISO_WS/CT_INP5/USB0_VBUS} - {id: 7, name: GND, external_signal_types: ground} - {id: 8, pin_num: '88', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5} - {id: 9, name: D13, pin_num: '61', pin_signal: PIO1_2/CTIMER0_MAT3/SCT_GPI6/HS_SPI_SCK/USB1_PORTPWRN/PLU_OUT5} - {id: 10, pin_num: '74', pin_signal: PIO0_20/FC3_CTS_SDA_SSEL0/CTIMER1_MAT1/CT_INP15/SCT_GPI2/FC7_RXD_SDA_MOSI_DATA/HS_SPI_SSEL0/PLU_IN5/SECURE_GPIO0_20/FC4_TXD_SCL_MISO_WS} - {id: 11, name: D12, pin_num: '62', pin_signal: PIO1_3/SCT0_OUT4/HS_SPI_MISO/USB0_PORTPWRN/PLU_OUT6} - {id: 12, pin_num: '90', pin_signal: PIO0_19/FC4_RTS_SCL_SSEL1/UTICK_CAP0/CTIMER0_MAT2/SCT0_OUT2/FC7_TXD_SCL_MISO_WS/PLU_IN4/SECURE_GPIO0_19} - {id: 13, name: D11, pin_num: '60', pin_signal: PIO0_26/FC2_RXD_SDA_MOSI_DATA/CLKOUT/CT_INP14/SCT0_OUT5/USB0_IDVALUE/FC0_SCK/HS_SPI_MOSI/SECURE_GPIO0_26} - {id: 14, pin_num: '76', pin_signal: PIO0_21/FC3_RTS_SCL_SSEL1/UTICK_CAP3/CTIMER3_MAT3/SCT_GPI3/FC7_SCK/PLU_CLKIN/SECURE_GPIO0_21} - {id: 15, name: D10, pin_num: '59', pin_signal: PIO1_1/FC3_RXD_SDA_MOSI_DATA/CT_INP3/SCT_GPI5/HS_SPI_SSEL1/USB1_OVERCURRENTN/PLU_OUT4} - {id: 16, pin_num: '85', pin_signal: PIO1_27/FC2_RTS_SCL_SSEL1/SD0_D4/CTIMER0_MAT3/CLKOUT/PLU_IN4} - {id: 17, name: D9, pin_num: '31', pin_signal: PIO1_5/FC0_RXD_SDA_MOSI_DATA/SD0_D2/CTIMER2_MAT0/SCT_GPI0} - {id: 18, pin_num: '73', pin_signal: PIO1_28/FC7_SCK/SD0_D5/CT_INP2/PLU_IN3} - {id: 19, name: D8, pin_num: '24', pin_signal: PIO1_8/FC0_CTS_SDA_SSEL0/SD0_CLK/SCT0_OUT1/FC4_SSEL2/ADC0_4} - {id: 20, pin_num: '2', pin_signal: PIO1_13/FC6_RXD_SDA_MOSI_DATA/CT_INP6/USB0_OVERCURRENTN/USB0_FRAME/SD0_CARD_DET_N} - id: C3 name: P18 pins: - {id: 1, name: D7, pin_num: '10', pin_signal: PIO1_9/FC1_SCK/CT_INP4/SCT0_OUT2/FC4_CTS_SDA_SSEL0/ADC0_12} - {id: 2, pin_num: '7', pin_signal: PIO0_1/FC3_CTS_SDA_SSEL0/CT_INP0/SCT_GPI1/SD1_CLK/CMP0_OUT/SECURE_GPIO0_1} - {id: 3, name: D6, pin_num: '40', pin_signal: PIO1_10/FC1_RXD_SDA_MOSI_DATA/CTIMER1_MAT0/SCT0_OUT3} - {id: 4, pin_num: '57', pin_signal: PIO1_14/UTICK_CAP2/CTIMER1_MAT2/FC5_CTS_SDA_SSEL0/USB0_LEDN/SD1_CMD/ACMP0_D} - {id: 5, name: D5, pin_num: '1', pin_signal: PIO1_4/FC0_SCK/SD0_D0/CTIMER2_MAT1/SCT0_OUT0/FREQME_GPIO_CLK_A} - {id: 6, pin_num: '77', pin_signal: PIO1_25/FC2_TXD_SCL_MISO_WS/SCT0_OUT2/SD1_D0/UTICK_CAP0/PLU_CLKIN} - {id: 7, name: D4-LED_GREEN, pin_num: '9', pin_signal: PIO1_7/FC0_RTS_SCL_SSEL1/SD0_D1/CTIMER2_MAT2/SCT_GPI4} - {id: 8, pin_num: '42', pin_signal: PIO1_23/FC2_SCK/SCT0_OUT0/SD1_D3/FC3_SSEL2/PLU_OUT5} - {id: 10, pin_num: '3', pin_signal: PIO1_24/FC2_RXD_SDA_MOSI_DATA/SCT0_OUT1/SD1_D1/FC3_SSEL3/PLU_OUT6} - {id: 11, name: D2, pin_num: '22', pin_signal: PIO0_15/FC6_CTS_SDA_SSEL0/UTICK_CAP2/CT_INP16/SCT0_OUT2/SD0_WR_PRT/SECURE_GPIO0_15/ADC0_2} - {id: 12, pin_num: '82', pin_signal: PIO1_15/UTICK_CAP3/CT_INP7/FC5_RTS_SCL_SSEL1/FC4_RTS_SCL_SSEL1/SD1_D2} - {id: 13, name: D1, pin_num: '27', pin_signal: PIO0_27/FC2_TXD_SCL_MISO_WS/CTIMER3_MAT2/SCT0_OUT6/FC7_RXD_SDA_MOSI_DATA/PLU_OUT0/SECURE_GPIO0_27} - {id: 14, pin_num: '58', pin_signal: PIO1_19/SCT0_OUT7/CTIMER3_MAT1/SCT_GPI7/FC4_SCK/PLU_OUT1/ACMPVREF} - {id: 15, name: D0, pin_num: '3', pin_signal: PIO1_24/FC2_RXD_SDA_MOSI_DATA/SCT0_OUT1/SD1_D1/FC3_SSEL3/PLU_OUT6} - {id: 16, pin_num: '64', pin_signal: PIO1_18/SD1_POW_EN/SCT0_OUT5/PLU_OUT0} - {id: 17, pin_num: '87', pin_signal: PIO1_16/FC6_TXD_SCL_MISO_WS/CTIMER1_MAT3/SD0_CMD} - {id: 18, pin_num: '68', pin_signal: PIO1_26/FC2_CTS_SDA_SSEL0/SCT0_OUT3/CT_INP3/UTICK_CAP1/HS_SPI_SSEL3/PLU_IN5} - {id: 19, pin_num: '43', pin_signal: PIO1_17/FC6_RTS_SCL_SSEL1/SCT0_OUT4/SD1_CARD_INT_N/SD1_CARD_DET_N} - {id: 20, pin_num: '56', pin_signal: PIO0_18/FC4_CTS_SDA_SSEL0/SD0_WR_PRT/CTIMER1_MAT0/SCT0_OUT1/PLU_IN3/SECURE_GPIO0_18/ACMP0_C} - id: C4 name: P19 pins: - {id: 2, name: A0, pin_num: '14', pin_signal: PIO0_16/FC4_TXD_SCL_MISO_WS/CLKOUT/CT_INP4/SECURE_GPIO0_16/ADC0_8} - {id: 4, name: A1, pin_num: '20', pin_signal: PIO0_23/MCLK/CTIMER1_MAT2/CTIMER3_MAT3/SCT0_OUT4/FC0_CTS_SDA_SSEL0/SD1_D1/SECURE_GPIO0_23/ADC0_0} - {id: 6, name: A2, pin_num: '54', pin_signal: PIO0_0/FC3_SCK/CTIMER0_MAT0/SCT_GPI0/SD1_CARD_INT_N/SECURE_GPIO0_0/ACMP0_A} - {id: 7, pin_num: '91', pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0} - {id: 8, name: A3, pin_num: '91', pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0} - {id: 9, pin_num: '71', pin_signal: PIO0_13/FC1_CTS_SDA_SSEL0/UTICK_CAP0/CT_INP0/SCT_GPI0/FC1_RXD_SDA_MOSI_DATA/PLU_IN0/SECURE_GPIO0_13} - {id: 10, name: A4, pin_num: '71', pin_signal: PIO0_13/FC1_CTS_SDA_SSEL0/UTICK_CAP0/CT_INP0/SCT_GPI0/FC1_RXD_SDA_MOSI_DATA/PLU_IN0/SECURE_GPIO0_13} - {id: 11, pin_num: '72', pin_signal: PIO0_14/FC1_RTS_SCL_SSEL1/UTICK_CAP1/CT_INP1/SCT_GPI1/FC1_TXD_SCL_MISO_WS/PLU_IN1/SECURE_GPIO0_14} - {id: 12, name: A5, pin_num: '72', pin_signal: PIO0_14/FC1_RTS_SCL_SSEL1/UTICK_CAP1/CT_INP1/SCT_GPI1/FC1_TXD_SCL_MISO_WS/PLU_IN1/SECURE_GPIO0_14} pin_labels: - {pin_num: '7', pin_signal: PIO0_1/FC3_CTS_SDA_SSEL0/CT_INP0/SCT_GPI1/SD1_CLK/CMP0_OUT/SECURE_GPIO0_1, label: 'P18[2]/SD1_CLK', identifier: LED_RED} - {pin_num: '88', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5, label: 'S1/J10[1]/U3[12]/P17[8]/P7[7]/U11[4]/P0_5-ISP1', identifier: LED} - {pin_num: '11', pin_signal: PIO1_0/FC0_RTS_SCL_SSEL1/SD0_D3/CT_INP2/SCT_GPI4/PLU_OUT3/ADC0_11, label: 'U20[2]/SD0_D3', identifier: BUTTON} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_gpio.h" #include "fsl_iocon.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitDEBUG_UARTPins(); BOARD_InitUSBPins(); BOARD_InitLEDsPins(); BOARD_InitBUTTONsPins(); BOARD_InitPins_Core0(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '92', peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_29/FC0_RXD_SDA_MOSI_DATA/SD1_D2/CTIMER2_MAT3/SCT0_OUT8/CMP0_OUT/PLU_OUT2/SECURE_GPIO0_29, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '94', peripheral: FLEXCOMM0, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_30/FC0_TXD_SCL_MISO_WS/SD1_D3/CTIMER0_MAT0/SCT0_OUT9/SECURE_GPIO0_30, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitDEBUG_UARTPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_UART_RX = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN29 (coords: 92) is configured as FC0_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN, DEBUG_UART_RX); const uint32_t DEBUG_UART_TX = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN30 (coords: 94) is configured as FC0_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN, DEBUG_UART_TX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '13', peripheral: SWD, signal: SWCLK, pin_signal: PIO0_11/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT2/FREQME_GPIO_CLK_A/SWCLK/SECURE_GPIO0_11/ADC0_9, mode: pullDown, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '12', peripheral: SWD, signal: SWDIO, pin_signal: PIO0_12/FC3_TXD_SCL_MISO_WS/SD1_BACKEND_PWR/FREQME_GPIO_CLK_B/SCT_GPI7/SD0_POW_EN/SWDIO/FC6_TXD_SCL_MISO_WS/SECURE_GPIO0_12/ADC0_10, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '21', peripheral: SWD, signal: SWO, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: DEBUG_SWD_SWO, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitSWD_DEBUGPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t DEBUG_SWD_SWO = (/* Pin is configured as SWO */ IOCON_PIO_FUNC6 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT0 PIN10 (coords: 21) is configured as SWO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN, DEBUG_SWD_SWO); if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } else { const uint32_t DEBUG_SWD_SWDCLK = (/* Pin is configured as SWCLK */ IOCON_PIO_FUNC6 | /* Selects pull-down function */ IOCON_PIO_MODE_PULLDOWN | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN11 (coords: 13) is configured as SWCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, DEBUG_SWD_SWDCLK); } if (Chip_GetVersion()==1) { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } else { const uint32_t DEBUG_SWD_SWDIO = (/* Pin is configured as SWDIO */ IOCON_PIO_FUNC6 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled), only for A0 version */ IOCON_PIO_ASW_DIS_EN); /* PORT0 PIN12 (coords: 12) is configured as SWDIO */ IOCON_PinMuxSet(IOCON, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, DEBUG_SWD_SWDIO); } } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitUSBPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '97', peripheral: USBFSH, signal: USB_DP, pin_signal: USB0_DP} - {pin_num: '98', peripheral: USBFSH, signal: USB_DM, pin_signal: USB0_DM} - {pin_num: '78', peripheral: USBFSH, signal: USB_VBUS, pin_signal: PIO0_22/FC6_TXD_SCL_MISO_WS/UTICK_CAP1/CT_INP15/SCT0_OUT3/USB0_VBUS/SD1_D0/PLU_OUT7/SECURE_GPIO0_22, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '35', peripheral: USBHSH, signal: USB_DM, pin_signal: USB1_DM} - {pin_num: '34', peripheral: USBHSH, signal: USB_DP, pin_signal: USB1_DP} - {pin_num: '36', peripheral: USBHSH, signal: USB_VBUS, pin_signal: USB1_VBUS} - {pin_num: '65', peripheral: USBHSH, signal: USB_OVERCURRENTN, pin_signal: PIO1_30/FC7_TXD_SCL_MISO_WS/SD0_D7/SCT_GPI7/USB1_OVERCURRENTN/USB1_LEDN/PLU_IN1, mode: pullUp} - {pin_num: '66', peripheral: USBFSH, signal: USB_OVERCURRENTN, pin_signal: PIO0_28/FC0_SCK/SD1_CMD/CT_INP11/SCT0_OUT7/USB0_OVERCURRENTN/PLU_OUT1/SECURE_GPIO0_28, mode: pullUp} - {pin_num: '67', peripheral: USBFSH, signal: USB_PORTPWRN, pin_signal: PIO1_12/FC6_SCK/CTIMER1_MAT1/USB0_PORTPWRN/HS_SPI_SSEL2, mode: pullUp} - {pin_num: '80', peripheral: USBHSH, signal: USB_PORTPWRN, pin_signal: PIO1_29/FC7_RXD_SDA_MOSI_DATA/SD0_D6/SCT_GPI6/USB1_PORTPWRN/USB1_FRAME/PLU_IN2, mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitUSBPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitUSBPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t USB0_VBUS = (/* Pin is configured as USB0_VBUS */ IOCON_PIO_FUNC7 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN22 (coords: 78) is configured as USB0_VBUS */ IOCON_PinMuxSet(IOCON, BOARD_INITUSBPINS_USB0_VBUS_PORT, BOARD_INITUSBPINS_USB0_VBUS_PIN, USB0_VBUS); IOCON->PIO[0][28] = ((IOCON->PIO[0][28] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT028 (pin 66) is configured as USB0_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO0_28_FUNC_ALT7) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO0_28_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_28_DIGIMODE_DIGITAL)); IOCON->PIO[1][12] = ((IOCON->PIO[1][12] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT112 (pin 67) is configured as USB0_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_12_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_12_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_12_DIGIMODE_DIGITAL)); IOCON->PIO[1][29] = ((IOCON->PIO[1][29] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT129 (pin 80) is configured as USB1_PORTPWRN. */ | IOCON_PIO_FUNC(PIO1_29_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_29_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_29_DIGIMODE_DIGITAL)); IOCON->PIO[1][30] = ((IOCON->PIO[1][30] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT130 (pin 65) is configured as USB1_OVERCURRENTN. */ | IOCON_PIO_FUNC(PIO1_30_FUNC_ALT4) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_30_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_30_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '88', peripheral: GPIO, signal: 'PIO0, 5', pin_signal: PIO0_5/FC4_RXD_SDA_MOSI_DATA/CTIMER3_MAT0/SCT_GPI5/FC3_RTS_SCL_SSEL1/MCLK/SECURE_GPIO0_5, direction: OUTPUT, gpio_init_state: 'true', mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitLEDsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_Gpio0); gpio_pin_config_t LED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO0_5 (pin 88) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_GPIO, BOARD_INITLEDSPINS_LED_PORT, BOARD_INITLEDSPINS_LED_PIN, &LED_config); IOCON->PIO[0][5] = ((IOCON->PIO[0][5] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT05 (pin 88) is configured as PIO0_5. */ | IOCON_PIO_FUNC(PIO0_5_FUNC_ALT0) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO0_5_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO0_5_DIGIMODE_DIGITAL)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitBUTTONsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '32', peripheral: SYSCON, signal: RESET, pin_signal: RESETN} - {pin_num: '11', peripheral: GPIO, signal: 'PIO1, 0', pin_signal: PIO1_0/FC0_RTS_SCL_SSEL1/SD0_D3/CT_INP2/SCT_GPI4/PLU_OUT3/ADC0_11, direction: INPUT, mode: pullUp} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBUTTONsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitBUTTONsPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t BUTTON_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_0 (pin 11) */ GPIO_PinInit(BOARD_INITBUTTONSPINS_BUTTON_GPIO, BOARD_INITBUTTONSPINS_BUTTON_PORT, BOARD_INITBUTTONSPINS_BUTTON_PIN, &BUTTON_config); if (Chip_GetVersion()==1) { IOCON->PIO[1][0] = ((IOCON->PIO[1][0] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT10 (pin 11) is configured as PIO1_0. */ | IOCON_PIO_FUNC(PIO1_0_FUNC_ALT0) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_0_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_0_DIGIMODE_DIGITAL)); } else { IOCON->PIO[1][0] = ((IOCON->PIO[1][0] & /* Mask bits to zero which are setting */ (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) /* Selects pin function. * : PORT10 (pin 11) is configured as PIO1_0. */ | IOCON_PIO_FUNC(PIO1_0_FUNC_ALT0) /* Selects function mode (on-chip pull-up/pull-down resistor control). * : Pull-up. * Pull-up resistor enabled. */ | IOCON_PIO_MODE(PIO1_0_MODE_PULL_UP) /* Select Digital mode. * : Enable Digital mode. * Digital input is enabled. */ | IOCON_PIO_DIGIMODE(PIO1_0_DIGIMODE_DIGITAL)); } } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins_Core0: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins_Core0 * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitPins_Core0(void) { } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitI2SPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '91', peripheral: SYSCON, signal: MCLK, pin_signal: PIO1_31/MCLK/SD1_CLK/CTIMER0_MAT2/SCT0_OUT6/PLU_IN0, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '76', peripheral: FLEXCOMM7, signal: SCK, pin_signal: PIO0_21/FC3_RTS_SCL_SSEL1/UTICK_CAP3/CTIMER3_MAT3/SCT_GPI3/FC7_SCK/PLU_CLKIN/SECURE_GPIO0_21, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '74', peripheral: FLEXCOMM7, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_20/FC3_CTS_SDA_SSEL0/CTIMER1_MAT1/CT_INP15/SCT_GPI2/FC7_RXD_SDA_MOSI_DATA/HS_SPI_SSEL0/PLU_IN5/SECURE_GPIO0_20/FC4_TXD_SCL_MISO_WS, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '90', peripheral: FLEXCOMM7, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_19/FC4_RTS_SCL_SSEL1/UTICK_CAP0/CTIMER0_MAT2/SCT0_OUT2/FC7_TXD_SCL_MISO_WS/PLU_IN4/SECURE_GPIO0_19, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '21', peripheral: FLEXCOMM6, signal: SCK, pin_signal: PIO0_10/FC6_SCK/CT_INP10/CTIMER2_MAT0/FC1_TXD_SCL_MISO_WS/SCT0_OUT2/SWO/SECURE_GPIO0_10/ADC0_1, identifier: FC6_I2S_CLK, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled, asw: enabled} - {pin_num: '2', peripheral: FLEXCOMM6, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_13/FC6_RXD_SDA_MOSI_DATA/CT_INP6/USB0_OVERCURRENTN/USB0_FRAME/SD0_CARD_DET_N, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '87', peripheral: FLEXCOMM6, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_16/FC6_TXD_SCL_MISO_WS/CTIMER1_MAT3/SD0_CMD, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitI2SPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitI2SPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); const uint32_t FC6_I2S_CLK = (/* Pin is configured as FC6_SCK */ IOCON_PIO_FUNC1 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is closed (enabled) */ IOCON_PIO_ASW_EN); /* PORT0 PIN10 (coords: 21) is configured as FC6_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_CLK_PORT, BOARD_INITI2SPINS_FC6_I2S_CLK_PIN, FC6_I2S_CLK); const uint32_t FC7_I2S_WS = (/* Pin is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN19 (coords: 90) is configured as FC7_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_WS_PORT, BOARD_INITI2SPINS_FC7_I2S_WS_PIN, FC7_I2S_WS); const uint32_t FC7_I2S_TX = (/* Pin is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN20 (coords: 74) is configured as FC7_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_TX_PORT, BOARD_INITI2SPINS_FC7_I2S_TX_PIN, FC7_I2S_TX); const uint32_t FC7_I2S_SCK = (/* Pin is configured as FC7_SCK */ IOCON_PIO_FUNC7 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT0 PIN21 (coords: 76) is configured as FC7_SCK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC7_I2S_SCK_PORT, BOARD_INITI2SPINS_FC7_I2S_SCK_PIN, FC7_I2S_SCK); const uint32_t FC6_I2S_RX = (/* Pin is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN13 (coords: 2) is configured as FC6_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_RX_PORT, BOARD_INITI2SPINS_FC6_I2S_RX_PIN, FC6_I2S_RX); const uint32_t FC6_I2S_WS = (/* Pin is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC2 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN16 (coords: 87) is configured as FC6_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC6_I2S_WS_PORT, BOARD_INITI2SPINS_FC6_I2S_WS_PIN, FC6_I2S_WS); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SCL_PORT, BOARD_INITI2SPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_FC4_I2C_SDA_PORT, BOARD_INITI2SPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); const uint32_t MCLK = (/* Pin is configured as MCLK */ IOCON_PIO_FUNC1 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN31 (coords: 91) is configured as MCLK */ IOCON_PinMuxSet(IOCON, BOARD_INITI2SPINS_MCLK_PORT, BOARD_INITI2SPINS_MCLK_PIN, MCLK); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitACCELPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '30', peripheral: FLEXCOMM4, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO1_21/FC7_CTS_SDA_SSEL0/CTIMER3_MAT2/FC4_RXD_SDA_MOSI_DATA/PLU_OUT3, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '4', peripheral: FLEXCOMM4, signal: TXD_SCL_MISO_WS, pin_signal: PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2, mode: pullUp, slew_rate: standard, invert: disabled, open_drain: disabled} - {pin_num: '58', peripheral: GPIO, signal: 'PIO1, 19', pin_signal: PIO1_19/SCT0_OUT7/CTIMER3_MAT1/SCT_GPI7/FC4_SCK/PLU_OUT1/ACMPVREF, direction: INPUT, mode: inactive, slew_rate: standard, invert: disabled, open_drain: disabled, asw: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitACCELPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 (Core #0) */ void BOARD_InitACCELPins(void) { /* Enables the clock for the I/O controller.: Enable Clock. */ CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the GPIO1 module */ CLOCK_EnableClock(kCLOCK_Gpio1); gpio_pin_config_t ACCL_INTR_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO1_19 (pin 58) */ GPIO_PinInit(BOARD_INITACCELPINS_ACCL_INTR_GPIO, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, &ACCL_INTR_config); const uint32_t ACCL_INTR = (/* Pin is configured as PIO1_19 */ IOCON_PIO_FUNC0 | /* No addition pin function */ IOCON_PIO_MODE_INACT | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI | /* Analog switch is open (disabled) */ IOCON_PIO_ASW_DI); /* PORT1 PIN19 (coords: 58) is configured as PIO1_19 */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_ACCL_INTR_PORT, BOARD_INITACCELPINS_ACCL_INTR_PIN, ACCL_INTR); const uint32_t FC4_I2C_SCL = (/* Pin is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN20 (coords: 4) is configured as FC4_TXD_SCL_MISO_WS */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SCL_PORT, BOARD_INITACCELPINS_FC4_I2C_SCL_PIN, FC4_I2C_SCL); const uint32_t FC4_I2C_SDA = (/* Pin is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PIO_FUNC5 | /* Selects pull-up function */ IOCON_PIO_MODE_PULLUP | /* Standard mode, output slew rate control is enabled */ IOCON_PIO_SLEW_STANDARD | /* Input function is not inverted */ IOCON_PIO_INV_DI | /* Enables digital function */ IOCON_PIO_DIGITAL_EN | /* Open drain is disabled */ IOCON_PIO_OPENDRAIN_DI); /* PORT1 PIN21 (coords: 30) is configured as FC4_RXD_SDA_MOSI_DATA */ IOCON_PinMuxSet(IOCON, BOARD_INITACCELPINS_FC4_I2C_SDA_PORT, BOARD_INITACCELPINS_FC4_I2C_SDA_PIN, FC4_I2C_SDA); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board/pin_mux.h ================================================ /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_29 (number 92), P8[2]/U6[13]/FC0_USART_RXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN 29U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN_MASK (1U << 29U) /* @} */ /*! @name PIO0_30 (number 94), P8[3]/U6[12]/FC0_USART_TXD @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN 30U /*! * @brief PORT pin mask */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN_MASK (1U << 30U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_ASW_DIS_EN 0x00u /*!<@brief Analog switch is closed (enabled), only for A0 version */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC6 0x06u /*!<@brief Selects pin function 6 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLDOWN 0x10u /*!<@brief Selects pull-down function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO0_11 (number 13), U14[4]/SWDCLK_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN 11U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 11U) /* @} */ /*! @name PIO0_12 (number 12), U15[4]/D7/P7[2]/IF_SWDIO @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN 12U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 12U) /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ /*! * @brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PORT 0U /*! * @brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN 10U /*! * @brief PORT pin mask */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWO_PIN_MASK (1U << 10U) /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Enables digital function */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*! * @brief Selects pin function 7 */ #define IOCON_PIO_FUNC7 0x07u /*! * @brief Input function is not inverted */ #define IOCON_PIO_INV_DI 0x00u /*! * @brief No addition pin function */ #define IOCON_PIO_MODE_INACT 0x00u /*! * @brief Open drain is disabled */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*! * @brief Standard mode, output slew rate control is enabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_28_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 7. */ #define PIO0_28_FUNC_ALT7 0x07u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO0_28_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_12_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_12_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_12_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_29_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_29_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_29_MODE_PULL_UP 0x02u /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_30_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 4. */ #define PIO1_30_FUNC_ALT4 0x04u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_30_MODE_PULL_UP 0x02u /*! @name PIO0_22 (number 78), P10[1]/USB0_VBUS @{ */ #define BOARD_INITUSBPINS_USB0_VBUS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN 22U /*!<@brief PORT pin number */ #define BOARD_INITUSBPINS_USB0_VBUS_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitUSBPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO0_5_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 0. */ #define PIO0_5_FUNC_ALT0 0x00u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO0_5_MODE_PULL_UP 0x02u /*! @name PIO0_5 (number 88), S1/J10[1]/U3[12]/P17[8]/P7[7]/U11[4]/P0_5-ISP1 @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_GPIO_PIN_MASK (1U << 5U) /*!<@brief GPIO pin mask */ #define BOARD_INITLEDSPINS_LED_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_PIN 5U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Select Digital mode.: Enable Digital mode. Digital input is enabled. */ #define PIO1_0_DIGIMODE_DIGITAL 0x01u /*! * @brief Selects pin function.: Alternative connection 0. */ #define PIO1_0_FUNC_ALT0 0x00u /*! * @brief Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-up. Pull-up resistor enabled. */ #define PIO1_0_MODE_PULL_UP 0x02u /*! @name PIO1_0 (number 11), U20[2]/SD0_D3 @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_BUTTON_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!<@brief GPIO pin mask */ #define BOARD_INITBUTTONSPINS_BUTTON_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_BUTTON_PIN 0U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_BUTTON_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitBUTTONsPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins_Core0(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_EN 0x0400u /*!<@brief Analog switch is closed (enabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_FUNC2 0x02u /*!<@brief Selects pin function 2 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_FUNC7 0x07u /*!<@brief Selects pin function 7 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_31 (number 91), P19[7]/P19[8]/PLU_IN0/GPIO @{ */ #define BOARD_INITI2SPINS_MCLK_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_MCLK_PIN 31U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_MCLK_PIN_MASK (1U << 31U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_21 (number 76), P17[14]/FC7_I2S_SCK @{ */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_SCK_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_20 (number 74), P17[10]/FC7_I2S_TX @{ */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_TX_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_19 (number 90), P17[12]/FC7_I2S_WS @{ */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC7_I2S_WS_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO0_10 (number 21), U14[12]/SWO_TRGT @{ */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PORT 0U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN 10U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_CLK_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_13 (number 2), P17[20]/FC6_I2S_RX @{ */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN 13U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_RX_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_16 (number 87), P18[17]/SD1_PWR_EN @{ */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN 16U /*!<@brief PORT pin number */ #define BOARD_INITI2SPINS_FC6_I2S_WS_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitI2SPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #define IOCON_PIO_ASW_DI 0x00u /*!<@brief Analog switch is open (disabled) */ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */ /*! @name PIO1_21 (number 30), P17[3]/P24[6]/FC4_I2C_SDA_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN 21U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SDA_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_20 (number 4), P17[1]/P24[5]/FC4_I2C_SCL_ARD @{ */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN 20U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_FC4_I2C_SCL_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PIO1_19 (number 58), U7[3]/P18[14]/PLU_OUT1/GPIO @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */ #define BOARD_INITACCELPINS_ACCL_INTR_PORT 1U /*!<@brief PORT peripheral base pointer */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN 19U /*!<@brief PORT pin number */ #define BOARD_INITACCELPINS_ACCL_INTR_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitACCELPins(void); /* Function assigned for the Cortex-M33 (Core #0) */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board.cmake ================================================ set(MCU_VARIANT LPC55S69) set(MCU_CORE LPC55S69_cm33_core0) set(JLINK_DEVICE LPC55S69) set(PYOCD_TARGET LPC55S69) set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S69JBD64_cm33_core0 ) endfunction() ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MCU Link url: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcu-link-debug-probe:MCU-LINK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT BOARD_INITLEDSPINS_LED_PORT #define LED_PIN BOARD_INITLEDSPINS_LED_PIN #define LED_STATE_ON 0 // WAKE button (Dummy, use unused pin #define BUTTON_PORT BOARD_INITBUTTONSPINS_BUTTON_PORT #define BUTTON_PIN BOARD_INITBUTTONSPINS_BUTTON_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV USART0 // XTAL #define XTAL0_CLK_HZ (16 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/board.mk ================================================ MCU_VARIANT = LPC55S69 MCU_CORE = LPC55S69_cm33_core0 RHPORT_DEVICE ?= 1 CFLAGS += -DCPU_LPC55S69JBD64_cm33_core0 SRC_C += \ $(TOP)/$(BOARD_PATH)/board/clock_config.c \ $(TOP)/$(BOARD_PATH)/board/pin_mux.c \ $(TOP)/$(BOARD_PATH)/board/peripherals.c INC += $(TOP)/$(BOARD_PATH)/board JLINK_DEVICE = LPC55S69 PYOCD_TARGET = LPC55S69 # flash using pyocd flash: flash-pyocd ================================================ FILE: hw/bsp/lpc55/boards/mcu_link/mcu_link.mex ================================================ LPC55S69 LPC55S69JBD100 LPCXpresso55S69 A2 ksdk2_0 true false /* * Copyright 2026 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ true true true false 25.09.10 Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true Configures pin routing and optionally pin electrical features. true cm33_core1 true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true true 25.09.10 true true true true true true false true true true true true true false true INPUT true OUTPUT true true true true true true false true INPUT true OUTPUT true true true true true true true 0.0.0 true 2.2.0 true 25.09.10 0 true true 0.0.0 ================================================ FILE: hw/bsp/lpc55/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "board.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_power.h" #include "fsl_usart.h" #include "board/pin_mux.h" #include "board/clock_config.h" #include "board/peripherals.h" #ifdef NEOPIXEL_PIN #include "fsl_sctimer.h" #include "sct_neopixel.h" #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { tusb_int_handler(0, true); } void USB1_IRQHandler(void) { tusb_int_handler(1, true); } void board_init(void) { BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); board_led_write(0); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); NVIC_SetPriority(USB1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0) // Port0 is Full Speed NVIC_ClearPendingIRQ(USB0_IRQn); NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn); /* Turn on USB0 Phy */ POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /* reset the IP to make sure it's in reset state. */ RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn); if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) { // Enable USB Clock Adjustments to trim the FRO for the full speed controller ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK; CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); CLOCK_AttachClk(kFRO_HF_to_USB0_CLK); /*According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbhsl0); // enable usb0 host clock USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbhsl0); // disable usb0 host clock /* enable USB Device clock */ CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); } else { CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbfsSrcPll1, 48000000U); USBFSH->PORTMODE &= ~USBFSH_PORTMODE_DEV_ENABLE_MASK; } #endif #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) // Port1 is High Speed /* Turn on USB1 Phy */ POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* reset the IP to make sure it's in reset state. */ RESET_PeripheralReset(kUSB1H_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1D_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn); if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) { /* According to reference manual, device mode setting has to be set by access usb host register */ CLOCK_EnableClock(kCLOCK_Usbh1); // enable usb0 host clock USBHSH->PORTMODE = USBHSH_PORTMODE_SW_PDCOM_MASK; // Put PHY powerdown under software control USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK; CLOCK_DisableClock(kCLOCK_Usbh1); // disable usb0 host clock /* enable USB Device clock */ CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUnused, 0U); } else { CLOCK_EnableUsbhs0HostClock(kCLOCK_UsbSrcUnused, 0U); } CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_UsbPhySrcExt, XTAL0_CLK_HZ); // Enable PHY support for Low speed device + LS via FS Hub USBPHY->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; // Enable all power for normal operation USBPHY->PWD = 0; USBPHY->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK; USBPHY->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK; // PHY Tx calibration USBPHY->TX = ((USBPHY->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) | (USBPHY_TX_D_CAL(0x05U) | USBPHY_TX_TXCAL45DP(0x0AU) | USBPHY_TX_TXCAL45DM(0x0AU))); ARM_MPU_SetMemAttr(0, 0x44); // Normal memory, non-cacheable (inner and outer) ARM_MPU_SetRegion(0, ARM_MPU_RBAR(0x40100000, ARM_MPU_SH_NON, 0, 1, 1), ARM_MPU_RLAR(0x40104000, 0)); ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { // active low return BUTTON_STATE_ACTIVE == GPIO_PinRead(GPIO, BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #ifdef __clang__ void _exit (int __status) { (void) __status; while (1) {} } #endif #endif ================================================ FILE: hw/bsp/lpc55/family.cmake ================================================ include_guard() set(MCUX_DIR ${TOP}/hw/mcu/nxp/mcuxsdk-core) set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-devices-lpc/LPC5500) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS LPC55 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- # default device port to USB1 highspeed, host to USB0 fullspeed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () # port 0 is fullspeed, port 1 is highspeed set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${SDK_DIR}/${MCU_VARIANT}/iar/${MCU_CORE}_flash.icf) endif () if (NOT DEFINED STARTUP_FILE_IAR) set(STARTUP_FILE_IAR ${SDK_DIR}/${MCU_VARIANT}/iar/startup_${MCU_CORE}.s) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) # Some variants (e.g. LPC55S28) share drivers with another variant (e.g. LPC55S69) if (NOT DEFINED MCU_DRIVER_VARIANT) set(MCU_DRIVER_VARIANT ${MCU_VARIANT}) endif () add_library(${BOARD_TARGET} STATIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/pin_mux.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/peripherals.c # driver ${MCUX_DIR}/drivers/lpc_gpio/fsl_gpio.c ${MCUX_DIR}/drivers/common/fsl_common_arm.c ${MCUX_DIR}/drivers/flexcomm/fsl_flexcomm.c ${MCUX_DIR}/drivers/flexcomm/usart/fsl_usart.c # mcu ${SDK_DIR}/${MCU_VARIANT}/system_${MCU_CORE}.c ${SDK_DIR}/${MCU_DRIVER_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/${MCU_DRIVER_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/${MCU_DRIVER_VARIANT}/drivers/fsl_reset.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${TOP}/lib/sct_neopixel # driver ${MCUX_DIR}/drivers/common ${MCUX_DIR}/drivers/flexcomm ${MCUX_DIR}/drivers/flexcomm/usart ${MCUX_DIR}/drivers/lpc_iocon ${MCUX_DIR}/drivers/lpc_gpio ${MCUX_DIR}/drivers/sctimer # mcu ${SDK_DIR}/${MCU_VARIANT} ${SDK_DIR}/${MCU_DRIVER_VARIANT}/drivers ${SDK_DIR}/periph ${CMSIS_DIR}/CMSIS/Core/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} __STARTUP_CLEAR_BSS ) # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM if (RHPORT_DEVICE EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC [=[CFG_TUD_MEM_SECTION=__attribute__((section("m_usb_global")))]=] ) endif () if (RHPORT_HOST EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC [=[CFG_TUH_MEM_SECTION=__attribute__((section("m_usb_global")))]=] CFG_TUH_USBIP_IP3516=1 ) endif () update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_LPC55) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/lib/sct_neopixel/sct_neopixel.c ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) if (RHPORT_HOST EQUAL 0) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/ohci/ohci.c ) elseif (RHPORT_HOST EQUAL 1) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c ) endif () target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs -nostartfiles "LINKER:--defsym=__stack_size__=0x1000" "LINKER:--defsym=__heap_size__=0" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" "LINKER:--config_def=__stack_size__=0x1000" "LINKER:--config_def=__heap_size__=0" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") set_source_files_properties(${TOP}/lib/sct_neopixel/sct_neopixel.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-unused-parameter") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) #family_flash_pyocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/lpc55/family.mk ================================================ UF2_FAMILY_ID = 0x2abc77ec include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 MCUX_DIR = hw/mcu/nxp/mcuxsdk-core SDK_DIR = hw/mcu/nxp/mcux-devices-lpc # Some variants (e.g. LPC55S28) share drivers with another variant (e.g. LPC55S69) MCU_DRIVER_VARIANT ?= $(MCU_VARIANT) # Default device port to USB1 highspeed, host to USB0 fullspeed RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 CFLAGS += \ -flto \ -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC55XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ -DBOARD_TUD_RHPORT=$(RHPORT_DEVICE) \ -DBOARD_TUH_RHPORT=$(RHPORT_HOST) \ # port 0 is fullspeed, port 1 is highspeed ifeq ($(RHPORT_DEVICE), 1) CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # Port1 controller can only access USB_SRAM CFLAGS += -DCFG_TUD_MEM_SECTION='__attribute__((section("m_usb_global")))' else CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED endif ifeq ($(RHPORT_HOST), 1) CFLAGS += -DBOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED CFLAGS += -DCFG_TUH_MEM_SECTION='__attribute__((section("m_usb_global")))' CFLAGS += -DCFG_TUH_USBIP_IP3516=1 SRC_C += $(TOP)/src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c else CFLAGS += -DBOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=float-equal LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ -Wl,--defsym=__stack_size__=0x1000 \ -Wl,--defsym=__heap_size__=0 \ # All source paths should be relative to the top level. LD_FILE ?= $(SDK_DIR)/LPC5500/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld SRC_C += \ $(TOP)/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_VARIANT)/system_$(MCU_CORE).c \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_DRIVER_VARIANT)/drivers/fsl_clock.c \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_DRIVER_VARIANT)/drivers/fsl_power.c \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_DRIVER_VARIANT)/drivers/fsl_reset.c \ $(TOP)/$(MCUX_DIR)/drivers/lpc_gpio/fsl_gpio.c \ $(TOP)/$(MCUX_DIR)/drivers/common/fsl_common_arm.c \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/fsl_flexcomm.c \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/usart/fsl_usart.c \ $(TOP)/lib/sct_neopixel/sct_neopixel.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/sct_neopixel \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_VARIANT) \ $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_DRIVER_VARIANT)/drivers \ $(TOP)/$(SDK_DIR)/LPC5500/periph \ $(TOP)/$(MCUX_DIR)/drivers/common \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/usart \ $(TOP)/$(MCUX_DIR)/drivers/flexcomm/ \ $(TOP)/$(MCUX_DIR)/drivers/lpc_iocon \ $(TOP)/$(MCUX_DIR)/drivers/lpc_gpio \ $(TOP)/$(MCUX_DIR)/drivers/sctimer SRC_S += $(TOP)/$(SDK_DIR)/LPC5500/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S ================================================ FILE: hw/bsp/maxim/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "mxc_device.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS __NVIC_PRIO_BITS /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<-jlink` target for CMake. Most the Evaluation Kit and boards are shipped with a CMSIS-DAP compatible debug probe. However, at the time of writing, the necessary flashing algorithms for OpenOCD have not yet been incorporated into the OpenOCD master branch. To utilize the provided debug probes, please install the bundled MSDK package which includes the appropriate OpenOCD modifications. To leverage this OpenOCD instance, run the `flash-msdk` Makefile rule, or `-openocd` CMake target. ================================================ FILE: hw/bsp/maxim/boards/apard32690/board.cmake ================================================ set(MAX_DEVICE max32690) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/maxim/boards/apard32690/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: APARD32690-SL url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32690.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO2 #define LED_PIN MXC_GPIO_PIN_1 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 1 // Button #define BUTTON_PORT MXC_GPIO1 #define BUTTON_PIN MXC_GPIO_PIN_27 #define BUTTON_PULL MXC_GPIO_PAD_NONE #define BUTTON_STATE_ACTIVE 1 // UART Enable for UART on ARM SWD Connector #define UART_NUM 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/apard32690/board.mk ================================================ MAX_DEVICE = max32690 ================================================ FILE: hw/bsp/maxim/boards/max32650evkit/board.cmake ================================================ set(MAX_DEVICE max32650) function(update_board TARGET) endfunction() function(prepare_image TARGET_IN) #No signing required endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32650evkit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32650 EVKIT url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650-evkit.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32650.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO2 #define LED_PIN MXC_GPIO_PIN_25 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO2 #define BUTTON_PIN MXC_GPIO_PIN_28 #define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL #define UART_NUM 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32650evkit/board.mk ================================================ MAX_DEVICE = max32650 ================================================ FILE: hw/bsp/maxim/boards/max32650fthr/board.cmake ================================================ set(MAX_DEVICE max32650) function(update_board TARGET) endfunction() function(prepare_image TARGET_IN) #No signing required endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32650fthr/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32650 Feather url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650fthr.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32650.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO1 #define LED_PIN MXC_GPIO_PIN_14 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIO #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO1 #define BUTTON_PIN MXC_GPIO_PIN_19 #define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for SWD UART Pins. Pin Mux handled by the HAL #define UART_NUM 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32650fthr/board.mk ================================================ MAX_DEVICE = max32650 ================================================ FILE: hw/bsp/maxim/boards/max32651evkit/board.cmake ================================================ set(MAX_DEVICE max32650) # Use the secure linker file set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/max32651.ld) function(update_board TARGET) # for the signed target, need to add the __SLA_FWK__ define target_compile_definitions(${TARGET} PUBLIC __SLA_FWK__ ) endfunction() function(sign_image TARGET_IN) #For the signed target, set up a POST_BUILD command to sign the elf file once created if((WIN32) OR (MINGW) OR (MSYS)) set(SIGN_EXE "sign_app.exe") else() set(SIGN_EXE "sign_app") endif() set(MCU_PATH "${TOP}/hw/mcu/analog/msdk/") # Custom POST_BUILD command add_custom_command( TARGET ${TARGET_IN} POST_BUILD COMMAND ${CMAKE_OBJCOPY} $ -R .sig -O binary $/${TARGET_IN}.bin COMMAND ${MCU_PATH}/Tools/SBT/bin/${SIGN_EXE} -c MAX32651 key_file=${MCU_PATH}/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key ca=$/${TARGET_IN}.bin sca=$/${TARGET_IN}.sbin COMMAND ${CMAKE_OBJCOPY} $ --update-section .sig=$/${TARGET_IN}.sig VERBATIM ) endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32651evkit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32651 EVKIT url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32651-evkit.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32650.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO2 #define LED_PIN MXC_GPIO_PIN_25 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO2 #define BUTTON_PIN MXC_GPIO_PIN_28 #define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL #define UART_NUM 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32651evkit/board.mk ================================================ MAX_DEVICE = max32650 # Use the secure linker file LD_FILE = $(FAMILY_PATH)/linker/max32651.ld # Let the family script know the build needs to be signed SIGNED_BUILD := 1 ================================================ FILE: hw/bsp/maxim/boards/max32666evkit/board.cmake ================================================ set(MAX_DEVICE max32665) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32666evkit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32666 EVKIT url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666evkit.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32665.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO1 #define LED_PIN MXC_GPIO_PIN_14 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO1 #define BUTTON_PIN MXC_GPIO_PIN_6 #define BUTTON_PULL MXC_GPIO_PAD_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL #define UART_NUM 1 #define UART_MAP MAP_A #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32666evkit/board.mk ================================================ MAX_DEVICE = max32665 ================================================ FILE: hw/bsp/maxim/boards/max32666fthr/board.cmake ================================================ set(MAX_DEVICE max32665) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32666fthr/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32666 Feather url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666fthr.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max32665.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO0 #define LED_PIN MXC_GPIO_PIN_29 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO1 #define BUTTON_PIN MXC_GPIO_PIN_10 #define BUTTON_PULL MXC_GPIO_PAD_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for UART on SWD. Pin Mux handled by the HAL #define UART_NUM 1 #define UART_MAP MAP_B #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32666fthr/board.mk ================================================ MAX_DEVICE = max32665 ================================================ FILE: hw/bsp/maxim/boards/max32690evkit/board.cmake ================================================ set(MAX_DEVICE max32690) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/maxim/boards/max32690evkit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX32690 EVKIT url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32690evkit.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "max32690.h" // LED #define LED_PORT MXC_GPIO0 #define LED_PIN MXC_GPIO_PIN_14 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 0 // Button #define BUTTON_PORT MXC_GPIO4 #define BUTTON_PIN MXC_GPIO_PIN_0 #define BUTTON_PULL MXC_GPIO_PAD_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL #define UART_NUM 2 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max32690evkit/board.mk ================================================ MAX_DEVICE = max32690 ================================================ FILE: hw/bsp/maxim/boards/max78002evkit/board.cmake ================================================ set(MAX_DEVICE max78002) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/maxim/boards/max78002evkit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MAX78002 EVKIT url: https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78002evkit.html */ #ifndef BOARD_H_ #define BOARD_H_ #include "max78002.h" #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT MXC_GPIO2 #define LED_PIN MXC_GPIO_PIN_4 #define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH #define LED_STATE_ON 1 // Button #define BUTTON_PORT MXC_GPIO2 #define BUTTON_PIN MXC_GPIO_PIN_6 #define BUTTON_PULL MXC_GPIO_PAD_PULL_UP #define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL #define UART_NUM 0 #define UART_PORT MXC_GPIO0 #define UART_VDDIO_BITS 0xF #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/maxim/boards/max78002evkit/board.mk ================================================ MAX_DEVICE = max78002 ================================================ FILE: hw/bsp/maxim/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Analog Devices */ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "gpio.h" #include "mxc_sys.h" #if __has_include("mcr_regs.h") #include "mcr_regs.h" #endif #include "mxc_device.h" #include "uart.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "board.h" #include "bsp/board_api.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM); void board_init(void) { #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif mxc_gpio_cfg_t gpioConfig; // LED gpioConfig.drvstr = MXC_GPIO_DRVSTR_0; gpioConfig.func = MXC_GPIO_FUNC_OUT; gpioConfig.mask = LED_PIN; gpioConfig.pad = MXC_GPIO_PAD_NONE; gpioConfig.port = LED_PORT; gpioConfig.vssel = LED_VDDIO; MXC_GPIO_Config(&gpioConfig); board_led_write(false); // Button gpioConfig.drvstr = MXC_GPIO_DRVSTR_0; gpioConfig.func = MXC_GPIO_FUNC_IN; gpioConfig.mask = BUTTON_PIN; gpioConfig.pad = BUTTON_PULL; gpioConfig.port = BUTTON_PORT; gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO; MXC_GPIO_Config(&gpioConfig); // UART #if MAX_PERIPH_ID == 14 MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE, UART_MAP); #elif MAX_PERIPH_ID == 18 || MAX_PERIPH_ID == 87 MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE, MXC_UART_IBRO_CLK); #if MAX_PERIPH_ID == 87 UART_PORT->vssel |= UART_VDDIO_BITS; // Set necessary bits to 3.3V #endif #endif //USB #if defined(MAX32650) // Startup the HIRC96M clock if it's not on already if (!(MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_HIRC96_EN)) { MXC_GCR->clk_ctrl |= MXC_F_GCR_CLK_CTRL_HIRC96_EN; MXC_SYS_Clock_Timeout(MXC_F_GCR_CLK_CTRL_HIRC96_RDY); } MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB); #elif defined(MAX32665) || defined(MAX32666) // Startup the HIRC96M clock if it's not on already if (!(MXC_GCR->clkcn & MXC_F_GCR_CLKCN_HIRC96M_EN)) { MXC_GCR->clkcn |= MXC_F_GCR_CLKCN_HIRC96M_EN; } MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB); #elif defined(MAX32690) MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO); MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB); # elif defined(MAX78002) MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); #else #error "Unsupported MAXIM MCU for board_dfu_init" #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #if LED_STATE_ON state = !state; #endif if (state) { MXC_GPIO_OutClr(LED_PORT, LED_PIN); } else { MXC_GPIO_OutSet(LED_PORT, LED_PIN); } } uint32_t board_button_read(void) { uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; return BUTTON_STATE_ACTIVE == state; } size_t board_get_unique_id(uint8_t id[], size_t max_len) { #if defined(MAX32650) // USN is 13 bytes on this device (void) max_len; MXC_SYS_GetUSN(id, 13); return 13; #else uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN]; //USN Buffer MXC_SYS_GetUSN(hw_id, NULL); // 2nd parameter is optional checksum buffer size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); memcpy(id, hw_id, act_len); return act_len; #endif } int board_uart_read(uint8_t *buf, int len) { int uart_val; int act_len = 0; while (act_len < len) { if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { break; } else { *buf++ = (uint8_t) uart_val; act_len++; } } return act_len; } int board_uart_write(void const *buf, int len) { int act_len = 0; const uint8_t *ch_ptr = (const uint8_t *) buf; while (act_len < len) { MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); act_len++; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/maxim/family.cmake ================================================ include_guard() # stub: overridden by board.cmake if needed function(sign_image TARGET_IN) endfunction() set(MSDK_LIB ${TOP}/hw/mcu/analog/msdk/Libraries) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) string(TOUPPER ${MAX_DEVICE} MAX_DEVICE_UPPER) cmake_print_variables(MAX_DEVICE MAX_DEVICE_UPPER) set(JLINK_DEVICE ${MAX_DEVICE}) set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/${MAX_DEVICE}.cfg") set(FAMILY_MCUS ${MAX_DEVICE_UPPER} CACHE INTERNAL "") if (${MAX_DEVICE} STREQUAL "max32650") set(PERIPH_ID 10) set(PERIPH_SUFFIX "me") elseif (${MAX_DEVICE} STREQUAL "max32665" OR ${MAX_DEVICE} STREQUAL "max32666") set(PERIPH_ID 14) set(PERIPH_SUFFIX "me") elseif (${MAX_DEVICE} STREQUAL "max32690") set(PERIPH_ID 18) set(PERIPH_SUFFIX "me") elseif (${MAX_DEVICE} STREQUAL "max78002") set(PERIPH_ID 87) set(PERIPH_SUFFIX "ai") else() message(FATAL_ERROR "Unsupported MAX device: ${MAX_DEVICE}") endif() #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/GCC/startup_${MAX_DEVICE}.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MAX_DEVICE}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) # Common add_library(${BOARD_TARGET} STATIC ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/heap.c ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/system_${MAX_DEVICE}.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_assert.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_delay.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_lock.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/nvic_table.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/pins_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/SYS/sys_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_common.c ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_reva.c ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_common.c ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_reva.c ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_reva.c ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_common.c ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_${PERIPH_SUFFIX}${PERIPH_ID}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${MSDK_LIB}/CMSIS/5.9.0/Core/Include ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Include ${MSDK_LIB}/PeriphDrivers/Include/${MAX_DEVICE_UPPER} ${MSDK_LIB}/PeriphDrivers/Source/SYS ${MSDK_LIB}/PeriphDrivers/Source/GPIO ${MSDK_LIB}/PeriphDrivers/Source/ICC ${MSDK_LIB}/PeriphDrivers/Source/FLC ${MSDK_LIB}/PeriphDrivers/Source/UART ) # device specific if (${MAX_DEVICE} STREQUAL "max32650" OR ${MAX_DEVICE} STREQUAL "max32665" OR ${MAX_DEVICE} STREQUAL "max32666") target_sources(${BOARD_TARGET} PRIVATE ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_common.c ${MSDK_LIB}/PeriphDrivers/Source/TPU/tpu_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/TPU/tpu_reva.c ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_reva.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${MSDK_LIB}/PeriphDrivers/Source/TPU ) elseif (${MAX_DEVICE} STREQUAL "max32690") target_sources(${BOARD_TARGET} PRIVATE ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_reva.c ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_common.c ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_revb.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${MSDK_LIB}/PeriphDrivers/Source/CTB ) elseif (${MAX_DEVICE} STREQUAL "max78002") target_sources(${BOARD_TARGET} PRIVATE ${MSDK_LIB}/PeriphDrivers/Source/AES/aes_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/AES/aes_revb.c ${MSDK_LIB}/PeriphDrivers/Source/TRNG/trng_${PERIPH_SUFFIX}${PERIPH_ID}.c ${MSDK_LIB}/PeriphDrivers/Source/TRNG/trng_revb.c ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_revb.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${MSDK_LIB}/PeriphDrivers/Source/AES ${MSDK_LIB}/PeriphDrivers/Source/TRNG ) else() message(FATAL_ERROR "Unsupported MAX device: ${MAX_DEVICE}") endif() target_compile_definitions(${BOARD_TARGET} PUBLIC TARGET=${MAX_DEVICE_UPPER} TARGET_REV=0x4131 MXC_ASSERT_ENABLE ${MAX_DEVICE_UPPER} IAR_PRAGMAS=0 MAX_PERIPH_ID=${PERIPH_ID} BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED ) target_compile_options(${BOARD_TARGET} PRIVATE -Wno-error=strict-prototypes ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${MAX_DEVICE_UPPER}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/mentor/musb/dcd_musb.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") # warnings caused by MSDK headers target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes) if (${MAX_DEVICE} STREQUAL "max78002") target_compile_options(${TARGET} PRIVATE -Wno-error=redundant-decls) endif () set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) sign_image(${TARGET}) # for secured device such as max32651 family_flash_openocd_adi(${TARGET}) endfunction() ================================================ FILE: hw/bsp/maxim/family.mk ================================================ MSDK_LIB = hw/mcu/analog/msdk/Libraries # Add any board specific make rules include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 PORT ?= 0 JLINK_DEVICE = ${MAX_DEVICE} MAX_DEVICE_UPPER = $(call to_upper,${MAX_DEVICE}) ifeq ($(MAX_DEVICE),max32650) PERIPH_ID = 10 PERIPH_SUFFIX = me endif ifneq ($(filter $(MAX_DEVICE),max32665 max32666),) PERIPH_ID = 14 PERIPH_SUFFIX = me endif ifeq ($(MAX_DEVICE),max32690) PERIPH_ID = 18 PERIPH_SUFFIX = me endif ifeq ($(MAX_DEVICE),max78002) PERIPH_ID = 87 PERIPH_SUFFIX = ai endif ifndef PERIPH_ID $(error Unsupported MAX device: ${MAX_DEVICE}) endif # Configure the flash rule. By default, use JLink. SIGNED_BUILD ?= 0 DEFAULT_FLASH = flash-jlink # -------------- # Compiler Flags # -------------- CFLAGS += \ -DTARGET=${MAX_DEVICE_UPPER}\ -DTARGET_REV=0x4131 \ -DMXC_ASSERT_ENABLE \ -D${MAX_DEVICE_UPPER} \ -DIAR_PRAGMAS=0 \ -DMAX_PERIPH_ID=${PERIPH_ID} \ -DCFG_TUSB_MCU=OPT_MCU_${MAX_DEVICE_UPPER} \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # mcu driver cause following warnings CFLAGS += \ -Wno-error=old-style-declaration \ -Wno-error=redundant-decls \ -Wno-error=strict-prototypes \ -Wno-error=unused-parameter \ -Wno-error=cast-align \ -Wno-error=cast-qual \ -Wno-error=sign-compare \ -Wno-error=enum-conversion \ LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs LD_FILE_GCC ?= $(FAMILY_PATH)/linker/${MAX_DEVICE}.ld # If the applications needs to be signed (for the MAX32651), sign it first and # then need to use MSDK's OpenOCD to flash it # Also need to include the __SLA_FWK__ define to enable the signed header into # memory ifeq ($(SIGNED_BUILD), 1) # Extra definitions to build for the secure part CFLAGS += -D__SLA_FWK__ DEFAULT_FLASH := sign-build flash-msdk endif # ----------------- # Sources & Include # ----------------- # common SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/heap.c \ ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/system_${MAX_DEVICE}.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_assert.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_delay.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/mxc_lock.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/nvic_table.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/pins_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/SYS/sys_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_common.c \ ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/FLC/flc_reva.c \ ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_common.c \ ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/GPIO/gpio_reva.c \ ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_reva.c \ ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_common.c \ ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_${PERIPH_SUFFIX}${PERIPH_ID}.c \ SRC_S_GCC += ${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Source/GCC/startup_${MAX_DEVICE}.S INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/${MSDK_LIB}/CMSIS/5.9.0/Core/Include \ $(TOP)/${MSDK_LIB}/CMSIS/Device/Maxim/${MAX_DEVICE_UPPER}/Include \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Include/${MAX_DEVICE_UPPER} \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/SYS \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/GPIO \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/ICC \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/FLC \ $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/UART \ # device specific ifneq ($(filter $(MAX_DEVICE),max32650 max32665 max32666),) SRC_C += \ ${MSDK_LIB}/PeriphDrivers/Source/ICC/icc_common.c \ ${MSDK_LIB}/PeriphDrivers/Source/TPU/tpu_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/TPU/tpu_reva.c \ ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_reva.c \ INC += $(TOP)/${MSDK_LIB}/PeriphDrivers/Source/TPU endif ifeq (${MAX_DEVICE},max32690) SRC_C += \ ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_reva.c \ ${MSDK_LIB}/PeriphDrivers/Source/CTB/ctb_common.c \ ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_revb.c \ INC += ${TOP}/${MSDK_LIB}/PeriphDrivers/Source/CTB endif ifeq (${MAX_DEVICE},max78002) SRC_C += \ ${MSDK_LIB}/PeriphDrivers/Source/AES/aes_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/AES/aes_revb.c \ ${MSDK_LIB}/PeriphDrivers/Source/TRNG/trng_${PERIPH_SUFFIX}${PERIPH_ID}.c \ ${MSDK_LIB}/PeriphDrivers/Source/TRNG/trng_revb.c \ ${MSDK_LIB}/PeriphDrivers/Source/UART/uart_revb.c \ INC += \ ${TOP}/${MSDK_LIB}/PeriphDrivers/Source/AES \ ${TOP}/${MSDK_LIB}/PeriphDrivers/Source/TRNG endif # The MAX32651EVKIT is pin for pin identical to the MAX32650EVKIT, however the # MAX32651 has a secure bootloader which requires the image to be signed before # loading into flash. All MAX32651EVKIT's have the same key for evaluation # purposes, so create a special flash rule to sign the binary and flash using # the MSDK. MCU_PATH = $(TOP)/hw/mcu/analog/msdk/ # Assume no extension for sign utility SIGN_EXE = sign_app ifeq ($(OS), Windows_NT) # Must use .exe extension on Windows, since the binaries # for Linux may live in the same place. SIGN_EXE := sign_app.exe else UNAME = $(shell uname -s) ifneq ($(findstring MSYS_NT,$(UNAME)),) # Must also use .exe extension for MSYS2 SIGN_EXE := sign_app.exe endif endif # Rule to sign the build. This will in-place modify the existing .elf file # an populate the .sig section with the signature value sign-build: $(BUILD)/$(PROJECT).elf $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin $(MCU_PATH)/Tools/SBT/bin/$(SIGN_EXE) -c MAX32651 \ key_file="$(MCU_PATH)/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key" \ ca=$(BUILD)/$(PROJECT).bin sca=$(BUILD)/$(PROJECT).sbin $(OBJCOPY) $(BUILD)/$(PROJECT).elf --update-section .sig=$(BUILD)/$(PROJECT).sig # Optional flash option when running within an installed MSDK to use OpenOCD # Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. # If the MSDK is installed, flash-msdk can be run to utilize the the modified # openocd with the algorithms MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) flash-msdk: $(BUILD)/$(PROJECT).elf $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ -f interface/cmsis-dap.cfg -f target/max32650.cfg \ -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" # Configure the flash rule flash: $(DEFAULT_FLASH) ================================================ FILE: hw/bsp/maxim/linker/max32650.ld ================================================ MEMORY { ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64kB ROM */ FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00300000 /* 3MB flash */ SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */ } SECTIONS { .text : { _text = .; KEEP(*(.isr_vector)) *(.text*) /* program code */ *(.rodata*) /* read-only data: "const" */ KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) /* C++ Exception handling */ KEEP(*(.eh_frame*)) _etext = .; } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH /* it's used for C++ exception handling */ /* we need to keep this to avoid overlapping */ .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH .data : { _data = ALIGN(., 4); *(vtable) *(.data*) /*read-write initialized data: initialized global variable*/ *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ *(.flashprog*) /* Flash program */ /* These array sections are used by __libc_init_array to call static C++ constructors */ . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); _edata = ALIGN(., 4); } > SRAM AT>FLASH __load_data = LOADADDR(.data); .bss : { . = ALIGN(4); _bss = .; *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > SRAM .heap (COPY): { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/maxim/linker/max32651.ld ================================================ MEMORY { HEADER (rx): ORIGIN = 0x10000000, LENGTH = 0x200 FLASH (rx) : ORIGIN = 0x10000200, LENGTH = 0x002FFE00 /* 3MB flash */ SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */ } /* Added Oct 9, 2018 to go to correct reset vector. */ ENTRY(Reset_Handler) PROVIDE( _start_SWAP = (((Reset_Handler) >> 24) | (((Reset_Handler) & 0x00FF0000) >> 8) | (((Reset_Handler) & 0x0000FF00) << 8) | ((Reset_Handler) << 24))); PROVIDE_HIDDEN( _SLA_Size = _endimage - __end_header ); PROVIDE( _SLA_Size_SWAP = (((_SLA_Size) >> 24) | (((_SLA_Size) & 0x00FF0000) >> 8) | (((_SLA_Size) & 0x0000FF00) << 8) | ((_SLA_Size) << 24))); /* Sections Definitions */ SECTIONS { .sb_sla_header : ALIGN(4) { FILL(0xFF) KEEP(*(.sb_sla_header)) /* Header for ROM code */ __end_header = . ; . = ALIGN(512); } > HEADER .text : { _text = .; KEEP(*(.isr_vector)) *(.text*) /* program code */ *(.rodata*) /* read-only data: "const" */ KEEP(*(.init)) KEEP(*(.fini)) /* C++ Exception handling */ KEEP(*(.eh_frame*)) _etext = .; } > FLASH /* it's used for C++ exception handling */ /* we need to keep this to avoid overlapping */ .ARM.exidx : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } > FLASH .data : { _data = ALIGN(., 4); *(.data*) /*read-write initialized data: initialized global variable*/ *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ *(.flashprog*) /* Flash program */ /* These array sections are used by __libc_init_array to call static C++ constructors */ . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); _edata = ALIGN(., 4); } > SRAM AT>FLASH __load_data = LOADADDR(.data); _enddata = LOADADDR(.data)+SIZEOF(.data); .sb_sla_trailer : AT(_enddata) { KEEP(*(.sb_sla_trailer)) /* Align image with 16 byte boundary to conform to flash encryption block size. */ FILL(0xDEADC0DE); /* NOTE: The FILL and ALIGN will not work unless something is written to the section. So, we use LONG. */ LONG(0xDEADC0DE); . = ALIGN(16); } > FLASH _endimage = LOADADDR(.sb_sla_trailer)+SIZEOF(.sb_sla_trailer); .sig : { KEEP(*(.sig)) LONG(0xDEADBEEF); } > FLASH .bss : { . = ALIGN(4); _bss = .; *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > SRAM .heap (COPY): { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/maxim/linker/max32665.ld ================================================ /* SPID and SPIX Sections here are maximum possible sizes */ /* If used, they should be adjusted for the external Flash/RAM size */ MEMORY { SPIX (rx) : ORIGIN = 0x08000000, LENGTH = 0x08000000 FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00100000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0008C000 SPID (rw) : ORIGIN = 0x80000000, LENGTH = 512M } /* Sections Definitions */ SECTIONS { .text : { _text = .; KEEP(*(.isr_vector)) *(.text*) /* program code */ *(.rodata*) /* read-only data: "const" */ KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) /* C++ Exception handling */ KEEP(*(.eh_frame*)) _etext = .; } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH /* This section will keep the SPIX data until loaded into the external device */ /* Upon initialization of SPIX (user code needs to do this) */ .xip_section : { KEEP(*(.xip_section*)) } > SPIX AT>FLASH __load_start_xip = LOADADDR(.xip_section); __load_length_xip = SIZEOF(.xip_section); /* it's used for C++ exception handling */ /* we need to keep this to avoid overlapping */ .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH .data : { _data = ALIGN(., 4); *(vtable) *(.data*) /*read-write initialized data: initialized global variable*/ *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */ *(.flashprog*) /* Flash program */ /* These array sections are used by __libc_init_array to call static C++ constructors */ . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); _edata = ALIGN(., 4); } > SRAM AT>FLASH __load_data = LOADADDR(.data); .bss : { . = ALIGN(4); _bss = .; *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM /* Setup the stack for Core 1, it will only be used if the user code * includes a definition of Stack_Size_Core1, which defines the space * reserved above the main core's stack for core 1's stack */ __StackTop_Core1 = ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit_Core1 = DEFINED(Stack_Size_Core1) ? __StackTop_Core1 - Stack_Size_Core1 : __StackTop_Core1; /* Set stack top to end of RAM, and stack limit move down by Stack_Size. * If core 1 is used, set the stack to the bottom of Core 1's stack region */ __StackTop = DEFINED(Stack_Size_Core1) ? __StackLimit_Core1 : ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit = __StackTop - Stack_Size; .heap (COPY): { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM PROVIDE(__stack = __StackTop); /* Check if data + heap + stack(s) exceeds RAM limit */ ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/maxim/linker/max32690.ld ================================================ MEMORY { ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 /* 128kB ROM */ FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00340000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* * Note that CS0/CS1 address mappings may be reversed using MXC_HPC->mbr0 and ->mbr1 * The following mappings are selected for simplicity */ HPB_CS0 (rwx) : ORIGIN = 0x60000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 0 */ HPB_CS1 (rwx) : ORIGIN = 0x70000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 1 */ } SECTIONS { .rom : { KEEP(*(.rom_vector)) *(.rom_handlers*) } > ROM .text : { _text = .; KEEP(*(.isr_vector)) EXCLUDE_FILE (*riscv.o) *(.text*) /* program code, exclude RISCV code */ *(.rodata*) /* read-only data: "const" */ KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) /* C++ Exception handling */ KEEP(*(.eh_frame*)) _etext = .; } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH /* These sections allow code to be compiled/linked for HPB addresses, but reside in * flash until copied by code to the external HPB flash device */ .hpb_cs0_section : { __hpb_cs0_start = ABSOLUTE(.); KEEP(*(.hpb_cs0_section*)) } > HPB_CS0 AT>FLASH __load_start_hpb_cs0 = LOADADDR(.hpb_cs0_section); __load_length_hpb_cs0 = SIZEOF(.hpb_cs0_section); .hpb_cs1_section : { __hpb_cs1_start = ABSOLUTE(.); KEEP(*(.hpb_cs1_section*)) } > HPB_CS1 AT>FLASH __load_start_hpb_cs1 = LOADADDR(.hpb_cs1_section); __load_length_hpb_cs1 = SIZEOF(.hpb_cs1_section); /* Binary import */ .bin_storage : { FILL(0xFF) _bin_start_ = .; KEEP(*(.bin_storage_img)) _bin_end_ = .; . = ALIGN(4); } > FLASH /* it's used for C++ exception handling */ /* we need to keep this to avoid overlapping */ .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH .data : { _data = ALIGN(., 4); *(vtable) *(.data*) /*read-write initialized data: initialized global variable*/ /* These array sections are used by __libc_init_array to call static C++ constructors */ . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); /* Run the flash programming functions from SRAM */ *(.flashprog) _edata = ALIGN(., 4); } > SRAM AT>FLASH __load_data = LOADADDR(.data); .bss : { . = ALIGN(4); _bss = .; *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > SRAM .heap (COPY): { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/maxim/linker/max78002.ld ================================================ MEMORY { ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64 kB ROM */ FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00280000 /* 2.5 MB Flash */ SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00060000 /* 384 kB SRAM */ /*CSI2 (rwx) : ORIGIN = 0x2001F000, LENGTH = 0x00001000 4096 B CSI2 Buffer */ } SECTIONS { .rom : { KEEP(*(.rom_vector)) *(.rom_handlers*) } > ROM .text : { _text = .; KEEP(*(.isr_vector)) EXCLUDE_FILE (*riscv.o) *(.text*) /* Program code (exclude RISCV code) */ *(.rodata*) /* read-only data: "const" */ KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) /* C++ Exception handling */ KEEP(*(.eh_frame*)) _etext = .; } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH /* Binary import */ .bin_storage : { FILL(0xFF) _bin_start_ = .; KEEP(*(.bin_storage_img)) _bin_end_ = .; . = ALIGN(4); } > FLASH .rom_code : { . = ALIGN(16); _sran_code = .; *(.rom_code_section) _esran_code = .; } > ROM .flash_code : { . = ALIGN(16); _sran_code = .; *(.flash_code_section) _esran_code = .; } > FLASH .sram_code : { . = ALIGN(16); _sran_code = .; *(.sram_code_section) _esran_code = .; } > SRAM /* it's used for C++ exception handling */ /* we need to keep this to avoid overlapping */ .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH .data : { _data = ALIGN(., 4); _csi = . + 0x20000; *(vtable) *(.data*) /*read-write initialized data: initialized global variable*/ /* These array sections are used by __libc_init_array to call static C++ constructors */ . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); _edata = ALIGN(., 4); } > SRAM AT>FLASH __load_data = LOADADDR(.data); .bss : { . = ALIGN(4); _bss = .; *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM .shared : { . = ALIGN(4); _shared = .; *(.mailbox*) . = ALIGN(4); *(.shared*) /*read-write zero initialized data: uninitialized global variable*/ _eshared = ALIGN(., 4); } > SRAM __shared_data = LOADADDR(.shared); /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > SRAM .heap (COPY): { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); *(.heap*) __HeapLimit = ABSOLUTE(__StackLimit); } > SRAM PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") /* Section used by RISCV loader projects. See RISCV_LOAD documentation in the build system. */ .riscv_flash : { /* Align address to mod 256 with a small offset. This is required to match the flash page size.*/ . = ALIGN(256); /* ALIGN operatator is used here. Note that (. & 0x1FFFFF00) was used in the past, but a strange bug was seen on Windows where the & did not behave as expected.*/ . += 0x100; _riscv_boot = .; KEEP(*riscv.o (.text*)) } > FLASH } ================================================ FILE: hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } /*!< Set up system dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO12M */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivTRACE, 1U); /* !< Set TRACECLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set WWDT0CLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO24M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO24M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 24 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 6 MHz} - {id: System_clock.outFreq, value: 24 MHz} - {id: TRACE_clock.outFreq, value: 24 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} - {id: WWDT0_clock.outFreq, value: 1 MHz} settings: - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SYSCON.AHBCLKDIV.scale, value: '2'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO24M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO24M configuration ******************************************************************************/ void BOARD_BootClockFRO24M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } /*!< Set up system dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 2U); /* !< Set AHBCLKDIV divider to value 2 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI0); /* !< Switch LPSPI0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI1); /* !< Switch LPSPI1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPI2C0); /* !< Switch LPI2C0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART0); /* !< Switch LPUART0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART1); /* !< Switch LPUART1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART2); /* !< Switch LPUART2 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPTMR0); /* !< Switch LPTMR0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_I3C0FCLK); /* !< Switch I3C0FCLK to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP0); /* !< Switch CMP0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP1); /* !< Switch CMP1 to FRO_HF_DIV */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivTRACE, 1U); /* !< Set TRACECLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set WWDT0CLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO24M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO48M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO48M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 12 MHz} - {id: System_clock.outFreq, value: 48 MHz} - {id: TRACE_clock.outFreq, value: 48 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} - {id: WWDT0_clock.outFreq, value: 1 MHz} settings: - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO48M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO48M configuration ******************************************************************************/ void BOARD_BootClockFRO48M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } /*!< Set up system dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI0); /* !< Switch LPSPI0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI1); /* !< Switch LPSPI1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPI2C0); /* !< Switch LPI2C0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART0); /* !< Switch LPUART0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART1); /* !< Switch LPUART1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART2); /* !< Switch LPUART2 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPTMR0); /* !< Switch LPTMR0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_I3C0FCLK); /* !< Switch I3C0FCLK to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP0); /* !< Switch CMP0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP1); /* !< Switch CMP1 to FRO_HF_DIV */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivTRACE, 1U); /* !< Set TRACECLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set WWDT0CLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO48M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO64M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO64M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 64 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 64 MHz} - {id: FRO_HF_clock.outFreq, value: 64 MHz} - {id: MAIN_clock.outFreq, value: 64 MHz} - {id: Slow_clock.outFreq, value: 16 MHz} - {id: System_clock.outFreq, value: 64 MHz} - {id: TRACE_clock.outFreq, value: 64 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} - {id: WWDT0_clock.outFreq, value: 1 MHz} settings: - {id: VDD_CORE, value: voltage_1v1} - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FROHFDIV.scale, value: '1', locked: true} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} sources: - {id: SCG.FIRC.outFreq, value: 64 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO64M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO64M configuration ******************************************************************************/ void BOARD_BootClockFRO64M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } /*!< Set up system dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ CLOCK_SetupFROHFClocking(64000000U); /*!< Enable FRO HF(64MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI0); /* !< Switch LPSPI0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI1); /* !< Switch LPSPI1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPI2C0); /* !< Switch LPI2C0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART0); /* !< Switch LPUART0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART1); /* !< Switch LPUART1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART2); /* !< Switch LPUART2 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPTMR0); /* !< Switch LPTMR0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_I3C0FCLK); /* !< Switch I3C0FCLK to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP0); /* !< Switch CMP0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP1); /* !< Switch CMP1 to FRO_HF_DIV */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivTRACE, 1U); /* !< Set TRACECLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set WWDT0CLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO64M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO96M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO96M called_from_default_init: true outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 96 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 96 MHz} - {id: FRO_HF_clock.outFreq, value: 96 MHz} - {id: MAIN_clock.outFreq, value: 96 MHz} - {id: Slow_clock.outFreq, value: 24 MHz} - {id: System_clock.outFreq, value: 96 MHz} - {id: TRACE_clock.outFreq, value: 96 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} - {id: WWDT0_clock.outFreq, value: 1 MHz} settings: - {id: VDD_CORE, value: voltage_1v1} - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} sources: - {id: SCG.FIRC.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO96M configuration ******************************************************************************/ void BOARD_BootClockFRO96M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } /*!< Set up system dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI0); /* !< Switch LPSPI0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPSPI1); /* !< Switch LPSPI1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPI2C0); /* !< Switch LPI2C0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART0); /* !< Switch LPUART0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART1); /* !< Switch LPUART1 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPUART2); /* !< Switch LPUART2 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_LPTMR0); /* !< Switch LPTMR0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_I3C0FCLK); /* !< Switch I3C0FCLK to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP0); /* !< Switch CMP0 to FRO_HF_DIV */ CLOCK_AttachClk(kFRO_HF_DIV_to_CMP1); /* !< Switch CMP1 to FRO_HF_DIV */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivTRACE, 1U); /* !< Set TRACECLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set WWDT0CLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO96M_CORE_CLOCK; } ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h ================================================ /* * Copyright 2025 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO12M_ADC0_CLOCK 0UL /* Clock consumers of ADC0_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO12M_CLK16K_0_CLOCK 0UL /* Clock consumers of CLK16K_0_clock output : CMP0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO12M_CLK16K_1_CLOCK 0UL /* Clock consumers of CLK16K_1_clock output : CMP1, LPTMR0, WAKETIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CLK_1M_CLOCK 1000000UL /* Clock consumers of CLK_1M_clock output : CMC */ #define BOARD_BOOTCLOCKFRO12M_CLK_48M_CLOCK 0UL /* Clock consumers of CLK_48M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CLK_IN_CLOCK 0UL /* Clock consumers of CLK_IN_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CMP0FDIV_CLOCK 0UL /* Clock consumers of CMP0FDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO12M_CMP0RRDIV_CLOCK 0UL /* Clock consumers of CMP0RRDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO12M_CMP1FDIV_CLOCK 0UL /* Clock consumers of CMP1FDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO12M_CMP1RRDIV_CLOCK 0UL /* Clock consumers of CMP1RRDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO12M_CPU_CLOCK 12000000UL /* Clock consumers of CPU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO12M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO12M_FREQME_REFERENCE_CLOCK 0UL /* Clock consumers of FREQME_reference_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO12M_FREQME_TARGET_CLOCK 0UL /* Clock consumers of FREQME_target_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO12M_FRO_12M_CLOCK 12000000UL /* Clock consumers of FRO_12M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_FRO_HF_DIV_CLOCK 0UL /* Clock consumers of FRO_HF_DIV_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_FRO_HF_CLOCK 0UL /* Clock consumers of FRO_HF_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_I3C_FCLK_CLOCK 0UL /* Clock consumers of I3C_FCLK_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO12M_I3C_SLOW_TC_CLOCK 0UL /* Clock consumers of I3C_SLOW_TC_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO12M_I3C_SLOW_CLOCK 0UL /* Clock consumers of I3C_SLOW_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO12M_LPI2C0_CLOCK 0UL /* Clock consumers of LPI2C0_clock output : LPI2C0 */ #define BOARD_BOOTCLOCKFRO12M_LPSPI0_CLOCK 0UL /* Clock consumers of LPSPI0_clock output : LPSPI0 */ #define BOARD_BOOTCLOCKFRO12M_LPSPI1_CLOCK 0UL /* Clock consumers of LPSPI1_clock output : LPSPI1 */ #define BOARD_BOOTCLOCKFRO12M_LPTMR0_CLOCK 0UL /* Clock consumers of LPTMR0_clock output : LPTMR0 */ #define BOARD_BOOTCLOCKFRO12M_LPUART0_CLOCK 0UL /* Clock consumers of LPUART0_clock output : LPUART0 */ #define BOARD_BOOTCLOCKFRO12M_LPUART1_CLOCK 0UL /* Clock consumers of LPUART1_clock output : LPUART1 */ #define BOARD_BOOTCLOCKFRO12M_LPUART2_CLOCK 0UL /* Clock consumers of LPUART2_clock output : LPUART2 */ #define BOARD_BOOTCLOCKFRO12M_MAIN_CLOCK 12000000UL /* Clock consumers of MAIN_clock output : FLEXPWM0 */ #define BOARD_BOOTCLOCKFRO12M_OSTIMER_CLOCK 0UL /* Clock consumers of OSTIMER_clock output : OSTIMER0 */ #define BOARD_BOOTCLOCKFRO12M_FIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.FIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.SIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_SLOW_CLOCK 3000000UL /* Clock consumers of Slow_clock output : AOI0, CMC, CMP0, LPTMR0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL /* Clock consumers of System_clock output : ADC0, CMP1, CTIMER0, CTIMER1, CTIMER2, DMA0, FLEXPWM0, FREQME0, GPIO0, GPIO1, GPIO2, GPIO3, I3C0, INPUTMUX0, LPI2C0, LPSPI0, LPSPI1, LPUART0, LPUART1, LPUART2, OSTIMER0, PORT0, PORT1, PORT2, PORT3, QDC0, SWD, SysTick, USB0, UTICK0, WWDT0 */ #define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 12000000UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO12M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0 */ #define BOARD_BOOTCLOCKFRO12M_UTICK_CLOCK 1000000UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO12M_WUU_CLOCK 0UL /* Clock consumers of WUU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO12M_WWDT0_CLOCK 1000000UL /* Clock consumers of WWDT0_clock output : WWDT0 */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO24M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO24M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO24M_CORE_CLOCK 24000000U /*!< Core clock frequency: 24000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO24M_ADC0_CLOCK 0UL /* Clock consumers of ADC0_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO24M_CLK16K_0_CLOCK 0UL /* Clock consumers of CLK16K_0_clock output : CMP0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO24M_CLK16K_1_CLOCK 0UL /* Clock consumers of CLK16K_1_clock output : CMP1, LPTMR0, WAKETIMER0 */ #define BOARD_BOOTCLOCKFRO24M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_CLK_1M_CLOCK 1000000UL /* Clock consumers of CLK_1M_clock output : CMC */ #define BOARD_BOOTCLOCKFRO24M_CLK_48M_CLOCK 48000000UL /* Clock consumers of CLK_48M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_CLK_IN_CLOCK 0UL /* Clock consumers of CLK_IN_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_CMP0FDIV_CLOCK 0UL /* Clock consumers of CMP0FDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO24M_CMP0RRDIV_CLOCK 0UL /* Clock consumers of CMP0RRDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO24M_CMP1FDIV_CLOCK 0UL /* Clock consumers of CMP1FDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO24M_CMP1RRDIV_CLOCK 0UL /* Clock consumers of CMP1RRDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO24M_CPU_CLOCK 24000000UL /* Clock consumers of CPU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO24M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO24M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO24M_FREQME_REFERENCE_CLOCK 0UL /* Clock consumers of FREQME_reference_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO24M_FREQME_TARGET_CLOCK 0UL /* Clock consumers of FREQME_target_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO24M_FRO_12M_CLOCK 12000000UL /* Clock consumers of FRO_12M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_FRO_HF_DIV_CLOCK 48000000UL /* Clock consumers of FRO_HF_DIV_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_FRO_HF_CLOCK 48000000UL /* Clock consumers of FRO_HF_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_I3C_FCLK_CLOCK 0UL /* Clock consumers of I3C_FCLK_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO24M_I3C_SLOW_TC_CLOCK 0UL /* Clock consumers of I3C_SLOW_TC_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO24M_I3C_SLOW_CLOCK 0UL /* Clock consumers of I3C_SLOW_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO24M_LPI2C0_CLOCK 0UL /* Clock consumers of LPI2C0_clock output : LPI2C0 */ #define BOARD_BOOTCLOCKFRO24M_LPSPI0_CLOCK 0UL /* Clock consumers of LPSPI0_clock output : LPSPI0 */ #define BOARD_BOOTCLOCKFRO24M_LPSPI1_CLOCK 0UL /* Clock consumers of LPSPI1_clock output : LPSPI1 */ #define BOARD_BOOTCLOCKFRO24M_LPTMR0_CLOCK 0UL /* Clock consumers of LPTMR0_clock output : LPTMR0 */ #define BOARD_BOOTCLOCKFRO24M_LPUART0_CLOCK 0UL /* Clock consumers of LPUART0_clock output : LPUART0 */ #define BOARD_BOOTCLOCKFRO24M_LPUART1_CLOCK 0UL /* Clock consumers of LPUART1_clock output : LPUART1 */ #define BOARD_BOOTCLOCKFRO24M_LPUART2_CLOCK 0UL /* Clock consumers of LPUART2_clock output : LPUART2 */ #define BOARD_BOOTCLOCKFRO24M_MAIN_CLOCK 48000000UL /* Clock consumers of MAIN_clock output : FLEXPWM0 */ #define BOARD_BOOTCLOCKFRO24M_OSTIMER_CLOCK 0UL /* Clock consumers of OSTIMER_clock output : OSTIMER0 */ #define BOARD_BOOTCLOCKFRO24M_FIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.FIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_SIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.SIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_SLOW_CLOCK 6000000UL /* Clock consumers of Slow_clock output : AOI0, CMC, CMP0, LPTMR0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO24M_SYSTEM_CLOCK 24000000UL /* Clock consumers of System_clock output : ADC0, CMP1, CTIMER0, CTIMER1, CTIMER2, DMA0, FLEXPWM0, FREQME0, GPIO0, GPIO1, GPIO2, GPIO3, I3C0, INPUTMUX0, LPI2C0, LPSPI0, LPSPI1, LPUART0, LPUART1, LPUART2, OSTIMER0, PORT0, PORT1, PORT2, PORT3, QDC0, SWD, SysTick, USB0, UTICK0, WWDT0 */ #define BOARD_BOOTCLOCKFRO24M_TRACE_CLOCK 24000000UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO24M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0 */ #define BOARD_BOOTCLOCKFRO24M_UTICK_CLOCK 1000000UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO24M_WUU_CLOCK 0UL /* Clock consumers of WUU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO24M_WWDT0_CLOCK 1000000UL /* Clock consumers of WWDT0_clock output : WWDT0 */ /******************************************************************************* * API for BOARD_BootClockFRO24M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO24M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO48M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO48M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO48M_ADC0_CLOCK 0UL /* Clock consumers of ADC0_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO48M_CLK16K_0_CLOCK 0UL /* Clock consumers of CLK16K_0_clock output : CMP0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO48M_CLK16K_1_CLOCK 0UL /* Clock consumers of CLK16K_1_clock output : CMP1, LPTMR0, WAKETIMER0 */ #define BOARD_BOOTCLOCKFRO48M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_CLK_1M_CLOCK 1000000UL /* Clock consumers of CLK_1M_clock output : CMC */ #define BOARD_BOOTCLOCKFRO48M_CLK_48M_CLOCK 48000000UL /* Clock consumers of CLK_48M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_CLK_IN_CLOCK 0UL /* Clock consumers of CLK_IN_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_CMP0FDIV_CLOCK 0UL /* Clock consumers of CMP0FDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO48M_CMP0RRDIV_CLOCK 0UL /* Clock consumers of CMP0RRDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO48M_CMP1FDIV_CLOCK 0UL /* Clock consumers of CMP1FDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO48M_CMP1RRDIV_CLOCK 0UL /* Clock consumers of CMP1RRDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO48M_CPU_CLOCK 48000000UL /* Clock consumers of CPU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO48M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO48M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO48M_FREQME_REFERENCE_CLOCK 0UL /* Clock consumers of FREQME_reference_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO48M_FREQME_TARGET_CLOCK 0UL /* Clock consumers of FREQME_target_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO48M_FRO_12M_CLOCK 12000000UL /* Clock consumers of FRO_12M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_FRO_HF_DIV_CLOCK 48000000UL /* Clock consumers of FRO_HF_DIV_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_FRO_HF_CLOCK 48000000UL /* Clock consumers of FRO_HF_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_I3C_FCLK_CLOCK 0UL /* Clock consumers of I3C_FCLK_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO48M_I3C_SLOW_TC_CLOCK 0UL /* Clock consumers of I3C_SLOW_TC_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO48M_I3C_SLOW_CLOCK 0UL /* Clock consumers of I3C_SLOW_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO48M_LPI2C0_CLOCK 0UL /* Clock consumers of LPI2C0_clock output : LPI2C0 */ #define BOARD_BOOTCLOCKFRO48M_LPSPI0_CLOCK 0UL /* Clock consumers of LPSPI0_clock output : LPSPI0 */ #define BOARD_BOOTCLOCKFRO48M_LPSPI1_CLOCK 0UL /* Clock consumers of LPSPI1_clock output : LPSPI1 */ #define BOARD_BOOTCLOCKFRO48M_LPTMR0_CLOCK 0UL /* Clock consumers of LPTMR0_clock output : LPTMR0 */ #define BOARD_BOOTCLOCKFRO48M_LPUART0_CLOCK 0UL /* Clock consumers of LPUART0_clock output : LPUART0 */ #define BOARD_BOOTCLOCKFRO48M_LPUART1_CLOCK 0UL /* Clock consumers of LPUART1_clock output : LPUART1 */ #define BOARD_BOOTCLOCKFRO48M_LPUART2_CLOCK 0UL /* Clock consumers of LPUART2_clock output : LPUART2 */ #define BOARD_BOOTCLOCKFRO48M_MAIN_CLOCK 48000000UL /* Clock consumers of MAIN_clock output : FLEXPWM0 */ #define BOARD_BOOTCLOCKFRO48M_OSTIMER_CLOCK 0UL /* Clock consumers of OSTIMER_clock output : OSTIMER0 */ #define BOARD_BOOTCLOCKFRO48M_FIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.FIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_SIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.SIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_SLOW_CLOCK 12000000UL /* Clock consumers of Slow_clock output : AOI0, CMC, CMP0, LPTMR0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO48M_SYSTEM_CLOCK 48000000UL /* Clock consumers of System_clock output : ADC0, CMP1, CTIMER0, CTIMER1, CTIMER2, DMA0, FLEXPWM0, FREQME0, GPIO0, GPIO1, GPIO2, GPIO3, I3C0, INPUTMUX0, LPI2C0, LPSPI0, LPSPI1, LPUART0, LPUART1, LPUART2, OSTIMER0, PORT0, PORT1, PORT2, PORT3, QDC0, SWD, SysTick, USB0, UTICK0, WWDT0 */ #define BOARD_BOOTCLOCKFRO48M_TRACE_CLOCK 48000000UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO48M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0 */ #define BOARD_BOOTCLOCKFRO48M_UTICK_CLOCK 1000000UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO48M_WUU_CLOCK 0UL /* Clock consumers of WUU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO48M_WWDT0_CLOCK 1000000UL /* Clock consumers of WWDT0_clock output : WWDT0 */ /******************************************************************************* * API for BOARD_BootClockFRO48M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO48M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO64M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO64M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO64M_CORE_CLOCK 64000000U /*!< Core clock frequency: 64000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO64M_ADC0_CLOCK 0UL /* Clock consumers of ADC0_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO64M_CLK16K_0_CLOCK 0UL /* Clock consumers of CLK16K_0_clock output : CMP0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO64M_CLK16K_1_CLOCK 0UL /* Clock consumers of CLK16K_1_clock output : CMP1, LPTMR0, WAKETIMER0 */ #define BOARD_BOOTCLOCKFRO64M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_CLK_1M_CLOCK 1000000UL /* Clock consumers of CLK_1M_clock output : CMC */ #define BOARD_BOOTCLOCKFRO64M_CLK_48M_CLOCK 48000000UL /* Clock consumers of CLK_48M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_CLK_IN_CLOCK 0UL /* Clock consumers of CLK_IN_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_CMP0FDIV_CLOCK 0UL /* Clock consumers of CMP0FDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO64M_CMP0RRDIV_CLOCK 0UL /* Clock consumers of CMP0RRDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO64M_CMP1FDIV_CLOCK 0UL /* Clock consumers of CMP1FDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO64M_CMP1RRDIV_CLOCK 0UL /* Clock consumers of CMP1RRDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO64M_CPU_CLOCK 64000000UL /* Clock consumers of CPU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO64M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO64M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO64M_FREQME_REFERENCE_CLOCK 0UL /* Clock consumers of FREQME_reference_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO64M_FREQME_TARGET_CLOCK 0UL /* Clock consumers of FREQME_target_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO64M_FRO_12M_CLOCK 12000000UL /* Clock consumers of FRO_12M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_FRO_HF_DIV_CLOCK 64000000UL /* Clock consumers of FRO_HF_DIV_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_FRO_HF_CLOCK 64000000UL /* Clock consumers of FRO_HF_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_I3C_FCLK_CLOCK 0UL /* Clock consumers of I3C_FCLK_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO64M_I3C_SLOW_TC_CLOCK 0UL /* Clock consumers of I3C_SLOW_TC_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO64M_I3C_SLOW_CLOCK 0UL /* Clock consumers of I3C_SLOW_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO64M_LPI2C0_CLOCK 0UL /* Clock consumers of LPI2C0_clock output : LPI2C0 */ #define BOARD_BOOTCLOCKFRO64M_LPSPI0_CLOCK 0UL /* Clock consumers of LPSPI0_clock output : LPSPI0 */ #define BOARD_BOOTCLOCKFRO64M_LPSPI1_CLOCK 0UL /* Clock consumers of LPSPI1_clock output : LPSPI1 */ #define BOARD_BOOTCLOCKFRO64M_LPTMR0_CLOCK 0UL /* Clock consumers of LPTMR0_clock output : LPTMR0 */ #define BOARD_BOOTCLOCKFRO64M_LPUART0_CLOCK 0UL /* Clock consumers of LPUART0_clock output : LPUART0 */ #define BOARD_BOOTCLOCKFRO64M_LPUART1_CLOCK 0UL /* Clock consumers of LPUART1_clock output : LPUART1 */ #define BOARD_BOOTCLOCKFRO64M_LPUART2_CLOCK 0UL /* Clock consumers of LPUART2_clock output : LPUART2 */ #define BOARD_BOOTCLOCKFRO64M_MAIN_CLOCK 64000000UL /* Clock consumers of MAIN_clock output : FLEXPWM0 */ #define BOARD_BOOTCLOCKFRO64M_OSTIMER_CLOCK 0UL /* Clock consumers of OSTIMER_clock output : OSTIMER0 */ #define BOARD_BOOTCLOCKFRO64M_FIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.FIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_SIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.SIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_SLOW_CLOCK 16000000UL /* Clock consumers of Slow_clock output : AOI0, CMC, CMP0, LPTMR0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO64M_SYSTEM_CLOCK 64000000UL /* Clock consumers of System_clock output : ADC0, CMP1, CTIMER0, CTIMER1, CTIMER2, DMA0, FLEXPWM0, FREQME0, GPIO0, GPIO1, GPIO2, GPIO3, I3C0, INPUTMUX0, LPI2C0, LPSPI0, LPSPI1, LPUART0, LPUART1, LPUART2, OSTIMER0, PORT0, PORT1, PORT2, PORT3, QDC0, SWD, SysTick, USB0, UTICK0, WWDT0 */ #define BOARD_BOOTCLOCKFRO64M_TRACE_CLOCK 64000000UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO64M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0 */ #define BOARD_BOOTCLOCKFRO64M_UTICK_CLOCK 1000000UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO64M_WUU_CLOCK 0UL /* Clock consumers of WUU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO64M_WWDT0_CLOCK 1000000UL /* Clock consumers of WWDT0_clock output : WWDT0 */ /******************************************************************************* * API for BOARD_BootClockFRO64M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO64M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO96M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKFRO96M_ADC0_CLOCK 0UL /* Clock consumers of ADC0_clock output : ADC0 */ #define BOARD_BOOTCLOCKFRO96M_CLK16K_0_CLOCK 0UL /* Clock consumers of CLK16K_0_clock output : CMP0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO96M_CLK16K_1_CLOCK 0UL /* Clock consumers of CLK16K_1_clock output : CMP1, LPTMR0, WAKETIMER0 */ #define BOARD_BOOTCLOCKFRO96M_CLKOUT_CLOCK 0UL /* Clock consumers of CLKOUT_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_CLK_1M_CLOCK 1000000UL /* Clock consumers of CLK_1M_clock output : CMC */ #define BOARD_BOOTCLOCKFRO96M_CLK_48M_CLOCK 48000000UL /* Clock consumers of CLK_48M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_CLK_IN_CLOCK 0UL /* Clock consumers of CLK_IN_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_CMP0FDIV_CLOCK 0UL /* Clock consumers of CMP0FDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO96M_CMP0RRDIV_CLOCK 0UL /* Clock consumers of CMP0RRDIV_clock output : CMP0 */ #define BOARD_BOOTCLOCKFRO96M_CMP1FDIV_CLOCK 0UL /* Clock consumers of CMP1FDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO96M_CMP1RRDIV_CLOCK 0UL /* Clock consumers of CMP1RRDIV_clock output : CMP1 */ #define BOARD_BOOTCLOCKFRO96M_CPU_CLOCK 96000000UL /* Clock consumers of CPU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_CTIMER0_CLOCK 0UL /* Clock consumers of CTIMER0_clock output : CTIMER0 */ #define BOARD_BOOTCLOCKFRO96M_CTIMER1_CLOCK 0UL /* Clock consumers of CTIMER1_clock output : CTIMER1 */ #define BOARD_BOOTCLOCKFRO96M_CTIMER2_CLOCK 0UL /* Clock consumers of CTIMER2_clock output : CTIMER2 */ #define BOARD_BOOTCLOCKFRO96M_FREQME_REFERENCE_CLOCK 0UL /* Clock consumers of FREQME_reference_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO96M_FREQME_TARGET_CLOCK 0UL /* Clock consumers of FREQME_target_clock output : FREQME0 */ #define BOARD_BOOTCLOCKFRO96M_FRO_12M_CLOCK 12000000UL /* Clock consumers of FRO_12M_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_FRO_HF_DIV_CLOCK 96000000UL /* Clock consumers of FRO_HF_DIV_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_FRO_HF_CLOCK 96000000UL /* Clock consumers of FRO_HF_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_I3C_FCLK_CLOCK 0UL /* Clock consumers of I3C_FCLK_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO96M_I3C_SLOW_TC_CLOCK 0UL /* Clock consumers of I3C_SLOW_TC_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO96M_I3C_SLOW_CLOCK 0UL /* Clock consumers of I3C_SLOW_clock output : I3C0 */ #define BOARD_BOOTCLOCKFRO96M_LPI2C0_CLOCK 0UL /* Clock consumers of LPI2C0_clock output : LPI2C0 */ #define BOARD_BOOTCLOCKFRO96M_LPSPI0_CLOCK 0UL /* Clock consumers of LPSPI0_clock output : LPSPI0 */ #define BOARD_BOOTCLOCKFRO96M_LPSPI1_CLOCK 0UL /* Clock consumers of LPSPI1_clock output : LPSPI1 */ #define BOARD_BOOTCLOCKFRO96M_LPTMR0_CLOCK 0UL /* Clock consumers of LPTMR0_clock output : LPTMR0 */ #define BOARD_BOOTCLOCKFRO96M_LPUART0_CLOCK 0UL /* Clock consumers of LPUART0_clock output : LPUART0 */ #define BOARD_BOOTCLOCKFRO96M_LPUART1_CLOCK 0UL /* Clock consumers of LPUART1_clock output : LPUART1 */ #define BOARD_BOOTCLOCKFRO96M_LPUART2_CLOCK 0UL /* Clock consumers of LPUART2_clock output : LPUART2 */ #define BOARD_BOOTCLOCKFRO96M_MAIN_CLOCK 96000000UL /* Clock consumers of MAIN_clock output : FLEXPWM0 */ #define BOARD_BOOTCLOCKFRO96M_OSTIMER_CLOCK 0UL /* Clock consumers of OSTIMER_clock output : OSTIMER0 */ #define BOARD_BOOTCLOCKFRO96M_FIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.FIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_SIRC_TRIM_CLOCK 0UL /* Clock consumers of SCG.SIRC_TRIM_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_SLOW_CLOCK 24000000UL /* Clock consumers of Slow_clock output : AOI0, CMC, CMP0, LPTMR0, WAKETIMER0, WUU0 */ #define BOARD_BOOTCLOCKFRO96M_SYSTEM_CLOCK 96000000UL /* Clock consumers of System_clock output : ADC0, CMP1, CTIMER0, CTIMER1, CTIMER2, DMA0, FLEXPWM0, FREQME0, GPIO0, GPIO1, GPIO2, GPIO3, I3C0, INPUTMUX0, LPI2C0, LPSPI0, LPSPI1, LPUART0, LPUART1, LPUART2, OSTIMER0, PORT0, PORT1, PORT2, PORT3, QDC0, SWD, SysTick, USB0, UTICK0, WWDT0 */ #define BOARD_BOOTCLOCKFRO96M_TRACE_CLOCK 96000000UL /* Clock consumers of TRACE_clock output : SWD */ #define BOARD_BOOTCLOCKFRO96M_USB0_CLOCK 0UL /* Clock consumers of USB0_clock output : USB0 */ #define BOARD_BOOTCLOCKFRO96M_UTICK_CLOCK 1000000UL /* Clock consumers of UTICK_clock output : UTICK0 */ #define BOARD_BOOTCLOCKFRO96M_WUU_CLOCK 0UL /* Clock consumers of WUU_clock output : N/A */ #define BOARD_BOOTCLOCKFRO96M_WWDT0_CLOCK 1000000UL /* Clock consumers of WWDT0_clock output : WWDT0 */ /******************************************************************************* * API for BOARD_BootClockFRO96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa153/frdm_mcxa153.mex ================================================ MCXA153 MCXA153VLH FRDM-MCXA153 ksdk2_0 true false /* * Copyright 2025 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ true true true false 25.09.10 Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. false cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true true Configures pin routing and optionally pin electrical features. true cm33_core0 true true true 25.09.10 true true true false true true true false true true true false true true true false true true true true N/A 25.09.10 N/A ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c ================================================ /* * Copyright 2025 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: MCXA153 package_id: MCXA153VLH mcu_data: ksdk2_0 processor_version: 25.09.10 board: FRDM-MCXA153 external_user_signals: {} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "fsl_gpio.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitDEBUG_UARTPins(); BOARD_InitLEDsPins(); BOARD_InitBUTTONsPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '51', peripheral: LPUART0, signal: RX, pin_signal: P0_2/TDO/SWO/LPUART0_RXD/LPSPI0_SCK/CT0_MAT0/UTICK_CAP0/I3C0_PUR, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} - {pin_num: '52', peripheral: LPUART0, signal: TX, pin_signal: P0_3/TDI/LPUART0_TXD/LPSPI0_SDO/CT0_MAT1/UTICK_CAP1/CMP0_OUT/CMP1_IN1, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitDEBUG_UARTPins(void) { /* Write to PORT0: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); /* LPUART0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); /* PORT0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); const port_pin_config_t DEBUG_UART_RX = {/* Internal pull-up/down resistor is disabled */ .pullSelect = kPORT_PullDisable, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* High drive strength is configured */ .driveStrength = kPORT_HighDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_RXD */ .mux = kPORT_MuxAlt2, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT0_2 (pin 51) is configured as LPUART0_RXD */ PORT_SetPinConfig(BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN, &DEBUG_UART_RX); const port_pin_config_t DEBUG_UART_TX = {/* Internal pull-up resistor is enabled */ .pullSelect = kPORT_PullUp, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* Low drive strength is configured */ .driveStrength = kPORT_LowDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_TXD */ .mux = kPORT_MuxAlt2, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT0_3 (pin 52) is configured as LPUART0_TXD */ PORT_SetPinConfig(BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT, BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN, &DEBUG_UART_TX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'false', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '50', peripheral: SWD, signal: SWCLK, pin_signal: P0_1/TCLK/SWCLK/LPUART0_CTS_B/LPSPI0_SDI/CT_INP1, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: enable, input_buffer: enable, invert_input: normal} - {pin_num: '49', peripheral: SWD, signal: SWDIO, pin_signal: P0_0/TMS/SWDIO/LPUART0_RTS_B/LPSPI0_PCS0/CT_INP0, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, input_buffer: enable, invert_input: normal} - {pin_num: '51', peripheral: SWD, signal: SWO, pin_signal: P0_2/TDO/SWO/LPUART0_RXD/LPSPI0_SCK/CT0_MAT0/UTICK_CAP0/I3C0_PUR, slew_rate: fast, open_drain: disable, drive_strength: high, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitSWD_DEBUGPins(void) { /* Write to PORT0: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); /* PORT0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); /* LPUART0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); const port_pin_config_t DEBUG_SWD_SWDIO = {/* Internal pull-up resistor is enabled */ .pullSelect = kPORT_PullUp, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* High drive strength is configured */ .driveStrength = kPORT_HighDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as SWDIO */ .mux = kPORT_MuxAlt1, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT0_0 (pin 49) is configured as SWDIO */ PORT_SetPinConfig(BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN, &DEBUG_SWD_SWDIO); const port_pin_config_t DEBUG_SWD_SWDCLK = {/* Internal pull-down resistor is enabled */ .pullSelect = kPORT_PullDown, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* Low drive strength is configured */ .driveStrength = kPORT_LowDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as SWCLK */ .mux = kPORT_MuxAlt1, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT0_1 (pin 50) is configured as SWCLK */ PORT_SetPinConfig(BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN, &DEBUG_SWD_SWDCLK); const port_pin_config_t DEBUG_UART_RX = {/* Internal pull-up/down resistor is disabled */ .pullSelect = kPORT_PullDisable, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* High drive strength is configured */ .driveStrength = kPORT_HighDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as SWO */ .mux = kPORT_MuxAlt1, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT0_2 (pin 51) is configured as SWO */ PORT_SetPinConfig(BOARD_INITSWD_DEBUGPINS_DEBUG_UART_RX_PORT, BOARD_INITSWD_DEBUGPINS_DEBUG_UART_RX_PIN, &DEBUG_UART_RX); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '37', peripheral: GPIO3, signal: 'GPIO, 13', pin_signal: P3_13/LPUART2_CTS_B/CT1_MAT3/PWM0_X1, direction: OUTPUT, gpio_init_state: 'true', slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: disable, input_buffer: enable, invert_input: normal} - {pin_num: '38', peripheral: GPIO3, signal: 'GPIO, 12', pin_signal: P3_12/LPUART2_RTS_B/CT1_MAT2/PWM0_X0, direction: OUTPUT, gpio_init_state: 'true', slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: disable, input_buffer: enable, invert_input: normal} - {pin_num: '46', peripheral: GPIO3, signal: 'GPIO, 0', pin_signal: P3_0/WUU0_IN22/TRIG_IN0/CT_INP16/PWM0_A0, direction: OUTPUT, gpio_init_state: 'true', slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitLEDsPins(void) { /* Write to GPIO3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GateGPIO3); /* Write to PORT3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT3); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); /* PORT3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); gpio_pin_config_t LED_BLUE_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO3_0 (pin 46) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_BLUE_GPIO, BOARD_INITLEDSPINS_LED_BLUE_PIN, &LED_BLUE_config); gpio_pin_config_t LED_RED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO3_12 (pin 38) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_RED_GPIO, BOARD_INITLEDSPINS_LED_RED_PIN, &LED_RED_config); gpio_pin_config_t LED_GREEN_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO3_13 (pin 37) */ GPIO_PinInit(BOARD_INITLEDSPINS_LED_GREEN_GPIO, BOARD_INITLEDSPINS_LED_GREEN_PIN, &LED_GREEN_config); /* PORT3_0 (pin 46) is configured as P3_0 */ PORT_SetPinMux(BOARD_INITLEDSPINS_LED_BLUE_PORT, BOARD_INITLEDSPINS_LED_BLUE_PIN, kPORT_MuxAlt0); PORT3->PCR[0] = ((PORT3->PCR[0] & /* Mask bits to zero which are setting */ (~(PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_SRE_MASK | PORT_PCR_PFE_MASK | PORT_PCR_ODE_MASK | PORT_PCR_DSE_MASK | PORT_PCR_IBE_MASK | PORT_PCR_INV_MASK))) /* Pull Select: Enables internal pullup resistor. */ | PORT_PCR_PS(PCR_PS_ps1) /* Pull Enable: Disables. */ | PORT_PCR_PE(PCR_PE_pe0) /* Slew Rate Enable: Fast. */ | PORT_PCR_SRE(PCR_SRE_sre0) /* Passive Filter Enable: Disables. */ | PORT_PCR_PFE(PCR_PFE_pfe0) /* Open Drain Enable: Disables. */ | PORT_PCR_ODE(PCR_ODE_ode0) /* Drive Strength Enable: Low. */ | PORT_PCR_DSE(PCR_DSE_dse0) /* Input Buffer Enable: Enables. */ | PORT_PCR_IBE(PCR_IBE_ibe1) /* Invert Input: Does not invert. */ | PORT_PCR_INV(PCR_INV_inv0)); /* PORT3_12 (pin 38) is configured as P3_12 */ PORT_SetPinMux(BOARD_INITLEDSPINS_LED_RED_PORT, BOARD_INITLEDSPINS_LED_RED_PIN, kPORT_MuxAlt0); PORT3->PCR[12] = ((PORT3->PCR[12] & /* Mask bits to zero which are setting */ (~(PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_SRE_MASK | PORT_PCR_ODE_MASK | PORT_PCR_DSE_MASK | PORT_PCR_IBE_MASK | PORT_PCR_INV_MASK))) /* Pull Select: Enables internal pullup resistor. */ | PORT_PCR_PS(PCR_PS_ps1) /* Pull Enable: Disables. */ | PORT_PCR_PE(PCR_PE_pe0) /* Slew Rate Enable: Fast. */ | PORT_PCR_SRE(PCR_SRE_sre0) /* Open Drain Enable: Disables. */ | PORT_PCR_ODE(PCR_ODE_ode0) /* Drive Strength Enable: Low. */ | PORT_PCR_DSE(PCR_DSE_dse0) /* Input Buffer Enable: Enables. */ | PORT_PCR_IBE(PCR_IBE_ibe1) /* Invert Input: Does not invert. */ | PORT_PCR_INV(PCR_INV_inv0)); /* PORT3_13 (pin 37) is configured as P3_13 */ PORT_SetPinMux(BOARD_INITLEDSPINS_LED_GREEN_PORT, BOARD_INITLEDSPINS_LED_GREEN_PIN, kPORT_MuxAlt0); PORT3->PCR[13] = ((PORT3->PCR[13] & /* Mask bits to zero which are setting */ (~(PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_SRE_MASK | PORT_PCR_ODE_MASK | PORT_PCR_DSE_MASK | PORT_PCR_IBE_MASK | PORT_PCR_INV_MASK))) /* Pull Select: Enables internal pullup resistor. */ | PORT_PCR_PS(PCR_PS_ps1) /* Pull Enable: Disables. */ | PORT_PCR_PE(PCR_PE_pe0) /* Slew Rate Enable: Fast. */ | PORT_PCR_SRE(PCR_SRE_sre0) /* Open Drain Enable: Disables. */ | PORT_PCR_ODE(PCR_ODE_ode0) /* Drive Strength Enable: Low. */ | PORT_PCR_DSE(PCR_DSE_dse0) /* Input Buffer Enable: Enables. */ | PORT_PCR_IBE(PCR_IBE_ibe1) /* Invert Input: Does not invert. */ | PORT_PCR_INV(PCR_INV_inv0)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitBUTTONsPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '1', peripheral: GPIO1, signal: 'GPIO, 7', pin_signal: P1_7/WUU0_IN9/TRIG_OUT2/LPUART2_CTS_B/CT_INP7/ADC0_A23, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} - {pin_num: '8', peripheral: GPIO1, signal: 'GPIO, 29', pin_signal: P1_29/RESET_B/SPC_LPREQ, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: enable, pull_value: low, input_buffer: enable, invert_input: normal} - {pin_num: '32', peripheral: GPIO3, signal: 'GPIO, 29', pin_signal: P3_29/WUU0_IN27/ISPMODE_N/CT_INP3/ADC0_A14, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBUTTONsPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitBUTTONsPins(void) { /* Write to PORT1: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT1); /* Write to PORT3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT3); /* GPIO1 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn); /* PORT1 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); /* PORT3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); const port_pin_config_t SW1 = {/* Internal pull-up resistor is enabled */ .pullSelect = kPORT_PullUp, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is enabled */ .passiveFilterEnable = kPORT_PassiveFilterEnable, /* Open drain output is enabled */ .openDrainEnable = kPORT_OpenDrainEnable, /* Low drive strength is configured */ .driveStrength = kPORT_LowDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as P1_29 */ .mux = kPORT_MuxAlt0, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT1_29 (pin 8) is configured as P1_29 */ PORT_SetPinConfig(BOARD_INITBUTTONSPINS_SW1_PORT, BOARD_INITBUTTONSPINS_SW1_PIN, &SW1); const port_pin_config_t SW3 = {/* Internal pull-up/down resistor is disabled */ .pullSelect = kPORT_PullDisable, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* Low drive strength is configured */ .driveStrength = kPORT_LowDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as P1_7 */ .mux = kPORT_MuxAlt0, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT1_7 (pin 1) is configured as P1_7 */ PORT_SetPinConfig(BOARD_INITBUTTONSPINS_SW3_PORT, BOARD_INITBUTTONSPINS_SW3_PIN, &SW3); const port_pin_config_t ISP = {/* Internal pull-up resistor is enabled */ .pullSelect = kPORT_PullUp, /* Low internal pull resistor value is selected. */ .pullValueSelect = kPORT_LowPullResistor, /* Fast slew rate is configured */ .slewRate = kPORT_FastSlewRate, /* Passive input filter is disabled */ .passiveFilterEnable = kPORT_PassiveFilterDisable, /* Open drain output is disabled */ .openDrainEnable = kPORT_OpenDrainDisable, /* Low drive strength is configured */ .driveStrength = kPORT_LowDriveStrength, /* Normal drive strength is configured */ .driveStrength1 = kPORT_NormalDriveStrength, /* Pin is configured as P3_29 */ .mux = kPORT_MuxAlt0, /* Digital input enabled */ .inputBuffer = kPORT_InputBufferEnable, /* Digital input is not inverted */ .invertInput = kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ .lockRegister = kPORT_UnlockRegister}; /* PORT3_29 (pin 32) is configured as P3_29 */ PORT_SetPinConfig(BOARD_INITBUTTONSPINS_ISP_PORT, BOARD_INITBUTTONSPINS_ISP_PIN, &ISP); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h ================================================ /* * Copyright 2025 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! @name PORT0_2 (number 51), P0_2/SWO/J25[3]/J18[6] @{ */ /* Symbols to be used with PORT driver */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PORT PORT0 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN 2U /*!<@brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_RX_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT0_3 (number 52), P0_3/J25[1]/J18[8] @{ */ /* Symbols to be used with PORT driver */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PORT PORT0 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN 3U /*!<@brief PORT pin number */ #define BOARD_INITDEBUG_UARTPINS_DEBUG_UART_TX_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /*! @name PORT0_1 (number 50), P0_1/SWCLK/JP10[2]/J18[4] @{ */ /* Symbols to be used with PORT driver */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PORT PORT0 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN 1U /*!<@brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT0_0 (number 49), P0_0/SWDIO/J18[2] @{ */ /* Symbols to be used with PORT driver */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PORT PORT0 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN 0U /*!<@brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT0_2 (number 51), P0_2/SWO/J25[3]/J18[6] @{ */ /* Symbols to be used with PORT driver */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_UART_RX_PORT PORT0 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_UART_RX_PIN 2U /*!<@brief PORT pin number */ #define BOARD_INITSWD_DEBUGPINS_DEBUG_UART_RX_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); #define PCR_DSE_dse0 0x00u /*!<@brief Drive Strength Enable: Low */ #define PCR_IBE_ibe1 0x01u /*!<@brief Input Buffer Enable: Enables */ #define PCR_INV_inv0 0x00u /*!<@brief Invert Input: Does not invert */ #define PCR_ODE_ode0 0x00u /*!<@brief Open Drain Enable: Disables */ #define PCR_PE_pe0 0x00u /*!<@brief Pull Enable: Disables */ #define PCR_PFE_pfe0 0x00u /*!<@brief Passive Filter Enable: Disables */ #define PCR_PS_ps1 0x01u /*!<@brief Pull Select: Enables internal pullup resistor */ #define PCR_SRE_sre0 0x00u /*!<@brief Slew Rate Enable: Fast */ /*! @name PORT3_13 (number 37), P3_13/J1[14] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN 13U /*!<@brief GPIO pin number */ #define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN_MASK (1U << 13U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITLEDSPINS_LED_GREEN_PORT PORT3 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN 13U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_GREEN_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT3_12 (number 38), P3_12/J1[12]/J5[1] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_RED_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN 12U /*!<@brief GPIO pin number */ #define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN_MASK (1U << 12U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITLEDSPINS_LED_RED_PORT PORT3 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_RED_PIN 12U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_RED_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT3_0 (number 46), P3_0/J1[8] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN 0U /*!<@brief GPIO pin number */ #define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN_MASK (1U << 0U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITLEDSPINS_LED_BLUE_PORT PORT3 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN 0U /*!<@brief PORT pin number */ #define BOARD_INITLEDSPINS_LED_BLUE_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDsPins(void); /*! @name PORT1_7 (number 1), P1_7/J1[1] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_SW3_GPIO GPIO1 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_SW3_GPIO_PIN 7U /*!<@brief GPIO pin number */ #define BOARD_INITBUTTONSPINS_SW3_GPIO_PIN_MASK (1U << 7U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITBUTTONSPINS_SW3_PORT PORT1 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_SW3_PIN 7U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_SW3_PIN_MASK (1U << 7U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT1_29 (number 8), P1_29/J3[6]/J18[10] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_SW1_GPIO GPIO1 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_SW1_GPIO_PIN 29U /*!<@brief GPIO pin number */ #define BOARD_INITBUTTONSPINS_SW1_GPIO_PIN_MASK (1U << 29U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITBUTTONSPINS_SW1_PORT PORT1 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_SW1_PIN 29U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_SW1_PIN_MASK (1U << 29U) /*!<@brief PORT pin mask */ /* @} */ /*! @name PORT3_29 (number 32), P3_29/J18[7]/J4[11] @{ */ /* Symbols to be used with GPIO driver */ #define BOARD_INITBUTTONSPINS_ISP_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITBUTTONSPINS_ISP_GPIO_PIN 29U /*!<@brief GPIO pin number */ #define BOARD_INITBUTTONSPINS_ISP_GPIO_PIN_MASK (1U << 29U) /*!<@brief GPIO pin mask */ /* Symbols to be used with PORT driver */ #define BOARD_INITBUTTONSPINS_ISP_PORT PORT3 /*!<@brief PORT peripheral base pointer */ #define BOARD_INITBUTTONSPINS_ISP_PIN 29U /*!<@brief PORT pin number */ #define BOARD_INITBUTTONSPINS_ISP_PIN_MASK (1U << 29U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitBUTTONsPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/board.cmake ================================================ set(MCU_VARIANT MCXA156) set(MCU_FAMILY MCXA) set(MCU_CORE MCXA156) set(JLINK_DEVICE MCXA156_M33) set(PYOCD_TARGET MCXA156) set(NXPLINK_DEVICE MCXA156:MCXA156) set(PORT 0) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_MCXA156VLH BOARD_TUD_RHPORT=0 BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED CFG_EXAMPLE_VIDEO_READONLY ) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c ) target_include_directories(${TARGET} PUBLIC ${SDK_DIR}/${MCU_FAMILY}/periph1 ) endfunction() ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Freedom MCXA156 url: https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA156 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_GPIO GPIO3 #define LED_CLK kCLOCK_GateGPIO3 #define LED_PIN 12 // red #define LED_STATE_ON 0 // ISP button #define BUTTON_GPIO GPIO0 #define BUTTON_CLK kCLOCK_GateGPIO0 #define BUTTON_PIN 6 //SW3 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART0 static inline void board_uart_init_clock(void) { /* attach 12 MHz clock to LPUART0 (debug console) */ CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); CLOCK_AttachClk(kFRO12M_to_LPUART0); RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); } // XTAL #define XTAL0_CLK_HZ (24 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/board.mk ================================================ MCU_VARIANT = MCXA156 MCU_FAMILY = MCXA MCU_CORE = MCXA156 PORT = 0 CPU_CORE = cortex-m33-nodsp-nofp CFLAGS += \ -DCPU_MCXA156VLH \ -DCFG_TUSB_MCU=OPT_MCU_MCXA15 \ INC += \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/periph1 JLINK_DEVICE = MCXA156 PYOCD_TARGET = MCXA156 # flash using pyocd flash: flash-jlink ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/clock_config.c ================================================ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to setup clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. * */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v13.0 processor: MCXA156 package_id: MCXA156VLL mcu_data: ksdk2_0 processor_version: 0.15.0 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "fsl_clock.h" #include "clock_config.h" #include "fsl_spc.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /* System clock frequency. */ //extern uint32_t SystemCoreClock; /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockFRO96M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CPU_clock.outFreq, value: 12 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: MAIN_clock.outFreq, value: 12 MHz} - {id: Slow_clock.outFreq, value: 3 MHz} - {id: System_clock.outFreq, value: 12 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} settings: - {id: SCGMode, value: SIRC} - {id: FRO_HF_PERIPHERALS_EN_CFG, value: Disabled} - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SCG.SCSSEL.sel, value: SCG.SIRC} - {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO12M */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO24M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO24M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 24 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 6 MHz} - {id: System_clock.outFreq, value: 24 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} settings: - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO24M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO24M configuration ******************************************************************************/ void BOARD_BootClockFRO24M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 2U); /* !< Set AHBCLKDIV divider to value 2 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO24M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO48M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO48M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 12 MHz} - {id: System_clock.outFreq, value: 48 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} settings: - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO48M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO48M configuration ******************************************************************************/ void BOARD_BootClockFRO48M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P0V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO48M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO64M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO64M outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 64 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 64 MHz} - {id: FRO_HF_clock.outFreq, value: 64 MHz} - {id: MAIN_clock.outFreq, value: 64 MHz} - {id: Slow_clock.outFreq, value: 16 MHz} - {id: System_clock.outFreq, value: 64 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} settings: - {id: VDD_CORE, value: voltage_1v1} - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FROHFDIV.scale, value: '1', locked: true} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} sources: - {id: SCG.FIRC.outFreq, value: 64 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO64M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO64M configuration ******************************************************************************/ void BOARD_BootClockFRO64M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } CLOCK_SetupFROHFClocking(64000000U); /*!< Enable FRO HF(64MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO64M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO96M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO96M called_from_default_init: true outputs: - {id: CLK_1M_clock.outFreq, value: 1 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CPU_clock.outFreq, value: 96 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_DIV_clock.outFreq, value: 96 MHz} - {id: FRO_HF_clock.outFreq, value: 96 MHz} - {id: MAIN_clock.outFreq, value: 96 MHz} - {id: Slow_clock.outFreq, value: 24 MHz} - {id: System_clock.outFreq, value: 96 MHz} - {id: UTICK_clock.outFreq, value: 1 MHz} settings: - {id: VDD_CORE, value: voltage_1v1} - {id: CLKOUTDIV_HALT, value: Enable} - {id: MRCC.FREQMEREFCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FREQMETARGETCLKSEL.sel, value: MRCC.aoi0_out0} - {id: MRCC.FROHFDIV.scale, value: '1', locked: true} - {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} - {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} sources: - {id: SCG.FIRC.outFreq, value: 96 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO96M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO96M configuration ******************************************************************************/ void BOARD_BootClockFRO96M(void) { uint32_t coreFreq; spc_active_mode_core_ldo_option_t ldoOption; spc_sram_voltage_config_t sramOption; /* Get the CPU Core frequency */ coreFreq = CLOCK_GetCoreSysClkFreq(); /* The flow of increasing voltage and frequency */ if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { /* Configure Flash to support different voltage level and frequency */ FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); /* Specifies the operating voltage for the SRAM's read/write timing margin */ sramOption.operateVoltage = kSPC_sramOperateAt1P1V; sramOption.requestVoltageUpdate = true; (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); /* Set the LDO_CORE VDD regulator level */ ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); } /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO96M_CORE_CLOCK; } ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/clock_config.h ================================================ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO24M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO24M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO24M_CORE_CLOCK 24000000U /*!< Core clock frequency: 24000000Hz */ /******************************************************************************* * API for BOARD_BootClockFRO24M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO24M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO48M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO48M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ /******************************************************************************* * API for BOARD_BootClockFRO48M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO48M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO64M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO64M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO64M_CORE_CLOCK 64000000U /*!< Core clock frequency: 64000000Hz */ /******************************************************************************* * API for BOARD_BootClockFRO64M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO64M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO96M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO96M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ /******************************************************************************* * API for BOARD_BootClockFRO96M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO96M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/pin_mux.c ================================================ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v15.0 processor: MCXA156 package_id: MCXA156VLL mcu_data: ksdk2_0 processor_version: 0.15.0 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: '78', peripheral: LPUART0, signal: RX, pin_signal: P0_2/TDO/SWO/LPUART0_RXD/LPSPI0_SCK/CT0_MAT0/UTICK_CAP0/FLEXIO0_D2, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, input_buffer: enable, invert_input: normal} - {pin_num: '79', peripheral: LPUART0, signal: TX, pin_signal: P0_3/TDI/LPUART0_TXD/LPSPI0_SDO/CT0_MAT1/UTICK_CAP1/FLEXIO0_D3/CMP0_OUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); CLOCK_AttachClk(kFRO12M_to_LPUART0); /* GPIO3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GateGPIO3); /* PORT3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT3); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); /* PORT3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); /* GPIO3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GateGPIO0); /* PORT3: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); /* GPIO3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kGPIO0_RST_SHIFT_RSTn); /* PORT3 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); /* PORT0: Peripheral clock is enabled */ CLOCK_EnableClock(kCLOCK_GatePORT0); /* LPUART0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); /* PORT0 peripheral is released from reset */ RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); const port_pin_config_t port0_2_pin78_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_RXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_2 (pin 78) is configured as LPUART0_RXD */ PORT_SetPinConfig(PORT0, 2U, &port0_2_pin78_config); const port_pin_config_t port0_3_pin79_config = {/* Internal pull-up resistor is enabled */ kPORT_PullUp, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as LPUART0_TXD */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_3 (pin 79) is configured as LPUART0_TXD */ PORT_SetPinConfig(PORT0, 3U, &port0_3_pin79_config); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxa156/pin_mux.h ================================================ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/board.cmake ================================================ set(MCU_VARIANT MCXN947) set(MCU_FAMILY MCXN) set(MCU_CORE MCXN947_cm33_core0) set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) set(PORT 1) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_MCXN947VDF_cm33_core0 BOARD_TUD_RHPORT=${PORT} # port 0 is fullspeed, port 1 is highspeed BOARD_TUD_MAX_SPEED=$ ) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c ) target_include_directories(${TARGET} PUBLIC ${SDK_DIR}/${MCU_FAMILY}/periph ) endfunction() ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Freedom MCXN947 url: https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXN947 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_GPIO GPIO0 #define LED_CLK kCLOCK_Gpio0 #define LED_PIN 10 // red #define LED_STATE_ON 0 // WAKE button (Dummy, use unused pin #define BUTTON_GPIO GPIO0 #define BUTTON_CLK kCLOCK_Gpio0 #define BUTTON_PIN 23 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART4 #define LP_FLEXCOMM_INST 4 #include "fsl_lpflexcomm.h" static inline void board_uart_init_clock(void) { /* attach FRO 12M to FLEXCOMM4 */ LP_FLEXCOMM_Init(LP_FLEXCOMM_INST, LP_FLEXCOMM_PERIPH_LPUART); CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); } // XTAL #define XTAL0_CLK_HZ (24 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/board.mk ================================================ MCU_VARIANT = MCXN947 MCU_FAMILY = MCXN MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 CPU_CORE = cortex-m33 CFLAGS += \ -DCPU_MCXN947VDF_cm33_core0 \ -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ INC += \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/periph JLINK_DEVICE = MCXN947_M33_0 PYOCD_TARGET = MCXN947 # flash using pyocd flash: flash-jlink ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to setup clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. * */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v10.0 processor: MCXN947 package_id: MCXN947VDF mcu_data: ksdk2_0 processor_version: 0.12.3 board: MCX-N9XX-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "clock_config.h" #include "fsl_clock.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /* System clock frequency. */ // extern uint32_t SystemCoreClock; /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: MAIN_clock.outFreq, value: 12 MHz} - {id: Slow_clock.outFreq, value: 3 MHz} - {id: System_clock.outFreq, value: 12 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SCGMode, value: SIRC} - {id: SCG.SCSSEL.sel, value: SCG.SIRC} - {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF48M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF48M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 12 MHz} - {id: System_clock.outFreq, value: 48 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF48M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF48M configuration ******************************************************************************/ void BOARD_BootClockFROHF48M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF144M ******************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF144M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 144 MHz} - {id: MAIN_clock.outFreq, value: 144 MHz} - {id: Slow_clock.outFreq, value: 18 MHz} - {id: System_clock.outFreq, value: 72 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} sources: - {id: SCG.FIRC.outFreq, value: 144 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF144M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF144M configuration ******************************************************************************/ void BOARD_BootClockFROHF144M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 150 MHz} - {id: PLL0_CLK_clock.outFreq, value: 150 MHz} - {id: Slow_clock.outFreq, value: 37.5 MHz} - {id: System_clock.outFreq, value: 150 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: RunPowerMode, value: OD} - {id: SCGMode, value: PLL0} - {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} - {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} - {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} - {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ /*!< Set up PLL0 */ const pll_setup_t pll0Setup = { .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), .pllndiv = SCG_APLLNDIV_NDIV(8U), .pllpdiv = SCG_APLLPDIV_PDIV(1U), .pllmdiv = SCG_APLLMDIV_MDIV(50U), .pllRate = 150000000U }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CLK_IN_clock.outFreq, value: 24 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: MAIN_clock.outFreq, value: 100 MHz} - {id: PLL1_CLK_clock.outFreq, value: 100 MHz} - {id: Slow_clock.outFreq, value: 25 MHz} - {id: System_clock.outFreq, value: 100 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: PLL1_Mode, value: Normal} - {id: SCGMode, value: PLL1} - {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} - {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} - {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} - {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} - {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} - {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} sources: - {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupExtClocking(24000000U); CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ /*!< Set up PLL1 */ const pll_setup_t pll1Setup = { .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), .pllndiv = SCG_SPLLNDIV_NDIV(6U), .pllpdiv = SCG_SPLLPDIV_PDIV(2U), .pllmdiv = SCG_SPLLMDIV_MDIV(100U), .pllRate = 100000000U }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; } ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ #define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF48M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF48M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ #define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFROHF48M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF48M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF144M ******************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF144M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ #define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFROHF144M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF144M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ #define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ #define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v12.0 processor: MCXN947 package_id: MCXN947VDF mcu_data: ksdk2_0 processor_version: 0.12.3 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, invert_input: normal} - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} - {pin_num: B7, peripheral: GPIO0, signal: 'GPIO, 23', pin_signal: PIO0_23/WUU0_IN5/EWM0_OUT_b/FC1_P3/CT_INP3/FLEXIO0_D7/ADC0_A15/CMP2_IN2, direction: INPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { /* Enables the clock for PORT0: Enables clock */ CLOCK_EnableClock(kCLOCK_Port0); /* Enables the clock for PORT1: Enables clock */ CLOCK_EnableClock(kCLOCK_Port1); const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as FC4_P0 */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT1_8 (pin A1) is configured as FC4_P0 */ PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as FC4_P1 */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT1_9 (pin B1) is configured as FC4_P1 */ PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); const port_pin_config_t SW2 = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PIO0_23 */ kPORT_MuxAlt0, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT0_23 (pin B7) is configured as PIO0_23 */ PORT_SetPinConfig(PORT0, 23U, &SW2); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/board.cmake ================================================ set(MCU_VARIANT MCXN947) set(MCU_FAMILY MCXN) set(MCU_CORE MCXN947_cm33_core0) set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) set(PORT 1) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_MCXN947VDF_cm33_core0 BOARD_TUD_RHPORT=${PORT} # port 0 is fullspeed, port 1 is highspeed BOARD_TUD_MAX_SPEED=$ ) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c ) target_include_directories(${TARGET} PUBLIC ${SDK_DIR}/${MCU_FAMILY}/periph ) endfunction() ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MCXN947 Breakout url: n/a */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_GPIO GPIO3 #define LED_CLK kCLOCK_Gpio3 #define LED_PIN 4 // red #define LED_STATE_ON 0 // WAKE button (Dummy, use unused pin #define BUTTON_GPIO GPIO0 #define BUTTON_CLK kCLOCK_Gpio0 #define BUTTON_PIN 6 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART4 static inline void board_uart_init_clock(void) { /* attach FRO 12M to FLEXCOMM4 */ CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); } //#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN //#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN // XTAL #define XTAL0_CLK_HZ (24 * 1000 * 1000U) #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/board.mk ================================================ MCU_VARIANT = MCXN947 MCU_FAMILY = MCXN MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 CPU_CORE = cortex-m33 CFLAGS += \ -DCPU_MCXN947VDF_cm33_core0 \ -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ INC += \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/periph JLINK_DEVICE = MCXN947_M33_0 PYOCD_TARGET = MCXN947 # flash using pyocd flash: flash-jlink ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/clock_config.c ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* * How to setup clock using clock driver functions: * * 1. Setup clock sources. * * 2. Set up wait states of the flash. * * 3. Set up all dividers. * * 4. Set up all selectors to provide selected clocks. * */ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Clocks v10.0 processor: MCXN947 package_id: MCXN947VDF mcu_data: ksdk2_0 processor_version: 0.12.3 board: MCX-N9XX-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ #include "clock_config.h" #include "fsl_clock.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /* System clock frequency. */ // extern uint32_t SystemCoreClock; /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ void BOARD_InitBootClocks(void) { BOARD_BootClockPLL150M(); } /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFRO12M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: MAIN_clock.outFreq, value: 12 MHz} - {id: Slow_clock.outFreq, value: 3 MHz} - {id: System_clock.outFreq, value: 12 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SCGMode, value: SIRC} - {id: SCG.SCSSEL.sel, value: SCG.SIRC} - {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFRO12M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFRO12M configuration ******************************************************************************/ void BOARD_BootClockFRO12M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF48M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF48M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 48 MHz} - {id: Slow_clock.outFreq, value: 12 MHz} - {id: System_clock.outFreq, value: 48 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF48M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF48M configuration ******************************************************************************/ void BOARD_BootClockFROHF48M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; } /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF144M ******************** ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockFROHF144M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 144 MHz} - {id: MAIN_clock.outFreq, value: 144 MHz} - {id: Slow_clock.outFreq, value: 18 MHz} - {id: System_clock.outFreq, value: 72 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} sources: - {id: SCG.FIRC.outFreq, value: 144 MHz} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockFROHF144M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockFROHF144M configuration ******************************************************************************/ void BOARD_BootClockFROHF144M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL150M called_from_default_init: true outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: FRO_HF_clock.outFreq, value: 48 MHz} - {id: MAIN_clock.outFreq, value: 150 MHz} - {id: PLL0_CLK_clock.outFreq, value: 150 MHz} - {id: Slow_clock.outFreq, value: 37.5 MHz} - {id: System_clock.outFreq, value: 150 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: PLL0_Mode, value: Normal} - {id: RunPowerMode, value: OD} - {id: SCGMode, value: PLL0} - {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} - {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} - {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} - {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} - {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL150M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL150M configuration ******************************************************************************/ void BOARD_BootClockPLL150M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ /*!< Set up PLL0 */ const pll_setup_t pll0Setup = { .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), .pllndiv = SCG_APLLNDIV_NDIV(8U), .pllpdiv = SCG_APLLPDIV_PDIV(1U), .pllmdiv = SCG_APLLMDIV_MDIV(50U), .pllRate = 150000000U }; CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; } /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!Configuration name: BOARD_BootClockPLL100M outputs: - {id: CLK_144M_clock.outFreq, value: 144 MHz} - {id: CLK_48M_clock.outFreq, value: 48 MHz} - {id: CLK_IN_clock.outFreq, value: 24 MHz} - {id: FRO_12M_clock.outFreq, value: 12 MHz} - {id: MAIN_clock.outFreq, value: 100 MHz} - {id: PLL1_CLK_clock.outFreq, value: 100 MHz} - {id: Slow_clock.outFreq, value: 25 MHz} - {id: System_clock.outFreq, value: 100 MHz} - {id: gdet_clock.outFreq, value: 48 MHz} - {id: trng_clock.outFreq, value: 48 MHz} settings: - {id: PLL1_Mode, value: Normal} - {id: SCGMode, value: PLL1} - {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} - {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} - {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} - {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} - {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} - {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} - {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} - {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} sources: - {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Variables for BOARD_BootClockPLL100M configuration ******************************************************************************/ /******************************************************************************* * Code for BOARD_BootClockPLL100M configuration ******************************************************************************/ void BOARD_BootClockPLL100M(void) { /*!< Enable SCG clock */ CLOCK_EnableClock(kCLOCK_Scg); CLOCK_SetupExtClocking(24000000U); CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ /*!< Set up PLL1 */ const pll_setup_t pll1Setup = { .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), .pllndiv = SCG_SPLLNDIV_NDIV(6U), .pllpdiv = SCG_SPLLPDIV_PDIV(2U), .pllmdiv = SCG_SPLLMDIV_MDIV(100U), .pllRate = 100000000U }; CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ /*!< Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ /*!< Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ /* Set SystemCoreClock variable */ SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; } ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/clock_config.h ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ #define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockFRO12M ********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFRO12M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ #define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFRO12M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFRO12M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF48M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF48M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ #define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFROHF48M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF48M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************* Configuration BOARD_BootClockFROHF144M ******************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockFROHF144M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ #define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockFROHF144M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockFROHF144M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL150M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL150M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ #define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockPLL150M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL150M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ******************** Configuration BOARD_BootClockPLL100M ********************* ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockPLL100M configuration ******************************************************************************/ #define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ #define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ /******************************************************************************* * API for BOARD_BootClockPLL100M configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockPLL100M(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/pin_mux.c ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v12.0 processor: MCXN947 package_id: MCXN947VDF mcu_data: ksdk2_0 processor_version: 0.12.3 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_port.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} - pin_list: - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, invert_input: normal} - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} - {pin_num: F14, peripheral: GPIO3, signal: 'GPIO, 4', pin_signal: PIO3_4/FC7_P2/CT_INP18/PWM0_X2/FLEXIO0_D12/SIM1_CLK, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { /* Enables the clock for PORT1: Enables clock */ CLOCK_EnableClock(kCLOCK_Port1); /* Enables the clock for PORT3: Enables clock */ CLOCK_EnableClock(kCLOCK_Port3); const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as FC4_P0 */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT1_8 (pin A1) is configured as FC4_P0 */ PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as FC4_P1 */ kPORT_MuxAlt2, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT1_9 (pin B1) is configured as FC4_P1 */ PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); const port_pin_config_t port3_4_pinF14_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Pin is configured as PIO3_4 */ kPORT_MuxAlt0, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT3_4 (pin F14) is configured as PIO3_4 */ PORT_SetPinConfig(PORT3, 4U, &port3_4_pinF14_config); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/boards/mcxn947brk/pin_mux.h ================================================ /* * Copyright 2022 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitPins(void); #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/mcx/debug.jlinkscript ================================================ int SetupTarget(void) { JLINK_ExecCommand("SetRTTSearchRanges 0x20000000 0x40000"); return 0; } ================================================ FILE: hw/bsp/mcx/drivers/spc/fsl_spc.c ================================================ /* * Copyright 2022-2024 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_spc.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.mcx_spc" #endif /* * $Coverage Justification Reference$ * * $Justification spc_c_ref_1$ * The SPC busy status flag is too short to get coverage data. */ /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* * Code ******************************************************************************/ /*! * brief Gets selected power domain's requested low power mode. * * param base SPC peripheral base address. * param powerDomainId Power Domain Id, please refer to spc_power_domain_id_t. * * return The selected power domain's requested low power mode, please refer to spc_power_domain_low_power_mode_t. */ spc_power_domain_low_power_mode_t SPC_GetPowerDomainLowPowerMode(SPC_Type *base, spc_power_domain_id_t powerDomainId) { assert((uint8_t)powerDomainId < SPC_PD_STATUS_COUNT); uint32_t val; val = ((base->PD_STATUS[(uint8_t)powerDomainId] & SPC_PD_STATUS_LP_MODE_MASK) >> SPC_PD_STATUS_LP_MODE_SHIFT); return (spc_power_domain_low_power_mode_t)val; } /*! * brief Gets Isolation status for each power domains. * * This function gets the status which indicates whether certain * peripheral and the IO pads are in a latched state as a result * of having been in POWERDOWN mode. * * param base SPC peripheral base address. * return Current isolation status for each power domains. */ uint8_t SPC_GetPeriphIOIsolationStatus(SPC_Type *base) { uint32_t reg; reg = base->SC; return (uint8_t)((reg & SPC_SC_ISO_CLR_MASK) >> SPC_SC_ISO_CLR_SHIFT); } /*! * brief Configs Low power request output pin. * * This function configs the low power request output pin * * param base SPC peripheral base address. * param config Pointer the spc_LowPower_Request_config_t structure. */ void SPC_SetLowPowerRequestConfig(SPC_Type *base, const spc_lowpower_request_config_t *config) { assert(config != NULL); uint32_t reg; reg = base->LPREQ_CFG; reg &= ~(SPC_LPREQ_CFG_LPREQOE_MASK | SPC_LPREQ_CFG_LPREQPOL_MASK | SPC_LPREQ_CFG_LPREQOV_MASK); if (config->enable) { reg |= SPC_LPREQ_CFG_LPREQOE_MASK | SPC_LPREQ_CFG_LPREQPOL((uint8_t)(config->polarity)) | SPC_LPREQ_CFG_LPREQOV((uint8_t)(config->override)); } else { reg &= ~SPC_LPREQ_CFG_LPREQOE_MASK; } base->LPREQ_CFG = reg; } #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * brief Configures VDD Core Glitch detector, including ripple counter selection, timeout value and so on. * * param base SPC peripheral base address. * param config Pointer to the structure in type of spc_vdd_core_glitch_detector_config_t. */ void SPC_ConfigVddCoreGlitchDetector(SPC_Type *base, const spc_vdd_core_glitch_detector_config_t *config) { assert(config != NULL); uint32_t reg; reg = (base->VDD_CORE_GLITCH_DETECT_SC) & ~(SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT_MASK | SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT_MASK | SPC_VDD_CORE_GLITCH_DETECT_SC_RE_MASK | SPC_VDD_CORE_GLITCH_DETECT_SC_IE_MASK); reg |= SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT(config->rippleCounterSelect) | SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT(config->resetTimeoutValue) | SPC_VDD_CORE_GLITCH_DETECT_SC_RE(config->enableReset) | SPC_VDD_CORE_GLITCH_DETECT_SC_IE(config->enableInterrupt); base->VDD_CORE_GLITCH_DETECT_SC = reg; } #endif /*! * brief Set SRAM operate voltage. * * param base SPC peripheral base address. * param config The pointer to spc_sram_voltage_config_t, specifies the configuration of sram voltage. */ void SPC_SetSRAMOperateVoltage(SPC_Type *base, const spc_sram_voltage_config_t *config) { assert(config != NULL); uint32_t reg = 0UL; reg |= SPC_SRAMCTL_VSM(config->operateVoltage); base->SRAMCTL = reg; if (config->requestVoltageUpdate) { base->SRAMCTL |= SPC_SRAMCTL_REQ_MASK; while ((base->SRAMCTL & SPC_SRAMCTL_ACK_MASK) == 0UL) { /* Wait until acknowledged */ ; } base->SRAMCTL &= ~SPC_SRAMCTL_REQ_MASK; } } /*! * brief Configs Bandgap mode in Active mode. * * @note To disable bandgap in Active mode: * 1. Disable all LVD's and HVD's in active mode; * 2. Disable Glitch detect; * 3. Configure LDO's and DCDC to low drive strength in active mode; * 4. Invoke this function to disable bandgap in active mode; * otherwise the error status will be reported. * * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please * take care of other system resources. * * param base SPC peripheral base address. * param mode The Bandgap mode be selected. * * retval kStatus_SPC_BandgapModeWrong The Bandgap can not be disabled in active mode. * retval kStatus_Success Config Bandgap mode in Active power mode successful. */ status_t SPC_SetActiveModeBandgapModeConfig(SPC_Type *base, spc_bandgap_mode_t mode) { uint32_t reg; uint32_t state; reg = base->ACTIVE_CFG; if (mode == kSPC_BandgapDisabled) { state = SPC_GetActiveModeVoltageDetectStatus(base); /* If any of the LVD/HVDs are kept enabled, bandgap mode must be enabled with buffer disabled. */ if (state != 0UL) { return kStatus_SPC_BandgapModeWrong; } /* The bandgap mode must be enabled if any regulators' drive strength set as Normal. */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK) == SPC_ACTIVE_CFG_SYSLDO_VDD_DS(kSPC_SysLDO_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_DCDC_VDD_DS_MASK) == SPC_ACTIVE_CFG_DCDC_VDD_DS(kSPC_DCDC_NormalVoltage)) { return kStatus_SPC_BandgapModeWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /* state of GLITCH_DETECT_DISABLE will be ignored if bandgap is disabled. */ if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL) { return kStatus_SPC_BandgapModeWrong; } #endif #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK) == SPC_ACTIVE_CFG_CORELDO_VDD_DS(kSPC_CoreLDO_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ } reg &= ~SPC_ACTIVE_CFG_BGMODE_MASK; reg |= SPC_ACTIVE_CFG_BGMODE(mode); base->ACTIVE_CFG = reg; return kStatus_Success; } /*! * brief Configs Bandgap mode in Low Power mode. * * @note To disable Bandgap in Low-power mode: * 1. Disable all LVD's ad HVD's in low power mode; * 2. Disable Glitch detect in low power mode; * 3. Configure LDO's and DCDC to low drive strength in low power mode; * 4. Disable bandgap in low power mode; * Otherwise, the error status will be reported. * * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please * take care of other system resources. * * param base SPC peripheral base address. * param mode The Bandgap mode be selected. * * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power mode is wrong. * retval kStatus_Success Config Bandgap mode in Low Power power mode successful. */ status_t SPC_SetLowPowerModeBandgapmodeConfig(SPC_Type *base, spc_bandgap_mode_t mode) { uint32_t reg; uint32_t state; reg = base->LP_CFG; if (mode == kSPC_BandgapDisabled) { state = (uint32_t)SPC_GetLowPowerModeVoltageDetectStatus(base); /* If any of the LVD/HVDs are kept enabled, bandgap mode must be enabled with buffer disabled. */ if (state != 0UL) { return kStatus_SPC_BandgapModeWrong; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) if ((base->LP_CFG & SPC_LP_CFG_DCDC_VDD_DS_MASK) == SPC_LP_CFG_DCDC_VDD_DS(kSPC_DCDC_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) if ((base->LP_CFG & SPC_LP_CFG_SYSLDO_VDD_DS_MASK) == SPC_LP_CFG_SYSLDO_VDD_DS(kSPC_SysLDO_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ if ((base->LP_CFG & SPC_LP_CFG_CORELDO_VDD_DS_MASK) == SPC_LP_CFG_CORELDO_VDD_DS(kSPC_CoreLDO_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /* state of GLITCH_DETECT_DISABLE will be ignored if bandgap is disabled. */ if ((base->LP_CFG & SPC_LP_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL) { return kStatus_SPC_BandgapModeWrong; } #endif } reg &= ~SPC_LP_CFG_BGMODE_MASK; reg |= SPC_LP_CFG_BGMODE(mode); base->LP_CFG = reg; return kStatus_Success; } /*! * brief Configs CORE voltage detect options. * * This function configs CORE voltage detect options. * Note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset only one is enabled. * * param base SPC peripheral base address. * param config Pointer to spc_core_voltage_detect_config_t structure. */ void SPC_SetCoreVoltageDetectConfig(SPC_Type *base, const spc_core_voltage_detect_config_t *config) { assert(config != NULL); uint32_t reg = 0UL; #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) reg |= (config->option.HVDInterruptEnable) ? SPC_VD_CORE_CFG_HVDIE(1U) : SPC_VD_CORE_CFG_HVDIE(0U); reg |= (config->option.HVDResetEnable) ? SPC_VD_CORE_CFG_HVDRE(1U) : SPC_VD_CORE_CFG_HVDRE(0U); #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ reg |= (config->option.LVDInterruptEnable) ? SPC_VD_CORE_CFG_LVDIE(1U) : SPC_VD_CORE_CFG_LVDIE(0U); reg |= (config->option.LVDResetEnable) ? SPC_VD_CORE_CFG_LVDRE(1U) : SPC_VD_CORE_CFG_LVDRE(0U); base->VD_CORE_CFG = reg; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) /*! * brief Enables the Core High Voltage Detector in Active mode. * * note If the CORE_LDO high voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low. * * param base SPC peripheral base address. * param enable Enable/Disable Core HVD. * true - Enable Core High voltage detector in active mode. * false - Disable Core High voltage detector in active mode. * * retval kStatus_Success Enable Core High Voltage Detect successfully. */ status_t SPC_EnableActiveModeCoreHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_CORE_HVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORE_HVDE_MASK; } return status; } /*! * brief Enables the Core High Voltage Detector in Low Power mode. * * note If the CORE_LDO high voltage detect is enabled in Low Power mode, * please note that the bandgap must be enabled and the drive strength of each regulator * must not set to low in low power mode. * * param base SPC peripheral base address. * param enable Enable/Disable Core HVD. * true - Enable Core High voltage detector in low power mode. * false - Disable Core High voltage detector in low power mode. * * retval kStatus_Success Enable Core High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeCoreHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_CORE_HVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_CORE_HVDE_MASK; } return status; } #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ /*! * brief Enables the Core VDD Low Voltage Detector in Active mode. * * note If the Core VDD high voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low. * * param base SPC peripheral base address. * param enable Enable/Disable Core LVD. * true - Enable Core Low voltage detector in active mode. * false - Disable Core Low voltage detector in active mode. * * retval kStatus_Success Enable Core Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeCoreLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_CORE_LVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORE_LVDE_MASK; } return status; } /*! * brief Enables the Core Low Voltage Detector in Low Power mode. * * note If the Core VDD low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * param base SPC peripheral base address. * param enable Enable/Disable Core HVD. * true - Enable Core Low voltage detector in low power mode. * false - Disable Core Low voltage detector in low power mode. * * retval kStatus_Success Enable Core Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeCoreLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_CORE_LVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_CORE_LVDE_MASK; } return status; } /*! * brief Set system VDD Low-voltage level selection. * * This function selects the system VDD low-voltage level. Changing system VDD low-voltage level * must be done after disabling the System VDD low voltage reset and interrupt. * * @deprecated In latest RM, reserved for all devices, will removed in next release. * * param base SPC peripheral base address. * param level System VDD Low-Voltage level selection. See @ref spc_low_voltage_level_select_t for details. */ void SPC_SetSystemVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level) { (void)level; (void)base; /* uint32_t reg; reg = base->VD_SYS_CFG; base->VD_SYS_CFG &= ~(SPC_VD_SYS_CFG_LVDRE_MASK | SPC_VD_SYS_CFG_LVDIE_MASK); reg |= SPC_VD_SYS_CFG_LVSEL(level); base->VD_SYS_CFG = reg; */ } /*! * brief Configs SYS VDD voltage detect options. * * This function config SYS voltage detect options. * Note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset only one is enabled. * * param base SPC peripheral base address. * param config Pointer to spc_system_voltage_detect_config_t structure. */ void SPC_SetSystemVoltageDetectConfig(SPC_Type *base, const spc_system_voltage_detect_config_t *config) { assert(config != NULL); uint32_t reg = 0UL; reg |= (config->option.HVDInterruptEnable) ? SPC_VD_SYS_CFG_HVDIE(1U) : SPC_VD_SYS_CFG_HVDIE(0U); reg |= (config->option.LVDInterruptEnable) ? SPC_VD_SYS_CFG_LVDIE(1U) : SPC_VD_SYS_CFG_LVDIE(0U); reg |= (config->option.HVDResetEnable) ? SPC_VD_SYS_CFG_HVDRE(1U) : SPC_VD_SYS_CFG_HVDRE(0U); reg |= (config->option.LVDResetEnable) ? SPC_VD_SYS_CFG_LVDRE(1U) : SPC_VD_SYS_CFG_LVDRE(0U); base->VD_SYS_CFG = reg; (void)(config->level); /* SPC_SetSystemVDDLowVoltageLevel(base, config->level); */ } /*! * brief Enables the System VDD High Voltage Detector in Active mode. * * note If the System_LDO high voltage detect is enabled in Active mode, * please note that the bandgap must be enabled and the drive strength of * each regulator must not set to low in Active mode. * * param base SPC peripheral base address. * param enable Enable/Disable System HVD. * true - Enable System High voltage detector in active mode. * false - Disable System High voltage detector in active mode. * * retval kStatus_Success Enable System High Voltage Detect successfully. */ status_t SPC_EnableActiveModeSystemHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_SYS_HVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_SYS_HVDE_MASK; } return status; } /*! * brief Enables the System VDD Low Voltage Detector in Active mode. * * note If the System_LDO low voltage detect is enabled in Active mode, * please note that the bandgap must be enabled and the drive strength of each * regulator must not set to low in Active mode. * * param base SPC peripheral base address. * param enable Enable/Disable System LVD. * true - Enable System Low voltage detector in active mode. * false - Disable System Low voltage detector in active mode. * * retval kStatus_Success Enable the System Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeSystemLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_SYS_LVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_SYS_LVDE_MASK; } return status; } /*! * brief Enables the System VDD High Voltage Detector in Low Power mode. * * note If the System_LDO high voltage detect is enabled in low power mode, * please note that the bandgap must be enabled and the drive strength of each * regulator must not set to low in low power mode. * * param base SPC peripheral base address. * param enable Enable/Disable System HVD. * true - Enable System High voltage detector in low power mode. * false - Disable System High voltage detector in low power mode. * * retval kStatus_Success Enable System High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeSystemHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_SYS_HVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_SYS_HVDE_MASK; } return status; } /*! * brief Enables the System VDD Low Voltage Detector in Low Power mode. * * note If the System_LDO low voltage detect is enabled in Low Power mode, * please note that the bandgap must be enabled and the drive strength of each * regulator must not set to low in Low Power mode. * * param base SPC peripheral base address. * param enable Enable/Disable System HVD. * true - Enable System Low voltage detector in low power mode. * false - Disable System Low voltage detector in low power mode. * * retval kStatus_Success Enable System Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeSystemLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_SYS_LVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_SYS_LVDE_MASK; } return status; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) /*! * brief Set IO VDD Low-Voltage level selection. * * This function selects the IO VDD Low-voltage level. Changing IO VDD low-voltage level * must be done after disabling the IO VDD low voltage reset and interrupt. * * param base SPC peripheral base address. * param level IO VDD Low-voltage level selection. */ void SPC_SetIOVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level) { uint32_t reg; reg = base->VD_IO_CFG; base->VD_IO_CFG &= ~(SPC_VD_IO_CFG_LVDRE_MASK | SPC_VD_IO_CFG_LVDIE_MASK | SPC_VD_IO_CFG_LVSEL_MASK); reg |= SPC_VD_IO_CFG_LVSEL(level); base->VD_IO_CFG = reg; } /*! * brief Configs IO VDD voltage detect options. * * This function config IO voltage detect options. * Note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset so only one is enabled. * * param base SPC peripheral base address. * param config Pointer to spc_IO_voltage_detect_config_t structure. */ void SPC_SetIOVoltageDetectConfig(SPC_Type *base, const spc_io_voltage_detect_config_t *config) { assert(config != NULL); uint32_t reg = 0UL; /* Set trip voltage level. */ SPC_SetIOVDDLowVoltageLevel(base, config->level); reg = base->VD_IO_CFG; reg &= ~(SPC_VD_IO_CFG_LVDRE_MASK | SPC_VD_IO_CFG_LVDIE_MASK | SPC_VD_IO_CFG_HVDRE_MASK | SPC_VD_IO_CFG_HVDIE_MASK); reg |= (config->option.HVDInterruptEnable) ? SPC_VD_IO_CFG_HVDIE(1U) : SPC_VD_IO_CFG_HVDIE(0U); reg |= (config->option.LVDInterruptEnable) ? SPC_VD_IO_CFG_LVDIE(1U) : SPC_VD_IO_CFG_LVDIE(0U); reg |= (config->option.HVDResetEnable) ? SPC_VD_IO_CFG_HVDRE(1U) : SPC_VD_IO_CFG_HVDRE(0U); reg |= (config->option.LVDResetEnable) ? SPC_VD_IO_CFG_LVDRE(1U) : SPC_VD_IO_CFG_LVDRE(0U); base->VD_IO_CFG = reg; } /*! * brief Enables the IO VDD High Voltage Detector in Active mode. * * note If the IO high voltage detect is enabled in Active mode, * please note that the bandgap must be enabled and the drive strength * of each regulator must not set to low in Active mode. * * param base SPC peripheral base address. * param enable Enable/Disable IO HVD. * true - Enable IO High voltage detector in active mode. * false - Disable IO High voltage detector in active mode. * * retval kStatus_Success Enable IO High Voltage Detect successfully. */ status_t SPC_EnableActiveModeIOHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_IO_HVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_IO_HVDE_MASK; } return status; } /*! * brief Enables the IO VDD Low Voltage Detector in Active mode. * * note If the IO low voltage detect is enabled in Active mode, * please note that the bandgap must be enabled and the drive strength * of each regulator must not set to low in Active mode. * * param base SPC peripheral base address. * param enable Enable/Disable IO LVD. * true - Enable IO Low voltage detector in active mode. * false - Disable IO Low voltage detector in active mode. * * retval kStatus_Success Enable IO Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeIOLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_IO_LVDE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_IO_LVDE_MASK; } return status; } /*! * brief Enables the IO VDD High Voltage Detector in Low Power mode. * * note If the IO high voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * param base SPC peripheral base address. * param enable Enable/Disable IO HVD. * true - Enable IO High voltage detector in low power mode. * false - Disable IO High voltage detector in low power mode. * * retval kStatus_Success Enable IO High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeIOHighVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_IO_HVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_IO_HVDE_MASK; } return status; } /*! * brief Enables the IO VDD Low Voltage Detector in Low Power mode. * * note If the IO low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * param base SPC peripheral base address. * param enable Enable/Disable IO HVD. * true - Enable IO Low voltage detector in low power mode. * false - Disable IO Low voltage detector in low power mode. * * retval kStatus_Success Enable IO Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeIOLowVoltageDetect(SPC_Type *base, bool enable) { status_t status = kStatus_Success; if (enable) { base->LP_CFG |= SPC_LP_CFG_IO_LVDE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_IO_LVDE_MASK; } return status; } #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ /*! * brief Configs external voltage domains * * This function configs external voltage domains isolation. * * param base SPC peripheral base address. * param lowPowerIsoMask The mask of external domains isolate enable during low power mode. * param IsoMask The mask of external domains isolate. */ void SPC_SetExternalVoltageDomainsConfig(SPC_Type *base, uint8_t lowPowerIsoMask, uint8_t IsoMask) { uint32_t reg = 0UL; reg |= SPC_EVD_CFG_REG_EVDISO(IsoMask) | SPC_EVD_CFG_REG_EVDLPISO(lowPowerIsoMask); base->EVD_CFG = reg; } /*! * brief Configs Core LDO Regulator in Active mode. * * @note The bandgap must be enabled before invoking this function. * @note To set Core LDO as low drive strength, all HVDs/LVDs must be disabled previously. * * param base SPC peripheral base address. * param option Pointer to the spc_active_mode_Core_LDO_option_t structure. * * retval kStatus_Success Config Core LDO regulator in Active power mode successful. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_BandgapModeWrong Bandgap should be enabled before invoking this function. * retval kStatus_SPC_CORELDOLowDriveStrengthIgnore To set Core LDO as low drive strength, * all LVDs/HVDs must be disabled before invoking this function. */ status_t SPC_SetActiveModeCoreLDORegulatorConfig(SPC_Type *base, const spc_active_mode_core_ldo_option_t *option) { assert(option != NULL); if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { return kStatus_SPC_Busy; } /* Check input parameters. */ /* 1. Bandgap must not be disabled. */ if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } /* 2. To set to low drive strength, all LVDs/HVDs must be disabled previously. */ if ((SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) && (option->CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength)) { return kStatus_SPC_CORELDOLowDriveStrengthIgnore; } if ((uint8_t)SPC_GetActiveModeCoreLDOVDDVoltageLevel(base) != (uint8_t)(option->CoreLDOVoltage)) { #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS (void)SPC_SetActiveModeCoreLDORegulatorDriveStrength(base, kSPC_CoreLDO_NormalDriveStrength); #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ (void)SPC_SetActiveModeCoreLDORegulatorVoltageLevel(base, option->CoreLDOVoltage); } #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS (void)SPC_SetActiveModeCoreLDORegulatorDriveStrength(base, option->CoreLDODriveStrength); #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ return kStatus_Success; } /*! * brief Set Core LDO VDD Regulator Voltage level in Active mode. * * @note In active mode, the Core LDO voltage level should only be changed when the * Core LDO is in normal drive strength. * * @note Update Core LDO voltage level will set Busy flag, * this function return only when busy flag is cleared by hardware * * param base SPC peripheral base address. * param voltageLevel Specify the voltage level of CORE LDO Regulator in Active mode, please refer to @ref spc_core_ldo_voltage_level_t. * * retval kStatus_SPC_CORELDOVoltageSetFail Core LDO voltage level should only be * changed when the CORE_LDO is in normal drive strength. * retval kStatus_Success Set Core LDO regulator voltage level in Active power mode successful. */ status_t SPC_SetActiveModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel) { if ((uint8_t)voltageLevel != (uint8_t)SPC_GetActiveModeCoreLDOVDDVoltageLevel(base)) { #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) if (SPC_GetActiveModeCoreLDODriveStrength(base) != kSPC_CoreLDO_NormalDriveStrength) { return kStatus_SPC_CORELDOVoltageSetFail; } #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ base->ACTIVE_CFG = ((base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_CORELDO_VDD_LVL_MASK) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(voltageLevel)); /* * $Branch Coverage Justification$ * $ref spc_c_ref_1$. */ while ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { } } return kStatus_Success; } #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS /*! * brief Set Core LDO VDD Regulator Drive Strength in Active mode. * * param base SPC peripheral base address. * param driveStrength Specify the drive strength of CORE LDO Regulator in Active mode, please refer to @ref spc_core_ldo_drive_strength_t. * * retval #kStatus_Success Set Core LDO regulator drive strength in Active power mode successful. * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore If any voltage detect enabled, core_ldo's drive strength can not set to low. * retval #kStatus_SPC_BandgapModeWrong The selected bandgap mode is not allowed. */ status_t SPC_SetActiveModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength) { if (driveStrength == kSPC_CoreLDO_LowDriveStrength) { /* If any voltage detect feature is enabled in Active mode, then CORE_LDO's drive strength must not set to low. */ if (SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) { return kStatus_SPC_CORELDOLowDriveStrengthIgnore; } } if (driveStrength == kSPC_CoreLDO_NormalDriveStrength) { /* If specify normal drive strength, bandgap must not be disabled. */ if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->ACTIVE_CFG = ((base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK) | SPC_ACTIVE_CFG_CORELDO_VDD_DS(driveStrength)); return kStatus_Success; } #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ /*! * brief Configs CORE LDO Regulator in low power mode * * This function configs CORE LDO Regulator in Low Power mode. * If CORE LDO VDD Drive Strength is set to Normal, the CORE LDO VDD regulator voltage * level in Active mode must be equal to the voltage level in Low power mode. And the Bandgap * must be programmed to select bandgap enabled. * Core VDD voltage levels for the Core LDO low power regulator can only be changed when the CORE * LDO Drive Strength is set as Normal. * * param base SPC peripheral base address. * param option Pointer to the spc_lowpower_mode_Core_LDO_option_t structure. * retval kStatus_Success Config Core LDO regulator in power mode successfully. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_CORELDOLowDriveStrengthIgnore HVDs/LVDs are not disabled before invoking this function. * retval kStatus_SPC_BandgapModeWrong The bandgap is not enabled before invoking this function. */ status_t SPC_SetLowPowerModeCoreLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_core_ldo_option_t *option) { status_t status = kStatus_Success; if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } status = SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(base, option->CoreLDODriveStrength); if (status == kStatus_Success) { (void)SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(base, option->CoreLDOVoltage); } return status; } /*! * brief Set Core LDO VDD Regulator Voltage level in Low power mode. * * @note If Core LDO's drive strengths are same in active and low power mode, the Core LDO's voltage must be set to the * same value in active and low power mode. Application should take care of this limitation. * * @note Some devices require Core LDO and DCDC have the same voltage level even if Core LDO is off. Application should * take care of this limitation. * * param base SPC peripheral base address. * param voltageLevel Voltage level of CORE LDO Regulator in Low power mode, please refer to @ref spc_core_ldo_voltage_level_t. * * retval #kStatus_SPC_Busy The SPC instance is busy to execute other operation. * retval #kStatus_Success Set Core LDO regulator voltage level in Low power mode successful. */ status_t SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel) { if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } base->LP_CFG = ((base->LP_CFG & ~SPC_LP_CFG_CORELDO_VDD_LVL_MASK) | SPC_LP_CFG_CORELDO_VDD_LVL(voltageLevel)); /* * $Branch Coverage Justification$ * $ref spc_c_ref_1$. */ while ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { } return kStatus_Success; } /*! * brief Set Core LDO VDD Regulator Drive Strength in Low power mode. * * param base SPC peripheral base address. * param driveStrength Specify drive strength of CORE LDO in low power mode. * * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Some voltage detect enabled, CORE LDO's drive strength can not set * as low. * retval #kStatus_Success Set Core LDO regulator drive strength in Low power mode successful. * retval #kStatus_SPC_BandgapModeWrong Bandgap is disabled when attempt to set CORE LDO work as normal drive strength. */ status_t SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength) { if (driveStrength == kSPC_CoreLDO_LowDriveStrength) { /* If any voltage detect feature is enabled in Low Power mode, then CORE_LDO's drive strength must not set to * low. */ if (SPC_GetLowPowerModeVoltageDetectStatus(base) != 0UL) { return kStatus_SPC_CORELDOLowDriveStrengthIgnore; } } else { /* To specify normal drive strength, the bandgap must be enabled in low power mode. */ if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->LP_CFG = ((base->LP_CFG & ~SPC_LP_CFG_CORELDO_VDD_DS_MASK) | SPC_LP_CFG_CORELDO_VDD_DS(driveStrength)); return kStatus_Success; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /*! * brief Configs System LDO VDD Regulator in Active mode. * * This function configs System LDO VDD Regulator in Active mode. * If System LDO VDD Drive Strength is set to Normal, the Bandgap mode in Active mode must be programmed * to a value that enable the bandgap. * If any voltage detects are kept enabled, configuration to set System LDO VDD drive strength to low will * be ignored. * If select System LDO VDD Regulator voltage level to Over Drive Voltage, the Drive Strength of System LDO VDD * Regulator must be set to Normal otherwise the regulator Drive Strength will be forced to Normal. * If select System LDO VDD Regulator voltage level to Over Drive Voltage, the High voltage detect must be disabled. * Otherwise it will be fail to regulator to Over Drive Voltage. * * param base SPC peripheral base address. * param option Pointer to the spc_active_mode_Sys_LDO_option_t structure. * retval kStatus_Success Config System LDO regulator in Active power mode successful. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_BandgapModeWrong The bandgap is not enabled before invoking this function. * retval kStatus_SPC_SYSLDOOverDriveVoltageFail HVD of System VDD is not disable before setting to Over Drive voltage. * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set System LDO VDD regulator's driver strength to Low will be * ignored. */ status_t SPC_SetActiveModeSystemLDORegulatorConfig(SPC_Type *base, const spc_active_mode_sys_ldo_option_t *option) { assert(option != NULL); if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } /* Check input parameters before setting registers. */ /* 1. To set to low DS, all LVDs/HVDs must be disabled previously. */ if ((SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) && (option->SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength)) { return kStatus_SPC_SYSLDOLowDriveStrengthIgnore; } /* 2. If specify normal drive strength, bandgap must not be disabled. */ if ((SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) && (option->SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength)) { return kStatus_SPC_BandgapModeWrong; } /* 3. Must disable system LDO high voltage detector before specifying overdrive voltage. */ if ((option->SysLDOVoltage == kSPC_SysLDO_OverDriveVoltage) && ((SPC_GetActiveModeVoltageDetectStatus(base) & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL)) { return kStatus_SPC_SYSLDOOverDriveVoltageFail; } (void)SPC_SetActiveModeSystemLDORegulatorDriveStrength(base, option->SysLDODriveStrength); (void)SPC_SetActiveModeSystemLDORegulatorVoltageLevel(base, option->SysLDOVoltage); return kStatus_Success; } /*! * brief Set System LDO Regulator voltage level in Active mode. * * @note The system LDO regulator can only operate at the overdrive voltage level for a limited amount of time for the * life of chip. * * param base SPC peripheral base address. * param voltageLevel Specify the voltage level of System LDO Regulator in Active mode. * * retval #kStatus_Success Set System LDO Regulator voltage level in Active mode successfully. * retval #kStatus_SPC_SYSLDOOverDriveVoltageFail Must disable system LDO high voltage detector before specifying * overdrive voltage. */ status_t SPC_SetActiveModeSystemLDORegulatorVoltageLevel(SPC_Type *base, spc_sys_ldo_voltage_level_t voltageLevel) { if (voltageLevel == kSPC_SysLDO_OverDriveVoltage) { /* Must disable system LDO high voltage detector before specifying overdrive voltage. */ if ((SPC_GetActiveModeVoltageDetectStatus(base) & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL) { return kStatus_SPC_SYSLDOOverDriveVoltageFail; } } base->ACTIVE_CFG = (base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_SYSLDO_VDD_LVL_MASK) | SPC_ACTIVE_CFG_SYSLDO_VDD_LVL(voltageLevel); return kStatus_Success; } /*! * brief Set System LDO Regulator Drive Strength in Active mode. * * param base SPC peripheral base address. * param driveStrength Specify the drive strength of System LDO Regulator in Active mode. * * retval #kStatus_Success Set System LDO Regulator drive strength in Active mode successfully. * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any voltage detect feature is enabled in active mode. * retval #kStatus_SPC_BandgapModeWrong Bandgap mode in Active mode must be programmed to a value that enables the bandgap if attempt to specify normal drive strength. */ status_t SPC_SetActiveModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength) { if (driveStrength == kSPC_SysLDO_LowDriveStrength) { /* If enabled any LVDs or HVDs, SPC will ignore the attempt to specify low drive strength. */ if (SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) { return kStatus_SPC_SYSLDOLowDriveStrengthIgnore; } } if (driveStrength == kSPC_SysLDO_NormalDriveStrength) { /* If specify normal drive strength, bandgap must not be disabled. */ if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->ACTIVE_CFG = (base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK) | SPC_ACTIVE_CFG_SYSLDO_VDD_DS(driveStrength); return kStatus_Success; } /*! * brief Configs System LDO regulator in low power modes. * * This function configs System LDO regulator in low power modes. * If System LDO VDD Regulator Drive strength is set to normal, bandgap mode in low power * mode must be programmed to a value that enables the Bandgap. * If any High voltage detectors or Low Voltage detectors are kept enabled, configuration * to set System LDO Regulator drive strength as Low will be ignored. * * param base SPC peripheral base address. * param option Pointer to spc_lowpower_mode_Sys_LDO_option_t structure. * * retval kStatus_Success Config System LDO regulator in Low Power Mode successfully. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power Mode is wrong. * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored. */ status_t SPC_SetLowPowerModeSystemLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_sys_ldo_option_t *option) { status_t status; if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } status = SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(base, option->SysLDODriveStrength); return status; } /*! * brief Set System LDO Regulator drive strength in Low Power Mode. * * param base SPC peripheral base address. * param driveStrength Specify the drive strength of System LDO Regulator in Low Power Mode. * * retval #kStatus_Success Set System LDO Regulator drive strength in Low Power Mode successfully. * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any voltage detect feature is enabled in low power mode. * retval #kStatus_SPC_BandgapModeWrong Bandgap mode in low power mode must be programmed to a value that enables the bandgap if attempt to specify normal drive strength. */ status_t SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength) { if (driveStrength == kSPC_SysLDO_LowDriveStrength) { /* If enabled any LVDs or HVDs, SPC will ignore the attempt to specify low drive strength. */ if (SPC_GetLowPowerModeVoltageDetectStatus(base) != 0UL) { return kStatus_SPC_SYSLDOLowDriveStrengthIgnore; } } else { /* If specify normal drive strength, bandgap must not be disabled. */ if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->LP_CFG = (base->LP_CFG & ~SPC_LP_CFG_SYSLDO_VDD_DS_MASK) | SPC_LP_CFG_SYSLDO_VDD_DS(driveStrength); return kStatus_Success; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /*! * brief Configs DCDC VDD Regulator in Active mode. * * note When changing the DCDC output voltage level, take care to change the CORE LDO voltage level. * * param base SPC peripheral base address. * param option Pointer to the spc_active_mode_DCDC_option_t structure. * * retval kStatus_Success Config DCDC regulator in Active power mode successful. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Active mode is wrong. */ status_t SPC_SetActiveModeDCDCRegulatorConfig(SPC_Type *base, const spc_active_mode_dcdc_option_t *option) { assert(option != NULL); status_t status = kStatus_Success; if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } status = SPC_SetActiveModeDCDCRegulatorDriveStrength(base, option->DCDCDriveStrength); if (status == kStatus_Success) { SPC_SetActiveModeDCDCRegulatorVoltageLevel(base, option->DCDCVoltage); } /* * $Branch Coverage Justification$ * $ref spc_c_ref_1$. */ while ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { } return status; } /*! * brief Set DCDC VDD Regulator drive strength in Active mode. * * note To set DCDC drive strength as Normal, the bandgap must be enabled. * * param base SPC peripheral base address. * param driveStrength Specify the DCDC VDD regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. * * retval #kStatus_Success Set DCDC VDD Regulator drive strength in Active mode successfully. * retval #kStatus_SPC_BandgapModeWrong Set DCDC VDD Regulator drive strength to Normal, the Bandgap must be enabled. */ status_t SPC_SetActiveModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength) { if (driveStrength == kSPC_DCDC_NormalDriveStrength) { /* If specify normal drive strength, bandgap must not be disabled. */ if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->ACTIVE_CFG = ((base->ACTIVE_CFG) & (~SPC_ACTIVE_CFG_DCDC_VDD_DS_MASK)) | SPC_ACTIVE_CFG_DCDC_VDD_DS(driveStrength); return kStatus_Success; } /*! * brief Configs DCDC VDD Regulator in Low power modes. * * If DCDC VDD Drive Strength is set to Normal, the Bandgap mode in Low Power mode must be programmed * to a value that enables the Bandgap. * In Deep Power Down mode, DCDC regulator is always turned off. * * param base SPC peripheral base address. * param option Pointer to the spc_lowpower_mode_DCDC_option_t structure. * * retval kStatus_Success Config DCDC regulator in low power mode successfully. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_BandgapModeWrong The bandgap should be enabled before invoking this function. */ status_t SPC_SetLowPowerModeDCDCRegulatorConfig(SPC_Type *base, const spc_lowpower_mode_dcdc_option_t *option) { if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { /* * $Line Coverage Justification$ * $ref spc_c_ref_1$. */ return kStatus_SPC_Busy; } /* Check input parameter before setting registers. */ if ((option->DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength) && (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled)) { return kStatus_SPC_BandgapModeWrong; } /* 1. Configure to desired voltage level. 2. Change to low drive strength. 3. Configure same voltage level in active mode. */ SPC_SetLowPowerModeDCDCRegulatorVoltageLevel(base, option->DCDCVoltage); /* Change to desired drive strength. */ if (option->DCDCDriveStrength != kSPC_DCDC_LowDriveStrength) { (void)SPC_SetLowPowerModeDCDCRegulatorDriveStrength(base, option->DCDCDriveStrength); } /* * $Branch Coverage Justification$ * $ref spc_c_ref_1$. */ while ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { } return kStatus_Success; } /*! * brief Set DCDC VDD Regulator drive strength in Low power mode. * * param base SPC peripheral base address. * param driveStrength Specify the DCDC VDD Regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. * * retval #kStatus_Success Set DCDC VDD Regulator drive strength in Low power mode successfully. * retval #kStatus_SPC_BandgapModeWrong Set DCDC VDD Regulator drive strength to Normal, the Bandgap must be enabled. */ status_t SPC_SetLowPowerModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength) { if (driveStrength == kSPC_DCDC_NormalDriveStrength) { /* If specify normal drive strength, bandgap must not be disabled. */ if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled) { return kStatus_SPC_BandgapModeWrong; } } base->LP_CFG = ((base->LP_CFG) & (~SPC_LP_CFG_DCDC_VDD_DS_MASK)) | SPC_LP_CFG_DCDC_VDD_DS(driveStrength); return kStatus_Success; } /*! * brief Config DCDC Burst options * * param base SPC peripheral base address. * param config Pointer to spc_DCDC_burst_config_t structure. */ void SPC_SetDCDCBurstConfig(SPC_Type *base, spc_dcdc_burst_config_t *config) { assert(config != NULL); uint32_t reg; reg = base->DCDC_CFG; reg &= ~(SPC_DCDC_CFG_FREQ_CNTRL_MASK | SPC_DCDC_CFG_FREQ_CNTRL_ON_MASK); reg |= SPC_DCDC_CFG_FREQ_CNTRL(config->freq); reg |= config->stabilizeBurstFreq ? SPC_DCDC_CFG_FREQ_CNTRL_ON(1U) : SPC_DCDC_CFG_FREQ_CNTRL_ON(0U); base->DCDC_CFG = reg; /* Blocking until previous DCDC burst completed. */ while ((base->DCDC_BURST_CFG & SPC_DCDC_BURST_CFG_BURST_ACK_MASK) == 0UL) { } if ((config->sofwareBurstRequest) || (config->externalBurstRequest)) { /* Clear DCDC burst acknowledge flag. */ base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_ACK_MASK; } base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_EXT_BURST_EN(config->externalBurstRequest); if (config->sofwareBurstRequest) { base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_REQ_MASK; } } /*! * brief Set the count value of the reference clock. * * This function set the count value of the reference clock to control the frequency * of dcdc refresh when dcdc is configured in Pulse Refresh mode. * * param base SPC peripheral base address. * param count The count value, 16 bit width. */ void SPC_SetDCDCRefreshCount(SPC_Type *base, uint16_t count) { uint32_t reg; reg = base->DCDC_BURST_CFG; reg &= ~SPC_DCDC_BURST_CFG_PULSE_REFRESH_CNT_MASK; reg |= SPC_DCDC_BURST_CFG_PULSE_REFRESH_CNT(count); base->DCDC_BURST_CFG = reg; } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ /*! * brief Configs all settings of regulators in Active mode at a time. * * @note This function is used to overwrite all settings of regulators(including bandgap mode, regulators' * drive strength and voltage level) in active mode at a time. * * @note Enable/disable LVDs/HVDs before invoking this function. * * @note This function will check input parameters based on hardware restrictions before setting registers, if input * parameters do not satisfy hardware restrictions the specific error will be reported. * * * @note Some hardware restrictions not covered, application should be aware of this and follow this hardware * restrictions otherwise some unknown issue may occur: * 1. If Core LDO's drive strength are set to same value in both Active mode and low power mode, * the voltage level should also set to same value. * 2. When switching Core LDO's drive strength from low to normal, ensure the LDO_CORE high voltage level is set * to same level that was set prior to switching to the LDO_CORE drive strength. Otherwise, if the LVDs are * enabled, an unexpected LVD can occur. * * @note If this function can not satisfy some tricky settings, please invoke other low-level functions. * * param base SPC peripheral base address. * param config Pointer to spc_active_mode_regulators_config_t structure. * retval kStatus_Success Config regulators in Active power mode successful. * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Active mode is wrong. * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * retval kStatus_SPC_CORELDOVoltageWrong The selected voltage level in active mode is not allowed. * retval kStatus_SPC_SYSLDOOverDriveVoltageFail Fail to regulator to Over Drive Voltage. * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to Low will be ignored. * retval kStatus_SPC_DCDCLowDriveStrengthIgnore Set driver strength to Low will be ignored. */ status_t SPC_SetActiveModeRegulatorsConfig(SPC_Type *base, const spc_active_mode_regulators_config_t *config) { assert(config != NULL); uint32_t activeModeVDValue = SPC_GetActiveModeVoltageDetectStatus(base); /* Check input parameters */ /* 1. Bandgap should not be disabled if any of regulator in normal drive strength or if any of LVDs/HVDs are enabled or if VDD CORE glitch detect are enabled. */ if ((config->bandgapMode == kSPC_BandgapDisabled) && ((activeModeVDValue != 0UL) #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) || (SPC_CheckActiveModeVddCoreGlitchDetectEnabled(base) == true) #endif /* FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) || (config->DCDCOption.DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength) #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) || (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength) #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) || (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_NormalDriveStrength) #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ )) { return kStatus_SPC_BandgapModeWrong; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /* 2. Must disable system LDO high voltage detector before specifying SysLDO to overdrive voltage */ if (((activeModeVDValue & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL) && (config->SysLDOOption.SysLDOVoltage == kSPC_SysLDO_OverDriveVoltage)) { return kStatus_SPC_SYSLDOOverDriveVoltageFail; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /* 3. To set System LDO's drive strength to low, all LVDs and HVDs must be disabled. */ if ((activeModeVDValue != 0UL) && (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength)) { return kStatus_SPC_SYSLDOLowDriveStrengthIgnore; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) /* 4. To set Core LDO's drive strength to low, all LVDs and HVDs must be disabled. */ if ((activeModeVDValue != 0UL) && (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength)) { return kStatus_SPC_CORELDOLowDriveStrengthIgnore; } #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /* 5. Core LDO and DCDC should have same voltage level. */ if ((uint8_t)config->DCDCOption.DCDCVoltage != (uint8_t)config->CoreLDOOption.CoreLDOVoltage) { return kStatus_SPC_CORELDOVoltageWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ if ((base->SC & SPC_SC_BUSY_MASK) != 0UL) { return kStatus_SPC_Busy; } base->ACTIVE_CFG = ((base->ACTIVE_CFG) & ~(SPC_ACTIVE_CFG_BGMODE_MASK)) | SPC_ACTIVE_CFG_BGMODE(config->bandgapMode); #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) SPC_EnableActiveModeCMPBandgapBuffer(base, config->lpBuff); #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) (void)SPC_SetActiveModeSystemLDORegulatorConfig(base, &config->SysLDOOption); #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) (void)SPC_SetActiveModeDCDCRegulatorConfig(base, &config->DCDCOption); #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ (void)SPC_SetActiveModeCoreLDORegulatorConfig(base, &config->CoreLDOOption); return kStatus_Success; } /*! * brief Configs regulators in Low Power mode. * * This function provides the method to config all on-chip regulators in Low Power mode. * * param base SPC peripheral base address. * param config Pointer to spc_lowpower_mode_regulators_config_t structure. * retval #kStatus_Success Config regulators in Low power mode successful. * retval #kStatus_SPC_BandgapModeWrong The bandgap should not be disabled based on input settings. * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Set driver strength to low will be ignored. * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored. * retval #kStatus_SPC_CORELDOVoltageWrong Core LDO and System LDO do not have same voltage level. */ status_t SPC_SetLowPowerModeRegulatorsConfig(SPC_Type *base, const spc_lowpower_mode_regulators_config_t *config) { assert(config != NULL); uint32_t lpModeVDValue = SPC_GetLowPowerModeVoltageDetectStatus(base); /* Check input parameters */ /* 1. Bandgap should not be disabled if any of regulator in normal drive strength or if any of LVDs/HVDs are enabled or if VDD CORE glitch detect are enabled. */ if ((config->bandgapMode == kSPC_BandgapDisabled) && ((lpModeVDValue != 0UL) #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) || (SPC_CheckLowPowerModeVddCoreGlitchDetectEnabled(base) == true) #endif /* FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) || (config->DCDCOption.DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength) #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) || (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength) #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) || (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_NormalDriveStrength) #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ )) { return kStatus_SPC_BandgapModeWrong; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /* 2. To set System LDO's drive strength to low, all LVDs and HVDs must be disabled. */ if ((lpModeVDValue != 0UL) && (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength)) { return kStatus_SPC_SYSLDOLowDriveStrengthIgnore; } #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) /* 3. To set Core LDO's drive strength to low, all LVDs and HVDs must be disabled. */ if ((lpModeVDValue != 0UL) && (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength)) { return kStatus_SPC_CORELDOLowDriveStrengthIgnore; } #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /* 5. Core LDO and DCDC should have same voltage level. */ if ((uint8_t)config->DCDCOption.DCDCVoltage != (uint8_t)config->CoreLDOOption.CoreLDOVoltage) { return kStatus_SPC_CORELDOVoltageWrong; } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ base->LP_CFG = ((base->LP_CFG) & ~(SPC_LP_CFG_BGMODE_MASK)) | SPC_LP_CFG_BGMODE(config->bandgapMode); #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) SPC_EnableLowPowerModeCMPBandgapBuffer(base, config->lpBuff); #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) SPC_EnableLowPowerModeCoreVDDInternalVoltageScaling(base, config->CoreIVS); #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT */ SPC_EnableLowPowerModeLowPowerIREF(base, config->lpIREF); #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) (void)SPC_SetLowPowerModeSystemLDORegulatorConfig(base, &config->SysLDOOption); #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) (void)SPC_SetLowPowerModeDCDCRegulatorConfig(base, &config->DCDCOption); #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ (void)SPC_SetLowPowerModeCoreLDORegulatorConfig(base, &config->CoreLDOOption); return kStatus_Success; } ================================================ FILE: hw/bsp/mcx/drivers/spc/fsl_spc.h ================================================ /* * Copyright 2022-2024 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef FSL_SPC_H_ #define FSL_SPC_H_ #include "fsl_common.h" /*! * @addtogroup mcx_spc * @{ */ /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*! @{ */ /*! @brief SPC driver version 2.4.2. */ #define FSL_SPC_DRIVER_VERSION (MAKE_VERSION(2, 4, 2)) /*! @} */ #define SPC_EVD_CFG_REG_EVDISO_SHIFT 0UL #define SPC_EVD_CFG_REG_EVDLPISO_SHIFT 8UL #define SPC_EVD_CFG_REG_EVDSTAT_SHIFT 16UL #define SPC_EVD_CFG_REG_EVDISO(x) ((uint32_t)(x) << SPC_EVD_CFG_REG_EVDISO_SHIFT) #define SPC_EVD_CFG_REG_EVDLPISO(x) ((uint32_t)(x) << SPC_EVD_CFG_REG_EVDLPISO_SHIFT) #define SPC_EVD_CFG_REG_EVDSTAT(x) ((uint32_t)(x) << SPC_EVD_CFG_REG_EVDSTAT_SHIFT) #if (defined(SPC_GLITCH_DETECT_SC_CNT_SELECT_MASK)) #define VDD_CORE_GLITCH_DETECT_SC GLITCH_DETECT_SC #define SPC_VDD_CORE_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG_MASK SPC_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG SPC_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG #define SPC_VDD_CORE_GLITCH_DETECT_SC_LOCK_MASK SPC_GLITCH_DETECT_SC_LOCK_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT_MASK SPC_GLITCH_DETECT_SC_CNT_SELECT_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT SPC_GLITCH_DETECT_SC_CNT_SELECT #define SPC_VDD_CORE_GLITCH_DETECT_SC_RE_MASK SPC_GLITCH_DETECT_SC_RE_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_RE SPC_GLITCH_DETECT_SC_RE #define SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT_MASK SPC_GLITCH_DETECT_SC_TIMEOUT_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT SPC_GLITCH_DETECT_SC_TIMEOUT #define SPC_VDD_CORE_GLITCH_DETECT_SC_IE_MASK SPC_GLITCH_DETECT_SC_IE_MASK #define SPC_VDD_CORE_GLITCH_DETECT_SC_IE SPC_GLITCH_DETECT_SC_IE #endif /*! * @brief SPC status enumeration. * * @note Some device(such as MCXA family) do not equip DCDC or System LDO, please refer to the reference manual * to check. */ enum { kStatus_SPC_Busy = MAKE_STATUS(kStatusGroup_SPC, 0U), /*!< The SPC instance is busy executing any type of power mode transition. */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) kStatus_SPC_DCDCLowDriveStrengthIgnore = MAKE_STATUS(kStatusGroup_SPC, 1U), /*!< DCDC Low drive strength setting be ignored for LVD/HVD enabled. */ kStatus_SPC_DCDCPulseRefreshModeIgnore = MAKE_STATUS(kStatusGroup_SPC, 2U), /*!< DCDC Pulse Refresh Mode drive strength setting be ignored for LVD/HVD enabled. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) kStatus_SPC_SYSLDOOverDriveVoltageFail = MAKE_STATUS(kStatusGroup_SPC, 3U), /*!< SYS LDO regulate to Over drive voltage failed for SYS LDO HVD must be disabled. */ kStatus_SPC_SYSLDOLowDriveStrengthIgnore = MAKE_STATUS(kStatusGroup_SPC, 4U), /*!< SYS LDO Low driver strength setting be ignored for LDO LVD/HVD enabled. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ kStatus_SPC_CORELDOLowDriveStrengthIgnore = MAKE_STATUS(kStatusGroup_SPC, 5U), /*!< CORE LDO Low driver strength setting be ignored for LDO LVD/HVD enabled. */ kStatus_SPC_CORELDOVoltageWrong = MAKE_STATUS(kStatusGroup_SPC, 7U), /*!< Core LDO voltage is wrong. */ kStatus_SPC_CORELDOVoltageSetFail = MAKE_STATUS(kStatusGroup_SPC, 8U), /*!< Core LDO voltage set fail. */ kStatus_SPC_BandgapModeWrong = MAKE_STATUS(kStatusGroup_SPC, 6U), /*!< Selected Bandgap Mode wrong. */ }; /*! * @brief Voltage Detect Status Flags. */ enum _spc_voltage_detect_flags { #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) kSPC_IOVDDHighVoltageDetectFlag = SPC_VD_STAT_IOVDD_HVDF_MASK, /*!< IO VDD High-Voltage detect flag. */ kSPC_IOVDDLowVoltageDetectFlag = SPC_VD_STAT_IOVDD_LVDF_MASK, /*!< IO VDD Low-Voltage detect flag. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ kSPC_SystemVDDHighVoltageDetectFlag = SPC_VD_STAT_SYSVDD_HVDF_MASK, /*!< System VDD High-Voltage detect flag. */ kSPC_SystemVDDLowVoltageDetectFlag = SPC_VD_STAT_SYSVDD_LVDF_MASK, /*!< System VDD Low-Voltage detect flag. */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) kSPC_CoreVDDHighVoltageDetectFlag = SPC_VD_STAT_COREVDD_HVDF_MASK, /*!< Core VDD High-Voltage detect flag. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ kSPC_CoreVDDLowVoltageDetectFlag = SPC_VD_STAT_COREVDD_LVDF_MASK, /*!< Core VDD Low-Voltage detect flag. */ }; /*! * @brief SPC power domain isolation status. * @note Some devices(such as MCXA family) do not contain WAKE Power Domain, please refer to the reference manual to * check. */ enum _spc_power_domains { kSPC_MAINPowerDomainRetain = 1UL << 16U, /*!< Peripherals and IO pads retain in MAIN Power Domain. */ kSPC_WAKEPowerDomainRetain = 1UL << 17U, /*!< Peripherals and IO pads retain in WAKE Power Domain. */ }; /*! * @brief The enumeration of all analog module that can be controlled by SPC in active or low-power modes. * @anchor spc_analog_module_control */ enum _spc_analog_module_control { kSPC_controlVref = 1UL << 0UL, /*!< Enable/disable VREF in active or low-power modes. */ kSPC_controlUsb3vDet = 1UL << 1UL, /*!< Enable/disable USB3V_Det in active or low-power modes. */ kSPC_controlDac0 = 1UL << 4UL, /*!< Enable/disable DAC0 in active or low-power modes. */ kSPC_controlDac1 = 1UL << 5UL, /*!< Enable/disable DAC1 in active or low-power modes. */ kSPC_controlDac2 = 1UL << 6UL, /*!< Enable/disable DAC2 in active or low-power modes. */ kSPC_controlOpamp0 = 1UL << 8UL, /*!< Enable/disable OPAMP0 in active or low-power modes. */ kSPC_controlOpamp1 = 1UL << 9UL, /*!< Enable/disable OPAMP1 in active or low-power modes. */ kSPC_controlOpamp2 = 1UL << 10UL, /*!< Enable/disable OPAMP2 in active or low-power modes. */ kSPC_controlCmp0 = 1UL << 16UL, /*!< Enable/disable CMP0 in active or low-power modes. */ kSPC_controlCmp1 = 1UL << 17UL, /*!< Enable/disable CMP1 in active or low-power modes. */ kSPC_controlCmp2 = 1UL << 18UL, /*!< Enable/disable CMP2 in active or low-power modes. */ kSPC_controlCmp0Dac = 1UL << 20UL, /*!< Enable/disable CMP0_DAC in active or low-power modes. */ kSPC_controlCmp1Dac = 1UL << 21UL, /*!< Enable/disable CMP1_DAC in active or low-power modes. */ kSPC_controlCmp2Dac = 1UL << 22UL, /*!< Enable/disable CMP2_DAC in active or low-power modes. */ kSPC_controlAllModules = 0x770773UL, /*!< Enable/disable all modules in active or low-power modes. */ }; /*! * @brief The enumeration of spc power domain, the connected power domain is chip specific, please refer to chip's RM * for details. */ typedef enum _spc_power_domain_id { kSPC_PowerDomain0 = 0U, /*!< Power domain0, the connected power domain is chip specific. */ kSPC_PowerDomain1 = 1U, /*!< Power domain1, the connected power domain is chip specific. */ } spc_power_domain_id_t; /*! * @brief The enumeration of Power domain's low power mode. */ typedef enum _spc_power_domain_low_power_mode { kSPC_SleepWithSYSClockRunning = 0U, /*!< Power domain request SLEEP mode with SYS clock running. */ kSPC_DeepSleepWithSysClockOff = 1U, /*!< Power domain request deep sleep mode with system clock off. */ kSPC_PowerDownWithSysClockOff = 2U, /*!< Power domain request power down mode with system clock off. */ kSPC_DeepPowerDownWithSysClockOff = 4U, /*!< Power domain request deep power down mode with system clock off. */ } spc_power_domain_low_power_mode_t; /*! * @brief SPC low power request output pin polarity. */ typedef enum _spc_lowPower_request_pin_polarity { kSPC_HighTruePolarity = 0x0U, /*!< Control the High Polarity of the Low Power Request Pin. */ kSPC_LowTruePolarity = 0x1U, /*!< Control the Low Polarity of the Low Power Request Pin. */ } spc_lowpower_request_pin_polarity_t; /*! * @brief SPC low power request output override. */ typedef enum _spc_lowPower_request_output_override { kSPC_LowPowerRequestNotForced = 0x0U, /*!< Not Forced. */ kSPC_LowPowerRequestReserved = 0x1U, /*!< Reserved. */ kSPC_LowPowerRequestForcedLow = 0x2U, /*!< Forced Low (Ignore LowPower request output polarity setting.) */ kSPC_LowPowerRequestForcedHigh = 0x3U, /*!< Forced High (Ignore LowPower request output polarity setting.) */ } spc_lowpower_request_output_override_t; /*! * @brief SPC Bandgap mode enumeration in Active mode or Low Power mode. */ typedef enum _spc_bandgap_mode { kSPC_BandgapDisabled = 0x0U, /*!< Bandgap disabled. */ kSPC_BandgapEnabledBufferDisabled = 0x1U, /*!< Bandgap enabled with Buffer disabled. */ kSPC_BandgapEnabledBufferEnabled = 0x2U, /*!< Bandgap enabled with Buffer enabled. */ kSPC_BandgapReserved = 0x3U, /*!< Reserved. */ } spc_bandgap_mode_t; #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /*! * @brief DCDC regulator voltage level enumeration in Active mode or Low Power Mode. * * @note #kSPC_DCDC_RetentionVoltage not supported for all power modes. */ typedef enum _spc_dcdc_voltage_level { kSPC_DCDC_RetentionVoltage = 0x0U, /*!< DCDC_CORE Regulator regulate to retention Voltage(Only supportedin low power modes) */ kSPC_DCDC_MidVoltage = 0x1U, /*!< DCDC_CORE Regulator regulate to Mid Voltage(1.0V). */ kSPC_DCDC_NormalVoltage = 0x2U, /*!< DCDC_CORE Regulator regulate to Normal Voltage(1.1V). */ kSPC_DCDC_OverdriveVoltage = 0x3U, /*!< DCDC_CORE Regulator regulate to Safe-Mode Voltage(1.2V). */ } spc_dcdc_voltage_level_t; /*! * @brief DCDC regulator Drive Strength enumeration in Active mode or Low Power Mode. * * @note Different drive strength differ in these DCDC characteristics: * Maximum load current * Quiescent current * Transient response. */ typedef enum _spc_dcdc_drive_strength { kSPC_DCDC_PulseRefreshMode = 0x0U, /*!< DCDC_CORE Regulator Drive Strength set to Pulse Refresh Mode, * This enum member is only useful for Low Power Mode config, please * note that pulse refresh mode is invalid in SLEEP mode. */ kSPC_DCDC_LowDriveStrength = 0x1U, /*!< DCDC_CORE regulator Drive Strength set to low. */ kSPC_DCDC_NormalDriveStrength = 0x2U, /*!< DCDC_CORE regulator Drive Strength set to Normal. */ } spc_dcdc_drive_strength_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /*! * @brief SYS LDO regulator voltage level enumeration in Active mode. */ typedef enum _spc_sys_ldo_voltage_level { kSPC_SysLDO_NormalVoltage = 0x0U, /*!< SYS LDO VDD Regulator regulate to Normal Voltage(1.8V). */ kSPC_SysLDO_OverDriveVoltage = 0x1U, /*!< SYS LDO VDD Regulator regulate to Over Drive Voltage(2.5V). */ } spc_sys_ldo_voltage_level_t; /*! * @brief SYS LDO regulator Drive Strength enumeration in Active mode or Low Power mode. */ typedef enum _spc_sys_ldo_drive_strength { kSPC_SysLDO_LowDriveStrength = 0x0U, /*!< SYS LDO VDD regulator Drive Strength set to low. */ kSPC_SysLDO_NormalDriveStrength = 0x1U, /*!< SYS LDO VDD regulator Drive Strength set to Normal. */ } spc_sys_ldo_drive_strength_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ /*! * @brief Core LDO regulator voltage level enumeration in Active mode or Low Power mode. */ typedef enum _spc_core_ldo_voltage_level { kSPC_CoreLDO_UnderDriveVoltage = 0x0U, /*!< @deprecated, to align with description of latest RM, please use #kSPC_Core_LDO_RetentionVoltage as instead. */ kSPC_Core_LDO_RetentionVoltage = 0x0U, /*!< Core LDO VDD regulator regulate to retention voltage, please note that only useful in low power modes and not all devices support this options please refer to devices' RM for details. */ kSPC_CoreLDO_MidDriveVoltage = 0x1U, /*!< Core LDO VDD regulator regulate to Mid Drive Voltage. */ kSPC_CoreLDO_NormalVoltage = 0x2U, /*!< Core LDO VDD regulator regulate to Normal Voltage. */ kSPC_CoreLDO_OverDriveVoltage = 0x3U, /*!< Core LDO VDD regulator regulate to overdrive Voltage. */ } spc_core_ldo_voltage_level_t; /*! * @brief CORE LDO VDD regulator Drive Strength enumeration in Low Power mode. */ typedef enum _spc_core_ldo_drive_strength { kSPC_CoreLDO_LowDriveStrength = 0x0U, /*!< Core LDO VDD regulator Drive Strength set to low. */ kSPC_CoreLDO_NormalDriveStrength = 0x1U, /*!< Core LDO VDD regulator Drive Strength set to Normal. */ } spc_core_ldo_drive_strength_t; /*! * @brief IO VDD Low-Voltage Level Select. */ typedef enum _spc_low_voltage_level_select { kSPC_LowVoltageNormalLevel = 0x0U, /*!< @deprecated, please use kSPC_LowVoltageHighRange as instead. */ kSPC_LowVoltageSafeLevel = 0x1U, /*!< @deprecated, please use kSPC_LowVoltageLowRange as instead. */ kSPC_LowVoltageHighRange = 0x0U, /*!< High range LVD threshold. */ kSPC_LowVoltageLowRange = 0x1U, /*!< Low range LVD threshold. */ } spc_low_voltage_level_select_t; #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * @brief Used to select output of 4-bit ripple counter is used to monitor a glitch on VDD core. */ typedef enum _spc_vdd_core_glitch_ripple_counter_select { kSPC_selectBit0Of4bitRippleCounter = 0x0U, /*!< Select bit-0 of 4-bit Ripple Counter to detect glitch on VDD Core. */ kSPC_selectBit1Of4bitRippleCounter = 0x1U, /*!< Select bit-1 of 4-bit Ripple Counter to detect glitch on VDD Core. */ kSPC_selectBit2Of4bitRippleCounter = 0x2U, /*!< Select bit-2 of 4-bit Ripple Counter to detect glitch on VDD Core. */ kSPC_selectBit3Of4bitRippleCounter = 0x3U, /*!< Select bit-3 of 4-bit Ripple Counter to detect glitch on VDD Core. */ } spc_vdd_core_glitch_ripple_counter_select_t; #endif /*! * @brief The list of the operating voltage for the SRAM's read/write timing margin. */ typedef enum _spc_sram_operate_voltage { kSPC_sramOperateAt1P0V = 0x1U, /*!< SRAM configured for 1.0V operation. */ kSPC_sramOperateAt1P1V = 0x2U, /*!< SRAM configured for 1.1V operation. */ kSPC_sramOperateAt1P2V = 0x3U, /*!< SRAM configured for 1.2V operation. */ } spc_sram_operate_voltage_t; #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * @brief The configuration of VDD Core glitch detector. */ typedef struct _spc_vdd_core_glitch_detector_config { spc_vdd_core_glitch_ripple_counter_select_t rippleCounterSelect; /*!< Used to set ripple counter. */ uint8_t resetTimeoutValue; /*!< The timeout value used to reset glitch detect/compare logic after an initial glitch is detected. */ bool enableReset; /*!< Used to enable/disable POR/LVD reset that caused by CORE VDD glitch detect error. */ bool enableInterrupt; /*!< Used to enable/disable hardware interrupt if CORE VDD glitch detect error. */ } spc_vdd_core_glitch_detector_config_t; #endif typedef struct _spc_sram_voltage_config { spc_sram_operate_voltage_t operateVoltage; /*!< Specifies the operating voltage for the SRAM's read/write timing margin. */ bool requestVoltageUpdate; /*!< Used to control whether request an SRAM trim value change. */ } spc_sram_voltage_config_t; /*! * @brief Low Power Request output pin configuration. */ typedef struct _spc_lowpower_request_config { bool enable; /*!< Low Power Request Output enable. */ spc_lowpower_request_pin_polarity_t polarity; /*!< Low Power Request Output pin polarity select. */ spc_lowpower_request_output_override_t override; /*!< Low Power Request Output Override. */ } spc_lowpower_request_config_t; /*! * @brief Core LDO regulator options in Active mode. */ typedef struct _spc_active_mode_core_ldo_option { spc_core_ldo_voltage_level_t CoreLDOVoltage; /*!< Core LDO Regulator Voltage Level selection in Active mode. */ #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS spc_core_ldo_drive_strength_t CoreLDODriveStrength; /*!< Core LDO Regulator Drive Strength selection in Active mode */ #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ } spc_active_mode_core_ldo_option_t; #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /*! * @brief System LDO regulator options in Active mode. */ typedef struct _spc_active_mode_sys_ldo_option { spc_sys_ldo_voltage_level_t SysLDOVoltage; /*!< System LDO Regulator Voltage Level selection in Active mode. */ spc_sys_ldo_drive_strength_t SysLDODriveStrength; /*!< System LDO Regulator Drive Strength selection in Active mode. */ } spc_active_mode_sys_ldo_option_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /*! * @brief DCDC regulator options in Active mode. */ typedef struct _spc_active_mode_dcdc_option { spc_dcdc_voltage_level_t DCDCVoltage; /*!< DCDC Regulator Voltage Level selection in Active mode. */ spc_dcdc_drive_strength_t DCDCDriveStrength; /*!< DCDC_CORE Regulator Drive Strength selection in Active mode. */ } spc_active_mode_dcdc_option_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ /*! * @brief Core LDO regulator options in Low Power mode. */ typedef struct _spc_lowpower_mode_core_ldo_option { spc_core_ldo_voltage_level_t CoreLDOVoltage; /*!< Core LDO Regulator Voltage Level selection in Low Power mode. */ spc_core_ldo_drive_strength_t CoreLDODriveStrength; /*!< Core LDO Regulator Drive Strength selection in Low Power mode */ } spc_lowpower_mode_core_ldo_option_t; #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /*! * @brief System LDO regulator options in Low Power mode. */ typedef struct _spc_lowpower_mode_sys_ldo_option { spc_sys_ldo_drive_strength_t SysLDODriveStrength; /*!< System LDO Regulator Drive Strength selection in Low Power mode. */ } spc_lowpower_mode_sys_ldo_option_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /*! * @brief DCDC regulator options in Low Power mode. */ typedef struct _spc_lowpower_mode_dcdc_option { spc_dcdc_voltage_level_t DCDCVoltage; /*!< DCDC Regulator Voltage Level selection in Low Power mode. */ spc_dcdc_drive_strength_t DCDCDriveStrength; /*!< DCDC_CORE Regulator Drive Strength selection in Low Power mode. */ } spc_lowpower_mode_dcdc_option_t; /*! * @brief DCDC Burst configuration. * @deprecated Do not recommend to use this structure. */ typedef struct _spc_dcdc_burst_config { bool sofwareBurstRequest; /*!< Enable/Disable DCDC Software Burst Request. */ bool externalBurstRequest; /*!< Enable/Disable DCDC External Burst Request. */ bool stabilizeBurstFreq; /*!< Enable/Disable DCDC frequency stabilization. */ uint8_t freq; /*!< The frequency of the current burst. */ } spc_dcdc_burst_config_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ /*! * @brief CORE/SYS/IO VDD Voltage Detect options. */ typedef struct _spc_voltage_detect_option { bool HVDInterruptEnable; /*!< CORE/SYS/IO VDD High Voltage Detect interrupt enable. */ bool HVDResetEnable; /*!< CORE/SYS/IO VDD High Voltage Detect reset enable. */ bool LVDInterruptEnable; /*!< CORE/SYS/IO VDD Low Voltage Detect interrupt enable. */ bool LVDResetEnable; /*!< CORE/SYS/IO VDD Low Voltage Detect reset enable. */ } spc_voltage_detect_option_t; /*! * @brief Core Voltage Detect configuration. */ typedef struct _spc_core_voltage_detect_config { spc_voltage_detect_option_t option; /*!< Core VDD Voltage Detect option. */ } spc_core_voltage_detect_config_t; /*! * @brief System Voltage Detect Configuration. */ typedef struct _spc_system_voltage_detect_config { spc_voltage_detect_option_t option; /*!< System VDD Voltage Detect option. */ spc_low_voltage_level_select_t level; /*!< @deprecated, reserved for all devices, will removed in next release. */ } spc_system_voltage_detect_config_t; #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) /*! * @brief IO Voltage Detect Configuration. */ typedef struct _spc_io_voltage_detect_config { spc_voltage_detect_option_t option; /*!< IO VDD Voltage Detect option. */ spc_low_voltage_level_select_t level; /*!< IO VDD Low-voltage level selection. */ } spc_io_voltage_detect_config_t; #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ /*! * @brief Active mode configuration. */ typedef struct _spc_active_mode_regulators_config { spc_bandgap_mode_t bandgapMode; /*!< Specify bandgap mode in active mode. */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) bool lpBuff; /*!< Enable/disable CMP bandgap buffer. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) spc_active_mode_dcdc_option_t DCDCOption; /*!< Specify DCDC configurations in active mode. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) spc_active_mode_sys_ldo_option_t SysLDOOption; /*!< Specify System LDO configurations in active mode. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ spc_active_mode_core_ldo_option_t CoreLDOOption; /*!< Specify Core LDO configurations in active mode. */ } spc_active_mode_regulators_config_t; /*! * @brief Low Power Mode configuration. */ typedef struct _spc_lowpower_mode_regulators_config { bool lpIREF; /*!< Enable/disable low power IREF in low power modes. */ spc_bandgap_mode_t bandgapMode; /*!< Specify bandgap mode in low power modes. */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) bool lpBuff; /*!< Enable/disable CMP bandgap buffer in low power modes. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) bool CoreIVS; /*!< Enable/disable CORE VDD internal voltage scaling. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) spc_lowpower_mode_dcdc_option_t DCDCOption; /*!< Specify DCDC configurations in low power modes. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) spc_lowpower_mode_sys_ldo_option_t SysLDOOption; /*!< Specify system LDO configurations in low power modes. */ #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ spc_lowpower_mode_core_ldo_option_t CoreLDOOption; /*!< Specify core LDO configurations in low power modes. */ } spc_lowpower_mode_regulators_config_t; /******************************************************************************* * API ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /*! * @name SPC Status * @{ */ /*! * @brief Gets Isolation status for each power domains. * * This function gets the status which indicates whether certain * peripheral and the IO pads are in a latched state as a result * of having been in POWERDOWN mode. * * @param base SPC peripheral base address. * @return Current isolation status for each power domains. See @ref _spc_power_domains for details. */ uint8_t SPC_GetPeriphIOIsolationStatus(SPC_Type *base); /*! * @brief Clears peripherals and I/O pads isolation flags for each power domains. * * This function clears peripherals and I/O pads isolation flags for each power domains. * After recovering from the POWERDOWN mode, user must invoke this function to release the * I/O pads and certain peripherals to their normal run mode state. Before invoking this * function, user must restore chip configuration in particular pin configuration for enabled * WUU wakeup pins. * * @param base SPC peripheral base address. */ static inline void SPC_ClearPeriphIOIsolationFlag(SPC_Type *base) { base->SC |= SPC_SC_ISO_CLR_MASK; } /*! * @brief Gets SPC busy status flag. * * This function gets SPC busy status flag. When SPC executing any type of power mode * transition in ACTIVE mode or any of the SOC low power mode, the SPC busy status flag is set * and this function returns true. When changing CORE LDO voltage level and DCDC voltage level * in ACTIVE mode, the SPC busy status flag is set and this function return true. * * @param base SPC peripheral base address. * @return Ack busy flag. * true - SPC is busy. * false - SPC is not busy. */ static inline bool SPC_GetBusyStatusFlag(SPC_Type *base) { return ((base->SC & SPC_SC_BUSY_MASK) != 0UL); } /*! * @brief Checks system low power request. * * @note Only when all power domains request low power mode entry, the result of this function is true. That means when * all power domains request low power mode entry, the SPC regulators will be controlled by LP_CFG register. * * @param base SPC peripheral base address. * @return The system low power request check result. * - \b true All power domains have requested low power mode and SPC has entered a low power state and power mode * configuration are based on the LP_CFG configuration register. * - \b false SPC in active mode and ACTIVE_CFG register control system power supply. */ static inline bool SPC_CheckLowPowerReqest(SPC_Type *base) { return ((base->SC & SPC_SC_SPC_LP_REQ_MASK) == SPC_SC_SPC_LP_REQ_MASK); } /*! * @brief Clears system low power request, set SPC in active mode. * * @param base SPC peripheral base address. */ static inline void SPC_ClearLowPowerRequest(SPC_Type *base) { base->SC |= SPC_SC_SPC_LP_REQ_MASK; } #if (defined(FSL_FEATURE_MCX_SPC_HAS_SWITCH_STATE_BIT) && FSL_FEATURE_MCX_SPC_HAS_SWITCH_STATE_BIT) /*! * @brief Checks whether the power switch is on. * * @param base SPC peripheral base address. * * @retval true The power switch is on. * @retval false The power switch is off. */ static inline bool SPC_CheckSwitchState(SPC_Type *base) { return ((base->SC & SPC_SC_SWITCH_STATE_MASK) != 0UL); } #endif /* FSL_FEATURE_MCX_SPC_HAS_SWITCH_STATE_BIT */ /*! * @brief Gets selected power domain's requested low power mode. * * @param base SPC peripheral base address. * @param powerDomainId Power Domain Id, please refer to @ref spc_power_domain_id_t. * * @return The selected power domain's requested low power mode, please refer to @ref spc_power_domain_low_power_mode_t. */ spc_power_domain_low_power_mode_t SPC_GetPowerDomainLowPowerMode(SPC_Type *base, spc_power_domain_id_t powerDomainId); /*! * @brief Checks power domain's low power request. * * @param base SPC peripheral base address. * @param powerDomainId Power Domain Id, please refer to @ref spc_power_domain_id_t. * @return The result of power domain's low power request. * - \b true The selected power domain requests low power mode entry. * - \b false The selected power domain does not request low power mode entry. */ static inline bool SPC_CheckPowerDomainLowPowerRequest(SPC_Type *base, spc_power_domain_id_t powerDomainId) { assert((uint8_t)powerDomainId < SPC_PD_STATUS_COUNT); return ((base->PD_STATUS[(uint8_t)powerDomainId] & SPC_PD_STATUS_PWR_REQ_STATUS_MASK) == SPC_PD_STATUS_PWR_REQ_STATUS_MASK); } /*! * @brief Clears selected power domain's low power request flag. * * @param base SPC peripheral base address. * @param powerDomainId Power Domain Id, please refer to @ref spc_power_domain_id_t. */ static inline void SPC_ClearPowerDomainLowPowerRequestFlag(SPC_Type *base, spc_power_domain_id_t powerDomainId) { assert((uint8_t)powerDomainId < SPC_PD_STATUS_COUNT); base->PD_STATUS[(uint8_t)powerDomainId] |= SPC_PD_STATUS_PD_LP_REQ_MASK; } /*! @} */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_SRAMRETLDO_REG) && FSL_FEATURE_MCX_SPC_HAS_SRAMRETLDO_REG) /*! * @name SRAM Retention LDO Control APIs * @{ */ /*! * @brief Trims SRAM retention regulator reference voltage, trim step is 12 mV, range is around 0.48V to 0.85V. * * @param base SPC peripheral base address. * @param trimValue Reference voltage trim value. */ static inline void SPC_TrimSRAMLdoRefVoltage(SPC_Type *base, uint8_t trimValue) { base->SRAMRETLDO_REFTRIM = ((base->SRAMRETLDO_REFTRIM & ~SPC_SRAMRETLDO_REFTRIM_REFTRIM_MASK) | SPC_SRAMRETLDO_REFTRIM_REFTRIM(trimValue)); } /*! * @brief Enables/disables SRAM retention LDO. * * @param base SPC peripheral base address. * @param enable Used to enable/disable SRAM LDO : * - \b true Enable SRAM LDO; * - \b false Disable SRAM LDO. */ static inline void SPC_EnableSRAMLdo(SPC_Type *base, bool enable) { if (enable) { base->SRAMRETLDO_CNTRL |= SPC_SRAMRETLDO_CNTRL_SRAMLDO_ON_MASK; } else { base->SRAMRETLDO_CNTRL &= ~SPC_SRAMRETLDO_CNTRL_SRAMLDO_ON_MASK; } } /*! * @brief * * @todo Need to check. * * @param base SPC peripheral base address. * @param mask The OR'ed value of SRAM Array. */ static inline void SPC_RetainSRAMArray(SPC_Type *base, uint8_t mask) { base->SRAMRETLDO_CNTRL |= SPC_SRAMRETLDO_CNTRL_SRAM_RET_EN(mask); } /*! @} */ #endif /* FSL_FEATURE_MCX_SPC_HAS_SRAMRETLDO_REG */ /*! * @name Low Power Request configuration * @{ */ /*! * @brief Configs Low power request output pin. * * This function config the low power request output pin * * @param base SPC peripheral base address. * @param config Pointer the @ref spc_lowpower_request_config_t structure. */ void SPC_SetLowPowerRequestConfig(SPC_Type *base, const spc_lowpower_request_config_t *config); /*! @} */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_CFG_REG) && FSL_FEATURE_MCX_SPC_HAS_CFG_REG) /*! * @name Integrated Power Switch Control APIs * @{ */ /*! * @brief Enables/disables the integrated power switch manually. * * @param base SPC peripheral base address. * @param enable Used to enable/disable the integrated power switch: * - \b true Enable the integrated power switch; * - \b false Disable the integrated power switch. */ static inline void SPC_EnableIntegratedPowerSwitchManually(SPC_Type *base, bool enable) { if (enable) { base->CFG |= (SPC_CFG_INTG_PWSWTCH_SLEEP_ACTIVE_EN_MASK | SPC_CFG_INTG_PWSWTCH_WKUP_ACTIVE_EN_MASK); } else { base->CFG &= ~(SPC_CFG_INTG_PWSWTCH_SLEEP_ACTIVE_EN_MASK | SPC_CFG_INTG_PWSWTCH_WKUP_ACTIVE_EN_MASK); } } /*! * @brief Enables/disables the integrated power switch automatically. * * To gate the integrated power switch when chip enter low power modes, and ungate the switch after wake-up from low * power modes: * @code * SPC_EnableIntegratedPowerSwitchAutomatically(SPC, true, true); * @endcode * * @param base SPC peripheral base address. * @param sleepGate Enable the integrated power switch when chip enter low power modes: * - \b true SPC asserts an output pin at low-power entry to power-gate the switch; * - \b false SPC does not assert an output pin at low-power entry to power-gate the switch. * @param wakeupUngate Enables the switch after wake-up from low power modes: * - \b true SPC asserts an output pin at low-power exit to power-ungate the switch; * - \b false SPC does not assert an output pin at low-power exit to power-ungate the switch. */ static inline void SPC_EnableIntegratedPowerSwitchAutomatically(SPC_Type *base, bool sleepGate, bool wakeupUngate) { uint32_t tmp32 = ((base->CFG) & ~(SPC_CFG_INTG_PWSWTCH_SLEEP_EN_MASK | SPC_CFG_INTG_PWSWTCH_WKUP_EN_MASK)); tmp32 |= SPC_CFG_INTG_PWSWTCH_SLEEP_EN(sleepGate) | SPC_CFG_INTG_PWSWTCH_WKUP_EN(wakeupUngate); base->CFG = tmp32; } /*! @} */ #endif /* FSL_FEATURE_MCX_SPC_HAS_CFG_REG */ #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * @name VDD Core Glitch Detector Control APIs * @{ */ /*! * @brief Configures VDD Core Glitch detector, including ripple counter selection, timeout value and so on. * * @param base SPC peripheral base address. * @param config Pointer to the structure in type of @ref spc_vdd_core_glitch_detector_config_t. */ void SPC_ConfigVddCoreGlitchDetector(SPC_Type *base, const spc_vdd_core_glitch_detector_config_t *config); /*! * @brief Checks selected 4-bit glitch ripple counter's output. * * @param base SPC peripheral base address. * @param rippleCounter The ripple counter to check, please refer to @ref spc_vdd_core_glitch_ripple_counter_select_t. * * @retval true The selected ripple counter output is 1, will generate interrupt or reset based on settings. * @retval false The selected ripple counter output is 0. */ static inline bool SPC_CheckGlitchRippleCounterOutput(SPC_Type *base, spc_vdd_core_glitch_ripple_counter_select_t rippleCounter) { return ((base->VDD_CORE_GLITCH_DETECT_SC & SPC_VDD_CORE_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG_MASK) == SPC_VDD_CORE_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG(1UL << (uint32_t)(rippleCounter))); } /*! * @brief Clears output of selected glitch ripple counter. * * @param base SPC peripheral base address. * @param rippleCounter The ripple counter to check, please refer to @ref spc_vdd_core_glitch_ripple_counter_select_t. */ static inline void SPC_ClearGlitchRippleCounterOutput(SPC_Type *base, spc_vdd_core_glitch_ripple_counter_select_t rippleCounter) { base->VDD_CORE_GLITCH_DETECT_SC |= SPC_VDD_CORE_GLITCH_DETECT_SC_GLITCH_DETECT_FLAG(1UL << (uint32_t)(rippleCounter)); } /*! * @brief After invoking this function, writes to SPC_VDD_CORE_GLITCH_DETECT_SC[RE] register are ignored. * * @param base SPC peripheral base address. */ static inline void SPC_LockVddCoreVoltageGlitchDetectResetControl(SPC_Type *base) { base->VDD_CORE_GLITCH_DETECT_SC |= SPC_VDD_CORE_GLITCH_DETECT_SC_LOCK_MASK; } /*! * @brief After invoking this function, writes to SPC_VDD_CORE_GLITCH_DETECT_SC[RE] register are allowed. * * @param base SPC peripheral base address. */ static inline void SPC_UnlockVddCoreVoltageGlitchDetectResetControl(SPC_Type *base) { base->VDD_CORE_GLITCH_DETECT_SC &= ~SPC_VDD_CORE_GLITCH_DETECT_SC_LOCK_MASK; } /*! * @brief Checks if SPC_VDD_CORE_GLITCH_DETECT_SC[RE] register is writable. * * @param base SPC peripheral base address. * * @retval true SPC_VDD_CORE_GLITCH_DETECT_SC[RE] register is writable. * @retval false SPC_VDD_CORE_GLITCH_DETECT_SC[RE] register is not writable. */ static inline bool SPC_CheckVddCoreVoltageGlitchResetControlState(SPC_Type *base) { return ((base->VDD_CORE_GLITCH_DETECT_SC & SPC_VDD_CORE_GLITCH_DETECT_SC_LOCK_MASK) != 0UL); } /*! @} */ #endif /*! * @name SRAM Control APIs * @{ */ /*! * @brief Set SRAM operate voltage. * * @param base SPC peripheral base address. * @param config The pointer to @ref spc_sram_voltage_config_t, specifies the configuration of sram voltage. */ void SPC_SetSRAMOperateVoltage(SPC_Type *base, const spc_sram_voltage_config_t *config); /*! @} */ /*! * @name Active Mode configuration * @{ */ /*! * @brief Gets the Bandgap mode in Active mode. * * @param base SPC peripheral base address. * @return Bandgap mode in the type of @ref spc_bandgap_mode_t enumeration. */ static inline spc_bandgap_mode_t SPC_GetActiveModeBandgapMode(SPC_Type *base) { return (spc_bandgap_mode_t)(uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_BGMODE_MASK) >> SPC_ACTIVE_CFG_BGMODE_SHIFT); } /*! * @brief Gets all voltage detectors status in Active mode. * * @param base SPC peripheral base address. * @return All voltage detectors status in Active mode. */ static inline uint32_t SPC_GetActiveModeVoltageDetectStatus(SPC_Type *base) { uint32_t state; state = base->ACTIVE_CFG & ( #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) SPC_ACTIVE_CFG_IO_HVDE_MASK | SPC_ACTIVE_CFG_IO_LVDE_MASK | #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ SPC_ACTIVE_CFG_SYS_HVDE_MASK | SPC_ACTIVE_CFG_SYS_LVDE_MASK | SPC_ACTIVE_CFG_CORE_LVDE_MASK #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) | SPC_ACTIVE_CFG_CORE_HVDE_MASK #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ ); return state; } /*! * @brief Configs Bandgap mode in Active mode. * * @note To disable bandgap in Active mode: * 1. Disable all LVD's and HVD's in active mode; * 2. Disable Glitch detect; * 3. Configure LDO's and DCDC to low drive strength in active mode; * 4. Invoke this function to disable bandgap in active mode; * otherwise the error status will be reported. * * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please * take care of other system resources. * * @param base SPC peripheral base address. * @param mode The Bandgap mode be selected. * * @retval #kStatus_SPC_BandgapModeWrong The Bandgap can not be disabled in active mode. * @retval #kStatus_Success Config Bandgap mode in Active power mode successful. */ status_t SPC_SetActiveModeBandgapModeConfig(SPC_Type *base, spc_bandgap_mode_t mode); #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) /*! * @brief Enables/Disable the CMP Bandgap Buffer in Active mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable CMP Bandgap buffer. * true - Enable Buffer Stored Reference voltage to CMP. * false - Disable Buffer Stored Reference voltage to CMP. */ static inline void SPC_EnableActiveModeCMPBandgapBuffer(SPC_Type *base, bool enable) { if (enable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_LPBUFF_EN_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_LPBUFF_EN_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ /*! * @brief Sets the delay when the regulators change voltage level in Active mode. * * @param base SPC peripheral base address. * @param delay The number of SPC timer clock cycles. */ static inline void SPC_SetActiveModeVoltageTrimDelay(SPC_Type *base, uint16_t delay) { base->ACTIVE_VDELAY = SPC_ACTIVE_VDELAY_ACTIVE_VDELAY(delay); } /*! * @brief Configs all settings of regulators in Active mode at a time. * * @note This function is used to overwrite all settings of regulators(including bandgap mode, regulators' * drive strength and voltage level) in active mode at a time. * * @note Enable/disable LVDs/HVDs before invoking this function. * * @note This function will check input parameters based on hardware restrictions before setting registers, if input * parameters do not satisfy hardware restrictions the specific error will be reported. * * * @note Some hardware restrictions not covered, application should be aware of this and follow this hardware * restrictions otherwise some unknown issue may occur: * 1. If Core LDO's drive strength are set to same value in both Active mode and low power mode, * the voltage level should also set to same value. * 2. When switching Core LDO's drive strength from low to normal, ensure the LDO_CORE high voltage level is set * to same level that was set prior to switching to the LDO_CORE drive strength. Otherwise, if the LVDs are * enabled, an unexpected LVD can occur. * * @note If this function can not satisfy some tricky settings, please invoke other APIs in low-level function group. * * @param base SPC peripheral base address. * @param config Pointer to spc_active_mode_regulators_config_t structure. * * @retval #kStatus_Success Config regulators in Active power mode successful. * @retval #kStatus_SPC_BandgapModeWrong Based on input setting, bandgap can not be disabled. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Any of LVDs/HVDs kept enabled before invoking this function. * @retval #kStatus_SPC_SYSLDOOverDriveVoltageFail Fail to regulator to Over Drive Voltage due to * System VDD HVD is not disabled. * @retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Any of LVDs/HVDs kept enabled before invoking this function. * @retval #kStatus_SPC_CORELDOVoltageWrong Core LDO and System LDO do not have same voltage level. */ status_t SPC_SetActiveModeRegulatorsConfig(SPC_Type *base, const spc_active_mode_regulators_config_t *config); #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * @brief Disables/Enables VDD Core Glitch Detect in Active mode. * * @note State of glitch detect disable feature will be ignored if bandgap is disabled and * glitch detect hardware will be forced to OFF state. * * @param base SPC peripheral base address. * @param disable Used to disable/enable VDD Core Glitch detect feature. * - \b true Disable VDD Core Low Voltage detect; * - \b false Enable VDD Core Low Voltage detect. */ static inline void SPC_DisableActiveModeVddCoreGlitchDetect(SPC_Type *base, bool disable) { if (disable) { base->ACTIVE_CFG |= SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK; } else { base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK; } } /*! * @brief Check if Glitch detect hardware is enabled in active mode. * * @param base SPC peripheral base address. * @return Indicate if Glitch detector is enabled. */ static inline bool SPC_CheckActiveModeVddCoreGlitchDetectEnabled(SPC_Type *base) { if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL) { return true; } else { return false; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT */ /*! * @brief Enables analog modules in active mode. * * @param base SPC peripheral base address. * @param maskValue The mask of analog modules to enable in active mode, should be the OR'ed value * of @ref spc_analog_module_control. */ static inline void SPC_EnableActiveModeAnalogModules(SPC_Type *base, uint32_t maskValue) { base->ACTIVE_CFG1 |= SPC_ACTIVE_CFG1_SOC_CNTRL(maskValue); } /*! * @brief Disables analog modules in active mode. * * @param base SPC peripheral base address. * @param maskValue The mask of analog modules to disable in active mode, should be the OR'ed value * of @ref spc_analog_module_control. */ static inline void SPC_DisableActiveModeAnalogModules(SPC_Type *base, uint32_t maskValue) { base->ACTIVE_CFG1 &= ~SPC_ACTIVE_CFG1_SOC_CNTRL(maskValue); } /*! * @brief Gets enabled analog modules that enabled in active mode. * * @param base SPC peripheral base address. * * @return The mask of enabled analog modules that enabled in active mode. */ static inline uint32_t SPC_GetActiveModeEnabledAnalogModules(SPC_Type *base) { return base->ACTIVE_CFG1; } /*! @} */ /*! * @name Low Power mode configuration * @{ */ /*! * @brief Gets the Bandgap mode in Low Power mode. * * @param base SPC peripheral base address. * @return Bandgap mode in the type of @ref spc_bandgap_mode_t enumeration. */ static inline spc_bandgap_mode_t SPC_GetLowPowerModeBandgapMode(SPC_Type *base) { return (spc_bandgap_mode_t)(uint32_t)((base->LP_CFG & SPC_LP_CFG_BGMODE_MASK) >> SPC_LP_CFG_BGMODE_SHIFT); } /*! * @brief Gets the status of all voltage detectors in Low Power mode. * * @param base SPC peripheral base address. * @return The status of all voltage detectors in low power mode. */ static inline uint32_t SPC_GetLowPowerModeVoltageDetectStatus(SPC_Type *base) { uint32_t state; state = base->LP_CFG & ( #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) SPC_LP_CFG_IO_HVDE_MASK | SPC_LP_CFG_IO_LVDE_MASK | #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ SPC_LP_CFG_SYS_HVDE_MASK | SPC_LP_CFG_SYS_LVDE_MASK | SPC_LP_CFG_CORE_LVDE_MASK #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) | SPC_LP_CFG_CORE_HVDE_MASK #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ ); return state; } /*! * @brief Enables/Disables Low Power IREF in low power modes. * * This function enables/disables Low Power IREF. Low Power IREF can only get * disabled in Deep power down mode. In other low power modes, the Low Power IREF * is always enabled. * * @param base SPC peripheral base address. * @param enable Enable/Disable Low Power IREF. * true - Enable Low Power IREF for Low Power modes. * false - Disable Low Power IREF for Deep Power Down mode. */ static inline void SPC_EnableLowPowerModeLowPowerIREF(SPC_Type *base, bool enable) { if (enable) { base->LP_CFG |= SPC_LP_CFG_LP_IREFEN_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_LP_IREFEN_MASK; } } /*! * @brief Configs Bandgap mode in Low Power mode. * * @note To disable Bandgap in Low-power mode: * 1. Disable all LVD's ad HVD's in low power mode; * 2. Disable Glitch detect in low power mode; * 3. Configure LDO's and DCDC to low drive strength in low power mode; * 4. Disable bandgap in low power mode; * Otherwise, the error status will be reported. * * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please * take care of other system resources. * * @param base SPC peripheral base address. * @param mode The Bandgap mode be selected. * * @retval #kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power mode is wrong. * @retval #kStatus_Success Config Bandgap mode in Low Power power mode successful. */ status_t SPC_SetLowPowerModeBandgapmodeConfig(SPC_Type *base, spc_bandgap_mode_t mode); #if (defined(FSL_FEATURE_MCX_SPC_HAS_SRAMLDO_DPD_ON_BIT) && FSL_FEATURE_MCX_SPC_HAS_SRAMLDO_DPD_ON_BIT) /*! * @brief Enables/disables SRAM_LDO deep power low power IREF. * * @param base SPC peripheral base address. * @param enable Used to enable/disable low power IREF : * - \b true: Low Power IREF is enabled ; * - \b false: Low Power IREF is disabled for power saving. */ static inline void SPC_EnableSRAMLdOLowPowerModeIREF(SPC_Type *base, bool enable) { if (enable) { base->LP_CFG |= SPC_LP_CFG_SRAMLDO_DPD_ON_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_SRAMLDO_DPD_ON_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_SRAMLDO_DPD_ON_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) /*! * @brief Enables/Disables CMP Bandgap Buffer. * * This function gates CMP bandgap buffer. CMP bandgap buffer is automatically disabled and turned off * in Deep Power Down mode. * * @deprecated No longer used, please use SPC_EnableLowPowerModeCMPBandgapBuffer as instead. * * @param base SPC peripheral base address. * @param enable Enable/Disable CMP Bandgap buffer. * true - Enable Buffer Stored Reference Voltage to CMP. * false - Disable Buffer Stored Reference Voltage to CMP. */ static inline void SPC_EnableLowPowerModeCMPBandgapBufferMode(SPC_Type *base, bool enable) { if (enable) { base->LP_CFG |= SPC_LP_CFG_LPBUFF_EN_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_LPBUFF_EN_MASK; } } /*! * @brief Enables/Disables CMP Bandgap Buffer. * * This function gates CMP bandgap buffer. CMP bandgap buffer is automatically disabled and turned off * in Deep Power Down mode. * * @deprecated No longer used. * * @param base SPC peripheral base address. * @param enable Enable/Disable CMP Bandgap buffer. * true - Enable Buffer Stored Reference Voltage to CMP. * false - Disable Buffer Stored Reference Voltage to CMP. */ static inline void SPC_EnableLowPowerModeCMPBandgapBuffer(SPC_Type *base, bool enable) { if (enable) { base->LP_CFG |= SPC_LP_CFG_LPBUFF_EN_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_LPBUFF_EN_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) /*! * @brief Enables/Disables CORE VDD IVS(Internal Voltage Scaling) in power down modes. * * This function gates CORE VDD IVS. When enabled, the IVS regulator will scale the * external input CORE VDD to a lower voltage level to reduce internal leakage. * IVS is invalid in Sleep or Deep power down mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable IVS. * true - enable CORE VDD IVS in Power Down mode. * false - disable CORE VDD IVS in Power Down mode. */ static inline void SPC_EnableLowPowerModeCoreVDDInternalVoltageScaling(SPC_Type *base, bool enable) { if (enable) { base->LP_CFG |= SPC_LP_CFG_COREVDD_IVS_EN_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_COREVDD_IVS_EN_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT */ /*! * @brief Sets the delay when exit the low power modes. * * @param base SPC peripheral base address. * @param delay The number of SPC timer clock cycles that the SPC waits on exit from low power modes. */ static inline void SPC_SetLowPowerWakeUpDelay(SPC_Type *base, uint16_t delay) { base->LPWKUP_DELAY = SPC_LPWKUP_DELAY_LPWKUP_DELAY(delay); } /*! * @brief Configs all settings of regulators in Low power mode at a time. * * @note This function is used to overwrite all settings of regulators(including bandgap mode, regulators' * drive strength and voltage level) in low power mode at a time. * * @note Enable/disable LVDs/HVDs before invoking this function. * * @note This function will check input parameters based on hardware restrictions before setting registers, if input * parameters do not satisfy hardware restrictions the specific error will be reported. * * @note Some hardware restrictions not covered, application should be aware of this and follow this hardware * restrictions otherwise some unknown issue may occur: * 1. If Core LDO's drive strength are set to same value in both Active mode and low power mode, * the voltage level should also set to same value. * 2. When switching Core LDO's drive strength from low to normal, ensure the LDO_CORE high voltage level is set * to same level that was set prior to switching to the LDO_CORE drive strength. Otherwise, if the LVDs are * enabled, an unexpected LVD can occur. * * @note If this function can not satisfy some tricky settings, please invoke other APIs in low-level function group. * * @param base SPC peripheral base address. * @param config Pointer to spc_lowpower_mode_regulators_config_t structure. * @retval #kStatus_Success Config regulators in Low power mode successful. * @retval #kStatus_SPC_BandgapModeWrong The bandgap should not be disabled based on input settings. * @retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Set driver strength to low will be ignored. * @retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored. * @retval #kStatus_SPC_CORELDOVoltageWrong Core LDO and System LDO do not have same voltage level. */ status_t SPC_SetLowPowerModeRegulatorsConfig(SPC_Type *base, const spc_lowpower_mode_regulators_config_t *config); #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) /*! * @brief Disable/Enable VDD Core Glitch Detect in low power mode. * * @note State of glitch detect disable feature will be ignored if bandgap is disabled and * glitch detect hardware will be forced to OFF state. * * @param base SPC peripheral base address. * @param disable Used to disable/enable VDD Core Glitch detect feature. * - \b true Disable VDD Core Low Voltage detect; * - \b false Enable VDD Core Low Voltage detect. */ static inline void SPC_DisableLowPowerModeVddCoreGlitchDetect(SPC_Type *base, bool disable) { if (disable) { base->LP_CFG |= SPC_LP_CFG_GLITCH_DETECT_DISABLE_MASK; } else { base->LP_CFG &= ~SPC_LP_CFG_GLITCH_DETECT_DISABLE_MASK; } } /*! * @brief Check if Glitch detect hardware is enabled in low power mode. * * @param base SPC peripheral base address. * @return Indicate if Glitch detector is enabled. */ static inline bool SPC_CheckLowPowerModeVddCoreGlitchDetectEnabled(SPC_Type *base) { if ((base->LP_CFG & SPC_LP_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL) { return true; } else { return false; } } #endif /*! * @brief Enables analog modules in low power modes. * * @param base SPC peripheral base address. * @param maskValue The mask of analog modules to enable in low power modes, should be OR'ed value of @ref spc_analog_module_control. */ static inline void SPC_EnableLowPowerModeAnalogModules(SPC_Type *base, uint32_t maskValue) { base->LP_CFG1 |= SPC_LP_CFG1_SOC_CNTRL(maskValue); } /*! * @brief Disables analog modules in low power modes. * * @param base SPC peripheral base address. * @param maskValue The mask of analog modules to disable in low power modes, should be OR'ed value of @ref spc_analog_module_control. */ static inline void SPC_DisableLowPowerModeAnalogModules(SPC_Type *base, uint32_t maskValue) { base->LP_CFG1 &= ~SPC_LP_CFG1_SOC_CNTRL(maskValue); } /*! * @brief Gets enabled analog modules that enabled in low power modes. * * @param base SPC peripheral base address. * * @return The mask of enabled analog modules that enabled in low power modes. */ static inline uint32_t SPC_GetLowPowerModeEnabledAnalogModules(SPC_Type *base) { return base->LP_CFG1; } /*! @} */ /*! * @name Voltage Detect Status * @{ */ /*! * @brief Get Voltage Detect Status Flags. * * @param base SPC peripheral base address. * @return Voltage Detect Status Flags. See @ref _spc_voltage_detect_flags for details. */ static inline uint8_t SPC_GetVoltageDetectStatusFlag(SPC_Type *base) { return (uint8_t)(base->VD_STAT); } /*! * @brief Clear Voltage Detect Status Flags. * * @param base SPC peripheral base address. * @param mask The mask of the voltage detect status flags. See @ref _spc_voltage_detect_flags for details. */ static inline void SPC_ClearVoltageDetectStatusFlag(SPC_Type *base, uint8_t mask) { base->VD_STAT |= mask; } /*! @} */ /*! * @name Voltage Detect configuration for Core voltage domain. * @{ */ /*! * @brief Configs CORE voltage detect options. * * @note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset so only one is enabled. * * @param base SPC peripheral base address. * @param config Pointer to spc_core_voltage_detect_config_t structure. */ void SPC_SetCoreVoltageDetectConfig(SPC_Type *base, const spc_core_voltage_detect_config_t *config); /*! * @brief Locks Core voltage detect reset setting. * * This function locks core voltage detect reset setting. After invoking this function * any configuration of Core voltage detect reset will be ignored. * * @param base SPC peripheral base address. */ static inline void SPC_LockCoreVoltageDetectResetSetting(SPC_Type *base) { base->VD_CORE_CFG |= SPC_VD_CORE_CFG_LOCK_MASK; } /*! * @brief Unlocks Core voltage detect reset setting. * * This function unlocks core voltage detect reset setting. If locks the Core * voltage detect reset setting, invoking this function to unlock. * * @param base SPC peripheral base address. */ static inline void SPC_UnlockCoreVoltageDetectResetSetting(SPC_Type *base) { base->VD_CORE_CFG &= ~SPC_VD_CORE_CFG_LOCK_MASK; } /*! * @brief Enables/Disables the Core Low Voltage Detector in Active mode. * * @note If the CORE_LDO low voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low. * * @param base SPC peripheral base address. * @param enable Enable/Disable Core LVD. * true - Enable Core Low voltage detector in active mode. * false - Disable Core Low voltage detector in active mode. * * @retval #kStatus_Success Enable/Disable Core Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeCoreLowVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the Core Low Voltage Detector in Low Power mode. * * This function enables/disables the Core Low Voltage Detector. * If enabled the Core Low Voltage detector. The Bandgap mode in * low power mode must be programmed so that Bandgap is enabled. * * @note If the CORE_LDO low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable Core HVD. * true - Enable Core Low voltage detector in low power mode. * false - Disable Core Low voltage detector in low power mode. * * @retval #kStatus_Success Enable/Disable Core Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeCoreLowVoltageDetect(SPC_Type *base, bool enable); #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) /*! * @brief Enables/Disables the Core High Voltage Detector in Active mode. * * @note If the CORE_LDO high voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low. * * @param base SPC peripheral base address. * @param enable Enable/Disable Core HVD. * true - Enable Core High voltage detector in active mode. * false - Disable Core High voltage detector in active mode. * * @retval #kStatus_Success Enable/Disable Core High Voltage Detect successfully. */ status_t SPC_EnableActiveModeCoreHighVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the Core High Voltage Detector in Low Power mode. * * This function enables/disables the Core High Voltage Detector. * If enabled the Core High Voltage detector. The Bandgap mode in * low power mode must be programmed so that Bandgap is enabled. * * @note If the CORE_LDO high voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in low power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable Core HVD. * true - Enable Core High voltage detector in low power mode. * false - Disable Core High voltage detector in low power mode. * * @retval #kStatus_Success Enable/Disable Core High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeCoreHighVoltageDetect(SPC_Type *base, bool enable); #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */ /*! @} */ /*! * @name Voltage detect configuration for System Voltage domain * @{ */ /*! * @brief Set system VDD Low-voltage level selection. * * This function selects the system VDD low-voltage level. Changing system VDD low-voltage level * must be done after disabling the System VDD low voltage reset and interrupt. * * @deprecated In latest RM, reserved for all devices, will removed in next release. * * @param base SPC peripheral base address. * @param level System VDD Low-Voltage level selection. */ void SPC_SetSystemVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level); /*! * @brief Configs SYS voltage detect options. * * This function config SYS voltage detect options. * @note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset so only one is enabled. * * @param base SPC peripheral base address. * @param config Pointer to spc_system_voltage_detect_config_t structure. */ void SPC_SetSystemVoltageDetectConfig(SPC_Type *base, const spc_system_voltage_detect_config_t *config); /*! * @brief Lock System voltage detect reset setting. * * This function locks system voltage detect reset setting. After invoking this function * any configuration of System Voltage detect reset will be ignored. * * @param base SPC peripheral base address. */ static inline void SPC_LockSystemVoltageDetectResetSetting(SPC_Type *base) { base->VD_SYS_CFG |= SPC_VD_SYS_CFG_LOCK_MASK; } /*! * @brief Unlock System voltage detect reset setting. * * This function unlocks system voltage detect reset setting. If locks the System * voltage detect reset setting, invoking this function to unlock. * * @param base SPC peripheral base address. */ static inline void SPC_UnlockSystemVoltageDetectResetSetting(SPC_Type *base) { base->VD_SYS_CFG &= ~SPC_VD_SYS_CFG_LOCK_MASK; } /*! * @brief Enables/Disables the System High Voltage Detector in Active mode. * * @note If the System_LDO high voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Active mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable System HVD. * true - Enable System High voltage detector in active mode. * false - Disable System High voltage detector in active mode. * * @retval #kStatus_Success Enable/Disable System High Voltage Detect successfully. */ status_t SPC_EnableActiveModeSystemHighVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disable the System Low Voltage Detector in Active mode. * * @note If the System_LDO low voltage detect is enabled in Active mode, * please note that the bandgap must be enabled and the drive strength of each * regulator must not set to low in Active mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable System LVD. * true - Enable System Low voltage detector in active mode. * false - Disable System Low voltage detector in active mode. * * @retval #kStatus_Success Enable/Disable the System Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeSystemLowVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the System High Voltage Detector in Low Power mode. * * @note If the System_LDO high voltage detect is enabled in Low Power mode, please note * that the bandgap must be enabled and the drive strength of each regulator must * not set to low in Low Power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable System HVD. * true - Enable System High voltage detector in low power mode. * false - Disable System High voltage detector in low power mode. * * @retval #kStatus_Success Enable/Disable System High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeSystemHighVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the System Low Voltage Detector in Low Power mode. * * @note If the System_LDO low voltage detect is enabled in Low Power mode, * please note that the bandgap must be enabled and the drive strength of each * regulator must not set to low in Low Power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable System HVD. * true - Enable System Low voltage detector in low power mode. * false - Disable System Low voltage detector in low power mode. * * @retval #kStatus_Success Enables System Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeSystemLowVoltageDetect(SPC_Type *base, bool enable); /*! @} */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) /*! * @name Voltage detect configuration for IO voltage domain * @{ */ /*! * @brief Set IO VDD Low-Voltage level selection. * * This function selects the IO VDD Low-voltage level. Changing IO VDD low-voltage level * must be done after disabling the IO VDD low voltage reset and interrupt. * * @param base SPC peripheral base address. * @param level IO VDD Low-voltage level selection. */ void SPC_SetIOVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level); /*! * @brief Configs IO voltage detect options. * * This function config IO voltage detect options. * @note: Setting both the voltage detect interrupt and reset * enable will cause interrupt to be generated on exit from reset. * If those conditioned is not desired, interrupt/reset so only one is enabled. * * @param base SPC peripheral base address. * @param config Pointer to spc_voltage_detect_config_t structure. */ void SPC_SetIOVoltageDetectConfig(SPC_Type *base, const spc_io_voltage_detect_config_t *config); /*! * @brief Lock IO Voltage detect reset setting. * * This function locks IO voltage detect reset setting. After invoking this function * any configuration of system voltage detect reset will be ignored. * * @param base SPC peripheral base address. */ static inline void SPC_LockIOVoltageDetectResetSetting(SPC_Type *base) { base->VD_IO_CFG |= SPC_VD_IO_CFG_LOCK_MASK; } /*! * @brief Unlock IO voltage detect reset setting. * * This function unlocks IO voltage detect reset setting. If locks the IO * voltage detect reset setting, invoking this function to unlock. * * @param base SPC peripheral base address. */ static inline void SPC_UnlockIOVoltageDetectResetSetting(SPC_Type *base) { base->VD_IO_CFG &= ~SPC_VD_IO_CFG_LOCK_MASK; } /*! * @brief Enables/Disables the IO High Voltage Detector in Active mode. * * @note If the IO high voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Active mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable IO HVD. * true - Enable IO High voltage detector in active mode. * false - Disable IO High voltage detector in active mode. * * @retval #kStatus_Success Enable/Disable IO High Voltage Detect successfully. */ status_t SPC_EnableActiveModeIOHighVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the IO Low Voltage Detector in Active mode. * * @note If the IO low voltage detect is enabled in Active mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Active mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable IO LVD. * true - Enable IO Low voltage detector in active mode. * false - Disable IO Low voltage detector in active mode. * * @retval #kStatus_Success Enable IO Low Voltage Detect successfully. */ status_t SPC_EnableActiveModeIOLowVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the IO High Voltage Detector in Low Power mode. * * @note If the IO high voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable IO HVD. * true - Enable IO High voltage detector in low power mode. * false - Disable IO High voltage detector in low power mode. * * @retval #kStatus_Success Enable IO High Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeIOHighVoltageDetect(SPC_Type *base, bool enable); /*! * @brief Enables/Disables the IO Low Voltage Detector in Low Power mode. * * @note If the IO low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled * and the drive strength of each regulator must not set to low in Low Power mode. * * @param base SPC peripheral base address. * @param enable Enable/Disable IO LVD. * true - Enable IO Low voltage detector in low power mode. * false - Disable IO Low voltage detector in low power mode. * * @retval #kStatus_Success Enable/Disable IO Low Voltage Detect in low power mode successfully. */ status_t SPC_EnableLowPowerModeIOLowVoltageDetect(SPC_Type *base, bool enable); /*! @} */ #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */ /*! * @name External Voltage domains configuration * @{ */ /*! * @brief Configs external voltage domains * * This function configs external voltage domains isolation. * * @param base SPC peripheral base address. * @param lowPowerIsoMask The mask of external domains isolate enable during low power mode. Please read the Reference * Manual for the Bitmap. * @param IsoMask The mask of external domains isolate. Please read the Reference Manual for the Bitmap. */ void SPC_SetExternalVoltageDomainsConfig(SPC_Type *base, uint8_t lowPowerIsoMask, uint8_t IsoMask); /*! * @brief Gets External Domains status. * * @param base SPC peripheral base address. * @return The status of each external domain. */ static inline uint8_t SPC_GetExternalDomainsStatus(SPC_Type *base) { return (uint8_t)(base->EVD_CFG >> SPC_EVD_CFG_REG_EVDSTAT_SHIFT); } /*! @} */ /*! * @name Low Level APIs To Set CORE LDO Regulator * @{ */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_CNTRL_REG) && FSL_FEATURE_MCX_SPC_HAS_CNTRL_REG) /*! * @brief Enable/Disable Core LDO regulator. * * @note The CORE LDO enable bit is write-once. * * @param base SPC peripheral base address. * @param enable Enable/Disable CORE LDO Regulator. * true - Enable CORE LDO Regulator. * false - Disable CORE LDO Regulator. */ static inline void SPC_EnableCoreLDORegulator(SPC_Type *base, bool enable) { if (enable) { base->CNTRL |= SPC_CNTRL_CORELDO_EN_MASK; } else { /* * $Branch Coverage Justification$ * If CORE_LDO is disabled, all RAMs data will powered off. */ base->CNTRL &= ~SPC_CNTRL_CORELDO_EN_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_CNTRL_REG */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DPDOWN_PULLDOWN_DISABLE_BIT) && \ FSL_FEATURE_MCX_SPC_HAS_DPDOWN_PULLDOWN_DISABLE_BIT) /*! * @brief Enable/Disable the CORE LDO Regulator pull down in Deep Power Down. * * @note This function only useful when enabled the CORE LDO Regulator. * * @param base SPC peripheral base address. * @param pulldown Enable/Disable CORE LDO pulldown in Deep Power Down mode. * true - CORE LDO Regulator will discharge in Deep Power Down mode. * false - CORE LDO Regulator will not discharge in Deep Power Down mode. */ static inline void SPC_PullDownCoreLDORegulator(SPC_Type *base, bool pulldown) { if (pulldown) { base->CORELDO_CFG &= ~SPC_CORELDO_CFG_DPDOWN_PULLDOWN_DISABLE_MASK; } else { base->CORELDO_CFG |= SPC_CORELDO_CFG_DPDOWN_PULLDOWN_DISABLE_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_DPDOWN_PULLDOWN_DISABLE_BIT */ /*! * @brief Configs Core LDO Regulator in Active mode. * * @note The bandgap must be enabled before invoking this function. * @note To set Core LDO as low drive strength, all HVDs/LVDs must be disabled previously. * * @param base SPC peripheral base address. * @param option Pointer to the spc_active_mode_core_ldo_option_t structure. * * @retval kStatus_Success Config Core LDO regulator in Active power mode successful. * @retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval kStatus_SPC_BandgapModeWrong Bandgap should be enabled before invoking this function. * @retval kStatus_SPC_CORELDOLowDriveStrengthIgnore To set Core LDO as low drive strength, * all LVDs/HVDs must be disabled before invoking this function. */ status_t SPC_SetActiveModeCoreLDORegulatorConfig(SPC_Type *base, const spc_active_mode_core_ldo_option_t *option); /*! * @brief Set Core LDO Regulator Voltage level in Active mode. * * @param base SPC peripheral base address. * @param voltageLevel Specify the voltage level of CORE LDO Regulator in Active mode, please refer to @ref spc_core_ldo_voltage_level_t. * * @note In active mode, the Core LDO voltage level should only be changed when the * Core LDO is in normal drive strength. * * @note Update Core LDO voltage level will set Busy flag, * this function return only when busy flag is cleared by hardware * * @retval kStatus_SPC_CORELDOVoltageSetFail The drive strength of Core LDO is not normal. * @retval kStatus_Success Set Core LDO regulator voltage level in Active power mode successful. */ status_t SPC_SetActiveModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel); /*! * @brief Gets CORE LDO Regulator Voltage level. * * This function returns the voltage level of CORE LDO Regulator in Active mode. * * @param base SPC peripheral base address. * @return Voltage level of CORE LDO in type of @ref spc_core_ldo_voltage_level_t enumeration. */ static inline spc_core_ldo_voltage_level_t SPC_GetActiveModeCoreLDOVDDVoltageLevel(SPC_Type *base) { return (spc_core_ldo_voltage_level_t)(uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_CORELDO_VDD_LVL_MASK) >> SPC_ACTIVE_CFG_CORELDO_VDD_LVL_SHIFT); } #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) /*! * @brief Set Core LDO VDD Regulator Drive Strength in Active mode. * * @param base SPC peripheral base address. * @param driveStrength Specify the drive strength of CORE LDO Regulator in Active mode, please refer to @ref spc_core_ldo_drive_strength_t. * * @retval #kStatus_Success Set Core LDO regulator drive strength in Active power mode successful. * @retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore If any voltage detect enabled, core_ldo's drive strength can not set to low. * @retval #kStatus_SPC_BandgapModeWrong The selected bandgap mode is not allowed. */ status_t SPC_SetActiveModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength); /*! * @brief Gets CORE LDO VDD Regulator Drive Strength in Active mode. * * @param base SPC peripheral base address. * @return Drive Strength of CORE LDO regulator in Active mode, please refer to @ref spc_core_ldo_drive_strength_t. */ static inline spc_core_ldo_drive_strength_t SPC_GetActiveModeCoreLDODriveStrength(SPC_Type *base) { return (spc_core_ldo_drive_strength_t)(uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK) >> SPC_ACTIVE_CFG_CORELDO_VDD_DS_SHIFT); } #endif /* defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */ /*! * @brief Configs CORE LDO Regulator in low power mode * * This function configs CORE LDO Regulator in Low Power mode. * If CORE LDO VDD Drive Strength is set to Normal, the CORE LDO VDD regulator voltage * level in Active mode must be equal to the voltage level in Low power mode. And the Bandgap * must be programmed to select bandgap enabled. * Core VDD voltage levels for the Core LDO low power regulator can only be changed when the CORE * LDO Drive Strength set as Normal. * * @param base SPC peripheral base address. * @param option Pointer to the spc_lowpower_mode_core_ldo_option_t structure. * * @retval #kStatus_Success Config Core LDO regulator in power mode successfully. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Set driver strength to low will be ignored. * @retval #kStatus_SPC_CORELDOVoltageSetFail. Fail to change Core LDO voltage level. */ status_t SPC_SetLowPowerModeCoreLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_core_ldo_option_t *option); /*! * @brief Set Core LDO VDD Regulator Voltage level in Low power mode. * * @note If CORE LDO's drive strength is set to Normal, the CORE LDO VDD regulator voltage in active mode and low power * mode must be same. * @note Voltage level for the CORE LDO in low power mode can only be changed when the CORE LDO Drive Strength set as * Normal. * * @param base SPC peripheral base address. * @param voltageLevel Voltage level of CORE LDO Regulator in Low power mode, please refer to @ref spc_core_ldo_voltage_level_t. * * @retval #kStatus_SPC_CORELDOVoltageWrong Voltage level in active mode and low power mode is not same. * @retval #kStatus_Success Set Core LDO regulator voltage level in Low power mode successful. * @retval #kStatus_SPC_CORELDOVoltageSetFail Fail to update voltage level because drive strength is incorrect. */ status_t SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel); /*! * @brief Gets the CORE LDO VDD Regulator Voltage Level for Low Power modes. * * @param base SPC peripheral base address. * @return The CORE LDO VDD Regulator's voltage level. */ static inline spc_core_ldo_voltage_level_t SPC_GetLowPowerCoreLDOVDDVoltageLevel(SPC_Type *base) { return ((spc_core_ldo_voltage_level_t)(uint32_t)((base->LP_CFG & SPC_LP_CFG_CORELDO_VDD_LVL_MASK) >> SPC_LP_CFG_CORELDO_VDD_LVL_SHIFT)); } /*! * @brief Set Core LDO VDD Regulator Drive Strength in Low power mode. * * @param base SPC peripheral base address. * @param driveStrength Specify drive strength of CORE LDO in low power mode. * * @retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Some voltage detect enabled, CORE LDO's drive strength can not set * as low. * @retval #kStatus_Success Set Core LDO regulator drive strength in Low power mode successful. * @retval #kStatus_SPC_BandgapModeWrong Bandgap is disabled when attempt to set CORE LDO work as normal drive strength. */ status_t SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength); /*! * @brief Gets CORE LDO VDD Drive Strength for Low Power modes. * * @param base SPC peripheral base address. * @return The CORE LDO's VDD Drive Strength. */ static inline spc_core_ldo_drive_strength_t SPC_GetLowPowerCoreLDOVDDDriveStrength(SPC_Type *base) { return (spc_core_ldo_drive_strength_t)(uint32_t)((base->LP_CFG & SPC_LP_CFG_CORELDO_VDD_DS_MASK) >> SPC_LP_CFG_CORELDO_VDD_DS_SHIFT); } #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) /*! * @name Low Level APIs To Set System LDO Regulator * @{ */ /*! * @brief Enable/Disable System LDO regulator. * * @note The SYSTEM LDO enable bit is write-once. * * @param base SPC peripheral base address. * @param enable Enable/Disable System LDO Regulator. * true - Enable System LDO Regulator. * false - Disable System LDO Regulator. */ static inline void SPC_EnableSystemLDORegulator(SPC_Type *base, bool enable) { if (enable) { base->CNTRL |= SPC_CNTRL_SYSLDO_EN_MASK; } else { /* * $Branch Coverage Justification$ * If SYSTEM_LDO is disabled, may cause some unexpected issues. */ base->CNTRL &= ~SPC_CNTRL_SYSLDO_EN_MASK; } } /*! * @brief Enable/Disable current sink feature of System LDO Regulator. * * @param base SPC peripheral base address. * @param sink Enable/Disable current sink feature. * true - Enable current sink feature of System LDO Regulator. * false - Disable current sink feature of System LDO Regulator. */ static inline void SPC_EnableSystemLDOSinkFeature(SPC_Type *base, bool sink) { if (sink) { base->SYSLDO_CFG |= SPC_SYSLDO_CFG_ISINKEN_MASK; } else { base->SYSLDO_CFG &= ~SPC_SYSLDO_CFG_ISINKEN_MASK; } } /*! * @brief Configs System LDO VDD Regulator in Active mode. * * @note If System LDO VDD Drive Strength is set to Normal, the Bandgap mode in Active mode must be programmed * to a value that enables the bandgap. * @note If any voltage detects are kept enabled, configuration to set System LDO VDD drive strength to low will * be ignored. * @note If select System LDO VDD Regulator voltage level to Over Drive Voltage, the Drive Strength of System LDO VDD * Regulator must be set to Normal otherwise the regulator Drive Strength will be forced to Normal. * @note If select System LDO VDD Regulator voltage level to Over Drive Voltage, the High voltage detect must be * disabled. Otherwise it will be fail to regulator to Over Drive Voltage. * * @param base SPC peripheral base address. * @param option Pointer to the spc_active_mode_sys_ldo_option_t structure. * * @retval #kStatus_Success Config System LDO regulator in Active power mode successful. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_BandgapModeWrong The bandgap is not enabled before invoking this function. * @retval #kStatus_SPC_SYSLDOOverDriveVoltageFail HVD of System VDD is not disable before setting to Over Drive * voltage. * @retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set System LDO VDD regulator's driver strength to Low will be * ignored. */ status_t SPC_SetActiveModeSystemLDORegulatorConfig(SPC_Type *base, const spc_active_mode_sys_ldo_option_t *option); /*! * @brief Set System LDO Regulator voltage level in Active mode. * * @note The system LDO regulator can only operate at the overdrive voltage level for a limited amount of time for the * life of chip. * * @param base SPC peripheral base address. * @param voltageLevel Specify the voltage level of System LDO Regulator in Active mode. * * @retval #kStatus_Success Set System LDO Regulator voltage level in Active mode successfully. * @retval #kStatus_SPC_SYSLDOOverDriveVoltageFail Must disable system LDO high voltage detector before specifying * overdrive voltage. */ status_t SPC_SetActiveModeSystemLDORegulatorVoltageLevel(SPC_Type *base, spc_sys_ldo_voltage_level_t voltageLevel); /*! * @brief Get System LDO Regulator voltage level in Active mode. * * @param base SPC peripheral base address. * @return System LDO Regulator voltage level in Active mode, please refer to @ref spc_sys_ldo_voltage_level_t. */ static inline spc_sys_ldo_voltage_level_t SPC_GetActiveModeSystemLDORegulatorVoltageLevel(SPC_Type *base) { return (spc_sys_ldo_voltage_level_t)(uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_SYSLDO_VDD_LVL_MASK) >> SPC_ACTIVE_CFG_SYSLDO_VDD_LVL_SHIFT); } /*! * @brief Set System LDO Regulator Drive Strength in Active mode. * * @param base SPC peripheral base address. * @param driveStrength Specify the drive strength of System LDO Regulator in Active mode. * * @retval #kStatus_Success Set System LDO Regulator drive strength in Active mode successfully. * @retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any voltage detect feature is enabled in active mode. * @retval #kStatus_SPC_BandgapModeWrong Bandgap mode in Active mode must be programmed to a value that enables the bandgap if attempt to specify normal drive strength. */ status_t SPC_SetActiveModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength); /*! * @brief Get System LDO Regulator Drive Strength in Active mode. * * @param base SPC peripheral base address. * @return System LDO regulator drive strength in Active mode, please refer to @ref spc_sys_ldo_drive_strength_t. */ static inline spc_sys_ldo_drive_strength_t SPC_GetActiveModeSystemLDORegulatorDriveStrength(SPC_Type *base) { return (spc_sys_ldo_drive_strength_t)(uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK) >> SPC_ACTIVE_CFG_SYSLDO_VDD_DS_SHIFT); } /*! * @brief Configs System LDO regulator in low power modes. * * This function configs System LDO regulator in low power modes. * If System LDO VDD Regulator Drive strength is set to normal, bandgap mode in low power * mode must be programmed to a value that enables the Bandgap. * If any High voltage detectors or Low Voltage detectors are kept enabled, configuration * to set System LDO Regulator drive strength as Low will be ignored. * * @param base SPC peripheral base address. * @param option Pointer to spc_lowpower_mode_sys_ldo_option_t structure. * * @retval #kStatus_Success Config System LDO regulator in Low Power Mode successfully. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored. */ status_t SPC_SetLowPowerModeSystemLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_sys_ldo_option_t *option); /*! * @brief Set System LDO Regulator drive strength in Low Power Mode. * * @param base SPC peripheral base address. * @param driveStrength Specify the drive strength of System LDO Regulator in Low Power Mode. * * @retval #kStatus_Success Set System LDO Regulator drive strength in Low Power Mode successfully. * @retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any voltage detect feature is enabled in low power mode. * @retval #kStatus_SPC_BandgapModeWrong Bandgap mode in low power mode must be programmed to a value that enables the bandgap if attempt to specify normal drive strength. */ status_t SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength); /*! * @brief Get System LDO Regulator drive strength in Low Power Mode. * * @param base SPC peripheral base address. * @return System LDO regulator drive strength in Low Power Mode, please refer to @ref spc_sys_ldo_drive_strength_t. */ static inline spc_sys_ldo_drive_strength_t SPC_GetLowPowerModeSystemLDORegulatorDriveStrength(SPC_Type *base) { return (spc_sys_ldo_drive_strength_t)(uint32_t)((base->LP_CFG & SPC_LP_CFG_SYSLDO_VDD_DS_MASK) >> SPC_LP_CFG_SYSLDO_VDD_DS_SHIFT); } /*! @} */ #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */ #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC) /*! * @name Low Level APIs To Set DCDC Regulator * @{ */ /*! * @brief Enable/Disable DCDC Regulator. * * @note The DCDC enable bit is write-once, settings only reset after a POR, LVD, or HVD event. * * @param base SPC peripheral base address. * @param enable Enable/Disable DCDC Regulator. * true - Enable DCDC Regulator. * false - Disable DCDC Regulator. */ static inline void SPC_EnableDCDCRegulator(SPC_Type *base, bool enable) { if (enable) { base->CNTRL |= SPC_CNTRL_DCDC_EN_MASK; } else { /* * $Branch Coverage Justification$ * If DCDC is disabled, all RAMs data will powered off. */ base->CNTRL &= ~SPC_CNTRL_DCDC_EN_MASK; } } /*! * @brief Config DCDC Burst options * * @param base SPC peripheral base address. * @param config Pointer to spc_dcdc_burst_config_t structure. */ void SPC_SetDCDCBurstConfig(SPC_Type *base, spc_dcdc_burst_config_t *config); /*! * @brief Trigger a software burst request to DCDC. * * @param base SPC peripheral base address. */ static inline void SPC_TriggerDCDCBurstRequest(SPC_Type *base) { /* Blocking until previous DCDC burst completed. */ while ((base->DCDC_BURST_CFG & SPC_DCDC_BURST_CFG_BURST_ACK_MASK) == 0UL) { } base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_REQ_MASK; } /*! * @brief Check if burst acknowledge flag is asserted. * * @param base SPC peripheral base address. * * @retval false DCDC burst not complete. * @retval true DCDC burst complete. */ static inline bool SPC_CheckDCDCBurstAck(SPC_Type *base) { return ((base->DCDC_BURST_CFG & SPC_DCDC_BURST_CFG_BURST_ACK_MASK) != 0UL); } /*! * @brief Clear DCDC busrt acknowledge flag. * * @param base SPC periphral base address. */ static inline void SPC_ClearDCDCBurstAckFlag(SPC_Type *base) { base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_ACK_MASK; } /*! * @brief Set the count value of the reference clock to configure the period of DCDC not active. * * @note This function is only useful when DCDC's drive strength is set as pulse refresh. * @note The pulse duration(time between on and off) is: reference clock period * (count + 2). * * @param base SPC peripheral base address. * @param count The count value, 16 bit width. */ void SPC_SetDCDCRefreshCount(SPC_Type *base, uint16_t count); #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC_CFG_BLEED_EN) && FSL_FEATURE_MCX_SPC_HAS_DCDC_CFG_BLEED_EN) /*! * @brief Enable a bleed resistor to discharge DCDC output when DCDC is disabled. * * @param base SPC peripheral base address. * @param enable Used to enable/disable bleed resistor. */ static inline void SPC_EnableDCDCBleedResistor(SPC_Type *base, bool enable) { if (enable) { base->DCDC_CFG |= SPC_DCDC_CFG_BLEED_EN_MASK; } else { base->DCDC_CFG &= ~SPC_DCDC_CFG_BLEED_EN_MASK; } } #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC_CFG_BLEED_EN */ /*! * @brief Configs DCDC_CORE Regulator in Active mode. * * @note When changing the DCDC output voltage level, take care to change the CORE LDO voltage level. * * @param base SPC peripheral base address. * @param option Pointer to the spc_active_mode_dcdc_option_t structure. * * @retval #kStatus_Success Config DCDC regulator in Active power mode successful. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_BandgapModeWrong Set DCDC_CORE Regulator drive strength to Normal, the Bandgap must be enabled. */ status_t SPC_SetActiveModeDCDCRegulatorConfig(SPC_Type *base, const spc_active_mode_dcdc_option_t *option); /*! * @brief Set DCDC_CORE Regulator voltage level in Active mode. * * @note When changing the DCDC output voltage level, take care to change the CORE LDO voltage level. * * @param base SPC peripheral base address. * @param voltageLevel Specify the DCDC_CORE Regulator voltage level, please refer to @ref spc_dcdc_voltage_level_t. */ static inline void SPC_SetActiveModeDCDCRegulatorVoltageLevel(SPC_Type *base, spc_dcdc_voltage_level_t voltageLevel) { base->ACTIVE_CFG = (base->ACTIVE_CFG & (~SPC_ACTIVE_CFG_DCDC_VDD_LVL_MASK)) | SPC_ACTIVE_CFG_DCDC_VDD_LVL(voltageLevel); } /*! * @brief Get DCDC_CORE Regulator voltage level in Active mode. * * @param base SPC peripheral base address. * @return DCDC_CORE Regulator voltage level, please refer to @ref spc_dcdc_voltage_level_t. */ static inline spc_dcdc_voltage_level_t SPC_GetActiveModeDCDCRegulatorVoltageLevel(SPC_Type *base) { return (spc_dcdc_voltage_level_t)((uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_DCDC_VDD_LVL_MASK) >> SPC_ACTIVE_CFG_DCDC_VDD_LVL_SHIFT)); } /*! * @brief Set DCDC_CORE Regulator drive strength in Active mode. * * @note To set DCDC drive strength as Normal, the bandgap must be enabled. * * @param base SPC peripheral base address. * @param driveStrength Specify the DCDC_CORE regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. * * @retval #kStatus_Success Set DCDC_CORE Regulator drive strength in Active mode successfully. * @retval #kStatus_SPC_BandgapModeWrong Set DCDC_CORE Regulator drive strength to Normal, the Bandgap must be enabled. */ status_t SPC_SetActiveModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength); /*! * @brief Get DCDC_CORE Regulator drive strength in Active mode. * * @param base SPC peripheral base address. * @return DCDC_CORE Regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. */ static inline spc_dcdc_drive_strength_t SPC_GetActiveModeDCDCRegulatorDriveStrength(SPC_Type *base) { return (spc_dcdc_drive_strength_t)((uint32_t)((base->ACTIVE_CFG & SPC_ACTIVE_CFG_DCDC_VDD_DS_MASK) >> SPC_ACTIVE_CFG_DCDC_VDD_DS_SHIFT)); } /*! * @brief Configs DCDC_CORE Regulator in Low power modes. * * @note If DCDC_CORE Drive Strength is set to Normal, the Bandgap mode in Low Power mode must be programmed * to a value that enables the Bandgap. * @note In Deep Power Down mode, DCDC regulator is always turned off. * * @param base SPC peripheral base address. * @param option Pointer to the spc_lowpower_mode_dcdc_option_t structure. * * @retval #kStatus_Success Config DCDC regulator in low power mode successfully. * @retval #kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition. * @retval #kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power mode is wrong. */ status_t SPC_SetLowPowerModeDCDCRegulatorConfig(SPC_Type *base, const spc_lowpower_mode_dcdc_option_t *option); /*! * @brief Set DCDC_CORE Regulator drive strength in Low power mode. * * @note To set drive strength as normal, the bandgap must be enabled. * * @param base SPC peripheral base address. * @param driveStrength Specify the DCDC_CORE Regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. * * @retval #kStatus_Success Set DCDC_CORE Regulator drive strength in Low power mode successfully. * @retval #kStatus_SPC_BandgapModeWrong Set DCDC_CORE Regulator drive strength to Normal, the Bandgap must be enabled. */ status_t SPC_SetLowPowerModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength); /*! * @brief Get DCDC_CORE Regulator drive strength in Low power mode. * * @param base SPC peripheral base address. * @return DCDC_CORE Regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t. */ static inline spc_dcdc_drive_strength_t SPC_GetLowPowerModeDCDCRegulatorDriveStrength(SPC_Type *base) { return (spc_dcdc_drive_strength_t)((uint32_t)((base->LP_CFG & SPC_LP_CFG_DCDC_VDD_DS_MASK) >> SPC_LP_CFG_DCDC_VDD_DS_SHIFT)); } /*! * @brief Set DCDC_CORE Regulator voltage level in Low power mode. * * @note To change DCDC level in Low-Power mode: * 1. Configure LP_CFG[DCDC_VDD_LVL] to desired level; * 2. Configure LP_CFG[DCDC_VDD_DS] to low driver strength; * 3. Configure ACTIVE_CFG[DCDC_VDD_LVL] to same level programmed in #1. * * @note After invoking this function, the voltage level in active mode(wakeup from low power modes) also changed, * if it is necessary, please invoke SPC_SetActiveModeDCDCRegulatorVoltageLevel() to change to desried voltage level. * * @param base SPC peripheral base address. * @param voltageLevel Specify the DCDC_CORE Regulator voltage level, please refer to @ref spc_dcdc_voltage_level_t. */ static inline void SPC_SetLowPowerModeDCDCRegulatorVoltageLevel(SPC_Type *base, spc_dcdc_voltage_level_t voltageLevel) { base->LP_CFG = (base->LP_CFG & (~SPC_LP_CFG_DCDC_VDD_LVL_MASK)) | SPC_LP_CFG_DCDC_VDD_LVL(voltageLevel); (void)SPC_SetLowPowerModeDCDCRegulatorDriveStrength(base, kSPC_DCDC_LowDriveStrength); SPC_SetActiveModeDCDCRegulatorVoltageLevel(base, voltageLevel); } /*! * @brief Get DCDC_CORE Regulator voltage level in Low power mode. * * @param base SPC peripheral base address. * @return DCDC_CORE Regulator voltage level, please refer to @ref spc_dcdc_voltage_level_t. */ static inline spc_dcdc_voltage_level_t SPC_GetLowPowerModeDCDCRegulatorVoltageLevel(SPC_Type *base) { return (spc_dcdc_voltage_level_t)((uint32_t)((base->LP_CFG & SPC_LP_CFG_DCDC_VDD_LVL_MASK) >> SPC_LP_CFG_DCDC_VDD_LVL_SHIFT)); } /*! @} */ #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */ #if defined(__cplusplus) } #endif /* __cplusplus */ /*! @} */ #endif /* FSL_SPC_H_ */ ================================================ FILE: hw/bsp/mcx/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_lpuart.h" #include "board.h" #include "pin_mux.h" #include "clock_config.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_MCXN9 void USB0_FS_IRQHandler(void) { tusb_int_handler(0, true); } void USB1_HS_IRQHandler(void) { tusb_int_handler(1, true); } #elif CFG_TUSB_MCU == OPT_MCU_MCXA15 void USB0_IRQHandler(void) { tusb_int_handler(0, true); } #endif void board_init(void) { BOARD_InitBootPins(); BOARD_InitBootClocks(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) #if CFG_TUSB_MCU == OPT_MCU_MCXN9 NVIC_SetPriority(USB0_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB1_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #else NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #endif // LED CLOCK_EnableClock(LED_CLK); gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); board_led_write(0); #ifdef NEOPIXEL_PIN // No neo pixel support yet #endif // Button #ifdef BUTTON_GPIO CLOCK_EnableClock(BUTTON_CLK); gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); #endif #ifdef UART_DEV // Enable UART when debug log is on board_uart_init_clock(); lpuart_config_t uart_config; LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; LPUART_Init(UART_DEV, &uart_config, 12000000u); #endif // USB VBUS /* PORT0 PIN22 configured as USB0_VBUS */ #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 0 // Port0 is Full Speed #if CFG_TUSB_MCU == OPT_MCU_MCXA15 RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); #elif CFG_TUSB_MCU == OPT_MCU_MCXN9 CLOCK_AttachClk(kCLK_48M_to_USB0); CLOCK_EnableClock(kCLOCK_Usb0Ram); CLOCK_EnableClock(kCLOCK_Usb0Fs); #endif CLOCK_EnableUsbfsClock(); #endif #if defined(BOARD_TUD_RHPORT) && BOARD_TUD_RHPORT == 1 && (CFG_TUSB_MCU == OPT_MCU_MCXN9) // Port1 is High Speed // Power SPC0->ACTIVE_VDELAY = 0x0500; /* Change the power DCDC to 1.8v (By default, DCDC is 1.8V), CORELDO to 1.1v (By default, CORELDO is 1.0V) */ SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK; SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) | SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u); /* Wait until it is done */ while (SPC0->SC & SPC_SC_BUSY_MASK) {} if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) { SCG0->TRIM_LOCK = 0x5a5a0001U; SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK; /* wait LDO ready */ while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK)); } SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK; SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK); /* xtal = 20 ~ 30MHz */ SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT); SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK; while (1) { if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) { break; } } // Clock SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK; CLOCK_EnableClock(kCLOCK_UsbHs); CLOCK_EnableClock(kCLOCK_UsbHsPhy); CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U); CLOCK_EnableUsbhsClock(); // USB PHY #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) USBPHY->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */ #endif // Enable PHY support for Low speed device + LS via FS Hub USBPHY->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; // Enable all power for normal operation USBPHY->PWD = 0; // TX Timing uint32_t phytx = USBPHY->TX; phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); phytx |= USBPHY_TX_D_CAL(0x04) | USBPHY_TX_TXCAL45DP(0x07) | USBPHY_TX_TXCAL45DM(0x07); //phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); USBPHY->TX = phytx; #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { #ifdef BUTTON_GPIO return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); #endif } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV LPUART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/mcx/family.cmake ================================================ include_guard() set(MCUX_DIR ${TOP}/hw/mcu/nxp/mcuxsdk-core) set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-devices-mcx) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up if (MCU_VARIANT STREQUAL "MCXA153") set(CMAKE_SYSTEM_CPU cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") elseif (MCU_VARIANT STREQUAL "MCXA156") set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") elseif (MCU_VARIANT STREQUAL "MCXN947") set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") else() message(FATAL_ERROR "MCU_VARIANT not supported") endif() set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) endif() set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/iar/${MCU_CORE}_flash.icf) endif () if (NOT DEFINED STARTUP_FILE_IAR) set(STARTUP_FILE_IAR ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/iar/startup_${MCU_CORE}.s) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver ${MCUX_DIR}/drivers/gpio/fsl_gpio.c ${MCUX_DIR}/drivers/common/fsl_common_arm.c ${MCUX_DIR}/drivers/lpuart/fsl_lpuart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/drivers/spc/fsl_spc.c # mcu ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/system_${MCU_CORE}.c ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/drivers/fsl_reset.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_DIR}/CMSIS/Core/Include ${MCUX_DIR}/drivers/gpio/ ${MCUX_DIR}/drivers/lpuart ${MCUX_DIR}/drivers/common ${MCUX_DIR}/drivers/port ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/drivers/spc ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT} ${SDK_DIR}/${MCU_FAMILY}/${MCU_VARIANT}/drivers ) if (${FAMILY_MCUS} STREQUAL "MCXN9") target_sources(${BOARD_TARGET} PRIVATE ${MCUX_DIR}/drivers/lpflexcomm/fsl_lpflexcomm.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${MCUX_DIR}/drivers/lpflexcomm ) elseif(${FAMILY_MCUS} STREQUAL "MCXA15") endif() update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) if (${FAMILY_MCUS} STREQUAL "MCXN9") family_add_tinyusb(${TARGET} OPT_MCU_MCXN9) elseif(${FAMILY_MCUS} STREQUAL "MCXA15") family_add_tinyusb(${TARGET} OPT_MCU_MCXA15) endif() target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/chipidea/$ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs "LINKER:--defsym=__stack_size__=0x1000" "LINKER:--defsym=__heap_size__=0" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" "LINKER:--config_def=__stack_size__=0x1000" "LINKER:--config_def=__heap_size__=0" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_nxplink(${TARGET}) #family_flash_pyocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/mcx/family.mk ================================================ UF2_FAMILY_ID = 0x2abc77ec include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 MCUX_DIR = hw/mcu/nxp/mcuxsdk-core SDK_DIR = hw/mcu/nxp/mcux-devices-mcx # Default to Highspeed PORT1 PORT ?= 1 CFLAGS += \ -flto \ -DBOARD_TUD_RHPORT=$(PORT) \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration -Wno-error=redundant-decls LDFLAGS_GCC += \ --specs=nosys.specs --specs=nano.specs \ -Wl,--defsym=__stack_size__=0x1000 \ -Wl,--defsym=__heap_size__=0 \ # All source paths should be relative to the top level. LD_FILE ?= $(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS ifeq ($(PORT), 1) $(info "PORT1 High Speed") CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED SRC_C += src/portable/chipidea/ci_hs/dcd_ci_hs.c else $(info "PORT0 Full Speed") CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED SRC_C += src/portable/chipidea/ci_fs/dcd_ci_fs.c endif SRC_C += \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/system_$(MCU_CORE).c \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/drivers/fsl_reset.c \ $(TOP)/$(MCUX_DIR)/drivers/gpio/fsl_gpio.c \ $(TOP)/$(MCUX_DIR)/drivers/lpuart/fsl_lpuart.c \ $(TOP)/$(MCUX_DIR)/drivers/common/fsl_common_arm.c \ hw/bsp/mcx/drivers/spc/fsl_spc.c # fsl_lpflexcomm for MCXN9 ifeq ($(MCU_VARIANT), MCXN947) SRC_C += $(MCUX_DIR)/drivers/lpflexcomm/fsl_lpflexcomm.c endif # fsl_spc for MCXNA15 ifeq ($(MCU_VARIANT), MCXA153) endif INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT) \ $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/drivers \ $(TOP)/$(MCUX_DIR)/drivers/ \ $(TOP)/$(MCUX_DIR)/drivers/lpuart \ $(TOP)/$(MCUX_DIR)/drivers/lpflexcomm \ $(TOP)/$(MCUX_DIR)/drivers/common \ $(TOP)/$(MCUX_DIR)/drivers/gpio \ $(TOP)/$(MCUX_DIR)/drivers/port \ $(TOP)/hw/bsp/mcx/drivers/spc SRC_S += $(TOP)/$(SDK_DIR)/$(MCU_FAMILY)/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S ================================================ FILE: hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "mm32_device.h" extern u32 SystemCoreClock; #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake ================================================ set(MCU_VARIANT mm32f327x) set(JLINK_DEVICE MM32F3273G8P) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC HSE_VALUE=12000000 ) endfunction() ================================================ FILE: hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h ================================================ /* metadata: name: DshanMCU Pitaya Lite with MM32F3273G8P url: https://gitee.com/weidongshan/DshanMCU-Pitaya-c */ #ifndef BOARD_H #define BOARD_H // GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_1 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_Pin_0 #define BUTTON_STATE_ACTIVE 0 #endif ================================================ FILE: hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk ================================================ MCU_VARIANT = mm32f327x CFLAGS += \ -DHSE_VALUE=12000000 LD_FILE = $(BOARD_PATH)/flash.ld # For flash-jlink target JLINK_DEVICE = MM32F3273G8P # flash target using on-board stlink #flash: flash-jlink ================================================ FILE: hw/bsp/mm32/boards/mm32f327x_pitaya_lite/flash.ld ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 MM32 SE TEAM * * 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. * * This file is part of the TinyUSB stack. */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x2001FFFF; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/mm32/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 MM32 SE TEAM * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: MindMotion */ #include "hal_conf.h" #include "mm32_device.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif extern u32 SystemCoreClock; #ifdef __GNUC__ #pragma GCC diagnostic pop #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void OTG_FS_IRQHandler(void) { tud_int_handler(0); } void USB_DeviceClockInit(void) { /* Select USBCLK source */ // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); RCC->CFGR &= ~(0x3 << 22); RCC->CFGR |= (0x1 << 22); /* Enable USB clock */ RCC->AHB2ENR |= 0x1 << 7; } void board_init(void) { // usb clock USB_DeviceClockInit(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); NVIC_SetPriority(SysTick_IRQn, 0x0); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // LED GPIO_InitTypeDef GPIO_InitStruct; GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); board_led_write(true); #ifdef BUTTON_PORT GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = BUTTON_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStruct.GPIO_Mode = BUTTON_STATE_ACTIVE ? GPIO_Mode_IPD : GPIO_Mode_IPU; GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #endif #ifdef UART_DEV // UART UART_InitTypeDef UART_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock GPIO_PinAFConfig(GPIOA, UART_TX_PIN, UART_GPIO_AF); GPIO_PinAFConfig(GPIOA, UART_RX_PIN, UART_GPIO_AF); UART_StructInit(&UART_InitStruct); UART_InitStruct.UART_BaudRate = CFG_BOARD_UART_BAUDRATE; UART_InitStruct.UART_WordLength = UART_WordLength_8b; UART_InitStruct.UART_StopBits = UART_StopBits_1; UART_InitStruct.UART_Parity = UART_Parity_No; UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; UART_Init(UART_DEV, &UART_InitStruct); UART_Cmd(UART_DEV, ENABLE); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = 1 << UART_TX_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = 1 << UART_RX_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { #ifdef BUTTON_PORT return GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN) == BUTTON_STATE_ACTIVE; #else return 0; #endif } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV const char* buff = buf; while (len) { while ((UART1->CSR & UART_IT_TXIEN) == 0); //The loop is sent until it is finished UART1->TDR = (*buff & 0xFF); buff++; len--; } return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/mm32/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) string(REPLACE "mm32f" "MM32F" MCU_VARIANT_UPPER ${MCU_VARIANT}) set(SDK_DIR ${TOP}/hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS MM32F327X CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR_StartAsm/startup_${MCU_VARIANT}_iar.s) set(LD_FILE_Clang ${LD_FILE_GNU}) # set(LD_FILE_IAR ) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Source/system_${MCU_VARIANT}.c ${SDK_DIR}/HAL_Lib/Src/hal_gpio.c ${SDK_DIR}/HAL_Lib/Src/hal_rcc.c ${SDK_DIR}/HAL_Lib/Src/hal_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_5}/CMSIS/Core/Include ${SDK_DIR}/Include ${SDK_DIR}/HAL_Lib/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_MM32F327X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/mm32/family.mk ================================================ UF2_FAMILY_ID = 0x0 include $(TOP)/$(BOARD_PATH)/board.mk MCU_VARIANT_UPPER = $(subst mm32f,MM32F,${MCU_VARIANT}) SDK_DIR = hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER} CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_MM32F327X \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized -Wno-error=cast-qual LDFLAGS_GCC += \ -nostdlib -nostartfiles \ -specs=nosys.specs -specs=nano.specs \ SRC_C += \ src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c \ $(SDK_DIR)/Source/system_${MCU_VARIANT}.c \ $(SDK_DIR)/HAL_Lib/Src/hal_gpio.c \ $(SDK_DIR)/HAL_Lib/Src/hal_rcc.c \ $(SDK_DIR)/HAL_Lib/Src/hal_uart.c \ SRC_S += ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/Include \ $(TOP)/$(SDK_DIR)/HAL_Lib/Inc ================================================ FILE: hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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 *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "msp430.h" #endif #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 #define configCPU_CLOCK_HZ ( ( unsigned long ) 7995392 ) /* Clock setup from main.c in the demo application. */ #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 4 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1700 ) ) #define configMAX_TASK_NAME_LEN ( 8 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 1 #define configIDLE_SHOULD_YIELD 1 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #endif /* FREERTOS_CONFIG_H */ ================================================ FILE: hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake ================================================ set(MCU_VARIANT msp430f5529) set(LD_FILE_GNU ${SDK_DIR}/msp430f5529.ld) function(update_board TARGET) target_compile_definitions(${TARGET} INTERFACE __MSP430F5529__ ) endfunction() ================================================ FILE: hw/bsp/msp430/boards/msp_exp430f5529lp/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: MSP430F5529 LaunchPad url: https://www.ti.com/tool/MSP-EXP430F5529LP */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT P1OUT #define LED_PIN BIT0 #define LED_STATE_ON 1 #define BUTTON_PORT P1IN #define BUTTON_PIN BIT1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk ================================================ CFLAGS += \ -D__MSP430F5529__ \ LD_FILE = ${SDK_DIR}/msp430f5529.ld ================================================ FILE: hw/bsp/msp430/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Texas Instruments */ #include "bsp/board_api.h" #include "board.h" #include "msp430.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_UBM_ISR(void) __attribute__ ((interrupt(USB_UBM_VECTOR))); void USB_UBM_ISR(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ uint32_t cnt = 0; static void SystemClock_Config(void) { WDTCTL = WDTPW + WDTHOLD; // Disable watchdog. // Increase VCore to level 2- required for 16 MHz operation on this MCU. PMMCTL0 = PMMPW + PMMCOREV_2; UCSCTL3 = SELREF__XT2CLK; // FLL is fed by XT2. // XT1 used for ACLK (default- not used in this demo) P5SEL |= BIT4; // Required to enable XT1 // Loop until XT1 fault flag is cleared. do { UCSCTL7 &= ~XT1LFOFFG; }while(UCSCTL7 & XT1LFOFFG); // XT2 is 4 MHz an external oscillator, use PLL to boost to 16 MHz. P5SEL |= BIT2; // Required to enable XT2. // Loop until XT2 fault flag is cleared do { UCSCTL7 &= ~XT2OFFG; }while(UCSCTL7 & XT2OFFG); // Kickstart the DCO into the correct frequency range, otherwise a // fault will occur. // FIXME: DCORSEL_6 should work according to datasheet params, but generates // a fault. I am not sure why it faults. UCSCTL1 = DCORSEL_7; UCSCTL2 = FLLD_2 + 3; // DCO freq = D * (N + 1) * (FLLREFCLK / n) // DCOCLKDIV freq = (N + 1) * (FLLREFCLK / n) // N = 3, D = 2, thus DCO freq = 32 MHz. // MCLK configured for 16 MHz using XT2. // SMCLK configured for 8 MHz using XT2. UCSCTL4 |= SELM__DCOCLKDIV + SELS__DCOCLKDIV; UCSCTL5 |= DIVM__16 + DIVS__2; // Now wait till everything's stabilized. do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); SFRIFG1 &= ~OFIFG; }while(SFRIFG1 & OFIFG); // Configure Timer A to use SMCLK as a source. Count 1000 ticks at 1 MHz. TA0CCTL0 |= CCIE; TA0CCR0 = 999; // 1000 ticks. TA0CTL |= TASSEL_2 + ID_3 + MC__UP; // Use SMCLK, divide by 8, start timer. // Initialize USB power and PLL. USBKEYPID = USBKEY; // VUSB enabled automatically. // Wait two milliseconds to stabilize, per manual recommendation. uint32_t ms_elapsed = tusb_time_millis_api(); do { while((tusb_time_millis_api() - ms_elapsed) < 2); }while(!(USBPWRCTL & USBBGVBV)); // USB uses XT2 (4 MHz) directly. Enable the PLL. USBPLLDIVB |= USBPLL_SETCLK_4_0; USBPLLCTL |= (UPFDEN | UPLLEN); // Wait until PLL locks. Check every 2ms, per manual. ms_elapsed = tusb_time_millis_api(); do { USBPLLIR &= ~USBOOLIFG; while((tusb_time_millis_api() - ms_elapsed) < 2); }while(USBPLLIR & USBOOLIFG); USBKEYPID = 0; } uint32_t wait = 0; void board_init(void) { __bis_SR_register(GIE); // Enable interrupts. SystemClock_Config(); // Enable basic I/O. P1DIR |= LED_PIN; // LED output. P1REN |= BUTTON_PIN; // Internal resistor enable. P1OUT |= BUTTON_PIN; // Pullup. // Enable the backchannel UART (115200) P4DIR |= BIT5; P4SEL |= (BIT5 | BIT4); UCA1CTL1 |= (UCSSEL__SMCLK | UCSWRST); // Hold in reset, use SMCLK. UCA1BRW = 4; UCA1MCTL |= (UCBRF_3 | UCBRS_5 | UCOS16); // Overampling mode, 115200 baud. // Copied from manual. UCA1CTL1 &= ~UCSWRST; // Set up USB pins. USBKEYPID = USBKEY; USBPHYCTL |= PUSEL; // Convert USB D+/D- pins to USB functionality. USBKEYPID = 0; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { if(state) { LED_PORT |= LED_PIN; } else { LED_PORT &= ~LED_PIN; } } uint32_t board_button_read(void) { return ((P1IN & BIT1) >> 1) == BUTTON_STATE_ACTIVE; } int board_uart_read(uint8_t * buf, int len) { for(int i = 0; i < len; i++) { // Wait until something to receive (cleared by reading buffer). while(!(UCA1IFG & UCRXIFG)); buf[i] = UCA1RXBUF; } return len; } int board_uart_write(void const * buf, int len) { const char * char_buf = (const char *) buf; for(int i = 0; i < len; i++) { // Wait until TX buffer is empty (cleared by writing buffer). while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = char_buf[i]; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void TIMER0_A0_ISR (void) __attribute__ ((interrupt(TIMER0_A0_VECTOR))); void TIMER0_A0_ISR (void) { system_ticks++; // TAxCCR0 CCIFG resets itself as soon as interrupt is invoked. } uint32_t tusb_time_millis_api(void) { uint32_t systick_mirror; // 32-bit update is not atomic on MSP430. We can read the bottom 16-bits, // an interrupt occurs, updates _all_ 32 bits, and then we return a // garbage value. And I've seen it happen! TA0CCTL0 &= ~CCIE; systick_mirror = system_ticks; TA0CCTL0 |= CCIE; return systick_mirror; } #endif ================================================ FILE: hw/bsp/msp430/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/ti/msp430/msp430-gcc-support-files/include) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU msp430 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/msp430_${TOOLCHAIN}.cmake) set(FAMILY_MCUS MSP430x5xx CACHE INTERNAL "") #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} INTERFACE) target_compile_definitions(${BOARD_TARGET} INTERFACE CFG_TUD_ENDPOINT0_SIZE=8 CFG_EXAMPLE_VIDEO_READONLY CFG_EXAMPLE_MSC_READONLY ) target_include_directories(${BOARD_TARGET} INTERFACE ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${SDK_DIR} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_MSP430x5xx) #---------- Port Specific ---------- # These files are built for each example since it depends on example's tusb_config.h target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c ) target_include_directories(${TARGET} PUBLIC # family, hw, board ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -L${SDK_DIR} ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () # Flashing family_add_bin_hex(${TARGET}) family_flash_msp430flasher(${TARGET}) endfunction() ================================================ FILE: hw/bsp/msp430/family.mk ================================================ CROSS_COMPILE = msp430-elf- SKIP_NANOLIB = 1 SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUD_ENDPOINT0_SIZE=8 LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c INC += \ ${TOP}/${SDK_DIR} \ $(TOP)/$(BOARD_PATH) # export for libmsp430.so to same installation ifneq ($(OS),Windows_NT) export LD_LIBRARY_PATH=$(dir $(shell which MSP430Flasher)) endif # flash target using TI MSP430-Flasher # http://www.ti.com/tool/MSP430-FLASHER # Please add its installation dir to PATH flash: $(BUILD)/$(PROJECT).hex MSP430Flasher -w $< -z [VCC] # flash target using mspdebug. flash-mspdebug: $(BUILD)/$(PROJECT).elf $(MSPDEBUG) tilib "prog $<" --allow-fw-update ================================================ FILE: hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "msp.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<PCCAN = 0u; #ifdef __MCU_HAS_LCD0__ SYSCTL->PCLCD = 0u; #endif SYSCTL->PCEMAC = 0u; SYSCTL->PCEPHY = 0u; SYSCTL->PCCCM = 0u; /* --- Setup system clock --- */ /* Start power-up process of the main oscillator */ SYSCTL->MOSCCTL = SYSCTL_MOSCCTL_OSCRNG; while (!(SYSCTL->RIS & SYSCTL_RIS_MOSCPUPRIS)) ; /* Wait for completion */ SYSCTL->MISC = SYSCTL_MISC_MOSCPUPMIS; /* Clear the completion interrupt status */ /* Set the main oscillator to PLL reference clock */ SYSCTL->RSCLKCFG = SYSCTL_RSCLKCFG_PLLSRC_MOSC; /* PLL freq. = (MOSC freq. / 10) * 96 = 240MHz */ SYSCTL->PLLFREQ1 = (4 << SYSCTL_PLLFREQ1_N_S) | (1 << SYSCTL_PLLFREQ1_Q_S); SYSCTL->PLLFREQ0 = (96 << SYSCTL_PLLFREQ0_MINT_S) | SYSCTL_PLLFREQ0_PLLPWR; /* Set BCHT=6, BCE=0, WS=5 for 120MHz system clock */ SYSCTL->MEMTIM0 = SYSCTL_MEMTIM0_EBCHT_3_5 | (5 << SYSCTL_MEMTIM0_EWS_S) | SYSCTL_MEMTIM0_FBCHT_3_5 | (5 << SYSCTL_MEMTIM0_FWS_S) | SYSCTL_MEMTIM0_MB1; /* Wait for completion of PLL power-up process */ while (!(SYSCTL->RIS & SYSCTL_RIS_PLLLRIS)) ; SYSCTL->MISC = SYSCTL_MISC_PLLLMIS; /* Clear the completion interrupt status */ /* Switch the system clock to PLL/4 */ SYSCTL->RSCLKCFG = SYSCTL_RSCLKCFG_MEMTIMU | SYSCTL_RSCLKCFG_ACG | SYSCTL_RSCLKCFG_USEPLL | SYSCTL_RSCLKCFG_PLLSRC_MOSC | (1 << SYSCTL_RSCLKCFG_PSYSDIV_S); SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif /* USR_LED1 ON1 */ bits = TU_BIT(CLK_LED); SYSCTL->RCGCGPIO |= bits; while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_LED->DIR = TU_BIT(GPIO_LED_PIN); GPIO_LED->DEN = TU_BIT(GPIO_LED_PIN); /* USR_SW1 PJ0 */ bits = TU_BIT(CLK_BUTTON); SYSCTL->RCGCGPIO |= bits; while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_BUTTON->PUR = TU_BIT(GPIO_BUTTON_PIN); GPIO_BUTTON->DEN = TU_BIT(GPIO_BUTTON_PIN); /* UART PA0,1 */ bits = TU_BIT(0); SYSCTL->RCGCGPIO |= bits; while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIOA->AFSEL = 3u; GPIOA->PCTL = 0x11u; GPIOA->DEN = 3u; SYSCTL->RCGCUART |= 1u << 0; while (!(SYSCTL->PRUART & (1u << 0))) ; UART0->CTL = 0; UART0->IBRD = 8; /* 8.68056 = 16MHz / (16 * 115200) */ UART0->FBRD = 44; /* 0.6875 = 44/64 -> 115108bps (0.08%) */ UART0->LCRH = UART_LCRH_WLEN_8 | UART_LCRH_FEN; UART0->CC = UART_CC_CS_PIOSC; /* Set the baud clock to PIOSC */ UART0->CTL = UART_CTL_RXE | UART_CTL_TXE | UART_CTL_UARTEN; /* USB PB0(ID) PB1(VBUS) PL6,7(DP,DM) */ bits = TU_BIT(1) | TU_BIT(10); SYSCTL->RCGCGPIO |= bits; while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIOB->AMSEL = TU_BIT(0) | TU_BIT(1); GPIOL->AMSEL = TU_BIT(6) | TU_BIT(7); #if CFG_TUH_ENABLED /* USB PD6(EPEN) */ bits = TU_BIT(3); SYSCTL->RCGCGPIO |= bits; while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIOD->AFSEL = TU_BIT(6); GPIOD->PCTL = 0x05000000u; GPIOD->DEN = TU_BIT(6); #endif SYSCTL->RCGCUSB = 1u; /* Open the clock gate for SYSCLK */ while (!(SYSCTL->PRUSB & (1u << 0))) ; USB0->CC = USB_CC_CLKEN | (3u << USB_CC_CLKDIV_S); /* 60MHz = 240MHz / 4 */ __DMB(); /* Wait for completion of opening of the clock gate */ SYSCTL->SRUSB = 1u; for (int i = 0; i < 16; ++i) __NOP(); SYSCTL->SRUSB = 0u; USB0->CC = USB_CC_CLKEN | (3u << USB_CC_CLKDIV_S); /* 60MHz = 240MHz / 4 */ __DMB(); /* Wait for completion of opening of the clock gate */ #if CFG_TUH_ENABLED USB0->GPCS = USB_GPCS_DEVMOD_OTG; USB0->EPC = USB_EPC_EPENDE | USB_EPC_EPEN_HIGH; #endif #if CFG_TUD_ENABLED USB0->GPCS = USB_GPCS_DEVMOD_DEVVBUS; #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { if (state) GPIO_LED->DATA |= TU_BIT(GPIO_LED_PIN); else GPIO_LED->DATA &= ~TU_BIT(GPIO_LED_PIN); } uint32_t board_button_read(void) { return (GPIO_BUTTON->DATA & TU_BIT(GPIO_BUTTON_PIN)) ? 0u : 1u; } int board_uart_read(uint8_t * buf, int len) { for (int i = 0; i < len; ++i) { while (UART0->FR & UART_FR_RXFE) ; *buf++ = UART0->DR; } return len; } int board_uart_write(void const * buf, int len) { uint8_t const *p = (uint8_t const *)buf; for (int i = 0; i < len; ++i) { while (UART0->FR & UART_FR_TXFF) ; UART0->DR = *p++; } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0u; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/msp432e4/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/ti/msp432e4) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS MSP432E4 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${SDK_DIR}/Source/${MCU_VARIANT}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) set(STARTUP_FILE_GNU ${SDK_DIR}/Source/startup_${MCU_VARIANT}_gcc.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Source/system_${MCU_VARIANT}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Include ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_MSP432E4) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/mentor/musb/dcd_musb.c ${TOP}/src/portable/mentor/musb/hcd_musb.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${TARGET} PUBLIC -mslow-flash-data ) target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported for MSP432E4") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_msp430flasher(${TARGET}) endfunction() ================================================ FILE: hw/bsp/msp432e4/family.mk ================================================ SDK_SIR = hw/mcu/ti/msp432e4 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -flto \ -mslow-flash-data \ -DCFG_TUSB_MCU=OPT_MCU_MSP432E4 # mcu driver cause following warnings CFLAGS += -Wno-error=cast-qual -Wno-error=format= LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs LD_FILE = hw/mcu/ti/msp432e4/Source/${MCU_VARIANT}.ld SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ src/portable/mentor/musb/hcd_musb.c \ $(SDK_SIR)/Source/system_${MCU_VARIANT}.c INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SDK_SIR)/Include \ $(TOP)/$(BOARD_PATH) SRC_S += $(SDK_SIR)/Source/startup_${MCU_VARIANT}_gcc.S # For flash-jlink target JLINK_DEVICE = $(MCU_VARIANT) ================================================ FILE: hw/bsp/nrf/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "nrf.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< RAM .fs_data : { PROVIDE(__start_fs_data = .); KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM } INSERT AFTER .data; INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/arduino_nano33_ble.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/arduino_nano33_ble/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Arduino Nano 33 BLE url: https://store.arduino.cc/arduino-nano-33-ble */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN _PINNUM(0, 24) #define LED_STATE_ON 0 // Button #define BUTTON_PIN _PINNUM(1, 11) // D2 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN _PINNUM(1, 10) #define UART_TX_PIN _PINNUM(1, 3) #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/arduino_nano33_ble/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA LD_FILE = $(BOARD_PATH)/$(BOARD).ld # flash using bossac (as part of Nano33 BSP tools) # can be found in arduino15/packages/arduino/tools/bossac/ # Add it to your PATH or change BOSSAC variable to match your installation BOSSAC = bossac flash: $(BUILD)/$(PROJECT).bin @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) $(BOSSAC) --port=$(SERIAL) -U -i -e -w $^ -R ================================================ FILE: hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/circuitplayground_bluefruit/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Circuit Playground Bluefruit url: https://www.adafruit.com/product/4333 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN _PINNUM(1, 14) #define LED_STATE_ON 1 // Button #define BUTTON_PIN _PINNUM(1, 15) #define BUTTON_STATE_ACTIVE 1 // UART #define UART_RX_PIN 30 #define UART_TX_PIN 14 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/circuitplayground_bluefruit/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/nrf52840_s140_v6.ld $(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@ # flash using adafruit-nrfutil dfu flash: $(BUILD)/$(PROJECT).zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200 ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) # enable max3421 host driver for this board # set(MAX3421_HOST 1) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather nRF52840 Express url: https://www.adafruit.com/product/4062 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN _PINNUM(1, 15) #define LED_STATE_ON 1 // Button #define BUTTON_PIN _PINNUM(1, 02) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 24 #define UART_TX_PIN 25 // SPI for USB host shield #define MAX3421_SCK_PIN 14 #define MAX3421_MOSI_PIN 13 #define MAX3421_MISO_PIN 15 #define MAX3421_CS_PIN 27 // D10 #define MAX3421_INTR_PIN 26 // D9 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_express/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA # enable max3421 host driver for this board MAX3421_HOST = 1 # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/nrf52840_s140_v6.ld $(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@ # flash using adafruit-nrfutil dfu flash: $(BUILD)/$(PROJECT).zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200 ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_sense/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather nRF52840 Sense url: https://www.adafruit.com/product/4516 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN _PINNUM(1, 9) #define LED_STATE_ON 1 // Button #define BUTTON_PIN _PINNUM(1, 02) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 24 #define UART_TX_PIN 25 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/feather_nrf52840_sense/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/nrf52840_s140_v6.ld $(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@ # flash using adafruit-nrfutil dfu flash: $(BUILD)/$(PROJECT).zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200 ================================================ FILE: hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/itsybitsy_nrf52840/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit ItsyBitsy nRF52840 Express url: https://www.adafruit.com/product/4481 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN _PINNUM(0, 6) #define LED_STATE_ON 1 // Button #define BUTTON_PIN _PINNUM(0, 29) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 25 #define UART_TX_PIN 24 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/itsybitsy_nrf52840/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/nrf52840_s140_v6.ld $(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@ # flash using adafruit-nrfutil dfu flash: $(BUILD)/$(PROJECT).zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200 ================================================ FILE: hw/bsp/nrf/boards/nrf52833dk/board.cmake ================================================ set(MCU_VARIANT nrf52833) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/nrf52833dk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Nordic nRF52833 DK url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 13 #define LED_STATE_ON 0 // Button #define BUTTON_PIN 11 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 8 #define UART_TX_PIN 6 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/nrf52833dk/board.mk ================================================ MCU_VARIANT = nrf52833 CFLAGS += -DNRF52833_XXAA LD_FILE = ${FAMILY_PATH}/linker/nrf52833_xxaa.ld # flash using jlink flash: flash-jlink ================================================ FILE: hw/bsp/nrf/boards/nrf52840dk/board.cmake ================================================ set(MCU_VARIANT nrf52840) function(update_board TARGET) endfunction() #board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000") #include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) #include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) #include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) #include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) ================================================ FILE: hw/bsp/nrf/boards/nrf52840dk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Nordic nRF52840DK url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 13 #define LED_STATE_ON 0 // Button #define BUTTON_PIN 25 // button 4 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 8 #define UART_TX_PIN 6 // SPI for USB host shield // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? //#define MAX3421_SCK_PIN _PINNUM(1, 15) //#define MAX3421_MOSI_PIN _PINNUM(1, 13) //#define MAX3421_MISO_PIN _PINNUM(1, 14) //#define MAX3421_CS_PIN _PINNUM(1, 12) //#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/nrf52840dk/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA # flash using jlink flash: flash-jlink ================================================ FILE: hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { // Dialog-generated settings Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); Project.SetDevice ("nRF52840_xxAA"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("8 MHz"); Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); // User settings File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10056/cdc_msc.elf"); } /********************************************************************* * * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging a RAM program on a Cortex-M target device * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // Exec.Reset(); // // VectorTableAddr = Elf.GetBaseAddr(); // // if (VectorTableAddr != 0xFFFFFFFF) { // // Util.Log("Resetting Program."); // // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetReset (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetDownload (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} ================================================ FILE: hw/bsp/nrf/boards/nrf52840dongle/board.cmake ================================================ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/nrf52840dongle/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Nordic nRF52840 Dongle url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 8 #define LED_STATE_ON 0 // Button #define BUTTON_PIN _PINNUM(1, 6) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 8 #define UART_TX_PIN 6 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/nrf52840dongle/board.mk ================================================ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA LD_FILE = $(BOARD_PATH)/$(BOARD).ld # flash using Nordic nrfutil (pip2 install nrfutil) # make BOARD=pca10059 SERIAL=/dev/ttyACM0 all flash NRFUTIL = nrfutil $(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex $(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@ flash: $(BUILD)/$(PROJECT).zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) $(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200 ================================================ FILE: hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000 RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 } INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/boards/nrf5340dk/board.cmake ================================================ set(MCU_VARIANT nrf5340) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nrf/boards/nrf5340dk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Nordic nRF5340 DK url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 28 #define LED_STATE_ON 0 // Button #define BUTTON_PIN 23 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 22 #define UART_TX_PIN 20 // SPI for USB host shield // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? //#define MAX3421_SCK_PIN _PINNUM(1, 15) //#define MAX3421_MOSI_PIN _PINNUM(1, 13) //#define MAX3421_MISO_PIN _PINNUM(1, 14) //#define MAX3421_CS_PIN _PINNUM(1, 12) //#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/nrf5340dk/board.mk ================================================ MCU_VARIANT = nrf5340 CFLAGS += -DNRF5340_XXAA -DNRF5340_XXAA_APPLICATION # enable max3421 host driver for this board MAX3421_HOST = 1 # caused by void SystemStoreFICRNS() (without void) in system_nrf5340_application.c CFLAGS += -Wno-error=strict-prototypes # flash using jlink JLINK_DEVICE = nrf5340_xxaa_app flash: flash-jlink ================================================ FILE: hw/bsp/nrf/boards/nrf5340dk/ozone/nrf5340.jdebug ================================================ /********************************************************************* * (c) SEGGER Microcontroller GmbH * * The Embedded Experts * * www.segger.com * ********************************************************************** File : Created : 30 Jun 2021 13:37 Ozone Version : V3.24a */ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { // Dialog-generated settings Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M33F.svd"); Project.AddSvdFile ("./nrf5340_application.svd"); Project.SetDevice ("nRF5340_xxAA_APP"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("16 MHz"); Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); // User settings File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10095/cdc_msc.elf"); } /********************************************************************* * * OnStartupComplete * * Function description * Called when program execution has reached/passed * the startup completion point. Optional. * ********************************************************************** */ //void OnStartupComplete (void) { //} /********************************************************************* * * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging an application in RAM on a Cortex-M target device. * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // VectorTableAddr = Elf.GetBaseAddr(); // // // // Set up initial stack pointer // // // if (VectorTableAddr != 0xFFFFFFFF) { // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // } // // // // Set up entry point PC // // // PC = Elf.GetEntryPointPC(); // // if (PC != 0xFFFFFFFF) { // Target.SetReg("PC", PC); // } else if (VectorTableAddr != 0xFFFFFFFF) { // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } else { // Util.Error("Project file error: failed to set entry point PC", 1); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. Optional. * The default implementation initializes SP and PC to reset values. ** ********************************************************************** */ void AfterTargetReset (void) { _SetupTarget(); } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. Optional. * The default implementation initializes SP and PC to reset values. * ********************************************************************** */ void AfterTargetDownload (void) { _SetupTarget(); } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} /********************************************************************* * * BeforeTargetResume * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetResume (void) { //} /********************************************************************* * * OnSnapshotLoad * * Function description * Called upon loading a snapshot. Optional. * * Additional information * This function is used to restore the target state in cases * where values cannot simply be written to the target. * Typical use: GPIO clock needs to be enabled, before * GPIO is configured. * ********************************************************************** */ //void OnSnapshotLoad (void) { //} /********************************************************************* * * OnSnapshotSave * * Function description * Called upon saving a snapshot. Optional. * * Additional information * This function is usually used to save values of the target * state which can either not be trivially read, * or need to be restored in a specific way or order. * Typically use: Memory Mapped Registers, * such as PLL and GPIO configuration. * ********************************************************************** */ //void OnSnapshotSave (void) { //} /********************************************************************* * * OnError * * Function description * Called when an error occurred. Optional. * ********************************************************************** */ //void OnError (void) { //} /********************************************************************* * * _SetupTarget * * Function description * Setup the target. * Called by AfterTargetReset() and AfterTargetDownload(). * * Auto-generated function. May be overridden by Ozone. * ********************************************************************** */ void _SetupTarget(void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); // // Set up initial stack pointer // SP = Target.ReadU32(VectorTableAddr); if (SP != 0xFFFFFFFF) { Target.SetReg("SP", SP); } // // Set up entry point PC // PC = Elf.GetEntryPointPC(); if (PC != 0xFFFFFFFF) { Target.SetReg("PC", PC); } else { Util.Error("Project script error: failed to set up entry point PC", 1); } } ================================================ FILE: hw/bsp/nrf/boards/nrf54h20dk/board.cmake ================================================ set(MCU_VARIANT nrf54h20) function(update_board TARGET) # temporarily, 54h20 has multiple sram sections target_compile_definitions(${TARGET} PUBLIC CFG_EXAMPLE_VIDEO_READONLY ) target_sources(${TARGET} PRIVATE # ${NRFX_PATH}/drivers/src/nrfx_usbreg.c ) endfunction() ================================================ FILE: hw/bsp/nrf/boards/nrf54h20dk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Nordic nRF54H20 DK url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 28 #define LED_STATE_ON 0 // Button #define BUTTON_PIN 23 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 22 #define UART_TX_PIN 20 // SPI for USB host shield // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? //#define MAX3421_SCK_PIN _PINNUM(1, 15) //#define MAX3421_MOSI_PIN _PINNUM(1, 13) //#define MAX3421_MISO_PIN _PINNUM(1, 14) //#define MAX3421_CS_PIN _PINNUM(1, 12) //#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/nrf/boards/nrf54h20dk/board.mk ================================================ MCU_VARIANT = nrf54h20 CFLAGS += -DNRF54H20_XXAA # enable max3421 host driver for this board MAX3421_HOST = 1 # caused by void SystemStoreFICRNS() (without void) in system_nrf5340_application.c CFLAGS += -Wno-error=strict-prototypes # flash using jlink JLINK_DEVICE = nrf5340_xxaa_app flash: flash-jlink ================================================ FILE: hw/bsp/nrf/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Nordic Semiconductor */ #include "bsp/board_api.h" #include "board.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wundef" #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "nrfx.h" #include "hal/nrf_gpio.h" #include "nrfx_gpiote.h" #if !defined(NRF54H20_XXAA) #include "nrfx_power.h" #endif #include "nrfx_uarte.h" #include "nrfx_spim.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_sdm.h" #include "nrf_soc.h" #endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // example only supports nrfx v3 for code simplicity #if !(defined(NRFX_CONFIG_API_VER_MAJOR) && NRFX_CONFIG_API_VER_MAJOR >= 3) && \ !(85301 >= (10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION)) #error "Example requires nrfx v3.0.0 or later" #endif /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ // Value is chosen to be as same as NRFX_POWER_USB_EVT_* in nrfx_power.h enum { USB_EVT_DETECTED = 0, USB_EVT_REMOVED = 1, USB_EVT_READY = 2 }; // Forward USB interrupt events to TinyUSB IRQ Handler #if defined(NRF54H20_XXAA) #define USBD_IRQn USBHS_IRQn void USBHS_IRQHandler(void) { tusb_int_handler(0, true); } static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(120); #else #ifdef NRF5340_XXAA #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk #define GPIOTE_IRQn GPIOTE1_IRQn #else #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk POWER_USBREGSTATUS_OUTPUTRDY_Msk #endif #if CFG_TUSB_OS != OPT_OS_ZEPHYR static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0); #endif void USBD_IRQHandler(void) { tud_int_handler(0); } #endif // tinyusb function that handles power event (detected, ready, removed) // We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. extern void tusb_hal_nrf_power_event(uint32_t event); #if !defined(NRF54H20_XXAA) // nrf power callback, could be unused if SD is enabled or usb is disabled (board_test example) TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { tusb_hal_nrf_power_event((uint32_t) event); } #endif //------------- Host using MAX2341E -------------// #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static void max3421_init(void); static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0); #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void board_init(void) { #if !defined(NRF54H20_XXAA) // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; // Use Internal OSC to compatible with all boards NRF_CLOCK->LFCLKSRC = LFCLK_SRC_RC; NRF_CLOCK->TASKS_LFCLKSTART = 1UL; #endif // LED nrf_gpio_cfg_output(LED_PIN); board_led_write(false); // Button nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_ZEPHYR #ifdef CONFIG_HAS_HW_NRF_USBREG // IRQ_CONNECT(USBREGULATOR_IRQn, DT_IRQ(DT_INST(0, nordic_nrf_clock), priority), nrfx_isr, nrfx_usbreg_irq_handler, 0); // irq_enable(USBREGULATOR_IRQn); #endif /* USB device controller access from devicetree */ #define DT_DRV_COMPAT nordic_nrf_usbd IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), nrfx_isr, USBD_IRQHandler, 0); irq_enable(DT_INST_IRQN(0)); #endif #if CFG_TUSB_OS != OPT_OS_ZEPHYR // UART nrfx_uarte_config_t uart_cfg = { .txd_pin = UART_TX_PIN, .rxd_pin = UART_RX_PIN, .rts_pin = NRF_UARTE_PSEL_DISCONNECTED, .cts_pin = NRF_UARTE_PSEL_DISCONNECTED, .p_context = NULL, .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE .interrupt_priority = 7, .config = { .hwfc = NRF_UARTE_HWFC_DISABLED, .parity = NRF_UARTE_PARITY_EXCLUDED, } }; nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); #endif //------------- USB -------------// #if CFG_TUD_ENABLED // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice // 2 is highest for application NVIC_SetPriority(USBD_IRQn, 2); #if !defined(NRF54H20_XXAA) // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially uint32_t usb_reg; #ifdef SOFTDEVICE_PRESENT uint8_t sd_en = false; sd_softdevice_is_enabled(&sd_en); if ( sd_en ) { sd_power_usbdetected_enable(true); sd_power_usbpwrrdy_enable(true); sd_power_usbremoved_enable(true); sd_power_usbregstatus_get(&usb_reg); }else #endif { // Power module init const nrfx_power_config_t pwr_cfg = {0}; nrfx_power_init(&pwr_cfg); // Register tusb function as USB power handler // cause cast-function-type warning const nrfx_power_usbevt_config_t config = {.handler = power_event_handler}; nrfx_power_usbevt_init(&config); nrfx_power_usbevt_enable(); // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially #ifdef NRF5340_XXAA usb_reg = NRF_USBREGULATOR->USBREGSTATUS; #else usb_reg = NRF_POWER->USBREGSTATUS; #endif } if ( usb_reg & VBUSDETECT_Msk ) { tusb_hal_nrf_power_event(USB_EVT_DETECTED); } if ( usb_reg & OUTPUTRDY_Msk ) { tusb_hal_nrf_power_event(USB_EVT_READY); } #endif #endif #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 max3421_init(); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; #if defined(NRF54H20_XXAA) uintptr_t did_addr = (uintptr_t) NRF_FICR->BLE.ADDR; #elif defined(NRF5340_XXAA) uintptr_t did_addr = (uintptr_t) NRF_FICR->INFO.DEVICEID; #else uintptr_t did_addr = (uintptr_t) NRF_FICR->DEVICEID; #endif const uint8_t* device_id = (const uint8_t*) did_addr; for(uint8_t i=0; i<8; i++) { id[i] = device_id[i]; } return 8; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; // nrfx_err_t err = nrfx_uarte_rx(&_uart_id, buf, (size_t) len); // return NRFX_SUCCESS == err ? len : 0; } int board_uart_write(void const* buf, int len) { #if CFG_TUSB_OS == OPT_OS_ZEPHYR (void) buf; return len; #else nrfx_err_t err = nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len ,0); return (NRFX_SUCCESS == err) ? len : 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif #ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); TU_ATTR_UNUSED void _start(void) { // called by startup code main(); while (1) {} } #endif //--------------------------------------------------------------------+ // Softdevice running //--------------------------------------------------------------------+ #ifdef SOFTDEVICE_PRESENT // process SOC event from SD uint32_t proc_soc(void) { uint32_t soc_evt; uint32_t err = sd_evt_get(&soc_evt); if (NRF_SUCCESS == err) { /*------------- usb power event handler -------------*/ int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED: (soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY : (soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1; if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt); } return err; } uint32_t proc_ble(void) { // do nothing with ble return NRF_ERROR_NOT_FOUND; } void SD_EVT_IRQHandler(void) { // process BLE and SOC until there is no more events while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) { } } void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { (void) id; (void) pc; (void) info; } #endif //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 void max3421_int_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t action, void* p_context) { (void) p_context; if (action != NRFX_GPIOTE_TRIGGER_HITOLO) { return; } if (pin != MAX3421_INTR_PIN) { return; } tusb_int_handler(1, true); } static void max3421_init(void) { // Somehow pca10056/95 is not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? // manually manage CS nrf_gpio_cfg_output(MAX3421_CS_PIN); nrf_gpio_pin_write(MAX3421_CS_PIN, 1); // USB host using max3421e usb controller via SPI nrfx_spim_config_t cfg = { .sck_pin = MAX3421_SCK_PIN, .mosi_pin = MAX3421_MOSI_PIN, .miso_pin = MAX3421_MISO_PIN, .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, .frequency = 4000000u, .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, // default setting 4 Mhz, Mode 0, MSB first .mode = NRF_SPIM_MODE_0, .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, .miso_pull = NRF_GPIO_PIN_NOPULL, }; // no handler --> blocking TU_ASSERT(NRFX_SUCCESS == nrfx_spim_init(&_spi, &cfg, NULL, NULL), ); // max3421e interrupt pin nrf_gpio_pin_pull_t intr_pull = NRF_GPIO_PIN_PULLUP; nrfx_gpiote_trigger_config_t intr_trigger = { .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, .p_in_channel = NULL, // sensing mechanism }; nrfx_gpiote_handler_config_t intr_handler = { .handler = max3421_int_handler, .p_context = NULL, }; nrfx_gpiote_input_pin_config_t intr_config = { .p_pull_config = &intr_pull, .p_trigger_config = &intr_trigger, .p_handler_config = &intr_handler, }; nrfx_gpiote_init(&_gpiote, 1); NVIC_SetPriority(GPIOTE_IRQn, 2); nrfx_gpiote_input_configure(&_gpiote, MAX3421_INTR_PIN, &intr_config); nrfx_gpiote_trigger_enable(&_gpiote, MAX3421_INTR_PIN, true); } // API to enable/disable MAX3421 INTR pin interrupt void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; // use NVIC_Enable/Disable instead since nrfx_gpiote_trigger_enable/disable clear pending and can miss interrupt // when disabled and re-enabled. if (enabled) { NVIC_EnableIRQ(GPIOTE_IRQn); } else { NVIC_DisableIRQ(GPIOTE_IRQn); } } // API to control MAX3421 SPI CS void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; nrf_gpio_pin_write(MAX3421_CS_PIN, active ? 0 : 1); } // API to transfer data with MAX3421 SPI // Either tx_buf or rx_buf can be NULL, which means transfer is write or read only bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { (void) rhport; nrfx_spim_xfer_desc_t xfer = { .p_tx_buffer = tx_buf, .tx_length = tx_buf ? xfer_bytes : 0, .p_rx_buffer = rx_buf, .rx_length = rx_buf ? xfer_bytes : 0, }; return nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS; } #endif ================================================ FILE: hw/bsp/nrf/family.cmake ================================================ include_guard() set(NRFX_PATH ${TOP}/hw/mcu/nordic/nrfx) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific, for zephyr BOARD_ALIAS may be used instead include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake OPTIONAL RESULT_VARIABLE board_cmake_included) if (NOT board_cmake_included) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD_ALIAS}/board.cmake) endif () # toolchain set up if (MCU_VARIANT STREQUAL nrf5340 OR MCU_VARIANT STREQUAL nrf54h20) set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(JLINK_DEVICE ${MCU_VARIANT}_xxaa_app) else () set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(JLINK_DEVICE ${MCU_VARIANT}_xxaa) endif () if (MCU_VARIANT STREQUAL "nrf54h20") set(FAMILY_MCUS NRF54 CACHE INTERNAL "") else () set(FAMILY_MCUS NRF5X CACHE INTERNAL "") endif () set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) #------------------------------------ # Startup & Linker script #------------------------------------ if (MCU_VARIANT STREQUAL nrf54h20) set(LD_FILE_GNU_DEFAULT ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_xxaa_application.ld) set(STARTUP_FILE_GNU ${NRFX_PATH}/mdk/gcc_startup_${MCU_VARIANT}_application.S) elseif (MCU_VARIANT STREQUAL nrf5340) set(LD_FILE_GNU_DEFAULT ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_xxaa_application.ld) set(STARTUP_FILE_GNU ${NRFX_PATH}/mdk/gcc_startup_${MCU_VARIANT}_application.S) else() set(LD_FILE_GNU_DEFAULT ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) set(STARTUP_FILE_GNU ${NRFX_PATH}/mdk/gcc_startup_${MCU_VARIANT}.S) endif () if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${LD_FILE_GNU_DEFAULT}) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${NRFX_PATH}/helpers/nrfx_flag32_allocator.c ${NRFX_PATH}/drivers/src/nrfx_gpiote.c ${NRFX_PATH}/drivers/src/nrfx_power.c ${NRFX_PATH}/drivers/src/nrfx_spim.c ${NRFX_PATH}/drivers/src/nrfx_uarte.c ${NRFX_PATH}/soc/nrfx_atomic.c ) if (MCU_VARIANT STREQUAL nrf54h20) target_sources(${BOARD_TARGET} PRIVATE ${NRFX_PATH}/mdk/system_nrf54h.c ) elseif (MCU_VARIANT STREQUAL nrf5340) target_sources(${BOARD_TARGET} PRIVATE ${NRFX_PATH}/mdk/system_${MCU_VARIANT}_application.c ${NRFX_PATH}/drivers/src/nrfx_usbreg.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA_APPLICATION) else() target_sources(${BOARD_TARGET} PRIVATE ${NRFX_PATH}/mdk/system_${MCU_VARIANT}.c ) endif () string(TOUPPER ${MCU_VARIANT} MCU_VARIANT_UPPER) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS CONFIG_GPIO_AS_PINRESET ${MCU_VARIANT_UPPER}_XXAA NRF_APPLICATION ) if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) endif () target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/nrfx_config ${NRFX_PATH} ${NRFX_PATH}/mdk ${NRFX_PATH}/drivers/include ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ #function(family_flash_adafruit_nrfutil TARGET) # add_custom_target(${TARGET}-adafruit-nrfutil # DEPENDS ${TARGET} # COMMAND adafruit-nrfutil --verbose dfu serial --package $^ -p /dev/ttyACM0 -b 115200 --singlebank --touch 1200 # ) #endfunction() function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${FAMILY_MCUS}) target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nordic/nrf5x/dcd_nrf5x.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (RTOS STREQUAL zephyr) target_include_directories(${TARGET} PUBLIC ${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx/bsp/stable/mdk) else () target_sources(${TARGET} PRIVATE ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -L${NRFX_PATH}/mdk --specs=nosys.specs --specs=nano.specs -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -L${NRFX_PATH}/mdk ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing # family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) # family_flash_adafruit_nrfutil(${TARGET}) endfunction() ================================================ FILE: hw/bsp/nrf/family.mk ================================================ UF2_FAMILY_ID = 0xADA52840 NRFX_PATH = hw/mcu/nordic/nrfx include $(TOP)/$(BOARD_PATH)/board.mk ifeq (${MCU_VARIANT},nrf54h20) CPU_CORE = cortex-m33 CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF54 LD_FILE_DEFAULT = ${FAMILY_PATH}/linker/${MCU_VARIANT}_xxaa_application.ld SRC_C += ${NRFX_PATH}/mdk/system_nrf54h.c SRC_S += ${NRFX_PATH}/mdk/gcc_startup_$(MCU_VARIANT)_application.S JLINK_DEVICE ?= $(MCU_VARIANT)_xxaa_app else ifeq (${MCU_VARIANT},nrf5340) CPU_CORE = cortex-m33 CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X LD_FILE_DEFAULT = ${FAMILY_PATH}/linker/${MCU_VARIANT}_xxaa_application.ld SRC_C += ${NRFX_PATH}/mdk/system_$(MCU_VARIANT)_application.c \ ${NRFX_PATH}/drivers/src/nrfx_usbreg.c SRC_S += ${NRFX_PATH}/mdk/gcc_startup_$(MCU_VARIANT)_application.S JLINK_DEVICE ?= $(MCU_VARIANT)_xxaa_app else CPU_CORE = cortex-m4 CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X LD_FILE_DEFAULT = ${FAMILY_PATH}/linker/${MCU_VARIANT}_xxaa.ld SRC_C += ${NRFX_PATH}/mdk/system_$(MCU_VARIANT).c SRC_S += ${NRFX_PATH}/mdk/gcc_startup_$(MCU_VARIANT).S JLINK_DEVICE ?= $(MCU_VARIANT)_xxaa endif endif CFLAGS += \ -DNRF_APPLICATION \ -DCONFIG_GPIO_AS_PINRESET \ -D__STARTUP_CLEAR_BSS #CFLAGS += -nostdlib #CFLAGS += -D__START=main # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -flto \ -Wno-error=undef \ -Wno-error=unused-parameter \ -Wno-error=unused-variable \ -Wno-error=cast-align \ -Wno-error=cast-qual \ -Wno-error=redundant-decls \ LDFLAGS_GCC += \ -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ -L$(TOP)/${NRFX_PATH}/mdk LDFLAGS_CLANG += \ -L$(TOP)/${NRFX_PATH}/mdk \ ifndef LD_FILE LD_FILE = ${LD_FILE_DEFAULT} endif SRC_C += \ src/portable/nordic/nrf5x/dcd_nrf5x.c \ src/portable/synopsys/dwc2/dwc2_common.c \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ ${NRFX_PATH}/helpers/nrfx_flag32_allocator.c \ ${NRFX_PATH}/drivers/src/nrfx_gpiote.c \ ${NRFX_PATH}/drivers/src/nrfx_power.c \ ${NRFX_PATH}/drivers/src/nrfx_spim.c \ ${NRFX_PATH}/drivers/src/nrfx_uarte.c \ ${NRFX_PATH}/soc/nrfx_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(FAMILY_PATH)/nrfx_config \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/${NRFX_PATH} \ $(TOP)/${NRFX_PATH}/mdk \ $(TOP)/${NRFX_PATH}/hal \ $(TOP)/${NRFX_PATH}/drivers/include \ $(TOP)/${NRFX_PATH}/drivers/src \ ASFLAGS += -D__HEAP_SIZE=0 ================================================ FILE: hw/bsp/nrf/linker/nrf52833_xxaa.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x20000 } INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/linker/nrf52840_s140_v6.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 /* SRAM required by S132 depend on * - Attribute Table Size * - Vendor UUID count * - Max ATT MTU * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 } SECTIONS { . = ALIGN(4); .svc_data : { PROVIDE(__start_svc_data = .); KEEP(*(.svc_data)) PROVIDE(__stop_svc_data = .); } > RAM .fs_data : { PROVIDE(__start_fs_data = .); KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM } INSERT AFTER .data; INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/linker/nrf52840_xxaa.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 EXTFLASH (rx) : ORIGIN = 0x12000000, LENGTH = 0x8000000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000 } INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/linker/nrf5340_xxaa_application.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 EXTFLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x8000000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x3F000 } INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/linker/nrf54h20_xxaa_application.ld ================================================ /* Linker script to configure memory regions. */ SEARCH_DIR(.) /*GROUP(-lgcc -lc) not compatible with clang*/ MEMORY { FLASH (rx) : ORIGIN = 0xE0A0000, LENGTH = 0x40000 /* Inside global MRAM0 */ FLASH1 (rx) : ORIGIN = 0x2F840000, LENGTH = 0x4000 /* OTP0 */ EXTFLASH (rx) : ORIGIN = 0x70000000, LENGTH = 0x20000000 RAM (rwx) : ORIGIN = 0x22000000, LENGTH = 0x8000 RAM1 (rwx) : ORIGIN = 0x2F000000, LENGTH = 0x80000 /* RAM00 */ RAM2 (rwx) : ORIGIN = 0x2F080000, LENGTH = 0x60000 /* RAM01 */ RAM3 (rwx) : ORIGIN = 0x2F880000, LENGTH = 0x10000 /* RAM20 */ RAM4 (rwx) : ORIGIN = 0x2F890000, LENGTH = 0x8000 /* RAM21 */ RAM5 (rwx) : ORIGIN = 0x2FC00000, LENGTH = 0x4000 /* RAM30 (low-speed) */ RAM6 (rwx) : ORIGIN = 0x2FC04000, LENGTH = 0x4000 /* RAM31 (low-speed) */ } INCLUDE "nrf_common.ld" ================================================ FILE: hw/bsp/nrf/nrfx_config/nrfx_config.h ================================================ /* * Copyright (c) 2019 - 2025, Nordic Semiconductor ASA * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * * 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef NRFX_CONFIG_H__ #define NRFX_CONFIG_H__ #include "nrfx_config_common.h" #if defined(NRF51) #include #elif defined(NRF52805_XXAA) #include #elif defined(NRF52810_XXAA) #include #elif defined(NRF52811_XXAA) #include #elif defined(NRF52820_XXAA) #include #elif defined(NRF52832_XXAA) || defined (NRF52832_XXAB) #include #elif defined(NRF52833_XXAA) #include #elif defined(NRF52840_XXAA) #include #elif defined(NRF5340_XXAA_APPLICATION) #include #elif defined(NRF5340_XXAA_NETWORK) #include #elif defined(NRF54H20_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54H20_XXAA) && defined(NRF_RADIOCORE) #include #elif defined(NRF54H20_XXAA) && defined(NRF_PPR) #include #elif defined(NRF54H20_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF54L05_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54L05_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF54L10_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54L10_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF54L15_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54L15_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF54LM20A_ENGA_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54LM20A_ENGA_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF54LS05B_ENGA_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54LV10A_ENGA_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF54LV10A_ENGA_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF7120_ENGA_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF7120_ENGA_XXAA) && defined(NRF_FLPR) #include #elif defined(NRF7120_ENGA_XXAA) && defined(NRF_LMAC) #include #elif defined(NRF7120_ENGA_XXAA) && defined(NRF_UMAC) #include #elif defined(NRF9120_XXAA) || defined(NRF9160_XXAA) #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_APPLICATION) #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_RADIOCORE) #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_PPR) #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_FLPR) #include #else #include "nrfx_config_ext.h" #endif #endif // NRFX_CONFIG_H__ ================================================ FILE: hw/bsp/nrf/nrfx_config/nrfx_config_common.h ================================================ /* * Copyright (c) 2022 - 2025, Nordic Semiconductor ASA * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * * 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef NRFX_CONFIG_COMMON_H__ #define NRFX_CONFIG_COMMON_H__ #ifndef NRFX_CONFIG_H__ #error "This file should not be included directly. Include nrfx_config.h instead." #endif /** @brief Symbol specifying major version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MAJOR #define NRFX_CONFIG_API_VER_MAJOR 3 #endif /** @brief Symbol specifying minor version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MINOR #define NRFX_CONFIG_API_VER_MINOR 12 #endif /** @brief Symbol specifying micro version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MICRO #define NRFX_CONFIG_API_VER_MICRO 0 #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #define NRFX_CLOCK_ENABLED 0 #define NRFX_UARTE_ENABLED 1 #if defined(NRF54H20_XXAA) #define NRFX_UARTE120_ENABLED 1 #else #define NRFX_POWER_ENABLED 1 #define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_UARTE0_ENABLED 1 #define NRFX_GPIOTE_ENABLED 1 #define NRFX_GPIOTE0_ENABLED 1 #define NRFX_SPIM_ENABLED 1 #define NRFX_SPIM1_ENABLED 1 // use SPI1 since nrf5340 share uart with spi #endif #define NRFX_PRS_ENABLED 0 #define NRFX_USBREG_ENABLED 1 #define NRF_STATIC_INLINE static inline #endif /* NRFX_CONFIG_COMMON_H__ */ ================================================ FILE: hw/bsp/nrf/nrfx_config/nrfx_config_ext.h ================================================ /* * Copyright (c) 2023 - 2025, Nordic Semiconductor ASA * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * * 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef NRFX_CONFIG_EXT_H__ #define NRFX_CONFIG_EXT_H__ #error "Unknown device." #endif // NRFX_CONFIG_EXT_H__ ================================================ FILE: hw/bsp/nrf/nrfx_config/nrfx_glue.h ================================================ /* * Copyright (c) 2017 - 2024, Nordic Semiconductor ASA * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * * 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef NRFX_GLUE_H__ #define NRFX_GLUE_H__ // THIS IS A TEMPLATE FILE. // It should be copied to a suitable location within the host environment into // which nrfx is integrated, and the following macros should be provided with // appropriate implementations. // And this comment should be removed from the customized file. #ifdef __cplusplus extern "C" { #endif /** * @defgroup nrfx_glue nrfx_glue.h * @{ * @ingroup nrfx * * @brief This file contains macros that should be implemented according to * the needs of the host environment into which @em nrfx is integrated. */ // Uncomment this line to use the standard MDK way of binding IRQ handlers // at linking time. #include //------------------------------------------------------------------------------ /** * @brief Macro for placing a runtime assertion. * * @param expression Expression to be evaluated. */ #define NRFX_ASSERT(expression) /** * @brief Macro for placing a compile time assertion. * * @param expression Expression to be evaluated. */ #define NRFX_STATIC_ASSERT(expression) //------------------------------------------------------------------------------ /** * @brief Macro for setting the priority of a specific IRQ. * * @param irq_number IRQ number. * @param priority Priority to be set. */ #define NRFX_IRQ_PRIORITY_SET(irq_number, priority) _NRFX_IRQ_PRIORITY_SET(irq_number, priority) static inline void _NRFX_IRQ_PRIORITY_SET(IRQn_Type irq_number, uint8_t priority) { NRFX_ASSERT(INTERRUPT_PRIORITY_IS_VALID(priority)); NVIC_SetPriority(irq_number, priority); } /** * @brief Macro for enabling a specific IRQ. * * @param irq_number IRQ number. */ #define NRFX_IRQ_ENABLE(irq_number) _NRFX_IRQ_ENABLE(irq_number) static inline void _NRFX_IRQ_ENABLE(IRQn_Type irq_number) { NVIC_ClearPendingIRQ(irq_number); NVIC_EnableIRQ(irq_number); } /** * @brief Macro for checking if a specific IRQ is enabled. * * @param irq_number IRQ number. * * @retval true If the IRQ is enabled. * @retval false Otherwise. */ #define NRFX_IRQ_IS_ENABLED(irq_number) _NRFX_IRQ_IS_ENABLED(irq_number) static inline bool _NRFX_IRQ_IS_ENABLED(IRQn_Type irq_number) { return 0 != (NVIC->ISER[irq_number / 32] & (1UL << (irq_number % 32))); } /** * @brief Macro for disabling a specific IRQ. * * @param irq_number IRQ number. */ #define NRFX_IRQ_DISABLE(irq_number) _NRFX_IRQ_DISABLE(irq_number) static inline void _NRFX_IRQ_DISABLE(IRQn_Type irq_number) { NVIC_DisableIRQ(irq_number); } /** * @brief Macro for setting a specific IRQ as pending. * * @param irq_number IRQ number. */ #define NRFX_IRQ_PENDING_SET(irq_number) _NRFX_IRQ_PENDING_SET(irq_number) static inline void _NRFX_IRQ_PENDING_SET(IRQn_Type irq_number) { NVIC_SetPendingIRQ(irq_number); } /** * @brief Macro for clearing the pending status of a specific IRQ. * * @param irq_number IRQ number. */ #define NRFX_IRQ_PENDING_CLEAR(irq_number) _NRFX_IRQ_PENDING_CLEAR(irq_number) static inline void _NRFX_IRQ_PENDING_CLEAR(IRQn_Type irq_number) { NVIC_ClearPendingIRQ(irq_number); } /** * @brief Macro for checking the pending status of a specific IRQ. * * @retval true If the IRQ is pending. * @retval false Otherwise. */ #define NRFX_IRQ_IS_PENDING(irq_number) _NRFX_IRQ_IS_PENDING(irq_number) static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) { return (NVIC_GetPendingIRQ(irq_number) == 1); } /** @brief Macro for entering into a critical section. */ #define NRFX_CRITICAL_SECTION_ENTER() /** @brief Macro for exiting from a critical section. */ #define NRFX_CRITICAL_SECTION_EXIT() //------------------------------------------------------------------------------ /** * @brief When set to a non-zero value, this macro specifies that * @ref nrfx_coredep_delay_us uses a precise DWT-based solution. * A compilation error is generated if the DWT unit is not present * in the SoC used. */ #define NRFX_DELAY_DWT_BASED 0 /** * @brief Macro for delaying the code execution for at least the specified time. * * @param us_time Number of microseconds to wait. */ #include #define NRFX_DELAY_US(us_time) nrfx_coredep_delay_us(us_time) //------------------------------------------------------------------------------ /** * @brief When set to a non-zero value, this macro specifies that the * @ref nrfx_error_codes and the @ref nrfx_err_t type itself are defined * in a customized way and the default definitions from @c * should not be used. */ #define NRFX_CUSTOM_ERROR_CODES 0 //------------------------------------------------------------------------------ /** * @brief Bitmask defining PPI channels reserved to be used outside of nrfx. */ #define NRFX_PPI_CHANNELS_USED 0 /** * @brief Bitmask defining PPI groups reserved to be used outside of nrfx. */ #define NRFX_PPI_GROUPS_USED 0 /** * @brief Bitmask defining SWI instances reserved to be used outside of nrfx. */ #define NRFX_SWI_USED 0 /** * @brief Bitmask defining TIMER instances reserved to be used outside of nrfx. */ #define NRFX_TIMERS_USED 0 /** @} */ //------------------------------------------------------------------------------ #include /** * @brief Atomic 32 bit unsigned type. */ #define nrfx_atomic_t nrfx_atomic_u32_t /** * @brief Stores value to an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value to store. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_STORE(p_data, value) nrfx_atomic_u32_fetch_store(p_data, value) /** * @brief Performs logical OR operation on an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value of second operand of OR operation. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_OR(p_data, value) nrfx_atomic_u32_fetch_or(p_data, value) /** * @brief Performs logical AND operation on an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value of second operand of AND operation. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_AND(p_data, value) nrfx_atomic_u32_fetch_and(p_data, value) /** * @brief Performs logical XOR operation on an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value of second operand of XOR operation. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_XOR(p_data, value) nrfx_atomic_u32_fetch_xor(p_data, value) /** * @brief Performs logical ADD operation on an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value of second operand of ADD operation. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_ADD(p_data, value) nrfx_atomic_u32_fetch_add(p_data, value) /** * @brief Performs logical SUB operation on an atomic object and returns previously stored value. * * @param[in] p_data Atomic memory pointer. * @param[in] value Value of second operand of SUB operation. * * @return Old value stored into atomic object. */ #define NRFX_ATOMIC_FETCH_SUB(p_data, value) nrfx_atomic_u32_fetch_sub(p_data, value) #ifdef __cplusplus } #endif #endif // NRFX_GLUE_H__ ================================================ FILE: hw/bsp/nrf/nrfx_config/nrfx_log.h ================================================ /* * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA * 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. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. */ #ifndef NRFX_LOG_H__ #define NRFX_LOG_H__ // THIS IS A TEMPLATE FILE. // It should be copied to a suitable location within the host environment into // which nrfx is integrated, and the following macros should be provided with // appropriate implementations. // And this comment should be removed from the customized file. #ifdef __cplusplus extern "C" { #endif /** * @defgroup nrfx_log nrfx_log.h * @{ * @ingroup nrfx * * @brief This file contains macros that should be implemented according to * the needs of the host environment into which @em nrfx is integrated. */ /** * @brief Macro for logging a message with the severity level ERROR. * * @param format printf-style format string, optionally followed by arguments * to be formatted and inserted in the resulting string. */ #define NRFX_LOG_ERROR(format, ...) /** * @brief Macro for logging a message with the severity level WARNING. * * @param format printf-style format string, optionally followed by arguments * to be formatted and inserted in the resulting string. */ #define NRFX_LOG_WARNING(format, ...) /** * @brief Macro for logging a message with the severity level INFO. * * @param format printf-style format string, optionally followed by arguments * to be formatted and inserted in the resulting string. */ #define NRFX_LOG_INFO(format, ...) /** * @brief Macro for logging a message with the severity level DEBUG. * * @param format printf-style format string, optionally followed by arguments * to be formatted and inserted in the resulting string. */ #define NRFX_LOG_DEBUG(format, ...) /** * @brief Macro for logging a memory dump with the severity level ERROR. * * @param[in] p_memory Pointer to the memory region to be dumped. * @param[in] length Length of the memory region in bytes. */ #define NRFX_LOG_HEXDUMP_ERROR(p_memory, length) /** * @brief Macro for logging a memory dump with the severity level WARNING. * * @param[in] p_memory Pointer to the memory region to be dumped. * @param[in] length Length of the memory region in bytes. */ #define NRFX_LOG_HEXDUMP_WARNING(p_memory, length) /** * @brief Macro for logging a memory dump with the severity level INFO. * * @param[in] p_memory Pointer to the memory region to be dumped. * @param[in] length Length of the memory region in bytes. */ #define NRFX_LOG_HEXDUMP_INFO(p_memory, length) /** * @brief Macro for logging a memory dump with the severity level DEBUG. * * @param[in] p_memory Pointer to the memory region to be dumped. * @param[in] length Length of the memory region in bytes. */ #define NRFX_LOG_HEXDUMP_DEBUG(p_memory, length) /** * @brief Macro for getting the textual representation of a given error code. * * @param[in] error_code Error code. * * @return String containing the textual representation of the error code. */ #define NRFX_LOG_ERROR_STRING_GET(error_code) /** @} */ #ifdef __cplusplus } #endif #endif // NRFX_LOG_H__ ================================================ FILE: hw/bsp/nuc100_120/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "NUC100Series.h" #endif /* Cortex-M0 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // NUC121/125 has 2 priority bits #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; .data : AT (__etext) { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (COPY): { __HeapBase = .; __end__ = .; end = __end__; KEEP(*(.heap*)) __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { KEEP(*(.stack*)) } > RAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/nuc100_120/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" #include "NUC100Series.h" #include "clk.h" #include "sys.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBD_IRQHandler(void) { tud_int_handler(0); } void board_init(void) { SYS_UnlockReg(); /* Enable Internal RC 22.1184 MHz clock */ CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk); /* Waiting for Internal RC clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk); /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1)); /* Enable external XTAL 12 MHz clock */ CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk); /* Waiting for external XTAL clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk); /* Set core clock */ CLK_SetCoreClock(48000000); /* Enable module clock */ CLK_EnableModuleClock(USBD_MODULE); /* Select module clock source */ CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV_USB(1)); SYS_LockReg(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(48000000 / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif GPIO_SetMode(LED_PORT, 1UL << LED_PIN, GPIO_PMD_OUTPUT); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #if 0 /* this would be the simplest solution... *IF* the part supported the pin data interface */ LED_PIN_IO = (state) ? LED_STATE_ON : (1-LED_STATE_ON); #else /* if the part's *PDIO pin data registers don't work, a more elaborate approach is needed */ uint32_t irq_state = __get_PRIMASK(); __disable_irq(); uint32_t current = LED_PORT->DOUT & ~(1UL << LED_PIN); LED_PORT->DOUT = current | (((state) ? LED_STATE_ON : (1UL-LED_STATE_ON)) << LED_PIN); __set_PRIMASK(irq_state); #endif } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } ================================================ FILE: hw/bsp/nuc100_120/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/nuvoton/nuc100_120) set(CMSIS_5 ${TOP}/lib/CMSIS_5) set(CMAKE_SYSTEM_CPU cortex-m0 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(OPENOCD_OPTION "-f interface/nulink.cfg -f target/numicroM0.cfg") set(FAMILY_MCUS NUC100 NUC120 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Device/Nuvoton/NUC100Series/Source/GCC/startup_NUC100Series.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Device/Nuvoton/NUC100Series/Source/system_NUC100Series.c ${SDK_DIR}/StdDriver/src/clk.c ${SDK_DIR}/StdDriver/src/gpio.c ${SDK_DIR}/StdDriver/src/sys.c ${SDK_DIR}/StdDriver/src/timer.c ${SDK_DIR}/StdDriver/src/uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Device/Nuvoton/NUC100Series/Include ${SDK_DIR}/StdDriver/inc ${SDK_DIR}/CMSIS/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_EXAMPLE_MSC_READONLY CFG_EXAMPLE_VIDEO_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_NUC120) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nuvoton/nuc120/dcd_nuc120.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) family_flash_openocd_nuvoton(${TARGET}) endfunction() ================================================ FILE: hw/bsp/nuc100_120/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_NUC120 CPU_CORE ?= cortex-m0 LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # LD_FILE is defined in board.mk SRC_C += \ src/portable/nuvoton/nuc120/dcd_nuc120.c \ hw/mcu/nuvoton/nuc100_120/Device/Nuvoton/NUC100Series/Source/system_NUC100Series.c \ hw/mcu/nuvoton/nuc100_120/StdDriver/src/clk.c \ hw/mcu/nuvoton/nuc100_120/StdDriver/src/gpio.c \ hw/mcu/nuvoton/nuc100_120/StdDriver/src/sys.c \ hw/mcu/nuvoton/nuc100_120/StdDriver/src/timer.c \ hw/mcu/nuvoton/nuc100_120/StdDriver/src/uart.c SRC_S += \ hw/mcu/nuvoton/nuc100_120/Device/Nuvoton/NUC100Series/Source/GCC/startup_NUC100Series.S INC += \ $(TOP)/hw/mcu/nuvoton/nuc100_120/Device/Nuvoton/NUC100Series/Include \ $(TOP)/hw/mcu/nuvoton/nuc100_120/StdDriver/inc \ $(TOP)/hw/mcu/nuvoton/nuc100_120/CMSIS/Include \ $(TOP)/$(BOARD_PATH) FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM0 # Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton # Please compile and install it from github source OPENOCD_NUVOTON_PATH ?= $(HOME)/app/OpenOCD-Nuvoton flash: $(BUILD)/$(PROJECT).elf $(OPENOCD_NUVOTON_PATH)/src/openocd -s $(OPENOCD_NUVOTON_PATH)/tcl -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit" ================================================ FILE: hw/bsp/nuc121_125/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "NuMicro.h" #endif /* Cortex-M0 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // NUC121/125 has 2 priority bits #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; .data : AT (__etext) { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (COPY): { __HeapBase = .; __end__ = .; end = __end__; KEEP(*(.heap*)) __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { KEEP(*(.stack*)) } > RAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/nuc121_125/boards/nutiny_sdk_nuc125/board.cmake ================================================ set(NUC_SERIES nuc125) set(JLINK_DEVICE NUC125SC2AE) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nuc125_flash.ld) function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/nuc121_125/boards/nutiny_sdk_nuc125/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT PB #define LED_PIN 4 #define LED_PIN_IO PB4 #define LED_STATE_ON 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/nuc121_125/boards/nutiny_sdk_nuc125/board.mk ================================================ NUC_SERIES = nuc125 JLINK_DEVICE = NUC125SC2AE LD_FILE = $(BOARD_PATH)/nuc125_flash.ld ================================================ FILE: hw/bsp/nuc121_125/boards/nutiny_sdk_nuc125/nuc125_flash.ld ================================================ /* Linker script to configure memory regions. */ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000 /* 32k */ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x2000 /* 8k */ } /* Library configurations */ GROUP(libgcc.a libc.a libm.a libnosys.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __end__ * end * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size */ ENTRY(Reset_Handler) SECTIONS { .text : { KEEP(*(.vectors)) __Vectors_End = .; __Vectors_Size = __Vectors_End - __Vectors; __end__ = .; *(.text*) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; .data : AT (__etext) { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (COPY): { __HeapBase = .; __end__ = .; end = __end__; KEEP(*(.heap*)) __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { KEEP(*(.stack*)) } > RAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/nuc121_125/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" #include "NuMicro.h" #include "clk.h" #include "sys.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBD_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // Board Initialization //--------------------------------------------------------------------+ void board_init(void) { /* Unlock protected registers */ SYS_UnlockReg(); /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable Internal HIRC 48 MHz clock */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN); /* Waiting for Internal RC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); /* Switch HCLK clock source to Internal HIRC and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); /* Enable module clock */ CLK_EnableModuleClock(USBD_MODULE); /* Select module clock source */ CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_HIRC, CLK_CLKDIV0_USB(1)); /* Enable module clock */ CLK_EnableModuleClock(USBD_MODULE); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(48000000 / 1000); #endif // LED GPIO_SetMode(LED_PORT, 1 << LED_PIN, GPIO_MODE_OUTPUT); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { LED_PIN_IO = (state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } ================================================ FILE: hw/bsp/nuc121_125/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/nuvoton/nuc121_125) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(OPENOCD_OPTION "-f interface/nulink.cfg -f target/numicroM0.cfg") set(FAMILY_MCUS NUC121 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Device/Nuvoton/NUC121/Source/GCC/startup_NUC121.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) # Common sources for all NUC12x add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Device/Nuvoton/NUC121/Source/system_NUC121.c ${SDK_DIR}/StdDriver/src/clk.c ${SDK_DIR}/StdDriver/src/gpio.c ${SDK_DIR}/StdDriver/src/fmc.c ${SDK_DIR}/StdDriver/src/sys.c ${SDK_DIR}/StdDriver/src/timer.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Device/Nuvoton/NUC121/Include ${SDK_DIR}/StdDriver/inc ${SDK_DIR}/CMSIS/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC __ARM_FEATURE_DSP=0 USE_ASSERT=0 CFG_EXAMPLE_MSC_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_NUC121) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nuvoton/nuc121/dcd_nuc121.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-redundant-decls") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) family_flash_openocd_nuvoton(${TARGET}) endfunction() ================================================ FILE: hw/bsp/nuc121_125/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -D__ARM_FEATURE_DSP=0 \ -DUSE_ASSERT=0 \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_NUC121 CPU_CORE ?= cortex-m0 # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls LDFLAGS_GCC += \ --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. # LD_FILE is defined in board.mk # Common sources for all NUC12x variants SRC_C += \ src/portable/nuvoton/nuc121/dcd_nuc121.c \ hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/system_NUC121.c \ hw/mcu/nuvoton/nuc121_125/StdDriver/src/clk.c \ hw/mcu/nuvoton/nuc121_125/StdDriver/src/gpio.c \ hw/mcu/nuvoton/nuc121_125/StdDriver/src/fmc.c \ hw/mcu/nuvoton/nuc121_125/StdDriver/src/sys.c \ hw/mcu/nuvoton/nuc121_125/StdDriver/src/timer.c # Additional sources are added in board.mk if needed (e.g., fmc, sys, timer, uart for NUC121) SRC_S += \ hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Source/GCC/startup_NUC121.S INC += \ $(TOP)/hw/mcu/nuvoton/nuc121_125/Device/Nuvoton/NUC121/Include \ $(TOP)/hw/mcu/nuvoton/nuc121_125/StdDriver/inc \ $(TOP)/hw/mcu/nuvoton/nuc121_125/CMSIS/Include \ $(TOP)/$(BOARD_PATH) # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM0 # Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton # Please compile and install it from github source OPENOCD_NUVOTON_PATH ?= $(HOME)/app/OpenOCD-Nuvoton flash: $(BUILD)/$(PROJECT).elf $(OPENOCD_NUVOTON_PATH)/src/openocd -s $(OPENOCD_NUVOTON_PATH)/tcl -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit" ================================================ FILE: hw/bsp/nuc126/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "NuMicro.h" #endif /* Cortex-M0 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // NUC121/125 has 2 priority bits #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; .data : AT (__etext) { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (COPY): { __HeapBase = .; __end__ = .; end = __end__; KEEP(*(.heap*)) __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { KEEP(*(.stack*)) } > RAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/nuc126/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" #include "NuMicro.h" #include "clk.h" #include "sys.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBD_IRQHandler(void) { tud_int_handler(0); } #define TRIM_INIT (SYS_BASE+0x118) void board_init(void) { /* Unlock protected registers */ SYS_UnlockReg(); /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable Internal RC 22.1184 MHz clock */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); /* Waiting for Internal RC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); #ifndef CRYSTAL_LESS /* Enable external XTAL 12 MHz clock */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); /* Waiting for external XTAL clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); /* Set core clock */ CLK_SetCoreClock(72000000); /* Use HIRC as UART clock source */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC, CLK_CLKDIV0_UART(1)); /* Use PLL as USB clock source */ CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_PLL, CLK_CLKDIV0_USB(3)); #else /* Enable Internal RC 48MHz clock */ CLK_EnableXtalRC(CLK_PWRCTL_HIRC48EN_Msk); /* Waiting for Internal RC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRC48STB_Msk); /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC48, CLK_CLKDIV0_HCLK(1)); /* Use HIRC as UART clock source */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC, CLK_CLKDIV0_UART(1)); /* Use HIRC48 as USB clock source */ CLK_SetModuleClock(USBD_MODULE, CLK_CLKSEL3_USBDSEL_HIRC48, CLK_CLKDIV0_USB(1)); #endif /* Enable module clock */ CLK_EnableModuleClock(USBD_MODULE); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(48000000 / 1000); #endif // LED GPIO_SetMode(LED_PORT, 1 << LED_PIN, GPIO_MODE_OUTPUT); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { LED_PIN_IO = (state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } ================================================ FILE: hw/bsp/nuc126/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/nuvoton/nuc126) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(OPENOCD_OPTION "-f interface/nulink.cfg -f target/numicroM0.cfg") set(FAMILY_MCUS NUC126 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Device/Nuvoton/NUC126/Source/GCC/startup_NUC126.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Device/Nuvoton/NUC126/Source/system_NUC126.c ${SDK_DIR}/StdDriver/src/clk.c ${SDK_DIR}/StdDriver/src/crc.c ${SDK_DIR}/StdDriver/src/gpio.c ${SDK_DIR}/StdDriver/src/rtc.c ${SDK_DIR}/StdDriver/src/sys.c ${SDK_DIR}/StdDriver/src/timer.c ${SDK_DIR}/StdDriver/src/uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Device/Nuvoton/NUC126/Include ${SDK_DIR}/StdDriver/inc ${SDK_DIR}/CMSIS/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC __ARM_FEATURE_DSP=0 USE_ASSERT=0 CFG_EXAMPLE_VIDEO_READONLY __CORTEX_SC=0 ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_NUC126) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nuvoton/nuc121/dcd_nuc121.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-redundant-decls") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) family_flash_openocd_nuvoton(${TARGET}) endfunction() ================================================ FILE: hw/bsp/nuc126/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -D__ARM_FEATURE_DSP=0 \ -DUSE_ASSERT=0 \ -DCFG_EXAMPLE_VIDEO_READONLY \ -D__CORTEX_SC=0 \ -DCFG_TUSB_MCU=OPT_MCU_NUC126 CPU_CORE ?= cortex-m0 # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. # LD_FILE is defined in board.mk SRC_C += \ src/portable/nuvoton/nuc121/dcd_nuc121.c \ hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Source/system_NUC126.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/clk.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/crc.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/gpio.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/rtc.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/sys.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/timer.c \ hw/mcu/nuvoton/nuc126/StdDriver/src/uart.c SRC_S += \ hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Source/GCC/startup_NUC126.S INC += \ $(TOP)/hw/mcu/nuvoton/nuc126/Device/Nuvoton/NUC126/Include \ $(TOP)/hw/mcu/nuvoton/nuc126/StdDriver/inc \ $(TOP)/hw/mcu/nuvoton/nuc126/CMSIS/Include \ $(TOP)/$(BOARD_PATH) # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM0 # Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton # Please compile and install it from github source OPENOCD_NUVOTON_PATH ?= $(HOME)/app/OpenOCD-Nuvoton flash: $(BUILD)/$(PROJECT).elf $(OPENOCD_NUVOTON_PATH)/src/openocd -s $(OPENOCD_NUVOTON_PATH)/tcl -f interface/nulink.cfg -f target/numicroM0.cfg -c "program $< reset exit" ================================================ FILE: hw/bsp/nuc505/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "NUC505Series.h" #endif /* Cortex-M4F port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header // NUC505 has 3 priority bits #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; .data : AT (__etext) { __data_start__ = .; *(.text*) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (COPY): { __HeapBase = .; __end__ = .; end = __end__; KEEP(*(.heap*)) __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { KEEP(*(.stack*)) } > RAM /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } ================================================ FILE: hw/bsp/nuc505/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" #include "NUC505Series.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBD_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ void board_init(void) { /* Enable XTAL */ CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk; CLK_SetCoreClock(96000000); /* Set PCLK divider */ CLK_SetModuleClock(PCLK_MODULE, 0, 1); /* Update System Core Clock */ SystemCoreClockUpdate(); /* Enable USB IP clock */ CLK_EnableModuleClock(USBD_MODULE); /* Select USB IP clock source */ CLK_SetModuleClock(USBD_MODULE, CLK_USBD_SRC_EXT, 0); CLK_SetModuleClock(PCLK_MODULE, 0, 1); /* Enable PHY */ USBD_ENABLE_PHY(); /* wait PHY clock ready */ while (1) { USBD->EP[EPA].EPMPS = 0x20; if (USBD->EP[EPA].EPMPS == 0x20) break; } /* Force SE0, and then clear it to connect*/ USBD_SET_SE0(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(96000000 / 1000); #endif GPIO_SetMode(LED_PORT, 1UL << LED_PIN, GPIO_MODE_OUTPUT); } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { uint32_t current = (state) ? LED_STATE_ON : (1-LED_STATE_ON); current <<= LED_PIN; uint32_t irq_state = __get_PRIMASK(); __disable_irq(); current |= LED_PORT->DOUT & ~(1UL << LED_PIN); LED_PORT->DOUT = current; __set_PRIMASK(irq_state); } uint32_t board_button_read(void) { return 0; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } ================================================ FILE: hw/bsp/nuc505/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/nuvoton/nuc505) set(CMSIS_5 ${TOP}/lib/CMSIS_5) set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(OPENOCD_OPTION "-f interface/nulink.cfg -f target/numicroM4.cfg") set(FAMILY_MCUS NUC505 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Device/Nuvoton/NUC505Series/Source/GCC/startup_NUC505Series.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Device/Nuvoton/NUC505Series/Source/system_NUC505Series.c ${SDK_DIR}/StdDriver/src/adc.c ${SDK_DIR}/StdDriver/src/clk.c ${SDK_DIR}/StdDriver/src/gpio.c ${SDK_DIR}/StdDriver/src/i2c.c ${SDK_DIR}/StdDriver/src/i2s.c ${SDK_DIR}/StdDriver/src/pwm.c ${SDK_DIR}/StdDriver/src/rtc.c ${SDK_DIR}/StdDriver/src/spi.c ${SDK_DIR}/StdDriver/src/spim.c ${SDK_DIR}/StdDriver/src/sys.c ${SDK_DIR}/StdDriver/src/timer.c ${SDK_DIR}/StdDriver/src/uart.c ${SDK_DIR}/StdDriver/src/wdt.c ${SDK_DIR}/StdDriver/src/wwdt.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Device/Nuvoton/NUC505Series/Include ${SDK_DIR}/StdDriver/inc ${SDK_DIR}/CMSIS/Include ) update_board(${BOARD_TARGET}) endfunction() function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_NUC505) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/nuvoton/nuc505/dcd_nuc505.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}") target_compile_options(${TARGET} PRIVATE -Wno-redundant-decls) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-redundant-decls") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) family_flash_openocd_nuvoton(${TARGET}) endfunction() ================================================ FILE: hw/bsp/nuc505/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_NUC505 CPU_CORE ?= cortex-m4 # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # LD_FILE is defined in board.mk SRC_C += \ src/portable/nuvoton/nuc505/dcd_nuc505.c \ hw/mcu/nuvoton/nuc505/Device/Nuvoton/NUC505Series/Source/system_NUC505Series.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/adc.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/clk.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/gpio.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/i2c.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/i2s.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/pwm.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/rtc.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/spi.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/spim.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/sys.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/timer.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/uart.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/wdt.c \ hw/mcu/nuvoton/nuc505/StdDriver/src/wwdt.c SRC_S += \ hw/mcu/nuvoton/nuc505/Device/Nuvoton/NUC505Series/Source/GCC/startup_NUC505Series.S INC += \ $(TOP)/hw/mcu/nuvoton/nuc505/Device/Nuvoton/NUC505Series/Include \ $(TOP)/hw/mcu/nuvoton/nuc505/StdDriver/inc \ $(TOP)/hw/mcu/nuvoton/nuc505/CMSIS/Include \ $(TOP)/$(BOARD_PATH) FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F # Note # To be able to program the SPI flash, it need to boot with ICP mode "1011". # However, in ICP mode, opencod cannot establish connection to the mcu. # Therefore, there is no easy command line flash for NUC505 # It is probably better to just use Nuvoton NuMicro ICP programming on windows to program the board # Flash using Nuvoton's openocd fork at https://github.com/OpenNuvoton/OpenOCD-Nuvoton # Please compile and install it from github source OPENOCD_NUVOTON_PATH ?= $(HOME)/app/OpenOCD-Nuvoton flash: $(BUILD)/$(PROJECT).elf $(OPENOCD_NUVOTON_PATH)/src/openocd -s $(OPENOCD_NUVOTON_PATH)/tcl -f interface/nulink.cfg -f target/numicroM4.cfg -c "program $< reset exit" ================================================ FILE: hw/bsp/pic32mz/boards/olimex_emz64/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Olimex PIC32-EMZ64 url: https://www.olimex.com/Products/PIC/Development/PIC32-EMZ64/open-source-hardware */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/pic32mz/boards/olimex_emz64/board.mk ================================================ JLINK_DEVICE=PIC32MZ2048EFH064 JLINK_IF=ICSP CFLAGS += \ -mprocessor=32MZ2048EFH064 \ ================================================ FILE: hw/bsp/pic32mz/boards/olimex_emz64/olimex_emz64.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #include #include #include #include "tusb.h" /* JTAG on, WDT off */ #pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1 #pragma config DEBUG=ON #pragma config JTAGEN=ON #pragma config FSLEEP=OFF #pragma config TRCEN=OFF #pragma config ICESEL=ICS_PGx2 #pragma config POSCMOD = EC #pragma config FNOSC = SPLL /* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/ #pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2 #pragma config FUSBIDIO=1 #pragma config WINDIS=NORMAL #pragma config WDTSPGM=1 #pragma config WDTPS=15 #pragma config FWDTEN=OFF void button_init(void) { // RB12 - button // ANSELB B12 not analog ANSELBCLR = TU_BIT(12); // TRISB B12 input TRISBSET = TU_BIT(12); // Pull-up CNPUBSET = TU_BIT(12); } void led_init(void) { // RB8 - LED // ANASELB RB8 not analog ANSELBCLR = TU_BIT(8); // TRISH RH2 output TRISBCLR = TU_BIT(8); // Initial value 0, LED off LATBCLR = TU_BIT(8); } void uart_init(void) { // RD4/RD0 Uart4 TX/RX // ANSELD - not present on 64 pin device /* Unlock system for PPS configuration */ SYSKEY = 0x00000000; SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; CFGCONbits.IOLOCK = 0; // PPS Input Remapping // U4RX -> RD0 U4RXR = 3; // PPS Output Remapping // RD4 -> U4TX RPD4R = 2; // Lock back the system after PPS configuration CFGCONbits.IOLOCK = 1; SYSKEY = 0x00000000; // UART4 // High speed mode // 8 bits, no parity, no RTS/CTS, no flow control U4MODE = 0x0; // Enable UART2 Receiver and Transmitter U4STASET = (_U4STA_UTXEN_MASK | _U4STA_URXEN_MASK | _U4STA_UTXISEL1_MASK); // BAUD Rate register Setup U4BRG = 100000000 / (16 * 115200) + 1; // Disable Interrupts IEC4CLR = _IEC5_U4EIE_MASK | _IEC5_U4RXIE_MASK | _IEC5_U4TXIE_MASK; // Turn ON UART2 U4MODESET = _U4MODE_ON_MASK; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { if (state) { LATBSET = TU_BIT(8); } else { LATBCLR = TU_BIT(8); } } uint32_t board_button_read(void) { return ((PORTB >> 12) & 1) == 0; } int board_uart_write(void const * buf, int len) { int i = len; uint8_t const * data = buf; while (i--) { while (U4STAbits.UTXBF) ; U4TXREG = *data++; } return len; } ================================================ FILE: hw/bsp/pic32mz/boards/olimex_hmz144/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Olimex PIC32-HMZ144 url: https://www.olimex.com/Products/PIC/Development/PIC32-HMZ144/open-source-hardware */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/pic32mz/boards/olimex_hmz144/board.mk ================================================ JLINK_DEVICE=PIC32MZ2048EFM144 JLINK_IF=ICSP CFLAGS += \ -mprocessor=32MZ2048EFM144 \ ================================================ FILE: hw/bsp/pic32mz/boards/olimex_hmz144/olimex_hmz144.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #include #include #include #include "tusb.h" /* JTAG on, WDT off */ #pragma config FDMTEN=0, FSOSCEN=0, DMTCNT=1 #pragma config DEBUG=ON #pragma config JTAGEN=ON #pragma config FSLEEP=OFF #pragma config TRCEN=OFF #pragma config ICESEL=ICS_PGx2 #pragma config POSCMOD = HS #pragma config FNOSC = SPLL /* 24MHz posc input to pll, div by 3, multiply by 50, div by 2 -> 200mhz*/ #pragma config FPLLICLK=0, FPLLIDIV=DIV_3, FPLLRNG=RANGE_5_10_MHZ, FPLLMULT=MUL_50, FPLLODIV=DIV_2 #pragma config FUSBIDIO=1 #pragma config WINDIS=NORMAL #pragma config WDTSPGM=1 #pragma config WDTPS=15 #pragma config FWDTEN=OFF void button_init(void) { // RB12 - button // ANSELB B12 not analog ANSELBCLR = TU_BIT(12); // TRISB B12 input TRISBSET = TU_BIT(12); } void led_init(void) { // RH2 - LED // ANASELH no analog function on RH2 // TRISH RH2 output TRISHCLR = TU_BIT(2); // Initial value 0, LED off LATHCLR = TU_BIT(2); } void uart_init(void) { // RE8/RE9 Uart2 TX/RX // ANSELE - TX/RX not analog ANSELECLR = TU_BIT(8) | TU_BIT(9); /* Unlock system for PPS configuration */ SYSKEY = 0x00000000; SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; CFGCONbits.IOLOCK = 0; // PPS Input Remapping // U2RX -> RE9 U2RXR = 13; // PPS Output Remapping // RE8 -> U2TX RPE8R = 2; // Lock back the system after PPS configuration CFGCONbits.IOLOCK = 1; SYSKEY = 0x00000000; // UART2 // High speed mode // 8 bits, no parity, no RTS/CTS, no flow control U2MODE = 0x0; // Enable UART2 Receiver and Transmitter U2STASET = (_U2STA_UTXEN_MASK | _U2STA_URXEN_MASK | _U2STA_UTXISEL1_MASK); // BAUD Rate register Setup U2BRG = 100000000 / (16 * 115200) + 1; // Disable Interrupts IEC4CLR = _IEC4_U2EIE_MASK | _IEC4_U2RXIE_MASK | _IEC4_U2TXIE_MASK; // Turn ON UART2 U2MODESET = _U2MODE_ON_MASK; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { if (state) { LATHSET = TU_BIT(2); } else { LATHCLR = TU_BIT(2); } } uint32_t board_button_read(void) { return ((PORTB >> 12) & 1) == 0; } int board_uart_write(void const * buf, int len) { int i = len; uint8_t const * data = buf; while (i--) { while (U2STAbits.UTXBF) ; U2TXREG = *data++; } return len; } ================================================ FILE: hw/bsp/pic32mz/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Microchip */ #include #include #include #include "tusb.h" void __attribute__((interrupt(IPL2AUTO), vector(_USB_VECTOR), no_fpu)) USBD_IRQHandler(void) { IFS4CLR = _IFS4_USBIF_MASK; tud_int_handler(0); } TU_ATTR_WEAK void button_init(void) { } TU_ATTR_WEAK void led_init(void) { } TU_ATTR_WEAK void uart_init(void) { } void board_init(void) { button_init(); led_init(); uart_init(); // Force device mode by overriding USB ID and settings it to 1 USBCRCONbits.PHYIDEN = 0; USBCRCONbits.USBIDVAL = 1; USBCRCONbits.USBIDOVEN = 1; // set interrupt priority (must much IPL2AUTO) IPC33CLR = _IPC33_USBIP_MASK; IPC33SET = (2 << _IPC33_USBIP_POSITION); // set interrupt subpriority IPC33CLR = _IPC33_USBIS_MASK; IPC33SET = (0 << _IPC33_USBIS_POSITION); USBCRCONbits.USBIE = 0; IFS4CLR = _IFS4_USBIF_MASK; IEC4SET = _IEC4_USBIE_MASK; __builtin_enable_interrupts(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ TU_ATTR_WEAK void board_led_write(bool state) { (void) state; } TU_ATTR_WEAK uint32_t board_button_read(void) { return 0; } TU_ATTR_WEAK int board_uart_read(uint8_t * buf, int len) { (void) buf; (void) len; return 0; } TU_ATTR_WEAK int board_uart_write(void const * buf, int len) { (void) buf; return len; } #if CFG_TUSB_OS == OPT_OS_NONE uint32_t tusb_time_millis_api(void) { // COUNTER is system clock (200MHz / 2 = 100MHz) convert to ms) return _CP0_GET_COUNT() / (100000000 / 1000); } #endif ================================================ FILE: hw/bsp/pic32mz/family.mk ================================================ CROSS_COMPILE = xc32- CFLAGS_OPTIMIZED = -O2 LIBS_GCC = -lgcc -lm SKIP_NANOLIB = 1 CFLAGS = \ -std=c99 \ -DCFG_TUSB_MCU=OPT_MCU_PIC32MZ include $(TOP)/$(BOARD_PATH)/board.mk SRC_C += \ src/portable/microchip/pic32mz/dcd_pic32mz.c \ INC += \ $(TOP)/hw/mcu/microchip/pic32mz \ $(TOP)/$(BOARD_PATH) \ # flash target using jlink flash: flash-jlink ================================================ FILE: hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #pragma GCC diagnostic ignored "-Wundef" // extra push due to https://github.com/renesas/fsp/pull/278 #pragma GCC diagnostic push #endif #include "bsp_api.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS __NVIC_PRIO_BITS /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< 0) ? 0U : 1U) << 1) /* CAN1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* CAN0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* IIC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9) /* IIC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* USBFS */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18) /* SPI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19) /* SPI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* SCI9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* SCI8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* SCI7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* SCI6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* SCI5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* SCI4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* SCI3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* SCI2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* SCI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCI0 */ | \ 0x33f4f9) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARC #define BSP_TZ_CFG_PSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* CAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CRC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* CTSU */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* SSIE0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* SDHI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* DOC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCE9 */ | \ 0x7fffcef4) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARD #define BSP_TZ_CFG_PSARD (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* AGT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* AGT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* AGT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* AGT0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* POEG3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* POEG2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* POEG1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* POEG0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* ADC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 16) /* ADC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20) /* DAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* TSN */ | \ 0xffae07f0) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARE #define BSP_TZ_CFG_PSARE (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* WDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* IWDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* RTC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* AGT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* AGT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* GPT9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* GPT8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* GPT7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* GPT6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* GPT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* GPT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* GPT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* GPT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* GPT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* GPT0 */ | \ 0x3f3ff8) /* Unused */ #endif #ifndef BSP_TZ_CFG_MSSAR #define BSP_TZ_CFG_MSSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* ELC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* DTC_DMAC */ | \ 0xfffffffc) /* Unused */ #endif /* Type 2 Peripheral Security Attribution */ /* Security attribution for Cache registers. */ #ifndef BSP_TZ_CFG_CSAR #define BSP_TZ_CFG_CSAR (0xFFFFFFFFU) #endif /* Security attribution for RSTSRn registers. */ #ifndef BSP_TZ_CFG_RSTSAR #define BSP_TZ_CFG_RSTSAR (0xFFFFFFFFU) #endif /* Security attribution for registers of LVD channels. */ #ifndef BSP_TZ_CFG_LVDSAR #define BSP_TZ_CFG_LVDSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) | /* LVD Channel 1 */ \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) | /* LVD Channel 2 */ \ 0xFFFFFFFCU) #endif /* Security attribution for LPM registers. */ #ifndef BSP_TZ_CFG_LPMSAR #define BSP_TZ_CFG_LPMSAR ((RA_NOT_DEFINED > 0) ? 0xFFFFFCEAU : 0xFFFFFFFFU) #endif /* Deep Standby Interrupt Factor Security Attribution Register. */ #ifndef BSP_TZ_CFG_DPFSAR #define BSP_TZ_CFG_DPFSAR ((RA_NOT_DEFINED > 0) ? 0xF2E00000U : 0xFFFFFFFFU) #endif /* Security attribution for CGC registers. */ #ifndef BSP_TZ_CFG_CGFSAR #if BSP_CFG_CLOCKS_SECURE /* Protect all CGC registers from Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFCE402U) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFFFFFFU) #endif #endif /* Security attribution for Battery Backup registers. */ #ifndef BSP_TZ_CFG_BBFSAR #define BSP_TZ_CFG_BBFSAR (0x00FFFFFF) #endif /* Security attribution for registers for IRQ channels. */ #ifndef BSP_TZ_CFG_ICUSARA #define BSP_TZ_CFG_ICUSARA (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* External IRQ0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* External IRQ1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* External IRQ2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* External IRQ3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* External IRQ4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* External IRQ5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* External IRQ6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* External IRQ7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8U) /* External IRQ8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9U) /* External IRQ9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 10U) /* External IRQ10 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11U) /* External IRQ11 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12U) /* External IRQ12 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13U) /* External IRQ13 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14U) /* External IRQ14 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15U) /* External IRQ15 */ | \ 0xFFFF0000U) #endif /* Security attribution for NMI registers. */ #ifndef BSP_TZ_CFG_ICUSARB #define BSP_TZ_CFG_ICUSARB (0 | 0xFFFFFFFEU) /* Should match AIRCR.BFHFNMINS. */ #endif /* Security attribution for registers for DMAC channels */ #ifndef BSP_TZ_CFG_ICUSARC #define BSP_TZ_CFG_ICUSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* DMAC Channel 0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* DMAC Channel 1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* DMAC Channel 2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* DMAC Channel 3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* DMAC Channel 4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* DMAC Channel 5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* DMAC Channel 6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* DMAC Channel 7 */ | \ 0xFFFFFF00U) #endif /* Security attribution registers for SELSR0. */ #ifndef BSP_TZ_CFG_ICUSARD #define BSP_TZ_CFG_ICUSARD ((RA_NOT_DEFINED > 0) ? 0xFFFFFFFEU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN0. */ #ifndef BSP_TZ_CFG_ICUSARE #define BSP_TZ_CFG_ICUSARE ((RA_NOT_DEFINED > 0) ? 0x04F2FFFFU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN1. */ #ifndef BSP_TZ_CFG_ICUSARF #define BSP_TZ_CFG_ICUSARF ((RA_NOT_DEFINED > 0) ? 0xFFFFFFF8U : 0xFFFFFFFFU) #endif /* Set DTCSTSAR if the Secure program uses the DTC. */ #if RA_NOT_DEFINED == RA_NOT_DEFINED #define BSP_TZ_CFG_DTC_USED (0U) #else #define BSP_TZ_CFG_DTC_USED (1U) #endif /* Security attribution of FLWT and FCKMHZ registers. */ #ifndef BSP_TZ_CFG_FSAR /* If the CGC registers are only accessible in Secure mode, than there is no * reason for nonsecure applications to access FLWT and FCKMHZ. */ #if BSP_CFG_CLOCKS_SECURE /* Protect FLWT and FCKMHZ registers from nonsecure write access. */ #define BSP_TZ_CFG_FSAR (0xFEFEU) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_FSAR (0xFFFFU) #endif #endif /* Security attribution for SRAM registers. */ #ifndef BSP_TZ_CFG_SRAMSAR /* If the CGC registers are only accessible in Secure mode, than there is no reason for Non Secure applications to access * SRAM0WTEN and therefore there is no reason to access PRCR2. */ #define BSP_TZ_CFG_SRAMSAR (\ 1 | \ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 1U) : 0U) | \ 4 | \ 0xFFFFFFF8U) #endif /* Security attribution for Standby RAM registers. */ #ifndef BSP_TZ_CFG_STBRAMSAR #define BSP_TZ_CFG_STBRAMSAR (0 | 0xFFFFFFF0U) #endif /* Security attribution for the DMAC Bus Master MPU settings. */ #ifndef BSP_TZ_CFG_MMPUSARA /* The DMAC Bus Master MPU settings should align with the DMAC channel settings. */ #define BSP_TZ_CFG_MMPUSARA (BSP_TZ_CFG_ICUSARC) #endif /* Security Attribution Register A for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARA #define BSP_TZ_CFG_BUSSARA (0xFFFFFFFFU) #endif /* Security Attribution Register B for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARB #define BSP_TZ_CFG_BUSSARB (0xFFFFFFFFU) #endif /* Enable Uninitialized Non-Secure Application Fallback. */ #ifndef BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK #define BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK (1U) #endif #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) /* Option Function Select Register 1 Security Attribution */ #ifndef BSP_CFG_ROM_REG_OFS1_SEL #if defined(_RA_TZ_SECURE) || defined(_RA_TZ_NONSECURE) #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U | ((0U << 0U)) | ((0U << 2U)) | ((BSP_CFG_CLOCKS_SECURE == 0) ? 0x700U : 0U)) #else #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U) #endif #endif #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEF8 | (1 << 2) | (3) | (1 << 8)) /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* Dual Mode Select Register */ #ifndef BSP_CFG_ROM_REG_DUALSEL #define BSP_CFG_ROM_REG_DUALSEL (0xFFFFFFF8U | (0x7U)) #endif /* Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_BPS0 #define BSP_CFG_ROM_REG_BPS0 (~( 0U)) #endif /* Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_BPS1 #define BSP_CFG_ROM_REG_BPS1 (~( 0U)) #endif /* Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_BPS2 #define BSP_CFG_ROM_REG_BPS2 (~( 0U)) #endif /* Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_BPS3 #define BSP_CFG_ROM_REG_BPS3 (0xFFFFFFFFU) #endif /* Permanent Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_PBPS0 #define BSP_CFG_ROM_REG_PBPS0 (~( 0U)) #endif /* Permanent Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_PBPS1 #define BSP_CFG_ROM_REG_PBPS1 (~( 0U)) #endif /* Permanent Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_PBPS2 #define BSP_CFG_ROM_REG_PBPS2 (~( 0U)) #endif /* Permanent Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_PBPS3 #define BSP_CFG_ROM_REG_PBPS3 (0xFFFFFFFFU) #endif /* Security Attribution for Block Protection Register 0 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL0 #define BSP_CFG_ROM_REG_BPS_SEL0 (BSP_CFG_ROM_REG_BPS0 & BSP_CFG_ROM_REG_PBPS0) #endif /* Security Attribution for Block Protection Register 1 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL1 #define BSP_CFG_ROM_REG_BPS_SEL1 (BSP_CFG_ROM_REG_BPS1 & BSP_CFG_ROM_REG_PBPS1) #endif /* Security Attribution for Block Protection Register 2 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL2 #define BSP_CFG_ROM_REG_BPS_SEL2 (BSP_CFG_ROM_REG_BPS2 & BSP_CFG_ROM_REG_PBPS2) #endif /* Security Attribution for Block Protection Register 3 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL3 #define BSP_CFG_ROM_REG_BPS_SEL3 (BSP_CFG_ROM_REG_BPS3 & BSP_CFG_ROM_REG_PBPS3) #endif /* Security Attribution for Bank Select Register */ #ifndef BSP_CFG_ROM_REG_BANKSEL_SEL #define BSP_CFG_ROM_REG_BANKSEL_SEL (0xFFFFFFFFU) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define LED1 (BSP_IO_PORT_01_PIN_07) #define SW1 (BSP_IO_PORT_04_PIN_08) extern const ioport_cfg_t g_bsp_pin_cfg; /* R7FA6M5BH3CFC.pincfg */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (24000000) /* XTAL 24000000Hz */ #define BSP_CFG_HOCO_FREQUENCY (2) /* HOCO 20MHz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_3) /* PLL Div /3 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(25U,0U) /* PLL Mul x25.0 */ #define BSP_CFG_PLL2_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL2 Src: XTAL */ #define BSP_CFG_PLL2_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL2 Div /2 */ #define BSP_CFG_PLL2_MUL BSP_CLOCKS_PLL_MUL(20U,0U) /* PLL2 Mul x20.0 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL2) /* UCLK Src: PLL2 */ #define BSP_CFG_U60CK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL2) /* U60CK Src: PLL2 */ #define BSP_CFG_OCTA_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* OCTASPICLK Disabled */ #define BSP_CFG_CANFDCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CANFDCLK Disabled */ #define BSP_CFG_CECCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CECCLK Disabled */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKA Div /2 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKB Div /4 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKC Div /4 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKD Div /2 */ #define BSP_CFG_BCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* BCLK Div /2 */ #define BSP_CFG_BCLK_OUTPUT (2) /* EBCLK Div /2 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* FCLK Div /4 */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_UCK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_5) /* UCLK Div /5 */ #define BSP_CFG_U60CK_DIV (BSP_CLOCKS_USB60_CLOCK_DIV_4) /* U60CK Div /4 */ #define BSP_CFG_OCTA_DIV (BSP_CLOCKS_OCTA_CLOCK_DIV_1) /* OCTASPICLK Div /1 */ #define BSP_CFG_CANFDCLK_DIV (BSP_CLOCKS_CANFD_CLOCK_DIV_1) /* CANFDCLK Div /1 */ #define BSP_CFG_CECCLK_DIV (BSP_CLOCKS_CEC_CLOCK_DIV_1) /* CECCLK Div /1 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/portenta_c33/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_01_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_11_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/portenta_c33/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x80000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x200000; DATA_FLASH_START = 0x08000000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x0100A100; OPTION_SETTING_LENGTH = 0x100; OPTION_SETTING_S_START = 0x0100A200; OPTION_SETTING_S_LENGTH = 0x100; ID_CODE_START = 0x00000000; ID_CODE_LENGTH = 0x0; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x4000000; OSPI_DEVICE_0_START = 0x68000000; OSPI_DEVICE_0_LENGTH = 0x8000000; OSPI_DEVICE_1_START = 0x70000000; OSPI_DEVICE_1_LENGTH = 0x10000000; /* Board has bootloader */ FLASH_IMAGE_START = 0x10000; ================================================ FILE: hw/bsp/ra/boards/portenta_c33/smart_configurator/configuration.xml ================================================ Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack Custom Board Support Files Renesas.RA_board_custom.5.6.0.pack Board support package for R7FA6M5BH3CFC Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 - FSP Data Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 - Events Renesas.RA_mcu_ra6m5.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m23 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra2a1) set(JLINK_DEVICE R7FA2A1AB) function(update_board TARGET) # target_compile_definitions(${TARGET} PUBLIC) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA2A1 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra2a1-evaluation-kit-ra2a1-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/board.mk ================================================ CPU_CORE = cortex-m23 MCU_VARIANT = ra2a1 # For flash-jlink target JLINK_DEVICE = R7FA2A1AB flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x400) #define BSP_CFG_HEAP_BYTES (0x400) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (2) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA2A1AB3CFM #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (262144) #define BSP_RAM_SIZE_BYTES (32768) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_LQFP #define BSP_PACKAGE_PINS (64) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra2a1/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA2A1 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (24000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (32000000) #elif BSP_CFG_HOCO_FREQUENCY == 4 #define BSP_HOCO_HZ (48000000) #elif BSP_CFG_HOCO_FREQUENCY == 5 #define BSP_HOCO_HZ (64000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (48U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (0) #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_USE_LOW_VOLTAGE_MODE ((0)) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEC3 | (1 << 2) | (3 << 3) | (0 << 8)) #define BSP_CFG_ROM_REG_MPU_PC0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC0_START (0x000FFFFC) #define BSP_CFG_ROM_REG_MPU_PC0_END (0x000FFFFF) #define BSP_CFG_ROM_REG_MPU_PC1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC1_START (0x000FFFFC) #define BSP_CFG_ROM_REG_MPU_PC1_END (0x000FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION0_START (0x000FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION0_END (0x000FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION1_START (0x200FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION1_END (0x200FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION2_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION2_START (0x407FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION2_END (0x407FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION3_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION3_START (0x400DFFFC) #define BSP_CFG_ROM_REG_MPU_REGION3_END (0x400DFFFF) #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* ID Code Note: To lock and disable the debug interface define BSP_ID_CODE_LOCKED in compiler settings. WARNING: This will disable debug access to the part. However, ALeRASE command will be accepted, which will clear (reset) the ID code. After clearing ID code, debug access will be enabled. */ #if defined(BSP_ID_CODE_LOCKED) #define BSP_CFG_ID_CODE_LONG_1 (0x00000000) #define BSP_CFG_ID_CODE_LONG_2 (0x00000000) #define BSP_CFG_ID_CODE_LONG_3 (0x00000000) #define BSP_CFG_ID_CODE_LONG_4 (0x00000000) #else /* ID CODE: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */ #define BSP_CFG_ID_CODE_LONG_1 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_2 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_3 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_4 (0xffFFFFFF) #endif #if (0) #define BSP_SECTION_FLASH_GAP BSP_PLACE_IN_SECTION(".flash_gap") #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define LED1 (BSP_IO_PORT_02_PIN_05) #define SW1 (BSP_IO_PORT_02_PIN_06) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA2A1-EK.pincfg */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (12000000) /* XTAL 12000000Hz */ #define BSP_CFG_HOCO_FREQUENCY (4) /* HOCO 48MHz */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_HOCO) /* Clock Src: HOCO */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKB Div /2 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKD Div /1 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* FCLK Div /2 */ #define BSP_CFG_SDADC_CLOCK_SOURCE (0) /* SDADCCLK Src: HOCO */ #define BSP_CFG_SDADCCLK_DIV (7) /* SDADCCLK Div /12 */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_00_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_02_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_02_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_03_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_03_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_04_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_09_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_09_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x8000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x40000; DATA_FLASH_START = 0x40100000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x00000000; OPTION_SETTING_LENGTH = 0x0; OPTION_SETTING_S_START = 0x80000000; OPTION_SETTING_S_LENGTH = 0x0; ID_CODE_START = 0x01010018; ID_CODE_LENGTH = 0x20; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x0; OSPI_DEVICE_0_START = 0x80020000; OSPI_DEVICE_0_LENGTH = 0x0; OSPI_DEVICE_1_START = 0x80030000; OSPI_DEVICE_1_LENGTH = 0x0; ================================================ FILE: hw/bsp/ra/boards/ra2a1_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack RA2A1-EK Board Support Files Renesas.RA_board_ra2a1_ek.5.6.0.pack Board support package for R7FA2A1AB3CFM Renesas.RA_mcu_ra2a1.5.6.0.pack Board support package for RA2A1 Renesas.RA_mcu_ra2a1.5.6.0.pack Board support package for RA2A1 - FSP Data Renesas.RA_mcu_ra2a1.5.6.0.pack Board support package for RA2A1 - Events Renesas.RA_mcu_ra2a1.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra4m1) set(JLINK_DEVICE R7FA4M1AB) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CFG_EXAMPLE_VIDEO_READONLY ) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA4M1 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m1-evaluation-kit-ra4m1-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/board.mk ================================================ CPU_CORE = cortex-m4 MCU_VARIANT = ra4m1 # For flash-jlink target JLINK_DEVICE = R7FA4M1AB flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x800) #define BSP_CFG_HEAP_BYTES (0x1000) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (4) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA4M1AB3CFP #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (262144) #define BSP_RAM_SIZE_BYTES (32768) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_LQFP #define BSP_PACKAGE_PINS (100) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra4m1/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA4M1 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (24000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (32000000) #elif BSP_CFG_HOCO_FREQUENCY == 4 #define BSP_HOCO_HZ (48000000) #elif BSP_CFG_HOCO_FREQUENCY == 5 #define BSP_HOCO_HZ (64000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (48U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEC3 | (1 << 2) | (3 << 3) | (0 << 8)) #define BSP_CFG_USE_LOW_VOLTAGE_MODE ((0)) #define BSP_CFG_ROM_REG_MPU_PC0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC0_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_PC0_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_PC1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC1_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_PC1_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION0_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_REGION0_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION1_START (0x200FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION1_END (0x200FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION2_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION2_START (0x407FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION2_END (0x407FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION3_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION3_START (0x400DFFFC) #define BSP_CFG_ROM_REG_MPU_REGION3_END (0x400DFFFF) #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* ID Code Note: To permanently lock and disable the debug interface define the BSP_ID_CODE_PERMANENTLY_LOCKED in the compiler settings. WARNING: This will disable debug access to the part and cannot be reversed by a debug probe. */ #if defined(BSP_ID_CODE_PERMANENTLY_LOCKED) #define BSP_CFG_ID_CODE_LONG_1 (0x00000000) #define BSP_CFG_ID_CODE_LONG_2 (0x00000000) #define BSP_CFG_ID_CODE_LONG_3 (0x00000000) #define BSP_CFG_ID_CODE_LONG_4 (0x00000000) #else /* ID CODE: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */ #define BSP_CFG_ID_CODE_LONG_1 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_2 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_3 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_4 (0xffFFFFFF) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define SW1 (BSP_IO_PORT_01_PIN_05) #define LED1 (BSP_IO_PORT_01_PIN_06) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA4M1-EK.pincfg */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (12000000) /* XTAL 12000000Hz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_HOCO_FREQUENCY (0) /* HOCO 24MHz */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL Div /2 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(8U,0U) /* PLL Mul x8 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKA Div /1 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKB Div /2 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKC Div /1 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKD Div /1 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* FCLK Div /2 */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* UCLK Src: PLL */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_02_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_04_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_04_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_04_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_09_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_09_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x8000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x40000; DATA_FLASH_START = 0x40100000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x00000000; OPTION_SETTING_LENGTH = 0x0; OPTION_SETTING_S_START = 0x80000000; OPTION_SETTING_S_LENGTH = 0x0; ID_CODE_START = 0x01010018; ID_CODE_LENGTH = 0x20; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x0; OSPI_DEVICE_0_START = 0x80020000; OSPI_DEVICE_0_LENGTH = 0x0; OSPI_DEVICE_1_START = 0x80030000; OSPI_DEVICE_1_LENGTH = 0x0; ================================================ FILE: hw/bsp/ra/boards/ra4m1_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack RA4M1-EK Board Support Files Renesas.RA_board_ra4m1_ek.5.6.0.pack Board support package for R7FA4M1AB3CFP Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 - FSP Data Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 - Events Renesas.RA_mcu_ra4m1.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra4m3) set(JLINK_DEVICE R7FA4M3AF) function(update_board TARGET) # target_compile_definitions(${TARGET} PUBLIC) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA4M3 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m3-evaluation-kit-ra4m3-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED1 (BSP_IO_PORT_04_PIN_15) #define LED_STATE_ON 1 #define SW1 (BSP_IO_PORT_00_PIN_05) #define BUTTON_STATE_ACTIVE 0 static const ioport_pin_cfg_t board_pin_cfg[] = { {.pin = LED1, .pin_cfg = IOPORT_CFG_PORT_DIRECTION_OUTPUT}, {.pin = SW1, .pin_cfg = IOPORT_CFG_PORT_DIRECTION_INPUT}, // USB FS {.pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, {.pin = BSP_IO_PORT_05_PIN_00, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, {.pin = BSP_IO_PORT_05_PIN_01, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, }; #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/board.mk ================================================ CPU_CORE = cortex-m33 MCU_VARIANT = ra4m3 # For flash-jlink target JLINK_DEVICE = R7FA4M3AF flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x800) #define BSP_CFG_HEAP_BYTES (0x800) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (4) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA4M3AF3CFB #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (1048576) #define BSP_RAM_SIZE_BYTES (131072) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_LQFP #define BSP_PACKAGE_PINS (144) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra4m3/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA4M3 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (16000000) #elif BSP_CFG_HOCO_FREQUENCY == 1 #define BSP_HOCO_HZ (18000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (20000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CFG_FLL_ENABLE (0) #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (112U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #if defined(_RA_TZ_SECURE) #define BSP_TZ_SECURE_BUILD (1) #define BSP_TZ_NONSECURE_BUILD (0) #elif defined(_RA_TZ_NONSECURE) #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (1) #else #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (0) #endif /* TrustZone Settings */ #define BSP_TZ_CFG_INIT_SECURE_ONLY (BSP_CFG_CLOCKS_SECURE || (!BSP_CFG_CLOCKS_OVERRIDE)) #define BSP_TZ_CFG_SKIP_INIT (BSP_TZ_NONSECURE_BUILD && BSP_TZ_CFG_INIT_SECURE_ONLY) #define BSP_TZ_CFG_EXCEPTION_RESPONSE (0) /* CMSIS TrustZone Settings */ #define SCB_CSR_AIRCR_INIT (1) #define SCB_AIRCR_BFHFNMINS_VAL (0) #define SCB_AIRCR_SYSRESETREQS_VAL (1) #define SCB_AIRCR_PRIS_VAL (0) #define TZ_FPU_NS_USAGE (1) #ifndef SCB_NSACR_CP10_11_VAL #define SCB_NSACR_CP10_11_VAL (3U) #endif #ifndef FPU_FPCCR_TS_VAL #define FPU_FPCCR_TS_VAL (1U) #endif #define FPU_FPCCR_CLRONRETS_VAL (1) #ifndef FPU_FPCCR_CLRONRET_VAL #define FPU_FPCCR_CLRONRET_VAL (1) #endif /* The C-Cache line size that is configured during startup. */ #ifndef BSP_CFG_C_CACHE_LINE_SIZE #define BSP_CFG_C_CACHE_LINE_SIZE (1U) #endif /* Type 1 Peripheral Security Attribution */ /* Peripheral Security Attribution Register (PSAR) Settings */ #ifndef BSP_TZ_CFG_PSARB #define BSP_TZ_CFG_PSARB (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CAN1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* CAN0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* IIC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9) /* IIC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* USBFS */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18) /* SPI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19) /* SPI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* SCI9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* SCI8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* SCI7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* SCI6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* SCI5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* SCI4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* SCI3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* SCI2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* SCI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCI0 */ | \ 0x33f4f9) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARC #define BSP_TZ_CFG_PSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* CAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CRC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* CTSU */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* SSIE0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* SDHI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* DOC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCE9 */ | \ 0x7fffcef4) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARD #define BSP_TZ_CFG_PSARD (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* AGT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* AGT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* AGT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* AGT0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* POEG3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* POEG2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* POEG1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* POEG0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* ADC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 16) /* ADC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20) /* DAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* TSN */ | \ 0xffae07f0) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARE #define BSP_TZ_CFG_PSARE (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* WDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* IWDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* RTC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* AGT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* AGT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* GPT9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* GPT8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* GPT7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* GPT6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* GPT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* GPT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* GPT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* GPT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* GPT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* GPT0 */ | \ 0x3f3ff8) /* Unused */ #endif #ifndef BSP_TZ_CFG_MSSAR #define BSP_TZ_CFG_MSSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* ELC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* DTC_DMAC */ | \ 0xfffffffc) /* Unused */ #endif /* Type 2 Peripheral Security Attribution */ /* Security attribution for Cache registers. */ #ifndef BSP_TZ_CFG_CSAR #define BSP_TZ_CFG_CSAR (0xFFFFFFFFU) #endif /* Security attribution for RSTSRn registers. */ #ifndef BSP_TZ_CFG_RSTSAR #define BSP_TZ_CFG_RSTSAR (0xFFFFFFFFU) #endif /* Security attribution for registers of LVD channels. */ #ifndef BSP_TZ_CFG_LVDSAR #define BSP_TZ_CFG_LVDSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) | /* LVD Channel 1 */ \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) | /* LVD Channel 2 */ \ 0xFFFFFFFCU) #endif /* Security attribution for LPM registers. */ #ifndef BSP_TZ_CFG_LPMSAR #define BSP_TZ_CFG_LPMSAR ((RA_NOT_DEFINED > 0) ? 0xFFFFFCEAU : 0xFFFFFFFFU) #endif /* Deep Standby Interrupt Factor Security Attribution Register. */ #ifndef BSP_TZ_CFG_DPFSAR #define BSP_TZ_CFG_DPFSAR ((RA_NOT_DEFINED > 0) ? 0xF2E00000U : 0xFFFFFFFFU) #endif /* Security attribution for CGC registers. */ #ifndef BSP_TZ_CFG_CGFSAR #if BSP_CFG_CLOCKS_SECURE /* Protect all CGC registers from Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFCE402U) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFFFFFFU) #endif #endif /* Security attribution for Battery Backup registers. */ #ifndef BSP_TZ_CFG_BBFSAR #define BSP_TZ_CFG_BBFSAR (0x00FFFFFF) #endif /* Security attribution for registers for IRQ channels. */ #ifndef BSP_TZ_CFG_ICUSARA #define BSP_TZ_CFG_ICUSARA (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* External IRQ0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* External IRQ1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* External IRQ2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* External IRQ3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* External IRQ4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* External IRQ5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* External IRQ6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* External IRQ7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8U) /* External IRQ8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9U) /* External IRQ9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 10U) /* External IRQ10 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11U) /* External IRQ11 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12U) /* External IRQ12 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13U) /* External IRQ13 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14U) /* External IRQ14 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15U) /* External IRQ15 */ | \ 0xFFFF0000U) #endif /* Security attribution for NMI registers. */ #ifndef BSP_TZ_CFG_ICUSARB #define BSP_TZ_CFG_ICUSARB (0 | 0xFFFFFFFEU) /* Should match AIRCR.BFHFNMINS. */ #endif /* Security attribution for registers for DMAC channels */ #ifndef BSP_TZ_CFG_ICUSARC #define BSP_TZ_CFG_ICUSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* DMAC Channel 0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* DMAC Channel 1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* DMAC Channel 2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* DMAC Channel 3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* DMAC Channel 4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* DMAC Channel 5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* DMAC Channel 6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* DMAC Channel 7 */ | \ 0xFFFFFF00U) #endif /* Security attribution registers for SELSR0. */ #ifndef BSP_TZ_CFG_ICUSARD #define BSP_TZ_CFG_ICUSARD ((RA_NOT_DEFINED > 0) ? 0xFFFFFFFEU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN0. */ #ifndef BSP_TZ_CFG_ICUSARE #define BSP_TZ_CFG_ICUSARE ((RA_NOT_DEFINED > 0) ? 0x04F2FFFFU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN1. */ #ifndef BSP_TZ_CFG_ICUSARF #define BSP_TZ_CFG_ICUSARF ((RA_NOT_DEFINED > 0) ? 0xFFFFFFF8U : 0xFFFFFFFFU) #endif /* Set DTCSTSAR if the Secure program uses the DTC. */ #if RA_NOT_DEFINED == RA_NOT_DEFINED #define BSP_TZ_CFG_DTC_USED (0U) #else #define BSP_TZ_CFG_DTC_USED (1U) #endif /* Security attribution of FLWT and FCKMHZ registers. */ #ifndef BSP_TZ_CFG_FSAR /* If the CGC registers are only accessible in Secure mode, than there is no * reason for nonsecure applications to access FLWT and FCKMHZ. */ #if BSP_CFG_CLOCKS_SECURE /* Protect FLWT and FCKMHZ registers from nonsecure write access. */ #define BSP_TZ_CFG_FSAR (0xFEFEU) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_FSAR (0xFFFFU) #endif #endif /* Security attribution for SRAM registers. */ #ifndef BSP_TZ_CFG_SRAMSAR /* If the CGC registers are only accessible in Secure mode, than there is no reason for Non Secure applications to access * SRAM0WTEN and therefore there is no reason to access PRCR2. */ #define BSP_TZ_CFG_SRAMSAR (\ 1 | \ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 1U) : 0U) | \ 4 | \ 0xFFFFFFF8U) #endif /* Security attribution for Standby RAM registers. */ #ifndef BSP_TZ_CFG_STBRAMSAR #define BSP_TZ_CFG_STBRAMSAR (0 | 0xFFFFFFF0U) #endif /* Security attribution for the DMAC Bus Master MPU settings. */ #ifndef BSP_TZ_CFG_MMPUSARA /* The DMAC Bus Master MPU settings should align with the DMAC channel settings. */ #define BSP_TZ_CFG_MMPUSARA (BSP_TZ_CFG_ICUSARC) #endif /* Security Attribution Register A for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARA #define BSP_TZ_CFG_BUSSARA (0xFFFFFFFFU) #endif /* Security Attribution Register B for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARB #define BSP_TZ_CFG_BUSSARB (0xFFFFFFFFU) #endif /* Enable Uninitialized Non-Secure Application Fallback. */ #ifndef BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK #define BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK (1U) #endif #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) /* Option Function Select Register 1 Security Attribution */ #ifndef BSP_CFG_ROM_REG_OFS1_SEL #if defined(_RA_TZ_SECURE) || defined(_RA_TZ_NONSECURE) #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U | ((0U << 0U)) | ((0U << 2U)) | ((BSP_CFG_CLOCKS_SECURE == 0) ? 0x700U : 0U)) #else #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U) #endif #endif #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEF8 | (1 << 2) | (3) | (1 << 8)) /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* Dual Mode Select Register */ #ifndef BSP_CFG_ROM_REG_DUALSEL #define BSP_CFG_ROM_REG_DUALSEL (0xFFFFFFFFU) #endif /* Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_BPS0 #define BSP_CFG_ROM_REG_BPS0 (~( 0U)) #endif /* Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_BPS1 #define BSP_CFG_ROM_REG_BPS1 (~( 0U)) #endif /* Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_BPS2 #define BSP_CFG_ROM_REG_BPS2 (0xFFFFFFFFU) #endif /* Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_BPS3 #define BSP_CFG_ROM_REG_BPS3 (0xFFFFFFFFU) #endif /* Permanent Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_PBPS0 #define BSP_CFG_ROM_REG_PBPS0 (~( 0U)) #endif /* Permanent Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_PBPS1 #define BSP_CFG_ROM_REG_PBPS1 (~( 0U)) #endif /* Permanent Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_PBPS2 #define BSP_CFG_ROM_REG_PBPS2 (0xFFFFFFFFU) #endif /* Permanent Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_PBPS3 #define BSP_CFG_ROM_REG_PBPS3 (0xFFFFFFFFU) #endif /* Security Attribution for Block Protection Register 0 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL0 #define BSP_CFG_ROM_REG_BPS_SEL0 (BSP_CFG_ROM_REG_BPS0 & BSP_CFG_ROM_REG_PBPS0) #endif /* Security Attribution for Block Protection Register 1 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL1 #define BSP_CFG_ROM_REG_BPS_SEL1 (BSP_CFG_ROM_REG_BPS1 & BSP_CFG_ROM_REG_PBPS1) #endif /* Security Attribution for Block Protection Register 2 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL2 #define BSP_CFG_ROM_REG_BPS_SEL2 (0xFFFFFFFFU) #endif /* Security Attribution for Block Protection Register 3 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL3 #define BSP_CFG_ROM_REG_BPS_SEL3 (0xFFFFFFFFU) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define ARDUINO_A0_MIKROBUS_AN (BSP_IO_PORT_00_PIN_00) #define ARDUINO_A1 (BSP_IO_PORT_00_PIN_01) #define ARDUINO_A2 (BSP_IO_PORT_00_PIN_03) #define SW1 (BSP_IO_PORT_00_PIN_05) #define SW2 (BSP_IO_PORT_00_PIN_06) #define ARDUINO_A3 (BSP_IO_PORT_00_PIN_07) #define PMOD1_INT (BSP_IO_PORT_00_PIN_08) #define ARDUINO_A4 (BSP_IO_PORT_00_PIN_14) #define ARDUINO_A5 (BSP_IO_PORT_00_PIN_15) #define ARDUINO_RX_MIKROBUS_RX (BSP_IO_PORT_01_PIN_00) #define ARDUINO_TX_MIKROBUS_TX (BSP_IO_PORT_01_PIN_01) #define ARDUINO_D2 (BSP_IO_PORT_01_PIN_05) #define ARDUINO_D3 (BSP_IO_PORT_01_PIN_11) #define MIKROBUS_RST (BSP_IO_PORT_01_PIN_15) #define ARDUINO_MISO_MIKROBUS_MISO_PMOD1_MISO (BSP_IO_PORT_02_PIN_02) #define ARDUINO_MOSI_MIKROBUS_MOSI_PMOD1_MOSI (BSP_IO_PORT_02_PIN_03) #define ARDUINO_CLK_MIKROBUS_CLK_PMOD1_CLK (BSP_IO_PORT_02_PIN_04) #define ARDUINO_SS_MIKCRBUS_SS (BSP_IO_PORT_02_PIN_05) #define PMOD1_SS1 (BSP_IO_PORT_02_PIN_06) #define PMOD1_SS2 (BSP_IO_PORT_02_PIN_07) #define PMOD1_SS3 (BSP_IO_PORT_03_PIN_02) #define ARDUINO_D9 (BSP_IO_PORT_03_PIN_03) #define ARDUINO_D7 (BSP_IO_PORT_03_PIN_04) #define QSPI_CLK (BSP_IO_PORT_03_PIN_05) #define QSPI_SSL (BSP_IO_PORT_03_PIN_06) #define QSPI_IO0 (BSP_IO_PORT_03_PIN_07) #define QSPI_IO1 (BSP_IO_PORT_03_PIN_08) #define QSPI_IO2 (BSP_IO_PORT_03_PIN_09) #define QSPI_IO3 (BSP_IO_PORT_03_PIN_10) #define PMOD1_RST (BSP_IO_PORT_03_PIN_11) #define LED3 (BSP_IO_PORT_04_PIN_00) #define LED2 (BSP_IO_PORT_04_PIN_04) #define USB_VBUS (BSP_IO_PORT_04_PIN_07) #define ARDUINO_D6_MIKROBUS_PWM (BSP_IO_PORT_04_PIN_08) #define MIKROBUS_INT (BSP_IO_PORT_04_PIN_09) #define PMOD2_INT (BSP_IO_PORT_04_PIN_14) #define LED1 (BSP_IO_PORT_04_PIN_15) #define USB_VBUS_EN (BSP_IO_PORT_05_PIN_00) #define USB_VBUS_OC (BSP_IO_PORT_05_PIN_01) #define GROVE2_AN1 (BSP_IO_PORT_05_PIN_05) #define GROVE2_AN2 (BSP_IO_PORT_05_PIN_06) #define GROVE1_SDA_QWIIC_SDA (BSP_IO_PORT_05_PIN_11) #define GROVE1_SCL_QWIIC_SCL (BSP_IO_PORT_05_PIN_12) #define ARDUINO_SCL_MIKROBUS_SCL (BSP_IO_PORT_06_PIN_01) #define ARDUINO_SDA_MIKROBUS_SDA (BSP_IO_PORT_06_PIN_02) #define ARDUINO_D8 (BSP_IO_PORT_06_PIN_11) #define ARDUINO_RST (BSP_IO_PORT_06_PIN_12) #define PMOD2_RST (BSP_IO_PORT_07_PIN_08) #define PMOD2_SS2 (BSP_IO_PORT_07_PIN_09) #define PMOD2_SS3 (BSP_IO_PORT_07_PIN_10) #define ARDUINO_D5 (BSP_IO_PORT_07_PIN_12) #define ARDUINO_D4 (BSP_IO_PORT_07_PIN_13) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA4M3 EK */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (24000000) /* XTAL 24000000Hz */ #define BSP_CFG_HOCO_FREQUENCY (2) /* HOCO 20MHz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_3) /* PLL Div /3 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(25U,0U) /* PLL Mul x25.0 */ #define BSP_CFG_PLL2_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL2 Src: XTAL */ #define BSP_CFG_PLL2_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL2 Div /2 */ #define BSP_CFG_PLL2_MUL BSP_CLOCKS_PLL_MUL(20U,0U) /* PLL2 Mul x20.0 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL2) /* UCLK Src: PLL2 */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* ICLK Div /2 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKA Div /2 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKB Div /4 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKC Div /4 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKD Div /2 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* FCLK Div /4 */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_UCK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_5) /* UCLK Div /5 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_01_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_03_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_03_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_03_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_03_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_GPT1) }, { .pin = BSP_IO_PORT_04_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_04_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_04_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_05_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_05_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_05_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_05_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_06_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_NMOS_ENABLE | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_06_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_NMOS_ENABLE | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_06_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_06_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_07_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_07_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_07_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_07_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_07_PIN_13, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x20000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x100000; DATA_FLASH_START = 0x08000000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x0100A100; OPTION_SETTING_LENGTH = 0x100; OPTION_SETTING_S_START = 0x0100A200; OPTION_SETTING_S_LENGTH = 0x100; ID_CODE_START = 0x00000000; ID_CODE_LENGTH = 0x0; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x4000000; OSPI_DEVICE_0_START = 0x80020000; OSPI_DEVICE_0_LENGTH = 0x0; OSPI_DEVICE_1_START = 0x80030000; OSPI_DEVICE_1_LENGTH = 0x0; ================================================ FILE: hw/bsp/ra/boards/ra4m3_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack Board support package for R7FA4M3AF3CFB Renesas.RA_mcu_ra4m3.5.6.0.pack Board support package for RA4M3 Renesas.RA_mcu_ra4m3.5.6.0.pack Board support package for RA4M3 - FSP Data Renesas.RA_mcu_ra4m3.5.6.0.pack Board support package for RA4M3 - Events Renesas.RA_mcu_ra4m3.5.6.0.pack RA4M3-EK Board Support Files Renesas.RA_board_ra4m3_ek.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra6m1) set(JLINK_DEVICE R7FA6M1AD) function(update_board TARGET) # target_compile_definitions(${TARGET} PUBLIC) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA6M1 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m1-evaluation-kit-ra6m1-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/board.mk ================================================ CPU_CORE = cortex-m4 MCU_VARIANT = ra6m1 # For flash-jlink target JLINK_DEVICE = R7FA6M1AD flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x1000) #define BSP_CFG_HEAP_BYTES (0x1000) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (6) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA6M1AD3CFP #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (524288) #define BSP_RAM_SIZE_BYTES (262144) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_LQFP #define BSP_PACKAGE_PINS (100) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra6m1/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA6M1 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (16000000) #elif BSP_CFG_HOCO_FREQUENCY == 1 #define BSP_HOCO_HZ (18000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (20000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CFG_FLL_ENABLE (0) #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (112U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEF8 | (1 << 2) | (3) | (1 << 8)) #define BSP_CFG_ROM_REG_MPU_PC0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC0_START (0xFFFFFFFC) #define BSP_CFG_ROM_REG_MPU_PC0_END (0xFFFFFFFF) #define BSP_CFG_ROM_REG_MPU_PC1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC1_START (0xFFFFFFFC) #define BSP_CFG_ROM_REG_MPU_PC1_END (0xFFFFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION0_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_REGION0_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION1_START (0x200FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION1_END (0x200FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION2_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION2_START (0x407FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION2_END (0x407FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION3_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION3_START (0x400DFFFC) #define BSP_CFG_ROM_REG_MPU_REGION3_END (0x400DFFFF) #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* ID Code Note: To lock and disable the debug interface define BSP_ID_CODE_LOCKED in compiler settings. WARNING: This will disable debug access to the part. However, ALeRASE command will be accepted, which will clear (reset) the ID code. After clearing ID code, debug access will be enabled. */ #if defined(BSP_ID_CODE_LOCKED) #define BSP_CFG_ID_CODE_LONG_1 (0x00000000) #define BSP_CFG_ID_CODE_LONG_2 (0x00000000) #define BSP_CFG_ID_CODE_LONG_3 (0x00000000) #define BSP_CFG_ID_CODE_LONG_4 (0x00000000) #else /* ID CODE: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */ #define BSP_CFG_ID_CODE_LONG_1 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_2 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_3 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_4 (0xffFFFFFF) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define LED1 (BSP_IO_PORT_01_PIN_12) #define SW1 (BSP_IO_PORT_04_PIN_15) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA6M1-EK.pincfg */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (12000000) /* XTAL 12000000Hz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_HOCO_FREQUENCY (2) /* HOCO 20MHz */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_1) /* PLL Div /1 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(20U,0U) /* PLL Mul x20.0 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* ICLK Div /2 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKA Div /2 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKB Div /4 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKC Div /4 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKD Div /2 */ #define BSP_CFG_BCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* BCLK Div /2 */ #define BSP_CFG_BCLK_OUTPUT (2) /* EBCLK Div /2 */ #define BSP_CFG_UCK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_5) /* UCLK Div /5 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* FCLK Div /4 */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_01_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_01_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_01_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_02_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_02_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CTSU) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x1FFE0000; RAM_LENGTH = 0x40000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x80000; DATA_FLASH_START = 0x40100000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x00000000; OPTION_SETTING_LENGTH = 0x0; OPTION_SETTING_S_START = 0x80000000; OPTION_SETTING_S_LENGTH = 0x0; ID_CODE_START = 0x0100A150; ID_CODE_LENGTH = 0x10; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x4000000; OSPI_DEVICE_0_START = 0x80020000; OSPI_DEVICE_0_LENGTH = 0x0; OSPI_DEVICE_1_START = 0x80030000; OSPI_DEVICE_1_LENGTH = 0x0; ================================================ FILE: hw/bsp/ra/boards/ra6m1_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack RA6M1-EK Board Support Files Renesas.RA_board_ra6m1_ek.5.6.0.pack Board support package for R7FA6M1AD3CFP Renesas.RA_mcu_ra6m1.5.6.0.pack Board support package for RA6M1 Renesas.RA_mcu_ra6m1.5.6.0.pack Board support package for RA6M1 - FSP Data Renesas.RA_mcu_ra6m1.5.6.0.pack Board support package for RA6M1 - Events Renesas.RA_mcu_ra6m1.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra6m5) set(JLINK_DEVICE R7FA6M5BH) set(JLINK_OPTION "-USB 000831915224") # device default to PORT 1 High Speed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA6M5 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m5-evaluation-kit-ra6m5-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/board.mk ================================================ CPU_CORE = cortex-m33 MCU_VARIANT = ra6m5 # For flash-jlink target JLINK_DEVICE = R7FA6M5BH # Port 1 is highspeed RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ozone/ra6m5.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Project.AddSvdFile ("Cortex-M33.svd"); Project.AddSvdFile ("./R7FA6M5BH.svd"); Project.SetDevice ("R7FA6M5BH"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("50 MHz"); Project.SetTraceSource ("Trace Pins"); Project.SetTracePortWidth (4); File.Open ("../../../../../../examples/cmake-build-ra6m5_ek/device/cdc_msc/cdc_msc.elf"); } /********************************************************************* * * BeforeTargetConnect * ********************************************************************** */ void BeforeTargetConnect (void) { // Trace pin init is done by J-Link script file as J-Link script files are IDE independent Project.SetJLinkScript("../../../debug.jlinkscript"); } /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetReset (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr != 0xFFFFFFFF) { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); } else { Util.Log("Project file error: failed to get program base"); } PC = Elf.GetEntryPointPC(); if (PC != 0xFFFFFFFF) { Target.SetReg("PC", PC); } else if (VectorTableAddr != 0xFFFFFFFF) { PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetDownload (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr != 0xFFFFFFFF) { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); } else { Util.Log("Project file error: failed to get program base"); } PC = Elf.GetEntryPointPC(); if (PC != 0xFFFFFFFF) { Target.SetReg("PC", PC); } else if (VectorTableAddr != 0xFFFFFFFF) { PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x1000) #define BSP_CFG_HEAP_BYTES (0x1000) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (6) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA6M5BH3CFC #define BSP_MCU_FEATURE_SET ('B') #define BSP_ROM_SIZE_BYTES (2097152) #define BSP_RAM_SIZE_BYTES (524288) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_LQFP #define BSP_PACKAGE_PINS (176) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra6m5/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA6M5 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (16000000) #elif BSP_CFG_HOCO_FREQUENCY == 1 #define BSP_HOCO_HZ (18000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (20000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CFG_FLL_ENABLE (0) #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (112U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #if defined(_RA_TZ_SECURE) #define BSP_TZ_SECURE_BUILD (1) #define BSP_TZ_NONSECURE_BUILD (0) #elif defined(_RA_TZ_NONSECURE) #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (1) #else #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (0) #endif /* TrustZone Settings */ #define BSP_TZ_CFG_INIT_SECURE_ONLY (BSP_CFG_CLOCKS_SECURE || (!BSP_CFG_CLOCKS_OVERRIDE)) #define BSP_TZ_CFG_SKIP_INIT (BSP_TZ_NONSECURE_BUILD && BSP_TZ_CFG_INIT_SECURE_ONLY) #define BSP_TZ_CFG_EXCEPTION_RESPONSE (0) /* CMSIS TrustZone Settings */ #define SCB_CSR_AIRCR_INIT (1) #define SCB_AIRCR_BFHFNMINS_VAL (0) #define SCB_AIRCR_SYSRESETREQS_VAL (1) #define SCB_AIRCR_PRIS_VAL (0) #define TZ_FPU_NS_USAGE (1) #ifndef SCB_NSACR_CP10_11_VAL #define SCB_NSACR_CP10_11_VAL (3U) #endif #ifndef FPU_FPCCR_TS_VAL #define FPU_FPCCR_TS_VAL (1U) #endif #define FPU_FPCCR_CLRONRETS_VAL (1) #ifndef FPU_FPCCR_CLRONRET_VAL #define FPU_FPCCR_CLRONRET_VAL (1) #endif /* The C-Cache line size that is configured during startup. */ #ifndef BSP_CFG_C_CACHE_LINE_SIZE #define BSP_CFG_C_CACHE_LINE_SIZE (1U) #endif /* Type 1 Peripheral Security Attribution */ /* Peripheral Security Attribution Register (PSAR) Settings */ #ifndef BSP_TZ_CFG_PSARB #define BSP_TZ_CFG_PSARB (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CAN1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* CAN0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* IIC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9) /* IIC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* USBFS */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18) /* SPI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19) /* SPI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* SCI9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* SCI8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* SCI7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* SCI6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* SCI5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* SCI4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* SCI3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* SCI2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* SCI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCI0 */ | \ 0x33f4f9) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARC #define BSP_TZ_CFG_PSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* CAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CRC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* CTSU */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* SSIE0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* SDHI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* DOC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCE9 */ | \ 0x7fffcef4) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARD #define BSP_TZ_CFG_PSARD (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* AGT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* AGT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* AGT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* AGT0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* POEG3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* POEG2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* POEG1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* POEG0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* ADC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 16) /* ADC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20) /* DAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* TSN */ | \ 0xffae07f0) /* Unused */ #endif #ifndef BSP_TZ_CFG_PSARE #define BSP_TZ_CFG_PSARE (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* WDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* IWDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* RTC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* AGT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* AGT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* GPT9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* GPT8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* GPT7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* GPT6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* GPT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* GPT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* GPT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* GPT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* GPT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* GPT0 */ | \ 0x3f3ff8) /* Unused */ #endif #ifndef BSP_TZ_CFG_MSSAR #define BSP_TZ_CFG_MSSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* ELC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* DTC_DMAC */ | \ 0xfffffffc) /* Unused */ #endif /* Type 2 Peripheral Security Attribution */ /* Security attribution for Cache registers. */ #ifndef BSP_TZ_CFG_CSAR #define BSP_TZ_CFG_CSAR (0xFFFFFFFFU) #endif /* Security attribution for RSTSRn registers. */ #ifndef BSP_TZ_CFG_RSTSAR #define BSP_TZ_CFG_RSTSAR (0xFFFFFFFFU) #endif /* Security attribution for registers of LVD channels. */ #ifndef BSP_TZ_CFG_LVDSAR #define BSP_TZ_CFG_LVDSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) | /* LVD Channel 1 */ \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) | /* LVD Channel 2 */ \ 0xFFFFFFFCU) #endif /* Security attribution for LPM registers. */ #ifndef BSP_TZ_CFG_LPMSAR #define BSP_TZ_CFG_LPMSAR ((RA_NOT_DEFINED > 0) ? 0xFFFFFCEAU : 0xFFFFFFFFU) #endif /* Deep Standby Interrupt Factor Security Attribution Register. */ #ifndef BSP_TZ_CFG_DPFSAR #define BSP_TZ_CFG_DPFSAR ((RA_NOT_DEFINED > 0) ? 0xF2E00000U : 0xFFFFFFFFU) #endif /* Security attribution for CGC registers. */ #ifndef BSP_TZ_CFG_CGFSAR #if BSP_CFG_CLOCKS_SECURE /* Protect all CGC registers from Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFCE402U) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0xFFFFFFFFU) #endif #endif /* Security attribution for Battery Backup registers. */ #ifndef BSP_TZ_CFG_BBFSAR #define BSP_TZ_CFG_BBFSAR (0x00FFFFFF) #endif /* Security attribution for registers for IRQ channels. */ #ifndef BSP_TZ_CFG_ICUSARA #define BSP_TZ_CFG_ICUSARA (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* External IRQ0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* External IRQ1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* External IRQ2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* External IRQ3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* External IRQ4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* External IRQ5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* External IRQ6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* External IRQ7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8U) /* External IRQ8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9U) /* External IRQ9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 10U) /* External IRQ10 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11U) /* External IRQ11 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12U) /* External IRQ12 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13U) /* External IRQ13 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14U) /* External IRQ14 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15U) /* External IRQ15 */ | \ 0xFFFF0000U) #endif /* Security attribution for NMI registers. */ #ifndef BSP_TZ_CFG_ICUSARB #define BSP_TZ_CFG_ICUSARB (0 | 0xFFFFFFFEU) /* Should match AIRCR.BFHFNMINS. */ #endif /* Security attribution for registers for DMAC channels */ #ifndef BSP_TZ_CFG_ICUSARC #define BSP_TZ_CFG_ICUSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* DMAC Channel 0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* DMAC Channel 1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* DMAC Channel 2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* DMAC Channel 3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* DMAC Channel 4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* DMAC Channel 5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* DMAC Channel 6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* DMAC Channel 7 */ | \ 0xFFFFFF00U) #endif /* Security attribution registers for SELSR0. */ #ifndef BSP_TZ_CFG_ICUSARD #define BSP_TZ_CFG_ICUSARD ((RA_NOT_DEFINED > 0) ? 0xFFFFFFFEU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN0. */ #ifndef BSP_TZ_CFG_ICUSARE #define BSP_TZ_CFG_ICUSARE ((RA_NOT_DEFINED > 0) ? 0x04F2FFFFU : 0xFFFFFFFFU) #endif /* Security attribution registers for WUPEN1. */ #ifndef BSP_TZ_CFG_ICUSARF #define BSP_TZ_CFG_ICUSARF ((RA_NOT_DEFINED > 0) ? 0xFFFFFFF8U : 0xFFFFFFFFU) #endif /* Set DTCSTSAR if the Secure program uses the DTC. */ #if RA_NOT_DEFINED == RA_NOT_DEFINED #define BSP_TZ_CFG_DTC_USED (0U) #else #define BSP_TZ_CFG_DTC_USED (1U) #endif /* Security attribution of FLWT and FCKMHZ registers. */ #ifndef BSP_TZ_CFG_FSAR /* If the CGC registers are only accessible in Secure mode, than there is no * reason for nonsecure applications to access FLWT and FCKMHZ. */ #if BSP_CFG_CLOCKS_SECURE /* Protect FLWT and FCKMHZ registers from nonsecure write access. */ #define BSP_TZ_CFG_FSAR (0xFEFEU) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_FSAR (0xFFFFU) #endif #endif /* Security attribution for SRAM registers. */ #ifndef BSP_TZ_CFG_SRAMSAR /* If the CGC registers are only accessible in Secure mode, than there is no reason for Non Secure applications to access * SRAM0WTEN and therefore there is no reason to access PRCR2. */ #define BSP_TZ_CFG_SRAMSAR (\ 1 | \ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 1U) : 0U) | \ 4 | \ 0xFFFFFFF8U) #endif /* Security attribution for Standby RAM registers. */ #ifndef BSP_TZ_CFG_STBRAMSAR #define BSP_TZ_CFG_STBRAMSAR (0 | 0xFFFFFFF0U) #endif /* Security attribution for the DMAC Bus Master MPU settings. */ #ifndef BSP_TZ_CFG_MMPUSARA /* The DMAC Bus Master MPU settings should align with the DMAC channel settings. */ #define BSP_TZ_CFG_MMPUSARA (BSP_TZ_CFG_ICUSARC) #endif /* Security Attribution Register A for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARA #define BSP_TZ_CFG_BUSSARA (0xFFFFFFFFU) #endif /* Security Attribution Register B for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARB #define BSP_TZ_CFG_BUSSARB (0xFFFFFFFFU) #endif /* Enable Uninitialized Non-Secure Application Fallback. */ #ifndef BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK #define BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK (1U) #endif #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) /* Option Function Select Register 1 Security Attribution */ #ifndef BSP_CFG_ROM_REG_OFS1_SEL #if defined(_RA_TZ_SECURE) || defined(_RA_TZ_NONSECURE) #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U | ((0U << 0U)) | ((0U << 2U)) | ((BSP_CFG_CLOCKS_SECURE == 0) ? 0x700U : 0U)) #else #define BSP_CFG_ROM_REG_OFS1_SEL (0xFFFFF8F8U) #endif #endif #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEF8 | (1 << 2) | (3) | (1 << 8)) /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* Dual Mode Select Register */ #ifndef BSP_CFG_ROM_REG_DUALSEL #define BSP_CFG_ROM_REG_DUALSEL (0xFFFFFFF8U | (0x7U)) #endif /* Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_BPS0 #define BSP_CFG_ROM_REG_BPS0 (~( 0U)) #endif /* Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_BPS1 #define BSP_CFG_ROM_REG_BPS1 (~( 0U)) #endif /* Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_BPS2 #define BSP_CFG_ROM_REG_BPS2 (~( 0U)) #endif /* Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_BPS3 #define BSP_CFG_ROM_REG_BPS3 (0xFFFFFFFFU) #endif /* Permanent Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_PBPS0 #define BSP_CFG_ROM_REG_PBPS0 (~( 0U)) #endif /* Permanent Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_PBPS1 #define BSP_CFG_ROM_REG_PBPS1 (~( 0U)) #endif /* Permanent Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_PBPS2 #define BSP_CFG_ROM_REG_PBPS2 (~( 0U)) #endif /* Permanent Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_PBPS3 #define BSP_CFG_ROM_REG_PBPS3 (0xFFFFFFFFU) #endif /* Security Attribution for Block Protection Register 0 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL0 #define BSP_CFG_ROM_REG_BPS_SEL0 (BSP_CFG_ROM_REG_BPS0 & BSP_CFG_ROM_REG_PBPS0) #endif /* Security Attribution for Block Protection Register 1 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL1 #define BSP_CFG_ROM_REG_BPS_SEL1 (BSP_CFG_ROM_REG_BPS1 & BSP_CFG_ROM_REG_PBPS1) #endif /* Security Attribution for Block Protection Register 2 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL2 #define BSP_CFG_ROM_REG_BPS_SEL2 (BSP_CFG_ROM_REG_BPS2 & BSP_CFG_ROM_REG_PBPS2) #endif /* Security Attribution for Block Protection Register 3 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL3 #define BSP_CFG_ROM_REG_BPS_SEL3 (BSP_CFG_ROM_REG_BPS3 & BSP_CFG_ROM_REG_PBPS3) #endif /* Security Attribution for Bank Select Register */ #ifndef BSP_CFG_ROM_REG_BANKSEL_SEL #define BSP_CFG_ROM_REG_BANKSEL_SEL (0xFFFFFFFFU) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define MIKROBUS_AN_ARDUINO_A0 (BSP_IO_PORT_00_PIN_00) #define ARDUINO_A1 (BSP_IO_PORT_00_PIN_01) #define ARDUINO_A2 (BSP_IO_PORT_00_PIN_02) #define ARDUINO_A3 (BSP_IO_PORT_00_PIN_03) #define SW2 (BSP_IO_PORT_00_PIN_04) #define SW1 (BSP_IO_PORT_00_PIN_05) #define LED1 (BSP_IO_PORT_00_PIN_06) #define LED2 (BSP_IO_PORT_00_PIN_07) #define LED3 (BSP_IO_PORT_00_PIN_08) #define ARDUINO_A4 (BSP_IO_PORT_00_PIN_14) #define ARDUINO_A5 (BSP_IO_PORT_00_PIN_15) #define OSPI_CLK (BSP_IO_PORT_01_PIN_00) #define OSPI_SIO7 (BSP_IO_PORT_01_PIN_01) #define OSPI_SIO1 (BSP_IO_PORT_01_PIN_02) #define OSPI_SIO6 (BSP_IO_PORT_01_PIN_03) #define OSPI_DQS (BSP_IO_PORT_01_PIN_04) #define OSPI_SIO5 (BSP_IO_PORT_01_PIN_05) #define OSPI_SIO0 (BSP_IO_PORT_01_PIN_06) #define OSPI_SIO3 (BSP_IO_PORT_01_PIN_07) #define MIKROBUS_PWM_ARDUINO_D3_PWM (BSP_IO_PORT_01_PIN_11) #define ARDUINO_D4 (BSP_IO_PORT_01_PIN_12) #define ARDUINO_D5 (BSP_IO_PORT_01_PIN_13) #define ARDUINO_D6 (BSP_IO_PORT_01_PIN_14) #define ARDUINO_D9 (BSP_IO_PORT_01_PIN_15) #define MIKROBUS_MISO_ARDUINO_MISO_PMOD1_MISO (BSP_IO_PORT_02_PIN_02) #define MIKROBUS_MOSI_ARDUINO_MOSI_PMOD1_MOSI (BSP_IO_PORT_02_PIN_03) #define MIKROBUS_SCK_ARDUINO_SCK_PMOD1_SCK (BSP_IO_PORT_02_PIN_04) #define MIKROBUS_SS_ARDUINO_SS (BSP_IO_PORT_02_PIN_05) #define PMOD1_SS (BSP_IO_PORT_02_PIN_06) #define ARDUINO_D8 (BSP_IO_PORT_02_PIN_07) #define PMOD1_SS2 (BSP_IO_PORT_03_PIN_01) #define PMOD1_SS3 (BSP_IO_PORT_03_PIN_02) #define MIKROBUS_RESET_ARDUINO_RESET (BSP_IO_PORT_03_PIN_03) #define QSPI_CLK (BSP_IO_PORT_03_PIN_05) #define QSPI_CS (BSP_IO_PORT_03_PIN_06) #define QSPI_IO0 (BSP_IO_PORT_03_PIN_07) #define QSPI_IO1 (BSP_IO_PORT_03_PIN_08) #define QSPI_IO2 (BSP_IO_PORT_03_PIN_09) #define QSPI_IO3 (BSP_IO_PORT_03_PIN_10) #define PMOD1_RST (BSP_IO_PORT_03_PIN_11) #define PMOD2_INT (BSP_IO_PORT_04_PIN_00) #define ETH_MDC (BSP_IO_PORT_04_PIN_01) #define ETH_MDIO (BSP_IO_PORT_04_PIN_02) #define ETH_RST (BSP_IO_PORT_04_PIN_03) #define PMOD2_RST (BSP_IO_PORT_04_PIN_04) #define ETH_TXEN (BSP_IO_PORT_04_PIN_05) #define ETH_TXD1 (BSP_IO_PORT_04_PIN_06) #define USBFS_VBUS (BSP_IO_PORT_04_PIN_07) #define PMOD2_SS2 (BSP_IO_PORT_04_PIN_08) #define MIKROBUS_INT_ARDUINO_INT0 (BSP_IO_PORT_04_PIN_09) #define PMOD2_MISO (BSP_IO_PORT_04_PIN_10) #define PMOD2_MOSI (BSP_IO_PORT_04_PIN_11) #define PMOD2_SCK (BSP_IO_PORT_04_PIN_12) #define PMOS2_SS (BSP_IO_PORT_04_PIN_13) #define GROVE1_SDA_QWIIC_SDA (BSP_IO_PORT_04_PIN_14) #define GROVE1_SCL_QWIIC_SCL (BSP_IO_PORT_04_PIN_15) #define USBFS_VBUS_EN (BSP_IO_PORT_05_PIN_00) #define USBFS_OVERCURA (BSP_IO_PORT_05_PIN_01) #define GROVE2_SCL (BSP_IO_PORT_05_PIN_05) #define GROVE2_SDA (BSP_IO_PORT_05_PIN_06) #define MIKROBUS_SDA_ARDUINO_SDA (BSP_IO_PORT_05_PIN_11) #define MIKROBUS_SCL_ARDUINO_SCL (BSP_IO_PORT_05_PIN_12) #define OSPI_SIO4 (BSP_IO_PORT_06_PIN_00) #define OSPI_SIO2 (BSP_IO_PORT_06_PIN_01) #define OSPI_CS1 (BSP_IO_PORT_06_PIN_02) #define ARDUINO_D7 (BSP_IO_PORT_06_PIN_08) #define CAN_TXD (BSP_IO_PORT_06_PIN_09) #define CAN_RDX (BSP_IO_PORT_06_PIN_10) #define CAN_STBY (BSP_IO_PORT_06_PIN_11) #define MIKROBUS_TX_ARDUINO_TX (BSP_IO_PORT_06_PIN_13) #define MIKROBUS_RX_ARDUINO_RX (BSP_IO_PORT_06_PIN_14) #define OSPI_RST (BSP_IO_PORT_06_PIN_15) #define ETH_TXD0 (BSP_IO_PORT_07_PIN_00) #define ETH_50REF (BSP_IO_PORT_07_PIN_01) #define ETH_RXD0 (BSP_IO_PORT_07_PIN_02) #define ETH_RXD1 (BSP_IO_PORT_07_PIN_03) #define ETH_RXERR (BSP_IO_PORT_07_PIN_04) #define ETH_CRSDV (BSP_IO_PORT_07_PIN_05) #define ETH_INT (BSP_IO_PORT_07_PIN_06) #define USBHS_OVERCURA (BSP_IO_PORT_07_PIN_07) #define PMOD2_SS3 (BSP_IO_PORT_07_PIN_08) #define PMOD1_INT (BSP_IO_PORT_09_PIN_05) #define USBHS_VBUS_EN (BSP_IO_PORT_11_PIN_00) #define USBHS_VBUS (BSP_IO_PORT_11_PIN_01) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA6M5 EK */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (24000000) /* XTAL 24000000Hz */ #define BSP_CFG_HOCO_FREQUENCY (2) /* HOCO 20MHz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_3) /* PLL Div /3 */ #define BSP_CFG_PLL_MUL (BSP_CLOCKS_PLL_MUL(25U,0U)) /* PLL Mul x25.0 */ #define BSP_CFG_PLL2_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL2 Src: XTAL */ #define BSP_CFG_PLL2_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL2 Div /2 */ #define BSP_CFG_PLL2_MUL (BSP_CLOCKS_PLL_MUL(20U,0U)) /* PLL2 Mul x20.0 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL2) /* UCLK Src: PLL2 */ #define BSP_CFG_U60CK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL2) /* U60CK Src: PLL2 */ #define BSP_CFG_OCTA_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* OCTASPICLK Disabled */ #define BSP_CFG_CANFDCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CANFDCLK Disabled */ #define BSP_CFG_CECCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CECCLK Disabled */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKA Div /2 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKB Div /4 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKC Div /4 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKD Div /2 */ #define BSP_CFG_BCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* BCLK Div /2 */ #define BSP_CFG_BCLK_OUTPUT (2) /* EBCLK Div /2 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* FCLK Div /4 */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_UCK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_5) /* UCLK Div /5 */ #define BSP_CFG_U60CK_DIV (BSP_CLOCKS_USB60_CLOCK_DIV_4) /* U60CK Div /4 */ #define BSP_CFG_OCTA_DIV (BSP_CLOCKS_OCTA_CLOCK_DIV_1) /* OCTASPICLK Div /1 */ #define BSP_CFG_CANFDCLK_DIV (BSP_CLOCKS_CANFD_CLOCK_DIV_1) /* CANFDCLK Div /1 */ #define BSP_CFG_CECCLK_DIV (BSP_CLOCKS_CEC_CLOCK_DIV_1) /* CECCLK Div /1 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_00_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_00_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_00_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_GPT1) }, { .pin = BSP_IO_PORT_01_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_13, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_01_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_02_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_02_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_02_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_02_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_02_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_03_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_03_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_03_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_03_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_QSPI) }, { .pin = BSP_IO_PORT_03_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_04_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_04_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_04_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_HIGH) }, { .pin = BSP_IO_PORT_04_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_04_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_04_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_04_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_13, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_04_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_05_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_NMOS_ENABLE | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_05_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_NMOS_ENABLE | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_05_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_05_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_06_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_06_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_06_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_06_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_06_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CAN) }, { .pin = BSP_IO_PORT_06_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_CAN) }, { .pin = BSP_IO_PORT_06_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_06_PIN_13, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_06_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_06_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_HIGH) }, { .pin = BSP_IO_PORT_07_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_ETHER_RMII) }, { .pin = BSP_IO_PORT_07_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_07_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, { .pin = BSP_IO_PORT_07_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_09_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_11_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, { .pin = BSP_IO_PORT_11_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x80000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x200000; DATA_FLASH_START = 0x08000000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x0100A100; OPTION_SETTING_LENGTH = 0x100; OPTION_SETTING_S_START = 0x0100A200; OPTION_SETTING_S_LENGTH = 0x100; ID_CODE_START = 0x00000000; ID_CODE_LENGTH = 0x0; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x4000000; OSPI_DEVICE_0_START = 0x68000000; OSPI_DEVICE_0_LENGTH = 0x8000000; OSPI_DEVICE_1_START = 0x70000000; OSPI_DEVICE_1_LENGTH = 0x10000000; ================================================ FILE: hw/bsp/ra/boards/ra6m5_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack RA6M5-EK Board Support Files Renesas.RA_board_ra6m5_ek.5.6.0.pack Board support package for R7FA6M5BH3CFC Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 - FSP Data Renesas.RA_mcu_ra6m5.5.6.0.pack Board support package for RA6M5 - Events Renesas.RA_mcu_ra6m5.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m85 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra8m1) set(JLINK_DEVICE R7FA8M1AH) #set(JLINK_OPTION "-USB 001083115236") # device default to PORT 1 High Speed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) endfunction() ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RA8M1 EK url: https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra8m1-evaluation-kit-ra8m1-mcu-group */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/board.mk ================================================ CPU_CORE = cortex-m85 MCU_VARIANT = ra8m1 # For flash-jlink target JLINK_DEVICE = R7FA8M1AH # Port 1 is highspeed RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Project.SetTraceSource ("Trace Pins"); Project.SetDevice ("R7FA8M1AH"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("50 MHz"); Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M85F.svd"); Project.AddSvdFile ("../../../../../../../cmsis-svd-data/data/Renesas/R7FA6M5BH.svd"); File.Open ("../../../../../../examples/cmake-build-ra8m1_ek/device/cdc_msc/cdc_msc.elf"); } /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { // Trace pin init is done by J-Link script file as J-Link script files are IDE independent //Project.SetJLinkScript("../../../debug.jlinkscript"); Project.SetJLinkScript ("$(ProjectDir)/Renesas_RA8_TracePins.pex"); } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. Optional. * The default implementation initializes SP and PC to reset values. * ********************************************************************** */ void AfterTargetDownload (void) { _SetupTarget(); } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} /********************************************************************* * * BeforeTargetResume * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetResume (void) { //} /********************************************************************* * * OnSnapshotLoad * * Function description * Called upon loading a snapshot. Optional. * * Additional information * This function is used to restore the target state in cases * where values cannot simply be written to the target. * Typical use: GPIO clock needs to be enabled, before * GPIO is configured. * ********************************************************************** */ //void OnSnapshotLoad (void) { //} /********************************************************************* * * OnSnapshotSave * * Function description * Called upon saving a snapshot. Optional. * * Additional information * This function is usually used to save values of the target * state which can either not be trivially read, * or need to be restored in a specific way or order. * Typically use: Memory Mapped Registers, * such as PLL and GPIO configuration. * ********************************************************************** */ //void OnSnapshotSave (void) { //} /********************************************************************* * * OnError * * Function description * Called when an error occurred. Optional. * ********************************************************************** */ //void OnError (void) { //} /********************************************************************* * * AfterProjectLoad * * Function description * After Project load routine. Optional. * ********************************************************************** */ //void AfterProjectLoad (void) { //} /********************************************************************* * * _SetupTarget * * Function description * Setup the target. * Called by AfterTargetReset() and AfterTargetDownload(). * * Auto-generated function. May be overridden by Ozone. * ********************************************************************** */ void _SetupTarget(void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); // // Set up initial stack pointer // SP = Target.ReadU32(VectorTableAddr); if (SP != 0xFFFFFFFF) { Target.SetReg("SP", SP); } // // Set up entry point PC // PC = Elf.GetEntryPointPC(); if (PC != 0xFFFFFFFF) { Target.SetReg("PC", PC); } else { Util.Error("Project script error: failed to set up entry point PC", 1); } } ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x1000) #define BSP_CFG_HEAP_BYTES (0x1000) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (8) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA8M1AHECBD #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (2064384) #define BSP_RAM_SIZE_BYTES (917504) #define BSP_DATA_FLASH_SIZE_BYTES (12288) #define BSP_PACKAGE_BGA #define BSP_PACKAGE_PINS (224) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra8m1/bsp_override.h" #include "../../../ra/fsp/src/bsp/mcu/ra8m1/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA8M1 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (0) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (16000000) #elif BSP_CFG_HOCO_FREQUENCY == 1 #define BSP_HOCO_HZ (18000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (20000000) #elif BSP_CFG_HOCO_FREQUENCY == 4 #define BSP_HOCO_HZ (32000000) #elif BSP_CFG_HOCO_FREQUENCY == 7 #define BSP_HOCO_HZ (48000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CFG_FLL_ENABLE (0) #define BSP_CFG_CLOCK_SETTLING_DELAY_ENABLE (1) #define BSP_CFG_SLEEP_MODE_DELAY_ENABLE (1) #define BSP_CFG_MSTP_CHANGE_DELAY_ENABLE (1) #define BSP_CFG_RTOS_IDLE_SLEEP (0) #define BSP_CFG_CLOCK_SETTLING_DELAY_US (150) #if defined(BSP_PACKAGE_LQFP) && (BSP_PACKAGE_PINS == 100) #define BSP_MAX_CLOCK_CHANGE_THRESHOLD (180000000U) #elif defined(BSP_PACKAGE_LQFP) #define BSP_MAX_CLOCK_CHANGE_THRESHOLD (200000000U) #else #define BSP_MAX_CLOCK_CHANGE_THRESHOLD (240000000U) #endif #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (112U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #if defined(_RA_TZ_SECURE) #define BSP_TZ_SECURE_BUILD (1) #define BSP_TZ_NONSECURE_BUILD (0) #elif defined(_RA_TZ_NONSECURE) #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (1) #else #define BSP_TZ_SECURE_BUILD (0) #define BSP_TZ_NONSECURE_BUILD (0) #endif /* TrustZone Settings */ #define BSP_TZ_CFG_INIT_SECURE_ONLY (BSP_CFG_CLOCKS_SECURE || (!BSP_CFG_CLOCKS_OVERRIDE)) #define BSP_TZ_CFG_SKIP_INIT (BSP_TZ_NONSECURE_BUILD && BSP_TZ_CFG_INIT_SECURE_ONLY) #define BSP_TZ_CFG_EXCEPTION_RESPONSE (0) /* CMSIS TrustZone Settings */ #define SCB_CSR_AIRCR_INIT (1) #define SCB_AIRCR_BFHFNMINS_VAL (0) #define SCB_AIRCR_SYSRESETREQS_VAL (1) #define SCB_AIRCR_PRIS_VAL (0) #define TZ_FPU_NS_USAGE (1) #ifndef SCB_NSACR_CP10_11_VAL #define SCB_NSACR_CP10_11_VAL (3U) #endif #ifndef FPU_FPCCR_TS_VAL #define FPU_FPCCR_TS_VAL (1U) #endif #define FPU_FPCCR_CLRONRETS_VAL (1) #ifndef FPU_FPCCR_CLRONRET_VAL #define FPU_FPCCR_CLRONRET_VAL (1) #endif /* Type 1 Peripheral Security Attribution */ /* Peripheral Security Attribution Register (PSAR) Settings */ #ifndef BSP_TZ_CFG_PSARB #define BSP_TZ_CFG_PSARB (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4) /* I3C */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* IIC1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9) /* IIC0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* USBFS */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* USBHS */ | \ (1 << 15) /* ETHERC/EDMAC */ | \ (1 << 16) /* OSPI */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18) /* SPI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19) /* SPI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* SCI9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* SCI4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* SCI3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* SCI2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* SCI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* SCI0 */) #endif #ifndef BSP_TZ_CFG_PSARC #define BSP_TZ_CFG_PSARC (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0) /* CAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* CRC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7) /* SSIE1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* SSIE0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* SDHI1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* SDHI0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* DOC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 16) /* CEU */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* CANFD1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* CANFD0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* RSIP-E51A */) #endif #ifndef BSP_TZ_CFG_PSARD #define BSP_TZ_CFG_PSARD (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4) /* AGT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5) /* AGT0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11) /* POEG3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12) /* POEG2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13) /* POEG1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14) /* POEG0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15) /* ADC121 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 16) /* ADC120 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20) /* DAC120 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* TSN */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* ACMPHS1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* ACMPHS0 */) #endif #ifndef BSP_TZ_CFG_PSARE #define BSP_TZ_CFG_PSARE (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1) /* WDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2) /* IWDT */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3) /* RTC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8) /* ULPT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9) /* ULPT0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18) /* GPT13 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19) /* GPT12 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20) /* GPT11 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 21) /* GPT10 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* GPT9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23) /* GPT8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 24) /* GPT7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 25) /* GPT6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 26) /* GPT5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 27) /* GPT4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 28) /* GPT3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 29) /* GPT2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 30) /* GPT1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* GPT0 */) #endif #ifndef BSP_TZ_CFG_MSSAR #define BSP_TZ_CFG_MSSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22) /* DTC_DMAC */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 31) /* ELC */) #endif /* Type 2 Peripheral Security Attribution */ /* Security attribution for RSTSRn registers. */ #ifndef BSP_TZ_CFG_RSTSAR #define BSP_TZ_CFG_RSTSAR (0x00000007U) #endif /* Security attribution for registers of LVD channels. */ #ifndef BSP_TZ_CFG_LVDSAR /* The LVD driver needs to access both channels. This means that the security attribution for both channels must be the same. */ #if (RA_NOT_DEFINED > 0) || (RA_NOT_DEFINED > 0) #define BSP_TZ_CFG_LVDSAR (0U) #else #define BSP_TZ_CFG_LVDSAR (3U) #endif #endif /* Security attribution for LPM registers. * - OPCCR based on clock security. * - Set remaining registers based on LPM security. */ #ifndef BSP_TZ_CFG_LPMSAR #define BSP_TZ_CFG_LPMSAR ((RA_NOT_DEFINED > 0) ? BSP_CFG_CLOCKS_SECURE == 0 : (\ 0x002E0106U | \ (BSP_CFG_CLOCKS_SECURE == 0))) #endif /* Deep Standby Interrupt Factor Security Attribution Register. */ #ifndef BSP_TZ_CFG_DPFSAR #define BSP_TZ_CFG_DPFSAR ((RA_NOT_DEFINED > 0) ? 0U : 0xAF1FFFFFU) #endif /* RAM Standby Control Security Attribution Register. */ #ifndef BSP_TZ_CFG_RSCSAR #define BSP_TZ_CFG_RSCSAR ((RA_NOT_DEFINED > 0) ? 0U : 0x00037FFFU) #endif /* Security attribution for CGC registers. */ #ifndef BSP_TZ_CFG_CGFSAR #if BSP_CFG_CLOCKS_SECURE /* Protect all CGC registers from Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0U) #else /* Allow Secure and Non-secure write access. */ #define BSP_TZ_CFG_CGFSAR (0x047F3BFDU) #endif #endif /* Security attribution for Battery Backup registers. */ #ifndef BSP_TZ_CFG_BBFSAR #if 0 #define BSP_TZ_CFG_BBFSAR (0U) #else #define BSP_TZ_CFG_BBFSAR (0x1FU) #endif #endif /* Security attribution for Battery Backup registers (VBTBKRn). */ #ifndef BSP_TZ_CFG_VBRSABAR #if 0 #define BSP_TZ_CFG_VBRSABAR (0xFFE0) #else #define BSP_TZ_CFG_VBRSABAR (0xED00) #endif #endif /* Security attribution for registers for IRQ channels. */ #ifndef BSP_TZ_CFG_ICUSARA #define BSP_TZ_CFG_ICUSARA (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* External IRQ0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* External IRQ1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* External IRQ2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* External IRQ3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* External IRQ4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* External IRQ5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* External IRQ6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* External IRQ7 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 8U) /* External IRQ8 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 9U) /* External IRQ9 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 10U) /* External IRQ10 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 11U) /* External IRQ11 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 12U) /* External IRQ12 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 13U) /* External IRQ13 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 14U) /* External IRQ14 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 15U) /* External IRQ15 */) #endif /* Security attribution for NMI registers. */ #ifndef BSP_TZ_CFG_ICUSARB #define BSP_TZ_CFG_ICUSARB (0 | 0U) /* Should match AIRCR.BFHFNMINS. */ #endif /* Security attribution for registers for DMAC channels */ #ifndef BSP_TZ_CFG_DMACCHSAR #define BSP_TZ_CFG_DMACCHSAR (\ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 0U) /* DMAC Channel 0 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 1U) /* DMAC Channel 1 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 2U) /* DMAC Channel 2 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 3U) /* DMAC Channel 3 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 4U) /* DMAC Channel 4 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 5U) /* DMAC Channel 5 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 6U) /* DMAC Channel 6 */ | \ (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 7U) /* DMAC Channel 7 */) #endif /* Security attribution registers for WUPEN0. */ #ifndef BSP_TZ_CFG_ICUSARE #define BSP_TZ_CFG_ICUSARE ((RA_NOT_DEFINED > 0) ? 0U : 0xFF1D0000U) #endif /* Security attribution registers for WUPEN1. */ #ifndef BSP_TZ_CFG_ICUSARF #define BSP_TZ_CFG_ICUSARF ((RA_NOT_DEFINED > 0) ? 0U : 0x00007F08U) #endif /* Trusted Event Route Control Register for IELSR, DMAC.DELSR and ELC.ELSR. Note that currently Trusted Event Route Control is not supported. */ #ifndef BSP_TZ_CFG_TEVTRCR #define BSP_TZ_CFG_TEVTRCR (0) #endif /* Security attribution register for ELCR, ELSEGR0, ELSEGR1 Security Attribution. */ #ifndef BSP_TZ_CFG_ELCSARA #define BSP_TZ_CFG_ELCSARA (0x00000007U) #endif /* Set DTCSTSAR if the Secure program uses the DTC. */ #if RA_NOT_DEFINED == RA_NOT_DEFINED #define BSP_TZ_CFG_DTC_USED (0U) #else #define BSP_TZ_CFG_DTC_USED (1U) #endif /* Security attribution of FLWT and FCKMHZ registers. */ #ifndef BSP_TZ_CFG_FSAR /* If the CGC registers are only accessible in Secure mode, than there is no * reason for nonsecure applications to access FLWT and FCKMHZ. */ #define BSP_TZ_CFG_FSAR (\ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 0) : 0U) | /* FLWTSA */\ ((RA_NOT_DEFINED) > 0 ? 0U: (1U << 1)) | /* FCACHESA */\ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 8) : 0U) | /* FCKMHZSA */ \ ((RA_NOT_DEFINED) > 0 ? 0U : (1U << 9U)) | /* FACICMISA */\ ((RA_NOT_DEFINED) > 0 ? 0U: (1U << 10U)) /* FACICMRSA */) #endif /* Security attribution for SRAM registers. */ #ifndef BSP_TZ_CFG_SRAMSAR /* If the CGC registers are only accessible in Secure mode, than there is no reason for Non Secure applications to access * SRAM0WTEN and therefore there is no reason to access PRCR2. */ #define BSP_TZ_CFG_SRAMSAR (\ ((1U) << 0U) | /* SRAMSA0 */\ ((1U) << 1U) | /* SRAMSA1 */\ ((1U) << 7U) | /* STBRAMSA */\ ((BSP_CFG_CLOCKS_SECURE == 0) ? (1U << 8U) : 0U) /* SRAMWTSA */) #endif /* Security attribution for the DMAC Bus Master MPU settings. */ #ifndef BSP_TZ_CFG_MMPUSARA /* The DMAC Bus Master MPU settings should align with the DMAC channel settings. */ #define BSP_TZ_CFG_MMPUSARA (BSP_TZ_CFG_DMACCHSAR) #endif /* Security Attribution Register A for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARA #define BSP_TZ_CFG_BUSSARA (1U) #endif /* Security Attribution Register B for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARB #define BSP_TZ_CFG_BUSSARB (1U) #endif /* Security Attribution Register C for BUS Control registers. */ #ifndef BSP_TZ_CFG_BUSSARC #define BSP_TZ_CFG_BUSSARC (1U) #endif /* Enable Uninitialized Non-Secure Application Fallback. */ #ifndef BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK #define BSP_TZ_CFG_NON_SECURE_APPLICATION_FALLBACK (1U) #endif #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) #define BSP_CFG_ROM_REG_OFS2 ((1 << 0) | 0xFFFFFFFEU) /* Option Function Select Register 1 Security Attribution */ #ifndef BSP_CFG_ROM_REG_OFS1_SEL #if defined(_RA_TZ_SECURE) || defined(_RA_TZ_NONSECURE) #define BSP_CFG_ROM_REG_OFS1_SEL (0x00000000U | ((0U << 0U)) | ((0U << 3U)) | ((0U << 5U)) | ((BSP_CFG_CLOCKS_SECURE == 0) ? 0xF00U : 0U) | ((0U << 24U)) | ((0U << 25U))) #else #define BSP_CFG_ROM_REG_OFS1_SEL (0x00000000U) #endif #endif #define BSP_CFG_ROM_REG_OFS1_INITECCEN (0 << 25) #define BSP_CFG_ROM_REG_OFS1 (0xFCFFFED0 | (1 << 3) | (7) | (1 << 5) | (1 << 8) | (1 << 24) | (BSP_CFG_ROM_REG_OFS1_INITECCEN)) /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* Dual Mode Select Register */ #ifndef BSP_CFG_ROM_REG_DUALSEL #define BSP_CFG_ROM_REG_DUALSEL (0xFFFFFFF8U | (0x7U)) #endif /* Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_BPS0 #define BSP_CFG_ROM_REG_BPS0 (~( 0U)) #endif /* Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_BPS1 #define BSP_CFG_ROM_REG_BPS1 (~( 0U)) #endif /* Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_BPS2 #define BSP_CFG_ROM_REG_BPS2 (~( 0U)) #endif /* Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_BPS3 #define BSP_CFG_ROM_REG_BPS3 (~( 0U)) #endif /* Permanent Block Protection Register 0 */ #ifndef BSP_CFG_ROM_REG_PBPS0 #define BSP_CFG_ROM_REG_PBPS0 (~( 0U)) #endif /* Permanent Block Protection Register 1 */ #ifndef BSP_CFG_ROM_REG_PBPS1 #define BSP_CFG_ROM_REG_PBPS1 (~( 0U)) #endif /* Permanent Block Protection Register 2 */ #ifndef BSP_CFG_ROM_REG_PBPS2 #define BSP_CFG_ROM_REG_PBPS2 (~( 0U)) #endif /* Permanent Block Protection Register 3 */ #ifndef BSP_CFG_ROM_REG_PBPS3 #define BSP_CFG_ROM_REG_PBPS3 (~( 0U)) #endif /* Security Attribution for Block Protection Register 0 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL0 #define BSP_CFG_ROM_REG_BPS_SEL0 (BSP_CFG_ROM_REG_BPS0 & BSP_CFG_ROM_REG_PBPS0) #endif /* Security Attribution for Block Protection Register 1 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL1 #define BSP_CFG_ROM_REG_BPS_SEL1 (BSP_CFG_ROM_REG_BPS1 & BSP_CFG_ROM_REG_PBPS1) #endif /* Security Attribution for Block Protection Register 2 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL2 #define BSP_CFG_ROM_REG_BPS_SEL2 (BSP_CFG_ROM_REG_BPS2 & BSP_CFG_ROM_REG_PBPS2) #endif /* Security Attribution for Block Protection Register 3 (If any blocks are marked as protected in the secure application, then mark them as secure) */ #ifndef BSP_CFG_ROM_REG_BPS_SEL3 #define BSP_CFG_ROM_REG_BPS_SEL3 (BSP_CFG_ROM_REG_BPS3 & BSP_CFG_ROM_REG_PBPS3) #endif /* Security Attribution for Bank Select Register */ #ifndef BSP_CFG_ROM_REG_BANKSEL_SEL #define BSP_CFG_ROM_REG_BANKSEL_SEL (0xFFFFFFFFU) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif /* FSBL Control Register 0 */ #ifndef BSP_CFG_ROM_REG_FSBLCTRL0 #define BSP_CFG_ROM_REG_FSBLCTRL0 ( \ (7 << R_OFS_DATAFLASH_FSBLCTRL0_FSBLEN_Pos) | \ (7 << R_OFS_DATAFLASH_FSBLCTRL0_FSBLSKIPSW_Pos) | \ (7 << R_OFS_DATAFLASH_FSBLCTRL0_FSBLSKIPDS_Pos) | \ (7 << R_OFS_DATAFLASH_FSBLCTRL0_FSBLCLK_Pos) | \ 0xFFFFF000) #endif /* FSBL Control Register 1 */ #ifndef BSP_CFG_ROM_REG_FSBLCTRL1 #define BSP_CFG_ROM_REG_FSBLCTRL1 ( \ (3 << R_OFS_DATAFLASH_FSBLCTRL1_FSBLEXMD_Pos) | \ 0xFFFFFFFC) #endif /* FSBL Control Register 2 */ #ifndef BSP_CFG_ROM_REG_FSBLCTRL2 #define BSP_CFG_ROM_REG_FSBLCTRL2 ( \ (15 << R_OFS_DATAFLASH_FSBLCTRL2_PORTPN_Pos) | \ (0x1F << R_OFS_DATAFLASH_FSBLCTRL2_PORTGN_Pos) | \ 0xFFFFFE00) #endif /* Start Address of Code Certificate Register 0 */ #ifndef BSP_CFG_ROM_REG_SACC0 #define BSP_CFG_ROM_REG_SACC0 (0xFFFFFFFF) #endif /* Start Address of Code Certificate Register 1 */ #ifndef BSP_CFG_ROM_REG_SACC1 #define BSP_CFG_ROM_REG_SACC1 (0xFFFFFFFF) #endif /* Start Address of Measurement Report Register */ #ifndef BSP_CFG_ROM_REG_SAMR #define BSP_CFG_ROM_REG_SAMR (0xFFFFFFFF) #endif #ifndef BSP_CFG_DCACHE_ENABLED #define BSP_CFG_DCACHE_ENABLED (0) #endif #ifndef BSP_CFG_SDRAM_ENABLED #define BSP_CFG_SDRAM_ENABLED (0) #endif #ifndef BSP_CFG_SDRAM_TRAS #define BSP_CFG_SDRAM_TRAS (6) #endif #ifndef BSP_CFG_SDRAM_TRCD #define BSP_CFG_SDRAM_TRCD (3) #endif #ifndef BSP_CFG_SDRAM_TRP #define BSP_CFG_SDRAM_TRP (3) #endif #ifndef BSP_CFG_SDRAM_TWR #define BSP_CFG_SDRAM_TWR (2) #endif #ifndef BSP_CFG_SDRAM_TCL #define BSP_CFG_SDRAM_TCL (3) #endif #ifndef BSP_CFG_SDRAM_TRFC #define BSP_CFG_SDRAM_TRFC (937) #endif #ifndef BSP_CFG_SDRAM_TREFW #define BSP_CFG_SDRAM_TREFW (8) #endif #ifndef BSP_CFG_SDRAM_INIT_ARFI #define BSP_CFG_SDRAM_INIT_ARFI (10) #endif #ifndef BSP_CFG_SDRAM_INIT_ARFC #define BSP_CFG_SDRAM_INIT_ARFC (8) #endif #ifndef BSP_CFG_SDRAM_INIT_PRC #define BSP_CFG_SDRAM_INIT_PRC (3) #endif #ifndef BSP_CFG_SDRAM_MULTIPLEX_ADDR_SHIFT #define BSP_CFG_SDRAM_MULTIPLEX_ADDR_SHIFT (1) #endif #ifndef BSP_CFG_SDRAM_ENDIAN_MODE #define BSP_CFG_SDRAM_ENDIAN_MODE (0) #endif #ifndef BSP_CFG_SDRAM_ACCESS_MODE #define BSP_CFG_SDRAM_ACCESS_MODE (1) #endif #ifndef BSP_CFG_SDRAM_BUS_WIDTH #define BSP_CFG_SDRAM_BUS_WIDTH (0) #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define ENET_RMII_INT (BSP_IO_PORT_00_PIN_00) #define ARDUINO_A3 (BSP_IO_PORT_00_PIN_01) #define GROVE2_AN102 (BSP_IO_PORT_00_PIN_02) #define ARDUINO_A1 (BSP_IO_PORT_00_PIN_03) #define ARDUINO_A0_MIKROBUS_AN000 (BSP_IO_PORT_00_PIN_04) #define GROVE2_AN001 (BSP_IO_PORT_00_PIN_05) #define PMOD1_IRQ11 (BSP_IO_PORT_00_PIN_06) #define ARDUINO_A004 (BSP_IO_PORT_00_PIN_07) #define USER_S2 (BSP_IO_PORT_00_PIN_08) #define SW1 (BSP_IO_PORT_00_PIN_09) #define MIKROBUS_IRQ14 (BSP_IO_PORT_00_PIN_10) #define ARDUINO_A4 (BSP_IO_PORT_00_PIN_14) #define ARDUINO_A5 (BSP_IO_PORT_00_PIN_15) #define OSPI_DQ0 (BSP_IO_PORT_01_PIN_00) #define OSPI_DQ3 (BSP_IO_PORT_01_PIN_01) #define OSPI_DQ4 (BSP_IO_PORT_01_PIN_02) #define OSPI_DQ2 (BSP_IO_PORT_01_PIN_03) #define OSPI_CS (BSP_IO_PORT_01_PIN_04) #define OSPI_INT (BSP_IO_PORT_01_PIN_05) #define OSPI_RESET (BSP_IO_PORT_01_PIN_06) #define LED3 (BSP_IO_PORT_01_PIN_07) #define ETH_A_RMII_RMII_RXDV (BSP_IO_PORT_01_PIN_12) #define ETH_A_LINKSTA (BSP_IO_PORT_01_PIN_14) #define MPLX_CTRL (BSP_IO_PORT_01_PIN_15) #define NMI (BSP_IO_PORT_02_PIN_00) #define MD (BSP_IO_PORT_02_PIN_01) #define CAN_STB (BSP_IO_PORT_02_PIN_07) #define TDI (BSP_IO_PORT_02_PIN_08) #define TDO (BSP_IO_PORT_02_PIN_09) #define SWDIO (BSP_IO_PORT_02_PIN_10) #define SWCLK (BSP_IO_PORT_02_PIN_11) #define EXTAL (BSP_IO_PORT_02_PIN_12) #define XTAL (BSP_IO_PORT_02_PIN_13) #define ETH_A_RXER (BSP_IO_PORT_03_PIN_00) #define ETH_A_RXD1 (BSP_IO_PORT_03_PIN_01) #define ETH_A_RXD0 (BSP_IO_PORT_03_PIN_02) #define ETH_A_REFCLK (BSP_IO_PORT_03_PIN_03) #define ETH_A_TXD0 (BSP_IO_PORT_03_PIN_04) #define ETH_A_TXD1 (BSP_IO_PORT_03_PIN_05) #define ETH_A_TXEN (BSP_IO_PORT_03_PIN_06) #define ETH_A_MDIO (BSP_IO_PORT_03_PIN_07) #define ETH_A_MDC (BSP_IO_PORT_03_PIN_08) #define ARDUINO_D0_MIKROBUS_RXD3 (BSP_IO_PORT_03_PIN_09) #define ARDUINO_D1_MIKROBUS_TXD3 (BSP_IO_PORT_03_PIN_10) #define CAN_RXD (BSP_IO_PORT_03_PIN_11) #define CAN_TXD (BSP_IO_PORT_03_PIN_12) #define I3C_SCL0_ARDUINO_MIKROBUS_PMOD1_3_qwiic (BSP_IO_PORT_04_PIN_00) #define I3C_SDA0_ARDUINO_MIKROBUS_PMOD1_4_qwiic (BSP_IO_PORT_04_PIN_01) #define ETH_B_MDIO (BSP_IO_PORT_04_PIN_02) #define ETH_B_LINKSTA (BSP_IO_PORT_04_PIN_03) #define ETH_B_RST_N (BSP_IO_PORT_04_PIN_04) #define ETH_B_TXEN (BSP_IO_PORT_04_PIN_05) #define ETH_B_TXD1 (BSP_IO_PORT_04_PIN_06) #define USBFS_VBUS (BSP_IO_PORT_04_PIN_07) #define USBHS_VBUSEN (BSP_IO_PORT_04_PIN_08) #define USBHS_OVRCURA (BSP_IO_PORT_04_PIN_09) #define MISOB_B_ARDUINO_MIKROBUS (BSP_IO_PORT_04_PIN_10) #define MOSIB_B_ARDUINO_MIKROBUS (BSP_IO_PORT_04_PIN_11) #define RSPCKB_B_ARDUINO_MIKROBUS (BSP_IO_PORT_04_PIN_12) #define SSLB0_B_ARDUINO_D10_MIKROBUS (BSP_IO_PORT_04_PIN_13) #define LED2 (BSP_IO_PORT_04_PIN_14) #define USBFS_VBUS_EN (BSP_IO_PORT_05_PIN_00) #define USBFS_OVERCURA (BSP_IO_PORT_05_PIN_01) #define MIKROBUS_RESET (BSP_IO_PORT_05_PIN_02) #define PMOD2_7_IRQ1 (BSP_IO_PORT_05_PIN_08) #define GROVE2_IIC_SDA1 (BSP_IO_PORT_05_PIN_11) #define GROVE2_IIC_SCL1 (BSP_IO_PORT_05_PIN_12) #define LED1 (BSP_IO_PORT_06_PIN_00) #define ARDUINO_D5 (BSP_IO_PORT_06_PIN_01) #define ARDUINO_D6 (BSP_IO_PORT_06_PIN_02) #define ARDUINO_D9 (BSP_IO_PORT_06_PIN_03) #define PMOD1_3_MISO0_RXD0_SCL0 (BSP_IO_PORT_06_PIN_09) #define PMOD1_2_MOSI0_TXD0 (BSP_IO_PORT_06_PIN_10) #define PMOD1_4_SCK0 (BSP_IO_PORT_06_PIN_11) #define PMOD1_1_SSL0_CTS_RTS (BSP_IO_PORT_06_PIN_12) #define PMOD1_1_CTS0 (BSP_IO_PORT_06_PIN_13) #define PMOD1_9_GPIO (BSP_IO_PORT_06_PIN_14) #define PMOD1_10_GPIO (BSP_IO_PORT_06_PIN_15) #define ETH_B_TXD0 (BSP_IO_PORT_07_PIN_00) #define ETH_B_REFCLK (BSP_IO_PORT_07_PIN_01) #define ETH_B_RXD0 (BSP_IO_PORT_07_PIN_02) #define ETH_B_RXD1 (BSP_IO_PORT_07_PIN_03) #define ETH_B_RXER (BSP_IO_PORT_07_PIN_04) #define ETH_B_RMII_RXDV (BSP_IO_PORT_07_PIN_05) #define I3C_SDA0_PULLUP (BSP_IO_PORT_07_PIN_11) #define OSPI_DQ5 (BSP_IO_PORT_08_PIN_00) #define OSPI_DS (BSP_IO_PORT_08_PIN_01) #define OSPI_DQ6 (BSP_IO_PORT_08_PIN_02) #define OSPI_DQ1 (BSP_IO_PORT_08_PIN_03) #define OSPI_DQ7 (BSP_IO_PORT_08_PIN_04) #define OSPI_CK (BSP_IO_PORT_08_PIN_08) #define PMOD2_8_RESET (BSP_IO_PORT_08_PIN_09) #define PMOD2_9_GPIO (BSP_IO_PORT_08_PIN_10) #define PMOD2_10_GPIO (BSP_IO_PORT_08_PIN_11) #define ARDUINO_RESET (BSP_IO_PORT_08_PIN_12) #define USBFS_P (BSP_IO_PORT_08_PIN_14) #define USBFS_N (BSP_IO_PORT_08_PIN_15) #define ARDUINO_D4 (BSP_IO_PORT_09_PIN_05) #define ARDUINO_D2 (BSP_IO_PORT_09_PIN_06) #define ARDUINO_D3_MIKROBUS_GTIOC13A (BSP_IO_PORT_09_PIN_07) #define ARDUINO_D7 (BSP_IO_PORT_09_PIN_08) #define ARDUINO_D8 (BSP_IO_PORT_09_PIN_09) #define PMOD2_3_MISO2_RXD2 (BSP_IO_PORT_10_PIN_02) #define PMOD2_2_MOSI2_TXD2 (BSP_IO_PORT_10_PIN_03) #define PMOD2_4_SCK2 (BSP_IO_PORT_10_PIN_04) #define PMOD2_1_CTS_RTS_SSL2 (BSP_IO_PORT_10_PIN_05) #define PMOD2_1_CTS2 (BSP_IO_PORT_10_PIN_06) #define PMOD1_8_RESET (BSP_IO_PORT_10_PIN_08) #define JLOB_COMS_TX (BSP_IO_PORT_10_PIN_14) #define JLOB_COMS_RX (BSP_IO_PORT_10_PIN_15) #define I3C_SCL0_PULLUP (BSP_IO_PORT_11_PIN_00) #define USBHS_VBUS (BSP_IO_PORT_11_PIN_01) extern const ioport_cfg_t g_bsp_pin_cfg; /* RA8M1 EK */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (20000000) /* XTAL 20000000Hz */ #define BSP_CFG_HOCO_FREQUENCY (7) /* HOCO 48MHz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL Div /2 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(96,0) /* PLL Mul x80-99|Mul x96|PLL Mul x96.00 */ #define BSP_CFG_PLL_FREQUENCY_HZ (960000000) /* PLL 960000000Hz */ #define BSP_CFG_PLODIVP (BSP_CLOCKS_PLL_DIV_2) /* PLL1P Div /2 */ #define BSP_CFG_PLL1P_FREQUENCY_HZ (480000000) /* PLL1P 480000000Hz */ #define BSP_CFG_PLODIVQ (BSP_CLOCKS_PLL_DIV_4) /* PLL1Q Div /4 */ #define BSP_CFG_PLL1Q_FREQUENCY_HZ (240000000) /* PLL1Q 240000000Hz */ #define BSP_CFG_PLODIVR (BSP_CLOCKS_PLL_DIV_2) /* PLL1R Div /2 */ #define BSP_CFG_PLL1R_FREQUENCY_HZ (480000000) /* PLL1R 480000000Hz */ #define BSP_CFG_PLL2_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* PLL2 Disabled */ #define BSP_CFG_PLL2_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL2 Div /2 */ #define BSP_CFG_PLL2_MUL BSP_CLOCKS_PLL_MUL(96,0) /* PLL2 Mul x80-99|Mul x96|PLL2 Mul x96.00 */ #define BSP_CFG_PLL2_FREQUENCY_HZ (0) /* PLL2 0Hz */ #define BSP_CFG_PL2ODIVP (BSP_CLOCKS_PLL_DIV_2) /* PLL2P Div /2 */ #define BSP_CFG_PLL2P_FREQUENCY_HZ (0) /* PLL2P 0Hz */ #define BSP_CFG_PL2ODIVQ (BSP_CLOCKS_PLL_DIV_2) /* PLL2Q Div /2 */ #define BSP_CFG_PLL2Q_FREQUENCY_HZ (0) /* PLL2Q 0Hz */ #define BSP_CFG_PL2ODIVR (BSP_CLOCKS_PLL_DIV_2) /* PLL2R Div /2 */ #define BSP_CFG_PLL2R_FREQUENCY_HZ (0) /* PLL2R 0Hz */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL1P) /* Clock Src: PLL1P */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_SCICLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* SCICLK Disabled */ #define BSP_CFG_SPICLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* SPICLK Disabled */ #define BSP_CFG_CANFDCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CANFDCLK Disabled */ #define BSP_CFG_I3CCLK_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* I3CCLK Disabled */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL1Q) /* UCK Src: PLL1Q */ #define BSP_CFG_U60CK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL1P) /* U60CK Src: PLL1P */ #define BSP_CFG_OCTA_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* OCTASPICLK Disabled */ #define BSP_CFG_CPUCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CPUCLK Div /1 */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* ICLK Div /2 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKA Div /4 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_8) /* PCLKB Div /8 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_8) /* PCLKC Div /8 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* PCLKD Div /4 */ #define BSP_CFG_PCLKE_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKE Div /2 */ #define BSP_CFG_SDCLK_OUTPUT (1) /* SDCLK Enabled */ #define BSP_CFG_BCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_4) /* BCLK Div /4 */ #define BSP_CFG_BCLK_OUTPUT (2) /* EBCLK Div /2 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_8) /* FCLK Div /8 */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_SCICLK_DIV (BSP_CLOCKS_SCI_CLOCK_DIV_4) /* SCICLK Div /4 */ #define BSP_CFG_SPICLK_DIV (BSP_CLOCKS_SPI_CLOCK_DIV_4) /* SPICLK Div /4 */ #define BSP_CFG_CANFDCLK_DIV (BSP_CLOCKS_CANFD_CLOCK_DIV_8) /* CANFDCLK Div /8 */ #define BSP_CFG_I3CCLK_DIV (BSP_CLOCKS_I3C_CLOCK_DIV_3) /* I3CCLK Div /3 */ #define BSP_CFG_UCK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_5) /* UCK Div /5 */ #define BSP_CFG_U60CK_DIV (BSP_CLOCKS_USB_CLOCK_DIV_8) /* U60CK Div /8 */ #define BSP_CFG_OCTA_DIV (BSP_CLOCKS_OCTA_CLOCK_DIV_4) /* OCTASPICLK Div /4 */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_00_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_00_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_ANALOG_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_01_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_02_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_02_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_02_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_03_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_03_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_03_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_03_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_03_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_TRACE) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_04_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, { .pin = BSP_IO_PORT_04_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, { .pin = BSP_IO_PORT_04_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_13, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SPI) }, { .pin = BSP_IO_PORT_04_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_05_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_05_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_05_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_MID | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_IIC) }, { .pin = BSP_IO_PORT_06_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_08_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HS_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_OSPI) }, { .pin = BSP_IO_PORT_08_PIN_09, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_08_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_08_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_10_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_10_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_10_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_10_PIN_05, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI0_2_4_6_8) }, { .pin = BSP_IO_PORT_10_PIN_06, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) }, { .pin = BSP_IO_PORT_10_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_10_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SCI1_3_5_7_9) }, { .pin = BSP_IO_PORT_11_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_DRIVE_HIGH | (uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_HS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; OPTION_SETTING_DATA_FLASH_S_START = DEFINED(OPTION_SETTING_DATA_FLASH_S_START) ? OPTION_SETTING_DATA_FLASH_S_START : 0; OPTION_SETTING_DATA_FLASH_S_LENGTH = DEFINED(OPTION_SETTING_DATA_FLASH_S_LENGTH) ? OPTION_SETTING_DATA_FLASH_S_LENGTH : 0; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_DATA_FLASH = PROJECT_SECURE_OR_FLAT && (OPTION_SETTING_DATA_FLASH_S_LENGTH != 0); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH OPTION_SETTING_DATA_FLASH_S (r) : ORIGIN = OPTION_SETTING_DATA_FLASH_S_START, LENGTH = OPTION_SETTING_DATA_FLASH_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __FLASH_NSC_START = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM . = .; __nocache_pre_location = .; .nocache ALIGN(32) (NOLOAD): { __nocache_start = .; KEEP(*(.nocache)) . = ALIGN(32); __nocache_end = .; } > RAM . = (SIZEOF(.nocache) > 0) ? __nocache_end : __nocache_pre_location; .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __RAM_NSC_START = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(FLASH_BOOTLOADER_LENGTH) ? (RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH) : DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_NSC_START, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM . = .; __nocache_sdram_pre_location = .; .nocache_sdram ALIGN(32) (NOLOAD): { __nocache_sdram_start = .; KEEP(*(.nocache_sdram)) . = ALIGN(32); __nocache_sdram_end = .; } > SDRAM . = (SIZEOF(.nocache_sdram) > 0) ? __nocache_sdram_end : __nocache_sdram_pre_location; /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_DATA_FLASH_S_S = ORIGIN(OPTION_SETTING_DATA_FLASH_S); .option_setting_data_flash_s : { __OPTION_SETTING_DATA_FLASH_S_Start = .; KEEP(*(.option_setting_data_flash_fsblctrl0)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x04 : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_fsblctrl1)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x08 : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_fsblctrl2)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x0C : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_sacc0)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x10 : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_sacc1)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x14 : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_samr)) . = USE_OPTION_SETTING_DATA_FLASH ? __OPTION_SETTING_DATA_FLASH_S_Start + 0x2E0 : __OPTION_SETTING_DATA_FLASH_S_Start; KEEP(*(.option_setting_data_flash_hoemrtpk)) __OPTION_SETTING_DATA_FLASH_S_End = .; } > OPTION_SETTING_DATA_FLASH_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_DATA_FLASH_S_N = __OPTION_SETTING_DATA_FLASH_S_End; } ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x22000000; RAM_LENGTH = 0xE0000; FLASH_START = 0x02000000; FLASH_LENGTH = 0x1F8000; DATA_FLASH_START = 0x27000000; DATA_FLASH_LENGTH = 0x3000; OPTION_SETTING_START = 0x0300A100; OPTION_SETTING_LENGTH = 0x100; OPTION_SETTING_S_START = 0x0300A200; OPTION_SETTING_S_LENGTH = 0x100; OPTION_SETTING_DATA_FLASH_S_START = 0x27030080; OPTION_SETTING_DATA_FLASH_S_LENGTH = 0x800; ID_CODE_START = 0x00000000; ID_CODE_LENGTH = 0x0; SDRAM_START = 0x68000000; SDRAM_LENGTH = 0x8000000; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x0; OSPI_DEVICE_0_START = 0x80000000; OSPI_DEVICE_0_LENGTH = 0x10000000; OSPI_DEVICE_1_START = 0x90000000; OSPI_DEVICE_1_LENGTH = 0x10000000; ITCM_START = 0x00000000; ITCM_LENGTH = 0x10000; DTCM_START = 0x20000000; DTCM_LENGTH = 0x10000; NS_OFFSET_START = 0x10000000; NS_OFFSET_LENGTH = 0x0; ================================================ FILE: hw/bsp/ra/boards/ra8m1_ek/smart_configurator/configuration.xml ================================================ Simple application that blinks an LED. No RTOS included. Renesas.RA_baremetal_blinky.5.6.0.pack Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack RA8M1-EK Board Support Files Renesas.RA_board_ra8m1_ek.5.6.0.pack Board support package for R7FA8M1AHECBD Renesas.RA_mcu_ra8m1.5.6.0.pack Board support package for RA8M1 Renesas.RA_mcu_ra8m1.5.6.0.pack Board support package for RA8M1 - FSP Data Renesas.RA_mcu_ra8m1.5.6.0.pack Board support package for RA8M1 - Events Renesas.RA_mcu_ra8m1.5.6.0.pack USB Basic Renesas.RA.5.6.0.pack USB Peripheral Communications Device Class Renesas.RA.5.6.0.pack ================================================ FILE: hw/bsp/ra/boards/uno_r4/board.cmake ================================================ set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(MCU_VARIANT ra4m1) set(JLINK_DEVICE R7FA4M1AB) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/ra/boards/uno_r4/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Arduino UNO R4 url: https://store-usa.arduino.cc/pages/uno-r4 */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_STATE_ON 1 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/ra/boards/uno_r4/board.mk ================================================ CPU_CORE = cortex-m4 MCU_VARIANT = ra4m1 # For flash-jlink target JLINK_DEVICE = R7FA4M1AB flash: flash-jlink ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/bsp/bsp_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CFG_H_ #define BSP_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_clock_cfg.h" #include "bsp_mcu_family_cfg.h" #include "board_cfg.h" #define RA_NOT_DEFINED 0 #ifndef BSP_CFG_RTOS #if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (2) #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) #define BSP_CFG_RTOS (1) #else #define BSP_CFG_RTOS (0) #endif #endif #ifndef BSP_CFG_RTC_USED #define BSP_CFG_RTC_USED (RA_NOT_DEFINED) #endif #undef RA_NOT_DEFINED #if defined(_RA_BOOT_IMAGE) #define BSP_CFG_BOOT_IMAGE (1) #endif #define BSP_CFG_MCU_VCC_MV (3300) #define BSP_CFG_STACK_MAIN_BYTES (0x800) #define BSP_CFG_HEAP_BYTES (0x1000) #define BSP_CFG_PARAM_CHECKING_ENABLE (0) #define BSP_CFG_ASSERT (0) #define BSP_CFG_ERROR_LOG (0) #define BSP_CFG_PFS_PROTECT ((1)) #define BSP_CFG_C_RUNTIME_INIT ((1)) #define BSP_CFG_EARLY_INIT ((0)) #define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) #ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED #define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (0) #endif #ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE #define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE #define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED #define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (0) #endif #ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS #define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 #endif #ifdef __cplusplus } #endif #endif /* BSP_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_CFG_H_ #define BSP_MCU_DEVICE_CFG_H_ #define BSP_CFG_MCU_PART_SERIES (4) #endif /* BSP_MCU_DEVICE_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_DEVICE_PN_CFG_H_ #define BSP_MCU_R7FA4M1AB3CNE #define BSP_MCU_FEATURE_SET ('A') #define BSP_ROM_SIZE_BYTES (262144) #define BSP_RAM_SIZE_BYTES (32768) #define BSP_DATA_FLASH_SIZE_BYTES (8192) #define BSP_PACKAGE_QFN #define BSP_PACKAGE_PINS (48) #endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_MCU_FAMILY_CFG_H_ #define BSP_MCU_FAMILY_CFG_H_ #ifdef __cplusplus extern "C" { #endif #include "bsp_mcu_device_pn_cfg.h" #include "bsp_mcu_device_cfg.h" #include "../../../ra/fsp/src/bsp/mcu/ra4m1/bsp_mcu_info.h" #include "bsp_clock_cfg.h" #define BSP_MCU_GROUP_RA4M1 (1) #define BSP_LOCO_HZ (32768) #define BSP_MOCO_HZ (8000000) #define BSP_SUB_CLOCK_HZ (32768) #if BSP_CFG_HOCO_FREQUENCY == 0 #define BSP_HOCO_HZ (24000000) #elif BSP_CFG_HOCO_FREQUENCY == 2 #define BSP_HOCO_HZ (32000000) #elif BSP_CFG_HOCO_FREQUENCY == 4 #define BSP_HOCO_HZ (48000000) #elif BSP_CFG_HOCO_FREQUENCY == 5 #define BSP_HOCO_HZ (64000000) #else #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" #endif #define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) #define BSP_VECTOR_TABLE_MAX_ENTRIES (48U) #define BSP_CFG_INLINE_IRQ_FUNCTIONS (1) #define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) #define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) #define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) #define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) #define OFS_SEQ5 (1 << 28) | (1 << 30) #define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) #define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEC3 | (1 << 2) | (3 << 3) | (0 << 8)) #define BSP_CFG_USE_LOW_VOLTAGE_MODE ((0)) #define BSP_CFG_ROM_REG_MPU_PC0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC0_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_PC0_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_PC1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_PC1_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_PC1_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION0_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION0_START (0x00FFFFFC) #define BSP_CFG_ROM_REG_MPU_REGION0_END (0x00FFFFFF) #define BSP_CFG_ROM_REG_MPU_REGION1_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION1_START (0x200FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION1_END (0x200FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION2_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION2_START (0x407FFFFC) #define BSP_CFG_ROM_REG_MPU_REGION2_END (0x407FFFFF) #define BSP_CFG_ROM_REG_MPU_REGION3_ENABLE (1) #define BSP_CFG_ROM_REG_MPU_REGION3_START (0x400DFFFC) #define BSP_CFG_ROM_REG_MPU_REGION3_END (0x400DFFFF) #ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT #define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) #endif /* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ #define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) /* ID Code Note: To permanently lock and disable the debug interface define the BSP_ID_CODE_PERMANENTLY_LOCKED in the compiler settings. WARNING: This will disable debug access to the part and cannot be reversed by a debug probe. */ #if defined(BSP_ID_CODE_PERMANENTLY_LOCKED) #define BSP_CFG_ID_CODE_LONG_1 (0x00000000) #define BSP_CFG_ID_CODE_LONG_2 (0x00000000) #define BSP_CFG_ID_CODE_LONG_3 (0x00000000) #define BSP_CFG_ID_CODE_LONG_4 (0x00000000) #else /* ID CODE: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */ #define BSP_CFG_ID_CODE_LONG_1 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_2 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_3 (0xFFFFFFFF) #define BSP_CFG_ID_CODE_LONG_4 (0xffFFFFFF) #endif #ifdef __cplusplus } #endif #endif /* BSP_MCU_FAMILY_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_PIN_CFG_H_ #define BSP_PIN_CFG_H_ #include "r_ioport.h" /* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ FSP_HEADER #define SW1 (BSP_IO_PORT_01_PIN_10) /* active low */ #define LED1 (BSP_IO_PORT_01_PIN_11) /* active high */ extern const ioport_cfg_t g_bsp_pin_cfg; /* R7FA4M1AB3CNE.pincfg */ void BSP_PinConfigSecurityInit(); /* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ FSP_FOOTER #endif /* BSP_PIN_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_cfg/fsp_cfg/r_ioport_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef R_IOPORT_CFG_H_ #define R_IOPORT_CFG_H_ #ifdef __cplusplus extern "C" { #endif #define IOPORT_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) #ifdef __cplusplus } #endif #endif /* R_IOPORT_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_gen/bsp_clock_cfg.h ================================================ /* generated configuration header file - do not edit */ #ifndef BSP_CLOCK_CFG_H_ #define BSP_CLOCK_CFG_H_ #define BSP_CFG_CLOCKS_SECURE (0) #define BSP_CFG_CLOCKS_OVERRIDE (0) #define BSP_CFG_XTAL_HZ (0) /* XTAL 0Hz */ #define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* PLL Src: Disabled */ #define BSP_CFG_HOCO_FREQUENCY (4) /* HOCO 48MHz */ #define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_4) /* PLL Div /4 */ #define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(12U,0U) /* PLL Mul x12 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_HOCO) /* Clock Src: HOCO */ #define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ #define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKA Div /1 */ #define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKB Div /2 */ #define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKC Div /1 */ #define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKD Div /1 */ #define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* FCLK Div /2 */ #define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ #define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ #define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_HOCO) /* UCLK Src: HOCO */ #endif /* BSP_CLOCK_CFG_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_gen/common_data.c ================================================ /* generated common source file - do not edit */ #include "common_data.h" ioport_instance_ctrl_t g_ioport_ctrl; const ioport_instance_t g_ioport = { .p_api = &g_ioport_on_ioport, .p_ctrl = &g_ioport_ctrl, .p_cfg = &g_bsp_pin_cfg, }; void g_common_init(void) { } ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_gen/common_data.h ================================================ /* generated common header file - do not edit */ #ifndef COMMON_DATA_H_ #define COMMON_DATA_H_ #include #include "bsp_api.h" #include "r_ioport.h" #include "bsp_pin_cfg.h" FSP_HEADER #define IOPORT_CFG_NAME g_bsp_pin_cfg #define IOPORT_CFG_OPEN R_IOPORT_Open #define IOPORT_CFG_CTRL g_ioport_ctrl /* IOPORT Instance */ extern const ioport_instance_t g_ioport; /* IOPORT control structure. */ extern ioport_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ ================================================ FILE: hw/bsp/ra/boards/uno_r4/ra_gen/pin_data.c ================================================ /* generated pin source file - do not edit */ #include "bsp_api.h" #include "r_ioport.h" const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_01_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_01_PIN_10, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT | (uint32_t) IOPORT_CFG_PULLUP_ENABLE) }, { .pin = BSP_IO_PORT_01_PIN_11, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) }, { .pin = BSP_IO_PORT_03_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG) }, { .pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_09_PIN_14, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, { .pin = BSP_IO_PORT_09_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_USB_FS) }, }; const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = sizeof(g_bsp_pin_cfg_data)/sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], }; #if BSP_TZ_SECURE_BUILD void R_BSP_PinCfgSecurityInit(void); /* Initialize SAR registers for secure pins. */ void R_BSP_PinCfgSecurityInit(void) { #if (2U == BSP_FEATURE_IOPORT_VERSION) uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #else uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; #endif memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) { uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; uint32_t port = port_pin >> 8U; uint32_t pin = port_pin & 0xFFU; pmsar[port] &= (uint16_t) ~(1U << pin); } for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) { #if (2U == BSP_FEATURE_IOPORT_VERSION) R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; #else R_PMISC->PMSAR[i].PMSAR = pmsar[i]; #endif } } #endif ================================================ FILE: hw/bsp/ra/boards/uno_r4/script/fsp.ld ================================================ /* Linker File for Renesas FSP */ INCLUDE memory_regions.ld /* Uncomment and set XIP_SECONDARY_SLOT_IMAGE to 1 below for the secondary XIP application image.*/ /* XIP_SECONDARY_SLOT_IMAGE = 1; */ QSPI_FLASH_PRV_LENGTH = DEFINED(QSPI_FLASH_SIZE) ? ABSOLUTE(QSPI_FLASH_SIZE) : ABSOLUTE(QSPI_FLASH_LENGTH); OSPI_DEVICE_0_PRV_LENGTH = DEFINED(OSPI_DEVICE_0_SIZE) ? ABSOLUTE(OSPI_DEVICE_0_SIZE) : ABSOLUTE(OSPI_DEVICE_0_LENGTH); OSPI_DEVICE_1_PRV_LENGTH = DEFINED(OSPI_DEVICE_1_SIZE) ? ABSOLUTE(OSPI_DEVICE_1_SIZE) : ABSOLUTE(OSPI_DEVICE_1_LENGTH); /* If a flat (secure) project has DEFINED RAM_NS_BUFFER_LENGTH, then emit IDAU symbols to allocate non-secure RAM. */ __RESERVE_NS_RAM = !DEFINED(PROJECT_NONSECURE) && DEFINED(RAM_NS_BUFFER_LENGTH) && (OPTION_SETTING_S_LENGTH != 0); ITCM_START = DEFINED(ITCM_START)? ITCM_START : 0; ITCM_LENGTH = DEFINED(ITCM_LENGTH)? ITCM_LENGTH : 0; DTCM_START = DEFINED(DTCM_START)? DTCM_START : 0; DTCM_LENGTH = DEFINED(DTCM_LENGTH)? DTCM_LENGTH : 0; RAM_NS_BUFFER_BLOCK_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? ALIGN(RAM_NS_BUFFER_LENGTH, 8192) : 0; RAM_NS_BUFFER_LENGTH = DEFINED(RAM_NS_BUFFER_LENGTH) ? RAM_NS_BUFFER_LENGTH : 0; RAM_NS_BUFFER_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_LENGTH; RAM_NS_BUFFER_BLOCK_START = RAM_START + RAM_LENGTH - RAM_NS_BUFFER_BLOCK_LENGTH; OPTION_SETTING_START_NS = DEFINED(PROJECT_NONSECURE) ? OPTION_SETTING_START : OPTION_SETTING_START + 0x80; /* This definition is used to avoid moving the counter in OPTION_SETTING regions for projects that should not configure option settings. * Bootloader images do not configure option settings because they are owned by the bootloader. * FSP_BOOTABLE_IMAGE is only defined in bootloader images. */ __bl_FSP_BOOTABLE_IMAGE = 1; __bln_FSP_BOOTABLE_IMAGE = 1; PROJECT_SECURE_OR_FLAT = (!DEFINED(PROJECT_NONSECURE) || DEFINED(PROJECT_SECURE)) && OPTION_SETTING_LENGTH && !DEFINED(FSP_BOOTABLE_IMAGE); USE_OPTION_SETTING_NS = DEFINED(PROJECT_NONSECURE) && !DEFINED(FSP_BOOTABLE_IMAGE); __bl_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_IMAGE_NUMBER == 1 ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : (DEFINED(BOOTLOADER_SECONDARY_USE_QSPI) || DEFINED(BOOTLOADER_SECONDARY_USE_OSPI_B)) ? FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_BOOTLOADER_SCRATCH_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_S_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH; __bl_FLASH_IMAGE_END = __bl_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_START + FLASH_BOOTLOADER_LENGTH + FLASH_APPLICATION_S_LENGTH + FLASH_BOOTLOADER_HEADER_LENGTH; __bl_XIP_SECONDARY_FLASH_IMAGE_END = __bl_XIP_SECONDARY_FLASH_IMAGE_START + __bl_FLASH_IMAGE_LENGTH; __bl_FLASH_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_START - FLASH_BOOTLOADER_HEADER_LENGTH + FLASH_APPLICATION_S_LENGTH; __bl_FLASH_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_IMAGE_END - FLASH_APPLICATION_NSC_LENGTH; __bl_RAM_NS_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : RAM_START + RAM_LENGTH - RAM_APPLICATION_NS_LENGTH; __bl_RAM_NSC_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? RAM_START + RAM_LENGTH : __bl_RAM_NS_START - RAM_APPLICATION_NSC_LENGTH; __bl_FLASH_NS_IMAGE_START = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : __bl_FLASH_NS_START + FLASH_BOOTLOADER_HEADER_LENGTH_2; __bln_FLASH_IMAGE_START = __bl_FLASH_NS_IMAGE_START | (!DEFINED (NS_OFFSET_START) ? 0 : NS_OFFSET_START); __bln_FLASH_IMAGE_LENGTH = !DEFINED(FLASH_BOOTLOADER_LENGTH) ? 0 : FLASH_APPLICATION_NS_LENGTH == 0 ? __bl_FLASH_IMAGE_END : FLASH_APPLICATION_NS_LENGTH - FLASH_BOOTLOADER_HEADER_LENGTH_2; XIP_SECONDARY_SLOT_IMAGE = DEFINED(XIP_SECONDARY_SLOT_IMAGE) ? XIP_SECONDARY_SLOT_IMAGE : 0; FLASH_ORIGIN = !DEFINED(FLASH_IMAGE_START) ? FLASH_START : XIP_SECONDARY_SLOT_IMAGE == 1 ? XIP_SECONDARY_FLASH_IMAGE_START : FLASH_IMAGE_START; LIMITED_FLASH_LENGTH = DEFINED(FLASH_IMAGE_LENGTH) ? FLASH_IMAGE_LENGTH : DEFINED(FLASH_BOOTLOADER_LENGTH) ? FLASH_BOOTLOADER_LENGTH : FLASH_LENGTH; OPTION_SETTING_SAS_SIZE = 0x34; OPTION_SETTING_SAS_LENGTH = !DEFINED(OPTION_SETTING_LENGTH) ? 0 : OPTION_SETTING_LENGTH == 0 ? 0 : OPTION_SETTING_LENGTH - OPTION_SETTING_SAS_SIZE; /* Define memory regions. */ MEMORY { ITCM (rx) : ORIGIN = ITCM_START, LENGTH = ITCM_LENGTH DTCM (rwx) : ORIGIN = DTCM_START, LENGTH = DTCM_LENGTH FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = LIMITED_FLASH_LENGTH RAM (rwx) : ORIGIN = RAM_START, LENGTH = RAM_LENGTH DATA_FLASH (rx) : ORIGIN = DATA_FLASH_START, LENGTH = DATA_FLASH_LENGTH QSPI_FLASH (rx) : ORIGIN = QSPI_FLASH_START, LENGTH = QSPI_FLASH_PRV_LENGTH OSPI_DEVICE_0 (rx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1 (rx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH OSPI_DEVICE_0_RAM (rwx) : ORIGIN = OSPI_DEVICE_0_START, LENGTH = OSPI_DEVICE_0_PRV_LENGTH OSPI_DEVICE_1_RAM (rwx) : ORIGIN = OSPI_DEVICE_1_START, LENGTH = OSPI_DEVICE_1_PRV_LENGTH SDRAM (rwx) : ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH OPTION_SETTING (r) : ORIGIN = OPTION_SETTING_START, LENGTH = OPTION_SETTING_LENGTH OPTION_SETTING_OFS (r) : ORIGIN = OPTION_SETTING_START, LENGTH = 0x18 OPTION_SETTING_SAS (r) : ORIGIN = OPTION_SETTING_START + OPTION_SETTING_SAS_SIZE, LENGTH = OPTION_SETTING_SAS_LENGTH OPTION_SETTING_S (r) : ORIGIN = OPTION_SETTING_S_START, LENGTH = OPTION_SETTING_S_LENGTH ID_CODE (rx) : ORIGIN = ID_CODE_START, LENGTH = ID_CODE_LENGTH } /* Library configurations */ GROUP(libgcc.a libc.a libm.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be DEFINED in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size * __qspi_flash_start__ * __qspi_flash_end__ * __qspi_flash_code_size__ * __qspi_region_max_size__ * __qspi_region_start_address__ * __qspi_region_end_address__ * __ospi_device_0_start__ * __ospi_device_0_end__ * __ospi_device_0_code_size__ * __ospi_device_0_region_max_size__ * __ospi_device_0_region_start_address__ * __ospi_device_0_region_end_address__ * __ospi_device_1_start__ * __ospi_device_1_end__ * __ospi_device_1_code_size__ * __ospi_device_1_region_max_size__ * __ospi_device_1_region_start_address__ * __ospi_device_1_region_end_address__ */ ENTRY(Reset_Handler) SECTIONS { .text : { __tz_FLASH_S = ABSOLUTE(FLASH_START); __ROM_Start = .; /* Even though the vector table is not 256 entries (1KB) long, we still allocate that much * space because ROM registers are at address 0x400 and there is very little space * in between. */ KEEP(*(.fixed_vectors*)) KEEP(*(.application_vectors*)) __Vectors_End = .; /* Some devices have a gap of code flash between the vector table and ROM Registers. * The flash gap section allows applications to place code and data in this section. */ *(.flash_gap*) /* ROM Registers start at address 0x00000400 for devices that do not have the OPTION_SETTING region. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x400; KEEP(*(.rom_registers*)) /* Reserving 0x100 bytes of space for ROM registers. */ . = OPTION_SETTING_LENGTH > 0 ? . : __ROM_Start + 0x500; /* Allocate flash write-boundary-aligned * space for sce9 wrapped public keys for mcuboot if the module is used. */ KEEP(*(.mcuboot_sce9_key*)) *(.text*) KEEP(*(.version)) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) __usb_dev_descriptor_start_fs = .; KEEP(*(.usb_device_desc_fs*)) __usb_cfg_descriptor_start_fs = .; KEEP(*(.usb_config_desc_fs*)) __usb_interface_descriptor_start_fs = .; KEEP(*(.usb_interface_desc_fs*)) __usb_descriptor_end_fs = .; __usb_dev_descriptor_start_hs = .; KEEP(*(.usb_device_desc_hs*)) __usb_cfg_descriptor_start_hs = .; KEEP(*(.usb_config_desc_hs*)) __usb_interface_descriptor_start_hs = .; KEEP(*(.usb_interface_desc_hs*)) __usb_descriptor_end_hs = .; KEEP(*(.eh_frame*)) __ROM_End = .; } > FLASH = 0xFF __Vectors_Size = __Vectors_End - __Vectors; . = .; __itcm_data_pre_location = .; /* Initialized ITCM data. */ /* Aligned to FCACHE2 for RA8. */ .itcm_data : ALIGN(16) { /* Start of ITCM Secure Trustzone region. */ __tz_ITCM_S = ABSOLUTE(ITCM_START); /* All ITCM data start */ __itcm_data_start = .; KEEP(*(.itcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* All ITCM data end */ __itcm_data_end = .; /* * Start of the ITCM Non-Secure Trustzone region. * ITCM_NS_START can be used to set a fixed address for non-secure ITCM in secure projects or flat projects. */ __tz_ITCM_N = DEFINED(ITCM_NS_START) ? ABSOLUTE(ITCM_NS_START) : ALIGN(__itcm_data_end, 8192); } > ITCM AT > FLASH = 0x00 /* Addresses exported for ITCM initialization. */ __itcm_data_init_start = LOADADDR(.itcm_data); __itcm_data_init_end = LOADADDR(.itcm_data) + SIZEOF(.itcm_data); ASSERT(ORIGIN(ITCM) % 8 == 0, "ITCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(ITCM) % 8 == 0, "ITCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.itcm_data) % 16 == 0, ".itcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.itcm_data) % 8 == 0, ".itcm_data section size must be a multiple of 8 bytes.") /* Restore location counter. */ /* If ITCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If ITCM is present, this will be the absolute address that follows the ITCM ROM location. */ . = (SIZEOF(.itcm_data) > 0) ? __itcm_data_init_end : __itcm_data_pre_location; __exidx_start = .; /DISCARD/ : { *(.ARM.extab* .gnu.linkonce.armextab.*) *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ /* .copy.table : { . = ALIGN(4); __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG (__data_end__ - __data_start__) LONG (__etext2) LONG (__data2_start__) LONG (__data2_end__ - __data2_start__) __copy_table_end__ = .; } > FLASH */ /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ /* .zero.table : { . = ALIGN(4); __zero_table_start__ = .; LONG (__bss_start__) LONG (__bss_end__ - __bss_start__) LONG (__bss2_start__) LONG (__bss2_end__ - __bss2_start__) __zero_table_end__ = .; } > FLASH */ __etext = .; __tz_RAM_S = ORIGIN(RAM); /* If DTC is used, put the DTC vector table at the start of SRAM. This avoids memory holes due to 1K alignment required by it. */ .fsp_dtc_vector_table (NOLOAD) : { . = ORIGIN(RAM); *(.fsp_dtc_vector_table) } > RAM /* Initialized data section. */ .data : { __data_start__ = .; . = ALIGN(4); __Code_In_RAM_Start = .; KEEP(*(.code_in_ram*)) __Code_In_RAM_End = .; *(vtable) /* Don't use *(.data*) because it will place data meant for .data_flash in this section. */ *(.data.*) *(.data) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH . = .; __dtcm_data_pre_location = LOADADDR(.data) + SIZEOF(.data); /* Initialized DTCM data. */ /* Aligned to FCACHE2 for RA8. */ .dtcm_data : ALIGN(16) { /* Start of DTCM Secure Trustzone region. */ __tz_DTCM_S = ABSOLUTE(DTCM_START); /* Initialized DTCM data start */ __dtcm_data_start = .; KEEP(*(.dtcm_data*)) /* Pad to eight byte alignment in case of ECC initialization. Fill zero. */ . = ALIGN(8); /* Initialized DTCM data end */ __dtcm_data_end = .; } > DTCM AT > FLASH = 0x00 . = __dtcm_data_end; /* Uninitialized DTCM data. */ /* ALIGN appears on the left side of the colon because it is being used to assign the VMA directly, as opposed to a right side appearance which would control the LMA. */ .dtcm_bss ALIGN(8) (NOLOAD) : { /* Uninitialized DTCM data start */ __dtcm_bss_start = .; KEEP(*(.dtcm_bss*)) /* Pad to eight byte alignment in case of ECC initialization. No fill because of NOLOAD. */ . = ALIGN(8); /* Uninitialized DTCM data end */ __dtcm_bss_end = .; /* * Start of the DTCM Non-Secure Trustzone region. * DTCM_NS_START can be used to set a fixed address for non-secure DTCM in secure projects or flat projects. */ __tz_DTCM_N = DEFINED(DTCM_NS_START) ? ABSOLUTE(DTCM_NS_START) : ALIGN(__dtcm_bss_end, 8192); } > DTCM /* Addresses exported for DTCM initialization. */ __dtcm_data_init_start = LOADADDR(.dtcm_data); __dtcm_data_init_end = LOADADDR(.dtcm_data) + SIZEOF(.dtcm_data); ASSERT(ORIGIN(DTCM) % 8 == 0, "DTCM memory region origin must be aligned to 8 bytes.") ASSERT(LENGTH(DTCM) % 8 == 0, "DTCM memory region length must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) == ADDR(.dtcm_bss), ".dtcm_bss has (VMA != LMA) but should be NOLOAD (VMA == LMA).") ASSERT(LOADADDR(.dtcm_data) % 16 == 0, ".dtcm_data section must be aligned to 16 bytes.") ASSERT(SIZEOF(.dtcm_data) % 8 == 0, ".dtcm_data section size must be a multiple of 8 bytes.") ASSERT(LOADADDR(.dtcm_bss) % 8 == 0, ".dtcm_bss section must be aligned to 8 bytes.") ASSERT(SIZEOF(.dtcm_bss) % 8 == 0, ".dtcm_bss section size must be a multiple of 8 bytes.") ASSERT(__dtcm_bss_start == __dtcm_data_end, ".dtcm_bss section is not adjacent to .dtcm_data section.") /* Restore location counter. */ /* If DTCM is not present, this will be the address stored in '.' before ALIGN was attempted. */ /* If DTCM is present, this will be the absolute address that follows the DTCM ROM location. */ . = (SIZEOF(.dtcm_data) > 0) ? __dtcm_data_init_end : __dtcm_data_pre_location; /* TrustZone Secure Gateway Stubs Section */ /* Store location counter for SPI non-retentive sections. */ sgstubs_pre_location = .; /* Determine the secure gateway stubs address either by the provided linker variable or the next 1024-byte block. */ SGSTUBS_LOC = (DEFINED(PROJECT_SECURE) && DEFINED(FLASH_NSC_START)) ? ABSOLUTE(FLASH_NSC_START) : ALIGN(1024); .gnu.sgstubs SGSTUBS_LOC : ALIGN(1024) { __tz_FLASH_C = DEFINED(FLASH_NSC_START) ? ABSOLUTE(FLASH_NSC_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : ALIGN(1024); _start_sg = .; *(.gnu.sgstubs*) . = ALIGN(32); _end_sg = .; } > FLASH __tz_FLASH_N = DEFINED(FLASH_NS_START) ? ABSOLUTE(FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(FLASH_START + FLASH_LENGTH) : FLASH_LENGTH < 32768 ? FLASH_LENGTH : ALIGN(32768); FLASH_NS_IMAGE_START = DEFINED(FLASH_NS_IMAGE_START) ? FLASH_NS_IMAGE_START : __tz_FLASH_N; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_S = ORIGIN(QSPI_FLASH); /* QSPI_FLASH section to be downloaded via debugger */ .qspi_flash : { __qspi_flash_start__ = .; KEEP(*(.qspi_flash*)) KEEP(*(.code_in_qspi*)) __qspi_flash_end__ = .; } > QSPI_FLASH __qspi_flash_code_size__ = __qspi_flash_end__ - __qspi_flash_start__; /* QSPI_FLASH non-retentive section, creates a copy in internal flash that can be copied to QSPI */ __qspi_flash_code_addr__ = sgstubs_pre_location; .qspi_non_retentive : AT(__qspi_flash_code_addr__) { __qspi_non_retentive_start__ = .; KEEP(*(.qspi_non_retentive*)) __qspi_non_retentive_end__ = .; } > QSPI_FLASH __qspi_non_retentive_size__ = __qspi_non_retentive_end__ - __qspi_non_retentive_start__; __qspi_region_max_size__ = 0x4000000; /* Must be the same as defined in MEMORY above */ __qspi_region_start_address__ = __qspi_flash_start__; __qspi_region_end_address__ = __qspi_flash_start__ + __qspi_region_max_size__; /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_QSPI_FLASH_N = __qspi_non_retentive_end__; /* Support for OctaRAM */ .OSPI_DEVICE_0_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_0_start__ = .; *(.ospi_device_0_no_load*) . = ALIGN(4); __ospi_device_0_end__ = .; } > OSPI_DEVICE_0_RAM .OSPI_DEVICE_1_NO_LOAD (NOLOAD): { . = ALIGN(4); __ospi_device_1_start__ = .; *(.ospi_device_1_no_load*) . = ALIGN(4); __ospi_device_1_end__ = .; } > OSPI_DEVICE_1_RAM /* Note: There are no secure/non-secure boundaries for QSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_S = ORIGIN(OSPI_DEVICE_0); /* OSPI_DEVICE_0 section to be downloaded via debugger */ .OSPI_DEVICE_0 : { __ospi_device_0_start__ = .; KEEP(*(.ospi_device_0*)) KEEP(*(.code_in_ospi_device_0*)) __ospi_device_0_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_code_size__ = __ospi_device_0_end__ - __ospi_device_0_start__; /* OSPI_DEVICE_0 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_0_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive)); .ospi_device_0_non_retentive : AT(__ospi_device_0_code_addr__) { __ospi_device_0_non_retentive_start__ = .; KEEP(*(.ospi_device_0_non_retentive*)) __ospi_device_0_non_retentive_end__ = .; } > OSPI_DEVICE_0 __ospi_device_0_non_retentive_size__ = __ospi_device_0_non_retentive_end__ - __ospi_device_0_non_retentive_start__; __ospi_device_0_region_max_size__ = 0x8000000; /* Must be the same as defined in MEMORY above */ __ospi_device_0_region_start_address__ = __ospi_device_0_start__; __ospi_device_0_region_end_address__ = __ospi_device_0_start__ + __ospi_device_0_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_0_N = __ospi_device_0_non_retentive_end__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_S = ORIGIN(OSPI_DEVICE_1); /* OSPI_DEVICE_1 section to be downloaded via debugger */ .OSPI_DEVICE_1 : { __ospi_device_1_start__ = .; KEEP(*(.ospi_device_1*)) KEEP(*(.code_in_ospi_device_1*)) __ospi_device_1_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_code_size__ = __ospi_device_1_end__ - __ospi_device_1_start__; /* OSPI_DEVICE_1 non-retentive section, creates a copy in internal flash that can be copied to OSPI */ __ospi_device_1_code_addr__ = sgstubs_pre_location + (SIZEOF(.qspi_non_retentive) + SIZEOF(.ospi_device_0_non_retentive)); .ospi_device_1_non_retentive : AT(__ospi_device_1_code_addr__) { __ospi_device_1_non_retentive_start__ = .; KEEP(*(.ospi_device_1_non_retentive*)) __ospi_device_1_non_retentive_end__ = .; } > OSPI_DEVICE_1 __ospi_device_1_non_retentive_size__ = __ospi_device_1_non_retentive_end__ - __ospi_device_1_non_retentive_start__; __ospi_device_1_region_max_size__ = 0x10000000; /* Must be the same as defined in MEMORY above */ __ospi_device_1_region_start_address__ = __ospi_device_1_start__; __ospi_device_1_region_end_address__ = __ospi_device_1_start__ + __ospi_device_1_region_max_size__; /* Note: There are no secure/non-secure boundaries for OSPI. These symbols are provided for the RA configuration tool. */ __tz_OSPI_DEVICE_1_N = __ospi_device_1_non_retentive_end__; .noinit (NOLOAD): { . = ALIGN(4); __noinit_start = .; KEEP(*(.noinit*)) . = ALIGN(8); /* Place the FreeRTOS heap here so that the __HeapLimit calculation does not include the freertos heap. */ KEEP(*(.heap.*)) __noinit_end = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .heap (NOLOAD): { . = ALIGN(8); __HeapBase = .; /* Place the STD heap here. */ KEEP(*(.heap)) __HeapLimit = .; } > RAM /* Stacks are stored in this section. */ .stack_dummy (NOLOAD): { . = ALIGN(8); __StackLimit = .; /* Main stack */ KEEP(*(.stack)) __StackTop = .; /* Thread stacks */ KEEP(*(.stack*)) __StackTopAll = .; } > RAM PROVIDE(__stack = __StackTopAll); /* This symbol represents the end of user allocated RAM. The RAM after this symbol can be used at run time for things such as ThreadX memory pool allocations. */ __RAM_segment_used_end__ = ALIGN(__StackTopAll , 4); /* RAM_NSC_START can be used to set a fixed address for non-secure callable RAM in secure projects. * If it is not specified, the address for NSC RAM is the end of RAM aligned to a 1K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_C = DEFINED(RAM_NSC_START) ? ABSOLUTE(RAM_NSC_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__RAM_segment_used_end__, 1024); /* RAM_NS_START can be used to set a fixed address for non-secure RAM in secure projects or flat projects. * RAM_NS_BUFFER_BLOCK_LENGTH is used to allocate non-secure buffers in a flat project. If it is not * specified, the address for NSC RAM is the end of RAM aligned to an 8K boundary. * In flat projects that require non-secure RAM, this variable is set to the start of non-secure RAM. */ __tz_RAM_N = DEFINED(RAM_NS_START) ? ABSOLUTE(RAM_NS_START - RAM_NS_BUFFER_BLOCK_LENGTH) : __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_BLOCK_START) : ALIGN(__tz_RAM_C, 8192); /* Non-secure buffers must be in non-secure RAM. This is primarily used for the EDMAC in flat projects. * The EDMAC is a non-secure bus master and can only access non-secure RAM. */ .ns_buffer (NOLOAD): { /* Allocate RAM on a 32-byte boundary to help with placement of Ethernet buffers. */ . = __RESERVE_NS_RAM ? ABSOLUTE(RAM_NS_BUFFER_START & 0xFFFFFFE0) : .; KEEP(*(.ns_buffer*)) } > RAM /* Data flash. */ .data_flash : { . = ORIGIN(DATA_FLASH); __tz_DATA_FLASH_S = .; __Data_Flash_Start = .; KEEP(*(.data_flash*)) __Data_Flash_End = .; __tz_DATA_FLASH_N = DEFINED(DATA_FLASH_NS_START) ? ABSOLUTE(DATA_FLASH_NS_START) : __RESERVE_NS_RAM ? ABSOLUTE(DATA_FLASH_START + DATA_FLASH_LENGTH) : ALIGN(1024); } > DATA_FLASH /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_S = ORIGIN(SDRAM); /* SDRAM */ .sdram (NOLOAD): { __SDRAM_Start = .; KEEP(*(.sdram*)) KEEP(*(.frame*)) __SDRAM_End = .; } > SDRAM /* Note: There are no secure/non-secure boundaries for SDRAM. These symbols are provided for the RA configuration tool. */ __tz_SDRAM_N = __SDRAM_End; /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. */ __tz_ID_CODE_S = ORIGIN(ID_CODE); /* Note: There are no secure/non-secure boundaries for ID_CODE. These symbols are provided for the RA configuration tool. * Set this symbol to the same value as __tz_ID_CODE_S so the RA configuration tool does not split the ID_CODE * memory region between TrustZone projects. */ __tz_ID_CODE_N = __tz_ID_CODE_S; .id_code : { __ID_Code_Start = .; KEEP(*(.id_code*)) __ID_Code_End = .; } > ID_CODE /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S = ORIGIN(OPTION_SETTING_OFS); .option_setting_ofs : { __OPTION_SETTING_OFS_Start = .; KEEP(*(.option_setting_ofs0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x04 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_ofs2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_OFS_Start + 0x10 : __OPTION_SETTING_OFS_Start; KEEP(*(.option_setting_dualsel)) __OPTION_SETTING_OFS_End = .; } > OPTION_SETTING_OFS = 0xFF .option_setting_sas : { __OPTION_SETTING_SAS_Start = .; KEEP(*(.option_setting_sas)) __OPTION_SETTING_SAS_End = .; } > OPTION_SETTING_SAS = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_N = ABSOLUTE(OPTION_SETTING_START_NS); .option_setting_ns : { __OPTION_SETTING_NS_Start = .; KEEP(*(.option_setting_ofs1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x04 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_ofs3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x10 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_banksel)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x40 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x44 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x48 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x4C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_bps3)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x60 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps0)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x64 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps1)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x68 : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps2)) . = USE_OPTION_SETTING_NS ? __OPTION_SETTING_NS_Start + 0x6C : __OPTION_SETTING_NS_Start; KEEP(*(.option_setting_pbps3)) __OPTION_SETTING_NS_End = .; } > OPTION_SETTING = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_S = ORIGIN(OPTION_SETTING_S); .option_setting_s : { __OPTION_SETTING_S_Start = .; KEEP(*(.option_setting_ofs1_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x04 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x10 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sec)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x40 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x44 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x48 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x4C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x60 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x64 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x68 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x6C : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_pbps_sec3)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x80 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs1_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x84 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_ofs3_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0x90 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_banksel_sel)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC0 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel0)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC4 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel1)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xC8 : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel2)) . = PROJECT_SECURE_OR_FLAT ? __OPTION_SETTING_S_Start + 0xCC : __OPTION_SETTING_S_Start; KEEP(*(.option_setting_bps_sel3)) __OPTION_SETTING_S_End = .; } > OPTION_SETTING_S = 0xFF /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_S_N = __OPTION_SETTING_S_End; } ================================================ FILE: hw/bsp/ra/boards/uno_r4/script/memory_regions.ld ================================================ /* generated memory regions file - do not edit */ RAM_START = 0x20000000; RAM_LENGTH = 0x8000; FLASH_START = 0x00000000; FLASH_LENGTH = 0x40000; DATA_FLASH_START = 0x40100000; DATA_FLASH_LENGTH = 0x2000; OPTION_SETTING_START = 0x00000000; OPTION_SETTING_LENGTH = 0x0; OPTION_SETTING_S_START = 0x80000000; OPTION_SETTING_S_LENGTH = 0x0; ID_CODE_START = 0x01010018; ID_CODE_LENGTH = 0x20; SDRAM_START = 0x80010000; SDRAM_LENGTH = 0x0; QSPI_FLASH_START = 0x60000000; QSPI_FLASH_LENGTH = 0x0; OSPI_DEVICE_0_START = 0x80020000; OSPI_DEVICE_0_LENGTH = 0x0; OSPI_DEVICE_1_START = 0x80030000; OSPI_DEVICE_1_LENGTH = 0x0; /* Uno R4 has bootloader */ FLASH_IMAGE_START = 0x4000; ================================================ FILE: hw/bsp/ra/boards/uno_r4/smart_configurator/configuration.xml ================================================ Board Support Package Common Files Renesas.RA.5.6.0.pack I/O Port Renesas.RA.5.6.0.pack Arm CMSIS Version 6 - Core (M) Arm.CMSIS6.6.1.0+fsp.5.6.0.pack Custom Board Support Files Renesas.RA_board_custom.5.6.0.pack Board support package for R7FA4M1AB3CNE Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 - FSP Data Renesas.RA_mcu_ra4m1.5.6.0.pack Board support package for RA4M1 - Events Renesas.RA_mcu_ra4m1.5.6.0.pack ================================================ FILE: hw/bsp/ra/debug.jlinkscript ================================================ int SetupTarget(void) { JLINK_ExecCommand("SetRTTSearchRanges 0x20000000 0x80000"); return 0; } ================================================ FILE: hw/bsp/ra/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Rafael Silva * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Renesas */ #include #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #pragma GCC diagnostic ignored "-Wundef" #endif #include "common_data.h" #include "renesas.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" /* Key code for writing PRCR register. */ #define BSP_PRV_PRCR_KEY (0xA500U) //--------------------------------------------------------------------+ // Vector Data //--------------------------------------------------------------------+ BSP_DONT_REMOVE BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = usbfs_interrupt_handler, /* USBFS INT (USBFS interrupt) */ [1] = usbfs_resume_handler, /* USBFS RESUME (USBFS resume interrupt) */ #ifndef BSP_MCU_GROUP_RA2A1 [2] = usbfs_d0fifo_handler, /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = usbfs_d1fifo_handler, /* USBFS FIFO 1 (DMA transfer request 1) */ #endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = usbhs_interrupt_handler, /* USBHS INT (USBHS interrupt) */ [5] = usbhs_d0fifo_handler, /* USBHS FIFO 0 (DMA transfer request 0) */ [6] = usbhs_d1fifo_handler, /* USBHS FIFO 1 (DMA transfer request 1) */ #endif }; const bsp_interrupt_event_t g_interrupt_event_link_select[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = BSP_PRV_IELS_ENUM(EVENT_USBFS_INT), /* USBFS INT (USBFS interrupt) */ [1] = BSP_PRV_IELS_ENUM(EVENT_USBFS_RESUME), /* USBFS RESUME (USBFS resume interrupt) */ #ifndef BSP_MCU_GROUP_RA2A1 [2] = BSP_PRV_IELS_ENUM(EVENT_USBFS_FIFO_0), /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = BSP_PRV_IELS_ENUM(EVENT_USBFS_FIFO_1), /* USBFS FIFO 1 (DMA transfer request 1) */ #endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = BSP_PRV_IELS_ENUM(EVENT_USBHS_USB_INT_RESUME), /* USBHS USB INT RESUME (USBHS interrupt) */ [5] = BSP_PRV_IELS_ENUM(EVENT_USBHS_FIFO_0), /* USBHS FIFO 0 (DMA transfer request 0) */ [6] = BSP_PRV_IELS_ENUM(EVENT_USBHS_FIFO_1), /* USBHS FIFO 1 (DMA transfer request 1) */ #endif }; //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_init(void) { // Enable global interrupts in CPSR register since board with bootloader such as Arduino Uno R4 // can transfer CPU control with CPSR.I bit set to 0 (disable IRQ) __enable_irq(); /* Configure pins. */ R_IOPORT_Open(&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME); #ifdef TRACE_ETM // TRCKCR is protected by PRCR bit0 register R_SYSTEM->PRCR = (uint16_t) (BSP_PRV_PRCR_KEY | 0x01); // Enable trace clock (max 100Mhz). Since PLL/CPU is 200Mhz, clock div = 2 R_SYSTEM->TRCKCR = R_SYSTEM_TRCKCR_TRCKEN_Msk | 0x01; R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_KEY; #endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USBFS_INT_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USBFS_RESUME_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USBFS_FIFO_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USBFS_FIFO_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif board_led_write(false); } void board_init_after_tusb(void) { // For board that use USB LDO regulator #if defined(BOARD_UNO_R4) R_USB_FS0->USBMC |= R_USB_FS0_USBMC_VDCEN_Msk; #endif } void board_led_write(bool state) { R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, LED1, state ? LED_STATE_ON : !LED_STATE_ON); } uint32_t board_button_read(void) { bsp_io_level_t lvl = !BUTTON_STATE_ACTIVE; R_IOPORT_PinRead(&IOPORT_CFG_CTRL, SW1, &lvl); return lvl == BUTTON_STATE_ACTIVE; } size_t board_get_unique_id(uint8_t id[], size_t max_len) { max_len = tu_min32(max_len, sizeof(bsp_unique_id_t)); bsp_unique_id_t const *uid = R_BSP_UniqueIdGet(); memcpy(id, uid->unique_id_bytes, max_len); return max_len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ //------------- USB0 FullSpeed -------------// void usbfs_interrupt_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); tusb_int_handler(0, true); } void usbfs_resume_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); tusb_int_handler(0, true); } void usbfs_d0fifo_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); // TODO not used yet } void usbfs_d1fifo_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); // TODO not used yet } //------------- USB1 HighSpeed -------------// #ifdef BOARD_HAS_USB_HIGHSPEED void usbhs_interrupt_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); tusb_int_handler(1, true); } void usbhs_d0fifo_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); // TODO not used yet } void usbhs_d1fifo_handler(void) { IRQn_Type irq = R_FSP_CurrentIrqGet(); R_BSP_IrqStatusClear(irq); // TODO not used yet } #endif //--------------------------------------------------------------------+ // stdlib //--------------------------------------------------------------------+ int close(int fd) { (void) fd; return -1; } int fstat(int fd, void *pstat) { (void) fd; (void) pstat; return 0; } off_t lseek(int fd, off_t pos, int whence) { (void) fd; (void) pos; (void) whence; return 0; } int isatty(int fd) { (void) fd; return 1; } ================================================ FILE: hw/bsp/ra/family.cmake ================================================ include_guard() if (NOT BOARD) message(FATAL_ERROR "BOARD not specified") endif () set(CMSIS_DIR ${TOP}/lib/CMSIS_6) set(FSP_RA ${TOP}/hw/mcu/renesas/fsp/ra/fsp) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) #set(FREERTOS_PORT A_CUSTOM_PORT CACHE INTERNAL "") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS RAXXX ${MCU_VARIANT} CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/script/fsp.ld) endif () #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${FSP_RA}/src/bsp/cmsis/Device/RENESAS/Source/startup.c ${FSP_RA}/src/bsp/cmsis/Device/RENESAS/Source/system.c ${FSP_RA}/src/bsp/mcu/all/bsp_clocks.c ${FSP_RA}/src/bsp/mcu/all/bsp_common.c ${FSP_RA}/src/bsp/mcu/all/bsp_delay.c ${FSP_RA}/src/bsp/mcu/all/bsp_group_irq.c ${FSP_RA}/src/bsp/mcu/all/bsp_guard.c ${FSP_RA}/src/bsp/mcu/all/bsp_io.c ${FSP_RA}/src/bsp/mcu/all/bsp_irq.c ${FSP_RA}/src/bsp/mcu/all/bsp_register_protection.c ${FSP_RA}/src/bsp/mcu/all/bsp_sbrk.c ${FSP_RA}/src/bsp/mcu/all/bsp_security.c ${FSP_RA}/src/r_ioport/r_ioport.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/ra_gen/common_data.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/ra_gen/pin_data.c ) target_compile_options(${BOARD_TARGET} PUBLIC -ffreestanding ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/ra_cfg/fsp_cfg ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/ra_cfg/fsp_cfg/bsp ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/ra_gen ${CMSIS_DIR}/CMSIS/Core/Include ${FSP_RA}/inc ${FSP_RA}/inc/api ${FSP_RA}/inc/instances ${FSP_RA}/src/bsp/cmsis/Device/RENESAS/Include ${FSP_RA}/src/bsp/mcu/all ${FSP_RA}/src/bsp/mcu/${MCU_VARIANT} ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_RAXXX) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${FSP_RA}/src/bsp/mcu/all/bsp_rom_registers.c ${TOP}/src/portable/renesas/rusb2/dcd_rusb2.c ${TOP}/src/portable/renesas/rusb2/hcd_rusb2.c ${TOP}/src/portable/renesas/rusb2/rusb2_common.c ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC # linker file "LINKER:--script=${LD_FILE_GNU}" -L${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/script -Wl,--defsym=end=__bss_end__ -nostartfiles --specs=nano.specs --specs=nosys.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${FSP_RA}/src/bsp/mcu/all/bsp_rom_registers.c PROPERTIES COMPILE_FLAGS "-Wno-undef") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () # Flashing family_flash_jlink(${TARGET}) family_add_bin_hex(${TARGET}) if (DEFINED DFU_UTIL_VID_PID) family_flash_dfu_util(${TARGET} ${DFU_UTIL_VID_PID}) endif () endfunction() ================================================ FILE: hw/bsp/ra/family.mk ================================================ FSP_RA = hw/mcu/renesas/fsp/ra/fsp include $(TOP)/$(BOARD_PATH)/board.mk # Don't include options setting in .bin file since it create unnecessary large file due to padding OBJCOPY_BIN_OPTION = --only-section .text --only-section .data --only-section .rodata --only-section .bss # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 # Determine RHPORT_DEVICE_SPEED if not defined ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # Determine RHPORT_HOST_SPEED if not defined ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_RAXXX \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} CFLAGS_GCC += \ -flto \ -Wno-error=undef \ -Wno-error=strict-prototypes \ -Wno-error=cast-align \ -Wno-error=cast-qual \ -Wno-error=unused-but-set-variable \ -Wno-error=unused-variable \ -ffreestanding LDFLAGS_GCC += \ -nostartfiles -nostdlib \ -specs=nosys.specs -specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/renesas/rusb2/dcd_rusb2.c \ src/portable/renesas/rusb2/hcd_rusb2.c \ src/portable/renesas/rusb2/rusb2_common.c \ ${BOARD_PATH}/ra_gen/common_data.c \ ${BOARD_PATH}/ra_gen/pin_data.c \ $(FSP_RA)/src/bsp/cmsis/Device/RENESAS/Source/startup.c \ $(FSP_RA)/src/bsp/cmsis/Device/RENESAS/Source/system.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_clocks.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_common.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_delay.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_group_irq.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_guard.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_io.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_irq.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_register_protection.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_rom_registers.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_sbrk.c \ $(FSP_RA)/src/bsp/mcu/all/bsp_security.c \ $(FSP_RA)/src/r_ioport/r_ioport.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(BOARD_PATH)/ra_cfg/fsp_cfg \ $(TOP)/$(BOARD_PATH)/ra_cfg/fsp_cfg/bsp \ $(TOP)/$(BOARD_PATH)/ra_gen \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(FSP_RA)/src/bsp/cmsis/Device/RENESAS/Include \ $(TOP)/$(FSP_RA)/inc \ $(TOP)/$(FSP_RA)/inc/api \ $(TOP)/$(FSP_RA)/inc/instances \ $(TOP)/$(FSP_RA)/src/bsp/mcu/all \ $(TOP)/$(FSP_RA)/src/bsp/mcu/$(MCU_VARIANT) \ ifndef LD_FILE LD_FILE = $(BOARD_PATH)/script/fsp.ld endif LDFLAGS += -L$(TOP)/$(BOARD_PATH)/script LDFLAGS += -Wl,--defsym=end=__bss_end__ # For freeRTOS port source # hack to use the port provided by renesas FREERTOS_PORTABLE_SRC = $(FSP_RA)/src/rm_freertos_port ================================================ FILE: hw/bsp/ra/vector_data.h ================================================ /* vector numbers are configurable/dynamic, hence this, it will be used inside the port */ #ifndef VECTOR_DATA_H #define VECTOR_DATA_H #ifdef __cplusplus extern "C" { #endif #if defined(BSP_MCU_GROUP_RA6M5) || defined(BSP_MCU_GROUP_RA6M3) || (BSP_CFG_MCU_PART_SERIES == 8) #define BOARD_HAS_USB_HIGHSPEED #endif /* ISR prototypes */ void usbfs_interrupt_handler(void); void usbfs_resume_handler(void); #ifndef BSP_MCU_GROUP_RA2A1 void usbfs_d0fifo_handler(void); void usbfs_d1fifo_handler(void); #endif #ifdef BOARD_HAS_USB_HIGHSPEED void usbhs_interrupt_handler(void); void usbhs_d0fifo_handler(void); void usbhs_d1fifo_handler(void); #endif /* Vector table allocations */ #define USBFS_INT_IRQn 0 #define USBFS_RESUME_IRQn 1 #define USBFS_FIFO_0_IRQn 2 #define USBFS_FIFO_1_IRQn 3 #define USBHS_USB_INT_RESUME_IRQn 4 /* USBHS USB INT RESUME (USBHS interrupt) */ #define USBHS_FIFO_0_IRQn 5 /* USBHS FIFO 0 (DMA transfer request 0) */ #define USBHS_FIFO_1_IRQn 6 /* USBHS FIFO 1 (DMA transfer request 1) */ #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/adafruit_feather_rp2040_usb_host/board.cmake ================================================ set(PICO_PLATFORM rp2040) set(PICO_BOARD adafruit_feather_rp2040_usb_host) set(CFG_TUH_RPI_PIO_USB 1) ================================================ FILE: hw/bsp/rp2040/boards/adafruit_feather_rp2040_usb_host/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather RP2040 with USB Type A Host url: https://www.adafruit.com/product/5723 */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ #define PICO_DEFAULT_PIO_USB_DP_PIN 16 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 18 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef PICO_DEFAULT_SPI #define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 #else #define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 #endif #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/adafruit_fruit_jam/adafruit_fruit_jam.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef BOARDS_ADAFRUIT_FRUIT_JAM_H #define BOARDS_ADAFRUIT_FRUIT_JAM_H // required for board that is not part of pico-sdk // ----------------------------------------------------- // NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- // pico_cmake_set PICO_PLATFORM=rp2350 // On some samples, the xosc can take longer to stabilize than is usual #ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 #endif // For board detection #define ADAFRUIT_FRUIT_JAM // --- RP2350 VARIANT --- #define PICO_RP2350A 0 // --- UART --- #ifndef PICO_DEFAULT_UART #define PICO_DEFAULT_UART 1 #endif #ifndef PICO_DEFAULT_UART_TX_PIN #define PICO_DEFAULT_UART_TX_PIN 8 #endif #ifndef PICO_DEFAULT_UART_RX_PIN #define PICO_DEFAULT_UART_RX_PIN 9 #endif // --- LED --- #ifndef PICO_DEFAULT_LED_PIN #define PICO_DEFAULT_LED_PIN 29 #endif #ifndef PICO_DEFAULT_WS2812_PIN #define PICO_DEFAULT_WS2812_PIN 32 #endif // --- I2C --- #ifndef PICO_DEFAULT_I2C #define PICO_DEFAULT_I2C 0 #endif #ifndef PICO_DEFAULT_I2C_SDA_PIN #define PICO_DEFAULT_I2C_SDA_PIN 20 #endif #ifndef PICO_DEFAULT_I2C_SCL_PIN #define PICO_DEFAULT_I2C_SCL_PIN 21 #endif // --- SPI --- #ifndef PICO_DEFAULT_SPI #define PICO_DEFAULT_SPI 1 #endif #ifndef PICO_DEFAULT_SPI_SCK_PIN #define PICO_DEFAULT_SPI_SCK_PIN 30 #endif #ifndef PICO_DEFAULT_SPI_TX_PIN #define PICO_DEFAULT_SPI_TX_PIN 31 #endif #ifndef PICO_DEFAULT_SPI_RX_PIN #define PICO_DEFAULT_SPI_RX_PIN 28 #endif // --- FLASH --- // FruitJam use w25q128 but sdk does not have .s for it, use q080 instead #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif // pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif // pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/adafruit_fruit_jam/board.cmake ================================================ set(PICO_PLATFORM rp2350-arm-s) set(PICO_BOARD adafruit_fruit_jam) set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR}) #set(OPENOCD_SERIAL E6614103E78E8324) set(CFG_TUH_RPI_PIO_USB 1) ================================================ FILE: hw/bsp/rp2040/boards/adafruit_fruit_jam/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Fruit Jam - Mini RP2350 url: https://www.adafruit.com/product/6200 */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ // default to pico brain tester #define PICO_DEFAULT_PIO_USB_DP_PIN 1 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 11 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/adafruit_metro_rp2350/adafruit_metro_rp2350.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef BOARDS_ADAFRUIT_METRO_RP2350_H #define BOARDS_ADAFRUIT_METRO_RP2350_H // required for board that is not part of pico-sdk // ----------------------------------------------------- // NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- // pico_cmake_set PICO_PLATFORM=rp2350 // On some samples, the xosc can take longer to stabilize than is usual #ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 #endif // For board detection #define ADAFRUIT_METRO_RP2350 // --- RP2350 VARIANT --- #define PICO_RP2350A 0 // --- UART --- #ifndef PICO_DEFAULT_UART #define PICO_DEFAULT_UART 0 #endif #ifndef PICO_DEFAULT_UART_TX_PIN #define PICO_DEFAULT_UART_TX_PIN 0 #endif #ifndef PICO_DEFAULT_UART_RX_PIN #define PICO_DEFAULT_UART_RX_PIN 1 #endif // --- LED --- #ifndef PICO_DEFAULT_LED_PIN #define PICO_DEFAULT_LED_PIN 23 #endif #ifndef PICO_DEFAULT_WS2812_PIN #define PICO_DEFAULT_WS2812_PIN 25 #endif // --- I2C --- #ifndef PICO_DEFAULT_I2C #define PICO_DEFAULT_I2C 0 #endif #ifndef PICO_DEFAULT_I2C_SDA_PIN #define PICO_DEFAULT_I2C_SDA_PIN 20 #endif #ifndef PICO_DEFAULT_I2C_SCL_PIN #define PICO_DEFAULT_I2C_SCL_PIN 21 #endif // --- SPI --- #ifndef PICO_DEFAULT_SPI #define PICO_DEFAULT_SPI 1 #endif #ifndef PICO_DEFAULT_SPI_SCK_PIN #define PICO_DEFAULT_SPI_SCK_PIN 30 #endif #ifndef PICO_DEFAULT_SPI_TX_PIN #define PICO_DEFAULT_SPI_TX_PIN 31 #endif #ifndef PICO_DEFAULT_SPI_RX_PIN #define PICO_DEFAULT_SPI_RX_PIN 28 #endif // --- FLASH --- // FruitJam use w25q128 but sdk does not have .s for it, use q080 instead #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif // pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif // pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/adafruit_metro_rp2350/board.cmake ================================================ set(PICO_PLATFORM rp2350-arm-s) set(PICO_BOARD adafruit_metro_rp2350) set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR}) #set(OPENOCD_SERIAL E6614103E78E8324) set(CFG_TUH_RPI_PIO_USB 1) ================================================ FILE: hw/bsp/rp2040/boards/adafruit_metro_rp2350/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Metro RP2350 url: https://www.adafruit.com/product/6003 */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ // default to pico brain tester #define PICO_DEFAULT_PIO_USB_DP_PIN 32 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 29 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake ================================================ set(PICO_PLATFORM rp2040) set(PICO_BOARD adafruit_feather_rp2040) # Enable MAX3421E USB Host set(MAX3421_HOST 1) ================================================ FILE: hw/bsp/rp2040/boards/feather_rp2040_max3421/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ #define PICO_DEFAULT_PIO_USB_DP_PIN 16 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 18 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef PICO_DEFAULT_SPI #define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 #else #define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 #endif #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/pico_sdk/board.cmake ================================================ # This builds with settings based purely on the current PICO_BOARD set via the SDK ================================================ FILE: hw/bsp/rp2040/boards/pico_sdk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake ================================================ set(PICO_PLATFORM rp2040) set(PICO_BOARD pico) #set(OPENOCD_SERIAL E6614103E719612F) ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Pico url: https://www.raspberrypi.com/products/raspberry-pi-pico/ */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ // default to pico brain tester #define PICO_DEFAULT_PIO_USB_DP_PIN 20 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 22 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef PICO_DEFAULT_SPI #define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 #else #define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 #endif #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake ================================================ set(PICO_PLATFORM rp2350-arm-s) set(PICO_BOARD pico2) #set(OPENOCD_SERIAL E6614103E77C5A24) ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Pico2 url: https://www.raspberrypi.com/products/raspberry-pi-pico-2/ */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ // default to pico brain tester #define PICO_DEFAULT_PIO_USB_DP_PIN 20 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 22 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef PICO_DEFAULT_SPI #define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 #else #define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 #endif #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico_w/board.cmake ================================================ set(PICO_PLATFORM rp2040) set(PICO_BOARD pico_w) ================================================ FILE: hw/bsp/rp2040/boards/raspberry_pi_pico_w/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Pico url: https://www.raspberrypi.com/products/raspberry-pi-pico/ */ #ifndef TUSB_BOARD_H #define TUSB_BOARD_H #ifdef __cplusplus extern "C" { #endif // UART and LED are already defined in pico-sdk board //--------------------------------------------------------------------+ // PIO_USB //--------------------------------------------------------------------+ // default to pico brain tester #define PICO_DEFAULT_PIO_USB_DP_PIN 20 #define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 22 #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 //-------------------------------------------------------------------- // USB Host MAX3421E //-------------------------------------------------------------------- #ifdef PICO_DEFAULT_SPI #define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2 #else #define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1 #endif #define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN #define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN #define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN #define MAX3421_CS_PIN 10 #define MAX3421_INTR_PIN 9 #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/rp2040/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Raspberry Pi */ #include "pico/stdlib.h" #include "pico/binary_info.h" #include "pico/unique_id.h" #include "hardware/gpio.h" #include "hardware/sync.h" #include "hardware/resets.h" #include "hardware/clocks.h" #include "hardware/structs/ioqspi.h" #include "hardware/structs/sio.h" #include "bsp/board_api.h" #include "board.h" #if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB) #include "pio_usb.h" #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 #include "hardware/spi.h" static void max3421_init(void); #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // LED #if !defined(LED_PIN) && defined(PICO_DEFAULT_LED_PIN) #define LED_PIN PICO_DEFAULT_LED_PIN #define LED_STATE_ON (!(PICO_DEFAULT_LED_PIN_INVERTED)) #endif // Button, if not defined use BOOTSEL button #ifndef BUTTON_PIN #define BUTTON_BOOTSEL #define BUTTON_STATE_ACTIVE 0 #endif // UART #if !defined(UART_DEV) && defined(PICO_DEFAULT_UART) && defined(LIB_PICO_STDIO_UART) && \ defined(PICO_DEFAULT_UART_TX_PIN) && defined(PICO_DEFAULT_UART_RX_PIN) #define UART_DEV PICO_DEFAULT_UART #define UART_TX_PIN PICO_DEFAULT_UART_TX_PIN #define UART_RX_PIN PICO_DEFAULT_UART_RX_PIN #endif #ifdef UART_DEV static uart_inst_t *uart_inst; #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #ifdef BUTTON_BOOTSEL // This example blinks the Picoboard LED when the BOOTSEL button is pressed. // // Picoboard has a button attached to the flash CS pin, which the bootrom // checks, and jumps straight to the USB bootcode if the button is pressed // (pulling flash CS low). We can check this pin in by jumping to some code in // SRAM (so that the XIP interface is not required), floating the flash CS // pin, and observing whether it is pulled low. // // This doesn't work if others are trying to access flash at the same time, // e.g. XIP streamer, or the other core. static bool __no_inline_not_in_flash_func(get_bootsel_button)(void) { const uint CS_PIN_INDEX = 1; // Must disable interrupts, as interrupt handlers may be in flash, and we // are about to temporarily disable flash access! uint32_t flags = save_and_disable_interrupts(); // Set chip select to Hi-Z hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); // Note we can't call into any sleep functions in flash right now for (volatile int i = 0; i < 1000; ++i) { __nop(); } // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. // Note the button pulls the pin *low* when pressed. #ifdef __ARM_ARCH_6M__ // CM0 for rp2040 #define CS_BIT (1u << 1) #else // rp2350 (cm33/risv) #define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS #endif bool button_state = (sio_hw->gpio_hi_in & CS_BIT); // Need to restore the state of chip select, else we are going to have a // bad time when we return to code in flash! hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); restore_interrupts(flags); return button_state; } #endif //------------- Segger RTT retarget -------------// #if defined(LOGGER_RTT) // Logging with RTT // - If RTT Control Block is not found by 'Auto Detection` try to use 'Search Range` with '0x20000000 0x10000' // - SWD speed is rather slow around 1000Khz #include "pico/stdio/driver.h" #include "SEGGER_RTT.h" static void stdio_rtt_write (const char *buf, int length) { SEGGER_RTT_Write(0, buf, (unsigned) length); } static int stdio_rtt_read (char *buf, int len) { return (int) SEGGER_RTT_Read(0, buf, (unsigned) len); } static stdio_driver_t stdio_rtt = { .out_chars = stdio_rtt_write, .out_flush = NULL, .in_chars = stdio_rtt_read }; void stdio_rtt_init(void) { stdio_set_driver_enabled(&stdio_rtt, true); } #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void board_init(void) { #if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB) // Set the system clock to a multiple of 12mhz for bit-banging USB with pico-usb set_sys_clock_khz(120000, true); // set_sys_clock_khz(180000, true); // set_sys_clock_khz(192000, true); // set_sys_clock_khz(240000, true); // set_sys_clock_khz(264000, true); #ifdef PICO_DEFAULT_PIO_USB_VBUSEN_PIN gpio_init(PICO_DEFAULT_PIO_USB_VBUSEN_PIN); gpio_set_dir(PICO_DEFAULT_PIO_USB_VBUSEN_PIN, GPIO_OUT); gpio_put(PICO_DEFAULT_PIO_USB_VBUSEN_PIN, PICO_DEFAULT_PIO_USB_VBUSEN_STATE); #endif // rp2040 use pico-pio-usb for host tuh_configure() can be used to passed pio configuration to the host stack // Note: tuh_configure() must be called before tuh_init() pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG; pio_cfg.pin_dp = PICO_DEFAULT_PIO_USB_DP_PIN; tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); #endif #ifdef LED_PIN bi_decl(bi_1pin_with_name(LED_PIN, "LED")); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); #endif // Button #ifndef BUTTON_BOOTSEL #endif #ifdef UART_DEV bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_RX_PIN, GPIO_FUNC_UART)); uart_inst = uart_get_instance(UART_DEV); stdio_uart_init_full(uart_inst, CFG_BOARD_UART_BAUDRATE, UART_TX_PIN, UART_RX_PIN); #endif #if defined(LOGGER_RTT) stdio_rtt_init(); #endif #if CFG_TUD_ENABLED // TODO probably set up device mode? #endif #if CFG_TUH_ENABLED #if CFG_TUH_MAX3421 max3421_init(); #endif #endif #if !CFG_TUD_ENABLED && !CFG_TUH_ENABLED // board test exxample, reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { (void) state; #ifdef LED_PIN gpio_put(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #endif } uint32_t board_button_read(void) { #ifdef BUTTON_BOOTSEL return BUTTON_STATE_ACTIVE == get_bootsel_button(); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { pico_unique_board_id_t pico_id; pico_get_unique_board_id(&pico_id); size_t len = PICO_UNIQUE_BOARD_ID_SIZE_BYTES; if (len > max_len) { len = max_len; } memcpy(id, pico_id.id, len); return len; } int board_uart_read(uint8_t *buf, int len) { #ifdef UART_DEV int count = 0; while ((count < len) && uart_is_readable(uart_inst)) { buf[count] = uart_getc(uart_inst); count++; } return count; #else (void) buf; (void) len; return 0; #endif } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV char const *bufch = (char const *) buf; for ( int i = 0; i < len; i++ ) { uart_putc(uart_inst, bufch[i]); } return len; #else (void) buf; (void) len; return 0; #endif } int board_getchar(void) { return getchar_timeout_us(0); } void board_putchar(int c) { stdio_putchar(c); } void board_init_after_tusb(void) { // nothing to do } void board_reset_to_bootloader(void) { // not implemented } //--------------------------------------------------------------------+ // USB Interrupt Handler // rp2040 implementation will install appropriate handler when initializing // tinyusb. There is no need to forward IRQ from application //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 void max3421_int_handler(uint gpio, uint32_t event_mask) { if (!(gpio == MAX3421_INTR_PIN && event_mask & GPIO_IRQ_EDGE_FALL)) { return; } tuh_int_handler(BOARD_TUH_RHPORT, true); } static void max3421_init(void) { // CS pin gpio_init(MAX3421_CS_PIN); gpio_set_dir(MAX3421_CS_PIN, GPIO_OUT); gpio_put(MAX3421_CS_PIN, true); // Interrupt pin gpio_init(MAX3421_INTR_PIN); gpio_set_dir(MAX3421_INTR_PIN, GPIO_IN); gpio_pull_up(MAX3421_INTR_PIN); gpio_set_irq_enabled_with_callback(MAX3421_INTR_PIN, GPIO_IRQ_EDGE_FALL, true, max3421_int_handler); // SPI init spi_init(MAX3421_SPI, 4*1000000ul); gpio_set_function(MAX3421_SCK_PIN, GPIO_FUNC_SPI); gpio_set_function(MAX3421_MOSI_PIN, GPIO_FUNC_SPI); gpio_set_function(MAX3421_MISO_PIN, GPIO_FUNC_SPI); #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnull-dereference" #endif spi_set_format(MAX3421_SPI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif } //// API to enable/disable MAX3421 INTR pin interrupt void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; irq_set_enabled(IO_IRQ_BANK0, enabled); } // API to control MAX3421 SPI CS void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; gpio_put(MAX3421_CS_PIN, !active); } // API to transfer data with MAX3421 SPI // Either tx_buf or rx_buf can be NULL, which means transfer is write or read only bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { (void) rhport; if (tx_buf == NULL && rx_buf == NULL) { return false; } int ret; if (tx_buf == NULL) { ret = spi_read_blocking(MAX3421_SPI, 0, rx_buf, xfer_bytes); }else if (rx_buf == NULL) { ret = spi_write_blocking(MAX3421_SPI, tx_buf, xfer_bytes); }else { ret = spi_write_read_blocking(MAX3421_SPI, tx_buf, rx_buf, xfer_bytes); } return ret == (int) xfer_bytes; } #endif ================================================ FILE: hw/bsp/rp2040/family.cmake ================================================ cmake_minimum_required(VERSION 3.13) include_guard(GLOBAL) if (NOT BOARD) message("BOARD not specified, defaulting to pico_sdk") set(BOARD pico_sdk) endif() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) #if (TOOLCHAIN STREQUAL "clang") # set(PICO_COMPILER "pico_arm_clang") #else() # set(PICO_COMPILER "pico_arm_gcc") #endif() # add the SDK in case we are standalone tinyusb example (noop if already present) include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake) # include basic family CMake functionality set(FAMILY_MCUS RP2040) if (PICO_PLATFORM STREQUAL "rp2040") set(JLINK_DEVICE rp2040_m0_0) set(OPENOCD_TARGET rp2040) elseif (PICO_PLATFORM STREQUAL "rp2350-arm-s" OR PICO_PLATFORM STREQUAL "rp2350") set(JLINK_DEVICE rp2350_m33_0) set(OPENOCD_TARGET rp2350) elseif (PICO_PLATFORM STREQUAL "rp2350-riscv") set(JLINK_DEVICE rp2350_riscv_0) set(OPENOCD_TARGET rp2350-riscv) endif() if (NOT OPENOCD_OPTION) set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/${OPENOCD_TARGET}.cfg -c \"adapter speed 5000\"") endif() if (NOT PICO_TINYUSB_PATH) set(PICO_TINYUSB_PATH ${TOP}) endif() if (NOT TINYUSB_OPT_OS) set(TINYUSB_OPT_OS OPT_OS_PICO) endif() #------------------------------------ # Base config for both device and host; wrapped by SDK's tinyusb_common #------------------------------------ add_library(tinyusb_common_base INTERFACE) target_sources(tinyusb_common_base INTERFACE ${TOP}/src/tusb.c ${TOP}/src/common/tusb_fifo.c ) target_include_directories(tinyusb_common_base INTERFACE ${TOP}/src ) if(DEFINED LOG) set(TINYUSB_DEBUG_LEVEL ${LOG}) elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") message("Compiling TinyUSB with CFG_TUSB_DEBUG=1") set(TINYUSB_DEBUG_LEVEL 1) else () set(TINYUSB_DEBUG_LEVEL 0) endif() target_compile_definitions(tinyusb_common_base INTERFACE CFG_TUSB_MCU=OPT_MCU_RP2040 CFG_TUSB_OS=${TINYUSB_OPT_OS} CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) if (CFG_TUH_RPI_PIO_USB) target_compile_definitions(tinyusb_common_base INTERFACE CFG_TUH_RPI_PIO_USB=1 ) endif() target_link_libraries(tinyusb_common_base INTERFACE hardware_structs hardware_irq hardware_resets pico_sync ) #------------------------------------ # Base config for device mode; wrapped by SDK's tinyusb_device #------------------------------------ add_library(tinyusb_device_base INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c ${TOP}/src/device/usbd.c ${TOP}/src/device/usbd_control.c ${TOP}/src/class/audio/audio_device.c ${TOP}/src/class/cdc/cdc_device.c ${TOP}/src/class/dfu/dfu_device.c ${TOP}/src/class/dfu/dfu_rt_device.c ${TOP}/src/class/hid/hid_device.c ${TOP}/src/class/midi/midi_device.c ${TOP}/src/class/msc/msc_device.c ${TOP}/src/class/mtp/mtp_device.c ${TOP}/src/class/net/ecm_rndis_device.c ${TOP}/src/class/net/ncm_device.c ${TOP}/src/class/printer/printer_device.c ${TOP}/src/class/usbtmc/usbtmc_device.c ${TOP}/src/class/vendor/vendor_device.c ${TOP}/src/class/video/video_device.c ) #------------------------------------ # Base config for host mode; wrapped by SDK's tinyusb_host #------------------------------------ add_library(tinyusb_host_base INTERFACE) target_sources(tinyusb_host_base INTERFACE ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c ${TOP}/src/host/usbh.c ${TOP}/src/host/hub.c ${TOP}/src/class/cdc/cdc_host.c ${TOP}/src/class/hid/hid_host.c ${TOP}/src/class/midi/midi_host.c ${TOP}/src/class/msc/msc_host.c ${TOP}/src/class/vendor/vendor_host.c ) # Sometimes have to do host specific actions in mostly common functions target_compile_definitions(tinyusb_host_base INTERFACE RP2040_USB_HOST_MODE=1 ) #------------------------------------ # Host MAX3421 #------------------------------------ add_library(tinyusb_host_max3421 INTERFACE) target_sources(tinyusb_host_max3421 INTERFACE ${TOP}/src/portable/analog/max3421/hcd_max3421.c ) target_compile_definitions(tinyusb_host_max3421 INTERFACE CFG_TUH_MAX3421=1 ) target_link_libraries(tinyusb_host_max3421 INTERFACE hardware_spi ) #------------------------------------ # BSP & Additions #------------------------------------ add_library(tinyusb_bsp INTERFACE) target_sources(tinyusb_bsp INTERFACE ${TOP}/hw/bsp/rp2040/family.c ) target_include_directories(tinyusb_bsp INTERFACE ${TOP}/hw ${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD} ) target_link_libraries(tinyusb_bsp INTERFACE pico_unique_id hardware_clocks ) # tinyusb_additions will hold our extra settings for examples add_library(tinyusb_additions INTERFACE) if (PICO_PLATFORM STREQUAL rp2040) target_compile_definitions(tinyusb_additions INTERFACE PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 ) endif () if(LOGGER STREQUAL "RTT" OR LOGGER STREQUAL "rtt") target_compile_definitions(tinyusb_additions INTERFACE LOGGER_RTT #SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ) target_sources(tinyusb_additions INTERFACE ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c ) set_source_files_properties(${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c PROPERTIES COMPILE_FLAGS "-Wno-cast-qual -Wno-cast-align -Wno-sign-conversion") target_include_directories(tinyusb_additions INTERFACE ${TOP}/lib/SEGGER_RTT/RTT ) endif() #------------------------------------ # Functions #------------------------------------ function(family_add_default_example_warnings TARGET) # Apply warnings to all TinyUSB interface library sources as well as examples sources # we cannot set compile options for target since it will not propagate to INTERFACE sources then picosdk files foreach(TINYUSB_TARGET IN ITEMS tinyusb_common_base tinyusb_device_base tinyusb_host_base tinyusb_host_max3421 tinyusb_bsp) get_target_property(TINYUSB_SOURCES ${TINYUSB_TARGET} INTERFACE_SOURCES) set_source_files_properties(${TINYUSB_SOURCES} PROPERTIES COMPILE_OPTIONS "${WARN_FLAGS_${CMAKE_C_COMPILER_ID}}") endforeach() # Also apply to example sources, but filter out any source files from lib/ (e.g. fatfs) get_target_property(EXAMPLE_SOURCES ${TARGET} SOURCES) set(FILTERED_SOURCES "") foreach(SOURCE_FILE IN LISTS EXAMPLE_SOURCES) string(FIND "${SOURCE_FILE}" "${TOP}/lib" FOUND_POS) if(FOUND_POS EQUAL -1) list(APPEND FILTERED_SOURCES ${SOURCE_FILE}) endif() endforeach() set_source_files_properties(${FILTERED_SOURCES} PROPERTIES COMPILE_OPTIONS "${WARN_FLAGS_${CMAKE_C_COMPILER_ID}}") if (CMAKE_C_COMPILER_ID STREQUAL "GNU") if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND NO_WARN_RWX_SEGMENTS_SUPPORTED) target_link_options(${TARGET} PRIVATE "LINKER:--no-warn-rwx-segments") endif() if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) target_compile_options(${TARGET} PRIVATE -Wconversion) endif() if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) target_compile_options(${TARGET} PRIVATE -Wcast-function-type -Wstrict-overflow) endif() if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) target_compile_options(${TARGET} PRIVATE -Wno-strict-aliasing) endif() endif() endfunction() # TODO merge with family_configure_common from family_support.cmake function(family_configure_target TARGET RTOS) if (RTOS STREQUAL noos OR RTOS STREQUAL "") set(RTOS_SUFFIX "") else() set(RTOS_SUFFIX _${RTOS}) endif() # export RTOS_SUFFIX to parent scope set(RTOS_SUFFIX ${RTOS_SUFFIX} PARENT_SCOPE) # compile define from command line if(DEFINED CFLAGS_CLI) separate_arguments(CFLAGS_CLI) target_compile_options(${TARGET} PUBLIC ${CFLAGS_CLI}) endif() pico_add_extra_outputs(${TARGET}) pico_enable_stdio_uart(${TARGET} 1) target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions) family_flash_openocd(${TARGET}) family_flash_jlink(${TARGET}) # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options family_add_bloaty(${TARGET}) family_add_linkermap(${TARGET}) family_add_membrowse(${TARGET}) endfunction() function(rp2040_family_configure_example_warnings TARGET) if (NOT PICO_TINYUSB_NO_EXAMPLE_WARNINGS) family_add_default_example_warnings(${TARGET}) endif() if(CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PRIVATE -Wno-unreachable-code) endif() suppress_tinyusb_warnings() endfunction() function(family_configure_device_example TARGET RTOS) family_configure_target(${TARGET} ${RTOS}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device${RTOS_SUFFIX}) rp2040_family_configure_example_warnings(${TARGET}) endfunction() function(family_add_pico_pio_usb TARGET) target_link_libraries(${TARGET} PUBLIC tinyusb_pico_pio_usb) endfunction() # since Pico-PIO_USB compiler support may lag, and change from version to version, add a function that pico-sdk/pico-examples # can check (if present) in case the user has updated their TinyUSB function(is_compiler_supported_by_pico_pio_usb OUTVAR) if ((NOT CMAKE_C_COMPILER_ID STREQUAL "GNU")) SET(${OUTVAR} 0 PARENT_SCOPE) else() set(${OUTVAR} 1 PARENT_SCOPE) endif() endfunction() function(family_configure_host_example TARGET RTOS) family_configure_target(${TARGET} ${RTOS}) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host${RTOS_SUFFIX}) rp2040_family_configure_example_warnings(${TARGET}) # For rp2040 enable pico-pio-usb if (TARGET tinyusb_pico_pio_usb) # Pico-PIO-USB does not compile with all pico-sdk supported compilers, so check before enabling it is_compiler_supported_by_pico_pio_usb(PICO_PIO_USB_COMPILER_SUPPORTED) if (PICO_PIO_USB_COMPILER_SUPPORTED) family_add_pico_pio_usb(${TARGET}) endif() endif() # for max3421 host if (MAX3421_HOST STREQUAL "1") target_link_libraries(${TARGET} PUBLIC tinyusb_host_max3421) endif() endfunction() function(family_configure_dual_usb_example TARGET RTOS) family_configure_target(${TARGET} ${RTOS}) # require tinyusb_pico_pio_usb target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_host tinyusb_pico_pio_usb ) rp2040_family_configure_example_warnings(${TARGET}) endfunction() function(check_and_add_pico_pio_usb_support) # check for pico_generate_pio_header (as depending on environment we may be called before SDK is # initialized in which case it isn't available yet), and only do the initialization once if (COMMAND pico_generate_pio_header AND NOT TARGET tinyusb_pico_pio_usb) #------------------------------------ # PIO USB for both host and device #------------------------------------ if (NOT DEFINED PICO_PIO_USB_PATH) set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB") endif() if (EXISTS ${PICO_PIO_USB_PATH}/src/pio_usb.c) add_library(tinyusb_pico_pio_usb INTERFACE) target_sources(tinyusb_device_base INTERFACE ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ) target_sources(tinyusb_host_base INTERFACE ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ) target_sources(tinyusb_pico_pio_usb INTERFACE ${PICO_PIO_USB_PATH}/src/pio_usb.c ${PICO_PIO_USB_PATH}/src/pio_usb_host.c ${PICO_PIO_USB_PATH}/src/pio_usb_device.c ${PICO_PIO_USB_PATH}/src/usb_crc.c ) target_include_directories(tinyusb_pico_pio_usb INTERFACE ${PICO_PIO_USB_PATH}/src ) target_link_libraries(tinyusb_pico_pio_usb INTERFACE hardware_dma hardware_pio pico_multicore ) target_compile_definitions(tinyusb_pico_pio_usb INTERFACE PIO_USB_USE_TINYUSB ) pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_tx.pio) pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_rx.pio) endif() endif() endfunction() # Try to add Pico-PIO_USB support now for the case where this file is included directly # after Pico SDK initialization, but without using the family_ functions (as is the case # when included by the SDK itself) check_and_add_pico_pio_usb_support() function(family_initialize_project PROJECT DIR) # call the original version of this function from family_common.cmake _family_initialize_project(${PROJECT} ${DIR}) enable_language(C CXX ASM) pico_sdk_init() # now re-check for adding Pico-PIO_USB support now SDK is definitely available check_and_add_pico_pio_usb_support() endfunction() # This method must be called from the project scope to suppress known warnings in TinyUSB source files function(suppress_tinyusb_warnings) # some of these are pretty silly warnings only occurring in some older GCC versions 9 or prior if (CMAKE_C_COMPILER_ID STREQUAL "GNU") if (CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) set(CONVERSION_WARNING_FILES ${PICO_TINYUSB_PATH}/src/tusb.c ${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c ${PICO_TINYUSB_PATH}/src/device/usbd.c ${PICO_TINYUSB_PATH}/src/device/usbd_control.c ${PICO_TINYUSB_PATH}/src/host/usbh.c ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_host.c ${PICO_TINYUSB_PATH}/src/class/hid/hid_device.c ${PICO_TINYUSB_PATH}/src/class/hid/hid_host.c ${PICO_TINYUSB_PATH}/src/class/audio/audio_device.c ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_device.c ${PICO_TINYUSB_PATH}/src/class/dfu/dfu_rt_device.c ${PICO_TINYUSB_PATH}/src/class/midi/midi_device.c ${PICO_TINYUSB_PATH}/src/class/usbtmc/usbtmc_device.c ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ) foreach(SOURCE_FILE IN LISTS CONVERSION_WARNING_FILES) set_source_files_properties(${SOURCE_FILE} PROPERTIES COMPILE_FLAGS "-Wno-conversion") endforeach() endif() if (TARGET tinyusb_pico_pio_usb) set_source_files_properties( ${PICO_TINYUSB_PATH}/hw/mcu/raspberry_pi/Pico-PIO-USB/src/pio_usb_device.c ${PICO_TINYUSB_PATH}/hw/mcu/raspberry_pi/Pico-PIO-USB/src/pio_usb.c ${PICO_TINYUSB_PATH}/hw/mcu/raspberry_pi/Pico-PIO-USB/src/pio_usb_host.c ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c PROPERTIES COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual -Wno-attributes") endif() elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties( ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c COMPILE_FLAGS "-Wno-unreachable-code") set_source_files_properties( ${PICO_TINYUSB_PATH}/src/class/cdc/cdc_host.c COMPILE_FLAGS "-Wno-unreachable-code-fallthrough") set_source_files_properties( ${PICO_TINYUSB_PATH}/lib/fatfs/source/ff.c PROPERTIES COMPILE_FLAGS "-Wno-cast-qual") endif() endfunction() ================================================ FILE: hw/bsp/rp2040/pico_sdk_import.cmake ================================================ # This is a copy of /external/pico_sdk_import.cmake # This can be dropped into an external project to help locate this SDK # It should be include()ed prior to project() if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") endif () if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") endif () if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") endif () set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT) include(FetchContent) set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) if (PICO_SDK_FETCH_FROM_GIT_PATH) get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") endif () FetchContent_Declare( pico_sdk GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk GIT_TAG master ) if (NOT pico_sdk) message("Downloading Raspberry Pi Pico SDK") FetchContent_Populate(pico_sdk) set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) endif () set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) else () message(FATAL_ERROR "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." ) endif () endif () get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") if (NOT EXISTS ${PICO_SDK_PATH}) message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") endif () set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") endif () set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) include(${PICO_SDK_INIT_CMAKE_FILE}) ================================================ FILE: hw/bsp/rp2040/rp2040-openocd.cfg ================================================ source [find interface/cmsis-dap.cfg] adapter speed 5000 source [find target/rp2040.cfg] ================================================ FILE: hw/bsp/rp2040/rp2350-openocd.cfg ================================================ source [find interface/cmsis-dap.cfg] adapter speed 5000 source [find target/rp2350.cfg] ================================================ FILE: hw/bsp/rw61x/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "fsl_device_registers.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 // RW61x has FPU but is disabled due to using cortex-m33-nodsp-nofp.mk #define configENABLE_TRUSTZONE 0 #define configRUN_FREERTOS_SECURE_ONLY 1 // Cortex-M33 runs in secure mode after reset by default! #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CAU_SLP_CTRL & PMU_CAU_SLP_CTRL_SOC_SLP_RDY_MASK) == 0U) { /* Enable the CAU sleep clock. */ CLOCK_EnableClock(kCLOCK_RefClkCauSlp); } if ((SYSCTL2->SOURCE_CLK_GATE & SYSCTL2_SOURCE_CLK_GATE_REFCLK_SYS_CG_MASK) != 0U) { /* Enable the REFCLK_SYS clock. */ CLOCK_EnableClock(kCLOCK_RefClkSys); } /* Initialize T3 PLL and enable outputs that are not clock gated. */ CLOCK_InitT3RefClk(kCLOCK_T3MciIrc48m); /* Enable FFRO - T3 PLL 48/60 MHz IRC clock output */ CLOCK_EnableClock(kCLOCK_T3PllMciIrcClk); /* Enable T3 PLL 256 MHz clock output */ CLOCK_EnableClock(kCLOCK_T3PllMci256mClk); /* Set core clock to safe system oscillator clock for initialization of other sources. */ CLOCK_AttachClk(kSYSOSC_to_MAIN_CLK); CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 1); /* Enable TCPU PLL MCI clock output */ CLOCK_EnableClock(kCLOCK_TcpuMciClk); /* Initialize TDDR PLL and enable outputs that are not clock gated. */ CLOCK_InitTddrRefClk(kCLOCK_TddrFlexspiDiv10); /* Enable TDDR PLL FlexSPI clock output */ CLOCK_EnableClock(kCLOCK_TddrMciFlexspiClk); /* Initialize AVPLL and enable both channels. */ CLOCK_InitAvPll(&avpllConfig_BOARD_BootClockRUN); /* Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kRC32K_to_CLK32K); /* Switch CLK32K to RC32K */ /*!< Please note SYSTICK_CLK source is used only if the SysTick SYST_CSR register CLKSOURCE bit is set to 0. */ CLOCK_AttachClk(kSYSTICK_DIV_to_SYSTICK_CLK); /* Switch SYSTICK_CLK to SYSTICK_DIV */ /* Set up dividers */ CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 1U); /* Set .AUDIOPLLCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivPllFrgClk, 13U); /* Set .FRGPLLCLKDIV divider to value 13 */ CLOCK_SetClkDiv(kCLOCK_DivMainPllClk, 1U); /* Set .MAINPLLCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivAux0PllClk, 1U); /* Set .AUX0PLLCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 1U); /* Set .SYSTICKFCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivPmuFclk, 5U); /* Set .PMUFCLKDIV divider to value 5 */ /* Select the main clock source for the main system clock (MAINCLKSELA and MAINCLKSELB). */ CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK); /*!< Set SystemCoreClock variable. */ SystemCoreClock = BOARD_BOOTCLOCKRUN_HCLK; } ================================================ FILE: hw/bsp/rw61x/boards/frdm_rw612/clock_config.h ================================================ /* * Copyright 2024 NXP * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /******************************************************************************* ************************ BOARD_InitBootClocks function ************************ ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes default configuration of clocks. * */ void BOARD_InitBootClocks(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ /******************************************************************************* ********************** Configuration BOARD_BootClockRUN *********************** ******************************************************************************/ /******************************************************************************* * Definitions for BOARD_BootClockRUN configuration ******************************************************************************/ /* Clock outputs (values are in Hz): */ #define BOARD_BOOTCLOCKRUN_AUDIO_PLL_CLK 12287999UL /* Clock consumers of audio_pll_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_AUX0_PLL_CLK 260000000UL /* Clock consumers of aux0_pll_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_AUX1_PLL_CLK 0UL /* Clock consumers of aux1_pll_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_AVPLL_CH1_CLKOUT 12287999UL /* Clock consumers of avpll_ch1_clkout output : N/A */ #define BOARD_BOOTCLOCKRUN_AVPLL_CH2_CLKOUT 63999997UL /* Clock consumers of avpll_ch2_clkout output : N/A */ #define BOARD_BOOTCLOCKRUN_CAU_SLP_CLK 4000000UL /* Clock consumers of cau_slp_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_32K 32000UL /* Clock consumers of clk_32k output : RTC */ #define BOARD_BOOTCLOCKRUN_CLK_OUT 0UL /* Clock consumers of clk_out output : N/A */ #define BOARD_BOOTCLOCKRUN_CLK_PMU_SYS 52000000UL /* Clock consumers of clk_pmu_sys output : PMU */ #define BOARD_BOOTCLOCKRUN_CTIMER0_FCLK 0UL /* Clock consumers of ctimer0_fclk output : CTIMER0 */ #define BOARD_BOOTCLOCKRUN_CTIMER1_FCLK 0UL /* Clock consumers of ctimer1_fclk output : CTIMER1 */ #define BOARD_BOOTCLOCKRUN_CTIMER2_FCLK 0UL /* Clock consumers of ctimer2_fclk output : CTIMER2 */ #define BOARD_BOOTCLOCKRUN_CTIMER3_FCLK 0UL /* Clock consumers of ctimer3_fclk output : CTIMER3 */ #define BOARD_BOOTCLOCKRUN_DMIC_FCLK 0UL /* Clock consumers of dmic_fclk output : DMIC0 */ #define BOARD_BOOTCLOCKRUN_ELS_128M_CLK 128000000UL /* Clock consumers of els_128m_clk output : ELS */ #define BOARD_BOOTCLOCKRUN_ELS_256M_CLK 256000000UL /* Clock consumers of els_256m_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_ELS_64M_CLK 64000000UL /* Clock consumers of els_64m_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_ELS_FCLK 0UL /* Clock consumers of els_fclk output : ELS */ #define BOARD_BOOTCLOCKRUN_FFRO_CLK_DIV4 12075471UL /* Clock consumers of ffro_clk_div4 output : N/A */ #define BOARD_BOOTCLOCKRUN_FLEXCOMM0_FCLK 0UL /* Clock consumers of flexcomm0_fclk output : FLEXCOMM0 */ #define BOARD_BOOTCLOCKRUN_FLEXCOMM14_FCLK 0UL /* Clock consumers of flexcomm14_fclk output : FLEXCOMM14 */ #define BOARD_BOOTCLOCKRUN_FLEXCOMM1_FCLK 0UL /* Clock consumers of flexcomm1_fclk output : FLEXCOMM1 */ #define BOARD_BOOTCLOCKRUN_FLEXCOMM2_FCLK 0UL /* Clock consumers of flexcomm2_fclk output : FLEXCOMM2 */ #define BOARD_BOOTCLOCKRUN_FLEXCOMM3_FCLK 0UL /* Clock consumers of flexcomm3_fclk output : FLEXCOMM3 */ #define BOARD_BOOTCLOCKRUN_FLEXSPI_FCLK 0UL /* Clock consumers of flexspi_fclk output : FLEXSPI */ #define BOARD_BOOTCLOCKRUN_GAU_FCLK 0UL /* Clock consumers of gau_fclk output : GAU_ACOMP, GAU_BG, GAU_DAC0, GAU_GPADC0, GAU_GPADC1 */ #define BOARD_BOOTCLOCKRUN_HCLK 260000000UL /* Clock consumers of hclk output : AHB_SECURE_CTRL, APU0, APU1, BLEAPU, BLECTRL, BUCK11, BUCK18, CACHE64_CTRL0, CACHE64_CTRL1, CACHE64_POLSEL0, CACHE64_POLSEL1, CAU, CDOG, CLKCTL0, CLKCTL1, CRC, CTIMER0, CTIMER1, CTIMER2, CTIMER3, DMA0, DMA1, DMIC0, ELS, ENET, FLEXCOMM0, FLEXCOMM1, FLEXCOMM14, FLEXCOMM2, FLEXCOMM3, FLEXSPI, FREQME, GAU_ACOMP, GAU_BG, GAU_DAC0, GAU_GPADC0, GAU_GPADC1, GDMA, GPIO, INPUTMUX, ITRC, LCDIC, MCI_IO_MUX, MRT0, MRT1, OCOTP, OSTIMER, PINT, PKC, PMU, POWERQUAD, PUF, ROMCP, RSTCTL0, RSTCTL1, RTC, SCT0, SDU_FBR_CARD, SDU_FN0_CARD, SDU_FN_CARD, SECGPIO, SENSOR_CTRL, SOCCTRL, SOC_OTP_CTRL, SYSCTL0, SYSCTL1, SYSCTL2, SysTick, TRNG, USBOTG, USIM, UTICK, WLAPU, WLCTRL, WWDT0 */ #define BOARD_BOOTCLOCKRUN_LCD_FCLK 0UL /* Clock consumers of lcd_fclk output : LCDIC */ #define BOARD_BOOTCLOCKRUN_LPOSC_CLK_I 1000000UL /* Clock consumers of lposc_clk_i output : N/A */ #define BOARD_BOOTCLOCKRUN_MAIN_CLK 260000000UL /* Clock consumers of main_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_MAIN_PLL_CLK 260000000UL /* Clock consumers of main_pll_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_MCLK_OUT 0UL /* Clock consumers of mclk_out output : N/A */ #define BOARD_BOOTCLOCKRUN_OSEVENT_FCLK 0UL /* Clock consumers of osevent_fclk output : OSTIMER */ #define BOARD_BOOTCLOCKRUN_OTP_FUSE_32M_CLK 32000000UL /* Clock consumers of otp_fuse_32m_clk output : OCOTP */ #define BOARD_BOOTCLOCKRUN_REFCLK_PHY 40000000UL /* Clock consumers of refclk_phy output : USBOTG */ #define BOARD_BOOTCLOCKRUN_REFCLK_SYS 0UL /* Clock consumers of refclk_sys output : N/A */ #define BOARD_BOOTCLOCKRUN_SCT_FCLK 0UL /* Clock consumers of sct_fclk output : SCT0 */ #define BOARD_BOOTCLOCKRUN_SFRO_CLK_I 16000000UL /* Clock consumers of sfro_clk_i output : N/A */ #define BOARD_BOOTCLOCKRUN_SYSOSC_CLK_I 0UL /* Clock consumers of sysosc_clk_i output : N/A */ #define BOARD_BOOTCLOCKRUN_SYSTICK_FCLK 260000000UL /* Clock consumers of systick_fclk output : SysTick */ #define BOARD_BOOTCLOCKRUN_T3PLL_MCI_213P3M 0UL /* Clock consumers of t3pll_mci_213p3m output : N/A */ #define BOARD_BOOTCLOCKRUN_T3PLL_MCI_256M 256000000UL /* Clock consumers of t3pll_mci_256m output : N/A */ #define BOARD_BOOTCLOCKRUN_T3PLL_MCI_48_60M_IRC 48301886UL /* Clock consumers of t3pll_mci_48_60m_irc output : N/A */ #define BOARD_BOOTCLOCKRUN_T3PLL_MCI_FLEXSPI_CLK 0UL /* Clock consumers of t3pll_mci_flexspi_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_TCPU_MCI_CLK 260000000UL /* Clock consumers of tcpu_mci_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_TCPU_MCI_FLEXSPI_CLK 0UL /* Clock consumers of tcpu_mci_flexspi_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_TDDR_MCI_ENET_CLK 0UL /* Clock consumers of tddr_mci_enet_clk output : ENET */ #define BOARD_BOOTCLOCKRUN_TDDR_MCI_FLEXSPI_CLK 320000000UL /* Clock consumers of tddr_mci_flexspi_clk output : N/A */ #define BOARD_BOOTCLOCKRUN_USIM_FCLK 0UL /* Clock consumers of usim_fclk output : USIM */ #define BOARD_BOOTCLOCKRUN_UTICK_FCLK 0UL /* Clock consumers of utick_fclk output : UTICK */ #define BOARD_BOOTCLOCKRUN_WDT0_FCLK 0UL /* Clock consumers of wdt0_fclk output : WWDT0 */ /*! @brief AVPLL set for BOARD_BootClockRUN configuration. */ extern const clock_avpll_config_t avpllConfig_BOARD_BootClockRUN; /******************************************************************************* * API for BOARD_BootClockRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ /*! * @brief This function executes configuration of clocks. * */ void BOARD_BootClockRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ #endif /* _CLOCK_CONFIG_H_ */ ================================================ FILE: hw/bsp/rw61x/boards/frdm_rw612/pin_mux.c ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Pins v17.0 processor: RW612 package_id: RW612ETA2I mcu_data: ksdk2_0 processor_version: 25.09.10 board: FRDM-RW612 pin_labels: - {pin_num: M2, pin_signal: GPIO_11, label: 'J1[6]/WAKEUP_BTN', identifier: WAKEUP;WAKEUP_BTN} - {pin_num: L7, pin_signal: GPIO_5, label: 'J1[7]/MCLK', identifier: MCLKOUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ #include "fsl_common.h" #include "fsl_gpio.h" #include "fsl_io_mux.h" #include "pin_mux.h" /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitBootPins * Description : Calls initialization functions. * * END ****************************************************************************************************************/ void BOARD_InitBootPins(void) { BOARD_InitPins(); BOARD_InitDEBUG_UARTPins(); BOARD_InitSWD_DEBUGPins(); BOARD_InitLEDPins(); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitPins: - options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'} - pin_list: - {pin_num: M2, peripheral: GPIO, signal: 'PIO0, 11', pin_signal: GPIO_11, identifier: WAKEUP_BTN, direction: INPUT} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 */ void BOARD_InitPins(void) { /* Enables the clock for the GPIO0 module */ GPIO_PortInit(GPIO, 0); gpio_pin_config_t WAKEUP_BTN_config = { .pinDirection = kGPIO_DigitalInput, .outputLogic = 0U }; /* Initialize GPIO functionality on pin PIO0_11 (pin M2) */ GPIO_PinInit(BOARD_INITPINS_WAKEUP_BTN_GPIO, BOARD_INITPINS_WAKEUP_BTN_PORT, BOARD_INITPINS_WAKEUP_BTN_PIN, &WAKEUP_BTN_config); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitDEBUG_UARTPins: - options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'} - pin_list: - {pin_num: E5, peripheral: FLEXCOMM3, signal: USART_RXD, pin_signal: GPIO_24} - {pin_num: F6, peripheral: FLEXCOMM3, signal: USART_TXD, pin_signal: GPIO_26} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitDEBUG_UARTPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 */ void BOARD_InitDEBUG_UARTPins(void) { /* Initialize FC3_USART_DATA functionality on pin GPIO_24, GPIO_26 (pin E5_F6) */ IO_MUX_SetPinMux(IO_MUX_FC3_USART_DATA); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitSWD_DEBUGPins: - options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'} - pin_list: - {pin_num: G5, peripheral: SWD, signal: CLK, pin_signal: GPIO_13} - {pin_num: K4, peripheral: SWD, signal: IO, pin_signal: GPIO_14} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitSWD_DEBUGPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 */ void BOARD_InitSWD_DEBUGPins(void) { MCI_IO_MUX->C_TIMER_IN = ((MCI_IO_MUX->C_TIMER_IN & /* Mask bits to zero which are setting */ (~(MCI_IO_MUX_C_TIMER_IN_CT_INP3_SEL_MASK | MCI_IO_MUX_C_TIMER_IN_CT_INP4_SEL_MASK))) /* sel GPIO-13 as ct_inp3: 0x00u */ | MCI_IO_MUX_C_TIMER_IN_CT_INP3_SEL(0x00u) /* sel GPIO-14 as ct_inp4: 0x00u */ | MCI_IO_MUX_C_TIMER_IN_CT_INP4_SEL(0x00u)); MCI_IO_MUX->C_TIMER_OUT = ((MCI_IO_MUX->C_TIMER_OUT & /* Mask bits to zero which are setting */ (~(MCI_IO_MUX_C_TIMER_OUT_CT0MAT3_SEL_MASK | MCI_IO_MUX_C_TIMER_OUT_CT1MAT0_SEL_MASK))) /* sel GPIO-13 as ct0mat3: 0x00u */ | MCI_IO_MUX_C_TIMER_OUT_CT0MAT3_SEL(0x00u) /* sel GPIO-14 as ct1mat0: 0x00u */ | MCI_IO_MUX_C_TIMER_OUT_CT1MAT0_SEL(0x00u)); MCI_IO_MUX->FC2 = ((MCI_IO_MUX->FC2 & /* Mask bits to zero which are setting */ (~(MCI_IO_MUX_FC2_SEL_FC2_I2C_MASK | MCI_IO_MUX_FC2_SEL_FC2_I2S_MASK | MCI_IO_MUX_FC2_SEL_FC2_SPI_MASK | MCI_IO_MUX_FC2_SEL_FC2_I2S_DATA_ONLY_MASK | MCI_IO_MUX_FC2_SEL_FC2_USART_DATA_MASK))) /* flexcomm2:select GPIO-13/14 as i2c function: 0x00u */ | MCI_IO_MUX_FC2_SEL_FC2_I2C(0x00u) /* flexcomm2:select GPIO-13/14/15 as i2s function: 0x00u */ | MCI_IO_MUX_FC2_SEL_FC2_I2S(0x00u) /* flexcomm2:select GPIO-13/14/15/16 as spi function: 0x00u */ | MCI_IO_MUX_FC2_SEL_FC2_SPI(0x00u) /* flexcomm2:select GPIO-13 as i2s data function: 0x00u */ | MCI_IO_MUX_FC2_SEL_FC2_I2S_DATA_ONLY(0x00u) /* flexcomm2:select GPIO-13/14 as usart rxd/txd: 0x00u */ | MCI_IO_MUX_FC2_SEL_FC2_USART_DATA(0x00u)); MCI_IO_MUX->GPIO_GRP0 = ((MCI_IO_MUX->GPIO_GRP0 & /* Mask bits to zero which are setting */ (~(MCI_IO_MUX_GPIO_GRP0_SEL_13_MASK | MCI_IO_MUX_GPIO_GRP0_SEL_14_MASK))) /* pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i]: 0x00u */ | MCI_IO_MUX_GPIO_GRP0_SEL(0x00u)); SOCCTRL->MCI_IOMUX_EN0 = ((SOCCTRL->MCI_IOMUX_EN0 & /* Mask bits to zero which are setting */ (~(SOCCIU_MCI_IOMUX_EN0_EN_21_0_13_MASK | SOCCIU_MCI_IOMUX_EN0_EN_21_0_14_MASK))) /* Bitwise enable control for mci_io_mux GPIO[21:0]: 0x00u */ | SOCCIU_MCI_IOMUX_EN0_EN_21_0(0x00u)); } /* clang-format off */ /* * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* BOARD_InitLEDPins: - options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'} - pin_list: - {pin_num: M1, peripheral: GPIO, signal: 'PIO0, 0', pin_signal: GPIO_0, direction: OUTPUT, gpio_init_state: 'true'} - {pin_num: N2, peripheral: GPIO, signal: 'PIO0, 1', pin_signal: GPIO_1, direction: OUTPUT, gpio_init_state: 'true'} - {pin_num: N8, peripheral: GPIO, signal: 'PIO0, 12', pin_signal: GPIO_12, direction: OUTPUT, gpio_init_state: 'true'} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitLEDPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ /* Function assigned for the Cortex-M33 */ void BOARD_InitLEDPins(void) { /* Enables the clock for the GPIO0 module */ CLOCK_EnableClock(kCLOCK_HsGpio0); gpio_pin_config_t LED_BLUE_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO0_0 (pin M1) */ GPIO_PinInit(BOARD_INITLEDPINS_LED_BLUE_GPIO, BOARD_INITLEDPINS_LED_BLUE_PORT, BOARD_INITLEDPINS_LED_BLUE_PIN, &LED_BLUE_config); gpio_pin_config_t LED_RED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO0_1 (pin N2) */ GPIO_PinInit(BOARD_INITLEDPINS_LED_RED_GPIO, BOARD_INITLEDPINS_LED_RED_PORT, BOARD_INITLEDPINS_LED_RED_PIN, &LED_RED_config); gpio_pin_config_t LED_GREEN_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 1U }; /* Initialize GPIO functionality on pin PIO0_12 (pin N8) */ GPIO_PinInit(BOARD_INITLEDPINS_LED_GREEN_GPIO, BOARD_INITLEDPINS_LED_GREEN_PORT, BOARD_INITLEDPINS_LED_GREEN_PIN, &LED_GREEN_config); /* Initialize GPIO0 functionality on pin GPIO_0 (pin M1) */ IO_MUX_SetPinMux(IO_MUX_GPIO0); /* Initialize GPIO1 functionality on pin GPIO_1 (pin N2) */ IO_MUX_SetPinMux(IO_MUX_GPIO1); /* Initialize GPIO12 functionality on pin GPIO_12 (pin N8) */ IO_MUX_SetPinMux(IO_MUX_GPIO12); } /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/rw61x/boards/frdm_rw612/pin_mux.h ================================================ /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. **********************************************************************************************************************/ #ifndef _PIN_MUX_H_ #define _PIN_MUX_H_ /*! * @addtogroup pin_mux * @{ */ /*********************************************************************************************************************** * API **********************************************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @brief Calls initialization functions. * */ void BOARD_InitBootPins(void); /*! * @brief mclk direction control: MCLK is in the output direction. */ #define MCLKPINDIR_MCLKPINDIR_OUTPUT_DIRECTION 0x01u /*! @name GPIO_5 (coord L7), J1[7]/MCLK @{ */ /* Routed pin properties */ #define BOARD_INITPINS_MCLKOUT_PERIPHERAL CLKCTL1 /*!<@brief Peripheral name */ #define BOARD_INITPINS_MCLKOUT_SIGNAL MCLK /*!<@brief Signal name */ #define BOARD_INITPINS_MCLKOUT_GPIO_PIN 5U /*!<@brief GPIO pin number */ #define BOARD_INITPINS_MCLKOUT_PORT 0U /*!<@brief PORT number */ #define BOARD_INITPINS_MCLKOUT_PIN 5U /*!<@brief PORT pin number */ #define BOARD_INITPINS_MCLKOUT_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ /* @} */ /*! @name GPIO_11 (coord M2), J1[6]/WAKEUP_BTN @{ */ /* Routed pin properties */ #define BOARD_INITPINS_WAKEUP_BTN_PERIPHERAL GPIO /*!<@brief Peripheral name */ #define BOARD_INITPINS_WAKEUP_BTN_SIGNAL PIO0 /*!<@brief Signal name */ #define BOARD_INITPINS_WAKEUP_BTN_CHANNEL 11 /*!<@brief Signal channel */ #define BOARD_INITPINS_WAKEUP_BTN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITPINS_WAKEUP_BTN_GPIO_PIN 11U /*!<@brief GPIO pin number */ #define BOARD_INITPINS_WAKEUP_BTN_PORT 0U /*!<@brief PORT number */ #define BOARD_INITPINS_WAKEUP_BTN_PIN 11U /*!<@brief PORT pin number */ #define BOARD_INITPINS_WAKEUP_BTN_PIN_MASK (1U << 11U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief * */ void BOARD_InitPins(void); /* Function assigned for the Cortex-M33 */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 */ /*! * @brief pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i] Mask for item 13. */ #define MCI_IO_MUX_GPIO_GRP0_SEL_13_MASK 0x2000u /*! * @brief pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i] Mask for item 14. */ #define MCI_IO_MUX_GPIO_GRP0_SEL_14_MASK 0x4000u /*! * @brief Bitwise enable control for mci_io_mux GPIO[21:0] Mask for item 13. */ #define SOCCIU_MCI_IOMUX_EN0_EN_21_0_13_MASK 0x2000u /*! * @brief Bitwise enable control for mci_io_mux GPIO[21:0] Mask for item 14. */ #define SOCCIU_MCI_IOMUX_EN0_EN_21_0_14_MASK 0x4000u /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 */ /*! @name GPIO_0 (coord M1), J1[14]/LED_BLUE @{ */ /* Routed pin properties */ #define BOARD_INITLEDPINS_LED_BLUE_PERIPHERAL GPIO /*!<@brief Peripheral name */ #define BOARD_INITLEDPINS_LED_BLUE_SIGNAL PIO0 /*!<@brief Signal name */ #define BOARD_INITLEDPINS_LED_BLUE_CHANNEL 0 /*!<@brief Signal channel */ #define BOARD_INITLEDPINS_LED_BLUE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDPINS_LED_BLUE_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDPINS_LED_BLUE_GPIO_PIN 0U /*!<@brief GPIO pin number */ #define BOARD_INITLEDPINS_LED_BLUE_PORT 0U /*!<@brief PORT number */ #define BOARD_INITLEDPINS_LED_BLUE_PIN 0U /*!<@brief PORT pin number */ #define BOARD_INITLEDPINS_LED_BLUE_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ /* @} */ /*! @name GPIO_1 (coord N2), J5[1]/LED_RED @{ */ /* Routed pin properties */ #define BOARD_INITLEDPINS_LED_RED_PERIPHERAL GPIO /*!<@brief Peripheral name */ #define BOARD_INITLEDPINS_LED_RED_SIGNAL PIO0 /*!<@brief Signal name */ #define BOARD_INITLEDPINS_LED_RED_CHANNEL 1 /*!<@brief Signal channel */ #define BOARD_INITLEDPINS_LED_RED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDPINS_LED_RED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDPINS_LED_RED_GPIO_PIN 1U /*!<@brief GPIO pin number */ #define BOARD_INITLEDPINS_LED_RED_PORT 0U /*!<@brief PORT number */ #define BOARD_INITLEDPINS_LED_RED_PIN 1U /*!<@brief PORT pin number */ #define BOARD_INITLEDPINS_LED_RED_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ /* @} */ /*! @name GPIO_12 (coord N8), LED_GREEN @{ */ /* Routed pin properties */ #define BOARD_INITLEDPINS_LED_GREEN_PERIPHERAL GPIO /*!<@brief Peripheral name */ #define BOARD_INITLEDPINS_LED_GREEN_SIGNAL PIO0 /*!<@brief Signal name */ #define BOARD_INITLEDPINS_LED_GREEN_CHANNEL 12 /*!<@brief Signal channel */ #define BOARD_INITLEDPINS_LED_GREEN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ #define BOARD_INITLEDPINS_LED_GREEN_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */ #define BOARD_INITLEDPINS_LED_GREEN_GPIO_PIN 12U /*!<@brief GPIO pin number */ #define BOARD_INITLEDPINS_LED_GREEN_PORT 0U /*!<@brief PORT number */ #define BOARD_INITLEDPINS_LED_GREEN_PIN 12U /*!<@brief PORT pin number */ #define BOARD_INITLEDPINS_LED_GREEN_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ /* @} */ /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitLEDPins(void); /* Function assigned for the Cortex-M33 */ #if defined(__cplusplus) } #endif /*! * @} */ #endif /* _PIN_MUX_H_ */ /*********************************************************************************************************************** * EOF **********************************************************************************************************************/ ================================================ FILE: hw/bsp/rw61x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2025, Gabriel Koppenstein * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: NXP */ #include "bsp/board_api.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" #include "board.h" #include "fsl_usart.h" #include "fsl_clock.h" #include "pin_mux.h" #include "clock_config.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tusb_int_handler(1, true); } void board_init(void) { // Init button pin, LED pins, SWD pins & UART pins BOARD_InitBootPins(); // Init Clocks BOARD_InitBootClocks(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #ifdef NEOPIXEL_PIN // No neo pixel support yet #endif #ifdef UART_DEV // Enable UART when debug log is on board_uart_init_clock(); usart_config_t uart_config; USART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableRx = true; uart_config.enableTx = true; USART_Init(UART_DEV, &uart_config, CLOCK_GetFlexCommClkFreq(LP_FLEXCOMM_INST)); #endif // USB Initialization // Reset USB RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn); // Enable USB Clock CLOCK_EnableClock(kCLOCK_Usb); // Enable USB PHY CLOCK_EnableUsbhsPhyClock(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinWrite(LED_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } uint32_t board_button_read(void) { #ifdef BUTTON_GPIO return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BOARD_INITPINS_WAKEUP_BTN_PORT, BUTTON_PIN); #endif } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/rw61x/family.cmake ================================================ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS RW61X CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c ${SDK_DIR}/drivers/common/fsl_common_arm.c ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c ${SDK_DIR}/drivers/flexcomm/usart/fsl_usart.c ${SDK_DIR}/drivers/flexspi/fsl_flexspi.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_5}/CMSIS/Core/Include ${SDK_DIR}/devices/${MCU_VARIANT} ${SDK_DIR}/devices/${MCU_VARIANT}/drivers ${SDK_DIR}/drivers ${SDK_DIR}/drivers/common ${SDK_DIR}/drivers/lpc_gpio ${SDK_DIR}/drivers/flexcomm ${SDK_DIR}/drivers/flexcomm/usart ${SDK_DIR}/drivers/flexspi ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_RW61X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c # ChipIdea HS ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c ${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c ${TOP}/src/portable/ehci/ehci.c # Startup File ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) # Add Board specific includes target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) # Linker Options if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () # Handle Startup File Properties (Linting/Warnings) set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w ) # Flashing & Binary Generation family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/rw61x/family.mk ================================================ UF2_FAMILY_ID = 0x2abc77ec SDK_DIR = hw/mcu/nxp/mcux-sdk include $(TOP)/$(BOARD_PATH)/board.mk # Default to Highspeed PORT1 PORT ?= 1 CFLAGS += \ -flto \ -DBOARD_TUD_RHPORT=$(PORT) \ -DBOARD_TUH_RHPORT=$(PORT) \ -DSERIAL_PORT_TYPE_UART=1 \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED \ -DBOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration -Wno-error=redundant-decls LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ src/portable/chipidea/ci_hs/hcd_ci_hs.c \ src/portable/ehci/ehci.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/system_$(MCU_CORE).c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_power.c \ $(SDK_DIR)/drivers/lpc_gpio/fsl_gpio.c \ $(SDK_DIR)/drivers/common/fsl_common_arm.c\ $(SDK_DIR)/drivers/flexcomm/fsl_flexcomm.c \ $(SDK_DIR)/drivers/flexcomm/usart/fsl_usart.c \ $(SDK_DIR)/drivers/flexspi/fsl_flexspi.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT) \ $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers \ $(TOP)/$(SDK_DIR)/drivers/ \ $(TOP)/$(SDK_DIR)/drivers/common\ $(TOP)/$(SDK_DIR)/drivers/lpc_gpio\ $(TOP)/$(SDK_DIR)/drivers/flexcomm \ $(TOP)/$(SDK_DIR)/drivers/flexcomm/usart \ $(TOP)/$(SDK_DIR)/drivers/flexspi \ SRC_S += $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S ================================================ FILE: hw/bsp/rx/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ // FIXME cause redundant-decls warnings extern uint32_t SystemCoreClock; #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) #define configRUN_FREERTOS_SECURE_ONLY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT #define vTickISR INT_Excep_CMT0_CMI0 #define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) #define configKERNEL_INTERRUPT_PRIORITY 1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #else /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ #if defined(__NVIC_PRIO_BITS) // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h #define configPRIO_BITS __NVIC_PRIO_BITS #elif defined(__ECLIC_INTCTLBITS) // RISC-V Bumblebee core from nuclei #define configPRIO_BITS __ECLIC_INTCTLBITS #elif defined(__IASMARM__) // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. // Therefore we will hard coded it to minimum value of 2 to get pass ci build. // IAR user must update this to correct value of the target MCU #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" #define configPRIO_BITS 2 #else #error "FreeRTOS configPRIO_BITS to be defined" #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< P20, RXD0 => P21 */ PORT2.PMR.BIT.B0 = 1U; PORT2.PCR.BIT.B0 = 1U; MPC.P20PFS.BYTE = 0b01010; PORT2.PMR.BIT.B1 = 1U; MPC.P21PFS.BYTE = 0b01010; /* USB VBUS -> P16 DPUPE -> P14 */ PORT1.PMR.BIT.B4 = 1U; PORT1.PMR.BIT.B6 = 1U; MPC.P14PFS.BYTE = 0b10001; MPC.P16PFS.BYTE = MPC_PFS_ISEL | 0b10001; MPC.PFUSB0.BIT.PUPHZS = 1; /* Lock MPC registers */ MPC.PWPR.BIT.PFSWE = 0; MPC.PWPR.BIT.B0WI = 1; /* Enable SCI0 */ SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(SCI0) = 0; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; SCI0.BRR = (SCI_PCLK / (32 * 115200)) - 1; IR(SCI0, RXI0) = 0; IR(SCI0, TXI0) = 0; IR(SCI0, TEI0) = 0; IPR(SCI0, RXI0) = IRQ_PRIORITY_SCI0; IPR(SCI0, TXI0) = IRQ_PRIORITY_SCI0; IPR(SCI0, TEI0) = IRQ_PRIORITY_SCI0; IEN(SCI0, RXI0) = 1; IEN(SCI0, TXI0) = 1; IEN(SCI0, TEI0) = 1; } ================================================ FILE: hw/bsp/rx/boards/gr_citrus/r5f5631fd.ld ================================================ __USTACK_SIZE = 0x00000400; __ISTACK_SIZE = 0x00000400; MEMORY { RAM : ORIGIN = 0x4, LENGTH = 0x3fffc ROM : ORIGIN = 0xFFE00000, LENGTH = 0x200000 } SECTIONS { .fvectors 0xFFFFFF80: AT(0xFFFFFF80) { KEEP(*(.fvectors)) } > ROM .text 0xFFE00000: AT(0xFFE00000) { *(.text) *(.text.*) *(P) etext = .; } > ROM .rvectors ALIGN(4): { _rvectors_start = .; KEEP(*(.rvectors)) _rvectors_end = .; } > ROM .init : { KEEP(*(.init)) __preinit_array_start = .; KEEP(*(.preinit_array)) __preinit_array_end = .; __init_array_start = (. + 3) & ~ 3; KEEP(*(.init_array)) KEEP(*(SORT(.init_array.*))) __init_array_end = .; __fini_array_start = .; KEEP(*(.fini_array)) KEEP(*(SORT(.fini_array.*))) __fini_array_end = .; } > ROM .fini : { KEEP(*(.fini)) } > ROM .got : { *(.got) *(.got.plt) } > ROM .rodata : { *(.rodata) *(.rodata.*) *(C_1) *(C_2) *(C) _erodata = .; } > ROM .eh_frame_hdr : { *(.eh_frame_hdr) } > ROM .eh_frame : { *(.eh_frame) } > ROM .jcr : { *(.jcr) } > ROM .tors : { __CTOR_LIST__ = .; . = ALIGN(2); ___ctors = .; *(.ctors) ___ctors_end = .; __CTOR_END__ = .; __DTOR_LIST__ = .; ___dtors = .; *(.dtors) ___dtors_end = .; __DTOR_END__ = .; . = ALIGN(2); _mdata = .; } > ROM .data : AT(_mdata) { _data = .; *(.data) *(.data.*) *(D) *(D_1) *(D_2) _edata = .; } > RAM .gcc_exc : { *(.gcc_exc) } > RAM .bss : { _bss = .; *(.bss) *(.bss.**) *(COMMON) *(B) *(B_1) *(B_2) _ebss = .; _end = .; } > RAM .ustack : { . = ALIGN(8); . = . + __USTACK_SIZE; PROVIDE(_ustack = .); } > RAM .istack : { . = ALIGN(8); . = . + __ISTACK_SIZE; PROVIDE(_istack = .); } > RAM } ================================================ FILE: hw/bsp/rx/boards/rx65n_target/board.cmake ================================================ set(MCU_VARIANT rx65n) set(MCU_FAMILY RX65X) set(CMAKE_SYSTEM_CPU rx64m CACHE INTERNAL "System Processor") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/r5f565ne.ld) set(JLINK_DEVICE R5F565NE) set(JLINK_IF JTAG) set(RFP_DEVICE rx65x) set(RFP_TOOL e2l) set(BOARD_SOURCES ${CMAKE_CURRENT_LIST_DIR}/rx65n_target.c ) function(update_board TARGET) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) endfunction() ================================================ FILE: hw/bsp/rx/boards/rx65n_target/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: RX65N Target Board url: https://www.renesas.com/en/products/microcontrollers-microprocessors/rx-32-bit-performance-efficiency-mcus/rtk5rx65n0c00000br-target-board-rx65n */ #ifndef BOARD_H_ #define BOARD_H_ #include "iodefine.h" #ifdef __cplusplus extern "C" { #endif // LED: PD6, active low (open-drain) #define BOARD_LED_WRITE(state) (PORTD.PODR.BIT.B6 = (state) ? 0 : 1) // Button: PB1, active low #define BOARD_BUTTON_READ() (PORTB.PIDR.BIT.B1 ? 0 : 1) // UART: SCI5 #define BOARD_UART_SCI SCI5 #define BOARD_SCI_TXI_HANDLER INT_Excep_SCI5_TXI5 #define BOARD_SCI_TEI_HANDLER INT_Excep_ICU_GROUPBL0 // SCI5 TEI uses group interrupt #define BOARD_SCI_RXI_HANDLER INT_Excep_SCI5_RXI5 // USB interrupt handler (software configurable vector) #define IRQ_USB0_USBI0 62 #define SLIBR_USBI0 SLIBR185 #define IR_USB0_USBI0 IR_PERIB_INTB185 #define IER_USB0_USBI0 IER_PERIB_INTB185 #define IEN_USB0_USBI0 IEN_PERIB_INTB185 #define IPR_USB0_USBI0 IPR_PERIB_INTB185 #define INT_Excep_USB0_USBI0 INT_Excep_PERIB_INTB185 #define BOARD_USB_IRQ_HANDLER INT_Excep_USB0_USBI0 // Clocks #define BOARD_PCLK 60000000 #define BOARD_CPUCLK 120000000 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/rx/boards/rx65n_target/board.mk ================================================ CFLAGS += \ -mcpu=rx64m \ -misa=v2 \ -DCFG_TUSB_MCU=OPT_MCU_RX65X \ -DIR_USB0_USBI0=IR_PERIB_INTB185 \ -DIER_USB0_USBI0=IER_PERIB_INTB185 \ -DIEN_USB0_USBI0=IEN_PERIB_INTB185 MCU_DIR = hw/mcu/renesas/rx/rx65n # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/r5f565ne.ld # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RX600 # For flash-jlink target JLINK_DEVICE = R5F565NE JLINK_IF = JTAG # For flash-pyocd target PYOCD_TARGET = # flash using rfp-cli flash: flash-rfp ================================================ FILE: hw/bsp/rx/boards/rx65n_target/r5f565ne.ld ================================================ __USTACK_SIZE = 0x00000800; __ISTACK_SIZE = 0x00000800; MEMORY { RAM : ORIGIN = 0x4, LENGTH = 0x3fffc RAM2 : ORIGIN = 0x00800000, LENGTH = 0x60000 OFS : ORIGIN = 0xFE7F5D00, LENGTH = 128 ROM : ORIGIN = 0xFFE00000, LENGTH = 0x200000 } SECTIONS { .exvectors 0xFFFFFF80: AT(0xFFFFFF80) { "_exvectors_start" = .; KEEP(*(.exvectors)) "_exvectors_end" = .; } >ROM .fvectors 0xFFFFFFFC: AT(0xFFFFFFFC) { KEEP(*(.fvectors)) } > ROM .text 0xFFE00000: AT(0xFFE00000) { *(.text) *(.text.*) *(P) KEEP(*(.text.*_isr)) etext = .; } > ROM .rvectors ALIGN(4): { _rvectors_start = .; KEEP(*(.rvectors)) _rvectors_end = .; } > ROM .init : { KEEP(*(.init)) __preinit_array_start = .; KEEP(*(.preinit_array)) __preinit_array_end = .; __init_array_start = (. + 3) & ~ 3; KEEP(*(.init_array)) KEEP(*(SORT(.init_array.*))) __init_array_end = .; __fini_array_start = .; KEEP(*(.fini_array)) KEEP(*(SORT(.fini_array.*))) __fini_array_end = .; } > ROM .fini : { KEEP(*(.fini)) } > ROM .got : { *(.got) *(.got.plt) } > ROM .rodata : { *(.rodata) *(.rodata.*) *(C_1) *(C_2) *(C) _erodata = .; } > ROM .eh_frame_hdr : { *(.eh_frame_hdr) } > ROM .eh_frame : { *(.eh_frame) } > ROM .jcr : { *(.jcr) } > ROM .tors : { __CTOR_LIST__ = .; . = ALIGN(2); ___ctors = .; *(.ctors) ___ctors_end = .; __CTOR_END__ = .; __DTOR_LIST__ = .; ___dtors = .; *(.dtors) ___dtors_end = .; __DTOR_END__ = .; . = ALIGN(2); _mdata = .; } > ROM .data : AT(_mdata) { _data = .; *(.data) *(.data.*) *(D) *(D_1) *(D_2) _edata = .; } > RAM .gcc_exc : { *(.gcc_exc) } > RAM .bss : { _bss = .; *(.bss) *(.bss.**) *(COMMON) *(B) *(B_1) *(B_2) _ebss = .; _end = .; } > RAM .ustack : { . = ALIGN(8); . = . + __USTACK_SIZE; PROVIDE(_ustack = .); } > RAM .istack : { . = ALIGN(8); . = . + __ISTACK_SIZE; PROVIDE(_istack = .); } > RAM .ofs1 0xFE7F5D00: AT(0xFE7F5D00) { KEEP(*(.ofs1)) } > OFS .ofs2 0xFE7F5D10: AT(0xFE7F5D10) { KEEP(*(.ofs2)) } > OFS .ofs3 0xFE7F5D20: AT(0xFE7F5D20) { KEEP(*(.ofs3)) } > OFS .ofs4 0xFE7F5D40: AT(0xFE7F5D40) { KEEP(*(.ofs4)) } > OFS .ofs5 0xFE7F5D48: AT(0xFE7F5D48) { KEEP(*(.ofs5)) } > OFS .ofs6 0xFE7F5D50: AT(0xFE7F5D50) { KEEP(*(.ofs6)) } > OFS .ofs7 0xFE7F5D64: AT(0xFE7F5D64) { KEEP(*(.ofs7)) } > OFS .ofs8 0xFE7F5D70: AT(0xFE7F5D70) { KEEP(*(.ofs8)) } > OFS } ================================================ FILE: hw/bsp/rx/boards/rx65n_target/rx65n_target.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ /* How to connect JLink and RX65n Target and option board * (For original comment https://github.com/hathach/tinyusb/pull/922#issuecomment-869786131) * * To enable JTAG, RX65N requires following connections on main board. * - short EJ2 jumper header, to disable onboard E2L. * - short EMLE(J1-2) and 3V3(J1-14 or J2-10), to enable In-Circuit Emulator. * * Note: For RX65N-Cloud-Kit, the option board's JTAG pins to some switches or floating. * To use JLink with the option board, I think some further modifications will be necessary. * * | Function | RX65N pin | main board | option board | JLink connector | * |:---------:|:----------:|:----------:|:------------:|:---------------:| * | 3V3 | VCC | J1-14 | CN5-6 | 1 | * | TRST | P34 | J1-16 | CN5-7 | 3 | * | GND | VSS | J1-12 | CN5-5 | 4 | * | TDI | P30 | J1-20 | CN5-10 | 5 | * | TMS | P31 | J1-19 | USER_SW | 7 | * | TCK/FINEC | P27 | J1-21 | N/A | 9 | * | TDO | P26 | J1-22 | CN5-9 | 13 | * | nRES | RES# | J1-10 | RESET_SW | 15 | * * JLink firmware needs to update to V6.96 or newer version to avoid * [a bug](https://forum.segger.com/index.php/Thread/7758-SOLVED-Bug-in-JLink-from-V6-88b-regarding-RX65N) * regarding downloading. */ #include "iodefine.h" #include "board.h" #define SYSTEM_PRCR_PRC1 (1<<1) #define SYSTEM_PRCR_PRKEY (0xA5u<<8) #define MPC_PFS_ISEL (1<<6) #define IRQ_PRIORITY_SCI5 5 #define SCI_PCLK 60000000 void HardwareSetup(void) { FLASH.ROMCIV.WORD = 1; while (FLASH.ROMCIV.WORD) ; FLASH.ROMCE.WORD = 1; while (!FLASH.ROMCE.WORD) ; SYSTEM.PRCR.WORD = 0xA503u; if (!SYSTEM.RSTSR1.BYTE) { RTC.RCR4.BYTE = 0; RTC.RCR3.BYTE = 12; while (12 != RTC.RCR3.BYTE) ; } SYSTEM.SOSCCR.BYTE = 1; if (SYSTEM.HOCOCR.BYTE) { SYSTEM.HOCOCR.BYTE = 0; while (!SYSTEM.OSCOVFSR.BIT.HCOVF) ; } SYSTEM.PLLCR.WORD = 0x1D10u; /* HOCO x 15 */ SYSTEM.PLLCR2.BYTE = 0; while (!SYSTEM.OSCOVFSR.BIT.PLOVF) ; SYSTEM.SCKCR.LONG = 0x21C11222u; SYSTEM.SCKCR2.WORD = 0x0041u; SYSTEM.ROMWT.BYTE = 0x02u; while (0x02u != SYSTEM.ROMWT.BYTE) ; SYSTEM.SCKCR3.WORD = 0x400u; SYSTEM.PRCR.WORD = 0xA500u; } void board_pin_init(void) { /* Setup software configurable interrupts for USB */ ICU.SLIBR_USBI0.BYTE = IRQ_USB0_USBI0; ICU.SLIPRCR.BYTE = 1; /* Unlock MPC registers */ MPC.PWPR.BIT.B0WI = 0; MPC.PWPR.BIT.PFSWE = 1; /* Button PB1 */ PORTB.PMR.BIT.B1 = 0U; PORTB.PDR.BIT.B1 = 0U; /* LED PD6 (open-drain, active low) */ PORTD.PODR.BIT.B6 = 1U; PORTD.ODR1.BIT.B4 = 1U; PORTD.PMR.BIT.B6 = 0U; PORTD.PDR.BIT.B6 = 1U; /* UART TXD5 => PA4, RXD5 => PA3 */ PORTA.PMR.BIT.B4 = 1U; PORTA.PCR.BIT.B4 = 1U; MPC.PA4PFS.BYTE = 0b01010; PORTA.PMR.BIT.B3 = 1U; MPC.PA3PFS.BYTE = 0b01010; /* USB VBUS -> P16 */ PORT1.PMR.BIT.B6 = 1U; MPC.P16PFS.BYTE = MPC_PFS_ISEL | 0b10001; /* Lock MPC registers */ MPC.PWPR.BIT.PFSWE = 0; MPC.PWPR.BIT.B0WI = 1; /* Enable SCI5 */ SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(SCI5) = 0; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; SCI5.SEMR.BIT.ABCS = 1; SCI5.SEMR.BIT.BGDM = 1; SCI5.BRR = (SCI_PCLK / (8 * 115200)) - 1; IR(SCI5, RXI5) = 0; IR(SCI5, TXI5) = 0; IS(SCI5, TEI5) = 0; IR(ICU, GROUPBL0) = 0; IPR(SCI5, RXI5) = IRQ_PRIORITY_SCI5; IPR(SCI5, TXI5) = IRQ_PRIORITY_SCI5; IPR(ICU,GROUPBL0) = IRQ_PRIORITY_SCI5; IEN(SCI5, RXI5) = 1; IEN(SCI5, TXI5) = 1; IEN(ICU,GROUPBL0) = 1; EN(SCI5, TEI5) = 1; } ================================================ FILE: hw/bsp/rx/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" #include "interrupt_handlers.h" #define SYSTEM_PRCR_PRC1 (1<<1) #define SYSTEM_PRCR_PRKEY (0xA5u<<8) #define CMT_CMCR_CKS_DIV_128 2 #define CMT_CMCR_CMIE (1<<6) #define IRQ_PRIORITY_CMT0 5 #define IRQ_PRIORITY_USBI0 6 #define SCI_SSR_FER (1<<4) #define SCI_SSR_ORER (1<<5) #define SCI_SCR_TEIE (1u<<2) #define SCI_SCR_RE (1u<<4) #define SCI_SCR_TE (1u<<5) #define SCI_SCR_RIE (1u<<6) #define SCI_SCR_TIE (1u<<7) // Board-specific pin/peripheral init (implemented per board) void board_pin_init(void); //--------------------------------------------------------------------+ // SCI UART interrupt handlers //--------------------------------------------------------------------+ typedef struct { uint8_t *buf; uint32_t cnt; } sci_buf_t; static volatile sci_buf_t sci_buf[2]; void BOARD_SCI_TXI_HANDLER(void) { uint8_t *buf = sci_buf[0].buf; uint32_t cnt = sci_buf[0].cnt; if (!buf || !cnt) { BOARD_UART_SCI.SCR.BYTE &= ~(SCI_SCR_TEIE | SCI_SCR_TE | SCI_SCR_TIE); return; } BOARD_UART_SCI.TDR = *buf; if (--cnt) { ++buf; } else { buf = NULL; BOARD_UART_SCI.SCR.BIT.TIE = 0; BOARD_UART_SCI.SCR.BIT.TEIE = 1; } sci_buf[0].buf = buf; sci_buf[0].cnt = cnt; } void BOARD_SCI_TEI_HANDLER(void) { BOARD_UART_SCI.SCR.BYTE &= ~(SCI_SCR_TEIE | SCI_SCR_TE | SCI_SCR_TIE); } void BOARD_SCI_RXI_HANDLER(void) { uint8_t *buf = sci_buf[1].buf; uint32_t cnt = sci_buf[1].cnt; if (!buf || !cnt || (BOARD_UART_SCI.SSR.BYTE & (SCI_SSR_FER | SCI_SSR_ORER))) { sci_buf[1].buf = NULL; BOARD_UART_SCI.SSR.BYTE = 0; BOARD_UART_SCI.SCR.BYTE &= ~(SCI_SCR_RE | SCI_SCR_RIE); return; } *buf = BOARD_UART_SCI.RDR; if (--cnt) { ++buf; } else { buf = NULL; BOARD_UART_SCI.SCR.BYTE &= ~(SCI_SCR_RE | SCI_SCR_RIE); } sci_buf[1].buf = buf; sci_buf[1].cnt = cnt; } //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void BOARD_USB_IRQ_HANDLER(void) { #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); #endif } //--------------------------------------------------------------------+ // Board init //--------------------------------------------------------------------+ void board_init(void) { #if CFG_TUSB_OS == OPT_OS_NONE /* Enable CMT0 */ SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(CMT0) = 0; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; /* Setup 1ms tick timer */ CMT0.CMCNT = 0; CMT0.CMCOR = BOARD_PCLK / 1000 / 128; CMT0.CMCR.WORD = CMT_CMCR_CMIE | CMT_CMCR_CKS_DIV_128; IR(CMT0, CMI0) = 0; IPR(CMT0, CMI0) = IRQ_PRIORITY_CMT0; IEN(CMT0, CMI0) = 1; CMT.CMSTR0.BIT.STR0 = 1; #endif /* Board-specific: pin mux, SCI, USB pin config */ board_pin_init(); /* Enable USB0 module */ unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(USB0) = 0; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | oldPRCR; /* USB IRQ */ IR(USB0, USBI0) = 0; IPR(USB0, USBI0) = IRQ_PRIORITY_USBI0; } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { BOARD_LED_WRITE(state); } uint32_t board_button_read(void) { return BOARD_BUTTON_READ(); } int board_uart_read(uint8_t* buf, int len) { sci_buf[1].buf = buf; sci_buf[1].cnt = len; BOARD_UART_SCI.SCR.BYTE |= SCI_SCR_RE | SCI_SCR_RIE; while (BOARD_UART_SCI.SCR.BIT.RE) ; return len - sci_buf[1].cnt; } int board_uart_write(void const *buf, int len) { sci_buf[0].buf = (uint8_t*)(uintptr_t) buf; sci_buf[0].cnt = len; BOARD_UART_SCI.SCR.BYTE |= SCI_SCR_TE | SCI_SCR_TIE; while (BOARD_UART_SCI.SCR.BIT.TE) ; return len; } //--------------------------------------------------------------------+ // Tick timer //--------------------------------------------------------------------+ #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void INT_Excep_CMT0_CMI0(void) { ++system_ticks; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #else uint32_t SystemCoreClock = BOARD_CPUCLK; #endif //--------------------------------------------------------------------+ // Newlib syscall stubs //--------------------------------------------------------------------+ int close(int fd) { (void)fd; return -1; } int fstat(int fd, void *pstat) { (void)fd; (void)pstat; return 0; } off_t lseek(int fd, off_t pos, int whence) { (void)fd; (void)pos; (void)whence; return 0; } int isatty(int fd) { (void)fd; return 1; } ================================================ FILE: hw/bsp/rx/family.cmake ================================================ include_guard() set(MCU_DIR ${TOP}/hw/mcu/renesas/rx) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/rx_gcc.cmake) set(FAMILY_MCUS ${MCU_FAMILY} CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${MCU_DIR}/${MCU_VARIANT}/vects.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${MCU_DIR}/${MCU_VARIANT} ) target_compile_definitions(${BOARD_TARGET} PUBLIC SSIZE_MAX=__INT_MAX__ ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${MCU_FAMILY}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/renesas/rusb2/rusb2_common.c ${TOP}/src/portable/renesas/rusb2/dcd_rusb2.c ${TOP}/src/portable/renesas/rusb2/hcd_rusb2.c ${MCU_DIR}/${MCU_VARIANT}/start.S ${BOARD_SOURCES} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${TARGET} PUBLIC -Wno-error=redundant-decls ) target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) endif () set_source_files_properties(${MCU_DIR}/${MCU_VARIANT}/start.S PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Suppress warnings for board-specific and family source files set_source_files_properties( ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${BOARD_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_rfp(${TARGET}) endfunction() ================================================ FILE: hw/bsp/rx/family.mk ================================================ # Cross Compiler for RX CROSS_COMPILE = rx-elf- include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ -nostartfiles \ -ffunction-sections \ -fdata-sections \ -fshort-enums \ -mlittle-endian-data \ -DSSIZE_MAX=__INT_MAX__ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=redundant-decls LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/renesas/rusb2/dcd_rusb2.c \ src/portable/renesas/rusb2/hcd_rusb2.c \ src/portable/renesas/rusb2/rusb2_common.c \ $(MCU_DIR)/vects.c \ $(FAMILY_PATH)/family.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) SRC_S += $(MCU_DIR)/start.S $(BUILD)/$(PROJECT).mot: $(BUILD)/$(PROJECT).elf @echo CREATE $@ $(OBJCOPY) -O srec -I elf32-rx-be-ns $^ $@ # flash using rfp-cli flash-rfp: $(BUILD)/$(PROJECT).mot rfp-cli -device rx65x -tool e2l -if fine -fo id FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -auth id FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -auto $^ ================================================ FILE: hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "sam.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd11/boards/samd11_xplained/board.cmake ================================================ set(JLINK_DEVICE ATSAMD11D14) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd11d14am_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD11D14AM__ ) endfunction() ================================================ FILE: hw/bsp/samd11/boards/samd11_xplained/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAMD11 Xplained Pro url: https://www.microchip.com/en-us/development-tool/ATSAMD11-XPRO */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN PIN_PA16 // pin PA22 #define LED_STATE_ON 0 // Button #define BUTTON_PIN PIN_PA14 // pin PB22 #define BUTTON_STATE_ACTIVE 0 #define BUTTON_PULL_MODE GPIO_PULL_UP #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd11/boards/samd11_xplained/board.mk ================================================ CFLAGS += -D__SAMD11D14AM__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/samd11d14am_flash.ld # For flash-jlink target JLINK_DEVICE = ATSAMD11D14 # flash using edbg flash: $(BUILD)/$(PROJECT).bin edbg -b -t samd11 -e -pv -f $< ================================================ FILE: hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD11D14AM * * Copyright (c) 2018 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) ENTRY(Reset_Handler) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00004000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00001000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x400; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd11/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Microchip */ #include "sam.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #endif #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hri/hri_nvmctrl_d11.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl_pm_config.h" #include "hpl/pm/hpl_pm_base.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_Handler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ /* Referenced GCLKs, should be initialized firstly */ #define _GCLK_INIT_1ST (1 << 0 | 1 << 1) /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, 2); _pm_init(); _sysctrl_init_sources(); #if _GCLK_INIT_1ST _gclk_init_generators_by_fref(_GCLK_INIT_1ST); #endif _sysctrl_init_referenced_generators(); _gclk_init_generators_by_fref(_GCLK_INIT_LAST); // 1ms tick timer (samd SystemCoreClock may not correct) SystemCoreClock = CONF_CPU_FREQUENCY; #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(CONF_CPU_FREQUENCY / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif // Led init gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_level(LED_PIN, 0); // Button init gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, BUTTON_PULL_MODE); /* USB Clock init * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock * for low speed and full speed operation. */ _pm_enable_bus_clock(PM_BUS_APBB, USB); _pm_enable_bus_clock(PM_BUS_AHB, USB); _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); // USB Pin Init gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA24, false); gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA25, false); gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM); gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler (void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } void _init(void); void _init(void) { // This _init() standin makes certain GCC environments happier. // They expect the main binary to have a constructor called _init; but don't provide a weak default. // Providing an empty constructor satisfies this odd case, and doesn't harm anything. } #endif ================================================ FILE: hw/bsp/samd11/family.cmake ================================================ include_guard() set(SAM_FAMILY samd11) set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMD11 CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ${SDK_DIR}/hpl/pm/hpl_pm.c ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/include ${SDK_DIR}/hal/include ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/pm ${SDK_DIR}/hpl/port ${SDK_DIR}/hri ${CMSIS_5}/CMSIS/Core/Include ) target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0 OSC32K_OVERWRITE_CALIBRATION=0 CFG_EXAMPLE_MSC_READONLY CFG_EXAMPLE_VIDEO_READONLY CFG_EXAMPLE_MTP_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_SAMD11) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/microchip/samd/dcd_samd.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/samd11/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -mthumb \ -nostdlib -nostartfiles \ -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DOSC32K_OVERWRITE_CALIBRATION=0 \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_EXAMPLE_MTP_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_SAMD11 # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ hw/mcu/microchip/samd11/gcc/system_samd11.c \ hw/mcu/microchip/samd11/gcc/gcc/startup_samd11.c \ hw/mcu/microchip/samd11/hal/src/hal_atomic.c \ hw/mcu/microchip/samd11/hpl/gclk/hpl_gclk.c \ hw/mcu/microchip/samd11/hpl/pm/hpl_pm.c \ hw/mcu/microchip/samd11/hpl/sysctrl/hpl_sysctrl.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/hw/mcu/microchip/samd11/ \ $(TOP)/hw/mcu/microchip/samd11/config \ $(TOP)/hw/mcu/microchip/samd11/include \ $(TOP)/hw/mcu/microchip/samd11/hal/include \ $(TOP)/hw/mcu/microchip/samd11/hal/utils/include \ $(TOP)/hw/mcu/microchip/samd11/hpl/pm/ \ $(TOP)/hw/mcu/microchip/samd11/hpl/port \ $(TOP)/hw/mcu/microchip/samd11/hri \ $(TOP)/hw/mcu/microchip/samd11/CMSIS/Include \ $(TOP)/hw/mcu/microchip/samd11/CMSIS/Core/Include ================================================ FILE: hw/bsp/samd2x_l2x/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "sam.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/atsaml21_xpro/board.cmake ================================================ set(SAM_FAMILY saml21) set(JLINK_DEVICE ATSAML21J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/saml21j18b_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAML21J18B__ ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/atsaml21_xpro/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAML21 Xplained Pro url: https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN (32 + 30) // PB30 #define LED_STATE_ON 0 // Button #define BUTTON_PIN (0 + 15) // PA15 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/atsaml21_xpro/board.mk ================================================ SAM_FAMILY = saml21 CFLAGS += -D__SAML21J18B__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/saml21j18b_flash.ld # For flash-jlink target JLINK_DEVICE = ATSAML21J18 # flash using jlink flash: flash-jlink ================================================ FILE: hw/bsp/samd2x_l2x/boards/atsaml21_xpro/saml21j18b_flash.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAML21J18B * * Copyright (c) 2016 Atmel Corporation, * a wholly owned subsidiary of Microchip Technology Inc. * * \asf_license_start * * \page License * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) ENTRY(Reset_Handler) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 lpram (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00002000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .lpram (NOLOAD): { . = ALIGN(8); _slpram = .; *(.lpram .lpram.*); . = ALIGN(8); _elpram = .; } > lpram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/circuitplayground_express/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/circuitplayground_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Circuit Playground Express url: https://www.adafruit.com/product/3333 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 28 #define BUTTON_STATE_ACTIVE 1 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/circuitplayground_express/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/circuitplayground_express/circuitplayground_express.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/curiosity_nano/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE atsamd21g17a) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd21g17a_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G17A__ CFG_EXAMPLE_MSC_READONLY CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/curiosity_nano/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAMD21 Curiosty Nano url: https://www.microchip.com/en-us/development-tool/dm320119 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN (32 + 10) // PB10 #define LED_STATE_ON 0 // Button #define BUTTON_PIN (0 + 11) // PB11 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 31 // CDC5_RX #define UART_TX_PIN 37 // CDC5_TX static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/curiosity_nano/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G17A__ -DCFG_EXAMPLE_MSC_READONLY -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/samd21g17a_flash.ld # For flash-jlink target JLINK_DEVICE = atsamd21g17a # flash using jlink (options are: jlink/cmsisdap/stlink/dfu) #flash: flash-jlink PYOCD_TARGET = atsamd21g17a PYOCD_OPTION = -O dap_protocol=swd flash: flash-pyocd ================================================ FILE: hw/bsp/samd2x_l2x/boards/curiosity_nano/samd21g17a_flash.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G17A/D * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/cynthion_d21/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd21g18a_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) target_link_options(${TARGET} PUBLIC "LINKER:--defsym=BOOTLOADER_SIZE=0x800" ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/cynthion_d21/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Great Scott Gadgets Cynthion url: https://greatscottgadgets.com/cynthion/ */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN PIN_PA22 #define LED_STATE_ON 1 // Button #define BUTTON_PIN PIN_PB22 #define BUTTON_STATE_ACTIVE 0 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/cynthion_d21/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY LD_FILE = $(BOARD_PATH)/samd21g18a_flash.ld # Default bootloader size is now 2K, allow to specify other ifeq ($(BOOTLOADER_SIZE), ) BOOTLOADER_SIZE := 0x800 endif LDFLAGS += -Wl,--defsym=BOOTLOADER_SIZE=$(BOOTLOADER_SIZE) # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 # flash using dfu-util flash: $(BUILD)/$(PROJECT).bin dfu-util -a 0 -d 1d50:615c -D $< || dfu-util -a 0 -d 16d0:05a5 -D $< ================================================ FILE: hw/bsp/samd2x_l2x/boards/cynthion_d21/samd21g18a_flash.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + BOOTLOADER_SIZE, LENGTH = 0x00040000 - BOOTLOADER_SIZE ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/feather_m0_express/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/feather_m0_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather M0 Express url: https://www.adafruit.com/product/3403 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 15 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 // SPI for USB host shield #define MAX3421_SERCOM_ID 4 // SERCOM4 #define MAX3421_SERCOM_FUNCTION 3 // function D (Sercom Alt) #define MAX3421_SCK_PIN (32+11) #define MAX3421_MOSI_PIN (32+10) #define MAX3421_MISO_PIN 12 #define MAX3421_TX_PAD 1 // MOSI = PAD_2, SCK = PAD_3 #define MAX3421_RX_PAD 0 // MISO = PAD_2 #define MAX3421_CS_PIN 18 // D10 #define MAX3421_INTR_PIN 7 // D10 #define MAX3421_INTR_EIC_ID 7 // EIC7 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/feather_m0_express/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/feather_m0_express/feather_m0_express.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/itsybitsy_m0/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/itsybitsy_m0/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit ItsyBitsy M0 url: https://www.adafruit.com/product/3727 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 21 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/itsybitsy_m0/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/itsybitsy_m0/itsybitsy_m0.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/metro_m0_express/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/metro_m0_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Metro M0 Express url: https://www.adafruit.com/product/3505 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 #define LED_STATE_ON 1 // Button: D5 #define BUTTON_PIN 15 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 // SPI for USB host shield #define MAX3421_SERCOM_ID 4 // SERCOM4 #define MAX3421_SERCOM_FUNCTION 3 // function D (Sercom Alt) #define MAX3421_SCK_PIN (32+11) #define MAX3421_MOSI_PIN (32+10) #define MAX3421_MISO_PIN 12 #define MAX3421_TX_PAD 1 // MOSI = PAD_2, SCK = PAD_3 #define MAX3421_RX_PAD 0 // MISO = PAD_2 #define MAX3421_CS_PIN 18 // D10 #define MAX3421_INTR_PIN 7 // D9 #define MAX3421_INTR_EIC_ID 7 // EIC7 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/metro_m0_express/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/metro_m0_express/metro_m0_express.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/qtpy/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21E18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21E18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/qtpy/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit QT Py url: https://www.adafruit.com/product/4600 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED is neopixel, leave unset for now // Button is wired to reset // UART #define UART_RX_PIN 8 #define UART_TX_PIN 7 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/qtpy/board.mk ================================================ SAM_FAMILY = samd21 # For Adafruit QT Py board CFLAGS += -D__SAMD21E18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21E18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/qtpy/qtpy.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/saml22_feather/board.cmake ================================================ set(SAM_FAMILY saml22) set(JLINK_DEVICE ATSAML22J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAML22J18A__ ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/saml22_feather/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAML22 Feather url: https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN PIN_PA08 #define LED_STATE_ON 1 // Button #define BUTTON_PIN PIN_PA06 #define BUTTON_STATE_ACTIVE 0 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/saml22_feather/board.mk ================================================ SAM_FAMILY = saml22 CFLAGS += -D__SAML22J18A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAML22J18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/saml22_feather/saml22_feather.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAML22J18A * * Copyright (c) 2018 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) ENTRY(Reset_Handler) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/seeeduino_xiao/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/seeeduino_xiao/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Seeeduino XIAO url: https://wiki.seeedstudio.com/Seeeduino-XIAO/ */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 #define LED_STATE_ON 0 // Button #define BUTTON_PIN 9 // PA4 pin D1 on seed input #define BUTTON_STATE_ACTIVE 0 // UART #define UART_RX_PIN 4 #define UART_TX_PIN 5 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/seeeduino_xiao/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 # flash using jlink flash: flash-jlink ================================================ FILE: hw/bsp/samd2x_l2x/boards/seeeduino_xiao/seeeduino_xiao.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K /* 8K offset to preserve bootloader */ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/sensorwatch_m0/board.cmake ================================================ set(SAM_FAMILY saml22) set(JLINK_DEVICE ATSAML21J18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAML22J18A__ ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/sensorwatch_m0/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SensorWatch url: https://github.com/joeycastillo/Sensor-Watch */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN PIN_PA21 #define LED_STATE_ON 1 // Button #define BUTTON_PIN PIN_PA22 #define BUTTON_STATE_ACTIVE 1 #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/sensorwatch_m0/board.mk ================================================ SAM_FAMILY = saml22 CFLAGS += -D__SAML22J18A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAML22J18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/sensorwatch_m0/sensorwatch_m0.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAML22J18A * * Copyright (c) 2018 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) ENTRY(Reset_Handler) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/sparkfun_samd21_mini_usb/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21G18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21G18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/sparkfun_samd21_mini_usb/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SparkFun SAMD21 Mini url: https://www.sparkfun.com/products/13664 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 17 // PA17 (D13) #define LED_STATE_ON 1 // Button #define BUTTON_PIN 14 // PA14 (D2) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_SERCOM 0 #define UART_RX_PIN 11 // PA11 D0 #define UART_TX_PIN 10 // PA10 D1 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; gpio_set_pin_direction(PIN_PA28, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA28, state); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd2x_l2x/boards/sparkfun_samd21_mini_usb/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD21G18 flash: flash-bossac ================================================ FILE: hw/bsp/samd2x_l2x/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/trinket_m0/board.cmake ================================================ set(SAM_FAMILY samd21) set(JLINK_DEVICE ATSAMD21E18) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD21E18A__ CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/boards/trinket_m0/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Jean Gressmann * * 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. * */ /* metadata: name: Adafruit Trinket M0 url: https://www.adafruit.com/product/3500 */ #pragma once // LED #define LED_PIN 10 // PA10 #define LED_STATE_ON 1 // UART #define UART_SERCOM 0 #define UART_RX_PIN 7 #define UART_TX_PIN 6 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } ================================================ FILE: hw/bsp/samd2x_l2x/boards/trinket_m0/board.mk ================================================ SAM_FAMILY = samd21 CFLAGS += -D__SAMD21E18A__ -DCFG_EXAMPLE_VIDEO_READONLY # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/trinket_m0.ld ================================================ FILE: hw/bsp/samd2x_l2x/boards/trinket_m0/trinket_m0.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD21G18A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 0x00040000 - 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd2x_l2x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Microchip */ #include "sam.h" #include "bsp/board_api.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #endif #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hpl/gclk/hpl_gclk_base.h" // SAMD21 specific includes #if defined(__SAMD21E15A__) || defined(__SAMD21E16A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) || \ defined(__SAMD21G15A__) || defined(__SAMD21G16A__) || defined(__SAMD21G17A__) || defined(__SAMD21G18A__) || \ defined(__SAMD21J15A__) || defined(__SAMD21J16A__) || defined(__SAMD21J17A__) || defined(__SAMD21J18A__) #define SAMD21_FAMILY #include "hri/hri_nvmctrl_d21.h" #include "hpl_pm_config.h" #include "hpl/pm/hpl_pm_base.h" #endif // SAML21/22 specific includes #if defined(__SAML21E15B__) || defined(__SAML21E16B__) || defined(__SAML21E17B__) || defined(__SAML21E18B__) || \ defined(__SAML21G16B__) || defined(__SAML21G17B__) || defined(__SAML21G18B__) || \ defined(__SAML21J16B__) || defined(__SAML21J17B__) || defined(__SAML21J18B__) || \ defined(__SAML22G16A__) || defined(__SAML22G17A__) || defined(__SAML22G18A__) || \ defined(__SAML22J16A__) || defined(__SAML22J17A__) || defined(__SAML22J18A__) || \ defined(__SAML22N16A__) || defined(__SAML22N17A__) || defined(__SAML22N18A__) #define SAML2X_FAMILY #include "hpl_mclk_config.h" #endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "board.h" // board_vbus_set is defined in board.h for boards that support it #if !defined(board_vbus_set) #define board_vbus_set(rhport, state) do { (void)(rhport); (void)(state); } while(0) #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #ifdef SAMD21_FAMILY /* Referenced GCLKs, should be initialized firstly */ #define _GCLK_INIT_1ST (1 << 0 | 1 << 1) /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) #endif #ifdef SAML2X_FAMILY /* Referenced GCLKs (out of 0~4), should be initialized firstly */ #define _GCLK_INIT_1ST 0x00000000 /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST 0x0000001F #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_Handler(void) { #if CFG_TUD_ENABLED tud_int_handler(0); #endif #if CFG_TUH_ENABLED && !CFG_TUH_MAX3421 tuh_int_handler(0); #endif } //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ static void uart_init(void); #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 #define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) static void max3421_init(void); #endif void board_init(void) { #ifdef SAMD21_FAMILY // Clock init for SAMD21 ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, 2); _pm_init(); _sysctrl_init_sources(); #if _GCLK_INIT_1ST _gclk_init_generators_by_fref(_GCLK_INIT_1ST); #endif _sysctrl_init_referenced_generators(); _gclk_init_generators_by_fref(_GCLK_INIT_LAST); #endif #ifdef SAML2X_FAMILY // Clock init for SAML2x ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, CONF_NVM_WAIT_STATE); _set_performance_level(2); _osc32kctrl_init_sources(); _oscctrl_init_sources(); _mclk_init(); #if _GCLK_INIT_1ST _gclk_init_generators_by_fref(_GCLK_INIT_1ST); #endif _oscctrl_init_referenced_generators(); _gclk_init_generators_by_fref(_GCLK_INIT_LAST); #if (CONF_PORT_EVCTRL_PORT_0 | CONF_PORT_EVCTRL_PORT_1 | CONF_PORT_EVCTRL_PORT_2 | CONF_PORT_EVCTRL_PORT_3) hri_port_set_EVCTRL_reg(PORT, 0, CONF_PORTA_EVCTRL); hri_port_set_EVCTRL_reg(PORT, 1, CONF_PORTB_EVCTRL); #endif #endif // Update SystemCoreClock since it is hard coded with asf4 and not correct // Init 1ms tick timer (samd SystemCoreClock may not correct) SystemCoreClock = CONF_CPU_FREQUENCY; #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(CONF_CPU_FREQUENCY / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif // Led init #ifdef LED_PIN gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); board_led_write(false); #endif // Button init #ifdef BUTTON_PIN gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULL_DOWN : GPIO_PULL_UP); #endif uart_init(); #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif /* USB Clock init * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock * for low speed and full speed operation. */ #ifdef SAMD21_FAMILY _pm_enable_bus_clock(PM_BUS_APBB, USB); _pm_enable_bus_clock(PM_BUS_AHB, USB); _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); #endif #ifdef SAML2X_FAMILY hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); hri_mclk_set_AHBMASK_USB_bit(MCLK); hri_mclk_set_APBBMASK_USB_bit(MCLK); #endif // USB Pin Init gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA24, false); gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA25, false); gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM); gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP); #ifdef SAMD21_FAMILY // Output 500hz PWM on D12 (PA19 - TCC0 WO[3]) so we can validate the GCLK0 clock speed with a Saleae. _pm_enable_bus_clock(PM_BUS_APBC, TCC0); TCC0->PER.bit.PER = 48000000 / 1000; TCC0->CC[3].bit.CC = 48000000 / 2000; TCC0->CTRLA.bit.ENABLE = true; gpio_set_pin_function(PIN_PA19, PINMUX_PA19F_TCC0_WO3); _gclk_enable_channel(TCC0_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); #endif #if CFG_TUH_ENABLED #if CFG_TUH_MAX3421 max3421_init(); #else // VBUS Power board_vbus_set(0, true); #endif #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { (void) state; #ifdef LED_PIN gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #endif } uint32_t board_button_read(void) { #ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); #else return 0; #endif } #if defined(UART_SERCOM) #define BOARD_SERCOM2(n) SERCOM ## n #define BOARD_SERCOM(n) BOARD_SERCOM2(n) static void uart_init(void) { #if UART_SERCOM == 0 #if UART_TX_PIN == 6 gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); #elif UART_TX_PIN == 10 gpio_set_pin_function(PIN_PA10, PINMUX_PA10C_SERCOM0_PAD2); #else #error "UART_TX_PIN not supported" #endif #if UART_RX_PIN == 7 gpio_set_pin_function(PIN_PA07, PINMUX_PA07D_SERCOM0_PAD3); #elif UART_RX_PIN == 11 gpio_set_pin_function(PIN_PA11, PINMUX_PA11C_SERCOM0_PAD3); #else #error "UART_RX_PIN not supported" #endif #ifdef SAMD21_FAMILY // setup clock (48MHz) _pm_enable_bus_clock(PM_BUS_APBC, SERCOM0); _gclk_enable_channel(SERCOM0_GCLK_ID_CORE, GCLK_CLKCTRL_GEN_GCLK0_Val); #endif #ifdef SAML2X_FAMILY // setup clock (48MHz) hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM0_GCLK_ID_CORE, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); hri_mclk_set_APBCMASK_SERCOM0_bit(MCLK); #endif SERCOM0->USART.CTRLA.bit.SWRST = 1; /* reset SERCOM & enable config */ while(SERCOM0->USART.SYNCBUSY.bit.SWRST); SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ SERCOM_USART_CTRLA_DORD | /* LSB first */ SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ SERCOM_USART_CTRLA_RXPO(3) | /* pad 3 */ SERCOM_USART_CTRLA_TXPO(1); /* pad 2 */ SERCOM0->USART.CTRLB.reg = SERCOM_USART_CTRLB_TXEN | /* tx enabled */ SERCOM_USART_CTRLB_RXEN; /* rx enabled */ /* 115200 */ SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); SERCOM0->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ #endif } static inline void uart_send_buffer(uint8_t const *text, size_t len) { for (size_t i = 0; i < len; ++i) { BOARD_SERCOM(UART_SERCOM)->USART.DATA.reg = text[i]; while((BOARD_SERCOM(UART_SERCOM)->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); } } static inline void uart_send_str(const char* text) { while (*text) { BOARD_SERCOM(UART_SERCOM)->USART.DATA.reg = *text++; while((BOARD_SERCOM(UART_SERCOM)->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); } } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const * buf, int len) { if (len < 0) { uart_send_str(buf); } else { uart_send_buffer(buf, len); } return len; } #else // ! defined(UART_SERCOM) static void uart_init(void) { } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #endif #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static void max3421_init(void) { //------------- SPI Init -------------// // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz uint32_t const baudrate = 12000000u; #ifdef SAMD21_FAMILY // Enable the APB clock for SERCOM PM->APBCMASK.reg |= 1u << (PM_APBCMASK_SERCOM0_Pos + MAX3421_SERCOM_ID); // Configure GCLK for SERCOM GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val + MAX3421_SERCOM_ID) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; while (GCLK->STATUS.bit.SYNCBUSY); #endif #ifdef SAML2X_FAMILY // Enable the APB clock for SERCOM hri_mclk_set_APBCMASK_reg(MCLK, 1u << (MCLK_APBCMASK_SERCOM0_Pos + MAX3421_SERCOM_ID)); // Configure GCLK for SERCOM hri_gclk_write_PCHCTRL_reg(GCLK, SERCOM0_GCLK_ID_CORE + MAX3421_SERCOM_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); #endif Sercom* sercom = MAX3421_SERCOM; // Disable the SPI module sercom->SPI.CTRLA.bit.ENABLE = 0; // Reset the SPI module sercom->SPI.CTRLA.bit.SWRST = 1; while (sercom->SPI.SYNCBUSY.bit.SWRST); // Set up SPI in master mode, MSB first, SPI mode 0 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | SERCOM_SPI_CTRLA_MODE(3); sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); // Set the baud rate sercom->SPI.BAUD.reg = (uint8_t) (SystemCoreClock / (2 * baudrate) - 1); // Configure SPI pins gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); // CS pin gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_level(MAX3421_CS_PIN, 1); // Enable the SPI module sercom->SPI.CTRLA.bit.ENABLE = 1; while (sercom->SPI.SYNCBUSY.bit.ENABLE); //------------- External Interrupt -------------// #ifdef SAMD21_FAMILY // Enable the APB clock for EIC (External Interrupt Controller) PM->APBAMASK.reg |= PM_APBAMASK_EIC; // Configure GCLK for EIC GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EIC | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; while (GCLK->STATUS.bit.SYNCBUSY); #endif #ifdef SAML2X_FAMILY // Enable the APB clock for EIC hri_mclk_set_APBAMASK_EIC_bit(MCLK); // Configure GCLK for EIC hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); #endif // Configure interrupt pin as an input with function A (external interrupt) gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); gpio_set_pin_function(MAX3421_INTR_PIN, 0); // Disable EIC EIC->CTRL.bit.ENABLE = 0; while (EIC->STATUS.bit.SYNCBUSY); // Configure EIC to trigger on falling edge uint8_t const sense_shift = MAX3421_INTR_EIC_ID * 4; EIC->CONFIG[0].reg &= ~(7 << sense_shift); EIC->CONFIG[0].reg |= 2 << sense_shift; #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(EIC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // Enable External Interrupt EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); // Enable EIC EIC->CTRL.bit.ENABLE = 1; while (EIC->STATUS.bit.SYNCBUSY); } void EIC_Handler(void) { // Clear the interrupt flag EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); // Call the TinyUSB interrupt handler tuh_int_handler(1, true); } // API to enable/disable MAX3421 INTR pin interrupt void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; if (enabled) { NVIC_EnableIRQ(EIC_IRQn); } else { NVIC_DisableIRQ(EIC_IRQn); } } // API to control MAX3421 SPI CS void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); } // API to transfer data with MAX3421 SPI // Either tx_buf or rx_buf can be NULL, which means transfer is write or read only bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { (void) rhport; Sercom* sercom = MAX3421_SERCOM; for (size_t count = 0; count < xfer_bytes; count++) { // Wait for the transmit buffer to be empty while (!sercom->SPI.INTFLAG.bit.DRE); // Write data to be transmitted uint8_t data = 0x00; if (tx_buf) { data = tx_buf[count]; } sercom->SPI.DATA.reg = (uint32_t) data; // Wait for the receive buffer to be filled while (!sercom->SPI.INTFLAG.bit.RXC); // Read received data data = (uint8_t) sercom->SPI.DATA.reg; if (rx_buf) { rx_buf[count] = data; } } // wait for bus idle and clear flags while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; return true; } #endif // Stub for libc init array (required by SAML21/SAML22) #ifdef SAML2X_FAMILY void _init(void); void _init(void) { } #endif ================================================ FILE: hw/bsp/samd2x_l2x/family.cmake ================================================ include_guard() # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # Determine which SAM family based on board configuration # SAM_FAMILY should be set by board.cmake (samd21, saml21, or saml22) if(NOT DEFINED SAM_FAMILY) # Default to samd21 if not specified for backward compatibility set(SAM_FAMILY samd21) endif() set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMD21 SAML2X CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) # Common sources for all SAM families set(COMMON_SOURCES ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ) # Family-specific sources if(SAM_FAMILY STREQUAL "samd21") list(APPEND COMMON_SOURCES ${SDK_DIR}/hpl/pm/hpl_pm.c ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c ) else() # SAML21/SAML22 list(APPEND COMMON_SOURCES ${SDK_DIR}/hpl/mclk/hpl_mclk.c ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c ${SDK_DIR}/hpl/pm/hpl_pm.c ) endif() add_library(${BOARD_TARGET} STATIC ${COMMON_SOURCES}) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/include ${SDK_DIR}/hal/include ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/pm ${SDK_DIR}/hpl/port ${SDK_DIR}/hri ${CMSIS_5}/CMSIS/Core/Include ) # Family-specific compile definitions if(SAM_FAMILY STREQUAL "samd21") target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0 ) else() # SAML21/SAML22 target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_OSC32K_CALIB_ENABLE=0 CFG_EXAMPLE_VIDEO_READONLY ) endif() update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) # Determine MCU option based on SAM_FAMILY if(SAM_FAMILY STREQUAL "samd21") set(MCU_OPTION OPT_MCU_SAMD21) elseif(SAM_FAMILY STREQUAL "saml21") set(MCU_OPTION OPT_MCU_SAML21) elseif(SAM_FAMILY STREQUAL "saml22") set(MCU_OPTION OPT_MCU_SAML22) else() message(FATAL_ERROR "Unknown SAM_FAMILY: ${SAM_FAMILY}") endif() family_add_tinyusb(${TARGET} ${MCU_OPTION}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/microchip/samd/dcd_samd.c ${TOP}/src/portable/microchip/samd/hcd_samd.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) # Add HCD support for SAMD21 (has host capability) if(SAM_FAMILY STREQUAL "samd21") target_sources(${TARGET} PUBLIC ${TOP}/src/portable/microchip/samd/hcd_samd.c ) endif() target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/samd2x_l2x/family.mk ================================================ UF2_FAMILY_ID = 0x68ed2b88 include $(TOP)/$(BOARD_PATH)/board.mk # SAM_FAMILY should be set by board.mk (samd21, saml21, or saml22) ifeq ($(SAM_FAMILY),) # Default to samd21 if not specified for backward compatibility SAM_FAMILY = samd21 endif SDK_DIR = hw/mcu/microchip/$(SAM_FAMILY) CPU_CORE ?= cortex-m0plus # Common CFLAGS CFLAGS += \ -flto \ # Family-specific CFLAGS ifeq ($(SAM_FAMILY),samd21) CFLAGS += \ -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 else # SAML21/SAML22 CFLAGS += \ -DCONF_OSC32K_CALIB_ENABLE=0 \ -DCFG_EXAMPLE_VIDEO_READONLY \ ifeq ($(SAM_FAMILY),saml21) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAML21 else ifeq ($(SAM_FAMILY),saml22) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAML22 endif endif # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ LDFLAGS_CLANG += # Common source files SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ ${SDK_DIR}/gcc/gcc/startup_$(SAM_FAMILY).c \ ${SDK_DIR}/gcc/system_$(SAM_FAMILY).c \ ${SDK_DIR}/hal/src/hal_atomic.c \ ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ # Family-specific source files ifeq ($(SAM_FAMILY),samd21) SRC_C += \ src/portable/microchip/samd/hcd_samd.c \ ${SDK_DIR}/hpl/pm/hpl_pm.c \ ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c \ else # SAML21/SAML22 SRC_C += \ ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ ${SDK_DIR}/hpl/pm/hpl_pm.c \ endif INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/${SDK_DIR} \ $(TOP)/${SDK_DIR}/config \ $(TOP)/${SDK_DIR}/include \ $(TOP)/${SDK_DIR}/hal/include \ $(TOP)/${SDK_DIR}/hal/utils/include \ $(TOP)/${SDK_DIR}/hpl/pm/ \ $(TOP)/${SDK_DIR}/hpl/port \ $(TOP)/${SDK_DIR}/hri \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ # Add it to your PATH or change BOSSAC variable to match your installation BOSSAC = bossac flash-bossac: $(BUILD)/$(PROJECT).bin @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x2000 -e -w $^ -R ================================================ FILE: hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "sam.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; end = .; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake ================================================ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather M4 Express url: https://www.adafruit.com/product/3857 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define _PINNUM(port, pin) ((port)*32 + (pin)) // LED #define LED_PIN 23 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 16 // D5 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_TX_PIN (32 + 17) #define UART_RX_PIN (32 + 16) // SPI for USB host shield #define MAX3421_SERCOM_ID 1 // SERCOM2 #define MAX3421_SERCOM_FUNCTION 2 // function C #define MAX3421_SCK_PIN _PINNUM(0, 17) #define MAX3421_MOSI_PIN _PINNUM(1, 23) #define MAX3421_MISO_PIN _PINNUM(1, 22) #define MAX3421_TX_PAD 2 // MOSI = PAD_3, SCK = PAD_1 #define MAX3421_RX_PAD 2 // MISO = PAD_2 #define MAX3421_CS_PIN 20 // D10 #define MAX3421_INTR_PIN 19 // D9 #define MAX3421_INTR_EIC_ID 3 // EIC3 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk ================================================ SAM_FAMILY = samd51 CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD51J19 flash: flash-bossac ================================================ FILE: hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD51G19A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake ================================================ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit ItsyBitsy M4 url: https://www.adafruit.com/product/3800 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 22 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 18 // D5 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_TX_PIN 16 #define UART_RX_PIN 17 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk ================================================ SAM_FAMILY = samd51 CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD51J19 flash: flash-bossac ================================================ FILE: hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD51G19A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake ================================================ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Metro M4 Express url: https://www.adafruit.com/product/3382 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 16 #define LED_STATE_ON 1 // Button: D5 #define BUTTON_PIN (32+14) #define BUTTON_STATE_ACTIVE 0 // UART #define UART_TX_PIN 23 #define UART_RX_PIN 22 // SPI for USB host shield #define MAX3421_SERCOM_ID 2 // SERCOM2 #define MAX3421_SERCOM_FUNCTION 2 // function C #define MAX3421_SCK_PIN 13 #define MAX3421_MOSI_PIN 12 #define MAX3421_MISO_PIN 14 #define MAX3421_TX_PAD 0 // MOSI = PAD_0, SCK = PAD_1 #define MAX3421_RX_PAD 2 // MISO = PAD_2 #define MAX3421_CS_PIN 18 // D10 #define MAX3421_INTR_PIN 20 // D9 #define MAX3421_INTR_EIC_ID 4 // EIC4 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk ================================================ SAM_FAMILY = samd51 CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD51J19 flash: flash-bossac ================================================ FILE: hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD51G19A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/pybadge/board.cmake ================================================ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/pybadge/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit PyBadge url: https://www.adafruit.com/product/4200 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN 23 #define LED_STATE_ON 1 // Button #define BUTTON_PIN 16 // D5 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_TX_PIN (32 + 17) #define UART_RX_PIN (32 + 16) static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/pybadge/board.mk ================================================ SAM_FAMILY = samd51 CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD51J19 flash: flash-bossac ================================================ FILE: hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD51G19A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/pyportal/board.cmake ================================================ set(SAM_FAMILY samd51) set(JLINK_DEVICE ATSAMD51J19) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAMD51J19A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/pyportal/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit PyPortal url: https://www.adafruit.com/product/4116 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN (32+23) #define LED_STATE_ON 1 // Button #define BUTTON_PIN (32+22) // D2 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_TX_PIN (32 + 13) #define UART_RX_PIN (32 + 12) static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/pyportal/board.mk ================================================ SAM_FAMILY = samd51 CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld # For flash-jlink target JLINK_DEVICE = ATSAMD51J19 flash: flash-bossac ================================================ FILE: hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAMD51G19A * * Copyright (c) 2017 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake ================================================ set(SAM_FAMILY same54) set(JLINK_DEVICE ATSAME54P20) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same54p20a_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAME54P20A__ ) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/boards/same54_xplained/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAME54 Xplained Pro url: https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAME54-XPRO */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PIN PIN_PC18 #define LED_STATE_ON 1 // Button: D5 #define BUTTON_PIN PIN_PB31 #define BUTTON_STATE_ACTIVE 0 // UART: SERCOM2 //#define UART_TX_PIN 23 //#define UART_RX_PIN 22 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk ================================================ SAM_FAMILY = same54 CFLAGS += -D__SAME54P20A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld # For flash-jlink target JLINK_DEVICE = ATSAME54P20 ================================================ FILE: hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld ================================================ /** * \file * * \brief Linker script for running in internal FLASH on the SAME54P20A * * Copyright (c) 2019 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; end = .; } ================================================ FILE: hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld ================================================ /** * \file * * \brief Linker script for running in internal SRAM on the SAME54P20A * * Copyright (c) 2019 Microchip Technology Inc. * * \asf_license_start * * \page License * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the Licence at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * \asf_license_stop * */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > ram /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > ram PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bkupram (NOLOAD): { . = ALIGN(8); _sbkupram = .; *(.bkupram .bkupram.*); . = ALIGN(8); _ebkupram = .; } > bkupram .qspi (NOLOAD): { . = ALIGN(8); _sqspi = .; *(.qspi .qspi.*); . = ALIGN(8); _eqspi = .; } > qspi /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; end = .; } ================================================ FILE: hw/bsp/samd5x_e5x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Microchip */ #include "sam.h" #include "bsp/board_api.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #endif #include "hal_gpio.h" #include "hal_init.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl_mclk_config.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif static inline void board_vbus_set(uint8_t rhport, bool state) TU_ATTR_UNUSED; #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ /* Referenced GCLKs, should be initialized firstly */ #define _GCLK_INIT_1ST 0xFFFFFFFF /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void USB_Any_Handler(void) { #if CFG_TUD_ENABLED tud_int_handler(0); #endif #if CFG_TUH_ENABLED && !CFG_TUH_MAX3421 tuh_int_handler(0); #endif } void USB_0_Handler(void) { USB_Any_Handler(); } void USB_1_Handler(void) { USB_Any_Handler(); } void USB_2_Handler(void) { USB_Any_Handler(); } void USB_3_Handler(void) { USB_Any_Handler(); } //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 #define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) #define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler) static void max3421_init(void); #endif void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); _osc32kctrl_init_sources(); _oscctrl_init_sources(); _mclk_init(); #if _GCLK_INIT_1ST _gclk_init_generators_by_fref(_GCLK_INIT_1ST); #endif _oscctrl_init_referenced_generators(); _gclk_init_generators_by_fref(_GCLK_INIT_LAST); // Update SystemCoreClock since it is hard coded with asf4 and not correct // Init 1ms tick timer (samd SystemCoreClock may not correct) SystemCoreClock = CONF_CPU_FREQUENCY; #if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(CONF_CPU_FREQUENCY / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif // Led init gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_level(LED_PIN, 0); #ifdef BUTTON_PIN // Button init gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); #endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif /* USB Clock init * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock * for low speed and full speed operation. */ hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); hri_mclk_set_AHBMASK_USB_bit(MCLK); hri_mclk_set_APBBMASK_USB_bit(MCLK); // USB Pin Init gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA24, false); gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA25, false); gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); #if CFG_TUH_ENABLED #if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 max3421_init(); #else // VBUS Power board_vbus_set(0, true); #endif #endif } void board_init_after_tusb(void) { } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { gpio_set_pin_level(LED_PIN, state); } uint32_t board_button_read(void) { // button is active low #ifdef BUTTON_PIN return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; uint32_t did_addr[4] = {0x008061FC, 0x00806010, 0x00806014, 0x00806018}; for (int i = 0; i < 4; i++) { uint32_t did = *((uint32_t const*) did_addr[i]); did = TU_BSWAP32(did); // swap endian to match samd51 uf2 bootloader memcpy(id + i * 4, &did, sizeof(uint32_t)); } return 16; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #if 0 /* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ static inline void uart_init(void) { gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); MCLK->APBBMASK.bit.SERCOM2_ = 1; GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); BOARD_SERCOM->USART.CTRLA.reg = SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ SERCOM_USART_CTRLA_DORD | /* LSB first */ SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ } static inline void uart_send_buffer(uint8_t const* text, size_t len) { for (size_t i = 0; i < len; ++i) { BOARD_SERCOM->USART.DATA.reg = text[i]; while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); } } static inline void uart_send_str(const char* text) { while (*text) { BOARD_SERCOM->USART.DATA.reg = *text++; while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); } } #endif #endif //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 static void max3421_init(void) { //------------- SPI Init -------------// // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz uint32_t const baudrate = 12000000u; struct { volatile uint32_t* mck_apb; uint32_t mask; uint8_t gclk_id_core; uint8_t gclk_id_slow; } const sercom_clock[] = { { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW }, { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW }, { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW }, { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW }, { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW }, { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW }, #ifdef SERCOM6_GCLK_ID_CORE { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW }, #endif #ifdef SERCOM7_GCLK_ID_CORE { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW }, #endif }; Sercom* sercom = MAX3421_SERCOM; // Enable the APB clock for SERCOM *sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask; // Configure GCLK for SERCOM GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); // Disable the SPI module sercom->SPI.CTRLA.bit.ENABLE = 0; // Reset the SPI module sercom->SPI.CTRLA.bit.SWRST = 1; while (sercom->SPI.SYNCBUSY.bit.SWRST); // Set up SPI in master mode, MSB first, SPI mode 0 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | SERCOM_SPI_CTRLA_MODE(3); sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); // Set the baud rate uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate)); if (baud_reg) { baud_reg--; } sercom->SPI.BAUD.reg = baud_reg; // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); // CS pin gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_level(MAX3421_CS_PIN, 1); // Enable the SPI module sercom->SPI.CTRLA.bit.ENABLE = 1; while (sercom->SPI.SYNCBUSY.bit.ENABLE) {} //------------- External Interrupt -------------// // Enable the APB clock for EIC (External Interrupt Controller) MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC; // Configure GCLK for EIC GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); // Configure PA20 as an input with function A (external interrupt) gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); gpio_set_pin_function(MAX3421_INTR_PIN, 0); // Disable EIC EIC->CTRLA.bit.ENABLE = 0; while (EIC->SYNCBUSY.bit.ENABLE); // Configure EIC to trigger on falling edge volatile uint32_t* eic_config; uint8_t sense_shift; if (MAX3421_INTR_EIC_ID < 8) { eic_config = &EIC->CONFIG[0].reg; sense_shift = MAX3421_INTR_EIC_ID * 4; } else { eic_config = &EIC->CONFIG[1].reg; sense_shift = (MAX3421_INTR_EIC_ID - 8) * 4; } *eic_config &= ~(7 << sense_shift); *eic_config |= 2 << sense_shift; #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // Enable External Interrupt EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); // Enable EIC EIC->CTRLA.bit.ENABLE = 1; while (EIC->SYNCBUSY.bit.ENABLE); } void MAX3421_EIC_Handler(void) { // Clear the interrupt flag EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); // Call the TinyUSB interrupt handler tuh_int_handler(1, true); } // API to enable/disable MAX3421 INTR pin interrupt void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; const IRQn_Type irq = EIC_0_IRQn + MAX3421_INTR_EIC_ID; if (enabled) { NVIC_EnableIRQ(irq); } else { NVIC_DisableIRQ(irq); } } // API to control MAX3421 SPI CS void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); } // API to transfer data with MAX3421 SPI // Either tx_buf or rx_buf can be NULL, which means transfer is write or read only bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { (void) rhport; Sercom* sercom = MAX3421_SERCOM; for (size_t count = 0; count < xfer_bytes; count++) { // Wait for the transmit buffer to be empty while (!sercom->SPI.INTFLAG.bit.DRE); // Write data to be transmitted uint8_t data = 0x00; if (tx_buf) { data = tx_buf[count]; } sercom->SPI.DATA.reg = (uint32_t) data; // Wait for the receive buffer to be filled while (!sercom->SPI.INTFLAG.bit.RXC); // Read received data data = (uint8_t) sercom->SPI.DATA.reg; if (rx_buf) { rx_buf[count] = data; } } // wait for bus idle and clear flags while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; return true; } #endif void HardFault_Handler(void) { __BKPT(0); while (1); } ================================================ FILE: hw/bsp/samd5x_e5x/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMD51 SAME54 CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c ${SDK_DIR}/hpl/mclk/hpl_mclk.c ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/include ${SDK_DIR}/hal/include ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/port ${SDK_DIR}/hri ${CMSIS_5}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_SAMD51) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/microchip/samd/dcd_samd.c ${TOP}/src/portable/microchip/samd/hcd_samd.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) #family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/samd5x_e5x/family.mk ================================================ UF2_FAMILY_ID = 0x55114460 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 SDK_DIR = hw/mcu/microchip/${SAM_FAMILY} CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_SAMD51 # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ src/portable/microchip/samd/hcd_samd.c \ ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c \ ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c \ ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ ${SDK_DIR}/hal/src/hal_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/${SDK_DIR} \ $(TOP)/${SDK_DIR}/config \ $(TOP)/${SDK_DIR}/include \ $(TOP)/${SDK_DIR}/hal/include \ $(TOP)/${SDK_DIR}/hal/utils/include \ $(TOP)/${SDK_DIR}/hpl/port \ $(TOP)/${SDK_DIR}/hri \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ # Add it to your PATH or change BOSSAC variable to match your installation BOSSAC = bossac flash-bossac: $(BUILD)/$(PROJECT).bin @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R # flash using edbg from https://github.com/ataradov/edbg flash-edbg: $(BUILD)/$(PROJECT).bin edbg --verbose -t $(MCU) -pv -f $< ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/board.cmake ================================================ set(JLINK_DEVICE ATSAME70N19B) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same70n19b_flash.ld) # N19B and Q21B share the same vector table / startup code set(STARTUP_FILE_GNU ${TOP}/hw/mcu/microchip/same70/same70b/gcc/gcc/startup_same70q21b.c) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAME70N19B__ ) endfunction() ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAME70 QMTech manufacturer: Microchip url: https://www.aliexpress.com/item/1005003173783268.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PIN GPIO(GPIO_PORTA, 15) #define LED_STATE_ON 1 #define LED_PORT_CLOCK ID_PIOB #define BUTTON_PIN GPIO(GPIO_PORTA, 21) #define BUTTON_STATE_ACTIVE 0 #define BUTTON_PORT_CLOCK ID_PIOA #define UART_TX_PIN GPIO(GPIO_PORTB, 1) #define UART_TX_FUNCTION MUX_PB4D_USART1_TXD1 #define UART_RX_PIN GPIO(GPIO_PORTB, 0) #define UART_RX_FUNCTION MUX_PA21A_USART1_RXD1 #define UART_PORT_CLOCK ID_USART1 #define BOARD_USART USART1 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/board.mk ================================================ CFLAGS += -D__SAME70N19B__ LD_FILE = $(BOARD_PATH)/same70n19b_flash.ld STARTUP_FILE = $(SDK_DIR)/same70b/gcc/gcc/startup_same70q21b.c JLINK_DEVICE = ATSAME70N19B ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/hpl_pmc_config.h ================================================ /* Auto-generated config file hpl_pmc_config.h */ #ifndef HPL_PMC_CONFIG_H #define HPL_PMC_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> #include #define CLK_SRC_OPTION_OSC32K 0 #define CLK_SRC_OPTION_XOSC32K 1 #define CLK_SRC_OPTION_OSC12M 2 #define CLK_SRC_OPTION_XOSC20M 3 #define CLK_SRC_OPTION_SLCK 0 #define CLK_SRC_OPTION_MAINCK 1 #define CLK_SRC_OPTION_PLLACK 2 #define CLK_SRC_OPTION_UPLLCKDIV 3 #define CLK_SRC_OPTION_MCK 4 #define CLK_SRC_OPTION_UPLLCK 3 #define CONF_RC_4M 0 #define CONF_RC_8M 1 #define CONF_RC_12M 2 #define CONF_XOSC32K_NO_BYPASS 0 #define CONF_XOSC32K_BYPASS 1 #define CONF_XOSC20M_NO_BYPASS 0 #define CONF_XOSC20M_BYPASS 1 // Clock_SLCK configuration // Indicates whether SLCK configuration is enabled or not // enable_clk_gen_slck #ifndef CONF_CLK_SLCK_CONFIG #define CONF_CLK_SLCK_CONFIG 1 #endif // Clock Generator // clock generator SLCK source // 32kHz High Accuracy Internal Oscillator (OSC32K) // 32kHz External Crystal Oscillator (XOSC32K) // This defines the clock source for SLCK // clk_gen_slck_oscillator #ifndef CONF_CLK_GEN_SLCK_SRC #define CONF_CLK_GEN_SLCK_SRC CLK_SRC_OPTION_OSC32K #endif // Enable Clock_SLCK // Indicates whether SLCK is enabled or disable // clk_gen_slck_arch_enable #ifndef CONF_CLK_SLCK_ENABLE #define CONF_CLK_SLCK_ENABLE 1 #endif // // // // // Clock_MAINCK configuration // Indicates whether MAINCK configuration is enabled or not // enable_clk_gen_mainck #ifndef CONF_CLK_MAINCK_CONFIG #define CONF_CLK_MAINCK_CONFIG 1 #endif // Clock Generator // clock generator MAINCK source // Embedded 4/8/12MHz RC Oscillator (OSC12M) // External 3-20MHz Oscillator (XOSC20M) // This defines the clock source for MAINCK // clk_gen_mainck_oscillator #ifndef CONF_CLK_GEN_MAINCK_SRC #define CONF_CLK_GEN_MAINCK_SRC CLK_SRC_OPTION_XOSC20M #endif // Enable Clock_MAINCK // Indicates whether MAINCK is enabled or disable // clk_gen_mainck_arch_enable #ifndef CONF_CLK_MAINCK_ENABLE #define CONF_CLK_MAINCK_ENABLE 1 #endif // Enable Main Clock Failure Detection // Indicates whether Main Clock Failure Detection is enabled or disable. // The 4/8/12 MHz RC oscillator must be selected as the source of MAINCK. // clk_gen_cfden_enable #ifndef CONF_CLK_CFDEN_ENABLE #define CONF_CLK_CFDEN_ENABLE 0 #endif // // // // // Clock_MCKR configuration // Indicates whether MCKR configuration is enabled or not // enable_clk_gen_mckr #ifndef CONF_CLK_MCKR_CONFIG #define CONF_CLK_MCKR_CONFIG 1 #endif // Clock Generator // clock generator MCKR source // Slow Clock (SLCK) // Main Clock (MAINCK) // PLLA Clock (PLLACK) // UDPLL with Divider (MCKR UPLLDIV2) // This defines the clock source for MCKR // clk_gen_mckr_oscillator #ifndef CONF_CLK_GEN_MCKR_SRC #define CONF_CLK_GEN_MCKR_SRC CLK_SRC_OPTION_PLLACK #endif // Enable Clock_MCKR // Indicates whether MCKR is enabled or disable // clk_gen_mckr_arch_enable #ifndef CONF_CLK_MCKR_ENABLE #define CONF_CLK_MCKR_ENABLE 1 #endif // // // Master Clock Prescaler // <0=> 1 // <1=> 2 // <2=> 4 // <3=> 8 // <4=> 16 // <5=> 32 // <6=> 64 // <7=> 3 // Select the clock prescaler. // mckr_presc #ifndef CONF_MCKR_PRESC #define CONF_MCKR_PRESC 0 #endif // // // Clock_MCK configuration // Indicates whether MCK configuration is enabled or not // enable_clk_gen_mck #ifndef CONF_CLK_MCK_CONFIG #define CONF_CLK_MCK_CONFIG 1 #endif // Clock Generator // clock generator MCK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for MCK // clk_gen_mck_oscillator #ifndef CONF_CLK_GEN_MCK_SRC #define CONF_CLK_GEN_MCK_SRC CLK_SRC_OPTION_MCKR #endif // // // Master Clock Controller Divider MCK divider // <0=> 1 // <1=> 2 // <3=> 3 // <2=> 4 // Select the master clock divider. // mck_div #ifndef CONF_MCK_DIV #define CONF_MCK_DIV 1 #endif // // // Clock_SYSTICK configuration // Indicates whether SYSTICK configuration is enabled or not // enable_clk_gen_systick #ifndef CONF_CLK_SYSTICK_CONFIG #define CONF_CLK_SYSTICK_CONFIG 1 #endif // Clock Generator // clock generator SYSTICK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for SYSTICK // clk_gen_systick_oscillator #ifndef CONF_CLK_GEN_SYSTICK_SRC #define CONF_CLK_GEN_SYSTICK_SRC CLK_SRC_OPTION_MCKR #endif // // // Systick clock divider // <8=> 8 // Select systick clock divider // systick_clock_div #ifndef CONF_SYSTICK_DIV #define CONF_SYSTICK_DIV 8 #endif // // // Clock_FCLK configuration // Indicates whether FCLK configuration is enabled or not // enable_clk_gen_fclk #ifndef CONF_CLK_FCLK_CONFIG #define CONF_CLK_FCLK_CONFIG 1 #endif // Clock Generator // clock generator FCLK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for FCLK // clk_gen_fclk_oscillator #ifndef CONF_CLK_GEN_FCLK_SRC #define CONF_CLK_GEN_FCLK_SRC CLK_SRC_OPTION_MCKR #endif // // // // // Clock_GCLK0 configuration // Indicates whether GCLK0 configuration is enabled or not // enable_clk_gen_gclk0 #ifndef CONF_CLK_GCLK0_CONFIG #define CONF_CLK_GCLK0_CONFIG 1 #endif // Clock Generator // clock generator GCLK0 source // Slow Clock (SLCK) // Main Clock (MAINCK) // USB 480M Clock (UPLLCK) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for GCLK0 // clk_gen_gclk0_oscillator #ifndef CONF_CLK_GEN_GCLK0_SRC #define CONF_CLK_GEN_GCLK0_SRC CLK_SRC_OPTION_MCK #endif // Enable Clock_GCLK0 // Indicates whether GCLK0 is enabled or disable // clk_gen_gclk0_arch_enable #ifndef CONF_CLK_GCLK0_ENABLE #define CONF_CLK_GCLK0_ENABLE 1 #endif // // // Enable GCLK0 GCLKEN // Indicates whether GCLK0 GCLKEN is enabled or disable // gclk0_gclken_enable #ifndef CONF_GCLK0_GCLKEN_ENABLE #define CONF_GCLK0_GCLKEN_ENABLE 0 #endif // Generic Clock GCLK0 divider <1-256> // Select the clock divider (divider = GCLKDIV + 1). // gclk0_div #ifndef CONF_GCLK0_DIV #define CONF_GCLK0_DIV 2 #endif // // // Clock_GCLK1 configuration // Indicates whether GCLK1 configuration is enabled or not // enable_clk_gen_gclk1 #ifndef CONF_CLK_GCLK1_CONFIG #define CONF_CLK_GCLK1_CONFIG 1 #endif // Clock Generator // clock generator GCLK1 source // Slow Clock (SLCK) // Main Clock (MAINCK) // USB 480M Clock (UPLLCK) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for GCLK1 // clk_gen_gclk1_oscillator #ifndef CONF_CLK_GEN_GCLK1_SRC #define CONF_CLK_GEN_GCLK1_SRC CLK_SRC_OPTION_PLLACK #endif // Enable Clock_GCLK1 // Indicates whether GCLK1 is enabled or disable // clk_gen_gclk1_arch_enable #ifndef CONF_CLK_GCLK1_ENABLE #define CONF_CLK_GCLK1_ENABLE 1 #endif // // // Enable GCLK1 GCLKEN // Indicates whether GCLK1 GCLKEN is enabled or disable // gclk1_gclken_enable #ifndef CONF_GCLK1_GCLKEN_ENABLE #define CONF_GCLK1_GCLKEN_ENABLE 0 #endif // Generic Clock GCLK1 divider <1-256> // Select the clock divider (divider = GCLKDIV + 1). // gclk1_div #ifndef CONF_GCLK1_DIV #define CONF_GCLK1_DIV 3 #endif // // // Clock_PCK0 configuration // Indicates whether PCK0 configuration is enabled or not // enable_clk_gen_pck0 #ifndef CONF_CLK_PCK0_CONFIG #define CONF_CLK_PCK0_CONFIG 1 #endif // Clock Generator // clock generator PCK0 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK0 // clk_gen_pck0_oscillator #ifndef CONF_CLK_GEN_PCK0_SRC #define CONF_CLK_GEN_PCK0_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK0 // Indicates whether PCK0 is enabled or disable // clk_gen_pck0_arch_enable #ifndef CONF_CLK_PCK0_ENABLE #define CONF_CLK_PCK0_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck0_presc #ifndef CONF_PCK0_PRESC #define CONF_PCK0_PRESC 1 #endif // // // Clock_PCK1 configuration // Indicates whether PCK1 configuration is enabled or not // enable_clk_gen_pck1 #ifndef CONF_CLK_PCK1_CONFIG #define CONF_CLK_PCK1_CONFIG 1 #endif // Clock Generator // clock generator PCK1 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK1 // clk_gen_pck1_oscillator #ifndef CONF_CLK_GEN_PCK1_SRC #define CONF_CLK_GEN_PCK1_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK1 // Indicates whether PCK1 is enabled or disable // clk_gen_pck1_arch_enable #ifndef CONF_CLK_PCK1_ENABLE #define CONF_CLK_PCK1_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck1_presc #ifndef CONF_PCK1_PRESC #define CONF_PCK1_PRESC 2 #endif // // // Clock_PCK2 configuration // Indicates whether PCK2 configuration is enabled or not // enable_clk_gen_pck2 #ifndef CONF_CLK_PCK2_CONFIG #define CONF_CLK_PCK2_CONFIG 1 #endif // Clock Generator // clock generator PCK2 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK2 // clk_gen_pck2_oscillator #ifndef CONF_CLK_GEN_PCK2_SRC #define CONF_CLK_GEN_PCK2_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK2 // Indicates whether PCK2 is enabled or disable // clk_gen_pck2_arch_enable #ifndef CONF_CLK_PCK2_ENABLE #define CONF_CLK_PCK2_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck2_presc #ifndef CONF_PCK2_PRESC #define CONF_PCK2_PRESC 3 #endif // // // Clock_PCK3 configuration // Indicates whether PCK3 configuration is enabled or not // enable_clk_gen_pck3 #ifndef CONF_CLK_PCK3_CONFIG #define CONF_CLK_PCK3_CONFIG 1 #endif // Clock Generator // clock generator PCK3 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK3 // clk_gen_pck3_oscillator #ifndef CONF_CLK_GEN_PCK3_SRC #define CONF_CLK_GEN_PCK3_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK3 // Indicates whether PCK3 is enabled or disable // clk_gen_pck3_arch_enable #ifndef CONF_CLK_PCK3_ENABLE #define CONF_CLK_PCK3_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck3_presc #ifndef CONF_PCK3_PRESC #define CONF_PCK3_PRESC 4 #endif // // // Clock_PCK4 configuration // Indicates whether PCK4 configuration is enabled or not // enable_clk_gen_pck4 #ifndef CONF_CLK_PCK4_CONFIG #define CONF_CLK_PCK4_CONFIG 1 #endif // Clock Generator // clock generator PCK4 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK4 // clk_gen_pck4_oscillator #ifndef CONF_CLK_GEN_PCK4_SRC #define CONF_CLK_GEN_PCK4_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK4 // Indicates whether PCK4 is enabled or disable // clk_gen_pck4_arch_enable #ifndef CONF_CLK_PCK4_ENABLE #define CONF_CLK_PCK4_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck4_presc #ifndef CONF_PCK4_PRESC #define CONF_PCK4_PRESC 5 #endif // // // Clock_PCK5 configuration // Indicates whether PCK5 configuration is enabled or not // enable_clk_gen_pck5 #ifndef CONF_CLK_PCK5_CONFIG #define CONF_CLK_PCK5_CONFIG 1 #endif // Clock Generator // clock generator PCK5 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK5 // clk_gen_pck5_oscillator #ifndef CONF_CLK_GEN_PCK5_SRC #define CONF_CLK_GEN_PCK5_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK5 // Indicates whether PCK5 is enabled or disable // clk_gen_pck5_arch_enable #ifndef CONF_CLK_PCK5_ENABLE #define CONF_CLK_PCK5_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck5_presc #ifndef CONF_PCK5_PRESC #define CONF_PCK5_PRESC 6 #endif // // // Clock_PCK6 configuration // Indicates whether PCK6 configuration is enabled or not // enable_clk_gen_pck6 #ifndef CONF_CLK_PCK6_CONFIG #define CONF_CLK_PCK6_CONFIG 1 #endif // Clock Generator // clock generator PCK6 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK6 // clk_gen_pck6_oscillator #ifndef CONF_CLK_GEN_PCK6_SRC #define CONF_CLK_GEN_PCK6_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK6 // Indicates whether PCK6 is enabled or disable // clk_gen_pck6_arch_enable #ifndef CONF_CLK_PCK6_ENABLE #define CONF_CLK_PCK6_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck6_presc #ifndef CONF_PCK6_PRESC #define CONF_PCK6_PRESC 7 #endif // // // Clock_USB_480M configuration // Indicates whether USB_480M configuration is enabled or not // enable_clk_gen_usb_480m #ifndef CONF_CLK_USB_480M_CONFIG #define CONF_CLK_USB_480M_CONFIG 1 #endif // Clock Generator // clock generator USB_480M source // USB 480M Clock (UPLLCK) // This defines the clock source for USB_480M // clk_gen_usb_480m_oscillator #ifndef CONF_CLK_GEN_USB_480M_SRC #define CONF_CLK_GEN_USB_480M_SRC CLK_SRC_OPTION_UPLLCK #endif // // // // // Clock_USB_48M configuration // Indicates whether USB_48M configuration is enabled or not // enable_clk_gen_usb_48m #ifndef CONF_CLK_USB_48M_CONFIG #define CONF_CLK_USB_48M_CONFIG 1 #endif // Clock Generator // clock generator USB_48M source // PLLA Clock (PLLACK) // UDPLL with Divider (MCKR UPLLDIV2) // This defines the clock source for USB_48M // clk_gen_usb_48m_oscillator #ifndef CONF_CLK_GEN_USB_48M_SRC #define CONF_CLK_GEN_USB_48M_SRC CLK_SRC_OPTION_UPLLCKDIV #endif // Enable Clock_USB_48M // Indicates whether USB_48M is enabled or disable // clk_gen_usb_48m_arch_enable #ifndef CONF_CLK_USB_48M_ENABLE #define CONF_CLK_USB_48M_ENABLE 1 #endif // // // USB Clock Controller Divider <1-16> // Select the USB clock divider (divider = USBDIV + 1). // usb_48m_div #ifndef CONF_USB_48M_DIV #define CONF_USB_48M_DIV 5 #endif // // // Clock_SLCK2 configuration // Indicates whether SLCK2 configuration is enabled or not // enable_clk_gen_slck2 #ifndef CONF_CLK_SLCK2_CONFIG #define CONF_CLK_SLCK2_CONFIG 1 #endif // Clock Generator // clock generator SLCK2 source // Slow Clock (SLCK) // This defines the clock source for SLCK2 // clk_gen_slck2_oscillator #ifndef CONF_CLK_GEN_SLCK2_SRC #define CONF_CLK_GEN_SLCK2_SRC CLK_SRC_OPTION_SLCK #endif // // // // // System Configuration // Indicates whether configuration for system is enabled or not // enable_hclk_clock #ifndef CONF_SYSTEM_CONFIG #define CONF_SYSTEM_CONFIG 1 #endif // Processor Clock Settings // Processor Clock source // Master Clock Controller (PMC_MCKR) // This defines the clock source for the HCLK (Processor clock) // hclk_clock_source #ifndef CONF_HCLK_SRC #define CONF_HCLK_SRC MCKR #endif // Flash Wait State // <0=> 1 cycle // <1=> 2 cycles // <2=> 3 cycles // <3=> 4 cycles // <4=> 5 cycles // <5=> 6 cycles // <6=> 7 cycles // This field defines the number of wait states for read and write operations. // efc_fws #ifndef CONF_EFC_WAIT_STATE #define CONF_EFC_WAIT_STATE 5 #endif // // // SysTick Clock // enable_systick_clk_clock #ifndef CONF_SYSTICK_CLK_CONFIG #define CONF_SYSTICK_CLK_CONFIG 1 #endif // SysTick Clock source // Master Clock Controller (PMC_MCKR) // This defines the clock source for the SysTick Clock // systick_clk_clock_source #ifndef CONF_SYSTICK_CLK_SRC #define CONF_SYSTICK_CLK_SRC MCKR #endif // SysTick Clock Divider // <8=> 8 // Fixed to 8 if Systick is not using Processor clock // systick_clk_clock_div #ifndef CONF_SYSTICK_CLK_DIV #define CONF_SYSTICK_CLK_DIV 8 #endif // // OSC32K Oscillator Configuration // Indicates whether configuration for OSC32K is enabled or not // enable_osc32k #ifndef CONF_OSC32K_CONFIG #define CONF_OSC32K_CONFIG 1 #endif // OSC32K Oscillator Control // OSC32K Oscillator Enable // Indicates whether OSC32K Oscillator is enabled or not // osc32k_arch_enable #ifndef CONF_OSC32K_ENABLE #define CONF_OSC32K_ENABLE 0 #endif // // // XOSC32K Oscillator Configuration // Indicates whether configuration for XOSC32K is enabled or not // enable_xosc32k #ifndef CONF_XOSC32K_CONFIG #define CONF_XOSC32K_CONFIG 0 #endif // XOSC32K Oscillator Control // Oscillator Bypass Select // The 32kHz crystal oscillator is not bypassed. // The 32kHz crystal oscillator is bypassed. // Indicates whether XOSC32K is bypassed. // xosc32k_bypass #ifndef CONF_XOSC32K #define CONF_XOSC32K CONF_XOSC32K_NO_BYPASS #endif // XOSC32K Oscillator Enable // Indicates whether XOSC32K Oscillator is enabled or not // xosc32k_arch_enable #ifndef CONF_XOSC32K_ENABLE #define CONF_XOSC32K_ENABLE 0 #endif // // // OSC12M Oscillator Configuration // Indicates whether configuration for OSC12M is enabled or not // enable_osc12m #ifndef CONF_OSC12M_CONFIG #define CONF_OSC12M_CONFIG 0 #endif // OSC12M Oscillator Control // OSC12M Oscillator Enable // Indicates whether OSC12M Oscillator is enabled or not. // osc12m_arch_enable #ifndef CONF_OSC12M_ENABLE #define CONF_OSC12M_ENABLE 0 #endif // OSC12M selector // <0=> 4000000 // <1=> 8000000 // <2=> 12000000 // Select the frequency of embedded fast RC oscillator. // osc12m_selector #ifndef CONF_OSC12M_SELECTOR #define CONF_OSC12M_SELECTOR 2 #endif // // // XOSC20M Oscillator Configuration // Indicates whether configuration for XOSC20M is enabled or not. // enable_xosc20m #ifndef CONF_XOSC20M_CONFIG #define CONF_XOSC20M_CONFIG 1 #endif // XOSC20M Oscillator Control // XOSC20M selector <3000000-20000000> // Select the frequency of crystal or ceramic resonator oscillator. // xosc20m_selector #ifndef CONF_XOSC20M_SELECTOR #define CONF_XOSC20M_SELECTOR 12000000 #endif // Start up time for the external oscillator (ms): <0-256> // Select start-up time. // xosc20m_startup_time #ifndef CONF_XOSC20M_STARTUP_TIME #define CONF_XOSC20M_STARTUP_TIME 62 #endif // Oscillator Bypass Select // The external crystal oscillator is not bypassed. // The external crystal oscillator is bypassed. // Indicates whether XOSC20M is bypassed. // xosc20m_bypass #ifndef CONF_XOSC20M #define CONF_XOSC20M CONF_XOSC20M_NO_BYPASS #endif // XOSC20M Oscillator Enable // Indicates whether XOSC20M Oscillator is enabled or not // xosc20m_arch_enable #ifndef CONF_XOSC20M_ENABLE #define CONF_XOSC20M_ENABLE 1 #endif // // // PLLACK Oscillator Configuration // Indicates whether configuration for PLLACK is enabled or not // enable_pllack #ifndef CONF_PLLACK_CONFIG #define CONF_PLLACK_CONFIG 1 #endif // PLLACK Reference Clock Source // Main Clock (MAINCK) // Select the clock source. // pllack_ref_clock #ifndef CONF_PLLACK_CLK #define CONF_PLLACK_CLK MAINCK #endif // PLLACK Oscillator Control // PLLACK Oscillator Enable // Indicates whether PLLACK Oscillator is enabled or not // pllack_arch_enable #ifndef CONF_PLLACK_ENABLE #define CONF_PLLACK_ENABLE 1 #endif // PLLA Frontend Divider (DIVA) <1-255> // Select the clock divider // pllack_div #ifndef CONF_PLLACK_DIV #define CONF_PLLACK_DIV 1 #endif // PLLACK Muliplier <1-62> // Indicates PLLA multiplier (multiplier = MULA + 1). // pllack_mul #ifndef CONF_PLLACK_MUL #define CONF_PLLACK_MUL 25 #endif // // // UPLLCK Oscillator Configuration // Indicates whether configuration for UPLLCK is enabled or not // enable_upllck #ifndef CONF_UPLLCK_CONFIG #define CONF_UPLLCK_CONFIG 1 #endif // UPLLCK Reference Clock Source // External 3-20MHz Oscillator (XOSC20M) // Select the clock source,only when the input frequency is 12M or 16M, the upllck output is 480M. // upllck_ref_clock #ifndef CONF_UPLLCK_CLK #define CONF_UPLLCK_CLK XOSC20M #endif // UPLLCK Oscillator Control // UPLLCK Oscillator Enable // Indicates whether UPLLCK Oscillator is enabled or not // upllck_arch_enable #ifndef CONF_UPLLCK_ENABLE #define CONF_UPLLCK_ENABLE 1 #endif // // // UPLLCKDIV Oscillator Configuration // Indicates whether configuration for UPLLCKDIV is enabled or not // enable_upllckdiv #ifndef CONF_UPLLCKDIV_CONFIG #define CONF_UPLLCKDIV_CONFIG 1 #endif // UPLLCKDIV Reference Clock Source // USB 480M Clock (UPLLCK) // Select the clock source. // upllckdiv_ref_clock #ifndef CONF_UPLLCKDIV_CLK #define CONF_UPLLCKDIV_CLK UPLLCK #endif // UPLLCKDIV Oscillator Control // UPLLCKDIV Clock Divider // <0=> 1 // <1=> 2 // Select the clock divider. // upllckdiv_div #ifndef CONF_UPLLCKDIV_DIV #define CONF_UPLLCKDIV_DIV 1 #endif // // // MCK/8 // enable_mck_div_8 #ifndef CONF_MCK_DIV_8_CONFIG #define CONF_MCK_DIV_8_CONFIG 0 #endif // MCK/8 Source // <0=> Master Clock (MCK) // mck_div_8_src #ifndef CONF_MCK_DIV_8_SRC #define CONF_MCK_DIV_8_SRC 0 #endif // // External Clock Input Configuration // enable_dummy_ext #ifndef CONF_DUMMY_EXT_CONFIG #define CONF_DUMMY_EXT_CONFIG 1 #endif // External Clock Input Source // All here are dummy values // Refer to the peripherals settings for actual input information // <0=> Specific clock input from specific pin // dummy_ext_src #ifndef CONF_DUMMY_EXT_SRC #define CONF_DUMMY_EXT_SRC 0 #endif // // External Clock Configuration // enable_dummy_ext_clk #ifndef CONF_DUMMY_EXT_CLK_CONFIG #define CONF_DUMMY_EXT_CLK_CONFIG 1 #endif // External Clock Source // All here are dummy values // Refer to the peripherals settings for actual input information // <0=> External Clock Input // dummy_ext_clk_src #ifndef CONF_DUMMY_EXT_CLK_SRC #define CONF_DUMMY_EXT_CLK_SRC 0 #endif // // <<< end of configuration section >>> #endif // HPL_PMC_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/hpl_usart_config.h ================================================ /* Auto-generated config file hpl_usart_config.h */ #ifndef HPL_USART_CONFIG_H #define HPL_USART_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> #include #ifndef CONF_USART_1_ENABLE #define CONF_USART_1_ENABLE 1 #endif // Basic Configuration // Frame parity // <0x0=>Even parity // <0x1=>Odd parity // <0x2=>Parity forced to 0 // <0x3=>Parity forced to 1 // <0x4=>No parity // Parity bit mode for USART frame // usart_parity #ifndef CONF_USART_1_PARITY #define CONF_USART_1_PARITY 0x4 #endif // Character Size // <0x0=>5 bits // <0x1=>6 bits // <0x2=>7 bits // <0x3=>8 bits // Data character size in USART frame // usart_character_size #ifndef CONF_USART_1_CHSIZE #define CONF_USART_1_CHSIZE 0x3 #endif // Stop Bit // <0=>1 stop bit // <1=>1.5 stop bits // <2=>2 stop bits // Number of stop bits in USART frame // usart_stop_bit #ifndef CONF_USART_1_SBMODE #define CONF_USART_1_SBMODE 0 #endif // Clock Output Select // <0=>The USART does not drive the SCK pin // <1=>The USART drives the SCK pin if USCLKS does not select the external clock SCK // Clock Output Select in USART sck, if in usrt master mode, please drive SCK. // usart_clock_output_select #ifndef CONF_USART_1_CLKO #define CONF_USART_1_CLKO 0 #endif // Baud rate <1-3000000> // USART baud rate setting // usart_baud_rate #ifndef CONF_USART_1_BAUD #define CONF_USART_1_BAUD 9600 #endif // // Advanced configuration // usart_advanced #ifndef CONF_USART_1_ADVANCED_CONFIG #define CONF_USART_1_ADVANCED_CONFIG 0 #endif // Channel Mode // <0=>Normal Mode // <1=>Automatic Echo // <2=>Local Loopback // <3=>Remote Loopback // Channel mode in USART frame // usart_channel_mode #ifndef CONF_USART_1_CHMODE #define CONF_USART_1_CHMODE 0 #endif // 9 bits character enable // Enable 9 bits character, this has high priority than 5/6/7/8 bits. // usart_9bits_enable #ifndef CONF_USART_1_MODE9 #define CONF_USART_1_MODE9 0 #endif // Variable Sync // <0=>User defined configuration // <1=>sync field is updated when a character is written into US_THR // Variable Synchronization of Command/Data Sync Start Frarm Delimiter // variable_sync #ifndef CONF_USART_1_VAR_SYNC #define CONF_USART_1_VAR_SYNC 0 #endif // Oversampling Mode // <0=>16 Oversampling // <1=>8 Oversampling // Oversampling Mode in UART mode // usart__oversampling_mode #ifndef CONF_USART_1_OVER #define CONF_USART_1_OVER 0 #endif // Inhibit Non Ack // <0=>The NACK is generated // <1=>The NACK is not generated // Inhibit Non Acknowledge // usart__inack #ifndef CONF_USART_1_INACK #define CONF_USART_1_INACK 1 #endif // Disable Successive NACK // <0=>NACK is sent on the ISO line as soon as a parity error occurs // <1=>Many parity errors generate a NACK on the ISO line // Disable Successive NACK // usart_dsnack #ifndef CONF_USART_1_DSNACK #define CONF_USART_1_DSNACK 0 #endif // Inverted Data // <0=>Data isn't inverted, nomal mode // <1=>Data is inverted // Inverted Data // usart_invdata #ifndef CONF_USART_1_INVDATA #define CONF_USART_1_INVDATA 0 #endif // Maximum Number of Automatic Iteration <0-7> // Defines the maximum number of iterations in mode ISO7816, protocol T = 0. // usart_max_iteration #ifndef CONF_USART_1_MAX_ITERATION #define CONF_USART_1_MAX_ITERATION 0 #endif // Receive Line Filter enable // whether the USART filters the receive line using a three-sample filter // usart_receive_filter_enable #ifndef CONF_USART_1_FILTER #define CONF_USART_1_FILTER 0 #endif // Manchester Encoder/Decoder Enable // whether the USART Manchester Encoder/Decoder // usart_manchester_filter_enable #ifndef CONF_USART_1_MAN #define CONF_USART_1_MAN 0 #endif // Manchester Synchronization Mode // <0=>The Manchester start bit is a 0 to 1 transition // <1=>The Manchester start bit is a 1 to 0 transition // Manchester Synchronization Mode // usart_manchester_synchronization_mode #ifndef CONF_USART_1_MODSYNC #define CONF_USART_1_MODSYNC 0 #endif // Start Frame Delimiter Selector // <0=>Start frame delimiter is COMMAND or DATA SYNC // <1=>Start frame delimiter is one bit // Start Frame Delimiter Selector // usart_start_frame_delimiter #ifndef CONF_USART_1_ONEBIT #define CONF_USART_1_ONEBIT 0 #endif // Fractional Part <0-7> // Fractional part of the baud rate if baud rate generator is in fractional mode // usart_arch_fractional #ifndef CONF_USART_1_FRACTIONAL #define CONF_USART_1_FRACTIONAL 0x0 #endif // Data Order // <0=>LSB is transmitted first // <1=>MSB is transmitted first // Data order of the data bits in the frame // usart_arch_msbf #ifndef CONF_USART_1_MSBF #define CONF_USART_1_MSBF 0 #endif // #define CONF_USART_1_MODE 0x0 // Calculate BAUD register value in UART mode #if CONF_USART1_CK_SRC < 3 #ifndef CONF_USART_1_BAUD_CD #define CONF_USART_1_BAUD_CD ((CONF_USART1_FREQUENCY) / CONF_USART_1_BAUD / 8 / (2 - CONF_USART_1_OVER)) #endif #ifndef CONF_USART_1_BAUD_FP #define CONF_USART_1_BAUD_FP \ ((CONF_USART1_FREQUENCY) / CONF_USART_1_BAUD / (2 - CONF_USART_1_OVER) - 8 * CONF_USART_1_BAUD_CD) #endif #elif CONF_USART1_CK_SRC == 3 // No division is active. The value written in US_BRGR has no effect. #ifndef CONF_USART_1_BAUD_CD #define CONF_USART_1_BAUD_CD 1 #endif #ifndef CONF_USART_1_BAUD_FP #define CONF_USART_1_BAUD_FP 1 #endif #endif // <<< end of configuration section >>> #endif // HPL_USART_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/hpl_xdmac_config.h ================================================ /* Auto-generated config file hpl_xdmac_config.h */ #ifndef HPL_XDMAC_CONFIG_H #define HPL_XDMAC_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> // XDMAC enable // Indicates whether xdmac is enabled or not // xdmac_enable #ifndef CONF_DMA_ENABLE #define CONF_DMA_ENABLE 0 #endif // Channel 0 settings // dmac_channel_0_settings #ifndef CONF_DMAC_CHANNEL_0_SETTINGS #define CONF_DMAC_CHANNEL_0_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_0 #ifndef CONF_DMAC_BURSTSIZE_0 #define CONF_DMAC_BURSTSIZE_0 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_0 #ifndef CONF_DMAC_CHUNKSIZE_0 #define CONF_DMAC_CHUNKSIZE_0 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_0 #ifndef CONF_DMAC_BEATSIZE_0 #define CONF_DMAC_BEATSIZE_0 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_0 #ifndef CONF_DMAC_SRC_INTERFACE_0 #define CONF_DMAC_SRC_INTERFACE_0 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_0 #ifndef CONF_DMAC_DES_INTERFACE_0 #define CONF_DMAC_DES_INTERFACE_0 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_0 #ifndef CONF_DMAC_SRCINC_0 #define CONF_DMAC_SRCINC_0 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_0 #ifndef CONF_DMAC_DSTINC_0 #define CONF_DMAC_DSTINC_0 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_0 #ifndef CONF_DMAC_TRANS_TYPE_0 #define CONF_DMAC_TRANS_TYPE_0 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_0 #ifndef CONF_DMAC_TRIGSRC_0 #define CONF_DMAC_TRIGSRC_0 0xff #endif // #if CONF_DMAC_TRANS_TYPE_0 == 0 #define CONF_DMAC_TYPE_0 0 #define CONF_DMAC_DSYNC_0 0 #elif CONF_DMAC_TRANS_TYPE_0 == 1 #define CONF_DMAC_TYPE_0 1 #define CONF_DMAC_DSYNC_0 0 #elif CONF_DMAC_TRANS_TYPE_0 == 2 #define CONF_DMAC_TYPE_0 1 #define CONF_DMAC_DSYNC_0 1 #endif #if CONF_DMAC_TRIGSRC_0 == 0xFF #define CONF_DMAC_SWREQ_0 1 #else #define CONF_DMAC_SWREQ_0 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_0_SETTINGS == 1 && CONF_DMAC_BEATSIZE_0 != 2 && ((!CONF_DMAC_SRCINC_0) || (!CONF_DMAC_DSTINC_0))) #if (!CONF_DMAC_SRCINC_0) #define CONF_DMAC_SRC_STRIDE_0 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_0) #define CONF_DMAC_DES_STRIDE_0 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_0 #define CONF_DMAC_SRC_STRIDE_0 0 #endif #ifndef CONF_DMAC_DES_STRIDE_0 #define CONF_DMAC_DES_STRIDE_0 0 #endif // Channel 1 settings // dmac_channel_1_settings #ifndef CONF_DMAC_CHANNEL_1_SETTINGS #define CONF_DMAC_CHANNEL_1_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_1 #ifndef CONF_DMAC_BURSTSIZE_1 #define CONF_DMAC_BURSTSIZE_1 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_1 #ifndef CONF_DMAC_CHUNKSIZE_1 #define CONF_DMAC_CHUNKSIZE_1 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_1 #ifndef CONF_DMAC_BEATSIZE_1 #define CONF_DMAC_BEATSIZE_1 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_1 #ifndef CONF_DMAC_SRC_INTERFACE_1 #define CONF_DMAC_SRC_INTERFACE_1 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_1 #ifndef CONF_DMAC_DES_INTERFACE_1 #define CONF_DMAC_DES_INTERFACE_1 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_1 #ifndef CONF_DMAC_SRCINC_1 #define CONF_DMAC_SRCINC_1 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_1 #ifndef CONF_DMAC_DSTINC_1 #define CONF_DMAC_DSTINC_1 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_1 #ifndef CONF_DMAC_TRANS_TYPE_1 #define CONF_DMAC_TRANS_TYPE_1 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_1 #ifndef CONF_DMAC_TRIGSRC_1 #define CONF_DMAC_TRIGSRC_1 0xff #endif // #if CONF_DMAC_TRANS_TYPE_1 == 0 #define CONF_DMAC_TYPE_1 0 #define CONF_DMAC_DSYNC_1 0 #elif CONF_DMAC_TRANS_TYPE_1 == 1 #define CONF_DMAC_TYPE_1 1 #define CONF_DMAC_DSYNC_1 0 #elif CONF_DMAC_TRANS_TYPE_1 == 2 #define CONF_DMAC_TYPE_1 1 #define CONF_DMAC_DSYNC_1 1 #endif #if CONF_DMAC_TRIGSRC_1 == 0xFF #define CONF_DMAC_SWREQ_1 1 #else #define CONF_DMAC_SWREQ_1 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_1_SETTINGS == 1 && CONF_DMAC_BEATSIZE_1 != 2 && ((!CONF_DMAC_SRCINC_1) || (!CONF_DMAC_DSTINC_1))) #if (!CONF_DMAC_SRCINC_1) #define CONF_DMAC_SRC_STRIDE_1 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_1) #define CONF_DMAC_DES_STRIDE_1 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_1 #define CONF_DMAC_SRC_STRIDE_1 0 #endif #ifndef CONF_DMAC_DES_STRIDE_1 #define CONF_DMAC_DES_STRIDE_1 0 #endif // Channel 2 settings // dmac_channel_2_settings #ifndef CONF_DMAC_CHANNEL_2_SETTINGS #define CONF_DMAC_CHANNEL_2_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_2 #ifndef CONF_DMAC_BURSTSIZE_2 #define CONF_DMAC_BURSTSIZE_2 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_2 #ifndef CONF_DMAC_CHUNKSIZE_2 #define CONF_DMAC_CHUNKSIZE_2 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_2 #ifndef CONF_DMAC_BEATSIZE_2 #define CONF_DMAC_BEATSIZE_2 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_2 #ifndef CONF_DMAC_SRC_INTERFACE_2 #define CONF_DMAC_SRC_INTERFACE_2 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_2 #ifndef CONF_DMAC_DES_INTERFACE_2 #define CONF_DMAC_DES_INTERFACE_2 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_2 #ifndef CONF_DMAC_SRCINC_2 #define CONF_DMAC_SRCINC_2 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_2 #ifndef CONF_DMAC_DSTINC_2 #define CONF_DMAC_DSTINC_2 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_2 #ifndef CONF_DMAC_TRANS_TYPE_2 #define CONF_DMAC_TRANS_TYPE_2 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_2 #ifndef CONF_DMAC_TRIGSRC_2 #define CONF_DMAC_TRIGSRC_2 0xff #endif // #if CONF_DMAC_TRANS_TYPE_2 == 0 #define CONF_DMAC_TYPE_2 0 #define CONF_DMAC_DSYNC_2 0 #elif CONF_DMAC_TRANS_TYPE_2 == 1 #define CONF_DMAC_TYPE_2 1 #define CONF_DMAC_DSYNC_2 0 #elif CONF_DMAC_TRANS_TYPE_2 == 2 #define CONF_DMAC_TYPE_2 1 #define CONF_DMAC_DSYNC_2 1 #endif #if CONF_DMAC_TRIGSRC_2 == 0xFF #define CONF_DMAC_SWREQ_2 1 #else #define CONF_DMAC_SWREQ_2 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_2_SETTINGS == 1 && CONF_DMAC_BEATSIZE_2 != 2 && ((!CONF_DMAC_SRCINC_2) || (!CONF_DMAC_DSTINC_2))) #if (!CONF_DMAC_SRCINC_2) #define CONF_DMAC_SRC_STRIDE_2 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_2) #define CONF_DMAC_DES_STRIDE_2 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_2 #define CONF_DMAC_SRC_STRIDE_2 0 #endif #ifndef CONF_DMAC_DES_STRIDE_2 #define CONF_DMAC_DES_STRIDE_2 0 #endif // Channel 3 settings // dmac_channel_3_settings #ifndef CONF_DMAC_CHANNEL_3_SETTINGS #define CONF_DMAC_CHANNEL_3_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_3 #ifndef CONF_DMAC_BURSTSIZE_3 #define CONF_DMAC_BURSTSIZE_3 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_3 #ifndef CONF_DMAC_CHUNKSIZE_3 #define CONF_DMAC_CHUNKSIZE_3 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_3 #ifndef CONF_DMAC_BEATSIZE_3 #define CONF_DMAC_BEATSIZE_3 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_3 #ifndef CONF_DMAC_SRC_INTERFACE_3 #define CONF_DMAC_SRC_INTERFACE_3 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_3 #ifndef CONF_DMAC_DES_INTERFACE_3 #define CONF_DMAC_DES_INTERFACE_3 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_3 #ifndef CONF_DMAC_SRCINC_3 #define CONF_DMAC_SRCINC_3 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_3 #ifndef CONF_DMAC_DSTINC_3 #define CONF_DMAC_DSTINC_3 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_3 #ifndef CONF_DMAC_TRANS_TYPE_3 #define CONF_DMAC_TRANS_TYPE_3 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_3 #ifndef CONF_DMAC_TRIGSRC_3 #define CONF_DMAC_TRIGSRC_3 0xff #endif // #if CONF_DMAC_TRANS_TYPE_3 == 0 #define CONF_DMAC_TYPE_3 0 #define CONF_DMAC_DSYNC_3 0 #elif CONF_DMAC_TRANS_TYPE_3 == 1 #define CONF_DMAC_TYPE_3 1 #define CONF_DMAC_DSYNC_3 0 #elif CONF_DMAC_TRANS_TYPE_3 == 2 #define CONF_DMAC_TYPE_3 1 #define CONF_DMAC_DSYNC_3 1 #endif #if CONF_DMAC_TRIGSRC_3 == 0xFF #define CONF_DMAC_SWREQ_3 1 #else #define CONF_DMAC_SWREQ_3 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_3_SETTINGS == 1 && CONF_DMAC_BEATSIZE_3 != 2 && ((!CONF_DMAC_SRCINC_3) || (!CONF_DMAC_DSTINC_3))) #if (!CONF_DMAC_SRCINC_3) #define CONF_DMAC_SRC_STRIDE_3 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_3) #define CONF_DMAC_DES_STRIDE_3 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_3 #define CONF_DMAC_SRC_STRIDE_3 0 #endif #ifndef CONF_DMAC_DES_STRIDE_3 #define CONF_DMAC_DES_STRIDE_3 0 #endif // Channel 4 settings // dmac_channel_4_settings #ifndef CONF_DMAC_CHANNEL_4_SETTINGS #define CONF_DMAC_CHANNEL_4_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_4 #ifndef CONF_DMAC_BURSTSIZE_4 #define CONF_DMAC_BURSTSIZE_4 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_4 #ifndef CONF_DMAC_CHUNKSIZE_4 #define CONF_DMAC_CHUNKSIZE_4 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_4 #ifndef CONF_DMAC_BEATSIZE_4 #define CONF_DMAC_BEATSIZE_4 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_4 #ifndef CONF_DMAC_SRC_INTERFACE_4 #define CONF_DMAC_SRC_INTERFACE_4 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_4 #ifndef CONF_DMAC_DES_INTERFACE_4 #define CONF_DMAC_DES_INTERFACE_4 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_4 #ifndef CONF_DMAC_SRCINC_4 #define CONF_DMAC_SRCINC_4 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_4 #ifndef CONF_DMAC_DSTINC_4 #define CONF_DMAC_DSTINC_4 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_4 #ifndef CONF_DMAC_TRANS_TYPE_4 #define CONF_DMAC_TRANS_TYPE_4 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_4 #ifndef CONF_DMAC_TRIGSRC_4 #define CONF_DMAC_TRIGSRC_4 0xff #endif // #if CONF_DMAC_TRANS_TYPE_4 == 0 #define CONF_DMAC_TYPE_4 0 #define CONF_DMAC_DSYNC_4 0 #elif CONF_DMAC_TRANS_TYPE_4 == 1 #define CONF_DMAC_TYPE_4 1 #define CONF_DMAC_DSYNC_4 0 #elif CONF_DMAC_TRANS_TYPE_4 == 2 #define CONF_DMAC_TYPE_4 1 #define CONF_DMAC_DSYNC_4 1 #endif #if CONF_DMAC_TRIGSRC_4 == 0xFF #define CONF_DMAC_SWREQ_4 1 #else #define CONF_DMAC_SWREQ_4 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_4_SETTINGS == 1 && CONF_DMAC_BEATSIZE_4 != 2 && ((!CONF_DMAC_SRCINC_4) || (!CONF_DMAC_DSTINC_4))) #if (!CONF_DMAC_SRCINC_4) #define CONF_DMAC_SRC_STRIDE_4 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_4) #define CONF_DMAC_DES_STRIDE_4 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_4 #define CONF_DMAC_SRC_STRIDE_4 0 #endif #ifndef CONF_DMAC_DES_STRIDE_4 #define CONF_DMAC_DES_STRIDE_4 0 #endif // Channel 5 settings // dmac_channel_5_settings #ifndef CONF_DMAC_CHANNEL_5_SETTINGS #define CONF_DMAC_CHANNEL_5_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_5 #ifndef CONF_DMAC_BURSTSIZE_5 #define CONF_DMAC_BURSTSIZE_5 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_5 #ifndef CONF_DMAC_CHUNKSIZE_5 #define CONF_DMAC_CHUNKSIZE_5 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_5 #ifndef CONF_DMAC_BEATSIZE_5 #define CONF_DMAC_BEATSIZE_5 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_5 #ifndef CONF_DMAC_SRC_INTERFACE_5 #define CONF_DMAC_SRC_INTERFACE_5 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_5 #ifndef CONF_DMAC_DES_INTERFACE_5 #define CONF_DMAC_DES_INTERFACE_5 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_5 #ifndef CONF_DMAC_SRCINC_5 #define CONF_DMAC_SRCINC_5 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_5 #ifndef CONF_DMAC_DSTINC_5 #define CONF_DMAC_DSTINC_5 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_5 #ifndef CONF_DMAC_TRANS_TYPE_5 #define CONF_DMAC_TRANS_TYPE_5 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_5 #ifndef CONF_DMAC_TRIGSRC_5 #define CONF_DMAC_TRIGSRC_5 0xff #endif // #if CONF_DMAC_TRANS_TYPE_5 == 0 #define CONF_DMAC_TYPE_5 0 #define CONF_DMAC_DSYNC_5 0 #elif CONF_DMAC_TRANS_TYPE_5 == 1 #define CONF_DMAC_TYPE_5 1 #define CONF_DMAC_DSYNC_5 0 #elif CONF_DMAC_TRANS_TYPE_5 == 2 #define CONF_DMAC_TYPE_5 1 #define CONF_DMAC_DSYNC_5 1 #endif #if CONF_DMAC_TRIGSRC_5 == 0xFF #define CONF_DMAC_SWREQ_5 1 #else #define CONF_DMAC_SWREQ_5 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_5_SETTINGS == 1 && CONF_DMAC_BEATSIZE_5 != 2 && ((!CONF_DMAC_SRCINC_5) || (!CONF_DMAC_DSTINC_5))) #if (!CONF_DMAC_SRCINC_5) #define CONF_DMAC_SRC_STRIDE_5 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_5) #define CONF_DMAC_DES_STRIDE_5 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_5 #define CONF_DMAC_SRC_STRIDE_5 0 #endif #ifndef CONF_DMAC_DES_STRIDE_5 #define CONF_DMAC_DES_STRIDE_5 0 #endif // Channel 6 settings // dmac_channel_6_settings #ifndef CONF_DMAC_CHANNEL_6_SETTINGS #define CONF_DMAC_CHANNEL_6_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_6 #ifndef CONF_DMAC_BURSTSIZE_6 #define CONF_DMAC_BURSTSIZE_6 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_6 #ifndef CONF_DMAC_CHUNKSIZE_6 #define CONF_DMAC_CHUNKSIZE_6 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_6 #ifndef CONF_DMAC_BEATSIZE_6 #define CONF_DMAC_BEATSIZE_6 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_6 #ifndef CONF_DMAC_SRC_INTERFACE_6 #define CONF_DMAC_SRC_INTERFACE_6 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_6 #ifndef CONF_DMAC_DES_INTERFACE_6 #define CONF_DMAC_DES_INTERFACE_6 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_6 #ifndef CONF_DMAC_SRCINC_6 #define CONF_DMAC_SRCINC_6 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_6 #ifndef CONF_DMAC_DSTINC_6 #define CONF_DMAC_DSTINC_6 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_6 #ifndef CONF_DMAC_TRANS_TYPE_6 #define CONF_DMAC_TRANS_TYPE_6 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_6 #ifndef CONF_DMAC_TRIGSRC_6 #define CONF_DMAC_TRIGSRC_6 0xff #endif // #if CONF_DMAC_TRANS_TYPE_6 == 0 #define CONF_DMAC_TYPE_6 0 #define CONF_DMAC_DSYNC_6 0 #elif CONF_DMAC_TRANS_TYPE_6 == 1 #define CONF_DMAC_TYPE_6 1 #define CONF_DMAC_DSYNC_6 0 #elif CONF_DMAC_TRANS_TYPE_6 == 2 #define CONF_DMAC_TYPE_6 1 #define CONF_DMAC_DSYNC_6 1 #endif #if CONF_DMAC_TRIGSRC_6 == 0xFF #define CONF_DMAC_SWREQ_6 1 #else #define CONF_DMAC_SWREQ_6 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_6_SETTINGS == 1 && CONF_DMAC_BEATSIZE_6 != 2 && ((!CONF_DMAC_SRCINC_6) || (!CONF_DMAC_DSTINC_6))) #if (!CONF_DMAC_SRCINC_6) #define CONF_DMAC_SRC_STRIDE_6 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_6) #define CONF_DMAC_DES_STRIDE_6 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_6 #define CONF_DMAC_SRC_STRIDE_6 0 #endif #ifndef CONF_DMAC_DES_STRIDE_6 #define CONF_DMAC_DES_STRIDE_6 0 #endif // Channel 7 settings // dmac_channel_7_settings #ifndef CONF_DMAC_CHANNEL_7_SETTINGS #define CONF_DMAC_CHANNEL_7_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_7 #ifndef CONF_DMAC_BURSTSIZE_7 #define CONF_DMAC_BURSTSIZE_7 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_7 #ifndef CONF_DMAC_CHUNKSIZE_7 #define CONF_DMAC_CHUNKSIZE_7 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_7 #ifndef CONF_DMAC_BEATSIZE_7 #define CONF_DMAC_BEATSIZE_7 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_7 #ifndef CONF_DMAC_SRC_INTERFACE_7 #define CONF_DMAC_SRC_INTERFACE_7 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_7 #ifndef CONF_DMAC_DES_INTERFACE_7 #define CONF_DMAC_DES_INTERFACE_7 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_7 #ifndef CONF_DMAC_SRCINC_7 #define CONF_DMAC_SRCINC_7 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_7 #ifndef CONF_DMAC_DSTINC_7 #define CONF_DMAC_DSTINC_7 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_7 #ifndef CONF_DMAC_TRANS_TYPE_7 #define CONF_DMAC_TRANS_TYPE_7 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_7 #ifndef CONF_DMAC_TRIGSRC_7 #define CONF_DMAC_TRIGSRC_7 0xff #endif // #if CONF_DMAC_TRANS_TYPE_7 == 0 #define CONF_DMAC_TYPE_7 0 #define CONF_DMAC_DSYNC_7 0 #elif CONF_DMAC_TRANS_TYPE_7 == 1 #define CONF_DMAC_TYPE_7 1 #define CONF_DMAC_DSYNC_7 0 #elif CONF_DMAC_TRANS_TYPE_7 == 2 #define CONF_DMAC_TYPE_7 1 #define CONF_DMAC_DSYNC_7 1 #endif #if CONF_DMAC_TRIGSRC_7 == 0xFF #define CONF_DMAC_SWREQ_7 1 #else #define CONF_DMAC_SWREQ_7 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_7_SETTINGS == 1 && CONF_DMAC_BEATSIZE_7 != 2 && ((!CONF_DMAC_SRCINC_7) || (!CONF_DMAC_DSTINC_7))) #if (!CONF_DMAC_SRCINC_7) #define CONF_DMAC_SRC_STRIDE_7 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_7) #define CONF_DMAC_DES_STRIDE_7 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_7 #define CONF_DMAC_SRC_STRIDE_7 0 #endif #ifndef CONF_DMAC_DES_STRIDE_7 #define CONF_DMAC_DES_STRIDE_7 0 #endif // Channel 8 settings // dmac_channel_8_settings #ifndef CONF_DMAC_CHANNEL_8_SETTINGS #define CONF_DMAC_CHANNEL_8_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_8 #ifndef CONF_DMAC_BURSTSIZE_8 #define CONF_DMAC_BURSTSIZE_8 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_8 #ifndef CONF_DMAC_CHUNKSIZE_8 #define CONF_DMAC_CHUNKSIZE_8 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_8 #ifndef CONF_DMAC_BEATSIZE_8 #define CONF_DMAC_BEATSIZE_8 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_8 #ifndef CONF_DMAC_SRC_INTERFACE_8 #define CONF_DMAC_SRC_INTERFACE_8 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_8 #ifndef CONF_DMAC_DES_INTERFACE_8 #define CONF_DMAC_DES_INTERFACE_8 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_8 #ifndef CONF_DMAC_SRCINC_8 #define CONF_DMAC_SRCINC_8 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_8 #ifndef CONF_DMAC_DSTINC_8 #define CONF_DMAC_DSTINC_8 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_8 #ifndef CONF_DMAC_TRANS_TYPE_8 #define CONF_DMAC_TRANS_TYPE_8 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_8 #ifndef CONF_DMAC_TRIGSRC_8 #define CONF_DMAC_TRIGSRC_8 0xff #endif // #if CONF_DMAC_TRANS_TYPE_8 == 0 #define CONF_DMAC_TYPE_8 0 #define CONF_DMAC_DSYNC_8 0 #elif CONF_DMAC_TRANS_TYPE_8 == 1 #define CONF_DMAC_TYPE_8 1 #define CONF_DMAC_DSYNC_8 0 #elif CONF_DMAC_TRANS_TYPE_8 == 2 #define CONF_DMAC_TYPE_8 1 #define CONF_DMAC_DSYNC_8 1 #endif #if CONF_DMAC_TRIGSRC_8 == 0xFF #define CONF_DMAC_SWREQ_8 1 #else #define CONF_DMAC_SWREQ_8 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_8_SETTINGS == 1 && CONF_DMAC_BEATSIZE_8 != 2 && ((!CONF_DMAC_SRCINC_8) || (!CONF_DMAC_DSTINC_8))) #if (!CONF_DMAC_SRCINC_8) #define CONF_DMAC_SRC_STRIDE_8 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_8) #define CONF_DMAC_DES_STRIDE_8 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_8 #define CONF_DMAC_SRC_STRIDE_8 0 #endif #ifndef CONF_DMAC_DES_STRIDE_8 #define CONF_DMAC_DES_STRIDE_8 0 #endif // Channel 9 settings // dmac_channel_9_settings #ifndef CONF_DMAC_CHANNEL_9_SETTINGS #define CONF_DMAC_CHANNEL_9_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_9 #ifndef CONF_DMAC_BURSTSIZE_9 #define CONF_DMAC_BURSTSIZE_9 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_9 #ifndef CONF_DMAC_CHUNKSIZE_9 #define CONF_DMAC_CHUNKSIZE_9 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_9 #ifndef CONF_DMAC_BEATSIZE_9 #define CONF_DMAC_BEATSIZE_9 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_9 #ifndef CONF_DMAC_SRC_INTERFACE_9 #define CONF_DMAC_SRC_INTERFACE_9 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_9 #ifndef CONF_DMAC_DES_INTERFACE_9 #define CONF_DMAC_DES_INTERFACE_9 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_9 #ifndef CONF_DMAC_SRCINC_9 #define CONF_DMAC_SRCINC_9 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_9 #ifndef CONF_DMAC_DSTINC_9 #define CONF_DMAC_DSTINC_9 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_9 #ifndef CONF_DMAC_TRANS_TYPE_9 #define CONF_DMAC_TRANS_TYPE_9 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_9 #ifndef CONF_DMAC_TRIGSRC_9 #define CONF_DMAC_TRIGSRC_9 0xff #endif // #if CONF_DMAC_TRANS_TYPE_9 == 0 #define CONF_DMAC_TYPE_9 0 #define CONF_DMAC_DSYNC_9 0 #elif CONF_DMAC_TRANS_TYPE_9 == 1 #define CONF_DMAC_TYPE_9 1 #define CONF_DMAC_DSYNC_9 0 #elif CONF_DMAC_TRANS_TYPE_9 == 2 #define CONF_DMAC_TYPE_9 1 #define CONF_DMAC_DSYNC_9 1 #endif #if CONF_DMAC_TRIGSRC_9 == 0xFF #define CONF_DMAC_SWREQ_9 1 #else #define CONF_DMAC_SWREQ_9 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_9_SETTINGS == 1 && CONF_DMAC_BEATSIZE_9 != 2 && ((!CONF_DMAC_SRCINC_9) || (!CONF_DMAC_DSTINC_9))) #if (!CONF_DMAC_SRCINC_9) #define CONF_DMAC_SRC_STRIDE_9 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_9) #define CONF_DMAC_DES_STRIDE_9 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_9 #define CONF_DMAC_SRC_STRIDE_9 0 #endif #ifndef CONF_DMAC_DES_STRIDE_9 #define CONF_DMAC_DES_STRIDE_9 0 #endif // Channel 10 settings // dmac_channel_10_settings #ifndef CONF_DMAC_CHANNEL_10_SETTINGS #define CONF_DMAC_CHANNEL_10_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_10 #ifndef CONF_DMAC_BURSTSIZE_10 #define CONF_DMAC_BURSTSIZE_10 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_10 #ifndef CONF_DMAC_CHUNKSIZE_10 #define CONF_DMAC_CHUNKSIZE_10 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_10 #ifndef CONF_DMAC_BEATSIZE_10 #define CONF_DMAC_BEATSIZE_10 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_10 #ifndef CONF_DMAC_SRC_INTERFACE_10 #define CONF_DMAC_SRC_INTERFACE_10 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_10 #ifndef CONF_DMAC_DES_INTERFACE_10 #define CONF_DMAC_DES_INTERFACE_10 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_10 #ifndef CONF_DMAC_SRCINC_10 #define CONF_DMAC_SRCINC_10 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_10 #ifndef CONF_DMAC_DSTINC_10 #define CONF_DMAC_DSTINC_10 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_10 #ifndef CONF_DMAC_TRANS_TYPE_10 #define CONF_DMAC_TRANS_TYPE_10 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_10 #ifndef CONF_DMAC_TRIGSRC_10 #define CONF_DMAC_TRIGSRC_10 0xff #endif // #if CONF_DMAC_TRANS_TYPE_10 == 0 #define CONF_DMAC_TYPE_10 0 #define CONF_DMAC_DSYNC_10 0 #elif CONF_DMAC_TRANS_TYPE_10 == 1 #define CONF_DMAC_TYPE_10 1 #define CONF_DMAC_DSYNC_10 0 #elif CONF_DMAC_TRANS_TYPE_10 == 2 #define CONF_DMAC_TYPE_10 1 #define CONF_DMAC_DSYNC_10 1 #endif #if CONF_DMAC_TRIGSRC_10 == 0xFF #define CONF_DMAC_SWREQ_10 1 #else #define CONF_DMAC_SWREQ_10 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_10_SETTINGS == 1 && CONF_DMAC_BEATSIZE_10 != 2 \ && ((!CONF_DMAC_SRCINC_10) || (!CONF_DMAC_DSTINC_10))) #if (!CONF_DMAC_SRCINC_10) #define CONF_DMAC_SRC_STRIDE_10 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_10) #define CONF_DMAC_DES_STRIDE_10 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_10 #define CONF_DMAC_SRC_STRIDE_10 0 #endif #ifndef CONF_DMAC_DES_STRIDE_10 #define CONF_DMAC_DES_STRIDE_10 0 #endif // Channel 11 settings // dmac_channel_11_settings #ifndef CONF_DMAC_CHANNEL_11_SETTINGS #define CONF_DMAC_CHANNEL_11_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_11 #ifndef CONF_DMAC_BURSTSIZE_11 #define CONF_DMAC_BURSTSIZE_11 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_11 #ifndef CONF_DMAC_CHUNKSIZE_11 #define CONF_DMAC_CHUNKSIZE_11 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_11 #ifndef CONF_DMAC_BEATSIZE_11 #define CONF_DMAC_BEATSIZE_11 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_11 #ifndef CONF_DMAC_SRC_INTERFACE_11 #define CONF_DMAC_SRC_INTERFACE_11 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_11 #ifndef CONF_DMAC_DES_INTERFACE_11 #define CONF_DMAC_DES_INTERFACE_11 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_11 #ifndef CONF_DMAC_SRCINC_11 #define CONF_DMAC_SRCINC_11 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_11 #ifndef CONF_DMAC_DSTINC_11 #define CONF_DMAC_DSTINC_11 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_11 #ifndef CONF_DMAC_TRANS_TYPE_11 #define CONF_DMAC_TRANS_TYPE_11 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_11 #ifndef CONF_DMAC_TRIGSRC_11 #define CONF_DMAC_TRIGSRC_11 0xff #endif // #if CONF_DMAC_TRANS_TYPE_11 == 0 #define CONF_DMAC_TYPE_11 0 #define CONF_DMAC_DSYNC_11 0 #elif CONF_DMAC_TRANS_TYPE_11 == 1 #define CONF_DMAC_TYPE_11 1 #define CONF_DMAC_DSYNC_11 0 #elif CONF_DMAC_TRANS_TYPE_11 == 2 #define CONF_DMAC_TYPE_11 1 #define CONF_DMAC_DSYNC_11 1 #endif #if CONF_DMAC_TRIGSRC_11 == 0xFF #define CONF_DMAC_SWREQ_11 1 #else #define CONF_DMAC_SWREQ_11 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_11_SETTINGS == 1 && CONF_DMAC_BEATSIZE_11 != 2 \ && ((!CONF_DMAC_SRCINC_11) || (!CONF_DMAC_DSTINC_11))) #if (!CONF_DMAC_SRCINC_11) #define CONF_DMAC_SRC_STRIDE_11 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_11) #define CONF_DMAC_DES_STRIDE_11 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_11 #define CONF_DMAC_SRC_STRIDE_11 0 #endif #ifndef CONF_DMAC_DES_STRIDE_11 #define CONF_DMAC_DES_STRIDE_11 0 #endif // Channel 12 settings // dmac_channel_12_settings #ifndef CONF_DMAC_CHANNEL_12_SETTINGS #define CONF_DMAC_CHANNEL_12_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_12 #ifndef CONF_DMAC_BURSTSIZE_12 #define CONF_DMAC_BURSTSIZE_12 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_12 #ifndef CONF_DMAC_CHUNKSIZE_12 #define CONF_DMAC_CHUNKSIZE_12 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_12 #ifndef CONF_DMAC_BEATSIZE_12 #define CONF_DMAC_BEATSIZE_12 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_12 #ifndef CONF_DMAC_SRC_INTERFACE_12 #define CONF_DMAC_SRC_INTERFACE_12 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_12 #ifndef CONF_DMAC_DES_INTERFACE_12 #define CONF_DMAC_DES_INTERFACE_12 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_12 #ifndef CONF_DMAC_SRCINC_12 #define CONF_DMAC_SRCINC_12 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_12 #ifndef CONF_DMAC_DSTINC_12 #define CONF_DMAC_DSTINC_12 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_12 #ifndef CONF_DMAC_TRANS_TYPE_12 #define CONF_DMAC_TRANS_TYPE_12 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_12 #ifndef CONF_DMAC_TRIGSRC_12 #define CONF_DMAC_TRIGSRC_12 0xff #endif // #if CONF_DMAC_TRANS_TYPE_12 == 0 #define CONF_DMAC_TYPE_12 0 #define CONF_DMAC_DSYNC_12 0 #elif CONF_DMAC_TRANS_TYPE_12 == 1 #define CONF_DMAC_TYPE_12 1 #define CONF_DMAC_DSYNC_12 0 #elif CONF_DMAC_TRANS_TYPE_12 == 2 #define CONF_DMAC_TYPE_12 1 #define CONF_DMAC_DSYNC_12 1 #endif #if CONF_DMAC_TRIGSRC_12 == 0xFF #define CONF_DMAC_SWREQ_12 1 #else #define CONF_DMAC_SWREQ_12 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_12_SETTINGS == 1 && CONF_DMAC_BEATSIZE_12 != 2 \ && ((!CONF_DMAC_SRCINC_12) || (!CONF_DMAC_DSTINC_12))) #if (!CONF_DMAC_SRCINC_12) #define CONF_DMAC_SRC_STRIDE_12 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_12) #define CONF_DMAC_DES_STRIDE_12 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_12 #define CONF_DMAC_SRC_STRIDE_12 0 #endif #ifndef CONF_DMAC_DES_STRIDE_12 #define CONF_DMAC_DES_STRIDE_12 0 #endif // Channel 13 settings // dmac_channel_13_settings #ifndef CONF_DMAC_CHANNEL_13_SETTINGS #define CONF_DMAC_CHANNEL_13_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_13 #ifndef CONF_DMAC_BURSTSIZE_13 #define CONF_DMAC_BURSTSIZE_13 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_13 #ifndef CONF_DMAC_CHUNKSIZE_13 #define CONF_DMAC_CHUNKSIZE_13 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_13 #ifndef CONF_DMAC_BEATSIZE_13 #define CONF_DMAC_BEATSIZE_13 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_13 #ifndef CONF_DMAC_SRC_INTERFACE_13 #define CONF_DMAC_SRC_INTERFACE_13 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_13 #ifndef CONF_DMAC_DES_INTERFACE_13 #define CONF_DMAC_DES_INTERFACE_13 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_13 #ifndef CONF_DMAC_SRCINC_13 #define CONF_DMAC_SRCINC_13 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_13 #ifndef CONF_DMAC_DSTINC_13 #define CONF_DMAC_DSTINC_13 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_13 #ifndef CONF_DMAC_TRANS_TYPE_13 #define CONF_DMAC_TRANS_TYPE_13 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_13 #ifndef CONF_DMAC_TRIGSRC_13 #define CONF_DMAC_TRIGSRC_13 0xff #endif // #if CONF_DMAC_TRANS_TYPE_13 == 0 #define CONF_DMAC_TYPE_13 0 #define CONF_DMAC_DSYNC_13 0 #elif CONF_DMAC_TRANS_TYPE_13 == 1 #define CONF_DMAC_TYPE_13 1 #define CONF_DMAC_DSYNC_13 0 #elif CONF_DMAC_TRANS_TYPE_13 == 2 #define CONF_DMAC_TYPE_13 1 #define CONF_DMAC_DSYNC_13 1 #endif #if CONF_DMAC_TRIGSRC_13 == 0xFF #define CONF_DMAC_SWREQ_13 1 #else #define CONF_DMAC_SWREQ_13 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_13_SETTINGS == 1 && CONF_DMAC_BEATSIZE_13 != 2 \ && ((!CONF_DMAC_SRCINC_13) || (!CONF_DMAC_DSTINC_13))) #if (!CONF_DMAC_SRCINC_13) #define CONF_DMAC_SRC_STRIDE_13 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_13) #define CONF_DMAC_DES_STRIDE_13 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_13 #define CONF_DMAC_SRC_STRIDE_13 0 #endif #ifndef CONF_DMAC_DES_STRIDE_13 #define CONF_DMAC_DES_STRIDE_13 0 #endif // Channel 14 settings // dmac_channel_14_settings #ifndef CONF_DMAC_CHANNEL_14_SETTINGS #define CONF_DMAC_CHANNEL_14_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_14 #ifndef CONF_DMAC_BURSTSIZE_14 #define CONF_DMAC_BURSTSIZE_14 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_14 #ifndef CONF_DMAC_CHUNKSIZE_14 #define CONF_DMAC_CHUNKSIZE_14 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_14 #ifndef CONF_DMAC_BEATSIZE_14 #define CONF_DMAC_BEATSIZE_14 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_14 #ifndef CONF_DMAC_SRC_INTERFACE_14 #define CONF_DMAC_SRC_INTERFACE_14 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_14 #ifndef CONF_DMAC_DES_INTERFACE_14 #define CONF_DMAC_DES_INTERFACE_14 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_14 #ifndef CONF_DMAC_SRCINC_14 #define CONF_DMAC_SRCINC_14 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_14 #ifndef CONF_DMAC_DSTINC_14 #define CONF_DMAC_DSTINC_14 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_14 #ifndef CONF_DMAC_TRANS_TYPE_14 #define CONF_DMAC_TRANS_TYPE_14 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_14 #ifndef CONF_DMAC_TRIGSRC_14 #define CONF_DMAC_TRIGSRC_14 0xff #endif // #if CONF_DMAC_TRANS_TYPE_14 == 0 #define CONF_DMAC_TYPE_14 0 #define CONF_DMAC_DSYNC_14 0 #elif CONF_DMAC_TRANS_TYPE_14 == 1 #define CONF_DMAC_TYPE_14 1 #define CONF_DMAC_DSYNC_14 0 #elif CONF_DMAC_TRANS_TYPE_14 == 2 #define CONF_DMAC_TYPE_14 1 #define CONF_DMAC_DSYNC_14 1 #endif #if CONF_DMAC_TRIGSRC_14 == 0xFF #define CONF_DMAC_SWREQ_14 1 #else #define CONF_DMAC_SWREQ_14 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_14_SETTINGS == 1 && CONF_DMAC_BEATSIZE_14 != 2 \ && ((!CONF_DMAC_SRCINC_14) || (!CONF_DMAC_DSTINC_14))) #if (!CONF_DMAC_SRCINC_14) #define CONF_DMAC_SRC_STRIDE_14 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_14) #define CONF_DMAC_DES_STRIDE_14 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_14 #define CONF_DMAC_SRC_STRIDE_14 0 #endif #ifndef CONF_DMAC_DES_STRIDE_14 #define CONF_DMAC_DES_STRIDE_14 0 #endif // Channel 15 settings // dmac_channel_15_settings #ifndef CONF_DMAC_CHANNEL_15_SETTINGS #define CONF_DMAC_CHANNEL_15_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_15 #ifndef CONF_DMAC_BURSTSIZE_15 #define CONF_DMAC_BURSTSIZE_15 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_15 #ifndef CONF_DMAC_CHUNKSIZE_15 #define CONF_DMAC_CHUNKSIZE_15 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_15 #ifndef CONF_DMAC_BEATSIZE_15 #define CONF_DMAC_BEATSIZE_15 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_15 #ifndef CONF_DMAC_SRC_INTERFACE_15 #define CONF_DMAC_SRC_INTERFACE_15 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_15 #ifndef CONF_DMAC_DES_INTERFACE_15 #define CONF_DMAC_DES_INTERFACE_15 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_15 #ifndef CONF_DMAC_SRCINC_15 #define CONF_DMAC_SRCINC_15 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_15 #ifndef CONF_DMAC_DSTINC_15 #define CONF_DMAC_DSTINC_15 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_15 #ifndef CONF_DMAC_TRANS_TYPE_15 #define CONF_DMAC_TRANS_TYPE_15 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_15 #ifndef CONF_DMAC_TRIGSRC_15 #define CONF_DMAC_TRIGSRC_15 0xff #endif // #if CONF_DMAC_TRANS_TYPE_15 == 0 #define CONF_DMAC_TYPE_15 0 #define CONF_DMAC_DSYNC_15 0 #elif CONF_DMAC_TRANS_TYPE_15 == 1 #define CONF_DMAC_TYPE_15 1 #define CONF_DMAC_DSYNC_15 0 #elif CONF_DMAC_TRANS_TYPE_15 == 2 #define CONF_DMAC_TYPE_15 1 #define CONF_DMAC_DSYNC_15 1 #endif #if CONF_DMAC_TRIGSRC_15 == 0xFF #define CONF_DMAC_SWREQ_15 1 #else #define CONF_DMAC_SWREQ_15 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_15_SETTINGS == 1 && CONF_DMAC_BEATSIZE_15 != 2 \ && ((!CONF_DMAC_SRCINC_15) || (!CONF_DMAC_DSTINC_15))) #if (!CONF_DMAC_SRCINC_15) #define CONF_DMAC_SRC_STRIDE_15 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_15) #define CONF_DMAC_DES_STRIDE_15 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_15 #define CONF_DMAC_SRC_STRIDE_15 0 #endif #ifndef CONF_DMAC_DES_STRIDE_15 #define CONF_DMAC_DES_STRIDE_15 0 #endif // Channel 16 settings // dmac_channel_16_settings #ifndef CONF_DMAC_CHANNEL_16_SETTINGS #define CONF_DMAC_CHANNEL_16_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_16 #ifndef CONF_DMAC_BURSTSIZE_16 #define CONF_DMAC_BURSTSIZE_16 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_16 #ifndef CONF_DMAC_CHUNKSIZE_16 #define CONF_DMAC_CHUNKSIZE_16 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_16 #ifndef CONF_DMAC_BEATSIZE_16 #define CONF_DMAC_BEATSIZE_16 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_16 #ifndef CONF_DMAC_SRC_INTERFACE_16 #define CONF_DMAC_SRC_INTERFACE_16 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_16 #ifndef CONF_DMAC_DES_INTERFACE_16 #define CONF_DMAC_DES_INTERFACE_16 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_16 #ifndef CONF_DMAC_SRCINC_16 #define CONF_DMAC_SRCINC_16 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_16 #ifndef CONF_DMAC_DSTINC_16 #define CONF_DMAC_DSTINC_16 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_16 #ifndef CONF_DMAC_TRANS_TYPE_16 #define CONF_DMAC_TRANS_TYPE_16 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_16 #ifndef CONF_DMAC_TRIGSRC_16 #define CONF_DMAC_TRIGSRC_16 0xff #endif // #if CONF_DMAC_TRANS_TYPE_16 == 0 #define CONF_DMAC_TYPE_16 0 #define CONF_DMAC_DSYNC_16 0 #elif CONF_DMAC_TRANS_TYPE_16 == 1 #define CONF_DMAC_TYPE_16 1 #define CONF_DMAC_DSYNC_16 0 #elif CONF_DMAC_TRANS_TYPE_16 == 2 #define CONF_DMAC_TYPE_16 1 #define CONF_DMAC_DSYNC_16 1 #endif #if CONF_DMAC_TRIGSRC_16 == 0xFF #define CONF_DMAC_SWREQ_16 1 #else #define CONF_DMAC_SWREQ_16 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_16_SETTINGS == 1 && CONF_DMAC_BEATSIZE_16 != 2 \ && ((!CONF_DMAC_SRCINC_16) || (!CONF_DMAC_DSTINC_16))) #if (!CONF_DMAC_SRCINC_16) #define CONF_DMAC_SRC_STRIDE_16 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_16) #define CONF_DMAC_DES_STRIDE_16 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_16 #define CONF_DMAC_SRC_STRIDE_16 0 #endif #ifndef CONF_DMAC_DES_STRIDE_16 #define CONF_DMAC_DES_STRIDE_16 0 #endif // Channel 17 settings // dmac_channel_17_settings #ifndef CONF_DMAC_CHANNEL_17_SETTINGS #define CONF_DMAC_CHANNEL_17_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_17 #ifndef CONF_DMAC_BURSTSIZE_17 #define CONF_DMAC_BURSTSIZE_17 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_17 #ifndef CONF_DMAC_CHUNKSIZE_17 #define CONF_DMAC_CHUNKSIZE_17 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_17 #ifndef CONF_DMAC_BEATSIZE_17 #define CONF_DMAC_BEATSIZE_17 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_17 #ifndef CONF_DMAC_SRC_INTERFACE_17 #define CONF_DMAC_SRC_INTERFACE_17 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_17 #ifndef CONF_DMAC_DES_INTERFACE_17 #define CONF_DMAC_DES_INTERFACE_17 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_17 #ifndef CONF_DMAC_SRCINC_17 #define CONF_DMAC_SRCINC_17 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_17 #ifndef CONF_DMAC_DSTINC_17 #define CONF_DMAC_DSTINC_17 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_17 #ifndef CONF_DMAC_TRANS_TYPE_17 #define CONF_DMAC_TRANS_TYPE_17 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_17 #ifndef CONF_DMAC_TRIGSRC_17 #define CONF_DMAC_TRIGSRC_17 0xff #endif // #if CONF_DMAC_TRANS_TYPE_17 == 0 #define CONF_DMAC_TYPE_17 0 #define CONF_DMAC_DSYNC_17 0 #elif CONF_DMAC_TRANS_TYPE_17 == 1 #define CONF_DMAC_TYPE_17 1 #define CONF_DMAC_DSYNC_17 0 #elif CONF_DMAC_TRANS_TYPE_17 == 2 #define CONF_DMAC_TYPE_17 1 #define CONF_DMAC_DSYNC_17 1 #endif #if CONF_DMAC_TRIGSRC_17 == 0xFF #define CONF_DMAC_SWREQ_17 1 #else #define CONF_DMAC_SWREQ_17 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_17_SETTINGS == 1 && CONF_DMAC_BEATSIZE_17 != 2 \ && ((!CONF_DMAC_SRCINC_17) || (!CONF_DMAC_DSTINC_17))) #if (!CONF_DMAC_SRCINC_17) #define CONF_DMAC_SRC_STRIDE_17 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_17) #define CONF_DMAC_DES_STRIDE_17 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_17 #define CONF_DMAC_SRC_STRIDE_17 0 #endif #ifndef CONF_DMAC_DES_STRIDE_17 #define CONF_DMAC_DES_STRIDE_17 0 #endif // Channel 18 settings // dmac_channel_18_settings #ifndef CONF_DMAC_CHANNEL_18_SETTINGS #define CONF_DMAC_CHANNEL_18_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_18 #ifndef CONF_DMAC_BURSTSIZE_18 #define CONF_DMAC_BURSTSIZE_18 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_18 #ifndef CONF_DMAC_CHUNKSIZE_18 #define CONF_DMAC_CHUNKSIZE_18 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_18 #ifndef CONF_DMAC_BEATSIZE_18 #define CONF_DMAC_BEATSIZE_18 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_18 #ifndef CONF_DMAC_SRC_INTERFACE_18 #define CONF_DMAC_SRC_INTERFACE_18 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_18 #ifndef CONF_DMAC_DES_INTERFACE_18 #define CONF_DMAC_DES_INTERFACE_18 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_18 #ifndef CONF_DMAC_SRCINC_18 #define CONF_DMAC_SRCINC_18 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_18 #ifndef CONF_DMAC_DSTINC_18 #define CONF_DMAC_DSTINC_18 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_18 #ifndef CONF_DMAC_TRANS_TYPE_18 #define CONF_DMAC_TRANS_TYPE_18 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_18 #ifndef CONF_DMAC_TRIGSRC_18 #define CONF_DMAC_TRIGSRC_18 0xff #endif // #if CONF_DMAC_TRANS_TYPE_18 == 0 #define CONF_DMAC_TYPE_18 0 #define CONF_DMAC_DSYNC_18 0 #elif CONF_DMAC_TRANS_TYPE_18 == 1 #define CONF_DMAC_TYPE_18 1 #define CONF_DMAC_DSYNC_18 0 #elif CONF_DMAC_TRANS_TYPE_18 == 2 #define CONF_DMAC_TYPE_18 1 #define CONF_DMAC_DSYNC_18 1 #endif #if CONF_DMAC_TRIGSRC_18 == 0xFF #define CONF_DMAC_SWREQ_18 1 #else #define CONF_DMAC_SWREQ_18 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_18_SETTINGS == 1 && CONF_DMAC_BEATSIZE_18 != 2 \ && ((!CONF_DMAC_SRCINC_18) || (!CONF_DMAC_DSTINC_18))) #if (!CONF_DMAC_SRCINC_18) #define CONF_DMAC_SRC_STRIDE_18 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_18) #define CONF_DMAC_DES_STRIDE_18 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_18 #define CONF_DMAC_SRC_STRIDE_18 0 #endif #ifndef CONF_DMAC_DES_STRIDE_18 #define CONF_DMAC_DES_STRIDE_18 0 #endif // Channel 19 settings // dmac_channel_19_settings #ifndef CONF_DMAC_CHANNEL_19_SETTINGS #define CONF_DMAC_CHANNEL_19_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_19 #ifndef CONF_DMAC_BURSTSIZE_19 #define CONF_DMAC_BURSTSIZE_19 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_19 #ifndef CONF_DMAC_CHUNKSIZE_19 #define CONF_DMAC_CHUNKSIZE_19 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_19 #ifndef CONF_DMAC_BEATSIZE_19 #define CONF_DMAC_BEATSIZE_19 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_19 #ifndef CONF_DMAC_SRC_INTERFACE_19 #define CONF_DMAC_SRC_INTERFACE_19 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_19 #ifndef CONF_DMAC_DES_INTERFACE_19 #define CONF_DMAC_DES_INTERFACE_19 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_19 #ifndef CONF_DMAC_SRCINC_19 #define CONF_DMAC_SRCINC_19 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_19 #ifndef CONF_DMAC_DSTINC_19 #define CONF_DMAC_DSTINC_19 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_19 #ifndef CONF_DMAC_TRANS_TYPE_19 #define CONF_DMAC_TRANS_TYPE_19 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_19 #ifndef CONF_DMAC_TRIGSRC_19 #define CONF_DMAC_TRIGSRC_19 0xff #endif // #if CONF_DMAC_TRANS_TYPE_19 == 0 #define CONF_DMAC_TYPE_19 0 #define CONF_DMAC_DSYNC_19 0 #elif CONF_DMAC_TRANS_TYPE_19 == 1 #define CONF_DMAC_TYPE_19 1 #define CONF_DMAC_DSYNC_19 0 #elif CONF_DMAC_TRANS_TYPE_19 == 2 #define CONF_DMAC_TYPE_19 1 #define CONF_DMAC_DSYNC_19 1 #endif #if CONF_DMAC_TRIGSRC_19 == 0xFF #define CONF_DMAC_SWREQ_19 1 #else #define CONF_DMAC_SWREQ_19 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_19_SETTINGS == 1 && CONF_DMAC_BEATSIZE_19 != 2 \ && ((!CONF_DMAC_SRCINC_19) || (!CONF_DMAC_DSTINC_19))) #if (!CONF_DMAC_SRCINC_19) #define CONF_DMAC_SRC_STRIDE_19 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_19) #define CONF_DMAC_DES_STRIDE_19 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_19 #define CONF_DMAC_SRC_STRIDE_19 0 #endif #ifndef CONF_DMAC_DES_STRIDE_19 #define CONF_DMAC_DES_STRIDE_19 0 #endif // Channel 20 settings // dmac_channel_20_settings #ifndef CONF_DMAC_CHANNEL_20_SETTINGS #define CONF_DMAC_CHANNEL_20_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_20 #ifndef CONF_DMAC_BURSTSIZE_20 #define CONF_DMAC_BURSTSIZE_20 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_20 #ifndef CONF_DMAC_CHUNKSIZE_20 #define CONF_DMAC_CHUNKSIZE_20 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_20 #ifndef CONF_DMAC_BEATSIZE_20 #define CONF_DMAC_BEATSIZE_20 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_20 #ifndef CONF_DMAC_SRC_INTERFACE_20 #define CONF_DMAC_SRC_INTERFACE_20 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_20 #ifndef CONF_DMAC_DES_INTERFACE_20 #define CONF_DMAC_DES_INTERFACE_20 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_20 #ifndef CONF_DMAC_SRCINC_20 #define CONF_DMAC_SRCINC_20 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_20 #ifndef CONF_DMAC_DSTINC_20 #define CONF_DMAC_DSTINC_20 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_20 #ifndef CONF_DMAC_TRANS_TYPE_20 #define CONF_DMAC_TRANS_TYPE_20 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_20 #ifndef CONF_DMAC_TRIGSRC_20 #define CONF_DMAC_TRIGSRC_20 0xff #endif // #if CONF_DMAC_TRANS_TYPE_20 == 0 #define CONF_DMAC_TYPE_20 0 #define CONF_DMAC_DSYNC_20 0 #elif CONF_DMAC_TRANS_TYPE_20 == 1 #define CONF_DMAC_TYPE_20 1 #define CONF_DMAC_DSYNC_20 0 #elif CONF_DMAC_TRANS_TYPE_20 == 2 #define CONF_DMAC_TYPE_20 1 #define CONF_DMAC_DSYNC_20 1 #endif #if CONF_DMAC_TRIGSRC_20 == 0xFF #define CONF_DMAC_SWREQ_20 1 #else #define CONF_DMAC_SWREQ_20 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_20_SETTINGS == 1 && CONF_DMAC_BEATSIZE_20 != 2 \ && ((!CONF_DMAC_SRCINC_20) || (!CONF_DMAC_DSTINC_20))) #if (!CONF_DMAC_SRCINC_20) #define CONF_DMAC_SRC_STRIDE_20 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_20) #define CONF_DMAC_DES_STRIDE_20 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_20 #define CONF_DMAC_SRC_STRIDE_20 0 #endif #ifndef CONF_DMAC_DES_STRIDE_20 #define CONF_DMAC_DES_STRIDE_20 0 #endif // Channel 21 settings // dmac_channel_21_settings #ifndef CONF_DMAC_CHANNEL_21_SETTINGS #define CONF_DMAC_CHANNEL_21_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_21 #ifndef CONF_DMAC_BURSTSIZE_21 #define CONF_DMAC_BURSTSIZE_21 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_21 #ifndef CONF_DMAC_CHUNKSIZE_21 #define CONF_DMAC_CHUNKSIZE_21 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_21 #ifndef CONF_DMAC_BEATSIZE_21 #define CONF_DMAC_BEATSIZE_21 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_21 #ifndef CONF_DMAC_SRC_INTERFACE_21 #define CONF_DMAC_SRC_INTERFACE_21 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_21 #ifndef CONF_DMAC_DES_INTERFACE_21 #define CONF_DMAC_DES_INTERFACE_21 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_21 #ifndef CONF_DMAC_SRCINC_21 #define CONF_DMAC_SRCINC_21 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_21 #ifndef CONF_DMAC_DSTINC_21 #define CONF_DMAC_DSTINC_21 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_21 #ifndef CONF_DMAC_TRANS_TYPE_21 #define CONF_DMAC_TRANS_TYPE_21 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_21 #ifndef CONF_DMAC_TRIGSRC_21 #define CONF_DMAC_TRIGSRC_21 0xff #endif // #if CONF_DMAC_TRANS_TYPE_21 == 0 #define CONF_DMAC_TYPE_21 0 #define CONF_DMAC_DSYNC_21 0 #elif CONF_DMAC_TRANS_TYPE_21 == 1 #define CONF_DMAC_TYPE_21 1 #define CONF_DMAC_DSYNC_21 0 #elif CONF_DMAC_TRANS_TYPE_21 == 2 #define CONF_DMAC_TYPE_21 1 #define CONF_DMAC_DSYNC_21 1 #endif #if CONF_DMAC_TRIGSRC_21 == 0xFF #define CONF_DMAC_SWREQ_21 1 #else #define CONF_DMAC_SWREQ_21 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_21_SETTINGS == 1 && CONF_DMAC_BEATSIZE_21 != 2 \ && ((!CONF_DMAC_SRCINC_21) || (!CONF_DMAC_DSTINC_21))) #if (!CONF_DMAC_SRCINC_21) #define CONF_DMAC_SRC_STRIDE_21 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_21) #define CONF_DMAC_DES_STRIDE_21 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_21 #define CONF_DMAC_SRC_STRIDE_21 0 #endif #ifndef CONF_DMAC_DES_STRIDE_21 #define CONF_DMAC_DES_STRIDE_21 0 #endif // Channel 22 settings // dmac_channel_22_settings #ifndef CONF_DMAC_CHANNEL_22_SETTINGS #define CONF_DMAC_CHANNEL_22_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_22 #ifndef CONF_DMAC_BURSTSIZE_22 #define CONF_DMAC_BURSTSIZE_22 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_22 #ifndef CONF_DMAC_CHUNKSIZE_22 #define CONF_DMAC_CHUNKSIZE_22 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_22 #ifndef CONF_DMAC_BEATSIZE_22 #define CONF_DMAC_BEATSIZE_22 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_22 #ifndef CONF_DMAC_SRC_INTERFACE_22 #define CONF_DMAC_SRC_INTERFACE_22 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_22 #ifndef CONF_DMAC_DES_INTERFACE_22 #define CONF_DMAC_DES_INTERFACE_22 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_22 #ifndef CONF_DMAC_SRCINC_22 #define CONF_DMAC_SRCINC_22 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_22 #ifndef CONF_DMAC_DSTINC_22 #define CONF_DMAC_DSTINC_22 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_22 #ifndef CONF_DMAC_TRANS_TYPE_22 #define CONF_DMAC_TRANS_TYPE_22 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_22 #ifndef CONF_DMAC_TRIGSRC_22 #define CONF_DMAC_TRIGSRC_22 0xff #endif // #if CONF_DMAC_TRANS_TYPE_22 == 0 #define CONF_DMAC_TYPE_22 0 #define CONF_DMAC_DSYNC_22 0 #elif CONF_DMAC_TRANS_TYPE_22 == 1 #define CONF_DMAC_TYPE_22 1 #define CONF_DMAC_DSYNC_22 0 #elif CONF_DMAC_TRANS_TYPE_22 == 2 #define CONF_DMAC_TYPE_22 1 #define CONF_DMAC_DSYNC_22 1 #endif #if CONF_DMAC_TRIGSRC_22 == 0xFF #define CONF_DMAC_SWREQ_22 1 #else #define CONF_DMAC_SWREQ_22 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_22_SETTINGS == 1 && CONF_DMAC_BEATSIZE_22 != 2 \ && ((!CONF_DMAC_SRCINC_22) || (!CONF_DMAC_DSTINC_22))) #if (!CONF_DMAC_SRCINC_22) #define CONF_DMAC_SRC_STRIDE_22 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_22) #define CONF_DMAC_DES_STRIDE_22 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_22 #define CONF_DMAC_SRC_STRIDE_22 0 #endif #ifndef CONF_DMAC_DES_STRIDE_22 #define CONF_DMAC_DES_STRIDE_22 0 #endif // Channel 23 settings // dmac_channel_23_settings #ifndef CONF_DMAC_CHANNEL_23_SETTINGS #define CONF_DMAC_CHANNEL_23_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_23 #ifndef CONF_DMAC_BURSTSIZE_23 #define CONF_DMAC_BURSTSIZE_23 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_23 #ifndef CONF_DMAC_CHUNKSIZE_23 #define CONF_DMAC_CHUNKSIZE_23 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_23 #ifndef CONF_DMAC_BEATSIZE_23 #define CONF_DMAC_BEATSIZE_23 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_23 #ifndef CONF_DMAC_SRC_INTERFACE_23 #define CONF_DMAC_SRC_INTERFACE_23 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_23 #ifndef CONF_DMAC_DES_INTERFACE_23 #define CONF_DMAC_DES_INTERFACE_23 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_23 #ifndef CONF_DMAC_SRCINC_23 #define CONF_DMAC_SRCINC_23 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_23 #ifndef CONF_DMAC_DSTINC_23 #define CONF_DMAC_DSTINC_23 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_23 #ifndef CONF_DMAC_TRANS_TYPE_23 #define CONF_DMAC_TRANS_TYPE_23 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_23 #ifndef CONF_DMAC_TRIGSRC_23 #define CONF_DMAC_TRIGSRC_23 0xff #endif // #if CONF_DMAC_TRANS_TYPE_23 == 0 #define CONF_DMAC_TYPE_23 0 #define CONF_DMAC_DSYNC_23 0 #elif CONF_DMAC_TRANS_TYPE_23 == 1 #define CONF_DMAC_TYPE_23 1 #define CONF_DMAC_DSYNC_23 0 #elif CONF_DMAC_TRANS_TYPE_23 == 2 #define CONF_DMAC_TYPE_23 1 #define CONF_DMAC_DSYNC_23 1 #endif #if CONF_DMAC_TRIGSRC_23 == 0xFF #define CONF_DMAC_SWREQ_23 1 #else #define CONF_DMAC_SWREQ_23 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_23_SETTINGS == 1 && CONF_DMAC_BEATSIZE_23 != 2 \ && ((!CONF_DMAC_SRCINC_23) || (!CONF_DMAC_DSTINC_23))) #if (!CONF_DMAC_SRCINC_23) #define CONF_DMAC_SRC_STRIDE_23 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_23) #define CONF_DMAC_DES_STRIDE_23 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_23 #define CONF_DMAC_SRC_STRIDE_23 0 #endif #ifndef CONF_DMAC_DES_STRIDE_23 #define CONF_DMAC_DES_STRIDE_23 0 #endif // // <<< end of configuration section >>> #endif // HPL_XDMAC_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_qmtech/peripheral_clk_config.h ================================================ /* Auto-generated config file peripheral_clk_config.h */ #ifndef PERIPHERAL_CLK_CONFIG_H #define PERIPHERAL_CLK_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> /** * \def CONF_HCLK_FREQUENCY * \brief HCLK's Clock frequency */ #ifndef CONF_HCLK_FREQUENCY #define CONF_HCLK_FREQUENCY 300000000 #endif /** * \def CONF_FCLK_FREQUENCY * \brief FCLK's Clock frequency */ #ifndef CONF_FCLK_FREQUENCY #define CONF_FCLK_FREQUENCY 300000000 #endif /** * \def CONF_CPU_FREQUENCY * \brief CPU's Clock frequency */ #ifndef CONF_CPU_FREQUENCY #define CONF_CPU_FREQUENCY 300000000 #endif /** * \def CONF_SLCK_FREQUENCY * \brief Slow Clock frequency */ #define CONF_SLCK_FREQUENCY 0 /** * \def CONF_MCK_FREQUENCY * \brief Master Clock frequency */ #define CONF_MCK_FREQUENCY 150000000 /** * \def CONF_PCK6_FREQUENCY * \brief Programmable Clock Controller 6 frequency */ #define CONF_PCK6_FREQUENCY 1714285 // USART Clock Settings // USART Clock source // <0=> Master Clock (MCK) // <1=> MCK / 8 for USART // <2=> Programmable Clock Controller 4 (PMC_PCK4) // <3=> External Clock // This defines the clock source for the USART // usart_clock_source #ifndef CONF_USART1_CK_SRC #define CONF_USART1_CK_SRC 0 #endif // USART External Clock Input on SCK <1-4294967295> // Inputs the external clock frequency on SCK // usart_clock_freq #ifndef CONF_USART1_SCK_FREQ #define CONF_USART1_SCK_FREQ 10000000 #endif // /** * \def USART FREQUENCY * \brief USART's Clock frequency */ #ifndef CONF_USART1_FREQUENCY #define CONF_USART1_FREQUENCY 150000000 #endif #ifndef CONF_SRC_USB_480M #define CONF_SRC_USB_480M 0 #endif #ifndef CONF_SRC_USB_48M #define CONF_SRC_USB_48M 1 #endif // USB Full/Low Speed Clock // USB Clock Controller (USB_48M) // usb_fsls_clock_source // 48MHz clock source for low speed and full speed. // It must be available when low speed is supported by host driver. // It must be available when low power mode is selected. #ifndef CONF_USBHS_FSLS_SRC #define CONF_USBHS_FSLS_SRC CONF_SRC_USB_48M #endif // USB Clock Source(Normal/Low-power Mode Selection) // USB High Speed Clock (USB_480M) // USB Clock Controller (USB_48M) // usb_clock_source // Select the clock source for USB. // In normal mode, use "USB High Speed Clock (USB_480M)". // In low-power mode, use "USB Clock Controller (USB_48M)". #ifndef CONF_USBHS_SRC #define CONF_USBHS_SRC CONF_SRC_USB_480M #endif /** * \def CONF_USBHS_FSLS_FREQUENCY * \brief USBHS's Full/Low Speed Clock Source frequency */ #ifndef CONF_USBHS_FSLS_FREQUENCY #define CONF_USBHS_FSLS_FREQUENCY 48000000 #endif /** * \def CONF_USBHS_FREQUENCY * \brief USBHS's Selected Clock Source frequency */ #ifndef CONF_USBHS_FREQUENCY #define CONF_USBHS_FREQUENCY 480000000 #endif // <<< end of configuration section >>> #endif // PERIPHERAL_CLK_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/board.cmake ================================================ set(JLINK_DEVICE ATSAME70Q21B) set(LD_FILE_GNU ${TOP}/hw/mcu/microchip/same70/same70b/gcc/gcc/same70q21b_flash.ld) set(LD_FILE_IAR ${TOP}/hw/mcu/microchip/same70/same70b/iar/config/linker/Microchip/atsame70q21b/flash.icf) set(STARTUP_FILE_GNU ${TOP}/hw/mcu/microchip/same70/same70b/gcc/gcc/startup_same70q21b.c) set(STARTUP_FILE_IAR ${TOP}/hw/mcu/microchip/same70/same70b/iar/iar/startup_same70q21b.c) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC __SAME70Q21B__ ) endfunction() ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: SAME70 Xplained manufacturer: Microchip url: https://www.microchip.com/en-us/development-tool/atsame70-xpld */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PIN GPIO(GPIO_PORTC, 8) #define LED_STATE_ON 1 #define LED_PORT_CLOCK ID_PIOC #define BUTTON_PIN GPIO(GPIO_PORTA, 11) #define BUTTON_STATE_ACTIVE 0 #define BUTTON_PORT_CLOCK ID_PIOA #define UART_TX_PIN GPIO(GPIO_PORTB, 4) #define UART_TX_FUNCTION MUX_PB4D_USART1_TXD1 #define UART_RX_PIN GPIO(GPIO_PORTA, 21) #define UART_RX_FUNCTION MUX_PA21A_USART1_RXD1 #define UART_PORT_CLOCK ID_USART1 #define BOARD_USART USART1 static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/board.mk ================================================ CFLAGS += -D__SAME70Q21B__ LD_FILE = $(SDK_DIR)/same70b/gcc/gcc/same70q21b_flash.ld STARTUP_FILE = $(SDK_DIR)/same70b/gcc/gcc/startup_same70q21b.c JLINK_DEVICE = ATSAME70Q21B ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/hpl_pmc_config.h ================================================ /* Auto-generated config file hpl_pmc_config.h */ #ifndef HPL_PMC_CONFIG_H #define HPL_PMC_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> #include #define CLK_SRC_OPTION_OSC32K 0 #define CLK_SRC_OPTION_XOSC32K 1 #define CLK_SRC_OPTION_OSC12M 2 #define CLK_SRC_OPTION_XOSC20M 3 #define CLK_SRC_OPTION_SLCK 0 #define CLK_SRC_OPTION_MAINCK 1 #define CLK_SRC_OPTION_PLLACK 2 #define CLK_SRC_OPTION_UPLLCKDIV 3 #define CLK_SRC_OPTION_MCK 4 #define CLK_SRC_OPTION_UPLLCK 3 #define CONF_RC_4M 0 #define CONF_RC_8M 1 #define CONF_RC_12M 2 #define CONF_XOSC32K_NO_BYPASS 0 #define CONF_XOSC32K_BYPASS 1 #define CONF_XOSC20M_NO_BYPASS 0 #define CONF_XOSC20M_BYPASS 1 // Clock_SLCK configuration // Indicates whether SLCK configuration is enabled or not // enable_clk_gen_slck #ifndef CONF_CLK_SLCK_CONFIG #define CONF_CLK_SLCK_CONFIG 1 #endif // Clock Generator // clock generator SLCK source // 32kHz High Accuracy Internal Oscillator (OSC32K) // 32kHz External Crystal Oscillator (XOSC32K) // This defines the clock source for SLCK // clk_gen_slck_oscillator #ifndef CONF_CLK_GEN_SLCK_SRC #define CONF_CLK_GEN_SLCK_SRC CLK_SRC_OPTION_OSC32K #endif // Enable Clock_SLCK // Indicates whether SLCK is enabled or disable // clk_gen_slck_arch_enable #ifndef CONF_CLK_SLCK_ENABLE #define CONF_CLK_SLCK_ENABLE 1 #endif // // // // // Clock_MAINCK configuration // Indicates whether MAINCK configuration is enabled or not // enable_clk_gen_mainck #ifndef CONF_CLK_MAINCK_CONFIG #define CONF_CLK_MAINCK_CONFIG 1 #endif // Clock Generator // clock generator MAINCK source // Embedded 4/8/12MHz RC Oscillator (OSC12M) // External 3-20MHz Oscillator (XOSC20M) // This defines the clock source for MAINCK // clk_gen_mainck_oscillator #ifndef CONF_CLK_GEN_MAINCK_SRC #define CONF_CLK_GEN_MAINCK_SRC CLK_SRC_OPTION_XOSC20M #endif // Enable Clock_MAINCK // Indicates whether MAINCK is enabled or disable // clk_gen_mainck_arch_enable #ifndef CONF_CLK_MAINCK_ENABLE #define CONF_CLK_MAINCK_ENABLE 1 #endif // Enable Main Clock Failure Detection // Indicates whether Main Clock Failure Detection is enabled or disable. // The 4/8/12 MHz RC oscillator must be selected as the source of MAINCK. // clk_gen_cfden_enable #ifndef CONF_CLK_CFDEN_ENABLE #define CONF_CLK_CFDEN_ENABLE 0 #endif // // // // // Clock_MCKR configuration // Indicates whether MCKR configuration is enabled or not // enable_clk_gen_mckr #ifndef CONF_CLK_MCKR_CONFIG #define CONF_CLK_MCKR_CONFIG 1 #endif // Clock Generator // clock generator MCKR source // Slow Clock (SLCK) // Main Clock (MAINCK) // PLLA Clock (PLLACK) // UDPLL with Divider (MCKR UPLLDIV2) // This defines the clock source for MCKR // clk_gen_mckr_oscillator #ifndef CONF_CLK_GEN_MCKR_SRC #define CONF_CLK_GEN_MCKR_SRC CLK_SRC_OPTION_PLLACK #endif // Enable Clock_MCKR // Indicates whether MCKR is enabled or disable // clk_gen_mckr_arch_enable #ifndef CONF_CLK_MCKR_ENABLE #define CONF_CLK_MCKR_ENABLE 1 #endif // // // Master Clock Prescaler // <0=> 1 // <1=> 2 // <2=> 4 // <3=> 8 // <4=> 16 // <5=> 32 // <6=> 64 // <7=> 3 // Select the clock prescaler. // mckr_presc #ifndef CONF_MCKR_PRESC #define CONF_MCKR_PRESC 0 #endif // // // Clock_MCK configuration // Indicates whether MCK configuration is enabled or not // enable_clk_gen_mck #ifndef CONF_CLK_MCK_CONFIG #define CONF_CLK_MCK_CONFIG 1 #endif // Clock Generator // clock generator MCK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for MCK // clk_gen_mck_oscillator #ifndef CONF_CLK_GEN_MCK_SRC #define CONF_CLK_GEN_MCK_SRC CLK_SRC_OPTION_MCKR #endif // // // Master Clock Controller Divider MCK divider // <0=> 1 // <1=> 2 // <3=> 3 // <2=> 4 // Select the master clock divider. // mck_div #ifndef CONF_MCK_DIV #define CONF_MCK_DIV 1 #endif // // // Clock_SYSTICK configuration // Indicates whether SYSTICK configuration is enabled or not // enable_clk_gen_systick #ifndef CONF_CLK_SYSTICK_CONFIG #define CONF_CLK_SYSTICK_CONFIG 1 #endif // Clock Generator // clock generator SYSTICK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for SYSTICK // clk_gen_systick_oscillator #ifndef CONF_CLK_GEN_SYSTICK_SRC #define CONF_CLK_GEN_SYSTICK_SRC CLK_SRC_OPTION_MCKR #endif // // // Systick clock divider // <8=> 8 // Select systick clock divider // systick_clock_div #ifndef CONF_SYSTICK_DIV #define CONF_SYSTICK_DIV 8 #endif // // // Clock_FCLK configuration // Indicates whether FCLK configuration is enabled or not // enable_clk_gen_fclk #ifndef CONF_CLK_FCLK_CONFIG #define CONF_CLK_FCLK_CONFIG 1 #endif // Clock Generator // clock generator FCLK source // Master Clock Controller (PMC_MCKR) // This defines the clock source for FCLK // clk_gen_fclk_oscillator #ifndef CONF_CLK_GEN_FCLK_SRC #define CONF_CLK_GEN_FCLK_SRC CLK_SRC_OPTION_MCKR #endif // // // // // Clock_GCLK0 configuration // Indicates whether GCLK0 configuration is enabled or not // enable_clk_gen_gclk0 #ifndef CONF_CLK_GCLK0_CONFIG #define CONF_CLK_GCLK0_CONFIG 1 #endif // Clock Generator // clock generator GCLK0 source // Slow Clock (SLCK) // Main Clock (MAINCK) // USB 480M Clock (UPLLCK) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for GCLK0 // clk_gen_gclk0_oscillator #ifndef CONF_CLK_GEN_GCLK0_SRC #define CONF_CLK_GEN_GCLK0_SRC CLK_SRC_OPTION_MCK #endif // Enable Clock_GCLK0 // Indicates whether GCLK0 is enabled or disable // clk_gen_gclk0_arch_enable #ifndef CONF_CLK_GCLK0_ENABLE #define CONF_CLK_GCLK0_ENABLE 1 #endif // // // Enable GCLK0 GCLKEN // Indicates whether GCLK0 GCLKEN is enabled or disable // gclk0_gclken_enable #ifndef CONF_GCLK0_GCLKEN_ENABLE #define CONF_GCLK0_GCLKEN_ENABLE 0 #endif // Generic Clock GCLK0 divider <1-256> // Select the clock divider (divider = GCLKDIV + 1). // gclk0_div #ifndef CONF_GCLK0_DIV #define CONF_GCLK0_DIV 2 #endif // // // Clock_GCLK1 configuration // Indicates whether GCLK1 configuration is enabled or not // enable_clk_gen_gclk1 #ifndef CONF_CLK_GCLK1_CONFIG #define CONF_CLK_GCLK1_CONFIG 1 #endif // Clock Generator // clock generator GCLK1 source // Slow Clock (SLCK) // Main Clock (MAINCK) // USB 480M Clock (UPLLCK) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for GCLK1 // clk_gen_gclk1_oscillator #ifndef CONF_CLK_GEN_GCLK1_SRC #define CONF_CLK_GEN_GCLK1_SRC CLK_SRC_OPTION_PLLACK #endif // Enable Clock_GCLK1 // Indicates whether GCLK1 is enabled or disable // clk_gen_gclk1_arch_enable #ifndef CONF_CLK_GCLK1_ENABLE #define CONF_CLK_GCLK1_ENABLE 1 #endif // // // Enable GCLK1 GCLKEN // Indicates whether GCLK1 GCLKEN is enabled or disable // gclk1_gclken_enable #ifndef CONF_GCLK1_GCLKEN_ENABLE #define CONF_GCLK1_GCLKEN_ENABLE 0 #endif // Generic Clock GCLK1 divider <1-256> // Select the clock divider (divider = GCLKDIV + 1). // gclk1_div #ifndef CONF_GCLK1_DIV #define CONF_GCLK1_DIV 3 #endif // // // Clock_PCK0 configuration // Indicates whether PCK0 configuration is enabled or not // enable_clk_gen_pck0 #ifndef CONF_CLK_PCK0_CONFIG #define CONF_CLK_PCK0_CONFIG 1 #endif // Clock Generator // clock generator PCK0 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK0 // clk_gen_pck0_oscillator #ifndef CONF_CLK_GEN_PCK0_SRC #define CONF_CLK_GEN_PCK0_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK0 // Indicates whether PCK0 is enabled or disable // clk_gen_pck0_arch_enable #ifndef CONF_CLK_PCK0_ENABLE #define CONF_CLK_PCK0_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck0_presc #ifndef CONF_PCK0_PRESC #define CONF_PCK0_PRESC 1 #endif // // // Clock_PCK1 configuration // Indicates whether PCK1 configuration is enabled or not // enable_clk_gen_pck1 #ifndef CONF_CLK_PCK1_CONFIG #define CONF_CLK_PCK1_CONFIG 1 #endif // Clock Generator // clock generator PCK1 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK1 // clk_gen_pck1_oscillator #ifndef CONF_CLK_GEN_PCK1_SRC #define CONF_CLK_GEN_PCK1_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK1 // Indicates whether PCK1 is enabled or disable // clk_gen_pck1_arch_enable #ifndef CONF_CLK_PCK1_ENABLE #define CONF_CLK_PCK1_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck1_presc #ifndef CONF_PCK1_PRESC #define CONF_PCK1_PRESC 2 #endif // // // Clock_PCK2 configuration // Indicates whether PCK2 configuration is enabled or not // enable_clk_gen_pck2 #ifndef CONF_CLK_PCK2_CONFIG #define CONF_CLK_PCK2_CONFIG 1 #endif // Clock Generator // clock generator PCK2 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK2 // clk_gen_pck2_oscillator #ifndef CONF_CLK_GEN_PCK2_SRC #define CONF_CLK_GEN_PCK2_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK2 // Indicates whether PCK2 is enabled or disable // clk_gen_pck2_arch_enable #ifndef CONF_CLK_PCK2_ENABLE #define CONF_CLK_PCK2_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck2_presc #ifndef CONF_PCK2_PRESC #define CONF_PCK2_PRESC 3 #endif // // // Clock_PCK3 configuration // Indicates whether PCK3 configuration is enabled or not // enable_clk_gen_pck3 #ifndef CONF_CLK_PCK3_CONFIG #define CONF_CLK_PCK3_CONFIG 1 #endif // Clock Generator // clock generator PCK3 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK3 // clk_gen_pck3_oscillator #ifndef CONF_CLK_GEN_PCK3_SRC #define CONF_CLK_GEN_PCK3_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK3 // Indicates whether PCK3 is enabled or disable // clk_gen_pck3_arch_enable #ifndef CONF_CLK_PCK3_ENABLE #define CONF_CLK_PCK3_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck3_presc #ifndef CONF_PCK3_PRESC #define CONF_PCK3_PRESC 4 #endif // // // Clock_PCK4 configuration // Indicates whether PCK4 configuration is enabled or not // enable_clk_gen_pck4 #ifndef CONF_CLK_PCK4_CONFIG #define CONF_CLK_PCK4_CONFIG 1 #endif // Clock Generator // clock generator PCK4 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK4 // clk_gen_pck4_oscillator #ifndef CONF_CLK_GEN_PCK4_SRC #define CONF_CLK_GEN_PCK4_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK4 // Indicates whether PCK4 is enabled or disable // clk_gen_pck4_arch_enable #ifndef CONF_CLK_PCK4_ENABLE #define CONF_CLK_PCK4_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck4_presc #ifndef CONF_PCK4_PRESC #define CONF_PCK4_PRESC 5 #endif // // // Clock_PCK5 configuration // Indicates whether PCK5 configuration is enabled or not // enable_clk_gen_pck5 #ifndef CONF_CLK_PCK5_CONFIG #define CONF_CLK_PCK5_CONFIG 1 #endif // Clock Generator // clock generator PCK5 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK5 // clk_gen_pck5_oscillator #ifndef CONF_CLK_GEN_PCK5_SRC #define CONF_CLK_GEN_PCK5_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK5 // Indicates whether PCK5 is enabled or disable // clk_gen_pck5_arch_enable #ifndef CONF_CLK_PCK5_ENABLE #define CONF_CLK_PCK5_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck5_presc #ifndef CONF_PCK5_PRESC #define CONF_PCK5_PRESC 6 #endif // // // Clock_PCK6 configuration // Indicates whether PCK6 configuration is enabled or not // enable_clk_gen_pck6 #ifndef CONF_CLK_PCK6_CONFIG #define CONF_CLK_PCK6_CONFIG 1 #endif // Clock Generator // clock generator PCK6 source // Slow Clock (SLCK) // Main Clock (MAINCK) // UDPLL with Divider (MCKR UPLLDIV2) // PLLA Clock (PLLACK) // Master Clock (MCK) // This defines the clock source for PCK6 // clk_gen_pck6_oscillator #ifndef CONF_CLK_GEN_PCK6_SRC #define CONF_CLK_GEN_PCK6_SRC CLK_SRC_OPTION_MAINCK #endif // Enable Clock_PCK6 // Indicates whether PCK6 is enabled or disable // clk_gen_pck6_arch_enable #ifndef CONF_CLK_PCK6_ENABLE #define CONF_CLK_PCK6_ENABLE 0 #endif // // // Programmable Clock Controller Prescaler <1-256> // Select the clock prescaler (prescaler = PRESC + 1). // pck6_presc #ifndef CONF_PCK6_PRESC #define CONF_PCK6_PRESC 7 #endif // // // Clock_USB_480M configuration // Indicates whether USB_480M configuration is enabled or not // enable_clk_gen_usb_480m #ifndef CONF_CLK_USB_480M_CONFIG #define CONF_CLK_USB_480M_CONFIG 1 #endif // Clock Generator // clock generator USB_480M source // USB 480M Clock (UPLLCK) // This defines the clock source for USB_480M // clk_gen_usb_480m_oscillator #ifndef CONF_CLK_GEN_USB_480M_SRC #define CONF_CLK_GEN_USB_480M_SRC CLK_SRC_OPTION_UPLLCK #endif // // // // // Clock_USB_48M configuration // Indicates whether USB_48M configuration is enabled or not // enable_clk_gen_usb_48m #ifndef CONF_CLK_USB_48M_CONFIG #define CONF_CLK_USB_48M_CONFIG 1 #endif // Clock Generator // clock generator USB_48M source // PLLA Clock (PLLACK) // UDPLL with Divider (MCKR UPLLDIV2) // This defines the clock source for USB_48M // clk_gen_usb_48m_oscillator #ifndef CONF_CLK_GEN_USB_48M_SRC #define CONF_CLK_GEN_USB_48M_SRC CLK_SRC_OPTION_UPLLCKDIV #endif // Enable Clock_USB_48M // Indicates whether USB_48M is enabled or disable // clk_gen_usb_48m_arch_enable #ifndef CONF_CLK_USB_48M_ENABLE #define CONF_CLK_USB_48M_ENABLE 1 #endif // // // USB Clock Controller Divider <1-16> // Select the USB clock divider (divider = USBDIV + 1). // usb_48m_div #ifndef CONF_USB_48M_DIV #define CONF_USB_48M_DIV 5 #endif // // // Clock_SLCK2 configuration // Indicates whether SLCK2 configuration is enabled or not // enable_clk_gen_slck2 #ifndef CONF_CLK_SLCK2_CONFIG #define CONF_CLK_SLCK2_CONFIG 1 #endif // Clock Generator // clock generator SLCK2 source // Slow Clock (SLCK) // This defines the clock source for SLCK2 // clk_gen_slck2_oscillator #ifndef CONF_CLK_GEN_SLCK2_SRC #define CONF_CLK_GEN_SLCK2_SRC CLK_SRC_OPTION_SLCK #endif // // // // // System Configuration // Indicates whether configuration for system is enabled or not // enable_hclk_clock #ifndef CONF_SYSTEM_CONFIG #define CONF_SYSTEM_CONFIG 1 #endif // Processor Clock Settings // Processor Clock source // Master Clock Controller (PMC_MCKR) // This defines the clock source for the HCLK (Processor clock) // hclk_clock_source #ifndef CONF_HCLK_SRC #define CONF_HCLK_SRC MCKR #endif // Flash Wait State // <0=> 1 cycle // <1=> 2 cycles // <2=> 3 cycles // <3=> 4 cycles // <4=> 5 cycles // <5=> 6 cycles // <6=> 7 cycles // This field defines the number of wait states for read and write operations. // efc_fws #ifndef CONF_EFC_WAIT_STATE #define CONF_EFC_WAIT_STATE 5 #endif // // // SysTick Clock // enable_systick_clk_clock #ifndef CONF_SYSTICK_CLK_CONFIG #define CONF_SYSTICK_CLK_CONFIG 1 #endif // SysTick Clock source // Master Clock Controller (PMC_MCKR) // This defines the clock source for the SysTick Clock // systick_clk_clock_source #ifndef CONF_SYSTICK_CLK_SRC #define CONF_SYSTICK_CLK_SRC MCKR #endif // SysTick Clock Divider // <8=> 8 // Fixed to 8 if Systick is not using Processor clock // systick_clk_clock_div #ifndef CONF_SYSTICK_CLK_DIV #define CONF_SYSTICK_CLK_DIV 8 #endif // // OSC32K Oscillator Configuration // Indicates whether configuration for OSC32K is enabled or not // enable_osc32k #ifndef CONF_OSC32K_CONFIG #define CONF_OSC32K_CONFIG 1 #endif // OSC32K Oscillator Control // OSC32K Oscillator Enable // Indicates whether OSC32K Oscillator is enabled or not // osc32k_arch_enable #ifndef CONF_OSC32K_ENABLE #define CONF_OSC32K_ENABLE 0 #endif // // // XOSC32K Oscillator Configuration // Indicates whether configuration for XOSC32K is enabled or not // enable_xosc32k #ifndef CONF_XOSC32K_CONFIG #define CONF_XOSC32K_CONFIG 0 #endif // XOSC32K Oscillator Control // Oscillator Bypass Select // The 32kHz crystal oscillator is not bypassed. // The 32kHz crystal oscillator is bypassed. // Indicates whether XOSC32K is bypassed. // xosc32k_bypass #ifndef CONF_XOSC32K #define CONF_XOSC32K CONF_XOSC32K_NO_BYPASS #endif // XOSC32K Oscillator Enable // Indicates whether XOSC32K Oscillator is enabled or not // xosc32k_arch_enable #ifndef CONF_XOSC32K_ENABLE #define CONF_XOSC32K_ENABLE 0 #endif // // // OSC12M Oscillator Configuration // Indicates whether configuration for OSC12M is enabled or not // enable_osc12m #ifndef CONF_OSC12M_CONFIG #define CONF_OSC12M_CONFIG 0 #endif // OSC12M Oscillator Control // OSC12M Oscillator Enable // Indicates whether OSC12M Oscillator is enabled or not. // osc12m_arch_enable #ifndef CONF_OSC12M_ENABLE #define CONF_OSC12M_ENABLE 0 #endif // OSC12M selector // <0=> 4000000 // <1=> 8000000 // <2=> 12000000 // Select the frequency of embedded fast RC oscillator. // osc12m_selector #ifndef CONF_OSC12M_SELECTOR #define CONF_OSC12M_SELECTOR 2 #endif // // // XOSC20M Oscillator Configuration // Indicates whether configuration for XOSC20M is enabled or not. // enable_xosc20m #ifndef CONF_XOSC20M_CONFIG #define CONF_XOSC20M_CONFIG 1 #endif // XOSC20M Oscillator Control // XOSC20M selector <3000000-20000000> // Select the frequency of crystal or ceramic resonator oscillator. // xosc20m_selector #ifndef CONF_XOSC20M_SELECTOR #define CONF_XOSC20M_SELECTOR 12000000 #endif // Start up time for the external oscillator (ms): <0-256> // Select start-up time. // xosc20m_startup_time #ifndef CONF_XOSC20M_STARTUP_TIME #define CONF_XOSC20M_STARTUP_TIME 62 #endif // Oscillator Bypass Select // The external crystal oscillator is not bypassed. // The external crystal oscillator is bypassed. // Indicates whether XOSC20M is bypassed. // xosc20m_bypass #ifndef CONF_XOSC20M #define CONF_XOSC20M CONF_XOSC20M_NO_BYPASS #endif // XOSC20M Oscillator Enable // Indicates whether XOSC20M Oscillator is enabled or not // xosc20m_arch_enable #ifndef CONF_XOSC20M_ENABLE #define CONF_XOSC20M_ENABLE 1 #endif // // // PLLACK Oscillator Configuration // Indicates whether configuration for PLLACK is enabled or not // enable_pllack #ifndef CONF_PLLACK_CONFIG #define CONF_PLLACK_CONFIG 1 #endif // PLLACK Reference Clock Source // Main Clock (MAINCK) // Select the clock source. // pllack_ref_clock #ifndef CONF_PLLACK_CLK #define CONF_PLLACK_CLK MAINCK #endif // PLLACK Oscillator Control // PLLACK Oscillator Enable // Indicates whether PLLACK Oscillator is enabled or not // pllack_arch_enable #ifndef CONF_PLLACK_ENABLE #define CONF_PLLACK_ENABLE 1 #endif // PLLA Frontend Divider (DIVA) <1-255> // Select the clock divider // pllack_div #ifndef CONF_PLLACK_DIV #define CONF_PLLACK_DIV 1 #endif // PLLACK Muliplier <1-62> // Indicates PLLA multiplier (multiplier = MULA + 1). // pllack_mul #ifndef CONF_PLLACK_MUL #define CONF_PLLACK_MUL 25 #endif // // // UPLLCK Oscillator Configuration // Indicates whether configuration for UPLLCK is enabled or not // enable_upllck #ifndef CONF_UPLLCK_CONFIG #define CONF_UPLLCK_CONFIG 1 #endif // UPLLCK Reference Clock Source // External 3-20MHz Oscillator (XOSC20M) // Select the clock source,only when the input frequency is 12M or 16M, the upllck output is 480M. // upllck_ref_clock #ifndef CONF_UPLLCK_CLK #define CONF_UPLLCK_CLK XOSC20M #endif // UPLLCK Oscillator Control // UPLLCK Oscillator Enable // Indicates whether UPLLCK Oscillator is enabled or not // upllck_arch_enable #ifndef CONF_UPLLCK_ENABLE #define CONF_UPLLCK_ENABLE 1 #endif // // // UPLLCKDIV Oscillator Configuration // Indicates whether configuration for UPLLCKDIV is enabled or not // enable_upllckdiv #ifndef CONF_UPLLCKDIV_CONFIG #define CONF_UPLLCKDIV_CONFIG 1 #endif // UPLLCKDIV Reference Clock Source // USB 480M Clock (UPLLCK) // Select the clock source. // upllckdiv_ref_clock #ifndef CONF_UPLLCKDIV_CLK #define CONF_UPLLCKDIV_CLK UPLLCK #endif // UPLLCKDIV Oscillator Control // UPLLCKDIV Clock Divider // <0=> 1 // <1=> 2 // Select the clock divider. // upllckdiv_div #ifndef CONF_UPLLCKDIV_DIV #define CONF_UPLLCKDIV_DIV 1 #endif // // // MCK/8 // enable_mck_div_8 #ifndef CONF_MCK_DIV_8_CONFIG #define CONF_MCK_DIV_8_CONFIG 0 #endif // MCK/8 Source // <0=> Master Clock (MCK) // mck_div_8_src #ifndef CONF_MCK_DIV_8_SRC #define CONF_MCK_DIV_8_SRC 0 #endif // // External Clock Input Configuration // enable_dummy_ext #ifndef CONF_DUMMY_EXT_CONFIG #define CONF_DUMMY_EXT_CONFIG 1 #endif // External Clock Input Source // All here are dummy values // Refer to the peripherals settings for actual input information // <0=> Specific clock input from specific pin // dummy_ext_src #ifndef CONF_DUMMY_EXT_SRC #define CONF_DUMMY_EXT_SRC 0 #endif // // External Clock Configuration // enable_dummy_ext_clk #ifndef CONF_DUMMY_EXT_CLK_CONFIG #define CONF_DUMMY_EXT_CLK_CONFIG 1 #endif // External Clock Source // All here are dummy values // Refer to the peripherals settings for actual input information // <0=> External Clock Input // dummy_ext_clk_src #ifndef CONF_DUMMY_EXT_CLK_SRC #define CONF_DUMMY_EXT_CLK_SRC 0 #endif // // <<< end of configuration section >>> #endif // HPL_PMC_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/hpl_usart_config.h ================================================ /* Auto-generated config file hpl_usart_config.h */ #ifndef HPL_USART_CONFIG_H #define HPL_USART_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> #include #ifndef CONF_USART_1_ENABLE #define CONF_USART_1_ENABLE 1 #endif // Basic Configuration // Frame parity // <0x0=>Even parity // <0x1=>Odd parity // <0x2=>Parity forced to 0 // <0x3=>Parity forced to 1 // <0x4=>No parity // Parity bit mode for USART frame // usart_parity #ifndef CONF_USART_1_PARITY #define CONF_USART_1_PARITY 0x4 #endif // Character Size // <0x0=>5 bits // <0x1=>6 bits // <0x2=>7 bits // <0x3=>8 bits // Data character size in USART frame // usart_character_size #ifndef CONF_USART_1_CHSIZE #define CONF_USART_1_CHSIZE 0x3 #endif // Stop Bit // <0=>1 stop bit // <1=>1.5 stop bits // <2=>2 stop bits // Number of stop bits in USART frame // usart_stop_bit #ifndef CONF_USART_1_SBMODE #define CONF_USART_1_SBMODE 0 #endif // Clock Output Select // <0=>The USART does not drive the SCK pin // <1=>The USART drives the SCK pin if USCLKS does not select the external clock SCK // Clock Output Select in USART sck, if in usrt master mode, please drive SCK. // usart_clock_output_select #ifndef CONF_USART_1_CLKO #define CONF_USART_1_CLKO 0 #endif // Baud rate <1-3000000> // USART baud rate setting // usart_baud_rate #ifndef CONF_USART_1_BAUD #define CONF_USART_1_BAUD 9600 #endif // // Advanced configuration // usart_advanced #ifndef CONF_USART_1_ADVANCED_CONFIG #define CONF_USART_1_ADVANCED_CONFIG 0 #endif // Channel Mode // <0=>Normal Mode // <1=>Automatic Echo // <2=>Local Loopback // <3=>Remote Loopback // Channel mode in USART frame // usart_channel_mode #ifndef CONF_USART_1_CHMODE #define CONF_USART_1_CHMODE 0 #endif // 9 bits character enable // Enable 9 bits character, this has high priority than 5/6/7/8 bits. // usart_9bits_enable #ifndef CONF_USART_1_MODE9 #define CONF_USART_1_MODE9 0 #endif // Variable Sync // <0=>User defined configuration // <1=>sync field is updated when a character is written into US_THR // Variable Synchronization of Command/Data Sync Start Frarm Delimiter // variable_sync #ifndef CONF_USART_1_VAR_SYNC #define CONF_USART_1_VAR_SYNC 0 #endif // Oversampling Mode // <0=>16 Oversampling // <1=>8 Oversampling // Oversampling Mode in UART mode // usart__oversampling_mode #ifndef CONF_USART_1_OVER #define CONF_USART_1_OVER 0 #endif // Inhibit Non Ack // <0=>The NACK is generated // <1=>The NACK is not generated // Inhibit Non Acknowledge // usart__inack #ifndef CONF_USART_1_INACK #define CONF_USART_1_INACK 1 #endif // Disable Successive NACK // <0=>NACK is sent on the ISO line as soon as a parity error occurs // <1=>Many parity errors generate a NACK on the ISO line // Disable Successive NACK // usart_dsnack #ifndef CONF_USART_1_DSNACK #define CONF_USART_1_DSNACK 0 #endif // Inverted Data // <0=>Data isn't inverted, nomal mode // <1=>Data is inverted // Inverted Data // usart_invdata #ifndef CONF_USART_1_INVDATA #define CONF_USART_1_INVDATA 0 #endif // Maximum Number of Automatic Iteration <0-7> // Defines the maximum number of iterations in mode ISO7816, protocol T = 0. // usart_max_iteration #ifndef CONF_USART_1_MAX_ITERATION #define CONF_USART_1_MAX_ITERATION 0 #endif // Receive Line Filter enable // whether the USART filters the receive line using a three-sample filter // usart_receive_filter_enable #ifndef CONF_USART_1_FILTER #define CONF_USART_1_FILTER 0 #endif // Manchester Encoder/Decoder Enable // whether the USART Manchester Encoder/Decoder // usart_manchester_filter_enable #ifndef CONF_USART_1_MAN #define CONF_USART_1_MAN 0 #endif // Manchester Synchronization Mode // <0=>The Manchester start bit is a 0 to 1 transition // <1=>The Manchester start bit is a 1 to 0 transition // Manchester Synchronization Mode // usart_manchester_synchronization_mode #ifndef CONF_USART_1_MODSYNC #define CONF_USART_1_MODSYNC 0 #endif // Start Frame Delimiter Selector // <0=>Start frame delimiter is COMMAND or DATA SYNC // <1=>Start frame delimiter is one bit // Start Frame Delimiter Selector // usart_start_frame_delimiter #ifndef CONF_USART_1_ONEBIT #define CONF_USART_1_ONEBIT 0 #endif // Fractional Part <0-7> // Fractional part of the baud rate if baud rate generator is in fractional mode // usart_arch_fractional #ifndef CONF_USART_1_FRACTIONAL #define CONF_USART_1_FRACTIONAL 0x0 #endif // Data Order // <0=>LSB is transmitted first // <1=>MSB is transmitted first // Data order of the data bits in the frame // usart_arch_msbf #ifndef CONF_USART_1_MSBF #define CONF_USART_1_MSBF 0 #endif // #define CONF_USART_1_MODE 0x0 // Calculate BAUD register value in UART mode #if CONF_USART1_CK_SRC < 3 #ifndef CONF_USART_1_BAUD_CD #define CONF_USART_1_BAUD_CD ((CONF_USART1_FREQUENCY) / CONF_USART_1_BAUD / 8 / (2 - CONF_USART_1_OVER)) #endif #ifndef CONF_USART_1_BAUD_FP #define CONF_USART_1_BAUD_FP \ ((CONF_USART1_FREQUENCY) / CONF_USART_1_BAUD / (2 - CONF_USART_1_OVER) - 8 * CONF_USART_1_BAUD_CD) #endif #elif CONF_USART1_CK_SRC == 3 // No division is active. The value written in US_BRGR has no effect. #ifndef CONF_USART_1_BAUD_CD #define CONF_USART_1_BAUD_CD 1 #endif #ifndef CONF_USART_1_BAUD_FP #define CONF_USART_1_BAUD_FP 1 #endif #endif // <<< end of configuration section >>> #endif // HPL_USART_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/hpl_xdmac_config.h ================================================ /* Auto-generated config file hpl_xdmac_config.h */ #ifndef HPL_XDMAC_CONFIG_H #define HPL_XDMAC_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> // XDMAC enable // Indicates whether xdmac is enabled or not // xdmac_enable #ifndef CONF_DMA_ENABLE #define CONF_DMA_ENABLE 0 #endif // Channel 0 settings // dmac_channel_0_settings #ifndef CONF_DMAC_CHANNEL_0_SETTINGS #define CONF_DMAC_CHANNEL_0_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_0 #ifndef CONF_DMAC_BURSTSIZE_0 #define CONF_DMAC_BURSTSIZE_0 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_0 #ifndef CONF_DMAC_CHUNKSIZE_0 #define CONF_DMAC_CHUNKSIZE_0 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_0 #ifndef CONF_DMAC_BEATSIZE_0 #define CONF_DMAC_BEATSIZE_0 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_0 #ifndef CONF_DMAC_SRC_INTERFACE_0 #define CONF_DMAC_SRC_INTERFACE_0 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_0 #ifndef CONF_DMAC_DES_INTERFACE_0 #define CONF_DMAC_DES_INTERFACE_0 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_0 #ifndef CONF_DMAC_SRCINC_0 #define CONF_DMAC_SRCINC_0 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_0 #ifndef CONF_DMAC_DSTINC_0 #define CONF_DMAC_DSTINC_0 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_0 #ifndef CONF_DMAC_TRANS_TYPE_0 #define CONF_DMAC_TRANS_TYPE_0 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_0 #ifndef CONF_DMAC_TRIGSRC_0 #define CONF_DMAC_TRIGSRC_0 0xff #endif // #if CONF_DMAC_TRANS_TYPE_0 == 0 #define CONF_DMAC_TYPE_0 0 #define CONF_DMAC_DSYNC_0 0 #elif CONF_DMAC_TRANS_TYPE_0 == 1 #define CONF_DMAC_TYPE_0 1 #define CONF_DMAC_DSYNC_0 0 #elif CONF_DMAC_TRANS_TYPE_0 == 2 #define CONF_DMAC_TYPE_0 1 #define CONF_DMAC_DSYNC_0 1 #endif #if CONF_DMAC_TRIGSRC_0 == 0xFF #define CONF_DMAC_SWREQ_0 1 #else #define CONF_DMAC_SWREQ_0 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_0_SETTINGS == 1 && CONF_DMAC_BEATSIZE_0 != 2 && ((!CONF_DMAC_SRCINC_0) || (!CONF_DMAC_DSTINC_0))) #if (!CONF_DMAC_SRCINC_0) #define CONF_DMAC_SRC_STRIDE_0 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_0) #define CONF_DMAC_DES_STRIDE_0 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_0 #define CONF_DMAC_SRC_STRIDE_0 0 #endif #ifndef CONF_DMAC_DES_STRIDE_0 #define CONF_DMAC_DES_STRIDE_0 0 #endif // Channel 1 settings // dmac_channel_1_settings #ifndef CONF_DMAC_CHANNEL_1_SETTINGS #define CONF_DMAC_CHANNEL_1_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_1 #ifndef CONF_DMAC_BURSTSIZE_1 #define CONF_DMAC_BURSTSIZE_1 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_1 #ifndef CONF_DMAC_CHUNKSIZE_1 #define CONF_DMAC_CHUNKSIZE_1 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_1 #ifndef CONF_DMAC_BEATSIZE_1 #define CONF_DMAC_BEATSIZE_1 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_1 #ifndef CONF_DMAC_SRC_INTERFACE_1 #define CONF_DMAC_SRC_INTERFACE_1 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_1 #ifndef CONF_DMAC_DES_INTERFACE_1 #define CONF_DMAC_DES_INTERFACE_1 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_1 #ifndef CONF_DMAC_SRCINC_1 #define CONF_DMAC_SRCINC_1 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_1 #ifndef CONF_DMAC_DSTINC_1 #define CONF_DMAC_DSTINC_1 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_1 #ifndef CONF_DMAC_TRANS_TYPE_1 #define CONF_DMAC_TRANS_TYPE_1 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_1 #ifndef CONF_DMAC_TRIGSRC_1 #define CONF_DMAC_TRIGSRC_1 0xff #endif // #if CONF_DMAC_TRANS_TYPE_1 == 0 #define CONF_DMAC_TYPE_1 0 #define CONF_DMAC_DSYNC_1 0 #elif CONF_DMAC_TRANS_TYPE_1 == 1 #define CONF_DMAC_TYPE_1 1 #define CONF_DMAC_DSYNC_1 0 #elif CONF_DMAC_TRANS_TYPE_1 == 2 #define CONF_DMAC_TYPE_1 1 #define CONF_DMAC_DSYNC_1 1 #endif #if CONF_DMAC_TRIGSRC_1 == 0xFF #define CONF_DMAC_SWREQ_1 1 #else #define CONF_DMAC_SWREQ_1 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_1_SETTINGS == 1 && CONF_DMAC_BEATSIZE_1 != 2 && ((!CONF_DMAC_SRCINC_1) || (!CONF_DMAC_DSTINC_1))) #if (!CONF_DMAC_SRCINC_1) #define CONF_DMAC_SRC_STRIDE_1 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_1) #define CONF_DMAC_DES_STRIDE_1 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_1 #define CONF_DMAC_SRC_STRIDE_1 0 #endif #ifndef CONF_DMAC_DES_STRIDE_1 #define CONF_DMAC_DES_STRIDE_1 0 #endif // Channel 2 settings // dmac_channel_2_settings #ifndef CONF_DMAC_CHANNEL_2_SETTINGS #define CONF_DMAC_CHANNEL_2_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_2 #ifndef CONF_DMAC_BURSTSIZE_2 #define CONF_DMAC_BURSTSIZE_2 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_2 #ifndef CONF_DMAC_CHUNKSIZE_2 #define CONF_DMAC_CHUNKSIZE_2 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_2 #ifndef CONF_DMAC_BEATSIZE_2 #define CONF_DMAC_BEATSIZE_2 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_2 #ifndef CONF_DMAC_SRC_INTERFACE_2 #define CONF_DMAC_SRC_INTERFACE_2 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_2 #ifndef CONF_DMAC_DES_INTERFACE_2 #define CONF_DMAC_DES_INTERFACE_2 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_2 #ifndef CONF_DMAC_SRCINC_2 #define CONF_DMAC_SRCINC_2 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_2 #ifndef CONF_DMAC_DSTINC_2 #define CONF_DMAC_DSTINC_2 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_2 #ifndef CONF_DMAC_TRANS_TYPE_2 #define CONF_DMAC_TRANS_TYPE_2 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_2 #ifndef CONF_DMAC_TRIGSRC_2 #define CONF_DMAC_TRIGSRC_2 0xff #endif // #if CONF_DMAC_TRANS_TYPE_2 == 0 #define CONF_DMAC_TYPE_2 0 #define CONF_DMAC_DSYNC_2 0 #elif CONF_DMAC_TRANS_TYPE_2 == 1 #define CONF_DMAC_TYPE_2 1 #define CONF_DMAC_DSYNC_2 0 #elif CONF_DMAC_TRANS_TYPE_2 == 2 #define CONF_DMAC_TYPE_2 1 #define CONF_DMAC_DSYNC_2 1 #endif #if CONF_DMAC_TRIGSRC_2 == 0xFF #define CONF_DMAC_SWREQ_2 1 #else #define CONF_DMAC_SWREQ_2 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_2_SETTINGS == 1 && CONF_DMAC_BEATSIZE_2 != 2 && ((!CONF_DMAC_SRCINC_2) || (!CONF_DMAC_DSTINC_2))) #if (!CONF_DMAC_SRCINC_2) #define CONF_DMAC_SRC_STRIDE_2 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_2) #define CONF_DMAC_DES_STRIDE_2 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_2 #define CONF_DMAC_SRC_STRIDE_2 0 #endif #ifndef CONF_DMAC_DES_STRIDE_2 #define CONF_DMAC_DES_STRIDE_2 0 #endif // Channel 3 settings // dmac_channel_3_settings #ifndef CONF_DMAC_CHANNEL_3_SETTINGS #define CONF_DMAC_CHANNEL_3_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_3 #ifndef CONF_DMAC_BURSTSIZE_3 #define CONF_DMAC_BURSTSIZE_3 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_3 #ifndef CONF_DMAC_CHUNKSIZE_3 #define CONF_DMAC_CHUNKSIZE_3 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_3 #ifndef CONF_DMAC_BEATSIZE_3 #define CONF_DMAC_BEATSIZE_3 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_3 #ifndef CONF_DMAC_SRC_INTERFACE_3 #define CONF_DMAC_SRC_INTERFACE_3 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_3 #ifndef CONF_DMAC_DES_INTERFACE_3 #define CONF_DMAC_DES_INTERFACE_3 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_3 #ifndef CONF_DMAC_SRCINC_3 #define CONF_DMAC_SRCINC_3 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_3 #ifndef CONF_DMAC_DSTINC_3 #define CONF_DMAC_DSTINC_3 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_3 #ifndef CONF_DMAC_TRANS_TYPE_3 #define CONF_DMAC_TRANS_TYPE_3 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_3 #ifndef CONF_DMAC_TRIGSRC_3 #define CONF_DMAC_TRIGSRC_3 0xff #endif // #if CONF_DMAC_TRANS_TYPE_3 == 0 #define CONF_DMAC_TYPE_3 0 #define CONF_DMAC_DSYNC_3 0 #elif CONF_DMAC_TRANS_TYPE_3 == 1 #define CONF_DMAC_TYPE_3 1 #define CONF_DMAC_DSYNC_3 0 #elif CONF_DMAC_TRANS_TYPE_3 == 2 #define CONF_DMAC_TYPE_3 1 #define CONF_DMAC_DSYNC_3 1 #endif #if CONF_DMAC_TRIGSRC_3 == 0xFF #define CONF_DMAC_SWREQ_3 1 #else #define CONF_DMAC_SWREQ_3 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_3_SETTINGS == 1 && CONF_DMAC_BEATSIZE_3 != 2 && ((!CONF_DMAC_SRCINC_3) || (!CONF_DMAC_DSTINC_3))) #if (!CONF_DMAC_SRCINC_3) #define CONF_DMAC_SRC_STRIDE_3 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_3) #define CONF_DMAC_DES_STRIDE_3 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_3 #define CONF_DMAC_SRC_STRIDE_3 0 #endif #ifndef CONF_DMAC_DES_STRIDE_3 #define CONF_DMAC_DES_STRIDE_3 0 #endif // Channel 4 settings // dmac_channel_4_settings #ifndef CONF_DMAC_CHANNEL_4_SETTINGS #define CONF_DMAC_CHANNEL_4_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_4 #ifndef CONF_DMAC_BURSTSIZE_4 #define CONF_DMAC_BURSTSIZE_4 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_4 #ifndef CONF_DMAC_CHUNKSIZE_4 #define CONF_DMAC_CHUNKSIZE_4 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_4 #ifndef CONF_DMAC_BEATSIZE_4 #define CONF_DMAC_BEATSIZE_4 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_4 #ifndef CONF_DMAC_SRC_INTERFACE_4 #define CONF_DMAC_SRC_INTERFACE_4 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_4 #ifndef CONF_DMAC_DES_INTERFACE_4 #define CONF_DMAC_DES_INTERFACE_4 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_4 #ifndef CONF_DMAC_SRCINC_4 #define CONF_DMAC_SRCINC_4 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_4 #ifndef CONF_DMAC_DSTINC_4 #define CONF_DMAC_DSTINC_4 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_4 #ifndef CONF_DMAC_TRANS_TYPE_4 #define CONF_DMAC_TRANS_TYPE_4 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_4 #ifndef CONF_DMAC_TRIGSRC_4 #define CONF_DMAC_TRIGSRC_4 0xff #endif // #if CONF_DMAC_TRANS_TYPE_4 == 0 #define CONF_DMAC_TYPE_4 0 #define CONF_DMAC_DSYNC_4 0 #elif CONF_DMAC_TRANS_TYPE_4 == 1 #define CONF_DMAC_TYPE_4 1 #define CONF_DMAC_DSYNC_4 0 #elif CONF_DMAC_TRANS_TYPE_4 == 2 #define CONF_DMAC_TYPE_4 1 #define CONF_DMAC_DSYNC_4 1 #endif #if CONF_DMAC_TRIGSRC_4 == 0xFF #define CONF_DMAC_SWREQ_4 1 #else #define CONF_DMAC_SWREQ_4 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_4_SETTINGS == 1 && CONF_DMAC_BEATSIZE_4 != 2 && ((!CONF_DMAC_SRCINC_4) || (!CONF_DMAC_DSTINC_4))) #if (!CONF_DMAC_SRCINC_4) #define CONF_DMAC_SRC_STRIDE_4 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_4) #define CONF_DMAC_DES_STRIDE_4 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_4 #define CONF_DMAC_SRC_STRIDE_4 0 #endif #ifndef CONF_DMAC_DES_STRIDE_4 #define CONF_DMAC_DES_STRIDE_4 0 #endif // Channel 5 settings // dmac_channel_5_settings #ifndef CONF_DMAC_CHANNEL_5_SETTINGS #define CONF_DMAC_CHANNEL_5_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_5 #ifndef CONF_DMAC_BURSTSIZE_5 #define CONF_DMAC_BURSTSIZE_5 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_5 #ifndef CONF_DMAC_CHUNKSIZE_5 #define CONF_DMAC_CHUNKSIZE_5 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_5 #ifndef CONF_DMAC_BEATSIZE_5 #define CONF_DMAC_BEATSIZE_5 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_5 #ifndef CONF_DMAC_SRC_INTERFACE_5 #define CONF_DMAC_SRC_INTERFACE_5 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_5 #ifndef CONF_DMAC_DES_INTERFACE_5 #define CONF_DMAC_DES_INTERFACE_5 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_5 #ifndef CONF_DMAC_SRCINC_5 #define CONF_DMAC_SRCINC_5 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_5 #ifndef CONF_DMAC_DSTINC_5 #define CONF_DMAC_DSTINC_5 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_5 #ifndef CONF_DMAC_TRANS_TYPE_5 #define CONF_DMAC_TRANS_TYPE_5 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_5 #ifndef CONF_DMAC_TRIGSRC_5 #define CONF_DMAC_TRIGSRC_5 0xff #endif // #if CONF_DMAC_TRANS_TYPE_5 == 0 #define CONF_DMAC_TYPE_5 0 #define CONF_DMAC_DSYNC_5 0 #elif CONF_DMAC_TRANS_TYPE_5 == 1 #define CONF_DMAC_TYPE_5 1 #define CONF_DMAC_DSYNC_5 0 #elif CONF_DMAC_TRANS_TYPE_5 == 2 #define CONF_DMAC_TYPE_5 1 #define CONF_DMAC_DSYNC_5 1 #endif #if CONF_DMAC_TRIGSRC_5 == 0xFF #define CONF_DMAC_SWREQ_5 1 #else #define CONF_DMAC_SWREQ_5 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_5_SETTINGS == 1 && CONF_DMAC_BEATSIZE_5 != 2 && ((!CONF_DMAC_SRCINC_5) || (!CONF_DMAC_DSTINC_5))) #if (!CONF_DMAC_SRCINC_5) #define CONF_DMAC_SRC_STRIDE_5 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_5) #define CONF_DMAC_DES_STRIDE_5 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_5 #define CONF_DMAC_SRC_STRIDE_5 0 #endif #ifndef CONF_DMAC_DES_STRIDE_5 #define CONF_DMAC_DES_STRIDE_5 0 #endif // Channel 6 settings // dmac_channel_6_settings #ifndef CONF_DMAC_CHANNEL_6_SETTINGS #define CONF_DMAC_CHANNEL_6_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_6 #ifndef CONF_DMAC_BURSTSIZE_6 #define CONF_DMAC_BURSTSIZE_6 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_6 #ifndef CONF_DMAC_CHUNKSIZE_6 #define CONF_DMAC_CHUNKSIZE_6 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_6 #ifndef CONF_DMAC_BEATSIZE_6 #define CONF_DMAC_BEATSIZE_6 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_6 #ifndef CONF_DMAC_SRC_INTERFACE_6 #define CONF_DMAC_SRC_INTERFACE_6 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_6 #ifndef CONF_DMAC_DES_INTERFACE_6 #define CONF_DMAC_DES_INTERFACE_6 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_6 #ifndef CONF_DMAC_SRCINC_6 #define CONF_DMAC_SRCINC_6 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_6 #ifndef CONF_DMAC_DSTINC_6 #define CONF_DMAC_DSTINC_6 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_6 #ifndef CONF_DMAC_TRANS_TYPE_6 #define CONF_DMAC_TRANS_TYPE_6 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_6 #ifndef CONF_DMAC_TRIGSRC_6 #define CONF_DMAC_TRIGSRC_6 0xff #endif // #if CONF_DMAC_TRANS_TYPE_6 == 0 #define CONF_DMAC_TYPE_6 0 #define CONF_DMAC_DSYNC_6 0 #elif CONF_DMAC_TRANS_TYPE_6 == 1 #define CONF_DMAC_TYPE_6 1 #define CONF_DMAC_DSYNC_6 0 #elif CONF_DMAC_TRANS_TYPE_6 == 2 #define CONF_DMAC_TYPE_6 1 #define CONF_DMAC_DSYNC_6 1 #endif #if CONF_DMAC_TRIGSRC_6 == 0xFF #define CONF_DMAC_SWREQ_6 1 #else #define CONF_DMAC_SWREQ_6 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_6_SETTINGS == 1 && CONF_DMAC_BEATSIZE_6 != 2 && ((!CONF_DMAC_SRCINC_6) || (!CONF_DMAC_DSTINC_6))) #if (!CONF_DMAC_SRCINC_6) #define CONF_DMAC_SRC_STRIDE_6 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_6) #define CONF_DMAC_DES_STRIDE_6 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_6 #define CONF_DMAC_SRC_STRIDE_6 0 #endif #ifndef CONF_DMAC_DES_STRIDE_6 #define CONF_DMAC_DES_STRIDE_6 0 #endif // Channel 7 settings // dmac_channel_7_settings #ifndef CONF_DMAC_CHANNEL_7_SETTINGS #define CONF_DMAC_CHANNEL_7_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_7 #ifndef CONF_DMAC_BURSTSIZE_7 #define CONF_DMAC_BURSTSIZE_7 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_7 #ifndef CONF_DMAC_CHUNKSIZE_7 #define CONF_DMAC_CHUNKSIZE_7 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_7 #ifndef CONF_DMAC_BEATSIZE_7 #define CONF_DMAC_BEATSIZE_7 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_7 #ifndef CONF_DMAC_SRC_INTERFACE_7 #define CONF_DMAC_SRC_INTERFACE_7 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_7 #ifndef CONF_DMAC_DES_INTERFACE_7 #define CONF_DMAC_DES_INTERFACE_7 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_7 #ifndef CONF_DMAC_SRCINC_7 #define CONF_DMAC_SRCINC_7 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_7 #ifndef CONF_DMAC_DSTINC_7 #define CONF_DMAC_DSTINC_7 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_7 #ifndef CONF_DMAC_TRANS_TYPE_7 #define CONF_DMAC_TRANS_TYPE_7 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_7 #ifndef CONF_DMAC_TRIGSRC_7 #define CONF_DMAC_TRIGSRC_7 0xff #endif // #if CONF_DMAC_TRANS_TYPE_7 == 0 #define CONF_DMAC_TYPE_7 0 #define CONF_DMAC_DSYNC_7 0 #elif CONF_DMAC_TRANS_TYPE_7 == 1 #define CONF_DMAC_TYPE_7 1 #define CONF_DMAC_DSYNC_7 0 #elif CONF_DMAC_TRANS_TYPE_7 == 2 #define CONF_DMAC_TYPE_7 1 #define CONF_DMAC_DSYNC_7 1 #endif #if CONF_DMAC_TRIGSRC_7 == 0xFF #define CONF_DMAC_SWREQ_7 1 #else #define CONF_DMAC_SWREQ_7 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_7_SETTINGS == 1 && CONF_DMAC_BEATSIZE_7 != 2 && ((!CONF_DMAC_SRCINC_7) || (!CONF_DMAC_DSTINC_7))) #if (!CONF_DMAC_SRCINC_7) #define CONF_DMAC_SRC_STRIDE_7 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_7) #define CONF_DMAC_DES_STRIDE_7 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_7 #define CONF_DMAC_SRC_STRIDE_7 0 #endif #ifndef CONF_DMAC_DES_STRIDE_7 #define CONF_DMAC_DES_STRIDE_7 0 #endif // Channel 8 settings // dmac_channel_8_settings #ifndef CONF_DMAC_CHANNEL_8_SETTINGS #define CONF_DMAC_CHANNEL_8_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_8 #ifndef CONF_DMAC_BURSTSIZE_8 #define CONF_DMAC_BURSTSIZE_8 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_8 #ifndef CONF_DMAC_CHUNKSIZE_8 #define CONF_DMAC_CHUNKSIZE_8 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_8 #ifndef CONF_DMAC_BEATSIZE_8 #define CONF_DMAC_BEATSIZE_8 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_8 #ifndef CONF_DMAC_SRC_INTERFACE_8 #define CONF_DMAC_SRC_INTERFACE_8 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_8 #ifndef CONF_DMAC_DES_INTERFACE_8 #define CONF_DMAC_DES_INTERFACE_8 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_8 #ifndef CONF_DMAC_SRCINC_8 #define CONF_DMAC_SRCINC_8 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_8 #ifndef CONF_DMAC_DSTINC_8 #define CONF_DMAC_DSTINC_8 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_8 #ifndef CONF_DMAC_TRANS_TYPE_8 #define CONF_DMAC_TRANS_TYPE_8 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_8 #ifndef CONF_DMAC_TRIGSRC_8 #define CONF_DMAC_TRIGSRC_8 0xff #endif // #if CONF_DMAC_TRANS_TYPE_8 == 0 #define CONF_DMAC_TYPE_8 0 #define CONF_DMAC_DSYNC_8 0 #elif CONF_DMAC_TRANS_TYPE_8 == 1 #define CONF_DMAC_TYPE_8 1 #define CONF_DMAC_DSYNC_8 0 #elif CONF_DMAC_TRANS_TYPE_8 == 2 #define CONF_DMAC_TYPE_8 1 #define CONF_DMAC_DSYNC_8 1 #endif #if CONF_DMAC_TRIGSRC_8 == 0xFF #define CONF_DMAC_SWREQ_8 1 #else #define CONF_DMAC_SWREQ_8 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_8_SETTINGS == 1 && CONF_DMAC_BEATSIZE_8 != 2 && ((!CONF_DMAC_SRCINC_8) || (!CONF_DMAC_DSTINC_8))) #if (!CONF_DMAC_SRCINC_8) #define CONF_DMAC_SRC_STRIDE_8 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_8) #define CONF_DMAC_DES_STRIDE_8 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_8 #define CONF_DMAC_SRC_STRIDE_8 0 #endif #ifndef CONF_DMAC_DES_STRIDE_8 #define CONF_DMAC_DES_STRIDE_8 0 #endif // Channel 9 settings // dmac_channel_9_settings #ifndef CONF_DMAC_CHANNEL_9_SETTINGS #define CONF_DMAC_CHANNEL_9_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_9 #ifndef CONF_DMAC_BURSTSIZE_9 #define CONF_DMAC_BURSTSIZE_9 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_9 #ifndef CONF_DMAC_CHUNKSIZE_9 #define CONF_DMAC_CHUNKSIZE_9 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_9 #ifndef CONF_DMAC_BEATSIZE_9 #define CONF_DMAC_BEATSIZE_9 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_9 #ifndef CONF_DMAC_SRC_INTERFACE_9 #define CONF_DMAC_SRC_INTERFACE_9 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_9 #ifndef CONF_DMAC_DES_INTERFACE_9 #define CONF_DMAC_DES_INTERFACE_9 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_9 #ifndef CONF_DMAC_SRCINC_9 #define CONF_DMAC_SRCINC_9 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_9 #ifndef CONF_DMAC_DSTINC_9 #define CONF_DMAC_DSTINC_9 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_9 #ifndef CONF_DMAC_TRANS_TYPE_9 #define CONF_DMAC_TRANS_TYPE_9 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_9 #ifndef CONF_DMAC_TRIGSRC_9 #define CONF_DMAC_TRIGSRC_9 0xff #endif // #if CONF_DMAC_TRANS_TYPE_9 == 0 #define CONF_DMAC_TYPE_9 0 #define CONF_DMAC_DSYNC_9 0 #elif CONF_DMAC_TRANS_TYPE_9 == 1 #define CONF_DMAC_TYPE_9 1 #define CONF_DMAC_DSYNC_9 0 #elif CONF_DMAC_TRANS_TYPE_9 == 2 #define CONF_DMAC_TYPE_9 1 #define CONF_DMAC_DSYNC_9 1 #endif #if CONF_DMAC_TRIGSRC_9 == 0xFF #define CONF_DMAC_SWREQ_9 1 #else #define CONF_DMAC_SWREQ_9 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_9_SETTINGS == 1 && CONF_DMAC_BEATSIZE_9 != 2 && ((!CONF_DMAC_SRCINC_9) || (!CONF_DMAC_DSTINC_9))) #if (!CONF_DMAC_SRCINC_9) #define CONF_DMAC_SRC_STRIDE_9 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_9) #define CONF_DMAC_DES_STRIDE_9 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_9 #define CONF_DMAC_SRC_STRIDE_9 0 #endif #ifndef CONF_DMAC_DES_STRIDE_9 #define CONF_DMAC_DES_STRIDE_9 0 #endif // Channel 10 settings // dmac_channel_10_settings #ifndef CONF_DMAC_CHANNEL_10_SETTINGS #define CONF_DMAC_CHANNEL_10_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_10 #ifndef CONF_DMAC_BURSTSIZE_10 #define CONF_DMAC_BURSTSIZE_10 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_10 #ifndef CONF_DMAC_CHUNKSIZE_10 #define CONF_DMAC_CHUNKSIZE_10 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_10 #ifndef CONF_DMAC_BEATSIZE_10 #define CONF_DMAC_BEATSIZE_10 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_10 #ifndef CONF_DMAC_SRC_INTERFACE_10 #define CONF_DMAC_SRC_INTERFACE_10 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_10 #ifndef CONF_DMAC_DES_INTERFACE_10 #define CONF_DMAC_DES_INTERFACE_10 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_10 #ifndef CONF_DMAC_SRCINC_10 #define CONF_DMAC_SRCINC_10 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_10 #ifndef CONF_DMAC_DSTINC_10 #define CONF_DMAC_DSTINC_10 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_10 #ifndef CONF_DMAC_TRANS_TYPE_10 #define CONF_DMAC_TRANS_TYPE_10 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_10 #ifndef CONF_DMAC_TRIGSRC_10 #define CONF_DMAC_TRIGSRC_10 0xff #endif // #if CONF_DMAC_TRANS_TYPE_10 == 0 #define CONF_DMAC_TYPE_10 0 #define CONF_DMAC_DSYNC_10 0 #elif CONF_DMAC_TRANS_TYPE_10 == 1 #define CONF_DMAC_TYPE_10 1 #define CONF_DMAC_DSYNC_10 0 #elif CONF_DMAC_TRANS_TYPE_10 == 2 #define CONF_DMAC_TYPE_10 1 #define CONF_DMAC_DSYNC_10 1 #endif #if CONF_DMAC_TRIGSRC_10 == 0xFF #define CONF_DMAC_SWREQ_10 1 #else #define CONF_DMAC_SWREQ_10 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_10_SETTINGS == 1 && CONF_DMAC_BEATSIZE_10 != 2 \ && ((!CONF_DMAC_SRCINC_10) || (!CONF_DMAC_DSTINC_10))) #if (!CONF_DMAC_SRCINC_10) #define CONF_DMAC_SRC_STRIDE_10 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_10) #define CONF_DMAC_DES_STRIDE_10 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_10 #define CONF_DMAC_SRC_STRIDE_10 0 #endif #ifndef CONF_DMAC_DES_STRIDE_10 #define CONF_DMAC_DES_STRIDE_10 0 #endif // Channel 11 settings // dmac_channel_11_settings #ifndef CONF_DMAC_CHANNEL_11_SETTINGS #define CONF_DMAC_CHANNEL_11_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_11 #ifndef CONF_DMAC_BURSTSIZE_11 #define CONF_DMAC_BURSTSIZE_11 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_11 #ifndef CONF_DMAC_CHUNKSIZE_11 #define CONF_DMAC_CHUNKSIZE_11 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_11 #ifndef CONF_DMAC_BEATSIZE_11 #define CONF_DMAC_BEATSIZE_11 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_11 #ifndef CONF_DMAC_SRC_INTERFACE_11 #define CONF_DMAC_SRC_INTERFACE_11 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_11 #ifndef CONF_DMAC_DES_INTERFACE_11 #define CONF_DMAC_DES_INTERFACE_11 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_11 #ifndef CONF_DMAC_SRCINC_11 #define CONF_DMAC_SRCINC_11 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_11 #ifndef CONF_DMAC_DSTINC_11 #define CONF_DMAC_DSTINC_11 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_11 #ifndef CONF_DMAC_TRANS_TYPE_11 #define CONF_DMAC_TRANS_TYPE_11 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_11 #ifndef CONF_DMAC_TRIGSRC_11 #define CONF_DMAC_TRIGSRC_11 0xff #endif // #if CONF_DMAC_TRANS_TYPE_11 == 0 #define CONF_DMAC_TYPE_11 0 #define CONF_DMAC_DSYNC_11 0 #elif CONF_DMAC_TRANS_TYPE_11 == 1 #define CONF_DMAC_TYPE_11 1 #define CONF_DMAC_DSYNC_11 0 #elif CONF_DMAC_TRANS_TYPE_11 == 2 #define CONF_DMAC_TYPE_11 1 #define CONF_DMAC_DSYNC_11 1 #endif #if CONF_DMAC_TRIGSRC_11 == 0xFF #define CONF_DMAC_SWREQ_11 1 #else #define CONF_DMAC_SWREQ_11 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_11_SETTINGS == 1 && CONF_DMAC_BEATSIZE_11 != 2 \ && ((!CONF_DMAC_SRCINC_11) || (!CONF_DMAC_DSTINC_11))) #if (!CONF_DMAC_SRCINC_11) #define CONF_DMAC_SRC_STRIDE_11 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_11) #define CONF_DMAC_DES_STRIDE_11 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_11 #define CONF_DMAC_SRC_STRIDE_11 0 #endif #ifndef CONF_DMAC_DES_STRIDE_11 #define CONF_DMAC_DES_STRIDE_11 0 #endif // Channel 12 settings // dmac_channel_12_settings #ifndef CONF_DMAC_CHANNEL_12_SETTINGS #define CONF_DMAC_CHANNEL_12_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_12 #ifndef CONF_DMAC_BURSTSIZE_12 #define CONF_DMAC_BURSTSIZE_12 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_12 #ifndef CONF_DMAC_CHUNKSIZE_12 #define CONF_DMAC_CHUNKSIZE_12 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_12 #ifndef CONF_DMAC_BEATSIZE_12 #define CONF_DMAC_BEATSIZE_12 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_12 #ifndef CONF_DMAC_SRC_INTERFACE_12 #define CONF_DMAC_SRC_INTERFACE_12 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_12 #ifndef CONF_DMAC_DES_INTERFACE_12 #define CONF_DMAC_DES_INTERFACE_12 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_12 #ifndef CONF_DMAC_SRCINC_12 #define CONF_DMAC_SRCINC_12 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_12 #ifndef CONF_DMAC_DSTINC_12 #define CONF_DMAC_DSTINC_12 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_12 #ifndef CONF_DMAC_TRANS_TYPE_12 #define CONF_DMAC_TRANS_TYPE_12 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_12 #ifndef CONF_DMAC_TRIGSRC_12 #define CONF_DMAC_TRIGSRC_12 0xff #endif // #if CONF_DMAC_TRANS_TYPE_12 == 0 #define CONF_DMAC_TYPE_12 0 #define CONF_DMAC_DSYNC_12 0 #elif CONF_DMAC_TRANS_TYPE_12 == 1 #define CONF_DMAC_TYPE_12 1 #define CONF_DMAC_DSYNC_12 0 #elif CONF_DMAC_TRANS_TYPE_12 == 2 #define CONF_DMAC_TYPE_12 1 #define CONF_DMAC_DSYNC_12 1 #endif #if CONF_DMAC_TRIGSRC_12 == 0xFF #define CONF_DMAC_SWREQ_12 1 #else #define CONF_DMAC_SWREQ_12 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_12_SETTINGS == 1 && CONF_DMAC_BEATSIZE_12 != 2 \ && ((!CONF_DMAC_SRCINC_12) || (!CONF_DMAC_DSTINC_12))) #if (!CONF_DMAC_SRCINC_12) #define CONF_DMAC_SRC_STRIDE_12 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_12) #define CONF_DMAC_DES_STRIDE_12 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_12 #define CONF_DMAC_SRC_STRIDE_12 0 #endif #ifndef CONF_DMAC_DES_STRIDE_12 #define CONF_DMAC_DES_STRIDE_12 0 #endif // Channel 13 settings // dmac_channel_13_settings #ifndef CONF_DMAC_CHANNEL_13_SETTINGS #define CONF_DMAC_CHANNEL_13_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_13 #ifndef CONF_DMAC_BURSTSIZE_13 #define CONF_DMAC_BURSTSIZE_13 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_13 #ifndef CONF_DMAC_CHUNKSIZE_13 #define CONF_DMAC_CHUNKSIZE_13 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_13 #ifndef CONF_DMAC_BEATSIZE_13 #define CONF_DMAC_BEATSIZE_13 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_13 #ifndef CONF_DMAC_SRC_INTERFACE_13 #define CONF_DMAC_SRC_INTERFACE_13 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_13 #ifndef CONF_DMAC_DES_INTERFACE_13 #define CONF_DMAC_DES_INTERFACE_13 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_13 #ifndef CONF_DMAC_SRCINC_13 #define CONF_DMAC_SRCINC_13 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_13 #ifndef CONF_DMAC_DSTINC_13 #define CONF_DMAC_DSTINC_13 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_13 #ifndef CONF_DMAC_TRANS_TYPE_13 #define CONF_DMAC_TRANS_TYPE_13 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_13 #ifndef CONF_DMAC_TRIGSRC_13 #define CONF_DMAC_TRIGSRC_13 0xff #endif // #if CONF_DMAC_TRANS_TYPE_13 == 0 #define CONF_DMAC_TYPE_13 0 #define CONF_DMAC_DSYNC_13 0 #elif CONF_DMAC_TRANS_TYPE_13 == 1 #define CONF_DMAC_TYPE_13 1 #define CONF_DMAC_DSYNC_13 0 #elif CONF_DMAC_TRANS_TYPE_13 == 2 #define CONF_DMAC_TYPE_13 1 #define CONF_DMAC_DSYNC_13 1 #endif #if CONF_DMAC_TRIGSRC_13 == 0xFF #define CONF_DMAC_SWREQ_13 1 #else #define CONF_DMAC_SWREQ_13 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_13_SETTINGS == 1 && CONF_DMAC_BEATSIZE_13 != 2 \ && ((!CONF_DMAC_SRCINC_13) || (!CONF_DMAC_DSTINC_13))) #if (!CONF_DMAC_SRCINC_13) #define CONF_DMAC_SRC_STRIDE_13 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_13) #define CONF_DMAC_DES_STRIDE_13 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_13 #define CONF_DMAC_SRC_STRIDE_13 0 #endif #ifndef CONF_DMAC_DES_STRIDE_13 #define CONF_DMAC_DES_STRIDE_13 0 #endif // Channel 14 settings // dmac_channel_14_settings #ifndef CONF_DMAC_CHANNEL_14_SETTINGS #define CONF_DMAC_CHANNEL_14_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_14 #ifndef CONF_DMAC_BURSTSIZE_14 #define CONF_DMAC_BURSTSIZE_14 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_14 #ifndef CONF_DMAC_CHUNKSIZE_14 #define CONF_DMAC_CHUNKSIZE_14 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_14 #ifndef CONF_DMAC_BEATSIZE_14 #define CONF_DMAC_BEATSIZE_14 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_14 #ifndef CONF_DMAC_SRC_INTERFACE_14 #define CONF_DMAC_SRC_INTERFACE_14 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_14 #ifndef CONF_DMAC_DES_INTERFACE_14 #define CONF_DMAC_DES_INTERFACE_14 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_14 #ifndef CONF_DMAC_SRCINC_14 #define CONF_DMAC_SRCINC_14 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_14 #ifndef CONF_DMAC_DSTINC_14 #define CONF_DMAC_DSTINC_14 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_14 #ifndef CONF_DMAC_TRANS_TYPE_14 #define CONF_DMAC_TRANS_TYPE_14 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_14 #ifndef CONF_DMAC_TRIGSRC_14 #define CONF_DMAC_TRIGSRC_14 0xff #endif // #if CONF_DMAC_TRANS_TYPE_14 == 0 #define CONF_DMAC_TYPE_14 0 #define CONF_DMAC_DSYNC_14 0 #elif CONF_DMAC_TRANS_TYPE_14 == 1 #define CONF_DMAC_TYPE_14 1 #define CONF_DMAC_DSYNC_14 0 #elif CONF_DMAC_TRANS_TYPE_14 == 2 #define CONF_DMAC_TYPE_14 1 #define CONF_DMAC_DSYNC_14 1 #endif #if CONF_DMAC_TRIGSRC_14 == 0xFF #define CONF_DMAC_SWREQ_14 1 #else #define CONF_DMAC_SWREQ_14 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_14_SETTINGS == 1 && CONF_DMAC_BEATSIZE_14 != 2 \ && ((!CONF_DMAC_SRCINC_14) || (!CONF_DMAC_DSTINC_14))) #if (!CONF_DMAC_SRCINC_14) #define CONF_DMAC_SRC_STRIDE_14 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_14) #define CONF_DMAC_DES_STRIDE_14 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_14 #define CONF_DMAC_SRC_STRIDE_14 0 #endif #ifndef CONF_DMAC_DES_STRIDE_14 #define CONF_DMAC_DES_STRIDE_14 0 #endif // Channel 15 settings // dmac_channel_15_settings #ifndef CONF_DMAC_CHANNEL_15_SETTINGS #define CONF_DMAC_CHANNEL_15_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_15 #ifndef CONF_DMAC_BURSTSIZE_15 #define CONF_DMAC_BURSTSIZE_15 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_15 #ifndef CONF_DMAC_CHUNKSIZE_15 #define CONF_DMAC_CHUNKSIZE_15 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_15 #ifndef CONF_DMAC_BEATSIZE_15 #define CONF_DMAC_BEATSIZE_15 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_15 #ifndef CONF_DMAC_SRC_INTERFACE_15 #define CONF_DMAC_SRC_INTERFACE_15 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_15 #ifndef CONF_DMAC_DES_INTERFACE_15 #define CONF_DMAC_DES_INTERFACE_15 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_15 #ifndef CONF_DMAC_SRCINC_15 #define CONF_DMAC_SRCINC_15 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_15 #ifndef CONF_DMAC_DSTINC_15 #define CONF_DMAC_DSTINC_15 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_15 #ifndef CONF_DMAC_TRANS_TYPE_15 #define CONF_DMAC_TRANS_TYPE_15 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_15 #ifndef CONF_DMAC_TRIGSRC_15 #define CONF_DMAC_TRIGSRC_15 0xff #endif // #if CONF_DMAC_TRANS_TYPE_15 == 0 #define CONF_DMAC_TYPE_15 0 #define CONF_DMAC_DSYNC_15 0 #elif CONF_DMAC_TRANS_TYPE_15 == 1 #define CONF_DMAC_TYPE_15 1 #define CONF_DMAC_DSYNC_15 0 #elif CONF_DMAC_TRANS_TYPE_15 == 2 #define CONF_DMAC_TYPE_15 1 #define CONF_DMAC_DSYNC_15 1 #endif #if CONF_DMAC_TRIGSRC_15 == 0xFF #define CONF_DMAC_SWREQ_15 1 #else #define CONF_DMAC_SWREQ_15 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_15_SETTINGS == 1 && CONF_DMAC_BEATSIZE_15 != 2 \ && ((!CONF_DMAC_SRCINC_15) || (!CONF_DMAC_DSTINC_15))) #if (!CONF_DMAC_SRCINC_15) #define CONF_DMAC_SRC_STRIDE_15 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_15) #define CONF_DMAC_DES_STRIDE_15 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_15 #define CONF_DMAC_SRC_STRIDE_15 0 #endif #ifndef CONF_DMAC_DES_STRIDE_15 #define CONF_DMAC_DES_STRIDE_15 0 #endif // Channel 16 settings // dmac_channel_16_settings #ifndef CONF_DMAC_CHANNEL_16_SETTINGS #define CONF_DMAC_CHANNEL_16_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_16 #ifndef CONF_DMAC_BURSTSIZE_16 #define CONF_DMAC_BURSTSIZE_16 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_16 #ifndef CONF_DMAC_CHUNKSIZE_16 #define CONF_DMAC_CHUNKSIZE_16 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_16 #ifndef CONF_DMAC_BEATSIZE_16 #define CONF_DMAC_BEATSIZE_16 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_16 #ifndef CONF_DMAC_SRC_INTERFACE_16 #define CONF_DMAC_SRC_INTERFACE_16 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_16 #ifndef CONF_DMAC_DES_INTERFACE_16 #define CONF_DMAC_DES_INTERFACE_16 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_16 #ifndef CONF_DMAC_SRCINC_16 #define CONF_DMAC_SRCINC_16 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_16 #ifndef CONF_DMAC_DSTINC_16 #define CONF_DMAC_DSTINC_16 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_16 #ifndef CONF_DMAC_TRANS_TYPE_16 #define CONF_DMAC_TRANS_TYPE_16 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_16 #ifndef CONF_DMAC_TRIGSRC_16 #define CONF_DMAC_TRIGSRC_16 0xff #endif // #if CONF_DMAC_TRANS_TYPE_16 == 0 #define CONF_DMAC_TYPE_16 0 #define CONF_DMAC_DSYNC_16 0 #elif CONF_DMAC_TRANS_TYPE_16 == 1 #define CONF_DMAC_TYPE_16 1 #define CONF_DMAC_DSYNC_16 0 #elif CONF_DMAC_TRANS_TYPE_16 == 2 #define CONF_DMAC_TYPE_16 1 #define CONF_DMAC_DSYNC_16 1 #endif #if CONF_DMAC_TRIGSRC_16 == 0xFF #define CONF_DMAC_SWREQ_16 1 #else #define CONF_DMAC_SWREQ_16 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_16_SETTINGS == 1 && CONF_DMAC_BEATSIZE_16 != 2 \ && ((!CONF_DMAC_SRCINC_16) || (!CONF_DMAC_DSTINC_16))) #if (!CONF_DMAC_SRCINC_16) #define CONF_DMAC_SRC_STRIDE_16 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_16) #define CONF_DMAC_DES_STRIDE_16 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_16 #define CONF_DMAC_SRC_STRIDE_16 0 #endif #ifndef CONF_DMAC_DES_STRIDE_16 #define CONF_DMAC_DES_STRIDE_16 0 #endif // Channel 17 settings // dmac_channel_17_settings #ifndef CONF_DMAC_CHANNEL_17_SETTINGS #define CONF_DMAC_CHANNEL_17_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_17 #ifndef CONF_DMAC_BURSTSIZE_17 #define CONF_DMAC_BURSTSIZE_17 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_17 #ifndef CONF_DMAC_CHUNKSIZE_17 #define CONF_DMAC_CHUNKSIZE_17 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_17 #ifndef CONF_DMAC_BEATSIZE_17 #define CONF_DMAC_BEATSIZE_17 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_17 #ifndef CONF_DMAC_SRC_INTERFACE_17 #define CONF_DMAC_SRC_INTERFACE_17 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_17 #ifndef CONF_DMAC_DES_INTERFACE_17 #define CONF_DMAC_DES_INTERFACE_17 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_17 #ifndef CONF_DMAC_SRCINC_17 #define CONF_DMAC_SRCINC_17 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_17 #ifndef CONF_DMAC_DSTINC_17 #define CONF_DMAC_DSTINC_17 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_17 #ifndef CONF_DMAC_TRANS_TYPE_17 #define CONF_DMAC_TRANS_TYPE_17 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_17 #ifndef CONF_DMAC_TRIGSRC_17 #define CONF_DMAC_TRIGSRC_17 0xff #endif // #if CONF_DMAC_TRANS_TYPE_17 == 0 #define CONF_DMAC_TYPE_17 0 #define CONF_DMAC_DSYNC_17 0 #elif CONF_DMAC_TRANS_TYPE_17 == 1 #define CONF_DMAC_TYPE_17 1 #define CONF_DMAC_DSYNC_17 0 #elif CONF_DMAC_TRANS_TYPE_17 == 2 #define CONF_DMAC_TYPE_17 1 #define CONF_DMAC_DSYNC_17 1 #endif #if CONF_DMAC_TRIGSRC_17 == 0xFF #define CONF_DMAC_SWREQ_17 1 #else #define CONF_DMAC_SWREQ_17 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_17_SETTINGS == 1 && CONF_DMAC_BEATSIZE_17 != 2 \ && ((!CONF_DMAC_SRCINC_17) || (!CONF_DMAC_DSTINC_17))) #if (!CONF_DMAC_SRCINC_17) #define CONF_DMAC_SRC_STRIDE_17 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_17) #define CONF_DMAC_DES_STRIDE_17 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_17 #define CONF_DMAC_SRC_STRIDE_17 0 #endif #ifndef CONF_DMAC_DES_STRIDE_17 #define CONF_DMAC_DES_STRIDE_17 0 #endif // Channel 18 settings // dmac_channel_18_settings #ifndef CONF_DMAC_CHANNEL_18_SETTINGS #define CONF_DMAC_CHANNEL_18_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_18 #ifndef CONF_DMAC_BURSTSIZE_18 #define CONF_DMAC_BURSTSIZE_18 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_18 #ifndef CONF_DMAC_CHUNKSIZE_18 #define CONF_DMAC_CHUNKSIZE_18 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_18 #ifndef CONF_DMAC_BEATSIZE_18 #define CONF_DMAC_BEATSIZE_18 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_18 #ifndef CONF_DMAC_SRC_INTERFACE_18 #define CONF_DMAC_SRC_INTERFACE_18 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_18 #ifndef CONF_DMAC_DES_INTERFACE_18 #define CONF_DMAC_DES_INTERFACE_18 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_18 #ifndef CONF_DMAC_SRCINC_18 #define CONF_DMAC_SRCINC_18 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_18 #ifndef CONF_DMAC_DSTINC_18 #define CONF_DMAC_DSTINC_18 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_18 #ifndef CONF_DMAC_TRANS_TYPE_18 #define CONF_DMAC_TRANS_TYPE_18 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_18 #ifndef CONF_DMAC_TRIGSRC_18 #define CONF_DMAC_TRIGSRC_18 0xff #endif // #if CONF_DMAC_TRANS_TYPE_18 == 0 #define CONF_DMAC_TYPE_18 0 #define CONF_DMAC_DSYNC_18 0 #elif CONF_DMAC_TRANS_TYPE_18 == 1 #define CONF_DMAC_TYPE_18 1 #define CONF_DMAC_DSYNC_18 0 #elif CONF_DMAC_TRANS_TYPE_18 == 2 #define CONF_DMAC_TYPE_18 1 #define CONF_DMAC_DSYNC_18 1 #endif #if CONF_DMAC_TRIGSRC_18 == 0xFF #define CONF_DMAC_SWREQ_18 1 #else #define CONF_DMAC_SWREQ_18 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_18_SETTINGS == 1 && CONF_DMAC_BEATSIZE_18 != 2 \ && ((!CONF_DMAC_SRCINC_18) || (!CONF_DMAC_DSTINC_18))) #if (!CONF_DMAC_SRCINC_18) #define CONF_DMAC_SRC_STRIDE_18 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_18) #define CONF_DMAC_DES_STRIDE_18 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_18 #define CONF_DMAC_SRC_STRIDE_18 0 #endif #ifndef CONF_DMAC_DES_STRIDE_18 #define CONF_DMAC_DES_STRIDE_18 0 #endif // Channel 19 settings // dmac_channel_19_settings #ifndef CONF_DMAC_CHANNEL_19_SETTINGS #define CONF_DMAC_CHANNEL_19_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_19 #ifndef CONF_DMAC_BURSTSIZE_19 #define CONF_DMAC_BURSTSIZE_19 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_19 #ifndef CONF_DMAC_CHUNKSIZE_19 #define CONF_DMAC_CHUNKSIZE_19 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_19 #ifndef CONF_DMAC_BEATSIZE_19 #define CONF_DMAC_BEATSIZE_19 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_19 #ifndef CONF_DMAC_SRC_INTERFACE_19 #define CONF_DMAC_SRC_INTERFACE_19 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_19 #ifndef CONF_DMAC_DES_INTERFACE_19 #define CONF_DMAC_DES_INTERFACE_19 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_19 #ifndef CONF_DMAC_SRCINC_19 #define CONF_DMAC_SRCINC_19 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_19 #ifndef CONF_DMAC_DSTINC_19 #define CONF_DMAC_DSTINC_19 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_19 #ifndef CONF_DMAC_TRANS_TYPE_19 #define CONF_DMAC_TRANS_TYPE_19 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_19 #ifndef CONF_DMAC_TRIGSRC_19 #define CONF_DMAC_TRIGSRC_19 0xff #endif // #if CONF_DMAC_TRANS_TYPE_19 == 0 #define CONF_DMAC_TYPE_19 0 #define CONF_DMAC_DSYNC_19 0 #elif CONF_DMAC_TRANS_TYPE_19 == 1 #define CONF_DMAC_TYPE_19 1 #define CONF_DMAC_DSYNC_19 0 #elif CONF_DMAC_TRANS_TYPE_19 == 2 #define CONF_DMAC_TYPE_19 1 #define CONF_DMAC_DSYNC_19 1 #endif #if CONF_DMAC_TRIGSRC_19 == 0xFF #define CONF_DMAC_SWREQ_19 1 #else #define CONF_DMAC_SWREQ_19 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_19_SETTINGS == 1 && CONF_DMAC_BEATSIZE_19 != 2 \ && ((!CONF_DMAC_SRCINC_19) || (!CONF_DMAC_DSTINC_19))) #if (!CONF_DMAC_SRCINC_19) #define CONF_DMAC_SRC_STRIDE_19 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_19) #define CONF_DMAC_DES_STRIDE_19 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_19 #define CONF_DMAC_SRC_STRIDE_19 0 #endif #ifndef CONF_DMAC_DES_STRIDE_19 #define CONF_DMAC_DES_STRIDE_19 0 #endif // Channel 20 settings // dmac_channel_20_settings #ifndef CONF_DMAC_CHANNEL_20_SETTINGS #define CONF_DMAC_CHANNEL_20_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_20 #ifndef CONF_DMAC_BURSTSIZE_20 #define CONF_DMAC_BURSTSIZE_20 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_20 #ifndef CONF_DMAC_CHUNKSIZE_20 #define CONF_DMAC_CHUNKSIZE_20 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_20 #ifndef CONF_DMAC_BEATSIZE_20 #define CONF_DMAC_BEATSIZE_20 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_20 #ifndef CONF_DMAC_SRC_INTERFACE_20 #define CONF_DMAC_SRC_INTERFACE_20 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_20 #ifndef CONF_DMAC_DES_INTERFACE_20 #define CONF_DMAC_DES_INTERFACE_20 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_20 #ifndef CONF_DMAC_SRCINC_20 #define CONF_DMAC_SRCINC_20 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_20 #ifndef CONF_DMAC_DSTINC_20 #define CONF_DMAC_DSTINC_20 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_20 #ifndef CONF_DMAC_TRANS_TYPE_20 #define CONF_DMAC_TRANS_TYPE_20 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_20 #ifndef CONF_DMAC_TRIGSRC_20 #define CONF_DMAC_TRIGSRC_20 0xff #endif // #if CONF_DMAC_TRANS_TYPE_20 == 0 #define CONF_DMAC_TYPE_20 0 #define CONF_DMAC_DSYNC_20 0 #elif CONF_DMAC_TRANS_TYPE_20 == 1 #define CONF_DMAC_TYPE_20 1 #define CONF_DMAC_DSYNC_20 0 #elif CONF_DMAC_TRANS_TYPE_20 == 2 #define CONF_DMAC_TYPE_20 1 #define CONF_DMAC_DSYNC_20 1 #endif #if CONF_DMAC_TRIGSRC_20 == 0xFF #define CONF_DMAC_SWREQ_20 1 #else #define CONF_DMAC_SWREQ_20 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_20_SETTINGS == 1 && CONF_DMAC_BEATSIZE_20 != 2 \ && ((!CONF_DMAC_SRCINC_20) || (!CONF_DMAC_DSTINC_20))) #if (!CONF_DMAC_SRCINC_20) #define CONF_DMAC_SRC_STRIDE_20 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_20) #define CONF_DMAC_DES_STRIDE_20 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_20 #define CONF_DMAC_SRC_STRIDE_20 0 #endif #ifndef CONF_DMAC_DES_STRIDE_20 #define CONF_DMAC_DES_STRIDE_20 0 #endif // Channel 21 settings // dmac_channel_21_settings #ifndef CONF_DMAC_CHANNEL_21_SETTINGS #define CONF_DMAC_CHANNEL_21_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_21 #ifndef CONF_DMAC_BURSTSIZE_21 #define CONF_DMAC_BURSTSIZE_21 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_21 #ifndef CONF_DMAC_CHUNKSIZE_21 #define CONF_DMAC_CHUNKSIZE_21 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_21 #ifndef CONF_DMAC_BEATSIZE_21 #define CONF_DMAC_BEATSIZE_21 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_21 #ifndef CONF_DMAC_SRC_INTERFACE_21 #define CONF_DMAC_SRC_INTERFACE_21 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_21 #ifndef CONF_DMAC_DES_INTERFACE_21 #define CONF_DMAC_DES_INTERFACE_21 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_21 #ifndef CONF_DMAC_SRCINC_21 #define CONF_DMAC_SRCINC_21 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_21 #ifndef CONF_DMAC_DSTINC_21 #define CONF_DMAC_DSTINC_21 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_21 #ifndef CONF_DMAC_TRANS_TYPE_21 #define CONF_DMAC_TRANS_TYPE_21 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_21 #ifndef CONF_DMAC_TRIGSRC_21 #define CONF_DMAC_TRIGSRC_21 0xff #endif // #if CONF_DMAC_TRANS_TYPE_21 == 0 #define CONF_DMAC_TYPE_21 0 #define CONF_DMAC_DSYNC_21 0 #elif CONF_DMAC_TRANS_TYPE_21 == 1 #define CONF_DMAC_TYPE_21 1 #define CONF_DMAC_DSYNC_21 0 #elif CONF_DMAC_TRANS_TYPE_21 == 2 #define CONF_DMAC_TYPE_21 1 #define CONF_DMAC_DSYNC_21 1 #endif #if CONF_DMAC_TRIGSRC_21 == 0xFF #define CONF_DMAC_SWREQ_21 1 #else #define CONF_DMAC_SWREQ_21 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_21_SETTINGS == 1 && CONF_DMAC_BEATSIZE_21 != 2 \ && ((!CONF_DMAC_SRCINC_21) || (!CONF_DMAC_DSTINC_21))) #if (!CONF_DMAC_SRCINC_21) #define CONF_DMAC_SRC_STRIDE_21 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_21) #define CONF_DMAC_DES_STRIDE_21 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_21 #define CONF_DMAC_SRC_STRIDE_21 0 #endif #ifndef CONF_DMAC_DES_STRIDE_21 #define CONF_DMAC_DES_STRIDE_21 0 #endif // Channel 22 settings // dmac_channel_22_settings #ifndef CONF_DMAC_CHANNEL_22_SETTINGS #define CONF_DMAC_CHANNEL_22_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_22 #ifndef CONF_DMAC_BURSTSIZE_22 #define CONF_DMAC_BURSTSIZE_22 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_22 #ifndef CONF_DMAC_CHUNKSIZE_22 #define CONF_DMAC_CHUNKSIZE_22 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_22 #ifndef CONF_DMAC_BEATSIZE_22 #define CONF_DMAC_BEATSIZE_22 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_22 #ifndef CONF_DMAC_SRC_INTERFACE_22 #define CONF_DMAC_SRC_INTERFACE_22 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_22 #ifndef CONF_DMAC_DES_INTERFACE_22 #define CONF_DMAC_DES_INTERFACE_22 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_22 #ifndef CONF_DMAC_SRCINC_22 #define CONF_DMAC_SRCINC_22 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_22 #ifndef CONF_DMAC_DSTINC_22 #define CONF_DMAC_DSTINC_22 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_22 #ifndef CONF_DMAC_TRANS_TYPE_22 #define CONF_DMAC_TRANS_TYPE_22 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_22 #ifndef CONF_DMAC_TRIGSRC_22 #define CONF_DMAC_TRIGSRC_22 0xff #endif // #if CONF_DMAC_TRANS_TYPE_22 == 0 #define CONF_DMAC_TYPE_22 0 #define CONF_DMAC_DSYNC_22 0 #elif CONF_DMAC_TRANS_TYPE_22 == 1 #define CONF_DMAC_TYPE_22 1 #define CONF_DMAC_DSYNC_22 0 #elif CONF_DMAC_TRANS_TYPE_22 == 2 #define CONF_DMAC_TYPE_22 1 #define CONF_DMAC_DSYNC_22 1 #endif #if CONF_DMAC_TRIGSRC_22 == 0xFF #define CONF_DMAC_SWREQ_22 1 #else #define CONF_DMAC_SWREQ_22 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_22_SETTINGS == 1 && CONF_DMAC_BEATSIZE_22 != 2 \ && ((!CONF_DMAC_SRCINC_22) || (!CONF_DMAC_DSTINC_22))) #if (!CONF_DMAC_SRCINC_22) #define CONF_DMAC_SRC_STRIDE_22 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_22) #define CONF_DMAC_DES_STRIDE_22 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_22 #define CONF_DMAC_SRC_STRIDE_22 0 #endif #ifndef CONF_DMAC_DES_STRIDE_22 #define CONF_DMAC_DES_STRIDE_22 0 #endif // Channel 23 settings // dmac_channel_23_settings #ifndef CONF_DMAC_CHANNEL_23_SETTINGS #define CONF_DMAC_CHANNEL_23_SETTINGS 0 #endif // Burst Size // <0x0=> 1 burst size // <0x1=> 4 burst size // <0x2=> 8 burst size // <0x3=> 16 burst size // Define the memory burst size // dmac_burstsize_23 #ifndef CONF_DMAC_BURSTSIZE_23 #define CONF_DMAC_BURSTSIZE_23 0x0 #endif // Chunk Size // <0x0=> 1 data transferred // <0x1=> 2 data transferred // <0x2=> 4 data transferred // <0x3=> 8 data transferred // <0x4=> 16 data transferred // Define the peripheral chunk size // dmac_chunksize_23 #ifndef CONF_DMAC_CHUNKSIZE_23 #define CONF_DMAC_CHUNKSIZE_23 0x0 #endif // Beat Size // <0=> 8-bit bus transfer // <1=> 16-bit bus transfer // <2=> 32-bit bus transfer // Defines the size of one beat // dmac_beatsize_23 #ifndef CONF_DMAC_BEATSIZE_23 #define CONF_DMAC_BEATSIZE_23 0x0 #endif // Source Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is read through the system bus interface 0 or 1 // dma_src_interface_23 #ifndef CONF_DMAC_SRC_INTERFACE_23 #define CONF_DMAC_SRC_INTERFACE_23 0x0 #endif // Destination Interface Identifier // <0x0=> AHB_IF0 // <0x1=> AHB_IF1 // Define the data is written through the system bus interface 0 or 1 // dma_des_interface_23 #ifndef CONF_DMAC_DES_INTERFACE_23 #define CONF_DMAC_DES_INTERFACE_23 0x0 #endif // Source Address Increment // Indicates whether the source address incremented as beat size or not // dmac_srcinc_23 #ifndef CONF_DMAC_SRCINC_23 #define CONF_DMAC_SRCINC_23 0 #endif // Destination Address Increment // Indicates whether the destination address incremented as beat size or not // dmac_dstinc_23 #ifndef CONF_DMAC_DSTINC_23 #define CONF_DMAC_DSTINC_23 0 #endif // Transfer Type // <0x0=> Memory to Memory Transfer // <0x1=> Peripheral to Memory Transfer // <0x2=> Memory to Peripheral Transfer // Define the data transfer type // dma_trans_type_23 #ifndef CONF_DMAC_TRANS_TYPE_23 #define CONF_DMAC_TRANS_TYPE_23 0x0 #endif // Trigger source // <0xFF=> Software Trigger // <0x00=> HSMCI TX/RX Trigger // <0x01=> SPI0 TX Trigger // <0x02=> SPI0 RX Trigger // <0x03=> SPI1 TX Trigger // <0x04=> SPI1 RX Trigger // <0x05=> QSPI TX Trigger // <0x06=> QSPI RX Trigger // <0x07=> USART0 TX Trigger // <0x08=> USART0 RX Trigger // <0x09=> USART1 TX Trigger // <0x0A=> USART1 RX Trigger // <0x0B=> USART2 TX Trigger // <0x0C=> USART2 RX Trigger // <0x0D=> PWM0 TX Trigger // <0x0E=> TWIHS0 TX Trigger // <0x0F=> TWIHS0 RX Trigger // <0x10=> TWIHS1 TX Trigger // <0x11=> TWIHS1 RX Trigger // <0x12=> TWIHS2 TX Trigger // <0x13=> TWIHS2 RX Trigger // <0x14=> UART0 TX Trigger // <0x15=> UART0 RX Trigger // <0x16=> UART1 TX Trigger // <0x17=> UART1 RX Trigger // <0x18=> UART2 TX Trigger // <0x19=> UART2 RX Trigger // <0x1A=> UART3 TX Trigger // <0x1B=> UART3 RX Trigger // <0x1C=> UART4 TX Trigger // <0x1D=> UART4 RX Trigger // <0x1E=> DACC TX Trigger // <0x20=> SSC TX Trigger // <0x21=> SSC RX Trigger // <0x22=> PIOA RX Trigger // <0x23=> AFEC0 RX Trigger // <0x24=> AFEC1 RX Trigger // <0x25=> AES TX Trigger // <0x26=> AES RX Trigger // <0x27=> PWM1 TX Trigger // <0x28=> TC0 RX Trigger // <0x29=> TC3 RX Trigger // <0x2A=> TC6 RX Trigger // <0x2B=> TC9 RX Trigger // <0x2C=> I2SC0 TX Left Trigger // <0x2D=> I2SC0 RX Left Trigger // <0x2E=> I2SC1 TX Left Trigger // <0x2F=> I2SC1 RX Left Trigger // <0x30=> I2SC0 TX Right Trigger // <0x31=> I2SC0 RX Right Trigger // <0x32=> I2SC1 TX Right Trigger // <0x33=> I2SC1 RX Right Trigger // Define the DMA trigger source // dmac_trifsrc_23 #ifndef CONF_DMAC_TRIGSRC_23 #define CONF_DMAC_TRIGSRC_23 0xff #endif // #if CONF_DMAC_TRANS_TYPE_23 == 0 #define CONF_DMAC_TYPE_23 0 #define CONF_DMAC_DSYNC_23 0 #elif CONF_DMAC_TRANS_TYPE_23 == 1 #define CONF_DMAC_TYPE_23 1 #define CONF_DMAC_DSYNC_23 0 #elif CONF_DMAC_TRANS_TYPE_23 == 2 #define CONF_DMAC_TYPE_23 1 #define CONF_DMAC_DSYNC_23 1 #endif #if CONF_DMAC_TRIGSRC_23 == 0xFF #define CONF_DMAC_SWREQ_23 1 #else #define CONF_DMAC_SWREQ_23 0 #endif /* Errata: If XDMA is used to transfer 8-bit or 16-bit data in fixed source address * or fixed destination address mode, source and destination addresses are incremented * by 8-bit or 16-bit. * Workaround: The user can fix the problem by setting the source addressing mode to * use microblock and data striding with microblock stride set to 0 and data stride set to -1. */ #if (CONF_DMAC_CHANNEL_23_SETTINGS == 1 && CONF_DMAC_BEATSIZE_23 != 2 \ && ((!CONF_DMAC_SRCINC_23) || (!CONF_DMAC_DSTINC_23))) #if (!CONF_DMAC_SRCINC_23) #define CONF_DMAC_SRC_STRIDE_23 ((int16_t)(-1)) #endif #if (!CONF_DMAC_DSTINC_23) #define CONF_DMAC_DES_STRIDE_23 ((int16_t)(-1)) #endif #endif #ifndef CONF_DMAC_SRC_STRIDE_23 #define CONF_DMAC_SRC_STRIDE_23 0 #endif #ifndef CONF_DMAC_DES_STRIDE_23 #define CONF_DMAC_DES_STRIDE_23 0 #endif // // <<< end of configuration section >>> #endif // HPL_XDMAC_CONFIG_H ================================================ FILE: hw/bsp/same7x/boards/same70_xplained/peripheral_clk_config.h ================================================ /* Auto-generated config file peripheral_clk_config.h */ #ifndef PERIPHERAL_CLK_CONFIG_H #define PERIPHERAL_CLK_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> /** * \def CONF_HCLK_FREQUENCY * \brief HCLK's Clock frequency */ #ifndef CONF_HCLK_FREQUENCY #define CONF_HCLK_FREQUENCY 300000000 #endif /** * \def CONF_FCLK_FREQUENCY * \brief FCLK's Clock frequency */ #ifndef CONF_FCLK_FREQUENCY #define CONF_FCLK_FREQUENCY 300000000 #endif /** * \def CONF_CPU_FREQUENCY * \brief CPU's Clock frequency */ #ifndef CONF_CPU_FREQUENCY #define CONF_CPU_FREQUENCY 300000000 #endif /** * \def CONF_SLCK_FREQUENCY * \brief Slow Clock frequency */ #define CONF_SLCK_FREQUENCY 0 /** * \def CONF_MCK_FREQUENCY * \brief Master Clock frequency */ #define CONF_MCK_FREQUENCY 150000000 /** * \def CONF_PCK6_FREQUENCY * \brief Programmable Clock Controller 6 frequency */ #define CONF_PCK6_FREQUENCY 1714285 // USART Clock Settings // USART Clock source // <0=> Master Clock (MCK) // <1=> MCK / 8 for USART // <2=> Programmable Clock Controller 4 (PMC_PCK4) // <3=> External Clock // This defines the clock source for the USART // usart_clock_source #ifndef CONF_USART1_CK_SRC #define CONF_USART1_CK_SRC 0 #endif // USART External Clock Input on SCK <1-4294967295> // Inputs the external clock frequency on SCK // usart_clock_freq #ifndef CONF_USART1_SCK_FREQ #define CONF_USART1_SCK_FREQ 10000000 #endif // /** * \def USART FREQUENCY * \brief USART's Clock frequency */ #ifndef CONF_USART1_FREQUENCY #define CONF_USART1_FREQUENCY 150000000 #endif #ifndef CONF_SRC_USB_480M #define CONF_SRC_USB_480M 0 #endif #ifndef CONF_SRC_USB_48M #define CONF_SRC_USB_48M 1 #endif // USB Full/Low Speed Clock // USB Clock Controller (USB_48M) // usb_fsls_clock_source // 48MHz clock source for low speed and full speed. // It must be available when low speed is supported by host driver. // It must be available when low power mode is selected. #ifndef CONF_USBHS_FSLS_SRC #define CONF_USBHS_FSLS_SRC CONF_SRC_USB_48M #endif // USB Clock Source(Normal/Low-power Mode Selection) // USB High Speed Clock (USB_480M) // USB Clock Controller (USB_48M) // usb_clock_source // Select the clock source for USB. // In normal mode, use "USB High Speed Clock (USB_480M)". // In low-power mode, use "USB Clock Controller (USB_48M)". #ifndef CONF_USBHS_SRC #define CONF_USBHS_SRC CONF_SRC_USB_480M #endif /** * \def CONF_USBHS_FSLS_FREQUENCY * \brief USBHS's Full/Low Speed Clock Source frequency */ #ifndef CONF_USBHS_FSLS_FREQUENCY #define CONF_USBHS_FSLS_FREQUENCY 48000000 #endif /** * \def CONF_USBHS_FREQUENCY * \brief USBHS's Selected Clock Source frequency */ #ifndef CONF_USBHS_FREQUENCY #define CONF_USBHS_FREQUENCY 480000000 #endif // <<< end of configuration section >>> #endif // PERIPHERAL_CLK_CONFIG_H ================================================ FILE: hw/bsp/same7x/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: Microchip */ #include "bsp/board_api.h" #include "sam.h" #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hal/include/hal_usart_async.h" #include "hpl/pmc/hpl_pmc.h" #include "hpl/usart/hpl_usart_base.h" #include "peripheral_clk_config.h" static inline void board_vbus_set(uint8_t rhport, bool state); void _init(void); #include "board.h" #ifndef UART_BUFFER_SIZE #define UART_BUFFER_SIZE 64 #endif #define LED_STATE_OFF (1 - LED_STATE_ON) static struct usart_async_descriptor edbg_com; static uint8_t edbg_com_buffer[UART_BUFFER_SIZE]; static volatile bool uart_busy = false; static void tx_complete_cb(const struct usart_async_descriptor *const io_descr) { (void) io_descr; uart_busy = false; } void board_init(void) { init_mcu(); /* Disable Watchdog */ hri_wdt_set_MR_WDDIS_bit(WDT); #ifdef LED_PIN _pmc_enable_periph_clock(LED_PORT_CLOCK); gpio_set_pin_level(LED_PIN, LED_STATE_OFF); gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); #endif #ifdef BUTTON_PIN _pmc_enable_periph_clock(BUTTON_PORT_CLOCK); gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULL_DOWN : GPIO_PULL_UP); gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); #endif _pmc_enable_periph_clock(UART_PORT_CLOCK); gpio_set_pin_function(UART_RX_PIN, UART_RX_FUNCTION); gpio_set_pin_function(UART_TX_PIN, UART_TX_FUNCTION); usart_async_init(&edbg_com, BOARD_USART, edbg_com_buffer, sizeof(edbg_com_buffer), _usart_get_usart_async()); usart_async_set_baud_rate(&edbg_com, CFG_BOARD_UART_BAUDRATE); usart_async_register_callback(&edbg_com, USART_ASYNC_TXC_CB, tx_complete_cb); usart_async_enable(&edbg_com); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer (SystemCoreClock may not be correct after init) SysTick_Config(CONF_CPU_FREQUENCY / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority((IRQn_Type) ID_USBHS, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // Enable USB clock _pmc_enable_periph_clock(ID_USBHS); #if CFG_TUH_ENABLED board_vbus_set(0, true); #endif } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void USBHS_Handler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef LED_PIN gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); #else return 0; #endif } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { while (uart_busy) {} uart_busy = true; io_write(&edbg_com.io, buf, len); return len; } // Read 128-bit unique ID via EFC STUI/SPUI commands // Must run from RAM since STUI remaps flash to the unique ID __attribute__((noinline)) TU_ATTR_SECTION(.ramfunc) static void read_unique_id(uint32_t uid[4]) { // Wait for flash to be ready while (!(EFC->EEFC_FSR & EEFC_FSR_FRDY)) {} // Issue Start Read Unique Identifier command EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_STUI; while (EFC->EEFC_FSR & EEFC_FSR_FRDY) {} // Read 128-bit unique ID from flash base address const volatile uint32_t *flash = (const volatile uint32_t *) IFLASH_ADDR; for (int i = 0; i < 4; i++) { uid[i] = flash[i]; } // Issue Stop Read Unique Identifier command EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SPUI; while (!(EFC->EEFC_FSR & EEFC_FSR_FRDY)) {} } size_t board_get_unique_id(uint8_t id[], size_t max_len) { const size_t uid_len = 16; if (max_len < uid_len) { return 0; } read_unique_id((uint32_t *)(uintptr_t) id); return uid_len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void _init(void) { } ================================================ FILE: hw/bsp/same7x/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(SDK_DIR ${TOP}/hw/mcu/microchip/same70) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m7 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMX7X CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/same70b/gcc/system_same70q21b.c ${SDK_DIR}/hpl/core/hpl_init.c ${SDK_DIR}/hpl/usart/hpl_usart.c ${SDK_DIR}/hpl/pmc/hpl_pmc.c ${SDK_DIR}/hal/src/hal_usart_async.c ${SDK_DIR}/hal/src/hal_io.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hal/utils/src/utils_ringbuffer.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/same70b/include ${SDK_DIR}/hal/include ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/core ${SDK_DIR}/hpl/pio ${SDK_DIR}/hpl/pmc ${SDK_DIR}/hri ${SDK_DIR}/CMSIS/Core/Include ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) update_board(${BOARD_TARGET}) if (TOOLCHAIN STREQUAL "gcc" OR TOOLCHAIN STREQUAL "clang") set_target_properties(${BOARD_TARGET} PROPERTIES COMPILE_FLAGS -Wno-error=cast-qual) endif () endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_SAMX7X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/microchip/samx7x/dcd_samx7x.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") # ignore hal error set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) endif() family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/same7x/family.mk ================================================ SDK_DIR = hw/mcu/microchip/same70 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m7 CFLAGS += \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m7 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_SAMX7X # suppress following warnings from mcu driver CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slows down compilation significantly CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. SRC_C += \ src/portable/microchip/samx7x/dcd_samx7x.c \ $(STARTUP_FILE) \ $(SDK_DIR)/same70b/gcc/system_same70q21b.c \ $(SDK_DIR)/hpl/core/hpl_init.c \ $(SDK_DIR)/hpl/usart/hpl_usart.c \ $(SDK_DIR)/hpl/pmc/hpl_pmc.c \ $(SDK_DIR)/hal/src/hal_usart_async.c \ $(SDK_DIR)/hal/src/hal_io.c \ $(SDK_DIR)/hal/src/hal_atomic.c \ $(SDK_DIR)/hal/utils/src/utils_ringbuffer.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(SDK_DIR) \ $(TOP)/$(SDK_DIR)/config \ $(TOP)/$(SDK_DIR)/same70b/include \ $(TOP)/$(SDK_DIR)/hal/include \ $(TOP)/$(SDK_DIR)/hal/utils/include \ $(TOP)/$(SDK_DIR)/hpl/core \ $(TOP)/$(SDK_DIR)/hpl/pio \ $(TOP)/$(SDK_DIR)/hpl/pmc \ $(TOP)/$(SDK_DIR)/hri \ $(TOP)/$(SDK_DIR)/CMSIS/Core/Include # For flash-jlink target flash: $(BUILD)/$(PROJECT).bin edbg --verbose -t same70 -pv -f $< ================================================ FILE: hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ extern uint32_t SystemCoreClock; #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; end = .; } > ram /* heap section */ .heap (NOLOAD): { . = ALIGN(8); _sheap = .; . = . + HEAP_SIZE; . = ALIGN(8); _eheap = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram . = ALIGN(4); _end = . ; _ram_end_ = ORIGIN(ram) + LENGTH(ram) - 1 ; } ================================================ FILE: hw/bsp/samg/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, hathach (tinyusb.org) * * 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. * */ /* metadata: manufacturer: Microchip */ #include "sam.h" // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "peripheral_clk_config.h" #include "hal/include/hal_init.h" #include "hal/include/hpl_usart_sync.h" #include "hpl/pmc/hpl_pmc.h" #include "hal/include/hal_gpio.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ struct _usart_sync_device edbg_com; //------------- IMPLEMENTATION -------------// void board_init(void) { init_mcu(); _pmc_enable_periph_clock(ID_PIOA); /* Disable Watchdog */ hri_wdt_set_MR_WDDIS_bit(WDT); // LED gpio_set_pin_level(LED_PIN, false); gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); // Button gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); // Uart via EDBG Com _pmc_enable_periph_clock(ID_FLEXCOM7); gpio_set_pin_function(UART_RX_PIN, MUX_PA27B_FLEXCOM7_RXD); gpio_set_pin_function(UART_TX_PIN, MUX_PA28B_FLEXCOM7_TXD); _usart_sync_init(&edbg_com, FLEXCOM7); _usart_sync_set_baud_rate(&edbg_com, CFG_BOARD_UART_BAUDRATE); _usart_sync_set_mode(&edbg_com, USART_MODE_ASYNCHRONOUS); _usart_sync_enable(&edbg_com); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer (samd SystemCoreClock may not correct) SysTick_Config(CONF_CPU_FREQUENCY / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; NVIC_SetPriority(UDP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // USB Pin, Clock init /* Clear SYSIO 10 & 11 for USB DM & DP */ hri_matrix_clear_CCFG_SYSIO_reg(MATRIX, CCFG_SYSIO_SYSIO10 | CCFG_SYSIO_SYSIO11); // Enable clock _pmc_enable_periph_clock(ID_UDP); /* USB Device mode & Transceiver active */ hri_matrix_write_CCFG_USBMR_reg(MATRIX, CCFG_USBMR_USBMODE); } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ void UDP_Handler(void) { #if CFG_TUD_ENABLED tud_int_handler(0); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { gpio_set_pin_level(LED_PIN, state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { uint8_t const* buf8 = (uint8_t const*) buf; for (int i = 0; i < len; i++) { while (!_usart_sync_is_ready_to_send(&edbg_com)) {} _usart_sync_write_byte(&edbg_com, buf8[i]); } return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void); void _init(void) { } ================================================ FILE: hw/bsp/samg/family.cmake ================================================ include_guard() set(SAM_FAMILY samg55) set(SDK_DIR ${TOP}/hw/mcu/microchip/samg55) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMG CACHE INTERNAL "") set(OPENOCD_OPTION "-f board/atmel_samg55_xplained_pro.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/${SAM_FAMILY}/gcc/gcc/startup_${SAM_FAMILY}.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/${SAM_FAMILY}/gcc/system_${SAM_FAMILY}.c ${SDK_DIR}/hal/src/hal_atomic.c ${SDK_DIR}/hpl/core/hpl_init.c ${SDK_DIR}/hpl/usart/hpl_usart.c ${SDK_DIR}/hpl/pmc/hpl_pmc.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${SDK_DIR} ${SDK_DIR}/config ${SDK_DIR}/samg55/include ${SDK_DIR}/hal/include ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/core ${SDK_DIR}/hpl/pio ${SDK_DIR}/hpl/pmc ${SDK_DIR}/hri ${SDK_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_SAMG) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/microchip/samg/dcd_samg.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/samg/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 SDK_DIR = hw/mcu/microchip/samg55 CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_SAMG # suppress following warnings from mcu driver CFLAGS += -Wno-error=undef -Wno-error=null-dereference -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/microchip/samg/dcd_samg.c \ ${SDK_DIR}/samg55/gcc/gcc/startup_samg55.c \ ${SDK_DIR}/samg55/gcc/system_samg55.c \ ${SDK_DIR}/hal/src/hal_atomic.c \ ${SDK_DIR}/hpl/core/hpl_init.c \ ${SDK_DIR}/hpl/usart/hpl_usart.c \ ${SDK_DIR}/hpl/pmc/hpl_pmc.c \ INC += \ $(TOP)/$(FAMILY_PATH) \ $(TOP)/$(BOARD_PATH) \ $(TOP)/${SDK_DIR} \ $(TOP)/${SDK_DIR}/config \ $(TOP)/${SDK_DIR}/samg55/include \ $(TOP)/${SDK_DIR}/hal/include \ $(TOP)/${SDK_DIR}/hal/utils/include \ $(TOP)/${SDK_DIR}/hpl/core \ $(TOP)/${SDK_DIR}/hpl/pio \ $(TOP)/${SDK_DIR}/hpl/pmc \ $(TOP)/${SDK_DIR}/hri \ $(TOP)/${SDK_DIR}/CMSIS/Core/Include # flash using edbg from https://github.com/ataradov/edbg flash-edbg: $(BUILD)/$(PROJECT).bin edbg --verbose -t samg55 -pv -f $< ================================================ FILE: hw/bsp/samg/hpl_usart_config.h ================================================ /* Auto-generated config file hpl_usart_config.h */ #ifndef HPL_USART_CONFIG_H #define HPL_USART_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> #include #ifndef CONF_USART_7_ENABLE #define CONF_USART_7_ENABLE 1 #endif // Basic Configuration // Frame parity // <0x0=>Even parity // <0x1=>Odd parity // <0x2=>Parity forced to 0 // <0x3=>Parity forced to 1 // <0x4=>No parity // Parity bit mode for USART frame // usart_parity #ifndef CONF_USART_7_PARITY #define CONF_USART_7_PARITY 0x4 #endif // Character Size // <0x0=>5 bits // <0x1=>6 bits // <0x2=>7 bits // <0x3=>8 bits // Data character size in USART frame // usart_character_size #ifndef CONF_USART_7_CHSIZE #define CONF_USART_7_CHSIZE 0x3 #endif // Stop Bit // <0=>1 stop bit // <1=>1.5 stop bits // <2=>2 stop bits // Number of stop bits in USART frame // usart_stop_bit #ifndef CONF_USART_7_SBMODE #define CONF_USART_7_SBMODE 0 #endif // Clock Output Select // <0=>The USART does not drive the SCK pin // <1=>The USART drives the SCK pin if USCLKS does not select the external clock SCK // Clock Output Select in USART sck, if in usrt master mode, please drive SCK. // usart_clock_output_select #ifndef CONF_USART_7_CLKO #define CONF_USART_7_CLKO 0 #endif // Baud rate <1-3000000> // USART baud rate setting // usart_baud_rate #ifndef CONF_USART_7_BAUD #define CONF_USART_7_BAUD 9600 #endif // // Advanced configuration // usart_advanced #ifndef CONF_USART_7_ADVANCED_CONFIG #define CONF_USART_7_ADVANCED_CONFIG 0 #endif // Channel Mode // <0=>Normal Mode // <1=>Automatic Echo // <2=>Local Loopback // <3=>Remote Loopback // Channel mode in USART frame // usart_channel_mode #ifndef CONF_USART_7_CHMODE #define CONF_USART_7_CHMODE 0 #endif // 9 bits character enable // Enable 9 bits character, this has high priority than 5/6/7/8 bits. // usart_9bits_enable #ifndef CONF_USART_7_MODE9 #define CONF_USART_7_MODE9 0 #endif // Variable Sync // <0=>User defined configuration // <1=>sync field is updated when a character is written into US_THR // Variable Synchronization of Command/Data Sync Start Frarm Delimiter // variable_sync #ifndef CONF_USART_7_VAR_SYNC #define CONF_USART_7_VAR_SYNC 0 #endif // Oversampling Mode // <0=>16 Oversampling // <1=>8 Oversampling // Oversampling Mode in UART mode // usart__oversampling_mode #ifndef CONF_USART_7_OVER #define CONF_USART_7_OVER 0 #endif // Inhibit Non Ack // <0=>The NACK is generated // <1=>The NACK is not generated // Inhibit Non Acknowledge // usart__inack #ifndef CONF_USART_7_INACK #define CONF_USART_7_INACK 1 #endif // Disable Successive NACK // <0=>NACK is sent on the ISO line as soon as a parity error occurs // <1=>Many parity errors generate a NACK on the ISO line // Disable Successive NACK // usart_dsnack #ifndef CONF_USART_7_DSNACK #define CONF_USART_7_DSNACK 0 #endif // Inverted Data // <0=>Data isn't inverted, nomal mode // <1=>Data is inverted // Inverted Data // usart_invdata #ifndef CONF_USART_7_INVDATA #define CONF_USART_7_INVDATA 0 #endif // Maximum Number of Automatic Iteration <0-7> // Defines the maximum number of iterations in mode ISO7816, protocol T = 0. // usart_max_iteration #ifndef CONF_USART_7_MAX_ITERATION #define CONF_USART_7_MAX_ITERATION 0 #endif // Receive Line Filter enable // whether the USART filters the receive line using a three-sample filter // usart_receive_filter_enable #ifndef CONF_USART_7_FILTER #define CONF_USART_7_FILTER 0 #endif // Manchester Encoder/Decoder Enable // whether the USART Manchester Encoder/Decoder // usart_manchester_filter_enable #ifndef CONF_USART_7_MAN #define CONF_USART_7_MAN 0 #endif // Manchester Synchronization Mode // <0=>The Manchester start bit is a 0 to 1 transition // <1=>The Manchester start bit is a 1 to 0 transition // Manchester Synchronization Mode // usart_manchester_synchronization_mode #ifndef CONF_USART_7_MODSYNC #define CONF_USART_7_MODSYNC 0 #endif // Start Frame Delimiter Selector // <0=>Start frame delimiter is COMMAND or DATA SYNC // <1=>Start frame delimiter is one bit // Start Frame Delimiter Selector // usart_start_frame_delimiter #ifndef CONF_USART_7_ONEBIT #define CONF_USART_7_ONEBIT 0 #endif // Fractional Part <0-7> // Fractional part of the baud rate if baud rate generator is in fractional mode // usart_arch_fractional #ifndef CONF_USART_7_FRACTIONAL #define CONF_USART_7_FRACTIONAL 0x0 #endif // Data Order // <0=>LSB is transmitted first // <1=>MSB is transmitted first // Data order of the data bits in the frame // usart_arch_msbf #ifndef CONF_USART_7_MSBF #define CONF_USART_7_MSBF 0 #endif // #define CONF_USART_7_MODE 0x0 // Calculate BAUD register value in UART mode #if CONF_FLEXCOM7_CK_SRC < 3 #ifndef CONF_USART_7_BAUD_CD #define CONF_USART_7_BAUD_CD ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / 8 / (2 - CONF_USART_7_OVER)) #endif #ifndef CONF_USART_7_BAUD_FP #define CONF_USART_7_BAUD_FP \ ((CONF_FLEXCOM7_FREQUENCY) / CONF_USART_7_BAUD / (2 - CONF_USART_7_OVER) - 8 * CONF_USART_7_BAUD_CD) #endif #elif CONF_FLEXCOM7_CK_SRC == 3 // No division is active. The value written in US_BRGR has no effect. #ifndef CONF_USART_7_BAUD_CD #define CONF_USART_7_BAUD_CD 1 #endif #ifndef CONF_USART_7_BAUD_FP #define CONF_USART_7_BAUD_FP 1 #endif #endif // <<< end of configuration section >>> #endif // HPL_USART_CONFIG_H ================================================ FILE: hw/bsp/samg/peripheral_clk_config.h ================================================ /* Auto-generated config file peripheral_clk_config.h */ #ifndef PERIPHERAL_CLK_CONFIG_H #define PERIPHERAL_CLK_CONFIG_H // <<< Use Configuration Wizard in Context Menu >>> /** * \def CONF_HCLK_FREQUENCY * \brief HCLK's Clock frequency */ #ifndef CONF_HCLK_FREQUENCY #define CONF_HCLK_FREQUENCY 8000000 #endif /** * \def CONF_FCLK_FREQUENCY * \brief FCLK's Clock frequency */ #ifndef CONF_FCLK_FREQUENCY #define CONF_FCLK_FREQUENCY 8000000 #endif /** * \def CONF_CPU_FREQUENCY * \brief CPU's Clock frequency */ #ifndef CONF_CPU_FREQUENCY #define CONF_CPU_FREQUENCY 8000000 #endif /** * \def CONF_SLCK_FREQUENCY * \brief Slow Clock frequency */ #ifndef CONF_SLCK_FREQUENCY #define CONF_SLCK_FREQUENCY 32768 #endif /** * \def CONF_MCK_FREQUENCY * \brief Master Clock frequency */ #ifndef CONF_MCK_FREQUENCY #define CONF_MCK_FREQUENCY 8000000 #endif // USB Clock Source // <0=> USB Clock Controller (USB_48M) // usb_clock_source // Select the clock source for USB. #ifndef CONF_UDP_SRC #define CONF_UDP_SRC 0 #endif /** * \def CONF_UDP_FREQUENCY * \brief UDP's Clock frequency */ #ifndef CONF_UDP_FREQUENCY #define CONF_UDP_FREQUENCY 48005120 #endif // FLEXCOM Clock Settings // FLEXCOM Clock source // <0=> Master Clock (MCK) // <1=> MCK / 8 // <2=> Programmable Clock Controller 6 (PMC_PCK6) // <2=> Programmable Clock Controller 7 (PMC_PCK7) // <3=> External Clock // This defines the clock source for the FLEXCOM, PCK6 is used for FLEXCOM0/1/2/3 and PCK7 is used for FLEXCOM4/5/6/7 // flexcom_clock_source #ifndef CONF_FLEXCOM7_CK_SRC #define CONF_FLEXCOM7_CK_SRC 0 #endif // FLEXCOM External Clock Input on SCK <1-4294967295> // Inputs the external clock frequency on SCK // flexcom_clock_freq #ifndef CONF_FLEXCOM7_SCK_FREQ #define CONF_FLEXCOM7_SCK_FREQ 10000000 #endif #ifndef CONF_FLEXCOM7_FREQUENCY #define CONF_FLEXCOM7_FREQUENCY 8000000 #endif // <<< end of configuration section >>> #endif // PERIPHERAL_CLK_CONFIG_H ================================================ FILE: hw/bsp/stm32c0/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32c0xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake ================================================ set(MCU_VARIANT stm32c071xx) set(JLINK_DEVICE stm32c071rb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32C071RBTx_FLASH.ld) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/stm32c071xx_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32C071xx ) endfunction() ================================================ FILE: hw/bsp/stm32c0/boards/stm32c071nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * Copyright (c) 2023, HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32C071 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-g071rb.html */ #ifndef BOARD_H_ #define BOARD_H_ // Green LED #define GREEN_LED_PORT GPIOA #define GREEN_LED_PIN GPIO_PIN_5 #define GREEN_LED_STATE_ON 1 // Blue LED #define BLUE_LED_PORT GPIOC #define BLUE_LED_PIN GPIO_PIN_9 #define BLUE_LED_STATE_ON 0 // Generic LED #define LED_PORT GREEN_LED_PORT #define LED_PIN GREEN_LED_PIN #define LED_STATE_ON GREEN_LED_STATE_ON // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 0 // Enable UART serial communication with the ST-Link #define UART_DEV USART2 #define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF1_USART2 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSE; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); } #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk ================================================ CFLAGS += \ -DSTM32C071xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32c071xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32C071RBTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32c071xx.s LD_FILE_IAR = $(BOARD_PATH)/stm32c071xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32c071rb ================================================ FILE: hw/bsp/stm32c0/boards/stm32c071nucleo/stm32c071xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20005FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0xc00; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; export symbol __ICFEDIT_region_RAM_start__; export symbol __ICFEDIT_region_RAM_end__; ================================================ FILE: hw/bsp/stm32c0/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2023 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32c0xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_DRD_FS_IRQHandler(void) { tusb_int_handler(0, true); } // Startup code generated by STM32CubeIDE uses USB_IRQHandler, while // stm32c071xx.s from cmsis_device_c0 uses USB_DRD_FS_IRQHandler. void USB_IRQHandler(void) { tusb_int_handler(0, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; void board_init(void) { HAL_Init(); board_clock_init(); // Enable peripheral clocks. __HAL_RCC_USB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // LED { GPIO_InitTypeDef gpio_init = { 0 }; gpio_init.Pin = LED_PIN; gpio_init.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(LED_PORT, &gpio_init); board_led_write(false); } // Button { GPIO_InitTypeDef gpio_init = { 0 }; gpio_init.Pin = BUTTON_PIN; gpio_init.Mode = GPIO_MODE_INPUT; gpio_init.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; HAL_GPIO_Init(BUTTON_PORT, &gpio_init); } #ifdef UART_DEV UART_CLK_EN(); // UART { GPIO_InitTypeDef gpio_init = { 0 }; gpio_init.Pin = UART_TX_PIN | UART_RX_PIN; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; gpio_init.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &gpio_init); } UartHandle = (UART_HandleTypeDef){ .Instance = UART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16, .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT }; HAL_UART_Init(&UartHandle); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; (void) UartHandle; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; HAL_IncTick(); } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32c0/family.cmake ================================================ include_guard() set(ST_FAMILY c0) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32C0 CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/stlink.cfg -f target/stm32c0x.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_EXAMPLE_VIDEO_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32C0) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${TOP}/src/portable/st/typec/typec_stm32.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_stlink(${TARGET}) #family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32c0/family.mk ================================================ ST_FAMILY = c0 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32C0 \ -DCFG_EXAMPLE_VIDEO_READONLY \ # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align -Wno-error=unused-parameter LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32c0/stm32c0xx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32c0xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32c0xx_hal_conf.h. ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32C0xx_HAL_CONF_H #define STM32C0xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /* ########################## Register Callbacks selection ############################## */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32c0xx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE (48000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE (48000000UL) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ #if !defined (LSI_STARTUP_TIME) #define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in ms */ #endif /* LSI_STARTUP_TIME */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE (32768UL) /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S1 peripheral * This value is used by the RCC HAL module to compute the I2S1 clock source * frequency. */ #if !defined (EXTERNAL_I2S1_CLOCK_VALUE) #define EXTERNAL_I2S1_CLOCK_VALUE (12288000UL) /*!< Value of the I2S1 External clock source in Hz*/ #endif /* EXTERNAL_I2S1_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 3U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include modules header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32c0xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32c0xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32c0xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32c0xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32c0xx_hal_adc.h" #include "stm32c0xx_hal_adc_ex.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32c0xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32c0xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32c0xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32c0xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32c0xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32c0xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32c0xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32c0xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32c0xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32c0xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32c0xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32c0xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32c0xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32c0xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32c0xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32c0xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32c0xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32c0xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for functions parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32C0xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f0xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<
© COPYRIGHT(c) 2019 STMicroelectronics
** ** 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. Neither the name of STMicroelectronics nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20004000; /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K } /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072disco/STM32F072RBTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F072RBTx Device with ** 128KByte FLASH, 16KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20004000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072disco/board.cmake ================================================ set(MCU_VARIANT stm32f072xb) set(JLINK_DEVICE stm32f072rb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F072RBTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F072xB CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F072 Discovery url: https://www.st.com/en/evaluation-tools/32f072bdiscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOC #define LED_PIN GPIO_PIN_6 #define LED_STATE_ON 1 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 // UART #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF1_USART1 #define UART_TX_PIN GPIO_PIN_9 #define UART_RX_PIN GPIO_PIN_10 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32f0_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Select HSI48 Oscillator as PLL source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI48; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK and PCLK1 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072disco/board.mk ================================================ MCU_VARIANT = stm32f072xb CFLAGS += -DSTM32F072xB -DCFG_EXAMPLE_VIDEO_READONLY # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F072RBTx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32f072rb # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld ================================================ /** ****************************************************************************** * @file LinkerScript.ld * @author Auto-generated by STM32CubeIDE * Abstract : Linker script for STM32072B-EVAL Board embedding STM32F072VBTx Device from stm32f0 series * 128Kbytes FLASH * 16Kbytes RAM * * Set heap size, stack size and stack location according * to application requirements. * * Set memory bank area and size if external memory is used ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072eval/board.cmake ================================================ set(MCU_VARIANT stm32f072xb) set(JLINK_DEVICE stm32f072vb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F072VBTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F072xB LSI_VALUE=40000 CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072eval/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F072 Eval url: https://www.st.com/en/evaluation-tools/stm32072b-eval.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOD #define LED_PIN GPIO_PIN_8 // LED1, GREEN // #define LED_PIN GPIO_PIN_9 // LED2, ORANGE // #define LED_PIN GPIO_PIN_10 // LED3, RED // #define LED_PIN GPIO_PIN_11 // LED4, BLUE #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 // JOY_SEL #define BUTTON_STATE_ACTIVE 1 // UART #define UART_DEV USART2 #define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE #define UART_GPIO_PORT GPIOD #define UART_GPIO_AF GPIO_AF0_USART2 #define UART_TX_PIN GPIO_PIN_5 #define UART_RX_PIN GPIO_PIN_6 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32f0_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB | RCC_PERIPHCLK_USART2; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f0/boards/stm32f072eval/board.mk ================================================ MCU_VARIANT = stm32f072xb CFLAGS += -DSTM32F072xB -DLSI_VALUE=40000 -DCFG_EXAMPLE_VIDEO_READONLY # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F072VBTx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32f072vb # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f0/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f0xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; void board_init(void) { board_stm32f0_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); // Enable UART Clock UART_CLK_EN(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // LED GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); // Uart GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle.Instance = UART_DEV; UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); // USB Pins // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // USB Clock enable __HAL_RCC_USB_CLK_ENABLE(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } #ifdef USE_FULL_ASSERT void assert_failed(const char* file, uint32_t line) { (void) file; (void) line; /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f0/family.cmake ================================================ include_guard() set(ST_FAMILY f0) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F0 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) #target_compile_options(${BOARD_TARGET} PUBLIC) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_EXAMPLE_MSC_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F0) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f0/family.mk ================================================ UF2_FAMILY_ID = 0x647824b6 ST_FAMILY = f0 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0 # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_STM32F0 # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=unused-parameter -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ------------------------ # All source paths should be relative to the top level. # ------------------------ SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32f0/stm32f0xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32f0xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F0xx_HAL_CONF_H #define __STM32F0xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_CAN_MODULE_ENABLED */ /*#define HAL_CEC_MODULE_ENABLED */ /*#define HAL_COMP_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED /*#define HAL_EXTI_MODULE_ENABLED */ /*#define HAL_I2C_MODULE_ENABLED */ /*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED /*#define HAL_RTC_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_TIM_MODULE_ENABLED */ /*#define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ /* ######################### Oscillator Values adaptation ################### */ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ /** * @brief In the following line adjust the External High Speed oscillator (HSE) Startup * Timeout value */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup * Timeout value */ #if !defined (HSI_STARTUP_TIMEOUT) #define HSI_STARTUP_TIMEOUT 5000U /*!< Time out for HSI start up */ #endif /* HSI_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator for ADC (HSI14) value. */ #if !defined (HSI14_VALUE) #define HSI14_VALUE 14000000U /*!< Value of the Internal High Speed oscillator for ADC in Hz. The real value may vary depending on the variations in voltage and temperature. */ #endif /* HSI14_VALUE */ /** * @brief Internal High Speed oscillator for USB (HSI48) value. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB in Hz. The real value may vary depending on the variations in voltage and temperature. */ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000U #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ /** * @brief Time out for LSE start up value in ms. */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY ((uint32_t)(1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority (lowest by default) */ /* Warning: Must be set to higher priority for HAL_Delay() */ /* and HAL_GetTick() usage under interrupt context */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define INSTRUCTION_CACHE_ENABLE 0U #define DATA_CACHE_ENABLE 0U #define USE_SPI_CRC 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ #define USE_FULL_ASSERT 1 /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f0xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f0xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32f0xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f0xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f0xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f0xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f0xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32f0xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32f0xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f0xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f0xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f0xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f0xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f0xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f0xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f0xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f0xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f0xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f0xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f0xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32f0xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f0xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f0xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32f0xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f0xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f0xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f0xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed(__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(const char* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F0xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f1xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_bluepill/board.cmake ================================================ set(MCU_VARIANT stm32f103xb) set(JLINK_DEVICE stm32f103c8) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F103X8_FLASH.ld) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/stm32f103x8_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F103xB HSE_VALUE=8000000U CFG_EXAMPLE_VIDEO_READONLY ) endfunction() ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F103 Bluepill url: https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOC #define LED_PIN GPIO_PIN_13 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 // UART #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA //#define UART_GPIO_AF GPIO_AF1_USART1 #define UART_TX_PIN GPIO_PIN_9 #define UART_RX_PIN GPIO_PIN_10 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32f1_clock_init(void) { RCC_ClkInitTypeDef clkinitstruct = {0}; RCC_OscInitTypeDef oscinitstruct = {0}; RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; /* Enable HSE Oscillator and activate PLL with HSE as source */ oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; oscinitstruct.HSEState = RCC_HSE_ON; oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; oscinitstruct.PLL.PLLState = RCC_PLL_ON; oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; HAL_RCC_OscConfig(&oscinitstruct); /* USB clock selection */ rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_bluepill/board.mk ================================================ MCU_VARIANT = stm32f103xb CFLAGS += -DSTM32F103xB -DHSE_VALUE=8000000U -DCFG_EXAMPLE_VIDEO_READONLY # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F103X8_FLASH.ld LD_FILE_IAR = $(BOARD_PATH)/stm32f103x8_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f103c8 # flash target ROM bootloader flash: flash-dfu-util ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_bluepill/stm32f103x8_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ; define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_mini_2/STM32F103XC_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : STM32F103XB_FLASH.ld ** ** Abstract : Linker script for STM32F103xB Device with ** 128KByte FLASH, 20KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20004FFF; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_mini_2/board.cmake ================================================ set(MCU_VARIANT stm32f103xb) set(JLINK_DEVICE stm32f103rc) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F103XC_FLASH.ld) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/stm32f103xc_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F103xB HSE_VALUE=8000000U ) endfunction() ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_mini_2/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F103 Mini v2 url: https://stm32-base.org/boards/STM32F103RCT6-STM32-Mini-V2.0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_8 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 // UART //#define UART_DEV USART1 //#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE //#define UART_GPIO_PORT GPIOA //#define UART_GPIO_AF GPIO_AF1_USART1 //#define UART_TX_PIN GPIO_PIN_9 //#define UART_RX_PIN GPIO_PIN_10 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32f1_clock_init(void) { RCC_ClkInitTypeDef clkinitstruct = {0}; RCC_OscInitTypeDef oscinitstruct = {0}; RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; /* Enable HSE Oscillator and activate PLL with HSE as source */ oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; oscinitstruct.HSEState = RCC_HSE_ON; oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; oscinitstruct.PLL.PLLState = RCC_PLL_ON; oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; HAL_RCC_OscConfig(&oscinitstruct); /* USB clock selection */ rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_mini_2/board.mk ================================================ MCU_VARIANT = stm32f103xb CFLAGS += -DSTM32F103xB -DHSE_VALUE=8000000U # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F103XC_FLASH.ld LD_FILE_IAR = $(BOARD_PATH)/stm32f103xc_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f103rc # flash target ROM bootloader flash: flash-jlink ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103_mini_2/stm32f103xc_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ; define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103ze_iar/board.cmake ================================================ set(MCU_VARIANT stm32f103xe) set(JLINK_DEVICE stm32f103ze) #set(JLINK_OPTION "-USB 320000338") string(TOUPPER ${MCU_VARIANT} MCU_VARIANT_UPPER) set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT_UPPER}_FLASH.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F103xE HSE_VALUE=8000000U ) endfunction() ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103ze_iar/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: IAR STM32 F103ze starter kit url: n/a */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOF #define LED_PIN GPIO_PIN_6 #define LED_STATE_ON 1 // Button #define BUTTON_PORT GPIOG #define BUTTON_PIN GPIO_PIN_8 #define BUTTON_STATE_ACTIVE 0 // USB Connect #define USB_CONNECT_PORT GPIOG #define USB_CONNECT_PIN GPIO_PIN_11 #define USB_CONNECT_STATE 0 // UART //#define UART_DEV USART1 //#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE //#define UART_GPIO_PORT GPIOA //#define UART_GPIO_AF GPIO_AF1_USART1 //#define UART_TX_PIN GPIO_PIN_9 //#define UART_RX_PIN GPIO_PIN_10 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32f1_clock_init(void) { RCC_ClkInitTypeDef clkinitstruct = {0}; RCC_OscInitTypeDef oscinitstruct = {0}; RCC_PeriphCLKInitTypeDef rccperiphclkinit = {0}; /* Enable HSE Oscillator and activate PLL with HSE as source */ oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; oscinitstruct.HSEState = RCC_HSE_ON; oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9; oscinitstruct.PLL.PLLState = RCC_PLL_ON; oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; HAL_RCC_OscConfig(&oscinitstruct); /* USB clock selection */ rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_USB; rccperiphclkinit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f1/boards/stm32f103ze_iar/board.mk ================================================ MCU_VARIANT = stm32f103xe CFLAGS += -DSTM32F103xE -DHSE_VALUE=8000000U # Linker LD_FILE_GCC = ${ST_CMSIS}/Source/Templates/gcc/linker/STM32F103XE_FLASH.ld LD_FILE_IAR = ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f103ze # flash target ROM bootloader flash: flash-jlink ================================================ FILE: hw/bsp/stm32f1/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f1xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_HP_IRQHandler(void) { tud_int_handler(0); } void USB_LP_IRQHandler(void) { tud_int_handler(0); } void USBWakeUp_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; void board_init(void) { board_stm32f1_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); #ifdef __HAL_RCC_GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE(); #endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // LED GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = LED_STATE_ON ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV // UART UART_CLK_EN(); GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle = (UART_HandleTypeDef) { .Instance = UART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); #endif #ifdef USB_CONNECT_PIN GPIO_InitStruct.Pin = USB_CONNECT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(USB_CONNECT_PORT, &GPIO_InitStruct); #endif // USB Pins // Configure USB DM and DP pins. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // USB Clock enable __HAL_RCC_USB_CLK_ENABLE(); } #ifdef USB_CONNECT_PIN void dcd_disconnect(uint8_t rhport) { (void)rhport; HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, (GPIO_PinState)(1 - USB_CONNECT_STATE)); } void dcd_connect(uint8_t rhport) { (void)rhport; HAL_GPIO_WritePin(USB_CONNECT_PORT, USB_CONNECT_PIN, (GPIO_PinState)USB_CONNECT_STATE); } #endif //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } #ifdef USE_FULL_ASSERT void assert_failed(const char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f1/family.cmake ================================================ include_guard() set(ST_FAMILY f1) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F1 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) endif () #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F1) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f1/family.mk ================================================ ST_FAMILY = f1 ST_CMSIS = hw/mcu/st/cmsis_device_${ST_FAMILY} ST_HAL_DRIVER = hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver include ${TOP}/${BOARD_PATH}/board.mk CPU_CORE ?= cortex-m3 # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F1 # GCC Flags CFLAGS_GCC += \ -flto \ # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ -specs=nosys.specs -specs=nano.specs # ------------------------ # All source paths should be relative to the top level. # ------------------------ SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ ${ST_CMSIS}/Source/Templates/system_stm32${ST_FAMILY}xx.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_cortex.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_rcc.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_rcc_ex.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_gpio.c \ ${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_uart.c INC += \ ${TOP}/${BOARD_PATH} \ ${TOP}/lib/CMSIS_5/CMSIS/Core/Include \ ${TOP}/${ST_CMSIS}/Include \ ${TOP}/${ST_HAL_DRIVER}/Inc # Startup SRC_S_GCC += ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s # flash target ROM bootloader: flash-dfu-util DFU_UTIL_OPTION = -a 0 --dfuse-address 0x08000000 ================================================ FILE: hw/bsp/stm32f1/stm32f1xx_hal_conf.h ================================================ /** ****************************************************************************** * @file USB_Device/HID_Standalone/Inc/stm32f1xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32f1xx_hal_conf.h. ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_CONF_H #define __STM32F1xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #if defined(USE_STM3210C_EVAL) #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ #else #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ #endif #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0x00U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Ethernet peripheral configuration ##################### */ /* Section 1 : Ethernet peripheral configuration */ /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ #define MAC_ADDR0 2U #define MAC_ADDR1 0U #define MAC_ADDR2 0U #define MAC_ADDR3 0U #define MAC_ADDR4 0U #define MAC_ADDR5 0U /* Definition of the Ethernet driver buffers size and count */ #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */ #define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ /* Section 2: PHY configuration section */ /* DP83848 PHY Address*/ #define DP83848_PHY_ADDRESS 0x01U /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY 0x000000FFU /* PHY Configuration delay */ #define PHY_CONFIG_DELAY 0x00000FFFU #define PHY_READ_TO 0x0000FFFFU #define PHY_WRITE_TO 0x0000FFFFU /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ #define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ #define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ #define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ #define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ #define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ #define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ #define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ #define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f1xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f1xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32f1xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f1xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f1xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CAN_LEGACY_MODULE_ENABLED #include "Legacy/stm32f1xx_hal_can_legacy.h" #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f1xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f1xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f1xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f1xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f1xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32f1xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32f1xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f1xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f1xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f1xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f1xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f1xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_PCCARD_MODULE_ENABLED #include "stm32f1xx_hal_pccard.h" #endif /* HAL_PCCARD_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32f1xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32f1xx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f1xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f1xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f1xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f1xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f1xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f1xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f1xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f1xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed(__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(const char* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F1xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f2xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f2/boards/stm32f207nucleo/board.cmake ================================================ set(MCU_VARIANT stm32f207xx) set(JLINK_DEVICE stm32f207zg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F207ZGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F207xx ) endfunction() ================================================ FILE: hw/bsp/stm32f2/boards/stm32f207nucleo/board.h ================================================ /* metadata: name: STM32 F207 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-f207zg.html */ #ifndef BOARD_H #define BOARD_H #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_14 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 120000000 * HCLK(Hz) = 120000000 * AHB Prescaler = 1 * APB1 Prescaler = 4 * APB2 Prescaler = 2 * HSE Frequency(Hz) = 8000000 * PLL_M = HSE_VALUE/1000000 * PLL_N = 240 * PLL_P = 2 * PLL_Q = 5 * VDD(V) = 3.3 * Flash Latency(WS) = 3 * @param None * @retval None */ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE / 1000000; RCC_OscInitStruct.PLL.PLLN = 240; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 5; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); } #endif ================================================ FILE: hw/bsp/stm32f2/boards/stm32f207nucleo/board.mk ================================================ MCU_VARIANT = stm32f207xx CFLAGS += -DSTM32F207xx # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/STM32F207ZGTx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32f207zg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f2/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f2xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ // enable all LED, Button, Uart, USB clock static void all_rcc_clk_enable(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D- __HAL_RCC_GPIOB_CLK_ENABLE(); // LED __HAL_RCC_GPIOC_CLK_ENABLE(); // Button } void board_init(void) { SystemClock_Config(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif all_rcc_clk_enable(); GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); board_led_write(false); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure VBUS Pin */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure ID pin */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Enable USB FS Clocks */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); #if CFG_TUD_ENABLED // Enable VBUS sense (B device) via pin PA9 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = true; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f2/family.cmake ================================================ include_guard() set(ST_FAMILY f2) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F2 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) endif () #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F2) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f2/family.mk ================================================ ST_FAMILY = f2 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m3 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F2 # mcu driver cause following warnings CFLAGS_GCC += \ -flto \ -Wno-error=sign-compare LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc \ $(TOP)/$(BOARD_PATH) # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_${MCU_VARIANT}.s # Linker LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf ================================================ FILE: hw/bsp/stm32f2/stm32f2xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32f2xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * *

© Copyright (c) 2017 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F2xx_HAL_CONF_H #define __STM32F2xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */ /* #define HAL_DMA_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ #define HAL_EXTI_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_UART_MODULE_ENABLED */ /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED #define HAL_PCD_MODULE_ENABLED /* #define HAL_HCD_MODULE_ENABLED */ /* ########################## HSE/HSI Values adaptation ##################### */ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S peripheral * This value is used by the I2S HAL module to compute the I2S clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the Internal oscillator in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define INSTRUCTION_CACHE_ENABLE 1U #define DATA_CACHE_ENABLE 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ /* Section 1 : Ethernet peripheral configuration */ /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ #define MAC_ADDR0 2U #define MAC_ADDR1 0U #define MAC_ADDR2 0U #define MAC_ADDR3 0U #define MAC_ADDR4 0U #define MAC_ADDR5 0U /* Definition of the Ethernet driver buffers size and count */ #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB 5U /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ #define ETH_TXBUFNB 5U /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ /* Section 2: PHY configuration section */ /* LAN8742A PHY Address*/ #define LAN8742A_PHY_ADDRESS 0x00U /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY 0x000000FFU /* PHY Configuration delay */ #define PHY_CONFIG_DELAY 0x00000FFFU #define PHY_READ_TO 0x0000FFFFU #define PHY_WRITE_TO 0x0000FFFFU /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ #define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ #define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ #define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f2xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f2xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32f2xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f2xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f2xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f2xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f2xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f2xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32f2xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f2xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32f2xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32f2xx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f2xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32f2xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32f2xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32f2xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_PCCARD_MODULE_ENABLED #include "stm32f2xx_hal_pccard.h" #endif /* HAL_PCCARD_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32f2xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f2xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f2xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f2xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f2xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32f2xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f2xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32f2xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f2xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f2xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f2xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f2xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f2xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f2xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f2xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f2xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32f2xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F2xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f3/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f3xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH _siccmram = LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f3/boards/stm32f303disco/board.cmake ================================================ set(MCU_VARIANT stm32f303xc) set(JLINK_DEVICE stm32f303vc) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F303VCTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F303xC ) endfunction() ================================================ FILE: hw/bsp/stm32f3/boards/stm32f303disco/board.h ================================================ /* metadata: name: STM32 F303 Discovery url: https://www.st.com/en/evaluation-tools/stm32f3discovery.html */ #ifndef BOARD_H #define BOARD_H #define LED_PORT GPIOE #define LED_PIN GPIO_PIN_9 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 72000000 * HCLK(Hz) = 72000000 * AHB Prescaler = 1 * APB1 Prescaler = 2 * APB2 Prescaler = 1 * HSE Frequency(Hz) = 8000000 * HSE PREDIV = 1 * PLLMUL = RCC_PLL_MUL9 (9) * Flash Latency(WS) = 2 * @param None * @retval None */ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Configures the USB clock */ HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); RCC_PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); /* Enable Power Clock */ __HAL_RCC_PWR_CLK_ENABLE(); } #endif ================================================ FILE: hw/bsp/stm32f3/boards/stm32f303disco/board.mk ================================================ MCU_VARIANT = stm32f303xc CFLAGS += \ -DSTM32F303xC \ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/STM32F303VCTx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32f303vc # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f3/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f3xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ // USB defaults to using interrupts 19, 20 and 42, however, this BSP sets the // SYSCFG_CFGR1.USB_IT_RMP bit remapping interrupts to 74, 75 and 76. // FIXME: Do all three need to be handled, or just the LP one? // USB high-priority interrupt (Channel 74): Triggered only by a correct // transfer event for isochronous and double-buffer bulk transfer to reach // the highest possible transfer rate. void USB_HP_IRQHandler(void) { tud_int_handler(0); } // USB low-priority interrupt (Channel 75): Triggered by all USB events // (Correct transfer, USB reset, etc.). The firmware has to check the // interrupt source before serving the interrupt. void USB_LP_IRQHandler(void) { tud_int_handler(0); } // USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB // Suspend mode. void USBWakeUp_RMP_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ void board_init(void) { SystemClock_Config(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif // Remap the USB interrupts __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_REMAPINTERRUPT_USB_ENABLE(); // LED __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); /* Configure USB DM and DP pins */ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF14_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Enable USB clock __HAL_RCC_USB_CLK_ENABLE(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { asm("bkpt 0"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f3/family.cmake ================================================ include_guard() set(ST_FAMILY f3) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m3 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F3 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) #target_compile_options(${BOARD_TARGET} PUBLIC) #target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F3) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f3/family.mk ================================================ ST_FAMILY = f3 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F3 # mcu driver cause following warnings CFLAGS_GCC += \ -flto \ -Wno-error=unused-parameter LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc \ $(TOP)/$(BOARD_PATH) # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_${MCU_VARIANT}.s # Linker LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf ================================================ FILE: hw/bsp/stm32f3/stm32f3xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32f3xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F3xx_HAL_CONF_H #define __STM32F3xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED /* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_HRTIM_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_OPAMP_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_PWR_MODULE_ENABLED */ #define HAL_RCC_MODULE_ENABLED /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SDADC_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* ########################## HSE/HSI Values adaptation ##################### */ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ /** * @brief In the following line adjust the External High Speed oscillator (HSE) Startup * Timeout value */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE (8000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup * Timeout value */ #if !defined (HSI_STARTUP_TIMEOUT) #define HSI_STARTUP_TIMEOUT (5000U) /*!< Time out for HSI start up */ #endif /* HSI_STARTUP_TIMEOUT */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE (40000U) #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ /** * @brief Time out for LSE start up value in ms. */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S peripheral * This value is used by the I2S HAL module to compute the I2S clock source * frequency, this source is inserted directly through I2S_CKIN pad. * - External clock generated through external PLL component on EVAL 303 (based on MCO or crystal) * - External clock not generated on EVAL 373 */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE (8000000U) /*!< Value of the External oscillator in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300U) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY ((uint32_t)(1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define INSTRUCTION_CACHE_ENABLE 0U #define DATA_CACHE_ENABLE 0U #define USE_SPI_CRC 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SDADC_REGISTER_CALLBACKS 0U /* SDADC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ #define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /*#define USE_FULL_ASSERT 1U*/ /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f3xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f3xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32f3xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f3xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f3xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f3xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f3xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CAN_LEGACY_MODULE_ENABLED #include "stm32f3xx_hal_can_legacy.h" #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32f3xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32f3xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f3xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f3xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f3xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32f3xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32f3xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32f3xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_PCCARD_MODULE_ENABLED #include "stm32f3xx_hal_pccard.h" #endif /* HAL_PCCARD_MODULE_ENABLED */ #ifdef HAL_HRTIM_MODULE_ENABLED #include "stm32f3xx_hal_hrtim.h" #endif /* HAL_HRTIM_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f3xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f3xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f3xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f3xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32f3xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f3xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f3xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f3xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SDADC_MODULE_ENABLED #include "stm32f3xx_hal_sdadc.h" #endif /* HAL_SDADC_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f3xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32f3xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f3xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f3xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32f3xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f3xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f3xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f3xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F3xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f4/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f4xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH _siccmram = LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/feather_stm32f405/board.cmake ================================================ set(MCU_VARIANT stm32f405xx) set(JLINK_DEVICE stm32f405rg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F405RGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/feather_stm32f405/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Adafruit Feather STM32F405 url: https://www.adafruit.com/product/4382 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART3 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_1, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // BUTTON .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_7, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // UART TX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Enable clocks for Uart __HAL_RCC_USART3_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/feather_stm32f405/board.mk ================================================ CFLAGS += -DSTM32F405xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F405RGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f405xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f405xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f405rg # flash target ROM bootloader flash: $(BUILD)/$(PROJECT).bin dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< ================================================ FILE: hw/bsp/stm32f4/boards/pyboardv11/STM32F405RGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F405RGTx Device with ** 1024KByte FLASH, 128KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH _siccmram = LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/pyboardv11/board.cmake ================================================ set(MCU_VARIANT stm32f405xx) set(JLINK_DEVICE stm32f405rg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F405RGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/pyboardv11/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Pyboard v1.1 url: https://www.adafruit.com/product/2390 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // BUTTON .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Enable clocks for Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/pyboardv11/board.mk ================================================ CFLAGS += -DSTM32F405xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F405RGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f405xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f405xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f405rg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f401blackpill/STM32F401VCTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F401VCTx Device with ** 256KByte FLASH, 64KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20010000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200;; /* required amount of heap */ _Min_Stack_Size = 0x400;; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f401blackpill/board.cmake ================================================ set(MCU_VARIANT stm32f401xc) set(JLINK_DEVICE stm32f401cc) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F401VCTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f401blackpill/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F401 Blackpill url: https://stm32-base.org/boards/STM32F401CCU6-WeAct-Black-Pill-V1.2 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Enable PA2 as the debug log UART #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define VBUS_SENSE_EN 0 static board_pindef_t board_pindef[] = { { // LED .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // BUTTON .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); // Enable clocks for Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f401blackpill/board.mk ================================================ CFLAGS += -DSTM32F401xC # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f401xc.s LD_FILE_GCC = $(BOARD_PATH)/STM32F401VCTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f401xc.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f401xc_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f401cc # flash target ROM bootloader flash: $(BUILD)/$(PROJECT).bin dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld ================================================ /** ****************************************************************************** * @file LinkerScript.ld * @author Auto-generated by STM32CubeIDE * @brief Linker script for STM32F407VETx Device from STM32F4 series * 512Kbytes FLASH * 64Kbytes CCMRAM * 128Kbytes RAM * * Set heap size, stack size and stack location according * to application requirements. * * Set memory bank area and size if external memory is used ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407blackvet/board.cmake ================================================ set(MCU_VARIANT stm32f407xx) set(JLINK_DEVICE stm32f407ve) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F407VETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F407xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407blackvet/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F407 Blackvet url: https://stm32-base.org/boards/STM32F407VET6-STM32-F4VE-V2.0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Enable PA2 as the debug log UART #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define VBUS_SENSE_EN 0 static board_pindef_t board_pindef[] = { { // LED .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // BUTTON .port = GPIOE, .pin_init = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/2000000; RCC_OscInitStruct.PLL.PLLN = 168; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Enable clocks for LED, Button, Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407blackvet/board.mk ================================================ CFLAGS += -DSTM32F407xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f407xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F407VETx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f407xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f407xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f407vg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407disco/STM32F407VGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F407VGTx Device with ** 1024KByte FLASH, 128KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x1000; /* required amount of heap */ _Min_Stack_Size = 0x4000; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH _siccmram = LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407disco/board.cmake ================================================ set(MCU_VARIANT stm32f407xx) set(JLINK_DEVICE stm32f407vg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F407VGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F407xx ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F407 Discovery url: https://www.st.com/en/evaluation-tools/stm32f4discovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // Enable PA2 as the debug log UART // It is not routed to the ST/Link on the Discovery board. #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // BUTTON .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Enable clocks Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f407disco/board.mk ================================================ CFLAGS += -DSTM32F407xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f407xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F407VGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f407xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f407xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f407vg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411blackpill/STM32F411CEUx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F411CEUx Device with ** 512KByte FLASH, 128KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200;; /* required amount of heap */ _Min_Stack_Size = 0x400;; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411blackpill/board.cmake ================================================ set(MCU_VARIANT stm32f411xe) set(JLINK_DEVICE stm32f411ce) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F411CEUx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F411xE HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411blackpill/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F411 Blackpill url: https://stm32-base.org/boards/STM32F411CEU6-WeAct-Black-Pill-V2.0 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define VBUS_SENSE_EN 0 static board_pindef_t board_pindef[] = { { // LED .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // BUTTON .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); // Enable clocks for Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411blackpill/board.mk ================================================ CFLAGS += -DSTM32F411xE -DHSE_VALUE=25000000 # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f411xe.s LD_FILE_GCC = $(BOARD_PATH)/STM32F411CEUx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f411xe.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f411xe_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f411ce # flash target ROM bootloader flash: $(BUILD)/$(PROJECT).bin dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411disco/STM32F411VETx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F411VETx Device with ** 512KByte FLASH, 128KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200;; /* required amount of heap */ _Min_Stack_Size = 0x400;; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411disco/board.cmake ================================================ set(MCU_VARIANT stm32f411xe) set(JLINK_DEVICE stm32f411ve) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F411VETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F411xE ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F411 Discovery url: https://www.st.com/en/evaluation-tools/32f411ediscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // BUTTON .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); // Enable clocks for UART __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f411disco/board.mk ================================================ CFLAGS += -DSTM32F411xE # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f411xe.s LD_FILE_GCC = $(BOARD_PATH)/STM32F411VETx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f411xe.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f411xe_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f411ve # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412disco/STM32F412ZGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F412ZGTx Device with ** 1024KByte FLASH, 256KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20040000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412disco/board.cmake ================================================ set(MCU_VARIANT stm32f412zx) set(JLINK_DEVICE stm32f412zg) # set(JLINK_OPTION "-USB 000771775987") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F412ZGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F412Zx ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F412 Discovery url: https://www.st.com/en/evaluation-tools/32f412gdiscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART Enable PA2 as the debug log UART #define UART_DEV USART2 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOE, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // BUTTON .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART2 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the * device is clocked below the maximum system frequency, to update the * voltage scaling value regarding system frequency refer to product * datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 200; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLR = 2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLLSAI output as USB clock source */ PeriphClkInitStruct.PLLI2S.PLLI2SM = 8; PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4; PeriphClkInitStruct.PLLI2S.PLLI2SN = 192; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48; PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ; PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC; PeriphClkInitStruct.PLLI2S.PLLI2SR = 7; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 * clocks dividers */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); // Enable clocks for Uart __HAL_RCC_USART2_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412disco/board.mk ================================================ CFLAGS += -DSTM32F412Zx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f412zx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F412ZGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f412zx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f412zx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f412zg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412nucleo/STM32F412ZGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F412ZGTx Device with ** 1024KByte FLASH, 256KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20040000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412nucleo/board.cmake ================================================ set(MCU_VARIANT stm32f412zx) set(JLINK_DEVICE stm32f412zg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F412ZGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F412Zx BOARD_TUD_RHPORT=0 ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F412 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-f412zg.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART Enable for STLink VCOM #define UART_DEV USART3 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // BUTTON .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the * device is clocked below the maximum system frequency, to update the * voltage scaling value regarding system frequency refer to product * datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 200; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLR = 2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLLSAI output as USB clock source */ PeriphClkInitStruct.PLLI2S.PLLI2SM = 8; PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4; PeriphClkInitStruct.PLLI2S.PLLI2SN = 192; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48; PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ; PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC; PeriphClkInitStruct.PLLI2S.PLLI2SR = 7; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 * clocks dividers */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); // Enable clocks for Uart __HAL_RCC_USART3_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f412nucleo/board.mk ================================================ CFLAGS += -DSTM32F412Zx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f412zx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F412ZGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f412zx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f412zx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f412zg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for NUCLEO-F439ZI Board embedding STM32F439ZITx Device from stm32f4 series ** 2048Kbytes FLASH ** 64Kbytes CCMRAM ** 192Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2021 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH _siccmram = LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .ccmram : { . = ALIGN(4); _sccmram = .; /* create a global symbol at ccmram start */ *(.ccmram) *(.ccmram*) . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ } >CCMRAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f4/boards/stm32f439nucleo/board.cmake ================================================ set(MCU_VARIANT stm32f439xx) set(JLINK_DEVICE stm32f439zi) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F439ZITX_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F439xx BOARD_TUD_RHPORT=0 ) endfunction() ================================================ FILE: hw/bsp/stm32f4/boards/stm32f439nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F439 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-f439zi.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART Enable for STLink VCOM #define UART_DEV USART3 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define VBUS_SENSE_EN 1 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // BUTTON .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the * device is clocked below the maximum system frequency, to update the * voltage scaling value regarding system frequency refer to product * datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 * clocks dividers */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Enable clocks Uart __HAL_RCC_USART3_CLK_ENABLE(); } static inline void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk ================================================ CFLAGS += -DSTM32F439xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f439xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32F439ZITX_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32f439xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32f439xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32f439zi # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f4xx_hal.h" #include "bsp/board_api.h" typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } void OTG_HS_IRQHandler(void) { tusb_int_handler(1, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16 } }; #endif void board_init(void) { board_clock_init(); //SystemCoreClockUpdate(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); #ifdef __HAL_RCC_GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE(); #endif __HAL_RCC_GPIOH_CLK_ENABLE(); #ifdef __HAL_RCC_GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE(); #endif for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif board_led_write(false); #ifdef UART_DEV HAL_UART_Init(&UartHandle); #endif //------------- USB FS -------------// GPIO_InitTypeDef GPIO_InitStruct; /* Configure USB D+ D- Pins */ GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure VBUS Pin */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* ID Pin */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Enable USB OTG clock __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); //------------- USB HS -------------// #ifdef __HAL_RCC_USB_OTG_HS_CLK_ENABLE GPIO_InitStruct.Pin = GPIO_PIN_14 | GPIO_PIN_15; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure VBUS Pin */ GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* ID Pin */ GPIO_InitStruct.Pin = GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Enable USB OTG clock __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); #endif #ifdef STM32F412Zx /* Configure POWER_SWITCH IO pin */ __HAL_RCC_GPIOG_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); #endif #if CFG_TUD_ENABLED tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(BOARD_TUD_RHPORT, TUD_CFGID_DWC2, &cfg); board_vbus_set(BOARD_TUD_RHPORT, false); #endif #if CFG_TUH_ENABLED board_vbus_set(BOARD_TUH_RHPORT, true); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t *stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t *id32 = (uint32_t *) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f4/family.cmake ================================================ include_guard() set(ST_FAMILY f4) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F4 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) # Most F7 does not has built-in HS PHY set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F4) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f4/family.mk ================================================ UF2_FAMILY_ID = 0x57755a57 ST_FAMILY = f4 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 # Determine RHPORT_DEVICE_SPEED if not defined ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # Determine RHPORT_HOST_SPEED if not defined ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c INC += \ $(TOP)/hw/bsp/stm32$(ST_FAMILY) \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f4/stm32f4xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32f4xx_hal_conf_template.h * @author MCD Application Team * @brief HAL configuration file ****************************************************************************** * @attention * *

© Copyright (c) 2017 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F4xx_HAL_CONF_H #define __STM32F4xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED /* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ #define HAL_FLASH_MODULE_ENABLED /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED /* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ /* #define HAL_DSI_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED /* #define HAL_QSPI_MODULE_ENABLED */ #define HAL_RCC_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SAI_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ // #define HAL_SPI_MODULE_ENABLED /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_FMPI2C_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ /* ########################## HSE/HSI Values adaptation ##################### */ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE (32000U) #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S peripheral * This value is used by the I2S HAL module to compute the I2S clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300U) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define INSTRUCTION_CACHE_ENABLE 1U #define DATA_CACHE_ENABLE 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Ethernet peripheral configuration ##################### */ /* Section 1 : Ethernet peripheral configuration */ /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ #define MAC_ADDR0 2U #define MAC_ADDR1 0U #define MAC_ADDR2 0U #define MAC_ADDR3 0U #define MAC_ADDR4 0U #define MAC_ADDR5 0U /* Definition of the Ethernet driver buffers size and count */ #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ #define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ /* Section 2: PHY configuration section */ /* DP83848 PHY Address*/ #define DP83848_PHY_ADDRESS 0x01U /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY 0x000000FFU /* PHY Configuration delay */ #define PHY_CONFIG_DELAY 0x00000FFFU #define PHY_READ_TO 0x0000FFFFU #define PHY_WRITE_TO 0x0000FFFFU /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ #define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ #define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ #define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ #define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ #define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ #define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ #define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ #define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f4xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f4xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32f4xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f4xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f4xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f4xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f4xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CAN_LEGACY_MODULE_ENABLED #include "stm32f4xx_hal_can_legacy.h" #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f4xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32f4xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32f4xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f4xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32f4xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32f4xx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f4xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32f4xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32f4xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32f4xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_PCCARD_MODULE_ENABLED #include "stm32f4xx_hal_pccard.h" #endif /* HAL_PCCARD_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32f4xx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32f4xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f4xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32f4xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f4xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f4xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32f4xx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f4xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32f4xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f4xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32f4xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32f4xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f4xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f4xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f4xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f4xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f4xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f4xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f4xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f4xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32f4xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_DSI_MODULE_ENABLED #include "stm32f4xx_hal_dsi.h" #endif /* HAL_DSI_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32f4xx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32f4xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_FMPI2C_MODULE_ENABLED #include "stm32f4xx_hal_fmpi2c.h" #endif /* HAL_FMPI2C_MODULE_ENABLED */ #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32f4xx_hal_spdifrx.h" #endif /* HAL_SPDIFRX_MODULE_ENABLED */ #ifdef HAL_DFSDM_MODULE_ENABLED #include "stm32f4xx_hal_dfsdm.h" #endif /* HAL_DFSDM_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32f4xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED #include "stm32f4xx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F4xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32f7/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32f7xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stlinkv3mini/board.cmake ================================================ set(MCU_VARIANT stm32f723xx) set(JLINK_DEVICE stm32f723xx) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F723xE_FLASH.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F723xx HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stlinkv3mini/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Stlink-v3 mini url: https://www.st.com/en/development-tools/stlink-v3mini.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART6 #define UART_CLK_EN __HAL_RCC_USART6_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_UART_TX 1 #define PINID_UART_RX 2 //#define PINID_VBUS0_EN 4 //#define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF8_USART6 }, .active_state = 0 }, { // UART RX .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF8_USART6 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stlinkv3mini/board.mk ================================================ MCU_VARIANT = stm32f723xx # Only OTG-HS has a connector on this board RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 1 PORT ?= 1 SPEED ?= high CFLAGS += \ -DSTM32F723xx \ -DHSE_VALUE=25000000 \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F723xE_FLASH.ld # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f7/boards/stm32f723disco/STM32F723xE_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F723xE Device with ** 512KByte FLASH, 256KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20040000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x460; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stm32f723disco/board.cmake ================================================ set(MCU_VARIANT stm32f723xx) set(JLINK_DEVICE stm32f723ie) #set(JLINK_OPTION "-USB 000776606156") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F723xE_FLASH.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) # For Hardware test: device default to PORT 0, Host to port 1 if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F723xx HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stm32f723disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F723 Discovery url: https://www.st.com/en/evaluation-tools/32f723ediscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART6 #define UART_CLK_EN __HAL_RCC_USART6_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 1 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 #define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_1, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF8_USART6 }, .active_state = 0 }, { // UART RX .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_7, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF8_USART6 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOG, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_OUTPUT_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // VBUS1 EN .port = GPIOH, .pin_init = { .Pin = GPIO_PIN_12, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE / 1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { board_pindef_t* pindef = &board_pindef[rhport ? PINID_VBUS1_EN : PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stm32f723disco/board.mk ================================================ MCU_VARIANT = stm32f723xx # For Hardware test: device default to PORT 0, Host to port 1 RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 1 CFLAGS += \ -DSTM32F723xx \ -DHSE_VALUE=25000000 \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F723xE_FLASH.ld # flash target using on-board stlink flash: flash-stlink # For flash-jlink target JLINK_DEVICE = stm32f723ie ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746disco/STM32F746ZGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F746ZGTx Device with ** 1024KByte FLASH, 320KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20050000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x460; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746disco/board.cmake ================================================ set(MCU_VARIANT stm32f746xx) set(JLINK_DEVICE stm32f746xx) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F746ZGTx_FLASH.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F746xx HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F746 Discovery url: https://www.st.com/en/evaluation-tools/32f746gdiscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 1 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 //#define PINID_VBUS0_EN 4 //#define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOI, .pin_init = { .Pin = GPIO_PIN_1, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOI, .pin_init = { .Pin = GPIO_PIN_11, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART1 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_7, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART1 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746disco/board.mk ================================================ MCU_VARIANT = stm32f746xx RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 PORT ?= 1 SPEED ?= high CFLAGS += \ -DSTM32F746xx \ -DHSE_VALUE=25000000 # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F746ZGTx_FLASH.ld # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746nucleo/STM32F746ZGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F746ZGTx Device with ** 1024KByte FLASH, 320KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20050000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x460; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746nucleo/board.cmake ================================================ set(MCU_VARIANT stm32f746xx) set(JLINK_DEVICE stm32f746xx) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F746ZGTx_FLASH.ld) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F746xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F746 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-f746zg.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 //#define PINID_VBUS0_EN 4 //#define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, }; static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; HAL_RCC_OscConfig(&RCC_OscInitStruct); // TODO need to enable usb clock source /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stm32f746nucleo/board.mk ================================================ MCU_VARIANT = stm32f746xx RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 PORT ?= 0 SPEED ?= full CFLAGS += \ -DSTM32F746xx \ -DHSE_VALUE=8000000 # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F746ZGTx_FLASH.ld # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f7/boards/stm32f767nucleo/STM32F767ZITx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F767ZITx Device with ** 2048KByte FLASH, 512KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20080000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stm32f767nucleo/board.cmake ================================================ set(MCU_VARIANT stm32f767xx) set(JLINK_DEVICE stm32f767zi) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F767ZITx_FLASH.ld) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F767xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stm32f767nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F767 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-f767zi.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 //#define PINID_VBUS0_EN 4 //#define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; RCC_OscInitStruct.PLL.PLLR = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stm32f767nucleo/board.mk ================================================ MCU_VARIANT = stm32f767xx RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 PORT ?= 0 SPEED ?= full CFLAGS += \ -DSTM32F767xx \ -DHSE_VALUE=8000000 \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F767ZITx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32f767zi # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f7/boards/stm32f769disco/STM32F769ZITx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32F767ZITx Device with ** 2048KByte FLASH, 512KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20080000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32f7/boards/stm32f769disco/board.cmake ================================================ set(MCU_VARIANT stm32f769xx) set(JLINK_DEVICE stm32f769ni) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F769ZITx_FLASH.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F769xx HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32f7/boards/stm32f769disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 F769 Discovery url: https://www.st.com/en/evaluation-tools/32f769idiscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 //#define PINID_VBUS0_EN 4 //#define PINID_VBUS1_EN 5 static board_pindef_t board_pindef[] = { { // LED .port = GPIOJ, .pin_init = { .Pin = GPIO_PIN_12, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART1 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART1 }, .active_state = 0 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; RCC_OscInitStruct.PLL.PLLR = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the OverDrive to reach the 216 MHz Frequency */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); UART_CLK_EN(); } static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32f7/boards/stm32f769disco/board.mk ================================================ MCU_VARIANT = stm32f769xx # Only OTG-HS has a connector on this board RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 1 PORT ?= 1 SPEED ?= high CFLAGS += \ -DSTM32F769xx \ -DHSE_VALUE=25000000 \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F769ZITx_FLASH.ld JLINK_DEVICE = stm32f769ni # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32f7/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 William D. Jones (thor0505@comcast.net), * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de), * Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32f7xx_hal.h" #include "bsp/board_api.h" typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16, } }; #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port void OTG_HS_IRQHandler(void) { tusb_int_handler(1, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ void board_init(void) { SCB_EnableICache(); HAL_Init(); board_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); // ULPI NXT __HAL_RCC_GPIOI_CLK_ENABLE(); // ULPI NXT #ifdef __HAL_RCC_GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE(); #endif for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #ifdef UART_DEV HAL_UART_Init(&UartHandle); #endif GPIO_InitTypeDef GPIO_InitStruct; //------------- rhport0: OTG_FS -------------// /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure OTG-FS ID pin */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" #endif /* Enable USB FS Clocks */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #if OTG_FS_VBUS_SENSE /* Configure VBUS Pin */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif //------------- rhport1: OTG_HS -------------// #ifdef USB_HS_PHYC // MCU with built-in HS PHY such as F723, F733, F730 /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_14 | GPIO_PIN_15); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure OTG-HS ID pin */ GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Enable PHYC Clocks */ __HAL_RCC_OTGPHYC_CLK_ENABLE(); #else // MCU with external ULPI PHY /* ULPI CLK */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* ULPI D0 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* ULPI D1 D2 D3 D4 D5 D6 D7 */ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* ULPI STP */ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* NXT */ GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /* ULPI DIR */ GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); #endif // USB_HS_PHYC // Enable USB HS & ULPI Clocks __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif // Turn off device vbus #if CFG_TUD_ENABLED board_vbus_set(BOARD_TUD_RHPORT, false); #endif // Turn on host vbus #if CFG_TUH_ENABLED board_vbus_set(BOARD_TUH_RHPORT, true); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { #ifdef UART_DEV int count = 0; // clear overrun error if any if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE)) { __HAL_UART_CLEAR_FLAG(&UartHandle, UART_CLEAR_OREF); } for (int i = 0; i < len; i++) { if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE)) { buf[i] = (uint8_t) UartHandle.Instance->RDR; count++; } else { break; } } return count; #else (void) buf; (void) len; return 0; #endif } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return -1; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #elif CFG_TUSB_OS == OPT_OS_THREADX // Keep HAL_GetTick() working for HAL functions called from board_init() void osal_threadx_tick_cb(void) { HAL_IncTick(); } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32f7/family.cmake ================================================ include_guard() set(ST_FAMILY f7) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m7-fpsp CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F7 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) # Most F7 does not has built-in HS PHY set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32F7) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32f7/family.mk ================================================ UF2_FAMILY_ID = 0x53b80f00 ST_FAMILY = f7 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m7-fpsp # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 # Determine RHPORT_DEVICE_SPEED if not defined ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # Determine RHPORT_HOST_SPEED if not defined ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ #ifeq ($(PORT), 1) # ifeq ($(SPEED), high) # CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED # $(info "Using OTG_HS in HighSpeed mode") # else # CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED # $(info "Using OTG_HS in FullSpeed mode") # endif #else # CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED # $(info "Using OTG_FS") #endif # GCC Flags CFLAGS_GCC += \ -flto \ # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32f7/stm32f7xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32f7xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F7xx_HAL_CONF_H #define __STM32F7xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED /* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ #define HAL_FLASH_MODULE_ENABLED /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED /* #define HAL_QSPI_MODULE_ENABLED */ #define HAL_RCC_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SAI_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */ /* #define HAL_MDIOS_MODULE_ENABLED */ /* ########################## HSE/HSI Values adaptation ##################### */ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S peripheral * This value is used by the I2S HAL module to compute the I2S clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define ART_ACCELERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1 */ /* ################## Ethernet peripheral configuration for NUCLEO 144 board ##################### */ /* Section 1 : Ethernet peripheral configuration */ /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ #define MAC_ADDR0 2U #define MAC_ADDR1 0U #define MAC_ADDR2 0U #define MAC_ADDR3 0U #define MAC_ADDR4 0U #define MAC_ADDR5 0U /* Definition of the Ethernet driver buffers size and count */ #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB ((uint32_t)5) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ #define ETH_TXBUFNB ((uint32_t)5) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ /* Section 2: PHY configuration section */ /* LAN8742A PHY Address*/ #define LAN8742A_PHY_ADDRESS 0x00 /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY ((uint32_t)0x00000FFF) /* PHY Configuration delay */ #define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) #define PHY_READ_TO ((uint32_t)0x0000FFFF) #define PHY_WRITE_TO ((uint32_t)0x0000FFFF) /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */ #define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ #define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */ #define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32f7xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f7xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32f7xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32f7xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32f7xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32f7xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CAN_LEGACY_MODULE_ENABLED #include "stm32f7xx_hal_can_legacy.h" #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32f7xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32f7xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32f7xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32f7xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32f7xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32f7xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32f7xx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32f7xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32f7xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32f7xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32f7xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32f7xx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32f7xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32f7xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32f7xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32f7xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32f7xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32f7xx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32f7xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32f7xx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32f7xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32f7xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32f7xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32f7xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32f7xx_hal_spdifrx.h" #endif /* HAL_SPDIFRX_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32f7xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32f7xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32f7xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32f7xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32f7xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32f7xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32f7xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32f7xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32f7xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_DFSDM_MODULE_ENABLED #include "stm32f7xx_hal_dfsdm.h" #endif /* HAL_DFSDM_MODULE_ENABLED */ #ifdef HAL_DSI_MODULE_ENABLED #include "stm32f7xx_hal_dsi.h" #endif /* HAL_DSI_MODULE_ENABLED */ #ifdef HAL_JPEG_MODULE_ENABLED #include "stm32f7xx_hal_jpeg.h" #endif /* HAL_JPEG_MODULE_ENABLED */ #ifdef HAL_MDIOS_MODULE_ENABLED #include "stm32f7xx_hal_mdios.h" #endif /* HAL_MDIOS_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32F7xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32g0xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<
© COPYRIGHT(c) 2019 STMicroelectronics
** ** 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. Neither the name of STMicroelectronics nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.cmake ================================================ set(MCU_VARIANT stm32g0b1xx) set(JLINK_DEVICE stm32g0b1re) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32G0B1RETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32G0B1xx ) endfunction() ================================================ FILE: hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * Copyright (c) 2023, HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 G0B1 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // G0B1RE Nucleo does not has usb connection. We need to manually connect // - PA12 for D+, CN10.12 // - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 0 // UART Enable for STLink VCOM #define UART_DEV USART2 #define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF1_USART2 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ #if 1 // Clock configure for STM32G0B1RE Nucleo static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 8; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); // Configure CRS clock source __HAL_RCC_CRS_CLK_ENABLE(); RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000); RCC_CRSInitStruct.ErrorLimitValue = 34; RCC_CRSInitStruct.HSI48CalibrationValue = 32; HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); /* Select HSI48 as USB clock source */ RCC_PeriphCLKInitTypeDef usb_clk = {0 }; usb_clk.PeriphClockSelection = RCC_PERIPHCLK_USB; usb_clk.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&usb_clk); // Enable HSI48 RCC_OscInitTypeDef osc_hsi48 = {0}; osc_hsi48.OscillatorType = RCC_OSCILLATORTYPE_HSI48; osc_hsi48.HSI48State = RCC_HSI48_ON; HAL_RCC_OscConfig(&osc_hsi48); } #else // Clock configure for STM32G0 nucleo with B0 mcu variant for someone that is skilled enough // to rework and solder the B0 chip. Note: SB17 may need to be soldered as well (check user manual) static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 12; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select HSI48 as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); } #endif #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.mk ================================================ CFLAGS += \ -DSTM32G0B1xx # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32g0b1xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32G0B1RETx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32g0b1xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32g0b1xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32g0b1re ================================================ FILE: hw/bsp/stm32g0/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2023 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32g0xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_UCPD1_2_IRQHandler(void) { tusb_int_handler(0, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV UART_HandleTypeDef UartHandle; #endif void board_init(void) { HAL_Init(); // required for HAL_RCC_Osc TODO check with freeRTOS board_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_UCPD1_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); board_led_write(false); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV UART_CLK_EN(); // UART GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle = (UART_HandleTypeDef){ .Instance = UART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16, .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT }; HAL_UART_Init(&UartHandle); #endif // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_USB_CLK_ENABLE(); /* Enable VDDUSB */ HAL_PWREx_EnableVddUSB(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; HAL_IncTick(); } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32g0/family.cmake ================================================ include_guard() set(ST_FAMILY g0) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32G0 CACHE INTERNAL "") set(OPENOCD_OPTION "-f interface/stlink.cfg -f target/stm32g0x.cfg") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32G0) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${TOP}/src/portable/st/typec/typec_stm32.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_stlink(${TARGET}) #family_flash_openocd(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32g0/family.mk ================================================ ST_FAMILY = g0 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32G0 # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32g0/stm32g0xx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32g0xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * * Copyright (c) 2018-2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32G0xx_HAL_CONF_H #define STM32G0xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_FDCAN_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /* ########################## Register Callbacks selection ############################## */ /** * @brief This is the list of modules where register callback can be used */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0u #define USE_HAL_CEC_REGISTER_CALLBACKS 0u #define USE_HAL_COMP_REGISTER_CALLBACKS 0u #define USE_HAL_CRYP_REGISTER_CALLBACKS 0u #define USE_HAL_DAC_REGISTER_CALLBACKS 0u #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0u #define USE_HAL_HCD_REGISTER_CALLBACKS 0u #define USE_HAL_I2C_REGISTER_CALLBACKS 0u #define USE_HAL_I2S_REGISTER_CALLBACKS 0u #define USE_HAL_IRDA_REGISTER_CALLBACKS 0u #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u #define USE_HAL_PCD_REGISTER_CALLBACKS 0u #define USE_HAL_RNG_REGISTER_CALLBACKS 0u #define USE_HAL_RTC_REGISTER_CALLBACKS 0u #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u #define USE_HAL_SPI_REGISTER_CALLBACKS 0u #define USE_HAL_TIM_REGISTER_CALLBACKS 0u #define USE_HAL_UART_REGISTER_CALLBACKS 0u #define USE_HAL_USART_REGISTER_CALLBACKS 0u #define USE_HAL_WWDG_REGISTER_CALLBACKS 0u /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE (8000000UL) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ #if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx) /** * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ #endif /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE (32768UL) /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S1 peripheral * This value is used by the RCC HAL module to compute the I2S1 clock source * frequency. */ #if !defined (EXTERNAL_I2S1_CLOCK_VALUE) #define EXTERNAL_I2S1_CLOCK_VALUE (48000UL) /*!< Value of the I2S1 External clock source in Hz*/ #endif /* EXTERNAL_I2S1_CLOCK_VALUE */ #if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx) /** * @brief External clock source for I2S2 peripheral * This value is used by the RCC HAL module to compute the I2S2 clock source * frequency. */ #if !defined (EXTERNAL_I2S2_CLOCK_VALUE) #define EXTERNAL_I2S2_CLOCK_VALUE 48000U /*!< Value of the I2S2 External clock source in Hz*/ #endif /* EXTERNAL_I2S2_CLOCK_VALUE */ #endif /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define INSTRUCTION_CACHE_ENABLE 1U /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* ################## CRYP peripheral configuration ########################## */ #define USE_HAL_CRYP_SUSPEND_RESUME 1U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include modules header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32g0xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32g0xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32g0xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32g0xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32g0xx_hal_adc.h" #include "stm32g0xx_hal_adc_ex.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32g0xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32g0xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32g0xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32g0xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32g0xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32g0xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32g0xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32g0xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32g0xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32g0xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32g0xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32g0xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32g0xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32g0xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32g0xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32g0xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32g0xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32g0xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32g0xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32g0xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32g0xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32g0xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32g0xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32g0xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32g0xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for functions parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32G0xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32g4xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<
© COPYRIGHT(c) 2020 STMicroelectronics
** ** 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. Neither the name of STMicroelectronics nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x1000 ; /* required amount of heap */ _Min_Stack_Size = 0x1000 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32g4/boards/b_g474e_dpow1/board.cmake ================================================ set(MCU_VARIANT stm32g474xx) set(JLINK_DEVICE stm32g474re) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32G474RETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32G474xx ) endfunction() ================================================ FILE: hw/bsp/stm32g4/boards/b_g474e_dpow1/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 B-G474E-DPOW1 Discovery kit url: https://www.st.com/en/evaluation-tools/b-g474e-dpow1.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // G474RE Nucleo does not has usb connection. We need to manually connect // - PA12 for D+, CN10.12 // - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 0 // UART Enable for STLink VCOM #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE #define UART_GPIO_PORT GPIOC #define UART_GPIO_AF GPIO_AF7_USART3 #define UART_TX_PIN GPIO_PIN_10 #define UART_RX_PIN GPIO_PIN_11 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ // CPU Frequency (Core Clock) is 170 MHz static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); /* Activate PLL with HSI as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; RCC_OscInitStruct.PLL.PLLN = 85; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV10; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); //------------- HSI48 and CRS for USB -------------// RCC_OscInitTypeDef osc_hsi48 = {0}; osc_hsi48.OscillatorType = RCC_OSCILLATORTYPE_HSI48; osc_hsi48.HSI48State = RCC_HSI48_ON; osc_hsi48.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&osc_hsi48); /*Enable CRS Clock*/ RCC_CRSInitTypeDef RCC_CRSInitStruct= {0}; __HAL_RCC_CRS_CLK_ENABLE(); /* Default Synchro Signal division factor (not divided) */ RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; /* HSI48 is synchronized with USB SOF at 1KHz rate */ RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; /* Set the TRIM[5:0] to the default value */ RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; /* Start automatic synchronization */ HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); } static inline void board_vbus_sense_init(void) { // Enable VBUS sense (B device) via pin PA9 } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32g4/boards/b_g474e_dpow1/board.mk ================================================ MCU_VARIANT = stm32g474xx CFLAGS += \ -DSTM32G474xx \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32G474RETx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32g474re ================================================ FILE: hw/bsp/stm32g4/boards/b_g474e_dpow1/cubemx/b_g474e_dpow1.ioc ================================================ #MicroXplorer Configuration settings - do not modify CAD.formats= CAD.pinconfig= CAD.provider= Dma.Request0=UCPD1_RX Dma.Request1=UCPD1_TX Dma.RequestsNb=2 Dma.UCPD1_RX.0.Direction=DMA_PERIPH_TO_MEMORY Dma.UCPD1_RX.0.EventEnable=DISABLE Dma.UCPD1_RX.0.Instance=DMA1_Channel1 Dma.UCPD1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.UCPD1_RX.0.MemInc=DMA_MINC_ENABLE Dma.UCPD1_RX.0.Mode=DMA_NORMAL Dma.UCPD1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.UCPD1_RX.0.PeriphInc=DMA_PINC_DISABLE Dma.UCPD1_RX.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.UCPD1_RX.0.Priority=DMA_PRIORITY_HIGH Dma.UCPD1_RX.0.RequestNumber=1 Dma.UCPD1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.UCPD1_RX.0.SignalID=NONE Dma.UCPD1_RX.0.SyncEnable=DISABLE Dma.UCPD1_RX.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.UCPD1_RX.0.SyncRequestNumber=1 Dma.UCPD1_RX.0.SyncSignalID=NONE Dma.UCPD1_TX.1.Direction=DMA_MEMORY_TO_PERIPH Dma.UCPD1_TX.1.EventEnable=DISABLE Dma.UCPD1_TX.1.Instance=DMA1_Channel2 Dma.UCPD1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.UCPD1_TX.1.MemInc=DMA_MINC_ENABLE Dma.UCPD1_TX.1.Mode=DMA_NORMAL Dma.UCPD1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.UCPD1_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.UCPD1_TX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.UCPD1_TX.1.Priority=DMA_PRIORITY_HIGH Dma.UCPD1_TX.1.RequestNumber=1 Dma.UCPD1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.UCPD1_TX.1.SignalID=NONE Dma.UCPD1_TX.1.SyncEnable=DISABLE Dma.UCPD1_TX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.UCPD1_TX.1.SyncRequestNumber=1 Dma.UCPD1_TX.1.SyncSignalID=NONE File.Version=6 GPIO.groupedBy=Group By Peripherals KeepUserPlacement=true Mcu.CPN=STM32G474RET3 Mcu.Family=STM32G4 Mcu.IP0=DMA Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS Mcu.IP4=UCPD1 Mcu.IP5=USART3 Mcu.IPNb=6 Mcu.Name=STM32G474R(B-C-E)Tx Mcu.Package=LQFP64 Mcu.Pin0=PC10 Mcu.Pin1=PC11 Mcu.Pin2=PB4 Mcu.Pin3=PB6 Mcu.Pin4=VP_SYS_VS_Systick Mcu.Pin5=VP_SYS_VS_DBSignals Mcu.PinsNb=6 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32G474RETx MxCube.Version=6.8.1 MxDb.Version=DB.6.0.81 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:false\:true\:false\:false NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:false\:true\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:false\:true\:false\:false PB4.Mode=Sink_AllSignals PB4.Signal=UCPD1_CC2 PB6.Mode=Sink_AllSignals PB6.Signal=UCPD1_CC1 PC10.GPIOParameters=GPIO_PuPd PC10.GPIO_PuPd=GPIO_PULLUP PC10.Mode=Asynchronous PC10.Signal=USART3_TX PC11.GPIOParameters=GPIO_PuPd PC11.GPIO_PuPd=GPIO_PULLUP PC11.Mode=Asynchronous PC11.Signal=USART3_RX PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32G474RETx ProjectManager.FirmwarePackage=STM32Cube FW_G4 V1.5.1 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=2 ProjectManager.MainLocation=Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain= ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=b_g474e_dpow1.ioc ProjectManager.ProjectName=b_g474e_dpow1 ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation=Src ProjectManager.UnderRoot=false ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART3_UART_Init-USART3-false-HAL-true,5-MX_UCPD1_Init-UCPD1-false-LL-true RCC.ADC12Freq_Value=150000000 RCC.ADC345Freq_Value=150000000 RCC.AHBFreq_Value=150000000 RCC.APB1Freq_Value=150000000 RCC.APB1TimFreq_Value=150000000 RCC.APB2Freq_Value=150000000 RCC.APB2TimFreq_Value=150000000 RCC.CRSFreq_Value=48000000 RCC.CortexFreq_Value=150000000 RCC.EXTERNAL_CLOCK_VALUE=12288000 RCC.FCLKCortexFreq_Value=150000000 RCC.FDCANFreq_Value=150000000 RCC.FamilyName=M RCC.HCLKFreq_Value=150000000 RCC.HRTIM1Freq_Value=150000000 RCC.HSE_VALUE=24000000 RCC.HSI48_VALUE=48000000 RCC.HSI_VALUE=16000000 RCC.I2C1Freq_Value=150000000 RCC.I2C2Freq_Value=150000000 RCC.I2C3Freq_Value=150000000 RCC.I2C4Freq_Value=150000000 RCC.I2SFreq_Value=150000000 RCC.IPParameters=ADC12Freq_Value,ADC345Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,EXTERNAL_CLOCK_VALUE,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HRTIM1Freq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LPTIM1Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,PLLM,PLLN,PLLPoutputFreq_Value,PLLQ,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PWRFreq_Value,QSPIFreq_Value,RNGFreq_Value,SAI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value RCC.LPTIM1Freq_Value=150000000 RCC.LPUART1Freq_Value=150000000 RCC.LSCOPinFreq_Value=32000 RCC.LSE_VALUE=32768 RCC.LSI_VALUE=32000 RCC.MCO1PinFreq_Value=16000000 RCC.PLLM=RCC_PLLM_DIV4 RCC.PLLN=75 RCC.PLLPoutputFreq_Value=150000000 RCC.PLLQ=RCC_PLLQ_DIV4 RCC.PLLQoutputFreq_Value=75000000 RCC.PLLRCLKFreq_Value=150000000 RCC.PWRFreq_Value=150000000 RCC.QSPIFreq_Value=150000000 RCC.RNGFreq_Value=75000000 RCC.SAI1Freq_Value=150000000 RCC.SYSCLKFreq_VALUE=150000000 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.UART4Freq_Value=150000000 RCC.UART5Freq_Value=150000000 RCC.USART1Freq_Value=150000000 RCC.USART2Freq_Value=150000000 RCC.USART3Freq_Value=150000000 RCC.USBFreq_Value=75000000 RCC.VCOInputFreq_Value=4000000 RCC.VCOOutputFreq_Value=300000000 USART3.AutoBaudRateEnableParam=UART_ADVFEATURE_AUTOBAUDRATE_DISABLE USART3.BaudRate=115200 USART3.DMADisableonRxErrorParam=ADVFEATURE_DMA_ENABLEONRXERROR USART3.DataInvertParam=ADVFEATURE_DATAINV_DISABLE USART3.IPParameters=BaudRate,WordLength,Parity,StopBits,Mode,OverSampling,OneBitSampling,AutoBaudRateEnableParam,TxPinLevelInvertParam,RxPinLevelInvertParam,DataInvertParam,SwapParam,OverrunDisableParam,DMADisableonRxErrorParam,MSBFirstParam,VirtualMode-Asynchronous USART3.MSBFirstParam=ADVFEATURE_MSBFIRST_DISABLE USART3.Mode=MODE_TX_RX USART3.OneBitSampling=UART_ONE_BIT_SAMPLE_DISABLE USART3.OverSampling=UART_OVERSAMPLING_16 USART3.OverrunDisableParam=ADVFEATURE_OVERRUN_ENABLE USART3.Parity=PARITY_ODD USART3.RxPinLevelInvertParam=ADVFEATURE_RXINV_DISABLE USART3.StopBits=STOPBITS_1 USART3.SwapParam=ADVFEATURE_SWAP_DISABLE USART3.TxPinLevelInvertParam=ADVFEATURE_TXINV_DISABLE USART3.VirtualMode-Asynchronous=VM_ASYNC USART3.WordLength=WORDLENGTH_8B VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick board=custom ================================================ FILE: hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for STM32G474RETx Device from stm32g4 series ** 512Kbytes FLASH ** 128Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© COPYRIGHT(c) 2020 STMicroelectronics

** ** 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. Neither the name of STMicroelectronics nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x1000 ; /* required amount of heap */ _Min_Stack_Size = 0x1000 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32g4/boards/stm32g474nucleo/board.cmake ================================================ set(MCU_VARIANT stm32g474xx) set(JLINK_DEVICE stm32g474re) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32G474RETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32G474xx HSE_VALUE=24000000 ) endfunction() ================================================ FILE: hw/bsp/stm32g4/boards/stm32g474nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 G474 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-g474re.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // G474RE Nucleo does not has usb connection. We need to manually connect // - PA12 for D+, CN10.12 // - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF12_LPUART1 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // Initializes the CPU, AHB and APB buses clocks RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; RCC_OscInitStruct.PLL.PLLN = 50; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; #if 0 // TODO need to check if USB clock is enabled /* Enable HSI48 */ memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&RCC_OscInitStruct); /*Enable CRS Clock*/ RCC_CRSInitTypeDef RCC_CRSInitStruct= {0}; __HAL_RCC_CRS_CLK_ENABLE(); /* Default Synchro Signal division factor (not divided) */ RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; /* HSI48 is synchronized with USB SOF at 1KHz rate */ RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; /* Set the TRIM[5:0] to the default value */ RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; /* Start automatic synchronization */ HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); #endif } static inline void board_vbus_sense_init(void) { // Enable VBUS sense (B device) via pin PA9 } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk ================================================ MCU_VARIANT = stm32g474xx CFLAGS += \ -DSTM32G474xx \ -DHSE_VALUE=24000000 # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32G474RETx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32g474re ================================================ FILE: hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for NUCLEO-G491RE Board embedding STM32G491RETx Device from stm32g4 series ** 512KBytes FLASH ** 112KBytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32g4/boards/stm32g491nucleo/board.cmake ================================================ set(MCU_VARIANT stm32g491xx) set(JLINK_DEVICE stm32g491re) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32G491RETX_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32G491xx HSE_VALUE=24000000 ) endfunction() ================================================ FILE: hw/bsp/stm32g4/boards/stm32g491nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 G491 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-g491re.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // G474RE Nucleo does not has usb connection. We need to manually connect // - PA12 for D+, CN10.12 // - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 0 // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF12_LPUART1 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // Initializes the CPU, AHB and APB buses clocks RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6; RCC_OscInitStruct.PLL.PLLN = 85; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; } static inline void board_vbus_sense_init(void) { // Enable VBUS sense (B device) via pin PA9 } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32g4/boards/stm32g491nucleo/board.mk ================================================ MCU_VARIANT = stm32g491xx CFLAGS += \ -DSTM32G491xx \ -DHSE_VALUE=24000000 # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32G491RETX_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32g491re ================================================ FILE: hw/bsp/stm32g4/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32g4xx_hal.h" #include "stm32g4xx_ll_bus.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_HP_IRQHandler(void) { tud_int_handler(0); } void USB_LP_IRQHandler(void) { tud_int_handler(0); } void USBWakeUp_IRQHandler(void) { tud_int_handler(0); } // USB PD void UCPD1_IRQHandler(void) { tuc_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV UART_HandleTypeDef UartHandle; #endif void board_init(void) { HAL_Init(); board_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_HP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; // LED memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); board_led_write(false); // Button memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV UART_CLK_EN(); // UART memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle = (UART_HandleTypeDef){ .Instance = UART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); #endif // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); __HAL_RCC_USB_CLK_ENABLE(); board_vbus_sense_init(); #if 1 // USB PD // Default CC1/CC2 is PB4/PB6 // Enable pwr for disabling dead battery feature in Power's CR3 __HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_CRC_CLK_ENABLE(); __HAL_RCC_UCPD1_CLK_ENABLE(); // Enable DMA for USB PD __HAL_RCC_DMAMUX1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32g4/family.cmake ================================================ include_guard() set(ST_FAMILY g4) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32G4 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32G4) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${TOP}/src/portable/st/typec/typec_stm32.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32g4/family.mk ================================================ UF2_FAMILY_ID = 0x4c71240a ST_FAMILY = g4 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32G4 # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ src/portable/st/typec/typec_stm32.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32g4/stm32g4xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32g4xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32G4xx_HAL_CONF_H #define STM32G4xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_COMP_MODULE_ENABLED */ /*#define HAL_CORDIC_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ /*#define HAL_FDCAN_MODULE_ENABLED */ /*#define HAL_FMAC_MODULE_ENABLED */ /*#define HAL_HRTIM_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ /*#define HAL_I2C_MODULE_ENABLED */ /*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */ /*#define HAL_NAND_MODULE_ENABLED */ /*#define HAL_NOR_MODULE_ENABLED */ /*#define HAL_OPAMP_MODULE_ENABLED */ /*#define HAL_PCD_MODULE_ENABLED */ /*#define HAL_QSPI_MODULE_ENABLED */ /*#define HAL_RNG_MODULE_ENABLED */ /*#define HAL_RTC_MODULE_ENABLED */ /*#define HAL_SAI_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_SRAM_MODULE_ENABLED */ /*#define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* ########################## Register Callbacks selection ############################## */ /** * @brief This is the list of modules where register callback can be used */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U #define USE_HAL_COMP_REGISTER_CALLBACKS 0U #define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U #define USE_HAL_DAC_REGISTER_CALLBACKS 0U #define USE_HAL_EXTI_REGISTER_CALLBACKS 0U #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U #define USE_HAL_FMAC_REGISTER_CALLBACKS 0U #define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U #define USE_HAL_I2C_REGISTER_CALLBACKS 0U #define USE_HAL_I2S_REGISTER_CALLBACKS 0U #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U #define USE_HAL_NAND_REGISTER_CALLBACKS 0U #define USE_HAL_NOR_REGISTER_CALLBACKS 0U #define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U #define USE_HAL_PCD_REGISTER_CALLBACKS 0U #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U #define USE_HAL_RNG_REGISTER_CALLBACKS 0U #define USE_HAL_RTC_REGISTER_CALLBACKS 0U #define USE_HAL_SAI_REGISTER_CALLBACKS 0U #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U #define USE_HAL_SPI_REGISTER_CALLBACKS 0U #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U #define USE_HAL_TIM_REGISTER_CALLBACKS 0U #define USE_HAL_UART_REGISTER_CALLBACKS 0U #define USE_HAL_USART_REGISTER_CALLBACKS 0U #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE (24000000UL) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE (48000000UL) /*!< Value of the Internal High Speed oscillator for USB FS/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ #define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for I2S and SAI peripherals * This value is used by the I2S and SAI HAL modules to compute the I2S and SAI clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (0UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U #define DATA_CACHE_ENABLE 1U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32g4xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32g4xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32g4xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32g4xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32g4xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32g4xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CORDIC_MODULE_ENABLED #include "stm32g4xx_hal_cordic.h" #endif /* HAL_CORDIC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32g4xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32g4xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32g4xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32g4xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32g4xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32g4xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_FMAC_MODULE_ENABLED #include "stm32g4xx_hal_fmac.h" #endif /* HAL_FMAC_MODULE_ENABLED */ #ifdef HAL_HRTIM_MODULE_ENABLED #include "stm32g4xx_hal_hrtim.h" #endif /* HAL_HRTIM_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32g4xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32g4xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32g4xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32g4xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32g4xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32g4xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32g4xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32g4xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32g4xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32g4xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32g4xx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32g4xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32g4xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32g4xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32g4xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32g4xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32g4xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32g4xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32g4xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32g4xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32g4xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32g4xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32G4xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32h5xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* Define to trap errors during development. */ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) #define configASSERT(_exp) \ do {\ if ( !(_exp) ) { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ taskDISABLE_INTERRUPTS(); \ __asm("BKPT #0\n"); \ }\ }\ } while(0) #endif /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<port, pindef->pin_init.Pin, GPIO_PIN_SET); // Initialize I2C4 for TCPP0203 (GPIO already configured in pindef array) __HAL_RCC_I2C4_CLK_ENABLE(); __HAL_RCC_I2C4_FORCE_RESET(); __HAL_RCC_I2C4_RELEASE_RESET(); if (HAL_I2C_Init(&i2c_handle) != HAL_OK) { return HAL_ERROR; } // Enable interrupt for TCPP0203 FLGn (GPIO already configured in pindef array) NVIC_SetPriority(EXTI1_IRQn, 12); NVIC_EnableIRQ(EXTI1_IRQn); return 0; } int32_t board_tcpp0203_deinit(void) { return 0; } int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } static inline void board_init2(void) { TCPP0203_IO_t io_ctx; io_ctx.Address = TCPP0203_I2C_ADDRESS_X68; io_ctx.Init = board_tcpp0203_init; io_ctx.DeInit = board_tcpp0203_deinit; io_ctx.ReadReg = i2c_readreg; io_ctx.WriteReg = i2c_writereg; TU_ASSERT(TCPP0203_RegisterBusIO(&tcpp0203_obj, &io_ctx) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_Init(&tcpp0203_obj) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); } void board_vbus_set(uint8_t rhport, bool state) { (void) state; if (rhport == 0) { TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } void EXTI1_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1); if (tcpp0203_obj.IsInitialized) { TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk ================================================ MCU_VARIANT = stm32h573xx CFLAGS += \ -DSTM32H573xx # For flash-jlink target JLINK_DEVICE = stm32h573ii SRC_C += \ $(ST_TCPP0203)/tcpp0203.c \ $(ST_TCPP0203)/tcpp0203_reg.c \ INC += \ $(TOP)/$(ST_TCPP0203) \ ================================================ FILE: hw/bsp/stm32h5/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2023 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wundef" #endif #include "stm32h5xx_hal.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" TU_ATTR_UNUSED static void Error_Handler(void) { } typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_DRD_FS_IRQHandler(void) { tusb_int_handler(0, true); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16, .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT } }; #endif void board_init(void) { HAL_Init(); // required for HAL_RCC_Osc TODO check with freeRTOS SystemClock_Config(); // implemented in board.h SystemCoreClockUpdate(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); #ifdef __HAL_RCC_GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE(); #endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } #ifdef UART_DEV UART_CLK_EN(); HAL_UART_Init(&UartHandle); #endif // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_USB_CLK_ENABLE(); /* Enable VDDUSB */ #if defined (PWR_USBSCR_USB33DEN) HAL_PWREx_EnableVddUSB(); #endif board_init2(); #if CFG_TUH_ENABLED board_vbus_set(BOARD_TUH_RHPORT, 1); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t* stm32_uuid = (volatile uint32_t*) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*) (uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; HAL_IncTick(); } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32h5/family.cmake ================================================ include_guard() set(ST_FAMILY h5) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(ST_TCPP0203 ${TOP}/hw/mcu/st/stm32-tcpp0203) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32H5 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ string(REPLACE "stm32h" "STM32H" MCU_VARIANT_UPPER ${MCU_VARIANT}) set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32H5) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${TOP}/src/portable/st/typec/typec_stm32.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32h5/family.mk ================================================ ST_FAMILY = h5 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver ST_TCPP0203 = hw/mcu/st/stm32-tcpp0203 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 MCU_VARIANT_UPPER = $(subst stm32h,STM32H,$(MCU_VARIANT)) # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32H5 # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -Wno-error=cast-align \ -Wno-error=undef \ -Wno-error=unused-parameter \ CFLAGS_CLANG += \ -Wno-error=parentheses-equality LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_i2c.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf LD_FILE_GCC = $(FAMILY_PATH)/linker/$(MCU_VARIANT_UPPER)_FLASH.ld # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H503xx Device from STM32H5 series ** 128Kbytes FLASH ** 32Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H523xx Device from STM32H5 series ** 512Kbytes FLASH ** 272Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H533xx Device from STM32H5 series ** 512Kbytes FLASH ** 272Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H562xx Device from STM32H5 series ** 2048Kbytes FLASH ** 640Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H563xx Device from STM32H5 series ** 2048Kbytes FLASH ** 640Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H573xx Device from STM32H5 series ** 2048Kbytes FLASH ** 640Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h5/linker/stm32h503xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32h5/linker/stm32h523xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20043FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32h5/linker/stm32h562xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32h5/linker/stm32h563xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32h5/linker/stm32h573xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32h5/stm32h5xx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32h5xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * * Copyright (c) 2018-2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32h5xx_HAL_CONF_H #define STM32h5xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_FDCAN_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED #define HAL_I2C_MODULE_ENABLED /* ########################## Register Callbacks selection ############################## */ /** * @brief This is the list of modules where register callback can be used */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0u #define USE_HAL_CEC_REGISTER_CALLBACKS 0u #define USE_HAL_COMP_REGISTER_CALLBACKS 0u #define USE_HAL_CRYP_REGISTER_CALLBACKS 0u #define USE_HAL_DAC_REGISTER_CALLBACKS 0u #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0u #define USE_HAL_HCD_REGISTER_CALLBACKS 0u #define USE_HAL_I2C_REGISTER_CALLBACKS 0u #define USE_HAL_I2S_REGISTER_CALLBACKS 0u #define USE_HAL_IRDA_REGISTER_CALLBACKS 0u #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u #define USE_HAL_PCD_REGISTER_CALLBACKS 0u #define USE_HAL_RNG_REGISTER_CALLBACKS 0u #define USE_HAL_RTC_REGISTER_CALLBACKS 0u #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u #define USE_HAL_SPI_REGISTER_CALLBACKS 0u #define USE_HAL_TIM_REGISTER_CALLBACKS 0u #define USE_HAL_UART_REGISTER_CALLBACKS 0u #define USE_HAL_USART_REGISTER_CALLBACKS 0u #define USE_HAL_WWDG_REGISTER_CALLBACKS 0u /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Core Speed oscillator (CSI) default value. * This value is the default CSI range value after Reset. */ #if !defined (CSI_VALUE) #define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ #endif /* CSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ #if !defined (LSI_STARTUP_TIME) #define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in ms */ #endif /* LSI_STARTUP_TIME */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for SPI/SAI peripheral * This value is used by the SPI/SAI HAL module to compute the SPI/SAI clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ############################################ System Configuration ################################################ */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300UL /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U /*!< Enable prefetch */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* ################## CRYP peripheral configuration ########################## */ #define USE_HAL_CRYP_SUSPEND_RESUME 1U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include modules header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32h5xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32h5xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32h5xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32h5xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32h5xx_hal_adc.h" #include "stm32h5xx_hal_adc_ex.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32h5xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32h5xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32h5xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32h5xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32h5xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32h5xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32h5xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32h5xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32h5xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32h5xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32h5xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32h5xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32h5xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32h5xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32h5xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32h5xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32h5xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32h5xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32h5xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32h5xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32h5xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32h5xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32h5xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32h5xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32h5xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for functions parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32h5xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32h7/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32h7xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL1 for System Clock */ RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 160; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* PLL3 for USB Clock */ PeriphClkInitStruct.PLL3.PLL3M = 25; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure bus clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /*activate CSI clock mondatory for I/O Compensation Cell*/ __HAL_RCC_CSI_ENABLE() ; /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE() ; /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/daisyseed/board.mk ================================================ MCU_VARIANT = stm32h750xx CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=16000000 LD_FILE_GCC = $(BOARD_PATH)/stm32h750ibkx_flash.ld # For flash-jlink target JLINK_DEVICE = stm32h750ibk6_m7 # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32H7 series ** 128Kbytes FLASH and 1056Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2022 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** **************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x2000 ; /* required amount of heap */ _Min_Stack_Size = 0x4000 ; /* required amount of stack */ /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM_D1 AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM_D1 /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld (debug in RAM dedicated) ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32H7 series ** 128Kbytes RAM_EXEC and 544Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2022 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** **************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { RAM_EXEC (xrw) : ORIGIN = 0x24000000, LENGTH = 128K DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Highest address of the user mode stack */ _estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x2000 ; /* required amount of heap */ _Min_Stack_Size = 0x4000 ; /* required amount of stack */ /* Define output sections */ SECTIONS { /* The startup code goes first into RAM_EXEC */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >RAM_EXEC /* The program code and other data goes into RAM_EXEC */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >RAM_EXEC /* Constant data goes into RAM_EXEC */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >RAM_EXEC .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM_EXEC .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >RAM_EXEC .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >RAM_EXEC .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >RAM_EXEC .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >RAM_EXEC /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >DTCMRAM AT> RAM_EXEC /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >DTCMRAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >DTCMRAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/boards/stm32h723nucleo/board.cmake ================================================ set(MCU_VARIANT stm32h723xx) set(JLINK_DEVICE stm32h723zg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H723xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h723nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H723 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-h723zg.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 // STM32F723 has only one USB HS peripheral // Nucleo board does not have ULPI so USB will operate in FS mode only // For the rest of the synopsys driver it is FS device however there // is only USB_OTG_HS defined. Here are required conversions to // make peripheral FS. #define __HAL_RCC_USB2_OTG_FS_CLK_ENABLE __HAL_RCC_USB1_OTG_HS_CLK_ENABLE #define GPIO_AF10_OTG2_HS GPIO_AF10_OTG1_HS #define USB_OTG_FS USB_OTG_HS #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_OUTPUT_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; /* The PWR block is always enabled on the H7 series- there is no clock enable. For now, use the default VOS3 scale mode (lowest) and limit clock frequencies to avoid potential current draw problems from bus power when using the max clock speeds throughout the chip. */ /* Enable HSE Oscillator and activate PLL1 with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLR = 2; /* Unused */ RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_0; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \ RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \ RCC_CLOCKTYPE_D3PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; /* Unlike on the STM32F4 family, it appears the maximum APB frequencies are device-dependent- 120 MHz for this board according to Figure 2 of the datasheet. Dividing by half will be safe for now. */ RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; /* 4 wait states required for 168MHz and VOS3. */ HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /* Like on F4, on H7, USB's actual peripheral clock and bus clock are separate. However, the main system PLL (PLL1) doesn't have a direct connection to the USB peripheral clock to generate 48 MHz, so we do this dance. This will connect PLL1's Q output to the USB peripheral clock. */ RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = { 0 }; RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; RCC_PeriphCLKInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h723nucleo/board.mk ================================================ MCU_VARIANT = stm32h723xx CFLAGS += -DSTM32H723xx -DHSE_VALUE=8000000 LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash.ld # For flash-jlink target JLINK_DEVICE = stm32h723zg # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743eval/board.cmake ================================================ set(MCU_VARIANT stm32h743xx) set(JLINK_DEVICE stm32h743xi) #set(JLINK_OPTION "-USB jtrace") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) # device default to PORT 1 High Speed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) target_sources(${TARGET} PRIVATE ${ST_MFXSTM32L152}/mfxstm32l152.c ${ST_MFXSTM32L152}/mfxstm32l152_reg.c ) target_include_directories(${TARGET} PUBLIC ${ST_MFXSTM32L152} ) target_compile_definitions(${TARGET} PUBLIC STM32H743xx HSE_VALUE=25000000 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743eval/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H743 Eval url: https://www.st.com/en/evaluation-tools/stm32h743i-eval.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "mfxstm32l152.h" // Need to change jumper setting J7 and J8 from RS-232 to STLink #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 1 // USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 #define ULPI_PINS \ {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOH, GPIO_PIN_4 }, {GPIOI, GPIO_PIN_11} #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 static board_pindef_t board_pindef[] = { { // LED .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // UART TX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_14, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_USART1 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_15, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_USART1 }, .active_state = 0 }, { // I2C SCL for MFX VBUS .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_I2C1 }, .active_state = 0 }, { // I2C SDA for MFX VBUS .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_7, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_I2C1 }, .active_state = 1 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /*!< Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while ( (PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY ) {} /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // PLL1 for System Clock (400Mhz) // From H743 eval manual ETM can only work at 50 MHz clock by default because ETM signals // are shared with other peripherals. Trace CLK = PLL1R. RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 160; // May reduce to 100/200 Mhz when tracing to avoid overflowing trace buffer RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = RCC_OscInitStruct.PLL.PLLN/10; // Trace clock is limit to 50 Mhz to meet board requirement RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure bus clocks dividers */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); /* PLL3 for USB Clock */ PeriphClkInitStruct.PLL3.PLL3M = 25; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /*activate CSI clock mondatory for I/O Compensation Cell*/ __HAL_RCC_CSI_ENABLE(); /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE(); /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } //--------------------------------------------------------------------+ // MFX //--------------------------------------------------------------------+ static I2C_HandleTypeDef i2c_handle = { .Instance = I2C1, .Init = { .Timing = 0x10C0ECFF, .OwnAddress1 = 0, .AddressingMode = I2C_ADDRESSINGMODE_7BIT, .DualAddressMode = I2C_DUALADDRESS_DISABLE, .OwnAddress2 = 0, .OwnAddress2Masks = I2C_OA2_NOMASK, .GeneralCallMode = I2C_GENERALCALL_DISABLE, .NoStretchMode = I2C_NOSTRETCH_DISABLE, } }; static MFXSTM32L152_Object_t mfx_obj = { 0 }; static MFXSTM32L152_IO_Mode_t* mfx_io = NULL; static uint32_t mfx_vbus_pin[2] = { MFXSTM32L152_GPIO_PIN_7, MFXSTM32L152_GPIO_PIN_9 }; static int32_t board_i2c_init(void) { __HAL_RCC_I2C1_CLK_ENABLE(); __HAL_RCC_I2C1_FORCE_RESET(); __HAL_RCC_I2C1_RELEASE_RESET(); if (HAL_I2C_Init(&i2c_handle) != HAL_OK) { return HAL_ERROR; } if (HAL_I2CEx_ConfigAnalogFilter(&i2c_handle, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { return HAL_ERROR; } if (HAL_I2CEx_ConfigDigitalFilter(&i2c_handle, 0) != HAL_OK) { return HAL_ERROR; } return 0; } static int32_t board_i2c_deinit(void) { return 0; } static int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { for (int retry = 0; retry < 3; retry++) { if (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)) { return 0; } HAL_Delay(10); } return -1; } static int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { for (int retry = 0; retry < 3; retry++) { if (HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)) { return 0; } HAL_Delay(10); } return -1; } static int32_t i2c_get_tick(void) { return (int32_t) HAL_GetTick(); } static inline void board_init2(void) { // IO control via MFX MFXSTM32L152_IO_t io_ctx; io_ctx.Init = board_i2c_init; io_ctx.DeInit = board_i2c_deinit; io_ctx.ReadReg = i2c_readreg; io_ctx.WriteReg = i2c_writereg; io_ctx.GetTick = i2c_get_tick; uint16_t i2c_addr[] = { 0x84, 0x86 }; for(uint8_t i = 0U; i < 2U; i++) { uint32_t mfx_id; io_ctx.Address = i2c_addr[i]; TU_ASSERT(MFXSTM32L152_RegisterBusIO(&mfx_obj, &io_ctx) == MFXSTM32L152_OK, ); TU_ASSERT(MFXSTM32L152_ReadID(&mfx_obj, &mfx_id) == MFXSTM32L152_OK, ); if ((mfx_id == MFXSTM32L152_ID) || (mfx_id == MFXSTM32L152_ID_2)) { TU_ASSERT(MFXSTM32L152_Init(&mfx_obj) == MFXSTM32L152_OK, ); break; } } mfx_io = &MFXSTM32L152_IO_Driver; mfx_io->IO_Start(&mfx_obj, MFXSTM32L152_GPIO_PINS_ALL); for(uint32_t i=0; i<2; i++) { MFXSTM32L152_IO_Init_t io_init = { .Pin = mfx_vbus_pin[i], .Mode = MFXSTM32L152_GPIO_MODE_OUTPUT_PP, .Pull = MFXSTM32L152_GPIO_PULLUP, }; mfx_io->Init(&mfx_obj, &io_init); } } // VBUS1 is actually controlled by USB3320C PHY (using dwc2 drivebus signal) static void TU_ATTR_UNUSED board_vbus_set(uint8_t rhport, bool state) { if (mfx_io) { mfx_io->IO_WritePin(&mfx_obj, mfx_vbus_pin[rhport], state); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743eval/board.mk ================================================ MCU_VARIANT = stm32h743xx CFLAGS += -DSTM32H743xx -DHSE_VALUE=25000000 RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash.ld SRC_C += \ ${ST_MFXSTM32L152}/mfxstm32l152.c \ ${ST_MFXSTM32L152}/mfxstm32l152_reg.c \ INC += $(TOP)/${ST_MFXSTM32L152} # For flash-jlink target JLINK_DEVICE = stm32h743xi # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743eval/cubemx/stm32h743eval.ioc ================================================ #MicroXplorer Configuration settings - do not modify CAD.formats=[] CAD.pinconfig=Project naming CAD.provider= File.Version=6 GPIO.groupedBy=Group By Peripherals I2C1.IPParameters=Timing I2C1.Timing=0x10C0ECFF KeepUserPlacement=false Mcu.CPN=STM32H743XIH6 Mcu.Family=STM32H7 Mcu.IP0=CORTEX_M7 Mcu.IP1=DEBUG Mcu.IP2=I2C1 Mcu.IP3=NVIC Mcu.IP4=RCC Mcu.IP5=SYS Mcu.IP6=USB_OTG_FS Mcu.IP7=USB_OTG_HS Mcu.IPNb=8 Mcu.Name=STM32H743XIHx Mcu.Package=TFBGA240 Mcu.Pin0=PI6 Mcu.Pin1=PI5 Mcu.Pin10=PA15 (JTDI) Mcu.Pin100=PC1 Mcu.Pin101=PC2 Mcu.Pin102=PC3 Mcu.Pin103=PJ9 Mcu.Pin104=PH2 Mcu.Pin105=PA2 Mcu.Pin106=PA1 Mcu.Pin107=PJ0 Mcu.Pin108=PE10 Mcu.Pin109=PJ8 Mcu.Pin11=PI1 Mcu.Pin110=PJ7 Mcu.Pin111=PJ6 Mcu.Pin112=PH3 Mcu.Pin113=PH4 Mcu.Pin114=PH5 Mcu.Pin115=PI15 Mcu.Pin116=PJ1 Mcu.Pin117=PF13 Mcu.Pin118=PF14 Mcu.Pin119=PE9 Mcu.Pin12=PI0 Mcu.Pin120=PE11 Mcu.Pin121=PB10 Mcu.Pin122=PB11 Mcu.Pin123=PH10 Mcu.Pin124=PH11 Mcu.Pin125=PD15 Mcu.Pin126=PD14 Mcu.Pin127=PA6 Mcu.Pin128=PA7 Mcu.Pin129=PB2 Mcu.Pin13=PI7 Mcu.Pin130=PF12 Mcu.Pin131=PF15 Mcu.Pin132=PE12 Mcu.Pin133=PE15 Mcu.Pin134=PJ5 Mcu.Pin135=PH9 Mcu.Pin136=PH12 Mcu.Pin137=PD11 Mcu.Pin138=PD12 Mcu.Pin139=PD13 Mcu.Pin14=PE1 Mcu.Pin140=PA0_C Mcu.Pin141=PA5 Mcu.Pin142=PC4 Mcu.Pin143=PB1 Mcu.Pin144=PJ2 Mcu.Pin145=PF11 Mcu.Pin146=PG0 Mcu.Pin147=PE8 Mcu.Pin148=PE13 Mcu.Pin149=PH6 Mcu.Pin15=PB6 Mcu.Pin150=PH8 Mcu.Pin151=PB12 Mcu.Pin152=PB15 Mcu.Pin153=PD10 Mcu.Pin154=PD9 Mcu.Pin155=PA3 Mcu.Pin156=PA4 Mcu.Pin157=PC5 Mcu.Pin158=PB0 Mcu.Pin159=PJ3 Mcu.Pin16=PB4 (NJTRST) Mcu.Pin160=PJ4 Mcu.Pin161=PG1 Mcu.Pin162=PE7 Mcu.Pin163=PE14 Mcu.Pin164=PH7 Mcu.Pin165=PB13 Mcu.Pin166=PB14 Mcu.Pin167=PD8 Mcu.Pin168=VP_SYS_VS_Systick Mcu.Pin17=PK4 Mcu.Pin18=PG11 Mcu.Pin19=PJ15 Mcu.Pin2=PI4 Mcu.Pin20=PD6 Mcu.Pin21=PD3 Mcu.Pin22=PC11 Mcu.Pin23=PA14 (JTCK/SWCLK) Mcu.Pin24=PI2 Mcu.Pin25=PH15 Mcu.Pin26=PH14 Mcu.Pin27=PC15-OSC32_OUT (OSC32_OUT) Mcu.Pin28=PC14-OSC32_IN (OSC32_IN) Mcu.Pin29=PE2 Mcu.Pin3=PB5 Mcu.Pin30=PE0 Mcu.Pin31=PB7 Mcu.Pin32=PB3 (JTDO/TRACESWO) Mcu.Pin33=PK6 Mcu.Pin34=PK3 Mcu.Pin35=PG12 Mcu.Pin36=PD7 Mcu.Pin37=PC12 Mcu.Pin38=PI3 Mcu.Pin39=PA13 (JTMS/SWDIO) Mcu.Pin4=PK5 Mcu.Pin40=PE5 Mcu.Pin41=PE4 Mcu.Pin42=PE3 Mcu.Pin43=PB9 Mcu.Pin44=PB8 Mcu.Pin45=PG15 Mcu.Pin46=PK7 Mcu.Pin47=PG14 Mcu.Pin48=PG13 Mcu.Pin49=PJ14 Mcu.Pin5=PG10 Mcu.Pin50=PJ12 Mcu.Pin51=PD2 Mcu.Pin52=PD0 Mcu.Pin53=PA10 Mcu.Pin54=PA9 Mcu.Pin55=PH13 Mcu.Pin56=PI9 Mcu.Pin57=PC13 Mcu.Pin58=PI8 Mcu.Pin59=PE6 Mcu.Pin6=PG9 Mcu.Pin60=PJ13 Mcu.Pin61=PD1 Mcu.Pin62=PC8 Mcu.Pin63=PC9 Mcu.Pin64=PA8 Mcu.Pin65=PA12 Mcu.Pin66=PA11 Mcu.Pin67=PI10 Mcu.Pin68=PI11 Mcu.Pin69=PC7 Mcu.Pin7=PD5 Mcu.Pin70=PC6 Mcu.Pin71=PG8 Mcu.Pin72=PG7 Mcu.Pin73=PF2 Mcu.Pin74=PF1 Mcu.Pin75=PF0 Mcu.Pin76=PG5 Mcu.Pin77=PG6 Mcu.Pin78=PI12 Mcu.Pin79=PI13 Mcu.Pin8=PD4 Mcu.Pin80=PI14 Mcu.Pin81=PF3 Mcu.Pin82=PG4 Mcu.Pin83=PG3 Mcu.Pin84=PG2 Mcu.Pin85=PK2 Mcu.Pin86=PH1-OSC_OUT (PH1) Mcu.Pin87=PH0-OSC_IN (PH0) Mcu.Pin88=PF5 Mcu.Pin89=PF4 Mcu.Pin9=PC10 Mcu.Pin90=PK0 Mcu.Pin91=PK1 Mcu.Pin92=PF6 Mcu.Pin93=PF7 Mcu.Pin94=PF8 Mcu.Pin95=PJ11 Mcu.Pin96=PC0 Mcu.Pin97=PF10 Mcu.Pin98=PF9 Mcu.Pin99=PJ10 Mcu.PinsNb=169 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32H743XIHx MxCube.Version=6.12.1 MxDb.Version=DB.6.0.121 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:true\:false\:false PA0_C.GPIOParameters=GPIO_Label PA0_C.GPIO_Label=Potentiometer PA0_C.Locked=true PA0_C.Signal=ADCx_INN1 PA1.GPIOParameters=GPIO_Label PA1.GPIO_Label=RMII_REF_CLK [LAN8742A_REFCLK0] PA1.Locked=true PA1.Signal=ETH_REF_CLK PA10.GPIOParameters=GPIO_Label PA10.GPIO_Label=USB_FS1_ID PA10.Locked=true PA10.Signal=USB_OTG_FS_ID PA11.GPIOParameters=GPIO_Label PA11.GPIO_Label=USB_FS1_DM PA11.Locked=true PA11.Mode=Device_Only PA11.Signal=USB_OTG_FS_DM PA12.GPIOParameters=GPIO_Label PA12.GPIO_Label=USB_FS1_DP PA12.Locked=true PA12.Mode=Device_Only PA12.Signal=USB_OTG_FS_DP PA13\ (JTMS/SWDIO).Locked=true PA13\ (JTMS/SWDIO).Mode=Trace_Synchro_4bits_SW PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO PA14\ (JTCK/SWCLK).Locked=true PA14\ (JTCK/SWCLK).Mode=Trace_Synchro_4bits_SW PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK PA15\ (JTDI).GPIOParameters=GPIO_Label PA15\ (JTDI).GPIO_Label=TDI PA15\ (JTDI).Locked=true PA15\ (JTDI).Signal=DEBUG_JTDI PA2.GPIOParameters=GPIO_Label PA2.GPIO_Label=ETH_MDIO [LAN8742A_MDIO] PA2.Locked=true PA2.Signal=ETH_MDIO PA3.GPIOParameters=GPIO_Label PA3.GPIO_Label=ULPI_D0 [USB3320C_D0] PA3.Locked=true PA3.Mode=Device_HS PA3.Signal=USB_OTG_HS_ULPI_D0 PA4.GPIOParameters=GPIO_Label PA4.GPIO_Label=LED3_RGB [LD3_Red] PA4.Locked=true PA4.Signal=GPIO_Output PA5.GPIOParameters=GPIO_Label PA5.GPIO_Label=ULPI_CK [USB3320C_CLKOUT] PA5.Locked=true PA5.Mode=Device_HS PA5.Signal=USB_OTG_HS_ULPI_CK PA6.GPIOParameters=GPIO_Label PA6.GPIO_Label=LCD_BL_CTRL PA6.Locked=true PA6.Signal=GPIO_Output PA7.GPIOParameters=GPIO_Label PA7.GPIO_Label=RMII_CRS_DV [LAN8742A_CRS_DV] PA7.Locked=true PA7.Signal=ETH_CRS_DV PA8.GPIOParameters=GPIO_Label PA8.GPIO_Label=MCO PA8.Locked=true PA8.Signal=RCC_MCO_1 PA9.GPIOParameters=GPIO_Label PA9.GPIO_Label=VBUS_FS1 PA9.Locked=true PA9.Signal=USB_OTG_FS_VBUS PB0.GPIOParameters=GPIO_Label PB0.GPIO_Label=ULPI_D1 [USB3320C_D1] PB0.Locked=true PB0.Mode=Device_HS PB0.Signal=USB_OTG_HS_ULPI_D1 PB1.GPIOParameters=GPIO_Label PB1.GPIO_Label=ULPI_D2 [USB3320C_D2] PB1.Locked=true PB1.Mode=Device_HS PB1.Signal=USB_OTG_HS_ULPI_D2 PB10.GPIOParameters=GPIO_Label PB10.GPIO_Label=ULPI_D3 [USB3320C_D3] PB10.Locked=true PB10.Mode=Device_HS PB10.Signal=USB_OTG_HS_ULPI_D3 PB11.GPIOParameters=GPIO_Label PB11.GPIO_Label=ULPI_D4 [USB3320C_D4] PB11.Locked=true PB11.Mode=Device_HS PB11.Signal=USB_OTG_HS_ULPI_D4 PB12.GPIOParameters=GPIO_Label PB12.GPIO_Label=ULPI_D5 [USB3320C_D5] PB12.Locked=true PB12.Mode=Device_HS PB12.Signal=USB_OTG_HS_ULPI_D5 PB13.GPIOParameters=GPIO_Label PB13.GPIO_Label=ULPI_D6 [USB3320C_D6] PB13.Locked=true PB13.Mode=Device_HS PB13.Signal=USB_OTG_HS_ULPI_D6 PB14.GPIOParameters=GPIO_Label PB14.GPIO_Label=RS232_TX [ST3241EBPR_T2IN] PB14.Locked=true PB14.Signal=USART1_TX PB15.GPIOParameters=GPIO_Label PB15.GPIO_Label=RS_232RX [ST3241EBPR_R3OUT] PB15.Locked=true PB15.Signal=USART1_RX PB2.GPIOParameters=GPIO_Label PB2.GPIO_Label=QSPI_CLK [MT25TL01GHBA8ESF_CLK_1] PB2.Locked=true PB2.Signal=QUADSPI_CLK PB3\ (JTDO/TRACESWO).Locked=true PB3\ (JTDO/TRACESWO).Signal=DEBUG_JTDO-SWO PB4\ (NJTRST).GPIOParameters=GPIO_Label PB4\ (NJTRST).GPIO_Label=TRST PB4\ (NJTRST).Locked=true PB4\ (NJTRST).Signal=DEBUG_JTRST PB5.GPIOParameters=GPIO_Label PB5.GPIO_Label=ULPI_D7 [USB3320C_D7] PB5.Locked=true PB5.Mode=Device_HS PB5.Signal=USB_OTG_HS_ULPI_D7 PB6.GPIOParameters=GPIO_Label PB6.GPIO_Label=I2C1_SCL [STM32L152CCT6_I2C_SCL] PB6.Locked=true PB6.Mode=I2C PB6.Signal=I2C1_SCL PB7.GPIOParameters=GPIO_Label PB7.GPIO_Label=I2C1_SDA [STM32L152CCT6_I2C_SDA] PB7.Locked=true PB7.Mode=I2C PB7.Signal=I2C1_SDA PB8.GPIOParameters=GPIO_Label PB8.GPIO_Label=SDIO1_CKIN PB8.Locked=true PB8.Signal=SDMMC1_CKIN PB9.GPIOParameters=GPIO_Label PB9.GPIO_Label=SDIO1_CDIR PB9.Locked=true PB9.Signal=SDMMC1_CDIR PC0.GPIOParameters=GPIO_Label PC0.GPIO_Label=ULPI_STP [USB3320C_STP] PC0.Locked=true PC0.Mode=Device_HS PC0.Signal=USB_OTG_HS_ULPI_STP PC1.GPIOParameters=GPIO_Label PC1.GPIO_Label=RMII_MDC [LAN8742A_MDC] PC1.Locked=true PC1.Signal=ETH_MDC PC10.GPIOParameters=GPIO_Label PC10.GPIO_Label=SDIO1_D2 PC10.Locked=true PC10.Signal=SDMMC1_D2 PC11.GPIOParameters=GPIO_Label PC11.GPIO_Label=SDIO1_D3 PC11.Locked=true PC11.Signal=SDMMC1_D3 PC12.GPIOParameters=GPIO_Label PC12.GPIO_Label=SDIO1_CLK PC12.Locked=true PC12.Signal=SDMMC1_CK PC13.GPIOParameters=GPIO_Label PC13.GPIO_Label=TAMPER_KEY [B1] PC13.Locked=true PC13.Signal=RTC_TAMP1 PC14-OSC32_IN\ (OSC32_IN).Locked=true PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN PC15-OSC32_OUT\ (OSC32_OUT).Locked=true PC15-OSC32_OUT\ (OSC32_OUT).Signal=RCC_OSC32_OUT PC2.GPIOParameters=GPIO_Label PC2.GPIO_Label=DFSDM_CLK PC2.Locked=true PC2.Signal=S_CKOUTDFSDM1 PC3.GPIOParameters=GPIO_Label PC3.GPIO_Label=DFSM_DAT1 PC3.Locked=true PC3.Signal=S_DATAIN1DFSDM1 PC4.GPIOParameters=GPIO_Label PC4.GPIO_Label=RMII_RXD0 [LAN8742A_RXD0] PC4.Locked=true PC4.Signal=ETH_RXD0 PC5.GPIOParameters=GPIO_Label PC5.GPIO_Label=RMII_RXD1 [LAN8742A_RXD1] PC5.Locked=true PC5.Signal=ETH_RXD1 PC6.GPIOParameters=GPIO_Label PC6.GPIO_Label=SDIO1_D0DIR PC6.Locked=true PC6.Signal=SDMMC1_D0DIR PC7.Locked=true PC7.Signal=DEBUG_TRGIO PC8.GPIOParameters=GPIO_Label PC8.GPIO_Label=SDIO1_D0 PC8.Locked=true PC8.Signal=SDMMC1_D0 PC9.GPIOParameters=GPIO_Label PC9.GPIO_Label=SDIO1_D1 PC9.Locked=true PC9.Signal=SDMMC1_D1 PD0.GPIOParameters=GPIO_Label PD0.GPIO_Label=D2 [IS42S32800G_DQ2] PD0.Locked=true PD0.Signal=FMC_D2_DA2 PD1.GPIOParameters=GPIO_Label PD1.GPIO_Label=D3 [IS42S32800G_DQ3] PD1.Locked=true PD1.Signal=FMC_D3_DA3 PD10.GPIOParameters=GPIO_Label PD10.GPIO_Label=D15 [IS42S32800G_DQ15] PD10.Locked=true PD10.Signal=FMC_D15_DA15 PD11.GPIOParameters=GPIO_Label PD11.GPIO_Label=A16 [PC28F128M29EWLA_A16] PD11.Locked=true PD11.Signal=FMC_A16_CLE PD12.GPIOParameters=GPIO_Label PD12.GPIO_Label=A17 [PC28F128M29EWLA_A17] PD12.Locked=true PD12.Signal=FMC_A17_ALE PD13.GPIOParameters=GPIO_Label PD13.GPIO_Label=A18 [PC28F128M29EWLA_A18] PD13.Locked=true PD13.Signal=FMC_A18 PD14.GPIOParameters=GPIO_Label PD14.GPIO_Label=D0 [IS42S32800G_DQ0] PD14.Locked=true PD14.Signal=FMC_D0_DA0 PD15.GPIOParameters=GPIO_Label PD15.GPIO_Label=D1 [IS42S32800G_DQ1] PD15.Locked=true PD15.Signal=FMC_D1_DA1 PD2.GPIOParameters=GPIO_Label PD2.GPIO_Label=SDIO1_CMD PD2.Locked=true PD2.Signal=SDMMC1_CMD PD3.GPIOParameters=GPIO_Label PD3.GPIO_Label=FDCAN1_STBY [MCP2562FD_STBY] PD3.Locked=true PD3.Signal=GPIO_Output PD4.GPIOParameters=GPIO_Label PD4.GPIO_Label=FMC_NOE [IS61WV102416BLL_OE] PD4.Locked=true PD4.Signal=FMC_NOE PD5.GPIOParameters=GPIO_Label PD5.GPIO_Label=FMC_NWE [IS61WV102416BLL_WE] PD5.Locked=true PD5.Signal=FMC_NWE PD6.GPIOParameters=GPIO_Label PD6.GPIO_Label=FMC_NWAIT [PC28F128M29EWLA_RB] PD6.Locked=true PD6.Signal=FMC_NWAIT PD7.GPIOParameters=GPIO_Label PD7.GPIO_Label=FMC_NE1 [PC28F128M29EWLA_E] PD7.Locked=true PD7.Signal=FMC_NE1 PD8.GPIOParameters=GPIO_Label PD8.GPIO_Label=D13 [IS42S32800G_DQ13] PD8.Locked=true PD8.Signal=FMC_D13_DA13 PD9.GPIOParameters=GPIO_Label PD9.GPIO_Label=D14 [IS42S32800G_DQ14] PD9.Locked=true PD9.Signal=FMC_D14_DA14 PE0.GPIOParameters=GPIO_Label PE0.GPIO_Label=FMC_NBL0 [IS42S32800G_DQM0] PE0.Locked=true PE0.Signal=FMC_NBL0 PE1.GPIOParameters=GPIO_Label PE1.GPIO_Label=FMC_NBL1 [IS42S32800G_DQM1] PE1.Locked=true PE1.Signal=FMC_NBL1 PE10.GPIOParameters=GPIO_Label PE10.GPIO_Label=D7 [IS42S32800G_DQ7] PE10.Locked=true PE10.Signal=FMC_D7_DA7 PE11.GPIOParameters=GPIO_Label PE11.GPIO_Label=D8 [IS42S32800G_DQ8] PE11.Locked=true PE11.Signal=FMC_D8_DA8 PE12.GPIOParameters=GPIO_Label PE12.GPIO_Label=D9 [IS42S32800G_DQ9] PE12.Locked=true PE12.Signal=FMC_D9_DA9 PE13.GPIOParameters=GPIO_Label PE13.GPIO_Label=D10 [IS42S32800G_DQ10] PE13.Locked=true PE13.Signal=FMC_D10_DA10 PE14.GPIOParameters=GPIO_Label PE14.GPIO_Label=D11 [IS42S32800G_DQ11] PE14.Locked=true PE14.Signal=FMC_D11_DA11 PE15.GPIOParameters=GPIO_Label PE15.GPIO_Label=D12 [IS42S32800G_DQ12] PE15.Locked=true PE15.Signal=FMC_D12_DA12 PE2.Locked=true PE2.Mode=Trace_Synchro_4bits_SW PE2.Signal=DEBUG_TRACECLK PE3.Locked=true PE3.Mode=Trace_Synchro_4bits_SW PE3.Signal=DEBUG_TRACED0 PE4.Locked=true PE4.Mode=Trace_Synchro_4bits_SW PE4.Signal=DEBUG_TRACED1 PE5.Locked=true PE5.Mode=Trace_Synchro_4bits_SW PE5.Signal=DEBUG_TRACED2 PE6.Locked=true PE6.Mode=Trace_Synchro_4bits_SW PE6.Signal=DEBUG_TRACED3 PE7.GPIOParameters=GPIO_Label PE7.GPIO_Label=D4 [IS42S32800G_DQ4] PE7.Locked=true PE7.Signal=FMC_D4_DA4 PE8.GPIOParameters=GPIO_Label PE8.GPIO_Label=D5 [IS42S32800G_DQ5] PE8.Locked=true PE8.Signal=FMC_D5_DA5 PE9.GPIOParameters=GPIO_Label PE9.GPIO_Label=D6 [IS42S32800G_DQ6] PE9.Locked=true PE9.Signal=FMC_D6_DA6 PF0.GPIOParameters=GPIO_Label PF0.GPIO_Label=A0 [PC28F128M29EWLA_A0] PF0.Locked=true PF0.Signal=FMC_A0 PF1.GPIOParameters=GPIO_Label PF1.GPIO_Label=A1 [PC28F128M29EWLA_A1] PF1.Locked=true PF1.Signal=FMC_A1 PF10.GPIOParameters=GPIO_Label PF10.GPIO_Label=LED1_RGB [LD1_Green] PF10.Locked=true PF10.Signal=GPIO_Output PF11.GPIOParameters=GPIO_Label PF11.GPIO_Label=SNDRAS [IS42S32800G_RAS] PF11.Locked=true PF11.Signal=FMC_SDNRAS PF12.GPIOParameters=GPIO_Label PF12.GPIO_Label=A6 [PC28F128M29EWLA_A6] PF12.Locked=true PF12.Signal=FMC_A6 PF13.GPIOParameters=GPIO_Label PF13.GPIO_Label=A7 [PC28F128M29EWLA_A7] PF13.Locked=true PF13.Signal=FMC_A7 PF14.GPIOParameters=GPIO_Label PF14.GPIO_Label=A8 [PC28F128M29EWLA_A8] PF14.Locked=true PF14.Signal=FMC_A8 PF15.GPIOParameters=GPIO_Label PF15.GPIO_Label=A9 [PC28F128M29EWLA_A9] PF15.Locked=true PF15.Signal=FMC_A9 PF2.GPIOParameters=GPIO_Label PF2.GPIO_Label=A2 [PC28F128M29EWLA_A2] PF2.Locked=true PF2.Signal=FMC_A2 PF3.GPIOParameters=GPIO_Label PF3.GPIO_Label=A3 [PC28F128M29EWLA_A3] PF3.Locked=true PF3.Signal=FMC_A3 PF4.GPIOParameters=GPIO_Label PF4.GPIO_Label=A4 [PC28F128M29EWLA_A4] PF4.Locked=true PF4.Signal=FMC_A4 PF5.GPIOParameters=GPIO_Label PF5.GPIO_Label=A5 [PC28F128M29EWLA_A5] PF5.Locked=true PF5.Signal=FMC_A5 PF6.GPIOParameters=GPIO_Label PF6.GPIO_Label=QSPI_BK1_IO3 [MT25TL01GHBA8ESF_DQ3] PF6.Locked=true PF6.Signal=QUADSPI_BK1_IO3 PF7.GPIOParameters=GPIO_Label PF7.GPIO_Label=QSPI_BK1_IO2 [MT25TL01GHBA8ESF_DQ2] PF7.Locked=true PF7.Signal=QUADSPI_BK1_IO2 PF8.GPIOParameters=GPIO_Label PF8.GPIO_Label=QSPI_BK1_IO0 [MT25TL01GHBA8ESF_DQ0] PF8.Locked=true PF8.Signal=QUADSPI_BK1_IO0 PF9.GPIOParameters=GPIO_Label PF9.GPIO_Label=QSPI_BK1_IO1 [MT25TL01GHBA8ESF_DQ1] PF9.Locked=true PF9.Signal=QUADSPI_BK1_IO1 PG0.GPIOParameters=GPIO_Label PG0.GPIO_Label=A10 [PC28F128M29EWLA_A10] PG0.Locked=true PG0.Signal=FMC_A10 PG1.GPIOParameters=GPIO_Label PG1.GPIO_Label=A11 [PC28F128M29EWLA_A11] PG1.Locked=true PG1.Signal=FMC_A11 PG10.GPIOParameters=GPIO_Label PG10.GPIO_Label=FMC_NE3 [IS61WV102416BLL_CE] PG10.Locked=true PG10.Signal=FMC_NE3 PG11.GPIOParameters=GPIO_Label PG11.GPIO_Label=RMII_TX_EN [LAN8742A_TXEN] PG11.Locked=true PG11.Signal=ETH_TX_EN PG12.GPIOParameters=GPIO_Label PG12.GPIO_Label=RMII_TXD1 [LAN8742A_TXD1] PG12.Locked=true PG12.Signal=ETH_TXD1 PG13.GPIOParameters=GPIO_Label PG13.GPIO_Label=RMII_TXD0 [LAN8742A_TXD0] PG13.Locked=true PG13.Signal=ETH_TXD0 PG14.GPIOParameters=GPIO_Label PG14.GPIO_Label=QSPI_BK2_IO3 [MT25TL01GHBA8ESF_DQ7] PG14.Locked=true PG14.Signal=QUADSPI_BK2_IO3 PG15.GPIOParameters=GPIO_Label PG15.GPIO_Label=SDNCAS [IS42S32800G_CAS] PG15.Locked=true PG15.Signal=FMC_SDNCAS PG2.GPIOParameters=GPIO_Label PG2.GPIO_Label=A12 [PC28F128M29EWLA_A12] PG2.Locked=true PG2.Signal=FMC_A12 PG3.GPIOParameters=GPIO_Label PG3.GPIO_Label=A13 [PC28F128M29EWLA_A13] PG3.Locked=true PG3.Signal=FMC_A13 PG4.Locked=true PG4.Signal=FMC_A14_BA0 PG5.Locked=true PG5.Signal=FMC_A15_BA1 PG6.GPIOParameters=GPIO_Label PG6.GPIO_Label=QSPI_BK1_NCS [MT25TL01GHBA8ESF_CS] PG6.Locked=true PG6.Signal=QUADSPI_BK1_NCS PG7.GPIOParameters=GPIO_Label PG7.GPIO_Label=SAI1_MCLKA [WM8994ECS_MCLK1] PG7.Locked=true PG7.Signal=SAI1_MCLK_A PG8.GPIOParameters=GPIO_Label PG8.GPIO_Label=SDCLK [IS42S32800G_CLK] PG8.Locked=true PG8.Signal=FMC_SDCLK PG9.GPIOParameters=GPIO_Label PG9.GPIO_Label=QSPI_BK2_IO2 [MT25TL01GHBA8ESF_DQ6] PG9.Locked=true PG9.Signal=QUADSPI_BK2_IO2 PH0-OSC_IN\ (PH0).Locked=true PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN PH1-OSC_OUT\ (PH1).Locked=true PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT PH10.GPIOParameters=GPIO_Label PH10.GPIO_Label=D18 [IS42S32800G_DQ18] PH10.Locked=true PH10.Signal=FMC_D18 PH11.GPIOParameters=GPIO_Label PH11.GPIO_Label=D19 [IS42S32800G_DQ19] PH11.Locked=true PH11.Signal=FMC_D19 PH12.GPIOParameters=GPIO_Label PH12.GPIO_Label=D20 [IS42S32800G_DQ20] PH12.Locked=true PH12.Signal=FMC_D20 PH13.GPIOParameters=GPIO_Label PH13.GPIO_Label=D21 [IS42S32800G_DQ21] PH13.Locked=true PH13.Signal=FMC_D21 PH14.GPIOParameters=GPIO_Label PH14.GPIO_Label=D22 [IS42S32800G_DQ22] PH14.Locked=true PH14.Signal=FMC_D22 PH15.GPIOParameters=GPIO_Label PH15.GPIO_Label=D23 [IS42S32800G_DQ23] PH15.Locked=true PH15.Signal=FMC_D23 PH2.GPIOParameters=GPIO_Label PH2.GPIO_Label=QSPI_BK2_IO0 [MT25TL01GHBA8ESF_DQ4] PH2.Locked=true PH2.Signal=QUADSPI_BK2_IO0 PH3.GPIOParameters=GPIO_Label PH3.GPIO_Label=QSPI_BK2_IO1 [MT25TL01GHBA8ESF_DQ5] PH3.Locked=true PH3.Signal=QUADSPI_BK2_IO1 PH4.GPIOParameters=GPIO_Label PH4.GPIO_Label=ULPI_NXT [USB3320C_NXT] PH4.Locked=true PH4.Mode=Device_HS PH4.Signal=USB_OTG_HS_ULPI_NXT PH5.GPIOParameters=GPIO_Label PH5.GPIO_Label=SDNWE [IS42S32800G_WE] PH5.Locked=true PH5.Signal=FMC_SDNWE PH6.GPIOParameters=GPIO_Label PH6.GPIO_Label=SDNE1 [IS42S32800G_CS] PH6.Locked=true PH6.Signal=FMC_SDNE1 PH7.GPIOParameters=GPIO_Label PH7.GPIO_Label=SDCKE1 [IS42S32800G_CKE] PH7.Locked=true PH7.Signal=FMC_SDCKE1 PH8.GPIOParameters=GPIO_Label PH8.GPIO_Label=D16 [IS42S32800G_DQ16] PH8.Locked=true PH8.Signal=FMC_D16 PH9.GPIOParameters=GPIO_Label PH9.GPIO_Label=D17 [IS42S32800G_DQ17] PH9.Locked=true PH9.Signal=FMC_D17 PI0.GPIOParameters=GPIO_Label PI0.GPIO_Label=D24 [IS42S32800G_DQ24] PI0.Locked=true PI0.Signal=FMC_D24 PI1.GPIOParameters=GPIO_Label PI1.GPIO_Label=D25 [IS42S32800G_DQ25] PI1.Locked=true PI1.Signal=FMC_D25 PI10.GPIOParameters=GPIO_Label PI10.GPIO_Label=D31 [IS42S32800G_DQ31] PI10.Locked=true PI10.Signal=FMC_D31 PI11.GPIOParameters=GPIO_Label PI11.GPIO_Label=ULPI_DIR [USB3320C_DIR] PI11.Locked=true PI11.Mode=Device_HS PI11.Signal=USB_OTG_HS_ULPI_DIR PI12.GPIOParameters=GPIO_Label PI12.GPIO_Label=LCD_HSYNC PI12.Locked=true PI12.Signal=LTDC_HSYNC PI13.GPIOParameters=GPIO_Label PI13.GPIO_Label=LCD_VSYNC PI13.Locked=true PI13.Signal=LTDC_VSYNC PI14.GPIOParameters=GPIO_Label PI14.GPIO_Label=LCD_CLK PI14.Locked=true PI14.Signal=LTDC_CLK PI15.GPIOParameters=GPIO_Label PI15.GPIO_Label=LCD_R0 PI15.Locked=true PI15.Signal=LTDC_R0 PI2.GPIOParameters=GPIO_Label PI2.GPIO_Label=D26 [IS42S32800G_DQ26] PI2.Locked=true PI2.Signal=FMC_D26 PI3.GPIOParameters=GPIO_Label PI3.GPIO_Label=D27 [IS42S32800G_DQ27 PI3.Locked=true PI3.Signal=FMC_D27 PI4.GPIOParameters=GPIO_Label PI4.GPIO_Label=FMC_NBL2 [IS42S32800G_DQM2] PI4.Locked=true PI4.Signal=FMC_NBL2 PI5.GPIOParameters=GPIO_Label PI5.GPIO_Label=FMC_NBL3 [IS42S32800G_DQM3] PI5.Locked=true PI5.Signal=FMC_NBL3 PI6.GPIOParameters=GPIO_Label PI6.GPIO_Label=D28 [IS42S32800G_DQ28] PI6.Locked=true PI6.Signal=FMC_D28 PI7.GPIOParameters=GPIO_Label PI7.GPIO_Label=D29 [IS42S32800G_DQ29] PI7.Locked=true PI7.Signal=FMC_D29 PI8.GPIOParameters=GPIO_Label PI8.GPIO_Label=MFX_IRQOUT [MFX_V3_IRQOUT] PI8.Locked=true PI8.Signal=GPXTI8 PI9.GPIOParameters=GPIO_Label PI9.GPIO_Label=D30 [IS42S32800G_DQ30] PI9.Locked=true PI9.Signal=FMC_D30 PJ0.GPIOParameters=GPIO_Label PJ0.GPIO_Label=LCD_R1 PJ0.Locked=true PJ0.Signal=LTDC_R1 PJ1.GPIOParameters=GPIO_Label PJ1.GPIO_Label=LCD_R2 PJ1.Locked=true PJ1.Signal=LTDC_R2 PJ10.GPIOParameters=GPIO_Label PJ10.GPIO_Label=LCd_G3 PJ10.Locked=true PJ10.Signal=LTDC_G3 PJ11.GPIOParameters=GPIO_Label PJ11.GPIO_Label=LCD_G4 PJ11.Locked=true PJ11.Signal=LTDC_G4 PJ12.Locked=true PJ12.Signal=DEBUG_TRGOUT PJ13.GPIOParameters=GPIO_Label PJ13.GPIO_Label=LCD_B1 PJ13.Locked=true PJ13.Signal=LTDC_B1 PJ14.GPIOParameters=GPIO_Label PJ14.GPIO_Label=LCD_B2 PJ14.Locked=true PJ14.Signal=LTDC_B2 PJ15.GPIOParameters=GPIO_Label PJ15.GPIO_Label=LCD_B3 PJ15.Locked=true PJ15.Signal=LTDC_B3 PJ2.GPIOParameters=GPIO_Label PJ2.GPIO_Label=LCD_R3 PJ2.Locked=true PJ2.Signal=LTDC_R3 PJ3.GPIOParameters=GPIO_Label PJ3.GPIO_Label=LCD_R4 PJ3.Locked=true PJ3.Signal=LTDC_R4 PJ4.GPIOParameters=GPIO_Label PJ4.GPIO_Label=LCD_R5 PJ4.Locked=true PJ4.Signal=LTDC_R5 PJ5.GPIOParameters=GPIO_Label PJ5.GPIO_Label=LCD_R6 PJ5.Locked=true PJ5.Signal=LTDC_R6 PJ6.GPIOParameters=GPIO_Label PJ6.GPIO_Label=LCD_R7 PJ6.Locked=true PJ6.Signal=LTDC_R7 PJ7.Locked=true PJ7.Signal=DEBUG_TRGIN PJ8.GPIOParameters=GPIO_Label PJ8.GPIO_Label=LCD_G1 PJ8.Locked=true PJ8.Signal=LTDC_G1 PJ9.GPIOParameters=GPIO_Label PJ9.GPIO_Label=LCD_G2 PJ9.Locked=true PJ9.Signal=LTDC_G2 PK0.GPIOParameters=GPIO_Label PK0.GPIO_Label=LCD_G5 PK0.Locked=true PK0.Signal=LTDC_G5 PK1.GPIOParameters=GPIO_Label PK1.GPIO_Label=LCD_G6 PK1.Locked=true PK1.Signal=LTDC_G6 PK2.GPIOParameters=GPIO_Label PK2.GPIO_Label=LCD_G7 PK2.Locked=true PK2.Signal=LTDC_G7 PK3.GPIOParameters=GPIO_Label PK3.GPIO_Label=LCD_B4 PK3.Locked=true PK3.Signal=LTDC_B4 PK4.GPIOParameters=GPIO_Label PK4.GPIO_Label=LCD_B5 PK4.Locked=true PK4.Signal=LTDC_B5 PK5.GPIOParameters=GPIO_Label PK5.GPIO_Label=LCD_B6 PK5.Locked=true PK5.Signal=LTDC_B6 PK6.GPIOParameters=GPIO_Label PK6.GPIO_Label=LCD_B7 PK6.Locked=true PK6.Signal=LTDC_B7 PK7.GPIOParameters=GPIO_Label PK7.GPIO_Label=LCD_DE PK7.Locked=true PK7.Signal=LTDC_DE PinOutPanel.CurrentBGAView=Top PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32H743XIHx ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.11.2 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=2 ProjectManager.MainLocation=Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain= ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=stm32h743eval.ioc ProjectManager.ProjectName=stm32h743eval ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation=Src/ ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true RCC.ADCFreq_Value=50390625 RCC.AHB12Freq_Value=200000000 RCC.AHB4Freq_Value=200000000 RCC.APB1Freq_Value=100000000 RCC.APB2Freq_Value=100000000 RCC.APB3Freq_Value=100000000 RCC.APB4Freq_Value=100000000 RCC.AXIClockFreq_Value=200000000 RCC.CECFreq_Value=32000 RCC.CKPERFreq_Value=64000000 RCC.CortexFreq_Value=400000000 RCC.CpuClockFreq_Value=400000000 RCC.D1CPREFreq_Value=400000000 RCC.D1PPRE=RCC_APB3_DIV2 RCC.D2PPRE1=RCC_APB1_DIV2 RCC.D2PPRE2=RCC_APB2_DIV2 RCC.D3PPRE=RCC_APB4_DIV2 RCC.DFSDMACLkFreq_Value=200000000 RCC.DFSDMFreq_Value=100000000 RCC.DIVM1=5 RCC.DIVM3=25 RCC.DIVN1=160 RCC.DIVN3=336 RCC.DIVP1Freq_Value=400000000 RCC.DIVP2Freq_Value=50390625 RCC.DIVP3Freq_Value=168000000 RCC.DIVQ1=4 RCC.DIVQ1Freq_Value=200000000 RCC.DIVQ2Freq_Value=50390625 RCC.DIVQ3=7 RCC.DIVQ3Freq_Value=48000000 RCC.DIVR1=8 RCC.DIVR1Freq_Value=100000000 RCC.DIVR2Freq_Value=50390625 RCC.DIVR3Freq_Value=168000000 RCC.EnbaleCSS=true RCC.FDCANFreq_Value=200000000 RCC.FMCFreq_Value=200000000 RCC.FamilyName=M RCC.HCLK3ClockFreq_Value=200000000 RCC.HCLKFreq_Value=200000000 RCC.HPRE=RCC_HCLK_DIV2 RCC.HPREFreq_Value=64000000 RCC.HRTIMFreq_Value=200000000 RCC.HSICalibrationValue=32 RCC.I2C123Freq_Value=100000000 RCC.I2C4Freq_Value=100000000 RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM3,DIVN1,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HPREFreq_Value,HRTIMFreq_Value,HSICalibrationValue,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,PWR_Regulator_Voltage_Scale,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value RCC.LPTIM1Freq_Value=100000000 RCC.LPTIM2Freq_Value=100000000 RCC.LPTIM345Freq_Value=100000000 RCC.LPUART1Freq_Value=100000000 RCC.LTDCFreq_Value=168000000 RCC.MCO1PinFreq_Value=64000000 RCC.MCO2PinFreq_Value=400000000 RCC.PLL2FRACN=0 RCC.PLL3FRACN=0 RCC.PLLFRACN=0 RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.PWR_Regulator_Voltage_Scale=PWR_REGULATOR_VOLTAGE_SCALE1 RCC.QSPIFreq_Value=200000000 RCC.RNGFreq_Value=48000000 RCC.RTCFreq_Value=32000 RCC.SAI1Freq_Value=200000000 RCC.SAI23Freq_Value=200000000 RCC.SAI4AFreq_Value=200000000 RCC.SAI4BFreq_Value=200000000 RCC.SDMMCFreq_Value=200000000 RCC.SPDIFRXFreq_Value=200000000 RCC.SPI123Freq_Value=200000000 RCC.SPI45Freq_Value=100000000 RCC.SPI6Freq_Value=100000000 RCC.SWPMI1Freq_Value=100000000 RCC.SYSCLKFreq_VALUE=400000000 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.Tim1OutputFreq_Value=200000000 RCC.Tim2OutputFreq_Value=200000000 RCC.TraceFreq_Value=100000000 RCC.USART16Freq_Value=100000000 RCC.USART234578Freq_Value=100000000 RCC.USBCLockSelection=RCC_USBCLKSOURCE_PLL3 RCC.USBFreq_Value=48000000 RCC.VCO1OutputFreq_Value=800000000 RCC.VCO2OutputFreq_Value=100781250 RCC.VCO3OutputFreq_Value=336000000 RCC.VCOInput1Freq_Value=5000000 RCC.VCOInput2Freq_Value=781250 RCC.VCOInput3Freq_Value=1000000 SH.ADCx_INN1.0=ADC1_INN1 SH.ADCx_INN1.ConfNb=1 SH.FMC_A0.0=FMC_A0 SH.FMC_A0.ConfNb=1 SH.FMC_A1.0=FMC_A1 SH.FMC_A1.ConfNb=1 SH.FMC_A10.0=FMC_A10 SH.FMC_A10.ConfNb=1 SH.FMC_A11.0=FMC_A11 SH.FMC_A11.ConfNb=1 SH.FMC_A12.0=FMC_A12 SH.FMC_A12.ConfNb=1 SH.FMC_A13.0=FMC_A13 SH.FMC_A13.ConfNb=1 SH.FMC_A14_BA0.0=FMC_BA0 SH.FMC_A14_BA0.1=FMC_A14 SH.FMC_A14_BA0.ConfNb=2 SH.FMC_A15_BA1.0=FMC_BA1 SH.FMC_A15_BA1.1=FMC_A15 SH.FMC_A15_BA1.ConfNb=2 SH.FMC_A16_CLE.0=FMC_A16 SH.FMC_A16_CLE.ConfNb=1 SH.FMC_A17_ALE.0=FMC_A17 SH.FMC_A17_ALE.ConfNb=1 SH.FMC_A18.0=FMC_A18 SH.FMC_A18.ConfNb=1 SH.FMC_A2.0=FMC_A2 SH.FMC_A2.ConfNb=1 SH.FMC_A3.0=FMC_A3 SH.FMC_A3.ConfNb=1 SH.FMC_A4.0=FMC_A4 SH.FMC_A4.ConfNb=1 SH.FMC_A5.0=FMC_A5 SH.FMC_A5.ConfNb=1 SH.FMC_A6.0=FMC_A6 SH.FMC_A6.ConfNb=1 SH.FMC_A7.0=FMC_A7 SH.FMC_A7.ConfNb=1 SH.FMC_A8.0=FMC_A8 SH.FMC_A8.ConfNb=1 SH.FMC_A9.0=FMC_A9 SH.FMC_A9.ConfNb=1 SH.FMC_D0_DA0.0=FMC_D0 SH.FMC_D0_DA0.ConfNb=1 SH.FMC_D10_DA10.0=FMC_D10 SH.FMC_D10_DA10.ConfNb=1 SH.FMC_D11_DA11.0=FMC_D11 SH.FMC_D11_DA11.ConfNb=1 SH.FMC_D12_DA12.0=FMC_D12 SH.FMC_D12_DA12.ConfNb=1 SH.FMC_D13_DA13.0=FMC_D13 SH.FMC_D13_DA13.ConfNb=1 SH.FMC_D14_DA14.0=FMC_D14 SH.FMC_D14_DA14.ConfNb=1 SH.FMC_D15_DA15.0=FMC_D15 SH.FMC_D15_DA15.ConfNb=1 SH.FMC_D16.0=FMC_D16 SH.FMC_D16.ConfNb=1 SH.FMC_D17.0=FMC_D17 SH.FMC_D17.ConfNb=1 SH.FMC_D18.0=FMC_D18 SH.FMC_D18.ConfNb=1 SH.FMC_D19.0=FMC_D19 SH.FMC_D19.ConfNb=1 SH.FMC_D1_DA1.0=FMC_D1 SH.FMC_D1_DA1.ConfNb=1 SH.FMC_D20.0=FMC_D20 SH.FMC_D20.ConfNb=1 SH.FMC_D21.0=FMC_D21 SH.FMC_D21.ConfNb=1 SH.FMC_D22.0=FMC_D22 SH.FMC_D22.ConfNb=1 SH.FMC_D23.0=FMC_D23 SH.FMC_D23.ConfNb=1 SH.FMC_D24.0=FMC_D24 SH.FMC_D24.ConfNb=1 SH.FMC_D25.0=FMC_D25 SH.FMC_D25.ConfNb=1 SH.FMC_D26.0=FMC_D26 SH.FMC_D26.ConfNb=1 SH.FMC_D27.0=FMC_D27 SH.FMC_D27.ConfNb=1 SH.FMC_D28.0=FMC_D28 SH.FMC_D28.ConfNb=1 SH.FMC_D29.0=FMC_D29 SH.FMC_D29.ConfNb=1 SH.FMC_D2_DA2.0=FMC_D2 SH.FMC_D2_DA2.ConfNb=1 SH.FMC_D30.0=FMC_D30 SH.FMC_D30.ConfNb=1 SH.FMC_D31.0=FMC_D31 SH.FMC_D31.ConfNb=1 SH.FMC_D3_DA3.0=FMC_D3 SH.FMC_D3_DA3.ConfNb=1 SH.FMC_D4_DA4.0=FMC_D4 SH.FMC_D4_DA4.ConfNb=1 SH.FMC_D5_DA5.0=FMC_D5 SH.FMC_D5_DA5.ConfNb=1 SH.FMC_D6_DA6.0=FMC_D6 SH.FMC_D6_DA6.ConfNb=1 SH.FMC_D7_DA7.0=FMC_D7 SH.FMC_D7_DA7.ConfNb=1 SH.FMC_D8_DA8.0=FMC_D8 SH.FMC_D8_DA8.ConfNb=1 SH.FMC_D9_DA9.0=FMC_D9 SH.FMC_D9_DA9.ConfNb=1 SH.FMC_NBL0.0=FMC_NBL0 SH.FMC_NBL0.ConfNb=1 SH.FMC_NBL1.0=FMC_NBL1 SH.FMC_NBL1.ConfNb=1 SH.FMC_NBL2.0=FMC_NBL2 SH.FMC_NBL2.ConfNb=1 SH.FMC_NBL3.0=FMC_NBL3 SH.FMC_NBL3.ConfNb=1 SH.FMC_NOE.0=FMC_NOE SH.FMC_NOE.ConfNb=1 SH.FMC_NWAIT.0=FMC_NWAIT SH.FMC_NWAIT.ConfNb=1 SH.FMC_NWE.0=FMC_NWE SH.FMC_NWE.ConfNb=1 SH.FMC_SDCLK.0=FMC_SDCLK SH.FMC_SDCLK.ConfNb=1 SH.FMC_SDNCAS.0=FMC_SDNCAS SH.FMC_SDNCAS.ConfNb=1 SH.FMC_SDNRAS.0=FMC_SDNRAS SH.FMC_SDNRAS.ConfNb=1 SH.FMC_SDNWE.0=FMC_SDNWE SH.FMC_SDNWE.ConfNb=1 SH.GPXTI8.0=GPIO_EXTI8 SH.GPXTI8.ConfNb=1 SH.S_CKOUTDFSDM1.0=DFSDM1_CKOUT SH.S_CKOUTDFSDM1.ConfNb=1 SH.S_DATAIN1DFSDM1.0=DFSDM1_DATIN1 SH.S_DATAIN1DFSDM1.ConfNb=1 USB_OTG_FS.IPParameters=VirtualMode USB_OTG_FS.VirtualMode=Device_Only USB_OTG_HS.IPParameters=VirtualMode-Device_HS USB_OTG_HS.VirtualMode-Device_HS=Device_HS VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick board=STM32H743I-EVAL2 boardIOC=true ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743eval/ozone/stm32h743.jdebug ================================================ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { Project.SetTraceSource ("Trace Pins"); Project.SetTraceTiming (100, 100, 100, 100); Project.SetSWO (0); Edit.SysVar (VAR_TRACE_CORE_CLOCK, 200000000); Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd"); Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); Project.AddSvdFile ("./STM32H743.svd"); Project.SetDevice ("STM32H743XI"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("50 MHz"); File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-stm32h743eval/cdc_msc.elf"); // File.Open ("../../../../../../examples/cmake-build-stm32h743eval_host1/host/cdc_msc_hid/cdc_msc_hid.elf"); } /********************************************************************* *0 * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging a RAM program on a Cortex-M target device * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // Exec.Reset(); // // VectorTableAddr = Elf.GetBaseAddr(); // // if (VectorTableAddr != 0xFFFFFFFF) { // // Util.Log("Resetting Program."); // // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetReset (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ void BeforeTargetConnect (void) { // // Trace pin init is done by J-Link script file as J-Link script files are IDE independent // //Project.SetJLinkScript("./ST_STM32H743_Traceconfig.pex"); } /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. * - Sets the PC register to program reset value. * - Sets the SP register to program reset value on Cortex-M. * ********************************************************************** */ void AfterTargetDownload (void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; VectorTableAddr = Elf.GetBaseAddr(); Util.Log("___"); if (VectorTableAddr == 0xFFFFFFFF) { Util.Log("Project file error: failed to get program base"); } else { SP = Target.ReadU32(VectorTableAddr); Target.SetReg("SP", SP); PC = Target.ReadU32(VectorTableAddr + 4); Target.SetReg("PC", PC); } } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743nucleo/board.cmake ================================================ set(MCU_VARIANT stm32h743xx) set(JLINK_DEVICE stm32h743xi) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H743xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H743 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-h743zi.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_OUTPUT_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 100; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } // Initialize USB clock RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.PLL3.PLL3M = 1; PeriphClkInitStruct.PLL3.PLL3N = 24; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 4; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_3; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743nucleo/board.mk ================================================ MCU_VARIANT = stm32h743xx CFLAGS += -DSTM32H743xx -DHSE_VALUE=8000000 LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash.ld # For flash-jlink target JLINK_DEVICE = stm32h743zi # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h743nucleo/cubemx/stm32h743nucleo.ioc ================================================ #MicroXplorer Configuration settings - do not modify CAD.formats= CAD.pinconfig= CAD.provider= ETH.IPParameters=MediaInterface ETH.MediaInterface=HAL_ETH_RMII_MODE File.Version=6 KeepUserPlacement=false Mcu.CPN=STM32H743ZIT6 Mcu.Family=STM32H7 Mcu.IP0=CORTEX_M7 Mcu.IP1=ETH Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SYS Mcu.IP5=USART3 Mcu.IP6=USB_OTG_FS Mcu.IPNb=7 Mcu.Name=STM32H743ZITx Mcu.Package=LQFP144 Mcu.Pin0=PC13 Mcu.Pin1=PC14-OSC32_IN (OSC32_IN) Mcu.Pin10=PC5 Mcu.Pin11=PB0 Mcu.Pin12=PB13 Mcu.Pin13=PB14 Mcu.Pin14=PD8 Mcu.Pin15=PD9 Mcu.Pin16=PD10 Mcu.Pin17=PG7 Mcu.Pin18=PA8 Mcu.Pin19=PA9 Mcu.Pin2=PC15-OSC32_OUT (OSC32_OUT) Mcu.Pin20=PA11 Mcu.Pin21=PA12 Mcu.Pin22=PG11 Mcu.Pin23=PG13 Mcu.Pin24=PE1 Mcu.Pin25=VP_SYS_VS_Systick Mcu.Pin3=PH0-OSC_IN (PH0) Mcu.Pin4=PH1-OSC_OUT (PH1) Mcu.Pin5=PC1 Mcu.Pin6=PA1 Mcu.Pin7=PA2 Mcu.Pin8=PA7 Mcu.Pin9=PC4 Mcu.PinsNb=26 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32H743ZITx MxCube.Version=6.9.2 MxDb.Version=DB.6.0.92 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA1.Locked=true PA1.Mode=RMII PA1.Signal=ETH_REF_CLK PA11.Locked=true PA11.Mode=Device_Only PA11.Signal=USB_OTG_FS_DM PA12.Locked=true PA12.Mode=Device_Only PA12.Signal=USB_OTG_FS_DP PA2.Locked=true PA2.Mode=RMII PA2.Signal=ETH_MDIO PA7.Locked=true PA7.Mode=RMII PA7.Signal=ETH_CRS_DV PA8.Locked=true PA8.Mode=Activate_SOF_FS PA8.Signal=USB_OTG_FS_SOF PA9.Locked=true PA9.Mode=Activate_VBUS PA9.Signal=USB_OTG_FS_VBUS PB0.GPIOParameters=GPIO_Label PB0.GPIO_Label=LD1 [Green Led] PB0.Locked=true PB0.Signal=GPIO_Output PB13.Locked=true PB13.Mode=RMII PB13.Signal=ETH_TXD1 PB14.GPIOParameters=GPIO_Label PB14.GPIO_Label=LD3 [Red Led] PB14.Locked=true PB14.Signal=GPIO_Output PC1.Locked=true PC1.Mode=RMII PC1.Signal=ETH_MDC PC13.GPIOParameters=GPIO_Label PC13.GPIO_Label=B1 [Blue PushButton] PC13.Locked=true PC13.Signal=GPIO_Input PC14-OSC32_IN\ (OSC32_IN).Locked=true PC14-OSC32_IN\ (OSC32_IN).Mode=LSE-External-Oscillator PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN PC15-OSC32_OUT\ (OSC32_OUT).Locked=true PC15-OSC32_OUT\ (OSC32_OUT).Mode=LSE-External-Oscillator PC15-OSC32_OUT\ (OSC32_OUT).Signal=RCC_OSC32_OUT PC4.Locked=true PC4.Mode=RMII PC4.Signal=ETH_RXD0 PC5.Locked=true PC5.Mode=RMII PC5.Signal=ETH_RXD1 PD10.GPIOParameters=GPIO_Label PD10.GPIO_Label=USB_OTG_FS_PWR_EN PD10.Locked=true PD10.Signal=GPIO_Output PD8.GPIOParameters=GPIO_Label PD8.GPIO_Label=STLINK_RX PD8.Locked=true PD8.Mode=Asynchronous PD8.Signal=USART3_TX PD9.GPIOParameters=GPIO_Label PD9.GPIO_Label=STLINK_TX PD9.Locked=true PD9.Mode=Asynchronous PD9.Signal=USART3_RX PE1.GPIOParameters=GPIO_Label PE1.GPIO_Label=LD2 [Yellow Led] PE1.Locked=true PE1.Signal=GPIO_Output PG11.Locked=true PG11.Mode=RMII PG11.Signal=ETH_TX_EN PG13.Locked=true PG13.Mode=RMII PG13.Signal=ETH_TXD0 PG7.GPIOParameters=GPIO_Label PG7.GPIO_Label=USB_OTG_FS_OVCR PG7.Locked=true PG7.Signal=GPXTI7 PH0-OSC_IN\ (PH0).Locked=true PH0-OSC_IN\ (PH0).Mode=HSE-External-Clock-Source PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN PH1-OSC_OUT\ (PH1).Locked=true PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32H743ZITx ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.11.1 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=2 ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain=STM32CubeIDE ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=stm32h743nucleo.ioc ProjectManager.ProjectName=stm32h743nucleo ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,false-3-MX_ETH_Init-ETH-false-HAL-true,4-MX_USART3_UART_Init-USART3-false-HAL-true,5-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true RCC.ADCFreq_Value=16125000 RCC.AHB12Freq_Value=200000000 RCC.AHB4Freq_Value=200000000 RCC.APB1Freq_Value=100000000 RCC.APB2Freq_Value=100000000 RCC.APB3Freq_Value=100000000 RCC.APB4Freq_Value=100000000 RCC.AXIClockFreq_Value=200000000 RCC.CECFreq_Value=32000 RCC.CKPERFreq_Value=64000000 RCC.CortexFreq_Value=400000000 RCC.CpuClockFreq_Value=400000000 RCC.D1CPREFreq_Value=400000000 RCC.D1PPRE=RCC_APB3_DIV2 RCC.D2PPRE1=RCC_APB1_DIV2 RCC.D2PPRE2=RCC_APB2_DIV2 RCC.D3PPRE=RCC_APB4_DIV2 RCC.DFSDMACLkFreq_Value=200000000 RCC.DFSDMFreq_Value=100000000 RCC.DIVM1=1 RCC.DIVM3=1 RCC.DIVN1=100 RCC.DIVN3=24 RCC.DIVP1Freq_Value=400000000 RCC.DIVP2Freq_Value=16125000 RCC.DIVP3Freq_Value=96000000 RCC.DIVQ1=4 RCC.DIVQ1Freq_Value=200000000 RCC.DIVQ2Freq_Value=16125000 RCC.DIVQ3=4 RCC.DIVQ3Freq_Value=48000000 RCC.DIVR1Freq_Value=400000000 RCC.DIVR2Freq_Value=16125000 RCC.DIVR3Freq_Value=96000000 RCC.FDCANFreq_Value=200000000 RCC.FMCFreq_Value=200000000 RCC.FamilyName=M RCC.HCLK3ClockFreq_Value=200000000 RCC.HCLKFreq_Value=200000000 RCC.HPRE=RCC_HCLK_DIV2 RCC.HRTIMFreq_Value=200000000 RCC.HSE_VALUE=8000000 RCC.I2C123Freq_Value=100000000 RCC.I2C4Freq_Value=100000000 RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM3,DIVN1,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,PWR_Regulator_Voltage_Scale,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value RCC.LPTIM1Freq_Value=100000000 RCC.LPTIM2Freq_Value=100000000 RCC.LPTIM345Freq_Value=100000000 RCC.LPUART1Freq_Value=100000000 RCC.LTDCFreq_Value=96000000 RCC.MCO1PinFreq_Value=64000000 RCC.MCO2PinFreq_Value=400000000 RCC.PLL2FRACN=0 RCC.PLL3FRACN=0 RCC.PLLFRACN=0 RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.PWR_Regulator_Voltage_Scale=PWR_REGULATOR_VOLTAGE_SCALE1 RCC.QSPIFreq_Value=200000000 RCC.RNGFreq_Value=48000000 RCC.RTCFreq_Value=32000 RCC.SAI1Freq_Value=200000000 RCC.SAI23Freq_Value=200000000 RCC.SAI4AFreq_Value=200000000 RCC.SAI4BFreq_Value=200000000 RCC.SDMMCFreq_Value=200000000 RCC.SPDIFRXFreq_Value=200000000 RCC.SPI123Freq_Value=200000000 RCC.SPI45Freq_Value=100000000 RCC.SPI6Freq_Value=100000000 RCC.SWPMI1Freq_Value=100000000 RCC.SYSCLKFreq_VALUE=400000000 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.Tim1OutputFreq_Value=200000000 RCC.Tim2OutputFreq_Value=200000000 RCC.TraceFreq_Value=64000000 RCC.USART16Freq_Value=100000000 RCC.USART234578Freq_Value=100000000 RCC.USBCLockSelection=RCC_USBCLKSOURCE_PLL3 RCC.USBFreq_Value=48000000 RCC.VCO1OutputFreq_Value=800000000 RCC.VCO2OutputFreq_Value=32250000 RCC.VCO3OutputFreq_Value=192000000 RCC.VCOInput1Freq_Value=8000000 RCC.VCOInput2Freq_Value=250000 RCC.VCOInput3Freq_Value=8000000 SH.GPXTI7.0=GPIO_EXTI7 SH.GPXTI7.ConfNb=1 USART3.IPParameters=VirtualMode-Asynchronous USART3.VirtualMode-Asynchronous=VM_ASYNC USB_OTG_FS.IPParameters=VirtualMode USB_OTG_FS.VirtualMode=Device_Only VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick board=NUCLEO-H743ZI2 boardIOC=true ================================================ FILE: hw/bsp/stm32h7/boards/stm32h745disco/board.cmake ================================================ set(MCU_VARIANT stm32h745xx) set(JLINK_DEVICE stm32h745xi_m7) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_CM7.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H745xx HSE_VALUE=25000000 CORE_CM7 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h745disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H745 Discovery url: https://www.st.com/en/evaluation-tools/stm32h745i-disco.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 static board_pindef_t board_pindef[] = { { // LED .port = GPIOJ, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_5, .Mode = GPIO_MODE_OUTPUT_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /*!< Supply configuration update enable */ /* For STM32H750XB, use "HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);" */ HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL1 for System Clock */ RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 160; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* PLL3 for USB Clock */ PeriphClkInitStruct.PLL3.PLL3M = 25; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure bus clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /*activate CSI clock mondatory for I/O Compensation Cell*/ __HAL_RCC_CSI_ENABLE() ; /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE() ; /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h745disco/board.mk ================================================ # STM32H745I-DISCO uses OTG_FS # FIXME: Reset enumerates, un/replug USB plug does not enumerate MCU_VARIANT = stm32h745xx CFLAGS += -DSTM32H745xx -DCORE_CM7 -DHSE_VALUE=25000000 # Default is FulSpeed port PORT ?= 0 LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash_CM7.ld LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h745xx_flash_CM7.icf # For flash-jlink target JLINK_DEVICE = stm32h745xi_m7 # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h747disco/board.cmake ================================================ set(MCU_VARIANT stm32h747xx) set(JLINK_DEVICE stm32h747xi_m7) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_CM7.icf) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) # device default to PORT 1 High Speed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H747xx HSE_VALUE=25000000 CORE_CM7 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h747disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H747 Discovery url: https://www.st.com/en/evaluation-tools/stm32h747i-disco.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 1 // USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 #define ULPI_PINS \ {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOH, GPIO_PIN_4 }, {GPIOI, GPIO_PIN_11} #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 static board_pindef_t board_pindef[] = { { // LED .port = GPIOI, .pin_init = { .Pin = GPIO_PIN_12, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 0 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /*!< Supply configuration update enable */ /* For STM32H750XB, use "HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);" */ HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL1 for System Clock */ RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 160; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* PLL3 for USB Clock */ PeriphClkInitStruct.PLL3.PLL3M = 25; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure bus clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /*activate CSI clock mondatory for I/O Compensation Cell*/ __HAL_RCC_CSI_ENABLE() ; /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE() ; /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h747disco/board.mk ================================================ # STM32H747I-DISCO uses OTG_FS # FIXME: Reset enumerates, un/replug USB plug does not enumerate MCU_VARIANT = stm32h747xx CFLAGS += -DSTM32H747xx -DCORE_CM7 -DHSE_VALUE=25000000 # Default is FulSpeed port PORT ?= 0 LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash_CM7.ld LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h747xx_flash_CM7.icf # For flash-jlink target JLINK_DEVICE = stm32h747xi_m7 # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake ================================================ set(MCU_VARIANT stm32h750xx) set(JLINK_DEVICE stm32h750vb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H750xx HSE_VALUE=25000000 CORE_CM7 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750_weact/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H750 WeAct url: https://www.adafruit.com/product/5032 */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 static board_pindef_t board_pindef[] = { { // LED .port = GPIOE, .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; // Supply configuration update enable HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); // Configure the main internal regulator output voltage __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} // Configure the PLL clock source __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); // Initializes the CPU, AHB and APB busses clocks RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 96; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB busses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_SPI4 |RCC_PERIPHCLK_SPI1|RCC_PERIPHCLK_USB |RCC_PERIPHCLK_QSPI; PeriphClkInitStruct.PLL3.PLL3M = 10; PeriphClkInitStruct.PLL3.PLL3N = 96; PeriphClkInitStruct.PLL3.PLL3P = 5; PeriphClkInitStruct.PLL3.PLL3Q = 5; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1; PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); // Enable USB Voltage detector HAL_PWREx_EnableUSBVoltageDetector(); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750_weact/board.mk ================================================ # STM32H745I-DISCO uses OTG_FS # FIXME: Reset enumerates, un/replug USB plug does not enumerate MCU_VARIANT = stm32h750xx CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=25000000 LD_FILE_GCC = $(BOARD_PATH)/stm32h750xx_flash_CM7.ld # For flash-jlink target JLINK_DEVICE = stm32h750vb # flash target using on-board stlink flash: flash-jlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** ** Abstract : Linker script for STM32H7 series ** 128Kbytes FLASH and 1Mbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed �as is,� without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2019 STMicroelectronics. ** All rights reserved. ** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** **************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1M ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake ================================================ set(MCU_VARIANT stm32h750xx) set(JLINK_DEVICE stm32h750xb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H750xx HSE_VALUE=25000000 CORE_CM7 ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750bdk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 H750b Discovery Kit url: https://www.st.com/en/evaluation-tools/stm32h750b-dk.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // UART #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_VBUS0_EN 4 static board_pindef_t board_pindef[] = { { // LED .port = GPIOJ, .pin_init = { .Pin = GPIO_PIN_2, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOC, .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_11, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // VBUS0 EN .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_5, .Mode = GPIO_MODE_OUTPUT_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /*!< Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL1 for System Clock */ RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 160; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* PLL3 for USB Clock */ PeriphClkInitStruct.PLL3.PLL3M = 25; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure bus clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /*activate CSI clock mondatory for I/O Compensation Cell*/ __HAL_RCC_CSI_ENABLE() ; /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE() ; /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } static inline void board_init2(void) { // For this board does nothing } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { board_pindef_t* pindef = &board_pindef[PINID_VBUS0_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750bdk/board.mk ================================================ # STM32H745I-DISCO uses OTG_FS # FIXME: Reset enumerates, un/replug USB plug does not enumerate MCU_VARIANT = stm32h750xx CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=25000000 LD_FILE_GCC = $(BOARD_PATH)/stm32h750xx_flash_CM7.ld # For flash-jlink target JLINK_DEVICE = stm32h750xb # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32h7/boards/stm32h750bdk/stm32h750xx_flash_CM7.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** ** Abstract : Linker script for STM32H7 series ** 128Kbytes FLASH and 1Mbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed �as is,� without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2019 STMicroelectronics. ** All rights reserved. ** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** **************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1M ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/boards/waveshare_openh743i/board.cmake ================================================ set(MCU_VARIANT stm32h743xx) set(JLINK_DEVICE stm32h743xi) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) # device default to PORT 1 High Speed if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif() if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif() function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32H743xx HSE_VALUE=8000000 HAL_TIM_MODULE_ENABLED ) target_sources(${TARGET} PUBLIC ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_tim.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_tim_ex.c ) endfunction() ================================================ FILE: hw/bsp/stm32h7/boards/waveshare_openh743i/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 * Ha Thach (tinyusb.org) * Benjamin Evans * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: Waveshare Open H743i url: https://www.waveshare.com/openh743i-c-standard.htm */ #ifndef BOARD_H_ #define BOARD_H_ /* ** BOARD SETUP ** * * NOTE: This board has bad signal integrity so you may experience some problems. * This setup assumes you have an openh743i-c Core and breakout board. For the HS * examples it also assumes you have a waveshare USB3300 breakout board plugged * into the ULPI PMOD header on the openh743i-c. * * UART Debugging: * Due to pin conflicts in the HS configuration, this BSP uses USART3 (PD8, PD9). * As such, you won't be able to use the UART to USB converter on board and will * require an external UART to USB converter. You could use the waveshare FT232 * USB UART Board (micro) but any 3.3V UART to USB converter will be fine. * * Fullspeed: * If VBUS sense is enabled, ensure the PA9-VBUS jumper is connected on the core * board. Connect the PB6 jumper for the LED and the Wakeup - PA0 jumper for the * button. Connect the USB cable to the USB connector on the core board. * * High Speed: * Remove all jumpers from the openh743i-c (especially the USART1 jumpers as the * pins conflict). Connect the PB6 jumper for the LED and the Wakeup - PA0 * jumper for the button. * * The reset pin on the ULPI PMOD port is not connected to the MCU. You'll need * to solder a wire from the RST pin on the USB3300 to a pin of your choosing on * the openh743i-c board (this example assumes you've used PD14 as specified with * the ULPI_RST_PORT and ULPI_RST_PIN defines below). * * Preferably power the board using the external 5VDC jack. Connect the USB cable * to the USB connector on the ULPI board. Adjust delays in this file as required. * * If you're having trouble, ask a question on the tinyUSB Github Discussion boards. * * Have fun! * */ #ifdef __cplusplus extern "C" { #endif // Need to change jumper setting J7 and J8 from RS-232 to STLink #define UART_DEV USART3 #define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 1 #define OTG_HS_VBUS_SENSE 0 // USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 #define ULPI_PINS \ {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOC, GPIO_PIN_2 }, {GPIOC, GPIO_PIN_3 } // ULPI PHY reset pin used by walkaround #define ULPI_RST_PORT GPIOD #define ULPI_RST_PIN GPIO_PIN_14 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 static board_pindef_t board_pindef[] = { { // LED .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // Button .port = GPIOA, .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, .active_state = 1 }, { // UART TX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // UART RX .port = GPIOD, .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, .active_state = 0 }, { // I2C SCL for MFX VBUS .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_6, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_I2C1 }, .active_state = 0 }, { // I2C SDA for MFX VBUS .port = GPIOB, .pin_init = { .Pin = GPIO_PIN_7, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF4_I2C1 }, .active_state = 1 }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; __HAL_RCC_SYSCFG_CLK_ENABLE(); // Supply configuration update enable HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); // Configure the main internal regulator output voltage __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) { } // Macro to configure the PLL clock source __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); // Initializes the RCC Oscillators according to the specified parameters in the RCC_OscInitTypeDef structure. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 2; RCC_OscInitStruct.PLL.PLLN = 240; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB | RCC_PERIPHCLK_USART3; PeriphClkInitStruct.PLL3.PLL3M = 8; PeriphClkInitStruct.PLL3.PLL3N = 336; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 7; PeriphClkInitStruct.PLL3.PLL3R = 2; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0; PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_PLL3; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); __HAL_RCC_CSI_ENABLE(); // Enable SYSCFG clock mondatory for I/O Compensation Cell __HAL_RCC_SYSCFG_CLK_ENABLE(); // Enables the I/O Compensation Cell HAL_EnableCompensationCell(); // Enable voltage detector HAL_PWREx_EnableUSBVoltageDetector(); } static inline void timer_board_delay(TIM_HandleTypeDef* tim_hdl, uint32_t ms) { uint32_t startMs = __HAL_TIM_GET_COUNTER(tim_hdl); while ((__HAL_TIM_GET_COUNTER(tim_hdl) - startMs) < ms) { asm("nop"); //do nothing } } static inline void board_init2(void) { // walkaround for resetting the ULPI PHY using Timer since systick is not // available when RTOS is used. // Init timer TIM_HandleTypeDef tim2Handle; TIM_ClockConfigTypeDef sClockSourceConfig = {0}; GPIO_InitTypeDef GPIO_InitStruct; // ULPI_RST GPIO_InitStruct.Pin = ULPI_RST_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = 0; HAL_GPIO_Init(ULPI_RST_PORT, &GPIO_InitStruct); __HAL_RCC_TIM2_CLK_ENABLE(); //Assuming timer clock is running at 260Mhz this should configure the timer counter to 1000Hz tim2Handle.Instance = TIM2; tim2Handle.Init.Prescaler = 60000U - 1U; tim2Handle.Init.CounterMode = TIM_COUNTERMODE_UP; tim2Handle.Init.Period = 0xFFFFFFFFU; tim2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; tim2Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; HAL_TIM_Base_Init(&tim2Handle); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&tim2Handle, &sClockSourceConfig); //Start the timer HAL_TIM_Base_Start(&tim2Handle); // Reset PHY, change the delays as you see fit timer_board_delay(&tim2Handle, 5U); HAL_GPIO_WritePin(ULPI_RST_PORT, ULPI_RST_PIN, GPIO_PIN_SET); timer_board_delay(&tim2Handle, 20U); HAL_GPIO_WritePin(ULPI_RST_PORT, ULPI_RST_PIN, GPIO_PIN_RESET); timer_board_delay(&tim2Handle, 20U); //Disable the timer used for delays HAL_TIM_Base_Stop(&tim2Handle); __HAL_RCC_TIM2_CLK_DISABLE(); } // need to short a jumper void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7/boards/waveshare_openh743i/board.mk ================================================ MCU_VARIANT = stm32h743xx CFLAGS += -DSTM32H743xx -DHSE_VALUE=8000000 RHPORT_SPEED = OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 0 LD_FILE_GCC = $(FAMILY_PATH)/linker/stm32h743xx_flash.ld # Use Timer module for ULPI PHY reset CFLAGS += -DHAL_TIM_MODULE_ENABLED SRC_C += \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_tim.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_tim_ex.c # For flash-jlink target JLINK_DEVICE = stm32h743ii # flash target using jlink flash: flash-jlink ================================================ FILE: hw/bsp/stm32h7/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 * William D. Jones (thor0505@comcast.net), * Ha Thach (tinyusb.org) * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32h7xx_hal.h" #include "bsp/board_api.h" TU_ATTR_UNUSED static void Error_Handler(void) { } typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16, } }; #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ // Despite being call USB2_OTG_FS on some MCUs // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } // Despite being call USB1_OTG_HS on some MCUs // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port void OTG_HS_IRQHandler(void) { tusb_int_handler(1, true); } #ifdef TRACE_ETM static void trace_etm_init(void) { // H7 trace pin is PE2 to PE6 GPIO_InitTypeDef gpio_init; gpio_init.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH; gpio_init.Alternate = GPIO_AF0_TRACE; HAL_GPIO_Init(GPIOE, &gpio_init); // Enable trace clk, also in D1 and D3 domain DBGMCU->CR |= DBGMCU_CR_DBG_TRACECKEN | DBGMCU_CR_DBG_CKD1EN | DBGMCU_CR_DBG_CKD3EN; } #else #define trace_etm_init() #endif void board_init(void) { SCB_EnableICache(); HAL_Init(); // Implemented in board.h SystemClock_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); #ifdef __HAL_RCC_GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE(); #endif __HAL_RCC_GPIOJ_CLK_ENABLE(); trace_etm_init(); for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000u); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1UL; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) #ifdef USB_OTG_FS_PERIPH_BASE NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #elif CFG_TUSB_OS == OPT_OS_THREADX // Disable SysTick before kernel entry; _tx_initialize_low_level() will re-configure it SysTick->CTRL &= ~1UL; #endif GPIO_InitTypeDef GPIO_InitStruct; #ifdef UART_DEV UART_CLK_EN(); HAL_UART_Init(&UartHandle); #endif //------------- USB FS -------------// // Despite being call USB2_OTG // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port // PA9 VUSB, PA10 ID, PA11 DM, PA12 DP // Configure DM DP Pins GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // This for ID line debug GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // https://community.st.com/s/question/0D50X00009XkYZLSA3/stm32h7-nucleo-usb-fs-cdc // TODO: Board init actually works fine without this line. HAL_PWREx_EnableUSBVoltageDetector(); __HAL_RCC_USB2_OTG_FS_CLK_ENABLE(); #if OTG_FS_VBUS_SENSE // Configure VBUS Pin GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif //------------- USB HS -------------// #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port struct { GPIO_TypeDef* port; uint32_t pin; } const ulpi_pins[] = { ULPI_PINS }; for (uint8_t i=0; i < sizeof(ulpi_pins)/sizeof(ulpi_pins[0]); i++) { GPIO_InitStruct.Pin = ulpi_pins[i].pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; HAL_GPIO_Init(ulpi_pins[i].port, &GPIO_InitStruct); } // Enable USB HS & ULPI Clocks __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE(); __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif #endif HAL_PWREx_EnableUSBVoltageDetector(); board_init2(); // optional init // Turn off device vbus #if CFG_TUD_ENABLED board_vbus_set(BOARD_TUD_RHPORT, false); #endif // Turn on host vbus #if CFG_TUH_ENABLED board_vbus_set(BOARD_TUH_RHPORT, true); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { #ifdef UART_DEV int count = 0; // clear overrun error if any if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE)) { __HAL_UART_CLEAR_FLAG(&UartHandle, UART_CLEAR_OREF); } for (int i = 0; i < len; i++) { if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE)) { buf[i] = (uint8_t) UartHandle.Instance->RDR; count++; } else { break; } } return count; #else (void) buf; (void) len; return 0; #endif } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return -1; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #elif CFG_TUSB_OS == OPT_OS_THREADX // Keep HAL_GetTick() working for HAL functions called from board_init() void osal_threadx_tick_cb(void) { HAL_IncTick(); } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32h7/family.cmake ================================================ include_guard() set(ST_FAMILY h7) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(ST_MFXSTM32L152 ${TOP}/hw/mcu/st/stm32-mfxstm32l152) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m7 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32H7 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) # Most F7 does not has built-in HS PHY set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) if(NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) endif() #------------------------------------ # BOARD_TARGET #------------------------------------ # only need to be built ONCE for all examples function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32H7) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}") if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC -nostartfiles --specs=nosys.specs --specs=nano.specs) endif () set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32h7/family.mk ================================================ ST_FAMILY = h7 ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/${ST_PREFIX}_hal_driver ST_MFXSTM32L152 = hw/mcu/st/stm32-mfxstm32l152 UF2_FAMILY_ID = 0x6db66082 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m7 # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_FULL_SPEED RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 # Determine RHPORT_DEVICE_SPEED if not defined ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # Determine RHPORT_HOST_SPEED if not defined ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ # GCC Flags # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -flto \ -Wno-error=cast-align \ -Wno-error=unused-parameter \ LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_dma.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c \ ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c \ ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart_ex.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32h7/linker/stm32h723xx_flash.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32H7 series ** 1024Kbytes FLASH and 560Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2021 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** **************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM_D1 AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM_D1 /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM_D1 .usbx_data 0x24027000 (NOLOAD): { *(.UsbHpcdSection) } >RAM_D1 .uart_bss 0x24028000 (NOLOAD): { *(.UsbxAppSection) } >RAM_D1 .usbx_bss 0x24029000 (NOLOAD): { *(.UsbxPoolSection) } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/linker/stm32h743xx_flash.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32H743XIHx Device with ** 2048KByte FLASH, 128KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM_D1 AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM_D1 /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/linker/stm32h745xx_flash_CM7.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** ** Abstract : Linker script for STM32H7 series ** 1024Kbytes FLASH and 192Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2019 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** ** Abstract : Linker script for STM32H7 series ** 1024Kbytes FLASH and 192Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2019 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7/stm32h7xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32h7xx_hal_conf_template.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32h7xx_hal_conf.h. ****************************************************************************** * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H7xx_HAL_CONF_H #define STM32H7xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED #define HAL_ADC_MODULE_ENABLED /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED /* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ /* #define HAL_EXTI_MODULE_ENABLED */ /* #define HAL_FDCAN_MODULE_ENABLED */ #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED /* #define HAL_HASH_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_HRTIM_MODULE_ENABLED */ /* #define HAL_HSEM_MODULE_ENABLED */ #define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ /* #define HAL_MDIOS_MODULE_ENABLED */ /* #define HAL_MDMA_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_OPAMP_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED /* #define HAL_QSPI_MODULE_ENABLED */ /* #define HAL_RAMECC_MODULE_ENABLED */ #define HAL_RCC_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SAI_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ #define HAL_SPI_MODULE_ENABLED /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SWPMI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) //#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #error HSE_VALUE is not defined #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal oscillator (CSI) default value. * This value is the default CSI value after Reset. */ #if !defined (CSI_VALUE) #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* CSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ #if !defined (LSI_VALUE) #define LSI_VALUE ((uint32_t)32000) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External clock source for I2S peripheral * This value is used by the I2S HAL module to compute the I2S clock source * frequency, this source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (0x0FUL) /*!< tick interrupt priority */ #define USE_RTOS 0 #define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */ #define USE_SPI_CRC 1U /*!< use CRC in SPI */ #define USE_FLASH_ECC 0U /*!< use ECC error management in FLASH */ #define USE_SDIO_TRANSCEIVER 0U /*!< use SDIO Transceiver */ #define SDIO_MAX_IO_NUMBER 7U /*!< SDIO device support maximum IO number */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ #define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ #define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U /* GFXMMU register callback disabled */ #define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ #define USE_HAL_OSPI_REGISTER_CALLBACKS 0U /* OSPI register callback disabled */ #define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SDIO_REGISTER_CALLBACKS 0U /* SDIO register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################### Ethernet Configuration ######################### */ #define ETH_TX_DESC_CNT 4U /* number of Ethernet Tx DMA descriptors */ #define ETH_RX_DESC_CNT 4U /* number of Ethernet Rx DMA descriptors */ #define ETH_MAC_ADDR0 (0x02UL) #define ETH_MAC_ADDR1 (0x00UL) #define ETH_MAC_ADDR2 (0x00UL) #define ETH_MAC_ADDR3 (0x00UL) #define ETH_MAC_ADDR4 (0x00UL) #define ETH_MAC_ADDR5 (0x00UL) /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1 */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32h7xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32h7xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32h7xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_MDMA_MODULE_ENABLED #include "stm32h7xx_hal_mdma.h" #endif /* HAL_MDMA_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32h7xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32h7xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32h7xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DSI_MODULE_ENABLED #include "stm32h7xx_hal_dsi.h" #endif /* HAL_DSI_MODULE_ENABLED */ #ifdef HAL_DFSDM_MODULE_ENABLED #include "stm32h7xx_hal_dfsdm.h" #endif /* HAL_DFSDM_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32h7xx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32h7xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32h7xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32h7xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32h7xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32h7xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32h7xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32h7xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32h7xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32h7xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32h7xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_HRTIM_MODULE_ENABLED #include "stm32h7xx_hal_hrtim.h" #endif /* HAL_HRTIM_MODULE_ENABLED */ #ifdef HAL_HSEM_MODULE_ENABLED #include "stm32h7xx_hal_hsem.h" #endif /* HAL_HSEM_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32h7xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32h7xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32h7xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32h7xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32h7xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32h7xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_JPEG_MODULE_ENABLED #include "stm32h7xx_hal_jpeg.h" #endif /* HAL_JPEG_MODULE_ENABLED */ #ifdef HAL_MDIOS_MODULE_ENABLED #include "stm32h7xx_hal_mdios.h" #endif /* HAL_MDIOS_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED #include "stm32h7xx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32h7xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32h7xx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32h7xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32h7xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32h7xx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_RAMECC_MODULE_ENABLED #include "stm32h7xx_hal_ramecc.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32h7xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32h7xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32h7xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32h7xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32h7xx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32h7xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32h7xx_hal_spdifrx.h" #endif /* HAL_SPDIFRX_MODULE_ENABLED */ #ifdef HAL_SWPMI_MODULE_ENABLED #include "stm32h7xx_hal_swpmi.h" #endif /* HAL_SWPMI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32h7xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32h7xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32h7xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32h7xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32h7xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32h7xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32h7xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32h7xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32h7xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32H7xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32h7rs/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32h7rsxx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<port, pindef->pin_init.Pin, GPIO_PIN_SET); __HAL_RCC_I2C3_CLK_ENABLE(); __HAL_RCC_I2C3_FORCE_RESET(); __HAL_RCC_I2C3_RELEASE_RESET(); if (HAL_I2C_Init(&i2c_handle) != HAL_OK) { return HAL_ERROR; } NVIC_SetPriority(EXTI8_IRQn, 12); NVIC_EnableIRQ(EXTI8_IRQn); return 0; } int32_t board_tcpp0203_deinit(void) { return 0; } int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } static inline void board_init2(void) { TCPP0203_IO_t io_ctx; io_ctx.Address = TCPP0203_I2C_ADDRESS_X68; io_ctx.Init = board_tcpp0203_init; io_ctx.DeInit = board_tcpp0203_deinit; io_ctx.ReadReg = i2c_readreg; io_ctx.WriteReg = i2c_writereg; TU_ASSERT(TCPP0203_RegisterBusIO(&tcpp0203_obj, &io_ctx) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_Init(&tcpp0203_obj) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); } void board_vbus_set(uint8_t rhport, bool state) { (void) state; if (rhport == 1) { TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } void EXTI8_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_8); if (tcpp0203_obj.IsInitialized) { TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32h7rs/boards/stm32h7s3nucleo/board.mk ================================================ MCU_VARIANT = stm32h7s3xx CFLAGS += -DSTM32H7S3xx # For flash-jlink target JLINK_DEVICE = stm32h7s3l8 # flash target using on-board stlink flash: flash-stlink SRC_C += \ $(ST_TCPP0203)/tcpp0203.c \ $(ST_TCPP0203)/tcpp0203_reg.c \ INC += \ $(TOP)/$(ST_TCPP0203) \ ================================================ FILE: hw/bsp/stm32h7rs/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 * William D. Jones (thor0505@comcast.net), * Ha Thach (tinyusb.org) * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32h7rsxx_hal.h" #include "bsp/board_api.h" TU_ATTR_UNUSED static void Error_Handler(void) { } typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16, } }; #endif #ifndef SWO_FREQ #define SWO_FREQ 4000000 #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ // Despite being call USB2_OTG_FS on some MCUs // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } // Despite being call USB1_OTG_HS on some MCUs // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port void OTG_HS_IRQHandler(void) { tusb_int_handler(1, true); } #ifdef TRACE_ETM void trace_etm_init(void) { // H7 trace pin is PE2 to PE6 GPIO_InitTypeDef gpio_init; gpio_init.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH; gpio_init.Alternate = GPIO_AF0_TRACE; HAL_GPIO_Init(GPIOE, &gpio_init); // Enable trace clk, also in D1 and D3 domain DBGMCU->CR |= DBGMCU_CR_DBG_TRACECKEN | DBGMCU_CR_DBG_CKD1EN | DBGMCU_CR_DBG_CKD3EN; } #else #define trace_etm_init() #endif #ifdef LOGGER_SWO void log_swo_init(void) { //UNLOCK FUNNEL *(volatile uint32_t*)(0x5C004FB0) = 0xC5ACCE55; // SWTF_LAR *(volatile uint32_t*)(0x5C003FB0) = 0xC5ACCE55; // SWO_LAR //SWO current output divisor register //To change it, you can use the following rule // value = (CPU_Freq / 3 / SWO_Freq) - 1 *(volatile uint32_t*)(0x5C003010) = ((SystemCoreClock / 3 / SWO_FREQ) - 1); // SWO_CODR //SWO selected pin protocol register *(volatile uint32_t*)(0x5C0030F0) = 0x00000002; // SWO_SPPR //Enable ITM input of SWO trace funnel *(volatile uint32_t*)(0x5C004000) |= 0x00000001; // SWFT_CTRL } #else #define log_swo_init() #endif static void MPU_AdjustRegionAddressSize(uint32_t Address, uint32_t Size, MPU_Region_InitTypeDef* pInit); static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct = {0}; uint32_t index = MPU_REGION_NUMBER0; uint32_t address; uint32_t size; /* Disable the MPU */ HAL_MPU_Disable(); /* Initialize the background region */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = index; MPU_InitStruct.BaseAddress = 0x0; MPU_InitStruct.Size = MPU_REGION_SIZE_4GB; MPU_InitStruct.SubRegionDisable = 0x87; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); index++; /* Initialize the non cacheable region */ #if defined ( __ICCARM__ ) /* get the region attribute form the icf file */ extern uint32_t NONCACHEABLEBUFFER_start; extern uint32_t NONCACHEABLEBUFFER_size; address = (uint32_t)&NONCACHEABLEBUFFER_start; size = (uint32_t)&NONCACHEABLEBUFFER_size; #elif defined (__CC_ARM) || defined(__ARMCC_VERSION) extern uint32_t Image$$RW_NONCACHEABLEBUFFER$$Base; extern uint32_t Image$$RW_NONCACHEABLEBUFFER$$Length; extern uint32_t Image$$RW_NONCACHEABLEBUFFER$$ZI$$Length; address = (uint32_t)&Image$$RW_NONCACHEABLEBUFFER$$Base; size = (uint32_t)&Image$$RW_NONCACHEABLEBUFFER$$Length + (uint32_t)&Image$$RW_NONCACHEABLEBUFFER$$ZI$$Length; #elif defined ( __GNUC__ ) extern int __NONCACHEABLEBUFFER_BEGIN; extern int __NONCACHEABLEBUFFER_END; address = (uint32_t)&__NONCACHEABLEBUFFER_BEGIN; size = (uint32_t)&__NONCACHEABLEBUFFER_END - (uint32_t)&__NONCACHEABLEBUFFER_BEGIN; #else #error "Compiler toolchain is unsupported" #endif if (size != 0) { /* Configure the MPU attributes as Normal Non Cacheable */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = index; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_AdjustRegionAddressSize(address, size, &MPU_InitStruct); HAL_MPU_ConfigRegion(&MPU_InitStruct); index++; } /* Initialize the region corresponding to the execution area (external or internal flash or external or internal RAM depending on scatter file definition) */ #if defined ( __ICCARM__ ) extern uint32_t __ICFEDIT_region_ROM_start__; extern uint32_t __ICFEDIT_region_ROM_end__; address = (uint32_t)&__ICFEDIT_region_ROM_start__; size = (uint32_t)&__ICFEDIT_region_ROM_end__ - (uint32_t)&__ICFEDIT_region_ROM_start__ + 1; #elif defined (__CC_ARM) || defined(__ARMCC_VERSION) extern uint32_t Image$$ER_ROM$$Base; extern uint32_t Image$$ER_ROM$$Limit; address = (uint32_t)&Image$$ER_ROM$$Base; size = (uint32_t)&Image$$ER_ROM$$Limit-(uint32_t)&Image$$ER_ROM$$Base; #elif defined ( __GNUC__ ) extern uint32_t __FLASH_BEGIN; extern uint32_t __FLASH_SIZE; address = (uint32_t)&__FLASH_BEGIN; size = (uint32_t)&__FLASH_SIZE; #else #error "Compiler toolchain is unsupported" #endif MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = index; MPU_InitStruct.SubRegionDisable = 0u; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_AdjustRegionAddressSize(address, size, &MPU_InitStruct); HAL_MPU_ConfigRegion(&MPU_InitStruct); index++; /* Reset unused MPU regions */ for(; index < __MPU_REGIONCOUNT ; index++) { /* All unused regions disabled */ MPU_InitStruct.Enable = MPU_REGION_DISABLE; MPU_InitStruct.Number = index; HAL_MPU_ConfigRegion(&MPU_InitStruct); } /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } /** * @brief This function adjusts the MPU region Address and Size within an MPU configuration. * @param Address memory address * @param Size memory size * @param pInit pointer to an MPU initialization structure * @retval None */ static void MPU_AdjustRegionAddressSize(uint32_t Address, uint32_t Size, MPU_Region_InitTypeDef* pInit) { /* Compute the MPU region size */ pInit->Size = ((31 - __CLZ(Size)) - 1); if (Size > (1u << (pInit->Size + 1))) { pInit->Size++; } uint32_t Modulo = Address % (1 << (pInit->Size - 1)); if (0 != Modulo) { /* Align address with MPU region size considering there is no need to increase the size */ pInit->BaseAddress = Address - Modulo; } else { pInit->BaseAddress = Address; } } void board_init(void) { HAL_Init(); MPU_Config(); SCB_EnableICache(); SCB_EnableDCache(); HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); // Implemented in board.h SystemClock_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOM_CLK_ENABLE(); __HAL_RCC_GPION_CLK_ENABLE(); __HAL_RCC_GPIOO_CLK_ENABLE(); __HAL_RCC_GPIOP_CLK_ENABLE(); log_swo_init(); trace_etm_init(); for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) #ifdef USB_OTG_FS_PERIPH_BASE NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #ifdef UART_DEV UART_CLK_EN(); HAL_UART_Init(&UartHandle); #endif //------------- USB FS -------------// #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0) // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port HAL_PWREx_EnableUSBVoltageDetector(); HAL_PWREx_EnableUSBReg(); __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); // PM14 VUSB, PM10 ID, PM11 DM, PM12 DP // Configure DM DP Pins GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOM, &GPIO_InitStruct); // This for ID line debug GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOM, &GPIO_InitStruct); #if OTG_FS_VBUS_SENSE // Configure VBUS Pin GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOM, &GPIO_InitStruct); #endif // vbus sense #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_FS_VBUS_SENSE; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif #endif //------------- USB HS -------------// #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) // Enable USB HS & ULPI Clocks __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USBPHYC_CLK_ENABLE(); // Enable USB power HAL_PWREx_EnableUSBVoltageDetector(); HAL_PWREx_EnableUSBHSregulator(); #if OTG_HS_VBUS_SENSE // Configure VBUS Pin GPIO_InitTypeDef GPIO_InitStruct2; GPIO_InitStruct2.Pin = GPIO_PIN_8; GPIO_InitStruct2.Mode = GPIO_MODE_INPUT; GPIO_InitStruct2.Pull = GPIO_NOPULL; GPIO_InitStruct2.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOM, &GPIO_InitStruct2); #endif #if CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1 tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = OTG_HS_VBUS_SENSE; tud_configure(1, TUD_CFGID_DWC2, &cfg); #endif #endif board_init2(); // Turn off device vbus #if CFG_TUD_ENABLED board_vbus_set(BOARD_TUD_RHPORT, false); #endif // Turn on host vbus #if CFG_TUH_ENABLED board_vbus_set(BOARD_TUH_RHPORT, true); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return -1; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32h7rs/family.cmake ================================================ include_guard() set(ST_FAMILY h7rs) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(ST_TCPP0203 ${TOP}/hw/mcu/st/stm32-tcpp0203) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m7 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32H7RS CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 1) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () if (NOT DEFINED RHPORT_SPEED) set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) endif () if (NOT DEFINED RHPORT_DEVICE_SPEED) list(GET RHPORT_SPEED ${RHPORT_DEVICE} RHPORT_DEVICE_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) list(GET RHPORT_SPEED ${RHPORT_HOST} RHPORT_HOST_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) if(NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_flash.ld) endif() set(LD_FILE_Clang ${LD_FILE_GNU}) if(NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) endif() #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} SEGGER_RTT_SECTION=\"noncacheable_buffer\" BUFFER_SIZE_UP=0x300 ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32H7RS ${RTOS}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32h7rs/family.mk ================================================ ST_FAMILY = h7rs ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/${ST_PREFIX}_hal_driver ST_TCPP0203 = hw/mcu/st/stm32-tcpp0203 UF2_FAMILY_ID = 0x6db66083 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m7 # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_SPEED ?= OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED RHPORT_DEVICE ?= 1 RHPORT_HOST ?= 1 # Determine RHPORT_DEVICE_SPEED if not defined ifndef RHPORT_DEVICE_SPEED ifeq ($(RHPORT_DEVICE), 0) RHPORT_DEVICE_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_DEVICE_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # Determine RHPORT_HOST_SPEED if not defined ifndef RHPORT_HOST_SPEED ifeq ($(RHPORT_HOST), 0) RHPORT_HOST_SPEED = $(firstword $(RHPORT_SPEED)) else RHPORT_HOST_SPEED = $(lastword $(RHPORT_SPEED)) endif endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7RS \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ -DSEGGER_RTT_SECTION="\"noncacheable_buffer\"" \ -DBUFFER_SIZE_UP=0x300 \ # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -Wno-error=cast-align \ -Wno-error=unused-parameter \ LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_dma.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_i2c.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart_ex.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_GCC ?= $(FAMILY_PATH)/linker/$(MCU_VARIANT)_flash.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** @brief : Linker script for STM32H7S3xx Device from STM32H7RS series ** 64Kbytes FLASH ** 456Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ __FLASH_BEGIN = 0x08000000; __FLASH_SIZE = 0x00010000; __RAM_BEGIN = 0x24000000; __RAM_SIZE = 0x4FC00; __RAM_NONCACHEABLEBUFFER_SIZE = 0x400; /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE } /* Highest address of the user mode stack */ _estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM RW_NONCACHEABLE : { __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ KEEP(*(noncacheable_buffer)) __NONCACHEABLEBUFFER_END = .; /* create symbol for end of section */ } > RAM_NONCACHEABLEBUFFER /* User_heap_stack section, used to check that there is enough "DTCM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >DTCM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32h7rs/stm32h7rsxx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32h7rsxx_hal_conf.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32h7rsxx_hal_conf.h. * ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32H7RSxx_HAL_CONF_H #define STM32H7RSxx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CEC_MODULE_ENABLED */ /* #define HAL_CORDIC_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DCMIPP_MODULE_ENABLED */ /* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_DTS_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ /* #define HAL_FDCAN_MODULE_ENABLED */ /* #define HAL_GFXMMU_MODULE_ENABLED */ /* #define HAL_GFXTIM_MODULE_ENABLED */ /* #define HAL_GPU2D_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ /* #define HAL_HCD_MODULE_ENABLED */ #define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_I3C_MODULE_ENABLED */ /* #define HAL_ICACHE_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ /* #define HAL_MCE_MODULE_ENABLED */ /* #define HAL_MDF_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_NAND_MODULE_ENABLED */ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ /* #define HAL_PKA_MODULE_ENABLED */ /* #define HAL_PSSI_MODULE_ENABLED */ /* #define HAL_RAMECC_MODULE_ENABLED */ /* #define HAL_RCC_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SAI_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_XSPI_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 24000000UL /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up (in ms) */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz */ #endif /* HSI_VALUE */ /** * @brief Internal Low-power oscillator (CSI) default value. * This value is the default CSI range value after Reset. */ #if !defined (CSI_VALUE) #define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz */ #endif /* CSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB OTG FS and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB OTG FS/RNG in Hz. The real value my vary depending on manufacturing process variations. */ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz. Value of the Internal Low Speed oscillator in Hz. The real value may vary depending on the variations in voltage and temperature.*/ #endif /* LSI_VALUE */ /** * @brief External Low Speed oscillator (LSE) value. */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up (in ms) */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for digital audio interfaces: SPI/I2S, SAI and ADF * This value is used by the RCC HAL module to provide the digital audio interfaces * frequency. This clock source is inserted directly through I2S_CKIN pad. */ #if !defined (EXTERNAL_CLOCK_VALUE) #define EXTERNAL_CLOCK_VALUE 48000UL /*!< Value of the external clock source in Hz */ #endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300UL /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (15UL)/*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32h7rsxx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U #define USE_HAL_CEC_REGISTER_CALLBACKS 0U #define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U #define USE_HAL_DCMIPP_REGISTER_CALLBACKS 0U #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U #define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U #define USE_HAL_HASH_REGISTER_CALLBACKS 0U #define USE_HAL_I2C_REGISTER_CALLBACKS 0U #define USE_HAL_I2S_REGISTER_CALLBACKS 0U #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U #define USE_HAL_JPEG_REGISTER_CALLBACKS 0U #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U #define USE_HAL_MDF_REGISTER_CALLBACKS 0U #define USE_HAL_MMC_REGISTER_CALLBACKS 0U #define USE_HAL_NAND_REGISTER_CALLBACKS 0U #define USE_HAL_NOR_REGISTER_CALLBACKS 0U #define USE_HAL_PCD_REGISTER_CALLBACKS 0U #define USE_HAL_PKA_REGISTER_CALLBACKS 0U #define USE_HAL_PSSI_REGISTER_CALLBACKS 0U #define USE_HAL_RNG_REGISTER_CALLBACKS 0U #define USE_HAL_RTC_REGISTER_CALLBACKS 0U #define USE_HAL_SAI_REGISTER_CALLBACKS 0U #define USE_HAL_SD_REGISTER_CALLBACKS 0U #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U #define USE_HAL_SPI_REGISTER_CALLBACKS 0U #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U #define USE_HAL_TIM_REGISTER_CALLBACKS 0U #define USE_HAL_UART_REGISTER_CALLBACKS 0U #define USE_HAL_USART_REGISTER_CALLBACKS 0U #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U #define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* ################## CRYP peripheral configuration ########################## */ #define USE_HAL_CRYP_SUSPEND_RESUME 0U /* ################## HASH peripheral configuration ########################## */ #define USE_HAL_HASH_SUSPEND_RESUME 0U /* ################## SDMMC peripheral configuration ######################### */ #define USE_SD_TRANSCEIVER 0U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32h7rsxx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32h7rsxx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32h7rsxx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32h7rsxx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32h7rsxx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED #include "stm32h7rsxx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_CORDIC_MODULE_ENABLED #include "stm32h7rsxx_hal_cordic.h" #endif /* HAL_CORDIC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32h7rsxx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32h7rsxx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DCMIPP_MODULE_ENABLED #include "stm32h7rsxx_hal_dcmipp.h" #endif /* HAL_DCMIPP_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32h7rsxx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DTS_MODULE_ENABLED #include "stm32h7rsxx_hal_dts.h" #endif /* HAL_DTS_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32h7rsxx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32h7rsxx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32h7rsxx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32h7rsxx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_GFXMMU_MODULE_ENABLED #include "stm32h7rsxx_hal_gfxmmu.h" #endif /* HAL_GFXMMU_MODULE_ENABLED */ #ifdef HAL_GFXTIM_MODULE_ENABLED #include "stm32h7rsxx_hal_gfxtim.h" #endif /* HAL_GFXTIM_MODULE_ENABLED */ #ifdef HAL_GPU2D_MODULE_ENABLED #include "stm32h7rsxx_hal_gpu2d.h" #endif /* HAL_GPU2D_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32h7rsxx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32h7rsxx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32h7rsxx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32h7rsxx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_I3C_MODULE_ENABLED #include "stm32h7rsxx_hal_i3c.h" #endif /* HAL_I3C_MODULE_ENABLED */ #ifdef HAL_ICACHE_MODULE_ENABLED #include "stm32h7rsxx_hal_icache.h" #endif /* HAL_ICACHE_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32h7rsxx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32h7rsxx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_JPEG_MODULE_ENABLED #include "stm32h7rsxx_hal_jpeg.h" #endif /* HAL_JPEG_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32h7rsxx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32h7rsxx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_MCE_MODULE_ENABLED #include "stm32h7rsxx_hal_mce.h" #endif /* HAL_MCE_MODULE_ENABLED */ #ifdef HAL_MDF_MODULE_ENABLED #include "stm32h7rsxx_hal_mdf.h" #endif /* HAL_MDF_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED #include "stm32h7rsxx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32h7rsxx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32h7rsxx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32h7rsxx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PKA_MODULE_ENABLED #include "stm32h7rsxx_hal_pka.h" #endif /* HAL_PKA_MODULE_ENABLED */ #ifdef HAL_PSSI_MODULE_ENABLED #include "stm32h7rsxx_hal_pssi.h" #endif /* HAL_PSSI_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32h7rsxx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RAMECC_MODULE_ENABLED #include "stm32h7rsxx_hal_ramecc.h" #endif /* HAL_RAMECC_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32h7rsxx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32h7rsxx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32h7rsxx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32h7rsxx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32h7rsxx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32h7rsxx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32h7rsxx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32h7rsxx_hal_spdifrx.h" #endif /* HAL_SPDIFRX_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32h7rsxx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32h7rsxx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32h7rsxx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32h7rsxx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32h7rsxx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32h7rsxx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_XSPI_MODULE_ENABLED #include "stm32h7rsxx_hal_xspi.h" #endif /* HAL_XSPI_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32H7RSxx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32l0xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l0/boards/stm32l052dap52/board.cmake ================================================ set(MCU_VARIANT stm32l052xx) set(JLINK_DEVICE stm32l052k8) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L052K8Ux_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L052xx ) endfunction() ================================================ FILE: hw/bsp/stm32l0/boards/stm32l052dap52/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L052 DAP url: n/a */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_4 #define LED_STATE_ON 1 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_6 #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV USART2 #define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF4_USART2 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32l0_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; /* Enable HSI Oscillator to be used as System clock source Enable HSI48 Oscillator to be used as USB clock source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select HSI48 as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select HSI as system clock source and configure the HCLK, PCLK1 and PCLK2 clock dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); /*Configure the clock recovery system (CRS)**********************************/ /*Enable CRS Clock*/ __HAL_RCC_CRS_CLK_ENABLE(); /* Default Synchro Signal division factor (not divided) */ RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; /* HSI48 is synchronized with USB SOF at 1KHz rate */ RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; /* Set the TRIM[5:0] to the default value*/ RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; /* Start automatic synchronization */ HAL_RCCEx_CRSConfig (&RCC_CRSInitStruct); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l0/boards/stm32l052dap52/board.mk ================================================ MCU_VARIANT = stm32l052xx CFLAGS += \ -DSTM32L052xx LD_FILE = $(BOARD_PATH)/STM32L052K8Ux_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32l052k8 # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32l0/boards/stm32l0538disco/STM32L053C8Tx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32L053C8Tx Device with ** 64KByte FLASH, 8KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20002000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x200; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake ================================================ set(MCU_VARIANT stm32l053xx) set(JLINK_DEVICE stm32l053r8) #set(JLINK_OPTION "-USB 778921770") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L053C8Tx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L053xx ) endfunction() ================================================ FILE: hw/bsp/stm32l0/boards/stm32l0538disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L0538 Discovery url: https://www.st.com/en/evaluation-tools/32l0538discovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 #define LED_STATE_ON 1 // Button #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 // UART //#define UART_DEV USART2 //#define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE //#define UART_GPIO_PORT GPIOA //#define UART_GPIO_AF GPIO_AF4_USART2 //#define UART_TX_PIN GPIO_PIN_2 //#define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void board_stm32l0_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; /* Enable HSI Oscillator to be used as System clock source Enable HSI48 Oscillator to be used as USB clock source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select HSI48 as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select HSI as system clock source and configure the HCLK, PCLK1 and PCLK2 clock dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); /*Configure the clock recovery system (CRS)**********************************/ /*Enable CRS Clock*/ __HAL_RCC_CRS_CLK_ENABLE(); /* Default Synchro Signal division factor (not divided) */ RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; /* HSI48 is synchronized with USB SOF at 1KHz rate */ RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; /* Set the TRIM[5:0] to the default value*/ RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; /* Start automatic synchronization */ HAL_RCCEx_CRSConfig (&RCC_CRSInitStruct); } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l0/boards/stm32l0538disco/board.mk ================================================ MCU_VARIANT = stm32l053xx CFLAGS += \ -DSTM32L053xx # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/STM32L053C8Tx_FLASH.ld # For flash-jlink target JLINK_DEVICE = STM32L053R8 # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32l0/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32l0xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV UART_HandleTypeDef UartHandle; #endif void board_init(void) { board_stm32l0_clock_init(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); // LED GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); board_led_write(false); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV // Enable UART Clock UART_CLK_EN(); GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle.Instance = UART_DEV; UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); #endif // USB Pins // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // USB Clock enable __HAL_RCC_USB_CLK_ENABLE(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* file, uint32_t line) { (void) file; (void) line; } #endif /* USE_FULL_ASSERT */ // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32l0/family.cmake ================================================ include_guard() set(ST_FAMILY l0) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32L0 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) #target_compile_options(${BOARD_TARGET} PUBLIC) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_EXAMPLE_MSC_READONLY CFG_EXAMPLE_VIDEO_READONLY ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32L0) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32l0/family.mk ================================================ ST_FAMILY = l0 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_STM32L0 # mcu driver cause following warnings CFLAGS_GCC += \ -flto \ -Wno-error=unused-parameter \ -Wno-error=redundant-decls \ -Wno-error=cast-align \ -Wno-error=maybe-uninitialized \ CFLAGS_CLANG += \ -Wno-error=parentheses-equality LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_${MCU_VARIANT}.s # Linker LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32l0/stm32l0xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32l0xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * * Copyright (c) 2016 STMicroelectronics International N.V. 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. Redistribution 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. Neither the name of STMicroelectronics nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for STMicroelectronics. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L0xx_HAL_CONF_H #define __STM32L0xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED // #define HAL_ADC_MODULE_ENABLED /* #define HAL_COMP_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED /* #define HAL_FIREWALL_MODULE_ENABLED */ #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LCD_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED //#define HAL_RNG_MODULE_ENABLED /* #define HAL_RTC_MODULE_ENABLED */ //#define HAL_SPI_MODULE_ENABLED /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ //#define HAL_PCD_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_PCD_MODULE_ENABLED */ /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator for USB (HSI48) value. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB in Hz. The real value may vary depending on the variations in voltage and temperature. */ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE ((uint32_t)37000U) /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ /** * @brief Time out for LSE start up value in ms. */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (((uint32_t)1U<<__NVIC_PRIO_BITS) - 1U) /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U #define PREREAD_ENABLE 0U #define BUFFER_CACHE_DISABLE 0U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/deregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32l0xx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U #define USE_HAL_COMP_REGISTER_CALLBACKS 0U #define USE_HAL_DAC_REGISTER_CALLBACKS 0U #define USE_HAL_I2C_REGISTER_CALLBACKS 0U #define USE_HAL_I2S_REGISTER_CALLBACKS 0U #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U #define USE_HAL_PCD_REGISTER_CALLBACKS 0U #define USE_HAL_RNG_REGISTER_CALLBACKS 0U #define USE_HAL_RTC_REGISTER_CALLBACKS 0U #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U #define USE_HAL_SPI_REGISTER_CALLBACKS 0U #define USE_HAL_TIM_REGISTER_CALLBACKS 0U #define USE_HAL_TSC_REGISTER_CALLBACKS 0U #define USE_HAL_UART_REGISTER_CALLBACKS 0U #define USE_HAL_USART_REGISTER_CALLBACKS 0U #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32l0xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32l0xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32l0xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32l0xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32l0xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32l0xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32l0xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32l0xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32l0xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FIREWALL_MODULE_ENABLED #include "stm32l0xx_hal_firewall.h" #endif /* HAL_FIREWALL_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32l0xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32l0xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32l0xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32l0xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LCD_MODULE_ENABLED #include "stm32l0xx_hal_lcd.h" #endif /* HAL_LCD_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32l0xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32l0xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32l0xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32l0xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32l0xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32l0xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32l0xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32l0xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32l0xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32l0xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32l0xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32l0xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32l0xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32l0xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32L0xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32l4/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32l4xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(8); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(8); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(8); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(8); } >FLASH .ARM.extab : { . = ALIGN(8); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(8); } >FLASH .ARM : { . = ALIGN(8); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(8); } >FLASH .preinit_array : { . = ALIGN(8); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(8); } >FLASH .init_array : { . = ALIGN(8); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(8); } >FLASH .fini_array : { . = ALIGN(8); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(8); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(8); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(8); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l4/boards/stm32l412nucleo/board.cmake ================================================ set(MCU_VARIANT stm32l412xx) set(JLINK_DEVICE stm32l412kb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L412KBUx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L412xx ) endfunction() ================================================ FILE: hw/bsp/stm32l4/boards/stm32l412nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L412 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-l412kb.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_3 #define LED_STATE_ON 1 // Not a real button #define BUTTON_PORT GPIOB #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF8_LPUART1 #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (MSI) * SYSCLK(Hz) = 80000000 * HCLK(Hz) = 80000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 1 * MSI Frequency(Hz) = 8000000 * PLL_M = 1 * PLL_N = 10 * PLL_Q = 2 * PLL_R = 2 * VDD(V) = 3.3 * @param None * @retval None */ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 10; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); /** Enable the SYSCFG APB clock */ __HAL_RCC_CRS_CLK_ENABLE(); /** Configures CRS */ RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000); RCC_CRSInitStruct.ErrorLimitValue = 34; RCC_CRSInitStruct.HSI48CalibrationValue = 32; HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); /* Select HSI48 output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL output as UART clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l4/boards/stm32l412nucleo/board.mk ================================================ CFLAGS += \ -DSTM32L412xx \ # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l412xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32L412KBUx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32l412xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32l412xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32l412kb ================================================ FILE: hw/bsp/stm32l4/boards/stm32l476disco/STM32L476VGTx_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32L476VGTx Device with ** 1024KByte FLASH, 96KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20018000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x500; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(8); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(8); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(8); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(8); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(8); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(8); } >FLASH .ARM.extab : { . = ALIGN(8); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(8); } >FLASH .ARM : { . = ALIGN(8); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(8); } >FLASH .preinit_array : { . = ALIGN(8); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(8); } >FLASH .init_array : { . = ALIGN(8); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(8); } >FLASH .fini_array : { . = ALIGN(8); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(8); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(8); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(8); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l4/boards/stm32l476disco/board.cmake ================================================ set(MCU_VARIANT stm32l476xx) set(JLINK_DEVICE stm32l476vg) # set(JLINK_OPTION "-USB 000777632258") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L476VGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L476xx ) endfunction() ================================================ FILE: hw/bsp/stm32l4/boards/stm32l476disco/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L476 Disco url: https://www.st.com/en/evaluation-tools/32l476gdiscovery.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_2 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV USART2 #define UART_CLK_EN __HAL_RCC_USART2_CLK_ENABLE #define UART_GPIO_PORT GPIOD #define UART_GPIO_AF GPIO_AF7_USART2 #define UART_TX_PIN GPIO_PIN_5 #define UART_RX_PIN GPIO_PIN_6 #define VBUS_SENSE_EN 0 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ /** * @brief System Clock Configuration * The system Clock is configured as follow : * * If define USB_USE_LSE_MSI_CLOCK enabled: * System Clock source = PLL (MSI) * SYSCLK(Hz) = 80000000 * HCLK(Hz) = 80000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 2 * MSI Frequency(Hz) = 4800000 * LSE Frequency(Hz) = 32768 * PLL_M = 6 * PLL_N = 40 * PLL_P = 7 * PLL_Q = 4 * PLL_R = 4 * Flash Latency(WS) = 4 * @param None * @retval None */ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; /* Enable the LSE Oscillator */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Enable the CSS interrupt in case LSE signal is corrupted or not present */ HAL_RCCEx_DisableLSECSS(); /* Set tick interrupt priority, default HAL value is intentionally invalid and that prevents PLL initialization in HAL_RCC_OscConfig() */ HAL_InitTick((1UL << __NVIC_PRIO_BITS) - 1UL); /* Enable MSI Oscillator and activate PLL with MSI as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 6; RCC_OscInitStruct.PLL.PLLN = 40; RCC_OscInitStruct.PLL.PLLP = 7; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 4; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Enable MSI Auto-calibration through LSE */ HAL_RCCEx_EnableMSIPLLMode(); /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l4/boards/stm32l476disco/board.mk ================================================ CFLAGS += \ -DSTM32L476xx \ # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l476xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32L476VGTx_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32l476xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32l476xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32l476vg ================================================ FILE: hw/bsp/stm32l4/boards/stm32l496nucleo/STM32L496ZGTX_FLASH.ld ================================================ /* ****************************************************************************** ** ** @file : LinkerScript.ld ** ** @author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for NUCLEO-L496ZG Board embedding STM32L496ZGTx Device from stm32l4 series ** 1024Kbytes ROM ** 256Kbytes RAM ** 64Kbytes SRAM2 ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2022 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K SRAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ /* Sections */ SECTIONS { /* The startup code into "ROM" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >ROM /* The program code and other data into "ROM" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "ROM" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >ROM .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >ROM .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >ROM .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >ROM .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >ROM .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM _sisram2 = LOADADDR(.sram2); /* SRAM2 section * * IMPORTANT NOTE! * If initialized variables will be placed in this section, * the startup code needs to be modified to copy the init-values. */ .sram2 : { . = ALIGN(4); _ssram2 = .; /* create a global symbol at sram2 start */ *(.sram2) *(.sram2*) . = ALIGN(4); _esram2 = .; /* create a global symbol at sram2 end */ } >SRAM2 AT> ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l4/boards/stm32l496nucleo/board.cmake ================================================ set(MCU_VARIANT stm32l496xx) set(JLINK_DEVICE stm32l496zg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L496ZGTX_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L496xx ) endfunction() ================================================ FILE: hw/bsp/stm32l4/boards/stm32l496nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L496 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-l496ZG-P.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_7 #define LED_STATE_ON 1 // Not a real button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOG #define UART_GPIO_AF GPIO_AF8_LPUART1 #define UART_TX_PIN GPIO_PIN_7 #define UART_RX_PIN GPIO_PIN_8 #define VBUS_SENSE_EN 1 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (MSI) * SYSCLK(Hz) = 80000000 * HCLK(Hz) = 80000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 1 * MSI Frequency(Hz) = 8000000 * PLL_M = 1 * PLL_N = 10 * PLL_Q = 2 * PLL_R = 2 * VDD(V) = 3.3 * @param None * @retval None */ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Configure LSE Drive Capability */ HAL_PWR_EnableBkUpAccess(); __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 10; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); // /** Enable the SYSCFG APB clock // */ // __HAL_RCC_CRS_CLK_ENABLE(); // // /** Configures CRS // */ // RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; // RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; // RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; // RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; // RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000); // RCC_CRSInitStruct.ErrorLimitValue = 34; // RCC_CRSInitStruct.HSI48CalibrationValue = 32; // // HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); /* Select HSI48 output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL output as UART clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l4/boards/stm32l496nucleo/board.mk ================================================ CFLAGS += \ -DSTM32L496xx \ # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l496xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32L496ZGTX_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32l496xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32l496xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32l496zg ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for STM32L4P5ZGTx Device from STM32L4PLUS series ** 1024Kbytes ROM ** 320Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© COPYRIGHT(c) 2019 STMicroelectronics

** ** 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. Neither the name of STMicroelectronics nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "ROM" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >ROM /* The program code and other data into "ROM" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "ROM" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >ROM .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >ROM .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >ROM .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >ROM .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >ROM .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.cmake ================================================ set(MCU_VARIANT stm32l4p5xx) set(JLINK_DEVICE stm32l4p5zg) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L4P5ZGTX_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L4P5xx ) endfunction() ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L4P5 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_14 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOG #define UART_GPIO_AF GPIO_AF8_LPUART1 #define UART_TX_PIN GPIO_PIN_7 #define UART_RX_PIN GPIO_PIN_8 #define VBUS_SENSE_EN 1 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (MSI) * SYSCLK(Hz) = 120000000 * HCLK(Hz) = 120000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 1 * MSI Frequency(Hz) = 48000000 * PLL_M = 12 * PLL_N = 60 * PLL_P = 2 * PLL_Q = 2 * VDD(V) = 3.3 * Main regulator output voltage = Scale1 mode * Flash Latency(WS) = 5 * The USB clock configuration from PLLSAI: * PLLSAIP = 8 FIXME * PLLSAIN = 384 FIXME * PLLSAIQ = 7 FIXME * @param None * @retval None */ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /* Activate PLL with MSI , stabilizied via PLL by LSE */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 12; RCC_OscInitStruct.PLL.PLLN = 60; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Enable MSI Auto-calibration through LSE */ HAL_RCCEx_EnableMSIPLLMode(); /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // Avoid overshoot and start with HCLK 60 MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); /* AHB prescaler divider at 1 as second step */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4p5nucleo/board.mk ================================================ CFLAGS += \ -DSTM32L4P5xx \ # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4p5xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32L4P5ZGTX_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32l4p5xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32l4p5xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32l4p5zg ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4r5nucleo/STM32L4RXxI_FLASH.ld ================================================ /* ***************************************************************************** ** ** File : LinkerScript.ld ** ** Abstract : Linker script for STM32L4RxI Device with ** 2048KByte FLASH, 640KByte RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ** (c)Copyright Ac6. ** You may use this file as-is or modify it according to the needs of your ** project. Distribution of this file (unmodified or modified) is not ** permitted. Ac6 permit registered System Workbench for MCU users the ** rights to distribute the assembled, compiled & linked contents of this ** file as part of an application binary file, provided that it is built ** using the System Workbench for MCU toolchain. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x200a0000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x460; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.cmake ================================================ set(MCU_VARIANT stm32l4r5xx) set(JLINK_DEVICE stm32l4r5zi) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L4RXxI_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32L4R5xx HSE_VALUE=8000000 ) endfunction() ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 L4R5 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_14 #define LED_STATE_ON 1 #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOG #define UART_GPIO_AF GPIO_AF8_LPUART1 #define UART_TX_PIN GPIO_PIN_7 #define UART_RX_PIN GPIO_PIN_8 #define VBUS_SENSE_EN 1 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (MSI) * SYSCLK(Hz) = 120000000 * HCLK(Hz) = 120000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 1 * MSI Frequency(Hz) = 48000000 * PLL_M = 12 * PLL_N = 60 * PLL_P = 2 * PLL_Q = 2 * VDD(V) = 3.3 * Main regulator output voltage = Scale1 mode * Flash Latency(WS) = 5 * The USB clock configuration from PLLSAI: * PLLSAIP = 8 FIXME * PLLSAIN = 384 FIXME * PLLSAIQ = 7 FIXME * @param None * @retval None */ static inline void board_clock_init(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /* Activate PLL with MSI , stabilizied via PLL by LSE */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 12; RCC_OscInitStruct.PLL.PLLN = 60; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 2; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Enable MSI Auto-calibration through LSE */ HAL_RCCEx_EnableMSIPLLMode(); /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // Avoid overshoot and start with HCLK 60 MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); /* AHB prescaler divider at 1 as second step */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32l4/boards/stm32l4r5nucleo/board.mk ================================================ CFLAGS += \ -DHSE_VALUE=8000000 \ -DSTM32L4R5xx \ # GCC SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l4r5xx.s LD_FILE_GCC = $(BOARD_PATH)/STM32L4RXxI_FLASH.ld # IAR SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32l4r5xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32l4r5xx_flash.icf # For flash-jlink target JLINK_DEVICE = stm32l4r5zi # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32l4/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 William D. Jones (thor0505@comcast.net), * Ha Thach (tinyusb.org) * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32l4xx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ #if defined(USB_OTG_FS) void OTG_FS_IRQHandler(void) #else void USB_IRQHandler(void) #endif { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; void board_init(void) { board_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); #if defined(GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); #endif #if defined(GPIOE) __HAL_RCC_GPIOE_CLK_ENABLE(); #endif #if defined(GPIOF) __HAL_RCC_GPIOF_CLK_ENABLE(); #endif #if defined(GPIOG) __HAL_RCC_GPIOG_CLK_ENABLE(); #endif __HAL_RCC_GPIOH_CLK_ENABLE(); UART_CLK_EN(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) #if defined(USB_OTG_FS) NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #else NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #endif /* Enable USB power on Pwrctrl CR2 register */ /* Enable Power Clock*/ __HAL_RCC_PWR_CLK_ENABLE(); #if defined(PWR_CR5_R1MODE) /* Enable voltage range 1 boost mode for frequency above 80 Mhz */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); #endif /* Enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); // IOSV bit MUST be set to access GPIO port G[2:15] */ __HAL_RCC_PWR_CLK_ENABLE(); #if defined(PWR_CR2_IOSV) HAL_PWREx_EnableVddIO2(); #endif // Uart GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle.Instance = UART_DEV; UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; //UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&UartHandle); /* Configure USB FS GPIOs */ /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; #if defined(USB_OTG_FS) GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; #else GPIO_InitStruct.Alternate = GPIO_AF10_USB_FS; #endif HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #if defined(USB_OTG_FS) /* Configure VBUS Pin */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure ID pin */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif #if defined(USB_OTG_FS) /* Enable USB FS Clocks */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); #if CFG_TUD_ENABLED /* Set Vbus sense */ tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif #else __HAL_RCC_USB_CLK_ENABLE(); #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32l4/family.cmake ================================================ include_guard() set(ST_FAMILY l4) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32L4 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${FAMILY_MCUS}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32l4/family.mk ================================================ ST_FAMILY = l4 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32L4 # GCC Flags CFLAGS_GCC += \ -flto \ -Wno-error=cast-align \ ifeq ($(TOOLCHAIN),gcc) CFLAGS_GCC += -Wno-error=maybe-uninitialized endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc \ $(TOP)/$(BOARD_PATH) # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32l4/stm32l4xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32l4xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32l4xx_hal_conf.h. ****************************************************************************** * @attention * *

© Copyright (c) 2017 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32L4xx_HAL_CONF_H #define __STM32L4xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED /* #define HAL_FIREWALL_MODULE_ENABLED */ #define HAL_FLASH_MODULE_ENABLED /* #define HAL_NAND_MODULE_ENABLED */ // #define HAL_NOR_MODULE_ENABLED // #define HAL_SRAM_MODULE_ENABLED /* #define HAL_HCD_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED //#define HAL_I2C_MODULE_ENABLED /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ //#define HAL_LCD_MODULE_ENABLED /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_OPAMP_MODULE_ENABLED */ //#define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED /* #define HAL_QSPI_MODULE_ENABLED */ #define HAL_RCC_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ //#define HAL_SAI_MODULE_ENABLED //#define HAL_SD_MODULE_ENABLED /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SWPMI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief External clock source for SAI1 peripheral * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source * frequency. */ #if !defined (EXTERNAL_SAI1_CLOCK_VALUE) #define EXTERNAL_SAI1_CLOCK_VALUE 48000U /*!< Value of the SAI1 External clock source in Hz*/ #endif /* EXTERNAL_SAI1_CLOCK_VALUE */ /** * @brief External clock source for SAI2 peripheral * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source * frequency. */ #if !defined (EXTERNAL_SAI2_CLOCK_VALUE) #define EXTERNAL_SAI2_CLOCK_VALUE 48000U /*!< Value of the SAI2 External clock source in Hz*/ #endif /* EXTERNAL_SAI2_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U #define DATA_CACHE_ENABLE 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ #define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32l4xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32l4xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32l4xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_DFSDM_MODULE_ENABLED #include "stm32l4xx_hal_dfsdm.h" #endif /* HAL_DFSDM_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32l4xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32l4xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CAN_MODULE_ENABLED #include "stm32l4xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CAN_LEGACY_MODULE_ENABLED #include "Legacy/stm32l4xx_hal_can_legacy.h" #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32l4xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32l4xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32l4xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32l4xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FIREWALL_MODULE_ENABLED #include "stm32l4xx_hal_firewall.h" #endif /* HAL_FIREWALL_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32l4xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32l4xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32l4xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32l4xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32l4xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32l4xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LCD_MODULE_ENABLED #include "stm32l4xx_hal_lcd.h" #endif /* HAL_LCD_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32l4xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32l4xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32l4xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32l4xx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32l4xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32l4xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32l4xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32l4xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32l4xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32l4xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_SWPMI_MODULE_ENABLED #include "stm32l4xx_hal_swpmi.h" #endif /* HAL_SWPMI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32l4xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32l4xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32l4xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32l4xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32l4xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32l4xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32l4xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32l4xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32l4xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32L4xx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32n6/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32n6xx.h" #endif /* Cortex M55 port configuration. */ #define configENABLE_MVE 0 #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<ROM /* The program code and other data into "RAM" Ram type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "RAM" Ram type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >ROM .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >ROM .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >ROM .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >ROM .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >ROM .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM .noncacheable : { . = ALIGN(8); __snoncacheable = .;/* create symbol for start of section */ KEEP(*(.noncacheable)) . = ALIGN(8); __enoncacheable = .; /* create symbol for end of section */ } > RAM .gnu.sgstubs : { . = ALIGN(4); *(.gnu.sgstubs*) /* Secure Gateway stubs */ . = ALIGN(4); } >ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32n6/boards/stm32n6570dk/board.cmake ================================================ set(MCU_VARIANT stm32n657xx) set(JLINK_DEVICE stm32n657x0) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32N657XX_AXISRAM2_fsbl.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32N657xx ) target_sources(${TARGET} PUBLIC ${ST_TCPP0203}/tcpp0203.c ${ST_TCPP0203}/tcpp0203_reg.c ) target_include_directories(${TARGET} PUBLIC ${ST_TCPP0203} ) endfunction() ================================================ FILE: hw/bsp/stm32n6/boards/stm32n6570dk/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 N6570-DK url: https://www.st.com/en/evaluation-tools/stm32n6570-dk.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "stm32n657xx.h" #include "stm32n6xx_ll_exti.h" #include "stm32n6xx_ll_system.h" #include "tcpp0203.h" #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 0 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_TCPP0203_EN 4 #define PINID_PWR_USB2 8 static board_pindef_t board_pindef[] = { {// LED .port = GPIOG, .pin_init = {.Pin = GPIO_PIN_10, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 1}, {// Button .port = GPIOC, .pin_init = {.Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 1}, {// UART TX .port = GPIOE, .pin_init = {.Pin = GPIO_PIN_5, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF7_USART1}, .active_state = 0}, {// UART RX .port = GPIOE, .pin_init = {.Pin = GPIO_PIN_6, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF7_USART1}, .active_state = 0}, {// VBUS input pin used for TCPP0203 EN .port = GPIOA, .pin_init = {.Pin = GPIO_PIN_4, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 0}, { // I2C SCL for TCPP0203 .port = GPIOD, .pin_init = {.Pin = GPIO_PIN_14, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF4_I2C2}, }, {// I2C SDA for TCPP0203 .port = GPIOD, .pin_init = {.Pin = GPIO_PIN_4, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF4_I2C2}, }, {// INT for TCPP0203 .port = GPIOD, .pin_init = {.Pin = GPIO_PIN_10, .Mode = GPIO_MODE_IT_FALLING, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, }, {// PWR for USB2 .port = GPIOB, .pin_init = {.Pin = GPIO_PIN_9, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, } }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /* Configure the power domain */ if (HAL_PWREx_ConfigSupply(PWR_EXTERNAL_SOURCE_SUPPLY) != HAL_OK) { Error_Handler(); } /* Get current CPU/System buses clocks configuration */ /* and if necessary switch to intermediate HSI clock */ /* to ensure target clock can be set */ HAL_RCC_GetClockConfig(&RCC_ClkInitStruct); if ((RCC_ClkInitStruct.CPUCLKSource == RCC_CPUCLKSOURCE_IC1) || (RCC_ClkInitStruct.SYSCLKSource == RCC_SYSCLKSOURCE_IC2_IC6_IC11)) { RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_CPUCLK | RCC_CLOCKTYPE_SYSCLK); RCC_ClkInitStruct.CPUCLKSource = RCC_CPUCLKSOURCE_HSI; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) { Error_Handler(); } } /* HSE selected as source (stable clock on Level 0 samples */ /* PLL1 output = ((HSE/PLLM)*PLLN)/PLLP1/PLLP2 */ /* = ((48000000/3)*75)/1/1 */ /* = (16000000*75)/1/1 */ /* = 1200000000 (1200 MHz) */ /* PLL2 off */ /* PLL3 off */ /* PLL4 off */ /* Enable HSE && HSI */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* 48 MHz */ RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL1.PLLM = 3; RCC_OscInitStruct.PLL1.PLLN = 75; /* PLL1 VCO = 48/3 * 75 = 1200MHz */ RCC_OscInitStruct.PLL1.PLLP1 = 1; /* PLL output = PLL VCO frequency / (PLLP1 * PLLP2) */ RCC_OscInitStruct.PLL1.PLLP2 = 1; /* PLL output = 1200 MHz */ RCC_OscInitStruct.PLL1.PLLFractional = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { /* Initialization error */ Error_Handler(); } /* Select PLL1 outputs as CPU and System bus clock source */ /* CPUCLK = ic1_ck = PLL1 output/ic1_divider = 600 MHz */ /* SYSCLK = ic2_ck = PLL1 output/ic2_divider = 400 MHz */ /* Configure the HCLK clock divider */ /* HCLK = PLL1 SYSCLK/HCLK divider = 200 MHz */ /* PCLKx = HCLK / PCLKx divider = 200 MHz */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_CPUCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK4 | RCC_CLOCKTYPE_PCLK5); RCC_ClkInitStruct.CPUCLKSource = RCC_CPUCLKSOURCE_IC1; RCC_ClkInitStruct.IC1Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC1Selection.ClockDivider = 2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_IC2_IC6_IC11; RCC_ClkInitStruct.IC2Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC2Selection.ClockDivider = 3; RCC_ClkInitStruct.IC6Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC6Selection.ClockDivider = 3; RCC_ClkInitStruct.IC11Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC11Selection.ClockDivider = 3; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /** Initializes the peripherals clock */ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1; PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /** Set USB OTG HS PHY1 Reference Clock Source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1; PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } //--------------------------------------------------------------------+ // USB PD //--------------------------------------------------------------------+ static I2C_HandleTypeDef i2c_handle = { .Instance = I2C2, .Init = { .Timing = 0x20C0EDFF, .OwnAddress1 = 0, .AddressingMode = I2C_ADDRESSINGMODE_7BIT, .DualAddressMode = I2C_DUALADDRESS_DISABLE, .OwnAddress2 = 0, .OwnAddress2Masks = I2C_OA2_NOMASK, .GeneralCallMode = I2C_GENERALCALL_DISABLE, .NoStretchMode = I2C_NOSTRETCH_DISABLE, }}; static TCPP0203_Object_t tcpp0203_obj = {0}; static int32_t board_tcpp0203_init(void) { board_pindef_t *pindef = &board_pindef[PINID_TCPP0203_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, GPIO_PIN_SET); __HAL_RCC_I2C2_CLK_ENABLE(); __HAL_RCC_I2C2_FORCE_RESET(); __HAL_RCC_I2C2_RELEASE_RESET(); if (HAL_I2C_Init(&i2c_handle) != HAL_OK) { return HAL_ERROR; } NVIC_SetPriority(EXTI10_IRQn, 12); NVIC_EnableIRQ(EXTI10_IRQn); return 0; } static int32_t board_tcpp0203_deinit(void) { return 0; } static int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } static int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } static inline void board_init2(void) { TCPP0203_IO_t io_ctx; io_ctx.Address = TCPP0203_I2C_ADDRESS_X68; io_ctx.Init = board_tcpp0203_init; io_ctx.DeInit = board_tcpp0203_deinit; io_ctx.ReadReg = i2c_readreg; io_ctx.WriteReg = i2c_writereg; TU_ASSERT(TCPP0203_RegisterBusIO(&tcpp0203_obj, &io_ctx) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_Init(&tcpp0203_obj) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { uint8_t switch_state = state ? TCPP0203_GD_PROVIDER_SWITCH_CLOSED : TCPP0203_GD_PROVIDER_SWITCH_OPEN; TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, switch_state) == TCPP0203_OK, ); } else if (rhport == 1) { board_pindef_t *pindef = &board_pindef[PINID_PWR_USB2]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET); } } void EXTI10_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_10); if (tcpp0203_obj.IsInitialized) { TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32n6/boards/stm32n6570dk/board.mk ================================================ MCU_VARIANT = stm32n657xx CFLAGS += -DSTM32N657xx JLINK_DEVICE = stm32n6xx LD_FILE_GCC = $(BOARD_PATH)/STM32N657XX_AXISRAM2_fsbl.ld # flash target using on-board stlink flash: flash-stlink PORT = 1 SRC_C += \ $(ST_TCPP0203)/tcpp0203.c \ $(ST_TCPP0203)/tcpp0203_reg.c \ INC += \ $(TOP)/$(ST_TCPP0203) \ ================================================ FILE: hw/bsp/stm32n6/boards/stm32n657nucleo/STM32N657XX_AXISRAM2_fsbl.ld ================================================ /* ****************************************************************************** ** ** @file : STM32N657XX_AXISRAM2_fsbl.ld ** ** @author : GPM Application Team ** ** @brief : Linker script for STM32N657XX Device from STM32N6 series ** 512 KBytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _sstack = _estack - _Min_Stack_Size; _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x800; /* required amount of stack */ /* Memories definition */ MEMORY { ROM (xrw) : ORIGIN = 0x34180400, LENGTH = 255K RAM (xrw) : ORIGIN = 0x341C0000, LENGTH = 256K } /* Sections */ SECTIONS { /* The startup code into "RAM" Ram type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >ROM /* The program code and other data into "RAM" Ram type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "RAM" Ram type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >ROM .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >ROM .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >ROM .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >ROM .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >ROM .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM .noncacheable : { . = ALIGN(8); __snoncacheable = .;/* create symbol for start of section */ KEEP(*(.noncacheable)) . = ALIGN(8); __enoncacheable = .; /* create symbol for end of section */ } > RAM .gnu.sgstubs : { . = ALIGN(4); *(.gnu.sgstubs*) /* Secure Gateway stubs */ . = ALIGN(4); } >ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32n6/boards/stm32n657nucleo/board.cmake ================================================ set(MCU_VARIANT stm32n657xx) set(JLINK_DEVICE stm32n657x0) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32N657XX_AXISRAM2_fsbl.ld) if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 0) endif () function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32N657xx ) target_sources(${TARGET} PUBLIC ${ST_TCPP0203}/tcpp0203.c ${ST_TCPP0203}/tcpp0203_reg.c ) target_include_directories(${TARGET} PUBLIC ${ST_TCPP0203} ) endfunction() ================================================ FILE: hw/bsp/stm32n6/boards/stm32n657nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 N657X0-Q Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-n657x0-q.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "stm32n657xx.h" #include "stm32n6xx_ll_exti.h" #include "stm32n6xx_ll_system.h" #include "tcpp0203.h" #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE // VBUS Sense detection #define OTG_FS_VBUS_SENSE 0 #define OTG_HS_VBUS_SENSE 0 #define PINID_LED 0 #define PINID_BUTTON 1 #define PINID_UART_TX 2 #define PINID_UART_RX 3 #define PINID_TCPP0203_EN 4 static board_pindef_t board_pindef[] = { {// LED .port = GPIOG, .pin_init = {.Pin = GPIO_PIN_10, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 1}, {// Button .port = GPIOC, .pin_init = {.Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 1}, {// UART TX .port = GPIOE, .pin_init = {.Pin = GPIO_PIN_5, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF7_USART1}, .active_state = 0}, {// UART RX .port = GPIOE, .pin_init = {.Pin = GPIO_PIN_6, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF7_USART1}, .active_state = 0}, {// VBUS input pin used for TCPP0203 EN .port = GPIOA, .pin_init = {.Pin = GPIO_PIN_7, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, .active_state = 0}, {// I2C SCL for TCPP0203 .port = GPIOB, .pin_init = {.Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF4_I2C2}, }, {// I2C SDA for TCPP0203 .port = GPIOB, .pin_init = {.Pin = GPIO_PIN_11, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF4_I2C2}, }, {// INT for TCPP0203 .port = GPIOD, .pin_init = {.Pin = GPIO_PIN_2, .Mode = GPIO_MODE_IT_FALLING, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0}, }, }; //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /* Configure the power domain */ if (HAL_PWREx_ConfigSupply(PWR_EXTERNAL_SOURCE_SUPPLY) != HAL_OK) { Error_Handler(); } /* Get current CPU/System buses clocks configuration */ /* and if necessary switch to intermediate HSI clock */ /* to ensure target clock can be set */ HAL_RCC_GetClockConfig(&RCC_ClkInitStruct); if ((RCC_ClkInitStruct.CPUCLKSource == RCC_CPUCLKSOURCE_IC1) || (RCC_ClkInitStruct.SYSCLKSource == RCC_SYSCLKSOURCE_IC2_IC6_IC11)) { RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_CPUCLK | RCC_CLOCKTYPE_SYSCLK); RCC_ClkInitStruct.CPUCLKSource = RCC_CPUCLKSOURCE_HSI; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) { Error_Handler(); } } /* HSE selected as source (stable clock on Level 0 samples */ /* PLL1 output = ((HSE/PLLM)*PLLN)/PLLP1/PLLP2 */ /* = ((48000000/3)*75)/1/1 */ /* = (16000000*75)/1/1 */ /* = 1200000000 (1200 MHz) */ /* PLL2 off */ /* PLL3 off */ /* PLL4 off */ /* Enable HSE && HSI */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* 48 MHz */ RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL1.PLLM = 3; RCC_OscInitStruct.PLL1.PLLN = 75; /* PLL1 VCO = 48/3 * 75 = 1200MHz */ RCC_OscInitStruct.PLL1.PLLP1 = 1; /* PLL output = PLL VCO frequency / (PLLP1 * PLLP2) */ RCC_OscInitStruct.PLL1.PLLP2 = 1; /* PLL output = 1200 MHz */ RCC_OscInitStruct.PLL1.PLLFractional = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { /* Initialization error */ Error_Handler(); } /* Select PLL1 outputs as CPU and System bus clock source */ /* CPUCLK = ic1_ck = PLL1 output/ic1_divider = 600 MHz */ /* SYSCLK = ic2_ck = PLL1 output/ic2_divider = 400 MHz */ /* Configure the HCLK clock divider */ /* HCLK = PLL1 SYSCLK/HCLK divider = 200 MHz */ /* PCLKx = HCLK / PCLKx divider = 200 MHz */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_CPUCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK4 | RCC_CLOCKTYPE_PCLK5); RCC_ClkInitStruct.CPUCLKSource = RCC_CPUCLKSOURCE_IC1; RCC_ClkInitStruct.IC1Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC1Selection.ClockDivider = 2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_IC2_IC6_IC11; RCC_ClkInitStruct.IC2Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC2Selection.ClockDivider = 3; RCC_ClkInitStruct.IC6Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC6Selection.ClockDivider = 3; RCC_ClkInitStruct.IC11Selection.ClockSelection = RCC_ICCLKSOURCE_PLL1; RCC_ClkInitStruct.IC11Selection.ClockDivider = 3; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /** Initializes the peripherals clock */ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1; PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /** Set USB OTG HS PHY1 Reference Clock Source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1; PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } //--------------------------------------------------------------------+ // USB PD //--------------------------------------------------------------------+ static I2C_HandleTypeDef i2c_handle = { .Instance = I2C2, .Init = { .Timing = 0x20C0EDFF, .OwnAddress1 = 0, .AddressingMode = I2C_ADDRESSINGMODE_7BIT, .DualAddressMode = I2C_DUALADDRESS_DISABLE, .OwnAddress2 = 0, .OwnAddress2Masks = I2C_OA2_NOMASK, .GeneralCallMode = I2C_GENERALCALL_DISABLE, .NoStretchMode = I2C_NOSTRETCH_DISABLE, }}; static TCPP0203_Object_t tcpp0203_obj = {0}; int32_t board_tcpp0203_init(void) { board_pindef_t *pindef = &board_pindef[PINID_TCPP0203_EN]; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, GPIO_PIN_SET); __HAL_RCC_I2C2_CLK_ENABLE(); __HAL_RCC_I2C2_FORCE_RESET(); __HAL_RCC_I2C2_RELEASE_RESET(); if (HAL_I2C_Init(&i2c_handle) != HAL_OK) { return HAL_ERROR; } NVIC_SetPriority(EXTI8_IRQn, 12); NVIC_EnableIRQ(EXTI8_IRQn); return 0; } int32_t board_tcpp0203_deinit(void) { return 0; } int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000)); return 0; } static inline void board_init2(void) { TCPP0203_IO_t io_ctx; io_ctx.Address = TCPP0203_I2C_ADDRESS_X68; io_ctx.Init = board_tcpp0203_init; io_ctx.DeInit = board_tcpp0203_deinit; io_ctx.ReadReg = i2c_readreg; io_ctx.WriteReg = i2c_writereg; TU_ASSERT(TCPP0203_RegisterBusIO(&tcpp0203_obj, &io_ctx) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_Init(&tcpp0203_obj) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); } void board_vbus_set(uint8_t rhport, bool state) { if (rhport == 0) { uint8_t switch_state = state ? TCPP0203_GD_PROVIDER_SWITCH_CLOSED : TCPP0203_GD_PROVIDER_SWITCH_OPEN; TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, switch_state) == TCPP0203_OK, ); } } void EXTI8_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_8); if (tcpp0203_obj.IsInitialized) { TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, ); TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, ); } } #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/stm32n6/boards/stm32n657nucleo/board.mk ================================================ MCU_VARIANT = stm32n657xx CFLAGS += -DSTM32N657xx JLINK_DEVICE = stm32n657x0 LD_FILE_GCC = $(BOARD_PATH)/STM32N657XX_AXISRAM2_fsbl.ld RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 0 # flash target using on-board stlink flash: flash-stlink PORT = 1 SRC_C += \ $(ST_TCPP0203)/tcpp0203.c \ $(ST_TCPP0203)/tcpp0203_reg.c \ INC += \ $(TOP)/$(ST_TCPP0203) \ ================================================ FILE: hw/bsp/stm32n6/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 * William D. Jones (thor0505@comcast.net), * Ha Thach (tinyusb.org) * Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" #endif #include "stm32n6xx_hal.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" TU_ATTR_UNUSED static void Error_Handler(void) { } void HardFault_Handler(void); static void MPU_Config(void); static void SystemIsolation_Config(void); typedef struct { GPIO_TypeDef* port; GPIO_InitTypeDef pin_init; uint8_t active_state; } board_pindef_t; #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV static UART_HandleTypeDef UartHandle = { .Instance = UART_DEV, .Init = { .BaudRate = CFG_BOARD_UART_BAUDRATE, .WordLength = UART_WORDLENGTH_8B, .StopBits = UART_STOPBITS_1, .Parity = UART_PARITY_NONE, .HwFlowCtl = UART_HWCONTROL_NONE, .Mode = UART_MODE_TX_RX, .OverSampling = UART_OVERSAMPLING_16, } }; #endif #ifndef SWO_FREQ #define SWO_FREQ 4000000 #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ // Despite being call USB2_OTG_FS on some MCUs // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void USB2_OTG_HS_IRQHandler(void) { tusb_int_handler(1, true); } // Despite being call USB1_OTG_HS on some MCUs // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port void USB1_OTG_HS_IRQHandler(void) { tusb_int_handler(0, true); } void board_init(void) { /* Enable BusFault and SecureFault handlers (HardFault is default) */ SCB->SHCSR |= (SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_SECUREFAULTENA_Msk); MPU_Config(); SystemIsolation_Config(); SCB_EnableICache(); SCB_EnableDCache(); HAL_PWREx_EnableVddA(); HAL_PWREx_EnableVddIO2(); HAL_PWREx_EnableVddIO3(); HAL_PWREx_EnableVddIO4(); HAL_PWREx_EnableVddIO5(); HAL_Init(); // Implemented in board.h SystemClock_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPION_CLK_ENABLE(); __HAL_RCC_GPIOO_CLK_ENABLE(); __HAL_RCC_GPIOP_CLK_ENABLE(); __HAL_RCC_GPIOQ_CLK_ENABLE(); for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) { HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init); } NVIC_SetPriority(UCPD1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); NVIC_EnableIRQ(UCPD1_IRQn); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB1_OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #ifdef UART_DEV UART_CLK_EN(); HAL_UART_Init(&UartHandle); #endif #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 0) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0) __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_EnableVddUSBVMEN(); while(__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)); HAL_PWREx_EnableVddUSB(); LL_AHB5_GRP1_ForceReset(0x00800000); __HAL_RCC_USB1_OTG_HS_FORCE_RESET(); __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET(); LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock(); LL_AHB5_GRP1_ReleaseReset(0x00800000); /* Peripheral clock enable */ __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); /* Required few clock cycles before accessing USB PHY Controller Registers */ for (volatile uint32_t i = 0; i < 10; i++) { __NOP(); // No Operation instruction to create a delay } USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4); USB1_HS_PHYC->USBPHYC_CR |= (0x1 << 16) | (0x2 << 4) | (0x1 << 2) | 0x1U; __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET(); /* Required few clock cycles before Releasing Reset */ for (volatile uint32_t i = 0; i < 10; i++) { __NOP(); // No Operation instruction to create a delay } __HAL_RCC_USB1_OTG_HS_RELEASE_RESET(); /* Peripheral PHY clock enable */ __HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE(); #if CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 0 board_vbus_set(BOARD_TUH_RHPORT, 1); #endif #endif #if (CFG_TUD_ENABLED && BOARD_TUD_RHPORT == 1) || (CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1) __HAL_RCC_USB2_OTG_HS_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_EnableVddUSBVMEN(); while(__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)); HAL_PWREx_EnableVddUSB(); LL_AHB5_GRP1_ForceReset(0x00800000); __HAL_RCC_USB2_OTG_HS_FORCE_RESET(); __HAL_RCC_USB2_OTG_HS_PHY_FORCE_RESET(); LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock(); LL_AHB5_GRP1_ReleaseReset(0x00800000); /* Peripheral clock enable */ __HAL_RCC_USB2_OTG_HS_CLK_ENABLE(); /* Required few clock cycles before accessing USB PHY Controller Registers */ for (volatile uint32_t i = 0; i < 10; i++) { __NOP(); // No Operation instruction to create a delay } USB2_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4); USB2_HS_PHYC->USBPHYC_CR |= (0x1 << 16) | (0x2 << 4) | (0x1 << 2) | 0x1U; __HAL_RCC_USB2_OTG_HS_PHY_RELEASE_RESET(); /* Required few clock cycles before Releasing Reset */ for (volatile uint32_t i = 0; i < 10; i++) { __NOP(); // No Operation instruction to create a delay } __HAL_RCC_USB2_OTG_HS_RELEASE_RESET(); /* Peripheral PHY clock enable */ __HAL_RCC_USB2_OTG_HS_PHY_CLK_ENABLE(); #if CFG_TUH_ENABLED && BOARD_TUH_RHPORT == 1 board_vbus_set(BOARD_TUH_RHPORT, 1); #endif #endif board_init2(); } static void MPU_Config(void) { MPU_Region_InitTypeDef default_config = {0}; MPU_Attributes_InitTypeDef attr_config = {0}; uint32_t primask_bit = __get_PRIMASK(); __disable_irq(); /* disable the MPU */ HAL_MPU_Disable(); /* create an attribute configuration for the MPU */ attr_config.Attributes = INNER_OUTER(MPU_NOT_CACHEABLE); attr_config.Number = MPU_ATTRIBUTES_NUMBER0; HAL_MPU_ConfigMemoryAttributes(&attr_config); /* Create a non cacheable region */ /*Normal memory type, code execution allowed */ default_config.Enable = MPU_REGION_ENABLE; default_config.Number = MPU_REGION_NUMBER0; default_config.BaseAddress = __NON_CACHEABLE_SECTION_BEGIN; default_config.LimitAddress = __NON_CACHEABLE_SECTION_END; default_config.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; default_config.AccessPermission = MPU_REGION_ALL_RW; default_config.IsShareable = MPU_ACCESS_NOT_SHAREABLE; default_config.AttributesIndex = MPU_ATTRIBUTES_NUMBER0; HAL_MPU_ConfigRegion(&default_config); /* enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); /* Exit critical section to lock the system and avoid any issue around MPU mechanisme */ __set_PRIMASK(primask_bit); } static void SystemIsolation_Config(void) { /* set all required IPs as secure privileged */ __HAL_RCC_RIFSC_CLK_ENABLE(); RIMC_MasterConfig_t RIMC_master = {0}; RIMC_master.MasterCID = RIF_CID_1; RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; /*RIMC configuration*/ HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_OTG1, &RIMC_master); HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_OTG2, &RIMC_master); /*RISUP configuration*/ HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_OTG1HS , RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_OTG2HS , RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { #ifdef PINID_LED board_pindef_t* pindef = &board_pindef[PINID_LED]; GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state); #else (void) state; #endif } uint32_t board_button_read(void) { #ifdef PINID_BUTTON board_pindef_t* pindef = &board_pindef[PINID_BUTTON]; return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin); #else return 0; #endif } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t* id32 = (uint32_t*) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return -1; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32n6/family.cmake ================================================ include_guard() set(ST_FAMILY n6) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) set(ST_TCPP0203 ${TOP}/hw/mcu/st/stm32-tcpp0203) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m55 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32N6 CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- if (NOT DEFINED RHPORT_DEVICE) set(RHPORT_DEVICE 0) endif () if (NOT DEFINED RHPORT_HOST) set(RHPORT_HOST 1) endif () # N6 are all high speed if (NOT DEFINED RHPORT_DEVICE_SPEED) set(RHPORT_DEVICE_SPEED OPT_MODE_HIGH_SPEED) endif () if (NOT DEFINED RHPORT_HOST_SPEED) set(RHPORT_HOST_SPEED OPT_MODE_HIGH_SPEED) endif () cmake_print_variables(RHPORT_DEVICE RHPORT_DEVICE_SPEED RHPORT_HOST RHPORT_HOST_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) if(NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT}_axisram2_fsbl.ld) endif() set(LD_FILE_Clang ${LD_FILE_GNU}) if(NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_axisram2_fsbl.icf) endif() #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}_fsbl.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rif.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${TOP}/lib/CMSIS_6/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) target_compile_definitions(${BOARD_TARGET} PUBLIC BOARD_TUD_RHPORT=${RHPORT_DEVICE} BOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} BOARD_TUH_RHPORT=${RHPORT_HOST} BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} SEGGER_RTT_SECTION=".noncacheable" BUFFER_SIZE_UP=0x4000 ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32N6 ${RTOS}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32n6/family.mk ================================================ ST_FAMILY = n6 ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/${ST_PREFIX}_hal_driver ST_TCPP0203 = hw/mcu/st/stm32-tcpp0203 UF2_FAMILY_ID = 0x6db66083 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m55 # ---------------------- # Port & Speed Selection # ---------------------- RHPORT_DEVICE ?= 0 RHPORT_HOST ?= 1 ifndef RHPORT_DEVICE_SPEED RHPORT_DEVICE_SPEED = OPT_MODE_HIGH_SPEED endif ifndef RHPORT_HOST_SPEED RHPORT_HOST_SPEED = OPT_MODE_HIGH_SPEED endif # -------------- # Compiler Flags # -------------- CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32N6 \ -DBOARD_TUD_RHPORT=${RHPORT_DEVICE} \ -DBOARD_TUD_MAX_SPEED=${RHPORT_DEVICE_SPEED} \ -DBOARD_TUH_RHPORT=${RHPORT_HOST} \ -DBOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED} \ -DSEGGER_RTT_SECTION="\".noncacheable\"" \ -DBUFFER_SIZE_UP=0x4000 \ # GCC Flags CFLAGS_GCC += \ -flto \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -Wno-error=cast-align \ -Wno-error=unused-parameter \ LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include # ----------------- SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}_fsbl.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_dma.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_hcd.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_i2c.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rif.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_ll_usb.c \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT)_fsbl.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_GCC ?= $(ST_CMSIS)/Source/Templates/gcc/linker/$(MCU_VARIANT)_flash.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32n6/partition_stm32n657xx.h ================================================ /** ****************************************************************************** * @file partition_stm32n657xx.h * @author MCD Application Team * @brief CMSIS STM32N657xx Device Initial Setup for Secure / Non-Secure Zones * for ARMCM55 based on CMSIS CORE V5.3.1 partition_ARMCM33.h Template. * * This file contains: * - Initialize Security Attribution Unit (SAU) CTRL register * - Setup behavior of Sleep and Exception Handling * - Setup behavior of Floating Point Unit * - Setup Interrupt Target * ******************************************************************************/ /* * Copyright (c) 2009-2016 ARM Limited. All rights reserved. * Portions Copyright (c) 2023 STMicroelectronics, all rights reserved * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PARTITION_STM32N657XX_H #define PARTITION_STM32N657XX_H /* //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- */ /* // Initialize Security Attribution Unit (SAU) CTRL register */ #define SAU_INIT_CTRL 0 /* // Enable SAU // Value for SAU->CTRL register bit ENABLE */ #define SAU_INIT_CTRL_ENABLE 0 /* // When SAU is disabled // <0=> All Memory is Secure // <1=> All Memory is Non-Secure // Value for SAU->CTRL register bit ALLNS // When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. */ #define SAU_INIT_CTRL_ALLNS 0 /* // */ /* // Initialize Security Attribution Unit (SAU) Address Regions // SAU configuration specifies regions to be one of: // - Secure and Non-Secure Callable // - Non-Secure // Note: All memory regions not configured by SAU are Secure */ #define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ /* // Initialize SAU Region 0 // Setup SAU Region 0 memory attributes */ #define SAU_INIT_REGION0 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START0 0x00000000 /* start address of SAU region 0 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END0 0x00000000 /* end address of SAU region 0 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC0 0 /* // */ /* // Initialize SAU Region 1 // Setup SAU Region 1 memory attributes */ #define SAU_INIT_REGION1 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START1 0x00000000 /* start address of SAU region 1 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END1 0x00000000 /* end address of SAU region 1 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC1 0 /* // */ /* // Initialize SAU Region 2 // Setup SAU Region 2 memory attributes */ #define SAU_INIT_REGION2 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START2 0x00000000 /* start address of SAU region 2 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END2 0x00000000 /* end address of SAU region 2 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC2 0 /* // */ /* // Initialize SAU Region 3 // Setup SAU Region 3 memory attributes */ #define SAU_INIT_REGION3 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START3 0x00000000 /* start address of SAU region 3 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END3 0x00000000 /* end address of SAU region 3 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC3 0 /* // */ /* // Initialize SAU Region 4 // Setup SAU Region 4 memory attributes */ #define SAU_INIT_REGION4 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC4 0 /* // */ /* // Initialize SAU Region 5 // Setup SAU Region 5 memory attributes */ #define SAU_INIT_REGION5 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START5 0x00000000 /* start address of SAU region 5 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END5 0x00000000 /* end address of SAU region 5 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC5 0 /* // */ /* // Initialize SAU Region 6 // Setup SAU Region 6 memory attributes */ #define SAU_INIT_REGION6 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC6 0 /* // */ /* // Initialize SAU Region 7 // Setup SAU Region 7 memory attributes */ #define SAU_INIT_REGION7 0 /* // Start Address <0-0xFFFFFFE0> */ #define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */ /* // End Address <0x1F-0xFFFFFFFF> */ #define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */ /* // Region is // <0=>Non-Secure // <1=>Secure, Non-Secure Callable */ #define SAU_INIT_NSC7 0 /* // */ /* // */ /* // Setup behaviour of Sleep and Exception Handling */ #define SCB_CSR_AIRCR_INIT 0 /* // Deep Sleep can be enabled by // <0=>Secure and Non-Secure state // <1=>Secure state only // Value for SCB->CSR register bit DEEPSLEEPS */ #define SCB_CSR_DEEPSLEEPS_VAL 0 /* // System reset request accessible from // <0=> Secure and Non-Secure state // <1=> Secure state only // Value for SCB->AIRCR register bit SYSRESETREQS */ #define SCB_AIRCR_SYSRESETREQS_VAL 0 /* // Priority of Non-Secure exceptions is // <0=> Not altered // <1=> Lowered to 0x04-0x07 // Value for SCB->AIRCR register bit PRIS */ #define SCB_AIRCR_PRIS_VAL 0 /* // BusFault, HardFault, and NMI target // <0=> Secure state // <1=> Non-Secure state // Value for SCB->AIRCR register bit BFHFNMINS */ #define SCB_AIRCR_BFHFNMINS_VAL 0 /* // */ /* // Setup behaviour of Floating Point Unit */ #define TZ_FPU_NS_USAGE 1 /* // Floating Point Unit usage // <0=> Secure state only // <3=> Secure and Non-Secure state // Value for SCB->NSACR register bits CP10, CP11 */ #define SCB_NSACR_CP10_11_VAL 3 /* // Treat floating-point registers as Secure // <0=> Disabled // <1=> Enabled // Value for FPU->FPCCR register bit TS */ #define FPU_FPCCR_TS_VAL 0 /* // Clear on return (CLRONRET) accessibility // <0=> Secure and Non-Secure state // <1=> Secure state only // Value for FPU->FPCCR register bit CLRONRETS */ #define FPU_FPCCR_CLRONRETS_VAL 0 /* // Clear floating-point caller saved registers on exception return // <0=> Disabled // <1=> Enabled // Value for FPU->FPCCR register bit CLRONRET */ #define FPU_FPCCR_CLRONRET_VAL 1 /* // */ /* // Setup Interrupt Target */ /* // Initialize ITNS 0 (Interrupts 0..31) */ #define NVIC_INIT_ITNS0 1 /* // Interrupts 0..31 // PVD_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // DTS_IRQn <0=> Secure state <1=> Non-Secure state // RCC_IRQn <0=> Secure state <1=> Non-Secure state // LOCKUP_IRQn <0=> Secure state <1=> Non-Secure state // CACHE_ECC_IRQn <0=> Secure state <1=> Non-Secure state // TCM_ECC_IRQn <0=> Secure state <1=> Non-Secure state // BKP_ECC_IRQn <0=> Secure state <1=> Non-Secure state // FPU_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // RTC_S_IRQn <0=> Secure state <1=> Non-Secure state // TAMP_IRQn <0=> Secure state <1=> Non-Secure state // RIFSC_TAMPER_IRQn <0=> Secure state <1=> Non-Secure state // IAC_IRQn <0=> Secure state <1=> Non-Secure state // RCC_S_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // RTC_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // IWDG_IRQn <0=> Secure state <1=> Non-Secure state // WWDG_IRQn <0=> Secure state <1=> Non-Secure state // EXTI0_IRQn <0=> Secure state <1=> Non-Secure state // EXTI1_IRQn <0=> Secure state <1=> Non-Secure state // EXTI2_IRQn <0=> Secure state <1=> Non-Secure state // EXTI3_IRQn <0=> Secure state <1=> Non-Secure state // EXTI4_IRQn <0=> Secure state <1=> Non-Secure state // EXTI5_IRQn <0=> Secure state <1=> Non-Secure state // EXTI6_IRQn <0=> Secure state <1=> Non-Secure state // EXTI7_IRQn <0=> Secure state <1=> Non-Secure state // EXTI8_IRQn <0=> Secure state <1=> Non-Secure state // EXTI9_IRQn <0=> Secure state <1=> Non-Secure state // EXTI10_IRQn <0=> Secure state <1=> Non-Secure state // EXTI11_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS0_VAL 0x00000000 /* // */ /* // Initialize ITNS 1 (Interrupts 32..63) */ #define NVIC_INIT_ITNS1 1 /* // Interrupts 32..63 // EXTI12_IRQn <0=> Secure state <1=> Non-Secure state // EXTI13_IRQn <0=> Secure state <1=> Non-Secure state // EXTI14_IRQn <0=> Secure state <1=> Non-Secure state // EXTI15_IRQn <0=> Secure state <1=> Non-Secure state // SAES_IRQn <0=> Secure state <1=> Non-Secure state // CRYP_IRQn <0=> Secure state <1=> Non-Secure state // PKA_IRQn <0=> Secure state <1=> Non-Secure state // HASH_IRQn <0=> Secure state <1=> Non-Secure state // RNG_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // MCE1_IRQn <0=> Secure state <1=> Non-Secure state // MCE2_IRQn <0=> Secure state <1=> Non-Secure state // MCE3_IRQn <0=> Secure state <1=> Non-Secure state // MCE4_IRQn <0=> Secure state <1=> Non-Secure state // ADC1_2_IRQn <0=> Secure state <1=> Non-Secure state // CSI_IRQn <0=> Secure state <1=> Non-Secure state // DCMIPP_IRQn <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // Reserved <0=> Secure state <1=> Non-Secure state // PAHB_ERR_IRQn <0=> Secure state <1=> Non-Secure state // NPU0_IRQn <0=> Secure state <1=> Non-Secure state // NPU1_IRQn <0=> Secure state <1=> Non-Secure state // NPU2_IRQn <0=> Secure state <1=> Non-Secure state // NPU3_IRQn <0=> Secure state <1=> Non-Secure state // CACHEAXI_IRQn <0=> Secure state <1=> Non-Secure state // LTDC_LO_IRQn <0=> Secure state <1=> Non-Secure state // LTDC_LO_ERR_IRQn <0=> Secure state <1=> Non-Secure state // DMA2D_IRQn <0=> Secure state <1=> Non-Secure state // JPEG_IRQn <0=> Secure state <1=> Non-Secure state // VENC_IRQn <0=> Secure state <1=> Non-Secure state // GFXMMU_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS1_VAL 0x00000000 /* // */ /* // Initialize ITNS 2 (Interrupts 64..95) */ #define NVIC_INIT_ITNS2 1 /* // Interrupts 64..95 // GFXTIM_IRQn <0=> Secure state <1=> Non-Secure state // GPU2D_IRQn <0=> Secure state <1=> Non-Secure state // GPU2D_ER_IRQn <0=> Secure state <1=> Non-Secure state // ICACHE_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel8_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel9_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel10_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel11_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel12_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel13_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel14_IRQn <0=> Secure state <1=> Non-Secure state // HPDMA1_Channel15_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel8_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel9_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel10_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel11_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS2_VAL 0x00000000 /* // */ /* // Initialize ITNS 3 (Interrupts 96..127) */ #define NVIC_INIT_ITNS3 1 /* // Interrupts 96..127 // GPDMA1_Channel12_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel13_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel14_IRQn <0=> Secure state <1=> Non-Secure state // GPDMA1_Channel15_IRQn <0=> Secure state <1=> Non-Secure state // I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state // I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state // I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state // I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state // I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state // I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state // I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state // I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state // I3C1_EV_IRQn <0=> Secure state <1=> Non-Secure state // I3C1_ER_IRQn <0=> Secure state <1=> Non-Secure state // I3C2_EV_IRQn <0=> Secure state <1=> Non-Secure state // I3C2_ER_IRQn <0=> Secure state <1=> Non-Secure state // TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state // TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state // TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state // TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state // TIM2_IRQn <0=> Secure state <1=> Non-Secure state // TIM3_IRQn <0=> Secure state <1=> Non-Secure state // TIM4_IRQn <0=> Secure state <1=> Non-Secure state // TIM5_IRQn <0=> Secure state <1=> Non-Secure state // TIM6_IRQn <0=> Secure state <1=> Non-Secure state // TIM7_IRQn <0=> Secure state <1=> Non-Secure state // TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state // TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state // TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state // TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state // TIM9_IRQn <0=> Secure state <1=> Non-Secure state // TIM10_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS3_VAL 0x00000000 /* // */ /* // Initialize ITNS 4 (Interrupts 128..159) */ #define NVIC_INIT_ITNS4 1 /* // Interrupts 128..159 // TIM11_IRQn <0=> Secure state <1=> Non-Secure state // TIM12_IRQn <0=> Secure state <1=> Non-Secure state // TIM13_IRQn <0=> Secure state <1=> Non-Secure state // TIM14_IRQn <0=> Secure state <1=> Non-Secure state // TIM15_IRQn <0=> Secure state <1=> Non-Secure state // TIM16_IRQn <0=> Secure state <1=> Non-Secure state // TIM17_IRQn <0=> Secure state <1=> Non-Secure state // TIM18_IRQn <0=> Secure state <1=> Non-Secure state // LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state // LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state // LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state // LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state // LPTIM5_IRQn <0=> Secure state <1=> Non-Secure state // ADF1_FLT0_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT0_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT1_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT2_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT3_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT4_IRQn <0=> Secure state <1=> Non-Secure state // MDF1_FLT5_IRQn <0=> Secure state <1=> Non-Secure state // SAI1_A_IRQn <0=> Secure state <1=> Non-Secure state // SAI1_B_IRQn <0=> Secure state <1=> Non-Secure state // SAI2_A_IRQn <0=> Secure state <1=> Non-Secure state // SAI2_B_IRQn <0=> Secure state <1=> Non-Secure state // SPDIFRX1_IRQn <0=> Secure state <1=> Non-Secure state // SPI1_IRQn <0=> Secure state <1=> Non-Secure state // SPI2_IRQn <0=> Secure state <1=> Non-Secure state // SPI3_IRQn <0=> Secure state <1=> Non-Secure state // SPI4_IRQn <0=> Secure state <1=> Non-Secure state // SPI5_IRQn <0=> Secure state <1=> Non-Secure state // SPI6_IRQn <0=> Secure state <1=> Non-Secure state // USART1_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS4_VAL 0x00000000 /* // */ /* // Initialize ITNS 5 (Interrupts 160..191) */ #define NVIC_INIT_ITNS5 1 /* // Interrupts 160..191 // USART2_IRQn <0=> Secure state <1=> Non-Secure state // USART3_IRQn <0=> Secure state <1=> Non-Secure state // UART4_IRQn <0=> Secure state <1=> Non-Secure state // UART5_IRQn <0=> Secure state <1=> Non-Secure state // USART6_IRQn <0=> Secure state <1=> Non-Secure state // UART7_IRQn <0=> Secure state <1=> Non-Secure state // UART8_IRQn <0=> Secure state <1=> Non-Secure state // UART9_IRQn <0=> Secure state <1=> Non-Secure state // USART10_IRQn <0=> Secure state <1=> Non-Secure state // LPUART1_IRQn <0=> Secure state <1=> Non-Secure state // XSPI1_IRQn <0=> Secure state <1=> Non-Secure state // XSPI2_IRQn <0=> Secure state <1=> Non-Secure state // XSPI3_IRQn <0=> Secure state <1=> Non-Secure state // FMC_IRQn <0=> Secure state <1=> Non-Secure state // SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state // SDMMC2_IRQn <0=> Secure state <1=> Non-Secure state // UCPD1_IRQn <0=> Secure state <1=> Non-Secure state // USB1_OTG_HS_IRQn <0=> Secure state <1=> Non-Secure state // USB2_OTG_HS_IRQn <0=> Secure state <1=> Non-Secure state // ETH1_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN2_IT0_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN2_IT1_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN3_IT0_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN3_IT1_IRQn <0=> Secure state <1=> Non-Secure state // FDCAN_CU_IRQn <0=> Secure state <1=> Non-Secure state // MDIOS_IRQn <0=> Secure state <1=> Non-Secure state // DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state // WAKEUP_PIN_IRQn <0=> Secure state <1=> Non-Secure state // CTI_INT0_IRQn <0=> Secure state <1=> Non-Secure state // CTI_INT1_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS5_VAL 0x00000000 /* // */ /* // Initialize ITNS 6 (Interrupts 192..223) */ #define NVIC_INIT_ITNS6 1 /* // Interrupts 192..223 // Reserved <0=> Secure state <1=> Non-Secure state // LTDC_UP_IRQn <0=> Secure state <1=> Non-Secure state // LTDC_UP_ERR_IRQn <0=> Secure state <1=> Non-Secure state */ #define NVIC_INIT_ITNS6_VAL 0x00000000 /* // */ /* // */ /* max 8 SAU regions. SAU regions are defined in partition.h */ #define SAU_INIT_REGION(n) \ SAU->RNR = (n & SAU_RNR_REGION_Msk); \ SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U /** \brief Setup a SAU Region \details Writes the region information contained in SAU_Region to the registers SAU_RNR, SAU_RBAR, and SAU_RLAR */ __STATIC_INLINE void TZ_SAU_Setup (void) { #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) SAU_INIT_REGION(0); #endif #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) SAU_INIT_REGION(1); #endif #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) SAU_INIT_REGION(2); #endif #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) SAU_INIT_REGION(3); #endif #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) SAU_INIT_REGION(4); #endif #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) SAU_INIT_REGION(5); #endif #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) SAU_INIT_REGION(6); #endif #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) SAU_INIT_REGION(7); #endif /* repeat this for all possible SAU regions */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; #endif #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); #endif #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; #endif #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; #endif #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; #endif #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; #endif #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; #endif #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; #endif #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; #endif } #endif /* PARTITION_STM32N657XX_H */ ================================================ FILE: hw/bsp/stm32n6/setup_iar.mac ================================================ /* Called once after the target reset. */ execUserReset() { /* Re-load image as AIXRAM2 is erased after CPU reset */ __loadImage("$EXE_DIR$\\$TARGET_BNAME$.hex", 0, 0); __restoreSoftwareBreakpoints(); #PC = __readMemory32(0x34180404, "Memory"); #SP = 0x341FFD00; } ================================================ FILE: hw/bsp/stm32n6/stm32n6.jdebug ================================================ /********************************************************************* * (c) SEGGER Microcontroller GmbH * * The Embedded Experts * * www.segger.com * ********************************************************************** File : Created : 31. Jan 2026 16:34 Ozone Version : V3.40e */ /********************************************************************* * * OnProjectLoad * * Function description * Project load routine. Required. * ********************************************************************** */ void OnProjectLoad (void) { // // Dialog-generated settings // Project.SetDevice ("STM32N657X0"); Project.SetHostIF ("USB", ""); Project.SetTargetIF ("SWD"); Project.SetTIFSpeed ("4 MHz"); Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M55F.svd"); // // User settings // File.Open ("$(ProjectDir)/../../../examples/device/cdc_msc/build/stm32n6570dk/RelWithDebInfo/cdc_msc.elf"); } /********************************************************************* * * OnStartupComplete * * Function description * Called when program execution has reached/passed * the startup completion point. Optional. * ********************************************************************** */ //void OnStartupComplete (void) { //} /********************************************************************* * * TargetReset * * Function description * Replaces the default target device reset routine. Optional. * * Notes * This example demonstrates the usage when * debugging an application in RAM on a Cortex-M target device. * ********************************************************************** */ //void TargetReset (void) { // // unsigned int SP; // unsigned int PC; // unsigned int VectorTableAddr; // // VectorTableAddr = Elf.GetBaseAddr(); // // // // Set up initial stack pointer // // // if (VectorTableAddr != 0xFFFFFFFF) { // SP = Target.ReadU32(VectorTableAddr); // Target.SetReg("SP", SP); // } // // // // Set up entry point PC // // // PC = Elf.GetEntryPointPC(); // // if (PC != 0xFFFFFFFF) { // Target.SetReg("PC", PC); // } else if (VectorTableAddr != 0xFFFFFFFF) { // PC = Target.ReadU32(VectorTableAddr + 4); // Target.SetReg("PC", PC); // } else { // Util.Error("Project file error: failed to set entry point PC", 1); // } //} /********************************************************************* * * BeforeTargetReset * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetReset (void) { //} /********************************************************************* * * AfterTargetReset * * Function description * Event handler routine. Optional. * The default implementation initializes SP and PC to reset values. ** ********************************************************************** */ void AfterTargetReset (void) { _SetupTarget(); } /********************************************************************* * * DebugStart * * Function description * Replaces the default debug session startup routine. Optional. * ********************************************************************** */ //void DebugStart (void) { //} /********************************************************************* * * TargetConnect * * Function description * Replaces the default target IF connection routine. Optional. * ********************************************************************** */ //void TargetConnect (void) { //} /********************************************************************* * * BeforeTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetConnect (void) { //} /********************************************************************* * * AfterTargetConnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetConnect (void) { //} /********************************************************************* * * TargetDownload * * Function description * Replaces the default program download routine. Optional. * ********************************************************************** */ //void TargetDownload (void) { //} /********************************************************************* * * BeforeTargetDownload * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDownload (void) { //} /********************************************************************* * * AfterTargetDownload * * Function description * Event handler routine. Optional. * The default implementation initializes SP and PC to reset values. * ********************************************************************** */ void AfterTargetDownload (void) { //_SetupTarget(); } /********************************************************************* * * BeforeTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetDisconnect * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetDisconnect (void) { //} /********************************************************************* * * AfterTargetHalt * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void AfterTargetHalt (void) { //} /********************************************************************* * * BeforeTargetResume * * Function description * Event handler routine. Optional. * ********************************************************************** */ //void BeforeTargetResume (void) { //} /********************************************************************* * * OnSnapshotLoad * * Function description * Called upon loading a snapshot. Optional. * * Additional information * This function is used to restore the target state in cases * where values cannot simply be written to the target. * Typical use: GPIO clock needs to be enabled, before * GPIO is configured. * ********************************************************************** */ //void OnSnapshotLoad (void) { //} /********************************************************************* * * OnSnapshotSave * * Function description * Called upon saving a snapshot. Optional. * * Additional information * This function is usually used to save values of the target * state which can either not be trivially read, * or need to be restored in a specific way or order. * Typically use: Memory Mapped Registers, * such as PLL and GPIO configuration. * ********************************************************************** */ //void OnSnapshotSave (void) { //} /********************************************************************* * * OnError * * Function description * Called when an error occurred. Optional. * ********************************************************************** */ //void OnError (void) { //} /********************************************************************* * * AfterProjectLoad * * Function description * After Project load routine. Optional. * ********************************************************************** */ //void AfterProjectLoad (void) { //} /********************************************************************* * * OnDebugStartBreakSymbolReached * * Function description * Called when program execution has reached/passed * the symbol to be breaked at during debug start. Optional. * ********************************************************************** */ //void OnDebugStartBreakSymReached (void) { //} /********************************************************************* * * _SetupTarget * * Function description * Setup the target. * Called by AfterTargetReset() and AfterTargetDownload(). * * Auto-generated function. May be overridden by Ozone. * ********************************************************************** */ void _SetupTarget(void) { unsigned int SP; unsigned int PC; unsigned int VectorTableAddr; Debug.Download(); Debug.Halt(); VectorTableAddr = Elf.GetBaseAddr(); // // Set up initial stack pointer // SP = Target.ReadU32(VectorTableAddr); if (SP != 0xFFFFFFFF) { Target.SetReg("SP", SP); } // // Set up entry point PC // PC = Elf.GetEntryPointPC(); if (PC != 0xFFFFFFFF) { Target.SetReg("PC", PC); } else { Util.Error("Project script error: failed to set up entry point PC", 1); } } ================================================ FILE: hw/bsp/stm32n6/stm32n6xx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32n6xx_hal_conf_template.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32n6xx_hal_conf.h. ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32N6xx_HAL_CONF_H #define STM32N6xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_BSEC_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_DCMI_MODULE_ENABLED */ /*#define HAL_DCMIPP_MODULE_ENABLED */ /*#define HAL_DMA2D_MODULE_ENABLED */ /*#define HAL_DTS_MODULE_ENABLED */ /*#define HAL_ETH_MODULE_ENABLED */ /*#define HAL_EXTI_MODULE_ENABLED */ /*#define HAL_FDCAN_MODULE_ENABLED */ /*#define HAL_GFXMMU_MODULE_ENABLED */ /*#define HAL_GFXTIM_MODULE_ENABLED */ /*#define HAL_HASH_MODULE_ENABLED */ /*#define HAL_HCD_MODULE_ENABLED */ #define HAL_I2C_MODULE_ENABLED /*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_I3C_MODULE_ENABLED */ /*#define HAL_ICACHE_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ /*#define HAL_JPEG_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */ /*#define HAL_LTDC_MODULE_ENABLED */ /*#define HAL_MCE_MODULE_ENABLED */ /*#define HAL_MDF_MODULE_ENABLED */ /*#define HAL_MMC_MODULE_ENABLED */ /*#define HAL_NAND_MODULE_ENABLED */ /*#define HAL_NOR_MODULE_ENABLED */ /*#define HAL_PCD_MODULE_ENABLED */ /*#define HAL_PKA_MODULE_ENABLED */ /*#define HAL_PSSI_MODULE_ENABLED */ /*#define HAL_RAMCFG_MODULE_ENABLED */ #define HAL_RIF_MODULE_ENABLED /*#define HAL_RNG_MODULE_ENABLED */ /*#define HAL_RTC_MODULE_ENABLED */ /*#define HAL_SAI_MODULE_ENABLED */ /*#define HAL_SD_MODULE_ENABLED */ /*#define HAL_SDIO_MODULE_ENABLED */ /*#define HAL_SDRAM_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED*/ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SPDIFRX_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_SRAM_MODULE_ENABLED */ /*#define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ /*#define HAL_XSPI_MODULE_ENABLED */ /*#define HAL_CACHEAXI_MODULE_ENABLED */ /*#define HAL_MDIOS_MODULE_ENABLED */ /*#define HAL_GPU2D_MODULE_ENABLED */ /*#define HAL_CACHEAXI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 48000000UL /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz */ #endif /* MSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz */ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz */ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz */ /* The real value may vary depending on the variations in voltage and temperature.*/ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300UL /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 15U /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32n6xx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CACHEAXI_REGISTER_CALLBACKS 0U /* CACHEAXI register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DCMIPP_REGISTER_CALLBACKS 0U /* DCMIPP register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ #define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U /* GFXMMU register callback disabled */ #define USE_HAL_GFXTIM_REGISTER_CALLBACKS 0U /* GFXTIM register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ #define USE_HAL_I3C_REGISTER_CALLBACKS 0U /* I3C register callback disabled */ #define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MCE_REGISTER_CALLBACKS 0U /* MCE register callback disabled */ #define USE_HAL_MDF_REGISTER_CALLBACKS 0U /* MDF register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ #define USE_HAL_PSSI_REGISTER_CALLBACKS 0U /* PSSI register callback disabled */ #define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SDIO_REGISTER_CALLBACKS 0U /* SDIO register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* ################## SDMMC peripheral configuration ######################### */ #define USE_SD_TRANSCEIVER 0U /* ################## SDIO peripheral configuration ########################## */ #define USE_SDIO_TRANSCEIVER 1U #define SDIO_MAX_IO_NUMBER 7U /*!< SDIO device support maximum IO number */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32n6xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32n6xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_RIF_MODULE_ENABLED #include "stm32n6xx_hal_rif.h" #endif /* HAL_RIF_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32n6xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CACHEAXI_MODULE_ENABLED #include "stm32n6xx_hal_cacheaxi.h" #endif /* HAL_CACHEAXI_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32n6xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32n6xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_BSEC_MODULE_ENABLED #include "stm32n6xx_hal_bsec.h" #endif /* HAL_BSEC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32n6xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32n6xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32n6xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_DCMIPP_MODULE_ENABLED #include "stm32n6xx_hal_dcmipp.h" #endif /* HAL_DCMIPP_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32n6xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DTS_MODULE_ENABLED #include "stm32n6xx_hal_dts.h" #endif /* HAL_DTS_MODULE_ENABLED */ #ifdef HAL_ETH_MODULE_ENABLED #include "stm32n6xx_hal_eth.h" #endif /* HAL_ETH_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32n6xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32n6xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_GFXMMU_MODULE_ENABLED #include "stm32n6xx_hal_gfxmmu.h" #endif /* HAL_GFXMMU_MODULE_ENABLED */ #ifdef HAL_GFXTIM_MODULE_ENABLED #include "stm32n6xx_hal_gfxtim.h" #endif /* HAL_GFXTIM_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32n6xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_GPU2D_MODULE_ENABLED #include "stm32n6xx_hal_gpu2d.h" #endif /* HAL_GPU2D_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32n6xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32n6xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32n6xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED #include "stm32n6xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_I3C_MODULE_ENABLED #include "stm32n6xx_hal_i3c.h" #endif /* HAL_I3C_MODULE_ENABLED */ #ifdef HAL_ICACHE_MODULE_ENABLED #include "stm32n6xx_hal_icache.h" #endif /* HAL_ICACHE_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32n6xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32n6xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_JPEG_MODULE_ENABLED #include "stm32n6xx_hal_jpeg.h" #endif /* HAL_JPEG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32n6xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32n6xx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_MCE_MODULE_ENABLED #include "stm32n6xx_hal_mce.h" #endif /* HAL_MCE_MODULE_ENABLED */ #ifdef HAL_MDF_MODULE_ENABLED #include "stm32n6xx_hal_mdf.h" #endif /* HAL_MDF_MODULE_ENABLED */ #ifdef HAL_MDIOS_MODULE_ENABLED #include "stm32n6xx_hal_mdios.h" #endif /* HAL_MDIOS_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED #include "stm32n6xx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32n6xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32n6xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32n6xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32n6xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PKA_MODULE_ENABLED #include "stm32n6xx_hal_pka.h" #endif /* HAL_PKA_MODULE_ENABLED */ #ifdef HAL_PSSI_MODULE_ENABLED #include "stm32n6xx_hal_pssi.h" #endif /* HAL_PSSI_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32n6xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RAMCFG_MODULE_ENABLED #include "stm32n6xx_hal_ramcfg.h" #endif /* HAL_RAMCFG_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32n6xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32n6xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32n6xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32n6xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SDIO_MODULE_ENABLED #include "stm32n6xx_hal_sdio.h" #endif /* HAL_SDIO_MODULE_ENABLED */ #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32n6xx_hal_sdram.h" #endif /* HAL_SDRAM_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32n6xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32n6xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32n6xx_hal_spdifrx.h" #endif /* HAL_SPDIFRX_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32n6xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32n6xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32n6xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32n6xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32n6xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32n6xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_XSPI_MODULE_ENABLED #include "stm32n6xx_hal_xspi.h" #endif /* HAL_XSPI_MODULE_ENABLED */ /* Exported macros -----------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32N6xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32u0/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32u0xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 200 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; #endif // LED GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV // UART GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UART_CLK_EN(); UartHandle.Instance = UART_DEV; UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); #endif #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Enable VDDUSB HAL_PWREx_EnableVddUSB(); // USB Clock enable __HAL_RCC_USB_CLK_ENABLE(); board_vbus_sense_init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1-LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { #ifdef UART_DEV (void) buf; (void) len; return 0; #else return 0; #endif } int board_uart_write(void const * buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32u0/family.cmake ================================================ include_guard() set(ST_FAMILY u0) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis-device-${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32U0 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ string(REPLACE "stm32u" "STM32U" MCU_VARIANT_UPPER ${MCU_VARIANT}) set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED LD_FILE_IAR) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) endif () #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32U0) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32u0/family.mk ================================================ ST_FAMILY = u0 ST_CMSIS = hw/mcu/st/cmsis-device-$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_STM32U0 # mcu driver cause following warnings CFLAGS_GCC += \ -flto \ -Wno-error=unused-parameter \ -Wno-error=redundant-decls \ -Wno-error=cast-align \ -Wno-error=maybe-uninitialized \ CFLAGS_CLANG += \ -Wno-error=parentheses-equality LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ ${ST_HAL_DRIVER}/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_${MCU_VARIANT}.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_${MCU_VARIANT}.s # Linker MCU_VARIANT_UPPER = $(subst stm32u,STM32U,$(MCU_VARIANT)) LD_FILE ?= $(FAMILY_PATH)/linker/$(MCU_VARIANT_UPPER)_FLASH.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf ================================================ FILE: hw/bsp/stm32u0/linker/STM32U083xx_FLASH.ld ================================================ /** ****************************************************************************** * @file LinkerScript.ld * @author Auto-generated by STM32CubeIDE * @brief Linker script for STM32U083xx Device from STM32U0 series * 256KBytes FLASH * 40KBytes RAM * * Set heap size, stack size and stack location according * to application requirements. * * Set memory bank area and size if external memory is used ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 40K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 256K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x800; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u0/linker/stm32u083xx_flash.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/stm32u0/stm32u0xx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32u0xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32U0xx_HAL_CONF_H #define __STM32U0xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_COMP_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRS_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LCD_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_OPAMP_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED /* #define HAL_RNG_MODULE_ENABLED */ /* #define HAL_RTC_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ /* #define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 4000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI32_VALUE) #define MSI32_VALUE 32000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI32_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (3U) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32u0xx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LCD_REGISTER_CALLBACKS 0U /* LCD register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32u0xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32u0xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32u0xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32u0xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32u0xx_hal_adc.h" #include "stm32u0xx_hal_adc_ex.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32u0xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32u0xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRS_MODULE_ENABLED #include "stm32u0xx_ll_crs.h" #endif /* HAL_CRS_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32u0xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32u0xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32u0xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32u0xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32u0xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32u0xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32u0xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_LCD_MODULE_ENABLED #include "stm32u0xx_hal_lcd.h" #endif /* HAL_LCD_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32u0xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32u0xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32u0xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32u0xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32u0xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32u0xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32u0xx_ll_system.h" #include "stm32u0xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32u0xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32u0xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32u0xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32u0xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32u0xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_LCD_MODULE_ENABLED #include "stm32u0xx_hal_lcd.h" #endif /* HAL_LCD_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32u0xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32U0xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32u5xx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< * Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 U575 Eval url: https://www.st.com/en/evaluation-tools/stm32u575i-ev.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif // LED GREEN #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_7 #define LED_STATE_ON 1 // // LED #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF7_USART1 #define UART_TX_PIN GPIO_PIN_9 #define UART_RX_PIN GPIO_PIN_10 #define VBUS_SENSE_EN 0 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; /* Enable Power Clock*/ __HAL_RCC_PWR_CLK_ENABLE(); /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 10; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 1; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); } static void SystemPower_Config(void) { } static inline void board_vbus_sense_init(void) { } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32u5/boards/stm32u575eval/board.mk ================================================ MCU_VARIANT = stm32u575xx CFLAGS += \ -DSTM32U575xx \ # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32u575ai ================================================ FILE: hw/bsp/stm32u5/boards/stm32u575nucleo/board.cmake ================================================ set(MCU_VARIANT stm32u575xx) set(JLINK_DEVICE stm32u575zi) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32U575xx ) endfunction() ================================================ FILE: hw/bsp/stm32u5/boards/stm32u575nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 U575 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-u575zi-q.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "stm32u5xx_ll_tim.h" // LED GREEN #define LED_PORT GPIOC #define LED_PIN GPIO_PIN_7 #define LED_STATE_ON 1 // BUTTON #define BUTTON_PORT GPIOA #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV LPUART1 #define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE #define UART_GPIO_PORT GPIOG #define UART_GPIO_AF GPIO_AF8_LPUART1 #define UART_TX_PIN GPIO_PIN_7 #define UART_RX_PIN GPIO_PIN_8 #define VBUS_SENSE_EN 0 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; /* Enable Power Clock */ __HAL_RCC_PWR_CLK_ENABLE(); /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 10; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 1; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; RCC_OscInitStruct.PLL.PLLFRACN = 0; HAL_RCC_OscConfig(&RCC_OscInitStruct); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); } static void SystemPower_Config(void) { } static inline void board_vbus_sense_init(void) { /* ADC config */ GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC; PeriphClkInit.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } __HAL_RCC_ADC12_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); ADC_HandleTypeDef hadc1; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc1.Init.Resolution = ADC_RESOLUTION_14B; hadc1.Init.GainCompensation = 0; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1.Init.LowPowerAutoWait = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH; hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; hadc1.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_68CYCLES; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } HAL_NVIC_EnableIRQ(ADC1_IRQn); /* TIM1 init for TRGO */ __HAL_RCC_TIM1_CLK_ENABLE(); TIM_HandleTypeDef htim1; TIM_ClockConfigTypeDef sClockSourceConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 159; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } LL_TIM_SetTriggerOutput(htim1.Instance, LL_TIM_TRGO_UPDATE); HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); HAL_ADC_Start_IT(&hadc1); HAL_TIM_Base_Start(&htim1); } void ADC1_IRQHandler(void) { if(LL_ADC_IsActiveFlag_EOC(ADC1) != 0) { /* Clear flag ADC group regular end of unitary conversion */ LL_ADC_ClearFlag_EOC(ADC1); /* ADC code = 4.5V * R2 / (R1 + R2) * (2^14) / 3.3V * with R1 = 330kOhm and R2 = 50kOhm */ const uint32_t threshold = 4500 * 50 / (50 + 330) * 16384 / 3300; if((ADC1->DR > threshold) && (USB_OTG_FS->GOTGCTL & USB_OTG_GOTGCTL_BVALOEN)) { USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; } else { USB_OTG_FS->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; } } if(LL_ADC_IsActiveFlag_OVR(ADC1) != 0) { /* Clear flag ADC group regular overrun */ LL_ADC_ClearFlag_OVR(ADC1); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk ================================================ MCU_VARIANT = stm32u575xx CFLAGS += \ -DSTM32U575xx \ # All source paths should be relative to the top level. LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32u575zi ================================================ FILE: hw/bsp/stm32u5/boards/stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5A5xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2512Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2023 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.cmake ================================================ set(MCU_VARIANT stm32u5a5xx) set(JLINK_DEVICE stm32u5a5zj) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32U5A5ZJTXQ_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32U5A5xx HSE_VALUE=16000000UL ) endfunction() ================================================ FILE: hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: STM32 U5a5 Nucleo url: https://www.st.com/en/evaluation-tools/nucleo-u5a5zj-q.html */ #ifndef BOARD_H_ #define BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "stm32u5xx_ll_tim.h" // LED GREEN #define LED_PORT GPIOC #define LED_PIN GPIO_PIN_7 #define LED_STATE_ON 1 // BUTTON #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 #define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV USART1 #define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE #define UART_GPIO_PORT GPIOA #define UART_GPIO_AF GPIO_AF7_USART1 #define UART_TX_PIN GPIO_PIN_9 #define UART_RX_PIN GPIO_PIN_10 #define VBUS_SENSE_EN 0 //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_EnableVddA(); /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 20; RCC_OscInitStruct.PLL.PLLP = 8; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); // USB Clock __HAL_RCC_SYSCFG_CLK_ENABLE(); RCC_PeriphCLKInitTypeDef usb_clk_init = { 0}; usb_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USBPHY; usb_clk_init.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_HSE; if (HAL_RCCEx_PeriphCLKConfig(&usb_clk_init) != HAL_OK) { Error_Handler(); } /** Set the OTG PHY reference clock selection */ HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1); // USART clock RCC_PeriphCLKInitTypeDef uart_clk_init = { 0}; uart_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USART1; uart_clk_init.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; if (HAL_RCCEx_PeriphCLKConfig(&uart_clk_init) != HAL_OK) { Error_Handler(); } } static inline void SystemPower_Config(void) { HAL_PWREx_EnableVddIO2(); /* * Switch to SMPS regulator instead of LDO */ if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN PWR */ /* USER CODE END PWR */ } static inline void board_vbus_sense_init(void) { /* ADC config */ GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC; PeriphClkInit.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } __HAL_RCC_ADC12_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); ADC_HandleTypeDef hadc1; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc1.Init.Resolution = ADC_RESOLUTION_14B; hadc1.Init.GainCompensation = 0; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1.Init.LowPowerAutoWait = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH; hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; hadc1.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_68CYCLES; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } HAL_NVIC_EnableIRQ(ADC1_2_IRQn); /* TIM1 init for TRGO */ __HAL_RCC_TIM1_CLK_ENABLE(); TIM_HandleTypeDef htim1; TIM_ClockConfigTypeDef sClockSourceConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 159; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } LL_TIM_SetTriggerOutput(htim1.Instance, LL_TIM_TRGO_UPDATE); HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); HAL_ADC_Start_IT(&hadc1); HAL_TIM_Base_Start(&htim1); } void ADC1_2_IRQHandler(void) { if(LL_ADC_IsActiveFlag_EOC(ADC1) != 0) { /* Clear flag ADC group regular end of unitary conversion */ LL_ADC_ClearFlag_EOC(ADC1); /* ADC code = 4.5V * R2 / (R1 + R2) * (2^14) / 3.3V * with R1 = 330kOhm and R2 = 50kOhm */ const uint32_t threshold = 4500 * 50 / (50 + 330) * 16384 / 3300; if((ADC1->DR > threshold) && (USB_OTG_HS->GOTGCTL & USB_OTG_GOTGCTL_BVALOEN)) { USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBVALOVAL; } else { USB_OTG_HS->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL; } } if(LL_ADC_IsActiveFlag_OVR(ADC1) != 0) { /* Clear flag ADC group regular overrun */ LL_ADC_ClearFlag_OVR(ADC1); } } #ifdef __cplusplus } #endif #endif /* BOARD_H_ */ ================================================ FILE: hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk ================================================ MCU_VARIANT = stm32u5a5xx CFLAGS += \ -DSTM32U5A5xx \ -DHSE_VALUE=16000000UL \ # All source paths should be relative to the top level. LD_FILE = ${BOARD_PATH}/STM32U5A5ZJTXQ_FLASH.ld # For flash-jlink target JLINK_DEVICE = stm32u575zi ================================================ FILE: hw/bsp/stm32u5/boards/stm32u5a5nucleo/cubemx/stm32u5a5nucleo.ioc ================================================ #MicroXplorer Configuration settings - do not modify ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_2 ADC1.IPParameters=Rank-1\#ChannelRegularConversion,master,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,MonitoredBy-1\#ChannelRegularConversion,NbrOfConversionFlag ADC1.MonitoredBy-1\#ChannelRegularConversion=__NULL ADC1.NbrOfConversionFlag=1 ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE ADC1.Rank-1\#ChannelRegularConversion=1 ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_5CYCLE ADC1.master=1 CAD.formats= CAD.pinconfig= CAD.provider= CORTEX_M33_NS.userName=CORTEX_M33 File.Version=6 GPDMA1.DIRECTION_GPDMACH0=DMA_MEMORY_TO_PERIPH GPDMA1.DIRECTION_GPDMACH3=DMA_MEMORY_TO_PERIPH GPDMA1.IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0=__NULL GPDMA1.IPHANDLE_GPDMACH3-SIMPLEREQUEST_GPDMACH3=__NULL GPDMA1.IPHANDLE_GPDMACH5-SIMPLEREQUEST_GPDMACH5=__NULL GPDMA1.IPParameters=IPHANDLE_GPDMACH5-SIMPLEREQUEST_GPDMACH5,REQUEST_GPDMACH5,IPHANDLE_GPDMACH3-SIMPLEREQUEST_GPDMACH3,REQUEST_GPDMACH3,DIRECTION_GPDMACH3,IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0,REQUEST_GPDMACH0,DIRECTION_GPDMACH0,SRCINC_GPDMACH0 GPDMA1.REQUEST_GPDMACH0=GPDMA1_REQUEST_USART1_TX GPDMA1.REQUEST_GPDMACH3=GPDMA1_REQUEST_UCPD1_TX GPDMA1.REQUEST_GPDMACH5=GPDMA1_REQUEST_UCPD1_RX GPDMA1.SRCINC_GPDMACH0=DMA_SINC_INCREMENTED GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false MMTAppReg1.MEMORYMAP.AP=RW_priv_only MMTAppReg1.MEMORYMAP.AppRegionName=RAM MMTAppReg1.MEMORYMAP.ContextName=CortexM33 MMTAppReg1.MEMORYMAP.CoreName=ARM Cortex-M33 MMTAppReg1.MEMORYMAP.DefaultDataRegion=true MMTAppReg1.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name,AP MMTAppReg1.MEMORYMAP.Name=RAM MMTAppReg1.MEMORYMAP.Size=2555904 MMTAppReg1.MEMORYMAP.StartAddress=0x20000000 MMTAppReg2.MEMORYMAP.AppRegionName=RAM Reserved Alias Region MMTAppReg2.MEMORYMAP.CoreName=ARM Cortex-M33 MMTAppReg2.MEMORYMAP.DefaultDataRegion=false MMTAppReg2.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ReservedRegion,Name MMTAppReg2.MEMORYMAP.Name=RAM Reserved Alias Region MMTAppReg2.MEMORYMAP.ReservedRegion=true MMTAppReg2.MEMORYMAP.Size=2555904 MMTAppReg2.MEMORYMAP.StartAddress=0x0A000000 MMTAppReg3.MEMORYMAP.AP=RO_priv_only MMTAppReg3.MEMORYMAP.AppRegionName=FLASH MMTAppReg3.MEMORYMAP.Cacheability=WTRA MMTAppReg3.MEMORYMAP.ContextName=CortexM33 MMTAppReg3.MEMORYMAP.CoreName=ARM Cortex-M33 MMTAppReg3.MEMORYMAP.DefaultCodeRegion=true MMTAppReg3.MEMORYMAP.DefaultDataRegion=false MMTAppReg3.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,MemType,ContextName,Name,AP,Cacheability,DefaultCodeRegion MMTAppReg3.MEMORYMAP.MemType=ROM MMTAppReg3.MEMORYMAP.Name=FLASH MMTAppReg3.MEMORYMAP.Size=4194304 MMTAppReg3.MEMORYMAP.StartAddress=0x08000000 MMTAppRegionsCount=3 MMTConfigApplied=false Mcu.CPN=STM32U5A5ZJT6Q Mcu.ContextProject=TrustZoneDisabled Mcu.Family=STM32U5 Mcu.IP0=ADC1 Mcu.IP1=CORTEX_M33_NS Mcu.IP10=UCPD1 Mcu.IP11=USART1 Mcu.IP12=USBPD Mcu.IP13=USBX Mcu.IP14=USB_OTG_HS Mcu.IP2=GPDMA1 Mcu.IP3=ICACHE Mcu.IP4=MEMORYMAP Mcu.IP5=NVIC Mcu.IP6=PWR Mcu.IP7=RCC Mcu.IP8=SYS Mcu.IP9=THREADX Mcu.IPNb=15 Mcu.Name=STM32U5A5ZJTxQ Mcu.Package=LQFP144 Mcu.Pin0=PH0-OSC_IN (PH0) Mcu.Pin1=PH1-OSC_OUT (PH1) Mcu.Pin10=VP_GPDMA1_VS_GPDMACH0 Mcu.Pin11=VP_GPDMA1_VS_GPDMACH3 Mcu.Pin12=VP_GPDMA1_VS_GPDMACH5 Mcu.Pin13=VP_ICACHE_VS_ICACHE Mcu.Pin14=VP_PWR_VS_DBSignals Mcu.Pin15=VP_PWR_VS_SECSignals Mcu.Pin16=VP_PWR_VS_LPOM Mcu.Pin17=VP_SYS_VS_tim6 Mcu.Pin18=VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault Mcu.Pin19=VP_USBPD_VS_USBPD1 Mcu.Pin2=PC1 Mcu.Pin20=VP_USBPD_VS_PD3TYPEC Mcu.Pin21=VP_USBPD_VS_usbpd_tim2 Mcu.Pin22=VP_USBPD_VS_usbpd_usb_cohabitation Mcu.Pin23=VP_USBX_Core_System Mcu.Pin24=VP_USBX_UX Device CoreStack_HS Mcu.Pin25=VP_USBX_UX Device Controller_HS Mcu.Pin26=VP_USBX_UX Device CDC ACM Class_HS Mcu.Pin27=VP_MEMORYMAP_VS_MEMORYMAP Mcu.Pin3=PB15 Mcu.Pin4=PG2 Mcu.Pin5=PA9 Mcu.Pin6=PA10 Mcu.Pin7=PA11 Mcu.Pin8=PA12 Mcu.Pin9=PA15 (JTDI) Mcu.PinsNb=28 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32U5A5ZJTxQ MxCube.Version=6.9.2 MxDb.Version=DB.6.0.92 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.ForceEnableDMAVector=true NVIC.GPDMA1_Channel0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true NVIC.GPDMA1_Channel3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true NVIC.GPDMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false NVIC.OTG_HS_IRQn=true\:7\:0\:true\:false\:true\:false\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false NVIC.SavedPendsvIrqHandlerGenerated=true NVIC.SavedSvcallIrqHandlerGenerated=true NVIC.SavedSystickIrqHandlerGenerated=true NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:false\:false\:false\:true\:false NVIC.TIM6_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true NVIC.TimeBase=TIM6_IRQn NVIC.TimeBaseIP=TIM6 NVIC.UCPD1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:false\:true NVIC.USART1_IRQn=true\:6\:0\:true\:false\:true\:false\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false PA10.GPIOParameters=GPIO_Speed,GPIO_PuPd PA10.GPIO_PuPd=GPIO_PULLUP PA10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH PA10.Mode=Asynchronous PA10.Signal=USART1_RX PA11.GPIOParameters=GPIO_Speed PA11.GPIO_Speed=GPIO_SPEED_FREQ_LOW PA11.Mode=Internal_Phy_Device PA11.Signal=USB_OTG_HS_DM PA12.GPIOParameters=GPIO_Speed PA12.GPIO_Speed=GPIO_SPEED_FREQ_LOW PA12.Mode=Internal_Phy_Device PA12.Signal=USB_OTG_HS_DP PA15\ (JTDI).Mode=Sink_AllSignals PA15\ (JTDI).Signal=UCPD1_CC1 PA9.GPIOParameters=GPIO_Speed,GPIO_PuPd PA9.GPIO_PuPd=GPIO_PULLUP PA9.GPIO_Speed=GPIO_SPEED_FREQ_HIGH PA9.Mode=Asynchronous PA9.Signal=USART1_TX PB15.Mode=Sink_AllSignals PB15.Signal=UCPD1_CC2 PC1.Mode=IN2-Single-Ended PC1.Signal=ADC1_IN2 PG2.GPIOParameters=GPIO_Label PG2.GPIO_Label=LED_RED PG2.Locked=true PG2.Signal=GPIO_Output PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT PWR.IPParameters=PowerMode PWR.PowerMode=PWR_SMPS_SUPPLY PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32U5A5ZJTxQ ProjectManager.Example=Ux_Device_CDC_ACM ProjectManager.ExampleSource=MxCubeFw ProjectManager.FirmwarePackage=STM32Cube FW_U5 V1.3.0 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true ProjectManager.LPBAM.generateCode= ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=1 ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain= ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=stm32u5a5nucleo.ioc ProjectManager.ProjectName=stm32u5a5nucleo ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=STM32CubeIDE ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_GPDMA1_Init-GPDMA1-false-HAL-true,4-MX_ICACHE_Init-ICACHE-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-false,6-MX_UCPD1_Init-UCPD1-false-LL-true,7-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-true-HAL-false,8-MX_USBPD_Init-USBPD-false-HAL-false,9-MX_USBX_Init-USBX-false-HAL-false,10-MX_ADC1_Init-ADC1-false-HAL-true,11-MX_MEMORYMAP_Init-MEMORYMAP-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true RCC.ADCFreq_Value=16000000 RCC.ADF1Freq_Value=160000000 RCC.AHBFreq_Value=160000000 RCC.APB1Freq_Value=160000000 RCC.APB1TimFreq_Value=160000000 RCC.APB2Freq_Value=160000000 RCC.APB2TimFreq_Value=160000000 RCC.APB3Freq_Value=160000000 RCC.CK48Freq_Value=48000000 RCC.CRSFreq_Value=48000000 RCC.CortexFreq_Value=160000000 RCC.DACCLockSelectionVirtual=RCC_DAC1CLKSOURCE_LSI RCC.DACFreq_Value=32000 RCC.EPOD_VALUE=16000000 RCC.FCLKCortexFreq_Value=160000000 RCC.FDCANFreq_Value=160000000 RCC.FamilyName=M RCC.HCLKFreq_Value=160000000 RCC.HSE_VALUE=16000000 RCC.HSI48_VALUE=48000000 RCC.HSI_VALUE=16000000 RCC.I2C1Freq_Value=160000000 RCC.I2C2Freq_Value=160000000 RCC.I2C3Freq_Value=160000000 RCC.I2C4Freq_Value=160000000 RCC.I2C5Freq_Value=160000000 RCC.I2C6Freq_Value=160000000 RCC.IPParameters=ADCFreq_Value,ADF1Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CK48Freq_Value,CRSFreq_Value,CortexFreq_Value,DACCLockSelectionVirtual,DACFreq_Value,EPOD_VALUE,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2C5Freq_Value,I2C6Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSIDIV_VALUE,LSI_VALUE,MCO1PinFreq_Value,MDF1Freq_Value,MSIClockRange,MSI_VALUE,OCTOSPIMFreq_Value,PLL1P,PLL2FRACN,PLL2PoutputFreq_Value,PLL2QoutputFreq_Value,PLL2RoutputFreq_Value,PLL3FRACN,PLL3PoutputFreq_Value,PLL3QoutputFreq_Value,PLL3RoutputFreq_Value,PLLFRACN,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,RNGFreq_Value,SAESFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBPHYCLockSelection,USBPHYFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOPLL2OutputFreq_Value,VCOPLL3OutputFreq_Value RCC.LPTIM2Freq_Value=160000000 RCC.LPUART1Freq_Value=160000000 RCC.LSCOPinFreq_Value=32000 RCC.LSE_VALUE=32768 RCC.LSIDIV_VALUE=32000 RCC.LSI_VALUE=32000 RCC.MCO1PinFreq_Value=160000000 RCC.MDF1Freq_Value=160000000 RCC.MSIClockRange=RCC_MSIRANGE_0 RCC.MSI_VALUE=48000000 RCC.OCTOSPIMFreq_Value=160000000 RCC.PLL1P=8 RCC.PLL2FRACN=0 RCC.PLL2PoutputFreq_Value=3096000000 RCC.PLL2QoutputFreq_Value=3096000000 RCC.PLL2RoutputFreq_Value=3096000000 RCC.PLL3FRACN=0 RCC.PLL3PoutputFreq_Value=3096000000 RCC.PLL3QoutputFreq_Value=3096000000 RCC.PLL3RoutputFreq_Value=3096000000 RCC.PLLFRACN=0 RCC.PLLN=20 RCC.PLLPoutputFreq_Value=40000000 RCC.PLLQoutputFreq_Value=160000000 RCC.PLLRCLKFreq_Value=160000000 RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.RNGFreq_Value=48000000 RCC.SAESFreq_Value=48000000 RCC.SAI1Freq_Value=3096000000 RCC.SAI2Freq_Value=3096000000 RCC.SDMMCFreq_Value=40000000 RCC.SPI1Freq_Value=160000000 RCC.SPI2Freq_Value=160000000 RCC.SPI3Freq_Value=160000000 RCC.SYSCLKFreq_VALUE=160000000 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.UART4Freq_Value=160000000 RCC.UART5Freq_Value=160000000 RCC.USART1Freq_Value=160000000 RCC.USART2Freq_Value=160000000 RCC.USART3Freq_Value=160000000 RCC.USART6Freq_Value=160000000 RCC.USBPHYCLockSelection=RCC_USBPHYCLKSOURCE_HSE RCC.USBPHYFreq_Value=16000000 RCC.VCOInput2Freq_Value=48000000 RCC.VCOInput3Freq_Value=48000000 RCC.VCOInputFreq_Value=16000000 RCC.VCOOutputFreq_Value=320000000 RCC.VCOPLL2OutputFreq_Value=6192000000 RCC.VCOPLL3OutputFreq_Value=6192000000 USART1.IPParameters=VirtualMode-Asynchronous USART1.VirtualMode-Asynchronous=VM_ASYNC USBX.BSP.number=1 USBX.Core_System=1 USBX.IPParameters=Core_System,UX_Device_CoreStack,UX_Device_Controller,UX_DEVICE_CDC_ACM,USBD_CDCACM_EPIN_ADDR,USBD_CDCACM_EPOUT_HS_MPS,USBD_CDCACM_EPIN_HS_MPS,UX_DEVICE_APP_MEM_POOL_SIZE,USBD_PRODUCT_STRING,UX_SLAVE_REQUEST_DATA_MAX_LENGTH,USBX_DEVICE_SYS_SIZE,USBD_PID,USBD_SERIAL_NUMBER,UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH,USBD_CDCACM_EPINCMD_ADDR,MAX_POWER_IN_MILLI_AMPER USBX.MAX_POWER_IN_MILLI_AMPER=0 USBX.USBD_CDCACM_EPINCMD_ADDR=2 USBX.USBD_CDCACM_EPIN_ADDR=1 USBX.USBD_CDCACM_EPIN_HS_MPS=512 USBX.USBD_CDCACM_EPOUT_HS_MPS=512 USBX.USBD_PID=22336 USBX.USBD_PRODUCT_STRING=STM32 Virtual ComPort USBX.USBD_SERIAL_NUMBER=CDC_ACM001 USBX.USBX_DEVICE_SYS_SIZE=4*1024 USBX.UX_DEVICE_APP_MEM_POOL_SIZE=8192 USBX.UX_DEVICE_CDC_ACM=1 USBX.UX_Device_Controller=1 USBX.UX_Device_CoreStack=1 USBX.UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=256 USBX.UX_SLAVE_REQUEST_DATA_MAX_LENGTH=512 USBX0.BSP.STBoard=false USBX0.BSP.api=Unknown USBX0.BSP.component= USBX0.BSP.condition= USBX0.BSP.instance=USB_OTG_HS USBX0.BSP.ip=USB_OTG_HS USBX0.BSP.mode=Device_Only USBX0.BSP.name=USBDevice USBX0.BSP.semaphore= USBX0.BSP.solution=USB_OTG_HS USB_OTG_HS.IPParameters=VirtualMode USB_OTG_HS.VirtualMode=Device_HS VP_GPDMA1_VS_GPDMACH0.Mode=SIMPLEREQUEST_GPDMACH0 VP_GPDMA1_VS_GPDMACH0.Signal=GPDMA1_VS_GPDMACH0 VP_GPDMA1_VS_GPDMACH3.Mode=SIMPLEREQUEST_GPDMACH3 VP_GPDMA1_VS_GPDMACH3.Signal=GPDMA1_VS_GPDMACH3 VP_GPDMA1_VS_GPDMACH5.Mode=SIMPLEREQUEST_GPDMACH5 VP_GPDMA1_VS_GPDMACH5.Signal=GPDMA1_VS_GPDMACH5 VP_ICACHE_VS_ICACHE.Mode=DirectMappedCache VP_ICACHE_VS_ICACHE.Signal=ICACHE_VS_ICACHE VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP VP_PWR_VS_DBSignals.Mode=DisableDeadBatterySignals VP_PWR_VS_DBSignals.Signal=PWR_VS_DBSignals VP_PWR_VS_LPOM.Mode=PowerOptimisation VP_PWR_VS_LPOM.Signal=PWR_VS_LPOM VP_PWR_VS_SECSignals.Mode=Security/Privilege VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals VP_SYS_VS_tim6.Mode=TIM6 VP_SYS_VS_tim6.Signal=SYS_VS_tim6 VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Mode=Core_Default VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Signal=THREADX_VS_RTOSJjThreadXJjCoreJjDefault VP_USBPD_VS_PD3TYPEC.Mode=PD3_TypeC VP_USBPD_VS_PD3TYPEC.Signal=USBPD_VS_PD3TYPEC VP_USBPD_VS_USBPD1.Mode=USBPD_P0 VP_USBPD_VS_USBPD1.Signal=USBPD_VS_USBPD1 VP_USBPD_VS_usbpd_tim2.Mode=TIM2 VP_USBPD_VS_usbpd_tim2.Signal=USBPD_VS_usbpd_tim2 VP_USBPD_VS_usbpd_usb_cohabitation.Mode=Enable USB Support VP_USBPD_VS_usbpd_usb_cohabitation.Signal=USBPD_VS_usbpd_usb_cohabitation VP_USBX_Core_System.Mode=Core_System VP_USBX_Core_System.Signal=USBX_Core_System VP_USBX_UX\ Device\ CDC\ ACM\ Class_HS.Mode=UX_Device_class_CDC_ACM_HS VP_USBX_UX\ Device\ CDC\ ACM\ Class_HS.Signal=USBX_UX Device CDC ACM Class_HS VP_USBX_UX\ Device\ Controller_HS.Mode=UX_Device_Controller_HS VP_USBX_UX\ Device\ Controller_HS.Signal=USBX_UX Device Controller_HS VP_USBX_UX\ Device\ CoreStack_HS.Mode=UX_Device_CoreStack_HS VP_USBX_UX\ Device\ CoreStack_HS.Signal=USBX_UX Device CoreStack_HS board=NUCLEO-U5A5ZJ-Q boardIOC=true ================================================ FILE: hw/bsp/stm32u5/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Hongtai Liu * Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ // Suppress warning caused by mcu driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wundef" #endif #include "stm32u5xx_hal.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "bsp/board_api.h" TU_ATTR_UNUSED static void Error_Handler(void) { } #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ #ifdef USB_DRD_FS void USB_IRQHandler(void) { tusb_int_handler(0, true); } #endif #ifdef USB_OTG_FS void OTG_FS_IRQHandler(void) { tusb_int_handler(0, true); } #endif #ifdef USB_OTG_HS void OTG_HS_IRQHandler(void) { tusb_int_handler(0, true); } #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ UART_HandleTypeDef UartHandle; void board_init(void) { // Init clock, implemented in board.h SystemClock_Config(); SystemPower_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); #ifdef GPIOF __HAL_RCC_GPIOF_CLK_ENABLE(); #endif __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); UART_CLK_EN(); /* Enable Instruction cache */ HAL_ICACHE_Enable(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; #endif GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); // IOSV bit MUST be set to access GPIO port G[2:15] */ HAL_PWREx_EnableVddIO2(); // Uart GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle.Instance = UART_DEV; UartHandle.Init.BaudRate = CFG_BOARD_UART_BAUDRATE; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&UartHandle); /* Configure USB GPIOs */ /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure ID pin */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #ifdef USB_DRD_FS // STM32U535/STM32U545 /* Enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); /* USB clock enable */ __HAL_RCC_USB_FS_CLK_ENABLE(); #endif #ifdef USB_OTG_FS #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif #if defined(OTG_FS_VBUS_SENSE) && OTG_FS_VBUS_SENSE // Configure VBUS Pin OTG_FS_VBUS_SENSE GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif // vbus sense #if CFG_TUD_ENABLED tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif /* Enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); /* USB clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); #endif #ifdef USB_OTG_HS // STM59x/Ax/Fx/Gx only have 1 USB HS port #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif /* USB clock enable */ __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USBPHYC_CLK_ENABLE(); /* Enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); HAL_PWREx_EnableUSBHSTranceiverSupply(); /*Configuring the SYSCFG registers OTG_HS PHY*/ HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); #if CFG_TUD_ENABLED tud_configure_dwc2_t cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; cfg.vbus_sensing = VBUS_SENSE_EN; tud_configure(0, TUD_CFGID_DWC2, &cfg); #endif #endif // USB_OTG_FS /* Non-standard VBus sense settings */ board_vbus_sense_init(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; volatile uint32_t *stm32_uuid = (volatile uint32_t *) UID_BASE; uint32_t *id32 = (uint32_t *) (uintptr_t) id; uint8_t const len = 12; id32[0] = stm32_uuid[0]; id32[1] = stm32_uuid[1]; id32[2] = stm32_uuid[2]; return len; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { asm("bkpt 1"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. void _init(void) { } ================================================ FILE: hw/bsp/stm32u5/family.cmake ================================================ include_guard() set(ST_FAMILY u5) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32U5 CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ string(REPLACE "stm32u" "STM32U" MCU_VARIANT_UPPER ${MCU_VARIANT}) set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_icache.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_adc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_adc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_tim.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32U5) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-self-assign") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32u5/family.mk ================================================ ST_FAMILY = u5 ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32U5 # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ -flto \ -Wno-error=cast-align \ -Wno-error=undef \ -Wno-error=unused-parameter \ -Wno-error=type-limits \ -Wno-self-assign \ ifeq ($(TOOLCHAIN),gcc) CFLAGS_GCC += -Wno-error=maybe-uninitialized endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ --specs=nosys.specs --specs=nano.specs SRC_C += \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_adc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_adc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_tim.c ifneq ($(filter stm32u545xx stm32u535xx,$(MCU_VARIANT)),) SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c else SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c endif INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc \ $(TOP)/$(BOARD_PATH) # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U535xE Device from STM32U5 series ** 512Kbytes FLASH ** 272Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2022 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U545xE Device from STM32U5 series ** 512Kbytes FLASH ** 272Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** ** Copyright (c) 2022 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for STM32U575xx Device from STM32U5 series ** 2048Kbytes ROM ** 784Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2021 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "ROM" Rom type memory */ .isr_vector : { . = ALIGN(8); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(8); } >ROM /* The program code and other data into "ROM" Rom type memory */ .text : { . = ALIGN(8); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(8); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "ROM" Rom type memory */ .rodata : { . = ALIGN(8); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(8); } >ROM .ARM.extab : { . = ALIGN(8); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(8); } >ROM .ARM : { . = ALIGN(8); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(8); } >ROM .preinit_array : { . = ALIGN(8); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(8); } >ROM .init_array : { . = ALIGN(8); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(8); } >ROM .fini_array : { . = ALIGN(8); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(8); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(8); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(8); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(8); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(8); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : Auto-generated by STM32CubeIDE ** ** Abstract : Linker script for STM32U585xx Device from STM32U5 series ** 2048Kbytes ROM ** 784Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2021 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "ROM" Rom type memory */ .isr_vector : { . = ALIGN(8); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(8); } >ROM /* The program code and other data into "ROM" Rom type memory */ .text : { . = ALIGN(8); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(8); _etext = .; /* define a global symbols at end of code */ } >ROM /* Constant data into "ROM" Rom type memory */ .rodata : { . = ALIGN(8); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(8); } >ROM .ARM.extab : { . = ALIGN(8); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(8); } >ROM .ARM : { . = ALIGN(8); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(8); } >ROM .preinit_array : { . = ALIGN(8); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(8); } >ROM .init_array : { . = ALIGN(8); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(8); } >ROM .fini_array : { . = ALIGN(8); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(8); } >ROM /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(8); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(8); _edata = .; /* define a global symbol at data end */ } >RAM AT> ROM /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(8); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(8); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U595xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2021 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U599xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2021 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5A9xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2021 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5F7xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2023 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5F9xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2023 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5G7xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2023 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32U5G9xJ Device from STM32U5 series ** 4096Kbytes FLASH ** 2528Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is without any warranty ** of any kind. ** ***************************************************************************** ** @attention ** **

© Copyright (c) 2023 STMicroelectronics. ** All rights reserved.

** ** This software component is licensed by ST under BSD 3-Clause license, ** the "License"; You may not use this file except in compliance with the ** License. You may obtain a copy of the License at: ** opensource.org/licenses/BSD-3-Clause ** ***************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { KEEP(*(.isr_vector)) /* Startup code */ } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32u5/stm32u5xx_hal_conf.h ================================================ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32u5xx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32U5xx_HAL_CONF_H #define STM32U5xx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED #define HAL_ADC_MODULE_ENABLED /*#define HAL_MDF_MODULE_ENABLED */ /*#define HAL_COMP_MODULE_ENABLED */ /*#define HAL_CORDIC_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ /*#define HAL_DMA2D_MODULE_ENABLED */ /*#define HAL_DSI_MODULE_ENABLED */ /*#define HAL_FDCAN_MODULE_ENABLED */ /*#define HAL_FMAC_MODULE_ENABLED */ /*#define HAL_GFXMMU_MODULE_ENABLED */ /*#define HAL_GPU2D_MODULE_ENABLED */ /*#define HAL_GTZC_MODULE_ENABLED */ /*#define HAL_HASH_MODULE_ENABLED */ /*#define HAL_HRTIM_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ /*#define HAL_I2C_MODULE_ENABLED */ /*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */ /*#define HAL_LTDC_MODULE_ENABLED */ /*#define HAL_NAND_MODULE_ENABLED */ /*#define HAL_NOR_MODULE_ENABLED */ /*#define HAL_OPAMP_MODULE_ENABLED */ #define HAL_OSPI_MODULE_ENABLED /*#define HAL_OTFDEC_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED /*#define HAL_PKA_MODULE_ENABLED */ /*#define HAL_QSPI_MODULE_ENABLED */ /*#define HAL_RNG_MODULE_ENABLED */ /*#define HAL_RTC_MODULE_ENABLED */ /*#define HAL_SAI_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_SD_MODULE_ENABLED */ /*#define HAL_MMC_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_SRAM_MODULE_ENABLED */ #define HAL_TIM_MODULE_ENABLED /*#define HAL_TSC_MODULE_ENABLED */ /*#define HAL_RAMCFG_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ /*#define HAL_DCMI_MODULE_ENABLED */ /*#define HAL_PSSI_MODULE_ENABLED */ #define HAL_ICACHE_MODULE_ENABLED /*#define HAL_DCACHE_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED /*#define HAL_HCD_MODULE_ENABLED */ /*#define HAL_XSPI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 16000000UL /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. * This internal oscillator is mainly dedicated to provide a high precision clock to * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency * which is subject to manufacturing process variations. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. The real value my vary depending on manufacturing process variations.*/ #endif /* HSI48_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768UL /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /** * @brief External clock source for SAI1 peripheral * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source * frequency. */ #if !defined (EXTERNAL_SAI1_CLOCK_VALUE) #define EXTERNAL_SAI1_CLOCK_VALUE 48000UL /*!< Value of the SAI1 External clock source in Hz*/ #endif /* EXTERNAL_SAI1_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300UL /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U /*!< Enable prefetch */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32u5xx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ #define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ #define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U /* GFXMMU register callback disabled */ #define USE_HAL_GPU2D_REGISTER_CALLBACKS 0U /* GPU2D register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ #define USE_HAL_MDF_REGISTER_CALLBACKS 0U /* MDF register callback disabled */ #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ #define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* MDIO register callback disabled */ #define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ #define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* ################## SDMMC peripheral configuration ######################### */ #define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */ /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32u5xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32u5xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_ICACHE_MODULE_ENABLED #include "stm32u5xx_hal_icache.h" #endif /* HAL_ICACHE_MODULE_ENABLED */ #ifdef HAL_DCACHE_MODULE_ENABLED #include "stm32u5xx_hal_dcache.h" #endif /* HAL_DCACHE_MODULE_ENABLED */ #ifdef HAL_GTZC_MODULE_ENABLED #include "stm32u5xx_hal_gtzc.h" #endif /* HAL_GTZC_MODULE_ENABLED */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32u5xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32u5xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ #ifdef HAL_DSI_MODULE_ENABLED #include "stm32u5xx_hal_dsi.h" #endif /* HAL_DSI_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32u5xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_PKA_MODULE_ENABLED #include "stm32u5xx_hal_pka.h" #endif /* HAL_PKA_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32u5xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32u5xx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32u5xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32u5xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED #include "stm32u5xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32u5xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32u5xx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32u5xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED #include "stm32u5xx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED #include "stm32u5xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED #include "stm32u5xx_hal_nand.h" #endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32u5xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32u5xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32u5xx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32u5xx_hal_ltdc.h" #endif /* HAL_LTDC_MODULE_ENABLED */ #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32u5xx_hal_opamp.h" #endif /* HAL_OPAMP_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32u5xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_OSPI_MODULE_ENABLED #include "stm32u5xx_hal_ospi.h" #endif /* HAL_OSPI_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32u5xx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32u5xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32u5xx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED #include "stm32u5xx_hal_sd.h" #endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32u5xx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32u5xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32u5xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32u5xx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32u5xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32u5xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32u5xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32u5xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32u5xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32u5xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32u5xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_CORDIC_MODULE_ENABLED #include "stm32u5xx_hal_cordic.h" #endif /* HAL_CORDIC_MODULE_ENABLED */ #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32u5xx_hal_dcmi.h" #endif /* HAL_DCMI_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32u5xx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32u5xx_hal_fdcan.h" #endif /* HAL_FDCAN_MODULE_ENABLED */ #ifdef HAL_FMAC_MODULE_ENABLED #include "stm32u5xx_hal_fmac.h" #endif /* HAL_FMAC_MODULE_ENABLED */ #ifdef HAL_GFXMMU_MODULE_ENABLED #include "stm32u5xx_hal_gfxmmu.h" #endif /* HAL_GFXMMU_MODULE_ENABLED */ #ifdef HAL_GPU2D_MODULE_ENABLED #include "stm32u5xx_hal_gpu2d.h" #endif /* HAL_GPU2D_MODULE_ENABLED */ #ifdef HAL_OTFDEC_MODULE_ENABLED #include "stm32u5xx_hal_otfdec.h" #endif /* HAL_OTFDEC_MODULE_ENABLED */ #ifdef HAL_PSSI_MODULE_ENABLED #include "stm32u5xx_hal_pssi.h" #endif /* HAL_PSSI_MODULE_ENABLED */ #ifdef HAL_RAMCFG_MODULE_ENABLED #include "stm32u5xx_hal_ramcfg.h" #endif /* HAL_RAMCFG_MODULE_ENABLED */ #ifdef HAL_MDF_MODULE_ENABLED #include "stm32u5xx_hal_mdf.h" #endif /* HAL_MDF_MODULE_ENABLED */ #ifdef HAL_XSPI_MODULE_ENABLED #include "stm32u5xx_hal_xspi.h" #endif /* HAL_XSPI_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32U5xx_HAL_CONF_H */ ================================================ FILE: hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32wbxx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM1 AT> FLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM1 /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM1 /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED /* used by the startup to initialize .MB_MEM2 data */ _siMB_MEM2 = LOADADDR(.MB_MEM2); .MB_MEM2 : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED AT> FLASH } ================================================ FILE: hw/bsp/stm32wb/family.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: manufacturer: STMicroelectronics */ #include "stm32wbxx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_HP_IRQHandler(void) { tud_int_handler(0); } void USB_LP_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifdef UART_DEV UART_HandleTypeDef UartHandle; #endif void board_init(void) { board_clock_init(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_HP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); #if 0 // MCO configuration for System clock value verification PA8 will have SYSCLK / 2 GPIO_InitStruct.Pin = 8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF0_MCO; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_2); #endif board_led_write(false); // Button GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); #ifdef UART_DEV UART_CLK_EN(); // UART GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); UartHandle = (UART_HandleTypeDef) { .Instance = UART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); #endif // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_PWREx_EnableVddUSB(); __HAL_RCC_USB_CLK_ENABLE(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const* buf, int len) { #ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t*) (uintptr_t) buf, len, 0xffff); return len; #else (void) buf; (void) len; return 0; #endif } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { asm("bkpt 1"); } // Required by __libc_init_array in startup code if we are compiling using -nostdlib/-nostartfiles. void _init(void); void _init(void) { } ================================================ FILE: hw/bsp/stm32wb/family.cmake ================================================ include_guard() set(ST_FAMILY wb) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32WB CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}_cm4.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}_cm4.s) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT}_flash_cm4.ld) endif() set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_cm4.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_${FAMILY_MCUS}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32wb/family.mk ================================================ UF2_FAMILY_ID = 0x70d16653 ST_FAMILY = wb ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32WB CFLAGS_GCC += \ -flto \ -nostdlib -nostartfiles \ -Wno-error=cast-align -Wno-unused-parameter LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ src/portable/st/stm32_fsdev/fsdev_common.c \ $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # Startup SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT)_cm4.s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT)_cm4.s # Linker LD_FILE_GCC ?= ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT}_flash_cm4.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash_cm4.icf # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32wb/stm32wbxx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32wbxx_hal_conf.h * @author MCD Application Team * @brief HAL configuration file. ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32WBxx_HAL_CONF_H #define __STM32WBxx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED /*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_COMP_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_HSEM_MODULE_ENABLED */ /*#define HAL_IPCC_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_LCD_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */ /*#define HAL_PCD_MODULE_ENABLED */ /*#define HAL_PKA_MODULE_ENABLED */ /*#define HAL_QSPI_MODULE_ENABLED */ #define HAL_RTC_MODULE_ENABLED /*#define HAL_SAI_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ #define HAL_CORTEX_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_IWDG_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED #define HAL_SPI_MODULE_ENABLED #define HAL_I2C_MODULE_ENABLED #define HAL_RNG_MODULE_ENABLED /*#define HAL_CRYP_MODULE_ENABLED */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0u #define USE_HAL_COMP_REGISTER_CALLBACKS 0u #define USE_HAL_CRYP_REGISTER_CALLBACKS 0u #define USE_HAL_I2C_REGISTER_CALLBACKS 0u #define USE_HAL_IRDA_REGISTER_CALLBACKS 0u #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u #define USE_HAL_PCD_REGISTER_CALLBACKS 0u #define USE_HAL_PKA_REGISTER_CALLBACKS 0u #define USE_HAL_QSPI_REGISTER_CALLBACKS 0u #define USE_HAL_RNG_REGISTER_CALLBACKS 0u #define USE_HAL_RTC_REGISTER_CALLBACKS 0u #define USE_HAL_SAI_REGISTER_CALLBACKS 0u #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u #define USE_HAL_SPI_REGISTER_CALLBACKS 0u #define USE_HAL_TIM_REGISTER_CALLBACKS 0u #define USE_HAL_TSC_REGISTER_CALLBACKS 0u #define USE_HAL_UART_REGISTER_CALLBACKS 0u #define USE_HAL_USART_REGISTER_CALLBACKS 0u #define USE_HAL_WWDG_REGISTER_CALLBACKS 0u /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal Multiple Speed oscillator (MSI) default value. * This value is the default MSI range value after Reset. */ #if !defined (MSI_VALUE) #define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI1) value. */ #if !defined (LSI1_VALUE) #define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/ #endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief Internal Low Speed oscillator (LSI2) value. */ #if !defined (LSI2_VALUE) #define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/ #endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ /** * @brief Internal Multiple Speed oscillator (HSI48) default value. * This value is the default HSI48 range value after Reset. */ #if !defined (HSI48_VALUE) #define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI48_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief External clock source for SAI1 peripheral * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source * frequency. */ #if !defined (EXTERNAL_SAI1_CLOCK_VALUE) #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/ #endif /* EXTERNAL_SAI1_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1 #define INSTRUCTION_CACHE_ENABLE 1 #define DATA_CACHE_ENABLE 1 /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 0U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32wbxx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32wbxx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32wbxx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32wbxx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32wbxx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32wbxx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32wbxx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32wbxx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_HSEM_MODULE_ENABLED #include "stm32wbxx_hal_hsem.h" #endif /* HAL_HSEM_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32wbxx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_IPCC_MODULE_ENABLED #include "stm32wbxx_hal_ipcc.h" #endif /* HAL_IPCC_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32wbxx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32wbxx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LCD_MODULE_ENABLED #include "stm32wbxx_hal_lcd.h" #endif /* HAL_LCD_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32wbxx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32wbxx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PKA_MODULE_ENABLED #include "stm32wbxx_hal_pka.h" #endif /* HAL_PKA_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32wbxx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_QSPI_MODULE_ENABLED #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U #include "stm32wbxx_hal_qspi.h" #endif /* HAL_QSPI_MODULE_ENABLED */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32wbxx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32wbxx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32wbxx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32wbxx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32wbxx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32wbxx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32wbxx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32wbxx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32wbxx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32wbxx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32wbxx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32wbxx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* __STM32WBxx_HAL_CONF_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ================================================ FILE: hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "stm32wbaxx.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #if defined(__ARM_FP) && __ARM_FP >= 4 #define configENABLE_FPU 1 #else #define configENABLE_FPU 0 #endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 4 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< #include "stm32wbaxx_hal.h" #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ #ifndef USART_TIMEOUT_TICKS #define USART_TIMEOUT_TICKS 1000 #endif static UART_HandleTypeDef uart_handle; //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB_OTG_HS_IRQHandler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ static void board_gpio_configuration(void) { GPIO_InitTypeDef gpio_init = {0}; USART_GPIO_CLK_EN(); USART_CLK_EN(); // Configure USART TX pin gpio_init.Pin = USART_TX_PIN; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_NOPULL; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; gpio_init.Alternate = USART_GPIO_AF; HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init); // Configure USART RX pin gpio_init.Pin = USART_RX_PIN; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; gpio_init.Alternate = USART_GPIO_AF; HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init); // Configure the LED LED_CLK_EN(); gpio_init.Pin = LED_PIN; gpio_init.Mode = GPIO_MODE_OUTPUT_PP; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_LOW; gpio_init.Alternate = 0; HAL_GPIO_Init(LED_PORT, &gpio_init); // Default LED state is off board_led_write(false); // Configure the button BUTTON_CLK_EN(); gpio_init.Pin = BUTTON_PIN; gpio_init.Mode = GPIO_MODE_INPUT; gpio_init.Pull = GPIO_PULLUP; gpio_init.Speed = GPIO_SPEED_FREQ_LOW; gpio_init.Alternate = 0; HAL_GPIO_Init(BUTTON_PORT, &gpio_init); // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. gpio_init.Pin = (GPIO_PIN_7 | GPIO_PIN_6); gpio_init.Mode = GPIO_MODE_INPUT; gpio_init.Pull = GPIO_NOPULL; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOD, &gpio_init); } static void board_uart_configuration(void) { uart_handle = ( UART_HandleTypeDef){ .Instance = USART_DEV, .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, .Init.WordLength = UART_WORDLENGTH_8B, .Init.StopBits = UART_STOPBITS_1, .Init.Parity = UART_PARITY_NONE, .Init.HwFlowCtl = UART_HWCONTROL_NONE, .Init.Mode = UART_MODE_TX_RX, .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&uart_handle); } void board_init(void) { board_system_clock_config(); board_gpio_configuration(); board_uart_configuration(); #ifdef USB_OTG_HS // STM32WBA65/64/62 only has 1 USB HS port #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // USB clock enable __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_PHY_CLK_ENABLE(); // See the reference manual section 11.4.7 for the USB OTG powering sequence // Remove the VDDUSB power isolation PWR->SVMCR |= PWR_SVMCR_USV; // Enable VDD11USB supply by clearing VDD11USBDIS to 0 PWR->VOSR &= ~PWR_VOSR_VDD11USBDIS; // Enable USB OTG internal power by setting USBPWREN to 1 PWR->VOSR |= PWR_VOSR_USBPWREN; // Wait for VDD11USB supply to be ready in VDD11USBRDY = 1 while ((PWR->VOSR & PWR_VOSR_VDD11USBRDY) == 0) {} // Enable USB OTG booster by setting USBBOOSTEN to 1 PWR->VOSR |= PWR_VOSR_USBBOOSTEN; // Wait for USB OTG booster to be ready in USBBOOSTRDY = 1 while ((PWR->VOSR & PWR_VOSR_USBBOOSTRDY) == 0) {} // Enable USB power on Pwrctrl CR2 register PWR->SVMCR |= PWR_SVMCR_USV; // Set the reference clock selection (must match the clock source) SYSCFG->OTGHSPHYCR &= ~SYSCFG_OTGHSPHYCR_CLKSEL; SYSCFG->OTGHSPHYCR |= SYSCFG_OTGHSPHYCR_CLKSEL_0 | SYSCFG_OTGHSPHYCR_CLKSEL_1 | SYSCFG_OTGHSPHYCR_CLKSEL_3;// 32MHz clock // Configuring the SYSCFG registers OTG_HS PHY SYSCFG->OTGHSPHYCR |= SYSCFG_OTGHSPHYCR_EN; #endif // USB_OTG_HS } void board_led_write(bool state) { GPIO_PinState pin_state = (GPIO_PinState)(state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } uint32_t board_button_read(void) { return HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == BUTTON_STATE_ACTIVE; } int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; return 0; } int board_uart_write(void const *buf, int len) { (void) HAL_UART_Transmit(&uart_handle, (const uint8_t *) buf, len, USART_TIMEOUT_TICKS); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif void HardFault_Handler(void) { asm( "bkpt 1" ); } // Required by __libc_init_array in startup code if we are compiling using -nostdlib/-nostartfiles. void _init(void); void _init(void) {} ================================================ FILE: hw/bsp/stm32wba/family.cmake ================================================ include_guard() set(ST_FAMILY wba) set(ST_PREFIX stm32${ST_FAMILY}xx) set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis-device-${ST_FAMILY}) set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32WBA CACHE INTERNAL "") # ---------------------- # Port & Speed Selection # ---------------------- set(RHPORT_DEVICE 0) set(RHPORT_HOST 0) # WBA65/64/62 has built-in HS PHY set(RHPORT_DEVICE_SPEED OPT_MODE_HIGH_SPEED) set(RHPORT_HOST_SPEED OPT_MODE_HIGH_SPEED) #------------------------------------ # Startup & Linker script #------------------------------------ # STM32WBA HAL uses uppercase MCU_VARIANT (excluding the x's) for linking and lowercase MCU_VARIANT for startup. string(TOUPPER "${MCU_VARIANT}" UPPERCASE_MCU_VARIANT) string(REGEX REPLACE "X" "x" UPPERCASE_MCU_VARIANT "${UPPERCASE_MCU_VARIANT}") set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${UPPERCASE_MCU_VARIANT}_FLASH_ns.ld) set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_ns.icf) #------------------------------------ # BOARD_TARGET #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_icache.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pcd.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pcd_ex.c ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_ll_usb.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMSIS_5}/CMSIS/Core/Include ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_STM32WBA) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) family_flash_stlink(${TARGET}) family_flash_jlink(${TARGET}) endfunction() ================================================ FILE: hw/bsp/stm32wba/family.mk ================================================ UF2_FAMILY_ID = 0x70d16657 ST_FAMILY = wba ST_PREFIX = stm32${ST_FAMILY}xx ST_CMSIS = hw/mcu/st/cmsis-device-$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32WBA CFLAGS_GCC += \ -flto \ -Wno-error=cast-align -Wno-unused-parameter LDFLAGS_GCC += \ -nostdlib -nostartfiles \ -specs=nosys.specs -specs=nano.specs -Wl,--gc-sections SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ src/portable/synopsys/dwc2/hcd_dwc2.c \ src/portable/synopsys/dwc2/dwc2_common.c \ $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_icache.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd_ex.c \ $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_ll_usb.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(BOARD_PATH)/include \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ $(TOP)/$(ST_HAL_DRIVER)/Inc # STM32WBA HAL uses uppercase MCU_VARIANT (excluding the x's) for linking and lowercase MCU_VARIANT for startup. UPPERCASE_MCU_VARIANT = $(subst XX,xx,$(call to_upper,$(MCU_VARIANT))) # Startup - Manually specify lowercase version for startup file SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_GCC ?= ${FAMILY_PATH}/linker/${UPPERCASE_MCU_VARIANT}_FLASH_ns.ld LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash_ns.icf # flash target using on-board stlink flash: flash-stlink ================================================ FILE: hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld ================================================ /* ****************************************************************************** ** ** File : LinkerScript.ld ** ** Author : STM32CubeIDE ** ** Abstract : Linker script for STM32WBA65xx Device from STM32WBA series ** 2048Kbytes FLASH ** 512Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used ** ** Target : STMicroelectronics STM32 ** ** Distribution: The file is distributed as is, without any warranty ** of any kind. ** ****************************************************************************** ** @attention ** ** Copyright (c) 2024 STMicroelectronics. ** All rights reserved. ** ** This software is licensed under terms that can be found in the LICENSE file ** in the root directory of this software component. ** If no LICENSE file comes with this software, it is provided AS-IS. ** ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20038000, LENGTH = 224K RAM2 (xrw) : ORIGIN = 0x20078000, LENGTH = 32K FLASH (rx) : ORIGIN = 0x08100000, LENGTH = 1024K } /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ /* Sections */ SECTIONS { /* The startup code into "FLASH" Rom type memory */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >FLASH .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >FLASH .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >FLASH .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >FLASH .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } ================================================ FILE: hw/bsp/stm32wba/stm32wbaxx_hal_conf.h ================================================ /** ****************************************************************************** * @file stm32wbaxx_hal_conf_template.h * @author MCD Application Team * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32wbaxx_hal_conf.h. ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef STM32WBAxx_HAL_CONF_H #define STM32WBAxx_HAL_CONF_H #ifdef __cplusplus extern "C" { #endif /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* ########################## Module Selection ############################## */ /** * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED // #define HAL_ADC_MODULE_ENABLED // #define HAL_COMP_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED // #define HAL_CRC_MODULE_ENABLED // #define HAL_CRYP_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED #define HAL_GTZC_MODULE_ENABLED #define HAL_HASH_MODULE_ENABLED #define HAL_HCD_MODULE_ENABLED #define HAL_HSEM_MODULE_ENABLED // #define HAL_I2C_MODULE_ENABLED #define HAL_ICACHE_MODULE_ENABLED // #define HAL_IRDA_MODULE_ENABLED // #define HAL_IWDG_MODULE_ENABLED // #define HAL_LPTIM_MODULE_ENABLED #define HAL_PCD_MODULE_ENABLED // #define HAL_PKA_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_RAMCFG_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED // #define HAL_RNG_MODULE_ENABLED // #define HAL_RTC_MODULE_ENABLED // #define HAL_SAI_MODULE_ENABLED // #define HAL_SMARTCARD_MODULE_ENABLED // #define HAL_SMBUS_MODULE_ENABLED #define HAL_SPI_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED // #define HAL_TSC_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED #define HAL_USART_MODULE_ENABLED // #define HAL_WWDG_MODULE_ENABLED // #define HAL_XSPI_MODULE_ENABLED /* ########################## Oscillator Values adaptation ####################*/ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) #define HSE_VALUE 32000000UL /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) #define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ #if !defined (LSI_VALUE) #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature.*/ #if defined (RCC_LSI2_SUPPORT) #if !defined (LSI2_VALUE) #define LSI2_VALUE 32000UL /*!< LSI2 Typical Value in Hz*/ #endif /* LSI2_VALUE */ #endif /** * @brief External Low Speed oscillator (LSE) value. * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) #define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief External clock source for SAI1 peripheral * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source * frequency. */ #if !defined (EXTERNAL_SAI1_CLOCK_VALUE) #define EXTERNAL_SAI1_CLOCK_VALUE 48000UL /*!< Value of the SAI1 External clock source in Hz*/ #endif /* EXTERNAL_SAI1_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section */ #define VDD_VALUE 3300UL /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY ((1UL<<__NVIC_PRIO_BITS) - 1UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U /*!< Enable prefetch */ /* ########################## Assert Selection ############################## */ /** * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ /* ################## Register callback feature configuration ############### */ /** * @brief Set below the peripheral configuration to "1U" to add the support * of HAL callback registration/unregistration feature for the HAL * driver(s). This allows user application to provide specific callback * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting * the default weak callback functions (see each stm32wbaxx_hal_ppp.h file * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef * for each PPP peripheral). */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ #define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ #define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ #define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ #define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ /* ################## SPI peripheral configuration ########################## */ /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver * Activated: CRC code is present inside driver * Deactivated: CRC code cleaned from driver */ #define USE_SPI_CRC 1U /* ################## CRYP peripheral configuration ########################## */ #define USE_HAL_CRYP_SUSPEND_RESUME 0U /* ################## HASH peripheral configuration ########################## */ #define USE_HAL_HASH_SUSPEND_RESUME 0U /* Includes ------------------------------------------------------------------*/ /** * @brief Include module's header file */ #ifdef HAL_DMA_MODULE_ENABLED #include "stm32wbaxx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_RCC_MODULE_ENABLED #include "stm32wbaxx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED #include "stm32wbaxx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_COMP_MODULE_ENABLED #include "stm32wbaxx_hal_comp.h" #endif /* HAL_COMP_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32wbaxx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED #include "stm32wbaxx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32wbaxx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32wbaxx_hal_exti.h" #endif /* HAL_EXTI_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32wbaxx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32wbaxx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ #ifdef HAL_GTZC_MODULE_ENABLED #include "stm32wbaxx_hal_gtzc.h" #endif /* HAL_GTZC_MODULE_ENABLED */ #ifdef HAL_HASH_MODULE_ENABLED #include "stm32wbaxx_hal_hash.h" #endif /* HAL_HASH_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED #include "stm32wbaxx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_HSEM_MODULE_ENABLED #include "stm32wbaxx_hal_hsem.h" #endif /* HAL_HSEM_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED #include "stm32wbaxx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_ICACHE_MODULE_ENABLED #include "stm32wbaxx_hal_icache.h" #endif /* HAL_ICACHE_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32wbaxx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32wbaxx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32wbaxx_hal_lptim.h" #endif /* HAL_LPTIM_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED #include "stm32wbaxx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_PKA_MODULE_ENABLED #include "stm32wbaxx_hal_pka.h" #endif /* HAL_PKA_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED #include "stm32wbaxx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RAMCFG_MODULE_ENABLED #include "stm32wbaxx_hal_ramcfg.h" #endif /* HAL_RAMCFG_MODULE_ENABLED */ #ifdef HAL_RNG_MODULE_ENABLED #include "stm32wbaxx_hal_rng.h" #endif /* HAL_RNG_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED #include "stm32wbaxx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_SAI_MODULE_ENABLED #include "stm32wbaxx_hal_sai.h" #endif /* HAL_SAI_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32wbaxx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32wbaxx_hal_smbus.h" #endif /* HAL_SMBUS_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED #include "stm32wbaxx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED #include "stm32wbaxx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_TSC_MODULE_ENABLED #include "stm32wbaxx_hal_tsc.h" #endif /* HAL_TSC_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED #include "stm32wbaxx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED #include "stm32wbaxx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32wbaxx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_XSPI_MODULE_ENABLED #include "stm32wbaxx_hal_xspi.h" #endif /* HAL_XSPI_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function * which reports the name of the source file and the source * line number of the call that failed. * If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else #define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ #ifdef __cplusplus } #endif #endif /* STM32WBAxx_HAL_CONF_H */ ================================================ FILE: hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #ifdef TM4C123GH6PM #include "TM4C123.h" #elif TM4C1294NCPDT #include "TM4C129.h" #else #error "Unknown TM4C device" #endif #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 3 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld ================================================ ENTRY(Reset_Handler) _estack = 0x20008000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ MEMORY { FLASH(rx) : ORIGIN = 0x00000000, LENGTH = 256K SRAM(rwx) : ORIGIN = 0x20000000, LENGTH = 32K } SECTIONS { .text : { . = ALIGN(4) ; KEEP(*(.vectors)) *(.text) *(.text.*) *(.init) *(.fini) *(.rodata) *(.rodata.*) *(.ARM.exidx*) . = ALIGN(4) ; __end_text = . ; } >FLASH .data : AT(ADDR(.text) + SIZEOF(.text)) { . = ALIGN(4); __start_data = . ; __la_data = LOADADDR(.data); *(.data) *(.data.*) . = ALIGN(4); __end_data = . ; } >SRAM .bss : { . = ALIGN(4) ; __start_bss = . ; __bss_start__ = __start_bss; *(.bss) *(.bss.*) *(.COMMON) __end_bss = . ; . = ALIGN(4); }>SRAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >SRAM } ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf ================================================ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; define symbol __ICFEDIT_region_ROM_end__ = 0x000FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2003FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x8000; define symbol __ICFEDIT_size_heap__ = 0x10000; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake ================================================ set(MCU_SUB_VARIANT 129) set(JLINK_DEVICE TM4C1294NCPDT) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/tm4c1294nc.ld) set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/TM4C1294NC.icf) set(OPENOCD_OPTION "-f board/ti_ek-tm4c1294xl.cfg") function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC TM4C1294NCPDT ) endfunction() ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /* metadata: name: TM4C1294 LaunchPad url: https://www.ti.com/tool/EK-TM4C1294XL */ #ifndef _BOARD_H_ #define _BOARD_H_ #ifdef __cplusplus extern "C" { #endif #include "TM4C129.h" #define BOARD_UART UART0 #define BOARD_UART_PORT GPIOA #define BTN_PORT_CLK 8 #define BOARD_BTN_PORT GPIOJ #define BOARD_BTN 0 #define BOARD_BTN_Msk (1u<<0) #define BUTTON_STATE_ACTIVE 0 #define LED_PORT_CLK 12 #define LED_PORT GPION #define LED_PIN_1 1 #define LED_PIN_2 0 #define LED_STATE_ON 1 #define BOARD_LED_PIN LED_PIN_2 #define GPIOA GPIOA_AHB #define GPIOB GPIOB_AHB #define GPIOC GPIOC_AHB #define GPIOD GPIOD_AHB #define GPIOE GPIOE_AHB #define GPIOF GPIOF_AHB #define GPIOG GPIOG_AHB #define GPIOH GPIOH_AHB #define GPIOI GPIOI_AHB #define GPIOJ GPIOJ_AHB #define GPIOA_Type GPIOA_AHB_Type #ifdef __cplusplus } #endif #endif ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk ================================================ MCU_SUB_VARIANT = 129 CFLAGS += -DTM4C1294NCPDT LD_FILE_GCC = $(BOARD_PATH)/tm4c1294nc.ld LD_FILE_IAR = $(BOARD_PATH)/TM4C1294NC.icf # For flash-jlink target JLINK_DEVICE = TM4C1294NCPDT # flash using openocd OPENOCD_OPTION = -f board/ti_ek-tm4c1294xl.cfg UNIFLASH_OPTION = -c ${TOP}/${BOARD_PATH}/${BOARD}.ccxml -r 1 flash: flash-openocd ================================================ FILE: hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld ================================================ ENTRY(Reset_Handler) _estack = 0x20008000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0; /* required amount of heap */ _Min_Stack_Size = 0x1000; /* required amount of stack */ MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 } SECTIONS { .text : { . = ALIGN(4) ; _text = . ; KEEP(*(.isr_vector)) *(.text) *(.text.*) *(.init) *(.fini) *(.rodata) *(.rodata.*) *(.ARM.exidx*) _etext = . ; . = ALIGN(4) ; } >FLASH .data : AT(ADDR(.text) + SIZEOF(.text)) { _data = .; . = ALIGN(4); _ldata = LOADADDR (.data); *(.data) *(.data.*) _edata = .; . = ALIGN(4); } >SRAM .bss : { . = ALIGN(4) ; _bss = .; *(.bss) *(.bss.*) *(.COMMON) _ebss = .; . = ALIGN(4); }>SRAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >SRAM } ================================================ FILE: hw/bsp/tm4c/family.c ================================================ /* metadata: manufacturer: Texas Instruments */ #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USB0_Handler(void) { #if CFG_TUH_ENABLED tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ static void board_uart_init(void) { SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA while (!(SYSCTL->PRGPIO & (1 << 0))) {} // Wait for the GPIOA clock to stabilize while (!(SYSCTL->PRUART & (1 << 0))) {} // Wait for the UART0 clock to stabilize GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation // - BRDI = SystemCoreClock / (16* baud) // - BRDF = int(fraction*64 + 0.5) UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit UART0->CC = 0x0; // Configure the UART clock source as system clock UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable } static void board_button_init(GPIOA_Type* port, uint8_t PinMsk) { /* Enable Port Clock */ SYSCTL->RCGCGPIO |= (1 << BTN_PORT_CLK); /* Let the clock stabilize */ while (!((SYSCTL->PRGPIO) & (1 << BTN_PORT_CLK))) {} /* Port Digital Enable */ port->DEN |= PinMsk; /* Set direction */ port->DIR &= ~PinMsk; } static void board_led_init(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { /* Enable Port Clock */ SYSCTL->RCGCGPIO |= (1 << LED_PORT_CLK); /* Let the clock stabilize */ while (!((SYSCTL->PRGPIO) & (1 << LED_PORT_CLK))) {} /* Port Digital Enable */ port->DEN |= PinMsk; /* Set direction */ port->DIR = dirmsk; } static void WriteGPIOPin(GPIOA_Type* port, uint8_t PinMsk, bool state) { if (state) { port->DATA |= PinMsk; } else { port->DATA &= ~(PinMsk); } } static uint32_t ReadGPIOPin(GPIOA_Type* port, uint8_t pinMsk) { return (port->DATA & pinMsk); } void board_init(void) { #ifdef TM4C123_H SystemCoreClockUpdate(); #endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // Explicitly disable systick to prevent its ISR from running before scheduler start SysTick->CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif #ifdef TM4C123_H /* Reset USB */ SYSCTL->SRCR2 |= (1u << 16); for (volatile uint8_t i = 0; i < 20; i++) {} SYSCTL->SRCR2 &= ~(1u << 16); /* Open the USB clock gate */ SYSCTL->RCGCUSB |= (1 << 0); /* Power-up USB PLL */ SYSCTL->RCC2 &= ~(1u << 14); /* USB IO Initialization */ SYSCTL->RCGCGPIO |= (1u << 3); /* Let the clock stabilize */ while (!(SYSCTL->PRGPIO & (1u << 3))) {} /* USB IOs to Analog Mode */ GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); GPIOD->DEN &= ~((1u << 4) | (1u << 5)); GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); #else // TM4C129 /* Reset USB */ SYSCTL->SRUSB = 1; for (volatile uint8_t i = 0; i < 20; i++) {} SYSCTL->SRUSB = 0; /* Open the USB clock gate */ SYSCTL->RCGCUSB = 1; /* Let the clock stabilize */ while(!(SYSCTL->PRUSB & 1)) {} /* USB IO Initialization */ SYSCTL->RCGCGPIO |= (1u << 10); /* Let the clock stabilize */ while (!(SYSCTL->PRGPIO & (1u << 10))) {} /* USB IOs to Analog Mode */ GPIOL->AFSEL &= ~((1u << 6) | (1u << 7)); GPIOL->DEN &= ~((1u << 6) | (1u << 7)); GPIOL->AMSEL |= ((1u << 6) | (1u << 7)); /* USB Clock Configuration */ USB0->CC = 0x207; #endif uint8_t leds = 1 << BOARD_LED_PIN; uint8_t dirmsk = 1 << BOARD_LED_PIN; /* Configure GPIO for board button */ board_button_init(BOARD_BTN_PORT, BOARD_BTN_Msk); /* Configure GPIO for board LED */ board_led_init(LED_PORT, leds, dirmsk); /* Initialize board UART */ board_uart_init(); TU_LOG1_INT(SystemCoreClock); } void board_led_write(bool state) { WriteGPIOPin(LED_PORT, (1 << BOARD_LED_PIN), state); } uint32_t board_button_read(void) { uint32_t gpio_value = ReadGPIOPin(BOARD_BTN_PORT, BOARD_BTN_Msk); return BUTTON_STATE_ACTIVE ? gpio_value : !gpio_value; } size_t board_get_unique_id(uint8_t id[], size_t max_len) { (void) max_len; uint8_t const len = 8; // Note: DID0, DID1 are variant ID, they aer used since TM4C123 does not have unique ID memcpy(id, (void*)(uintptr_t) &SYSCTL->DID0, len); return len; } int board_uart_write(void const* buf, int len) { uint8_t const* data = buf; for (int i = 0; i < len; i++) { while ((UART0->FR & (1 << 5)) != 0) {} // Poll until previous data was shofted out UART0->DR = data[i]; // Write UART0 DATA REGISTER } return len; } int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; } uint32_t tusb_time_millis_api(void) { return system_ticks; } #endif ================================================ FILE: hw/bsp/tm4c/family.cmake ================================================ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(MCU_VARIANT tm4c${MCU_SUB_VARIANT}) set(MCU_VARIANT_UPPER TM4C${MCU_SUB_VARIANT}) set(SDK_DIR ${TOP}/hw/mcu/ti/tm4c) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS TM4C CACHE INTERNAL "") #------------------------------------ # Startup & Linker script #------------------------------------ set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC/${MCU_VARIANT}_startup.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR/${MCU_VARIANT}_startup.c) #------------------------------------ # Board Target #------------------------------------ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Source/system_${MCU_VARIANT_UPPER}.c ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/Include ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) endfunction() #------------------------------------ # Functions #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) family_add_tinyusb(${TARGET} OPT_MCU_TM4C${MCU_SUB_VARIANT}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c ${TOP}/src/portable/mentor/musb/dcd_musb.c ${TOP}/src/portable/mentor/musb/hcd_musb.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} ) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") message(FATAL_ERROR "Clang is not supported") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) endif () # Flashing family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) family_flash_openocd(${TARGET}) family_flash_uniflash(${TARGET}) endfunction() ================================================ FILE: hw/bsp/tm4c/family.mk ================================================ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 MCU_VARIANT = tm4c${MCU_SUB_VARIANT} MCU_VARIANT_UPPER = TM4C${MCU_SUB_VARIANT} SDK_DIR = hw/mcu/ti/tm4c CFLAGS += \ -flto \ -DCFG_TUSB_MCU=OPT_MCU_TM4C${MCU_SUB_VARIANT} \ -uvectors \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(SDK_DIR)/Include \ $(TOP)/$(BOARD_PATH) SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ src/portable/mentor/musb/hcd_musb.c \ $(SDK_DIR)/Source/system_${MCU_VARIANT_UPPER}.c \ $(SDK_DIR)/Source/GCC/${MCU_VARIANT}_startup.c ================================================ FILE: hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h ================================================ /* * FreeRTOS Kernel V10.0.0 * Copyright (C) 2017 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. If you wish to use our Amazon * FreeRTOS name, please do so in a fair use way that does not cause confusion. * * 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. *----------------------------------------------------------*/ // skip if included from IAR assembler #ifndef __IASMARM__ #include "xmc_device.h" #endif /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 #define configENABLE_FPU 1 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configCPU_CLOCK_HZ SystemCoreClock #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) #define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 4 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 #define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configRECORD_STACK_HIGH_ADDRESS 1 #define configUSE_TRACE_FACILITY 1 // legacy trace #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 2 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) #define configTIMER_QUEUE_LENGTH 32 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 0 #define INCLUDE_uxTaskPriorityGet 0 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY #define INCLUDE_xResumeFromISR 0 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 0 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 0 #define INCLUDE_xTimerPendFunctionCall 0 /* FreeRTOS hooks to NVIC vectors */ #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler //--------------------------------------------------------------------+ // Interrupt nesting behavior configuration. //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header #define configPRIO_BITS 6 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB0_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif // USB Power Enable #if(UC_SERIES != XMC45) XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USB0); #endif XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USB0); XMC_SCU_POWER_EnableUsb(); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ void board_led_write(bool state) { uint32_t is_high = state ? LED_STATE_ON : (1 - LED_STATE_ON); XMC_GPIO_SetOutputLevel(LED_PIN, is_high ? XMC_GPIO_OUTPUT_LEVEL_HIGH : XMC_GPIO_OUTPUT_LEVEL_LOW); } uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == XMC_GPIO_GetInput(BUTTON_PIN); } size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t const len = tu_min8(16, max_len); memcpy(id, g_chipid, len); return len; } int board_uart_read(uint8_t* buf, int len) { #ifdef UART_DEV for(int i=0;i flash .tors : { ___ctors = . ; *(.ctors) ___ctors_end = . ; ___dtors = . ; *(.dtors) ___dtors_end = . ; . = ALIGN(4); } > ram .data : AT (ADDR (.text) + SIZEOF (.text)) { *(.data) *(.data*) *(.rodata) *(.rodata*) _edata = . ; . = ALIGN(4); } > ram .bss SIZEOF(.data) + ADDR(.data) : { _bss_start = . ; *(.bss) *(.bss*) *(COMMON) _end = . ; . = ALIGN(4); } > ram __data_load_start = LOADADDR(.data); __data_load_end = __data_load_start + SIZEOF(.data); .stab 0 (NOLOAD) : { *(.stab) } .stabstr 0 (NOLOAD) : { *(.stabstr) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* DWARF 3 */ .debug_pubtypes 0 : { *(.debug_pubtypes) } .debug_ranges 0 : { *(.debug_ranges) } /* DWARF Extension. */ .debug_macro 0 : { *(.debug_macro) } .debug_addr 0 : { *(.debug_addr) } } ================================================ FILE: hw/mcu/dialog/README.md ================================================ # Dialog DA1469x MCU **Dialog Semiconductors** provides SDKs for DA146x MCU family. Most of the files there can't be redistributed. Registers definition file `DA1469xAB.h` and some **ARM** originated headers are have licenses that allow for redistribution. Whole SDK repository can be downloaded from Dialog Semiconductor web page `https://www.dialog.com` ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/arm_license.txt ================================================ /* Copyright (c) 2009 - 2013 ARM LIMITED All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 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. - Neither the name of ARM nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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. ---------------------------------------------------------------------------*/ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/DA1469xAB.h ================================================ /* * Copyright (C) 2019 Dialog Semiconductor. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - 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. * - Neither the name of Dialog Semiconductor nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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. * * @file DA1469xAB.h * @brief CMSIS HeaderFile * @version 1.2 * @date 22. April 2019 * @note Generated by SVDConv V3.3.25 on Monday, 22.04.2019 11:06:30 * from File 'DA1469xAB.xml', */ /** @addtogroup PLA_BSP_REGISTERS * @{ */ /** @addtogroup DA1469x * @{ */ #ifndef DA1469X_H #define DA1469X_H #ifdef __cplusplus extern "C" { #endif /** @addtogroup Configuration_of_CMSIS * @{ */ /* =========================================================================================================================== */ /* ================ Interrupt Number Definition ================ */ /* =========================================================================================================================== */ /** * @brief Interrupt Number Definition */ typedef enum { /* ======================================= ARM Cortex-M33 Specific Interrupt Numbers ======================================= */ Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */ NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */ HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */ MemoryManagement_IRQn = -12, /*!< -12 Memory Management, MPU mismatch, including Access Violation and No Match */ BusFault_IRQn = -11, /*!< -11 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */ UsageFault_IRQn = -10, /*!< -10 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ SecureFault_IRQn = -9, /*!< -9 Secure Fault Handler */ SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */ DebugMonitor_IRQn = -4, /*!< -4 Debug Monitor */ PendSV_IRQn = -2, /*!< -2 Pendable request for system service */ SysTick_IRQn = -1, /*!< -1 System Tick Timer */ /* ========================================== DA1469x Specific Interrupt Numbers =========================================== */ SNC_IRQn = 0, /*!< 0 Sensor Node Controller interrupt request. */ DMA_IRQn = 1, /*!< 1 General Purpose DMA interrupt request. */ CHARGER_STATE_IRQn = 2, /*!< 2 Charger State interrupt request. */ CHARGER_ERROR_IRQn = 3, /*!< 3 Charger Error interrupt request. */ CMAC2SYS_IRQn = 4, /*!< 4 CMAC and mailbox interrupt request. */ UART_IRQn = 5, /*!< 5 UART interrupt request. */ UART2_IRQn = 6, /*!< 6 UART2 interrupt request. */ UART3_IRQn = 7, /*!< 7 UART3 interrupt request. */ I2C_IRQn = 8, /*!< 8 I2C interrupt request. */ I2C2_IRQn = 9, /*!< 9 I2C2 interrupt request. */ SPI_IRQn = 10, /*!< 10 SPI interrupt request. */ SPI2_IRQn = 11, /*!< 11 SPI2 interrupt request. */ PCM_IRQn = 12, /*!< 12 PCM interrupt request. */ SRC_IN_IRQn = 13, /*!< 13 SRC input interrupt request. */ SRC_OUT_IRQn = 14, /*!< 14 SRC output interrupt request. */ USB_IRQn = 15, /*!< 15 USB interrupt request. */ TIMER_IRQn = 16, /*!< 16 TIMER interrupt request. */ TIMER2_IRQn = 17, /*!< 17 TIMER2 interrupt request. */ RTC_IRQn = 18, /*!< 18 RTC interrupt request. */ KEY_WKUP_GPIO_IRQn = 19, /*!< 19 Debounced button press interrupt request. */ PDC_IRQn = 20, /*!< 20 Wakeup IRQ from PDC to CM33 */ VBUS_IRQn = 21, /*!< 21 VBUS presence interrupt request. */ MRM_IRQn = 22, /*!< 22 Cache Miss Rate Monitor interrupt request. */ MOTOR_CONTROLLER_IRQn = 23, /*!< 23 MOTOR and mailbox interrupt request. */ TRNG_IRQn = 24, /*!< 24 True Random Number Generation interrupt request. */ DCDC_IRQn = 25, /*!< 25 DCDC interrupt request. */ XTAL32M_RDY_IRQn = 26, /*!< 26 XTAL32M trimmed and ready interrupt request. */ GPADC_IRQn = 27, /*!< 27 General Purpose Analog-Digital Converter interrupt request. */ SDADC_IRQn = 28, /*!< 28 Sigma Delta Analog-Digital Converter interrupt request. */ CRYPTO_IRQn = 29, /*!< 29 Crypto interrupt request. */ CAPTIMER_IRQn = 30, /*!< 30 GPIO triggered Timer Capture interrupt request. */ RFDIAG_IRQn = 31, /*!< 31 Baseband or Radio Diagnostics interrupt request. */ LCD_CONTROLLER_IRQn = 32, /*!< 32 Parallel LCD Controller interrupt request. */ PLL_LOCK_IRQn = 33, /*!< 33 Pll lock interrupt request. */ TIMER3_IRQn = 34, /*!< 34 TIMER3 interrupt request. */ TIMER4_IRQn = 35, /*!< 35 TIMER4 interrupt request. */ LRA_IRQn = 36, /*!< 36 LRA/ERM interrupt request. */ RTC_EVENT_IRQn = 37, /*!< 37 RTC event interrupt request. */ GPIO_P0_IRQn = 38, /*!< 38 GPIO port 0 toggle interrupt request. */ GPIO_P1_IRQn = 39 /*!< 39 GPIO port 1 toggle interrupt request. */ } IRQn_Type; /* =========================================================================================================================== */ /* ================ Processor and Core Peripheral Section ================ */ /* =========================================================================================================================== */ /* ========================== Configuration of the ARM Cortex-M33 Processor and Core Peripherals =========================== */ #define __CM33_REV 0x0000U /*!< CM33 Core Revision */ #define __NVIC_PRIO_BITS 4 /*!< Number of Bits used for Priority Levels */ #define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ #define __VTOR_PRESENT 1 /*!< Set to 1 if CPU supports Vector Table Offset Register */ #define __MPU_PRESENT 1 /*!< MPU present */ #define __FPU_PRESENT 1 /*!< FPU present */ #define __FPU_DP 0 /*!< Double Precision FPU */ #define __DSP_PRESENT 1 /*!< DSP extension present */ #define __SAU_REGION_PRESENT 0 /*!< SAU present */ /** @} */ /* End of group Configuration_of_CMSIS */ #include "core_cm33.h" /*!< ARM Cortex-M33 processor and core peripherals */ #include "system_DA1469x.h" /*!< DA1469x System */ #ifndef __IM /*!< Fallback for older CMSIS versions */ #define __IM __I #endif #ifndef __OM /*!< Fallback for older CMSIS versions */ #define __OM __O #endif #ifndef __IOM /*!< Fallback for older CMSIS versions */ #define __IOM __IO #endif /* =========================================================================================================================== */ /* ================ Device Specific Peripheral Section ================ */ /* =========================================================================================================================== */ /** @addtogroup Device_Peripheral_peripherals * @{ */ /* =========================================================================================================================== */ /* ================ AES_HASH ================ */ /* =========================================================================================================================== */ /** * @brief AES_HASH registers (AES_HASH) */ typedef struct { /*!< (@ 0x30040000) AES_HASH Structure */ __IOM uint32_t CRYPTO_CTRL_REG; /*!< (@ 0x00000000) Crypto Control register */ __IOM uint32_t CRYPTO_START_REG; /*!< (@ 0x00000004) Crypto Start calculation */ __IOM uint32_t CRYPTO_FETCH_ADDR_REG; /*!< (@ 0x00000008) Crypto DMA fetch register */ __IOM uint32_t CRYPTO_LEN_REG; /*!< (@ 0x0000000C) Crypto Length of the input block in bytes */ __IOM uint32_t CRYPTO_DEST_ADDR_REG; /*!< (@ 0x00000010) Crypto DMA destination memory */ __IOM uint32_t CRYPTO_STATUS_REG; /*!< (@ 0x00000014) Crypto Status register */ __IOM uint32_t CRYPTO_CLRIRQ_REG; /*!< (@ 0x00000018) Crypto Clear interrupt request */ __IOM uint32_t CRYPTO_MREG0_REG; /*!< (@ 0x0000001C) Crypto Mode depended register 0 */ __IOM uint32_t CRYPTO_MREG1_REG; /*!< (@ 0x00000020) Crypto Mode depended register 1 */ __IOM uint32_t CRYPTO_MREG2_REG; /*!< (@ 0x00000024) Crypto Mode depended register 2 */ __IOM uint32_t CRYPTO_MREG3_REG; /*!< (@ 0x00000028) Crypto Mode depended register 3 */ __IM uint32_t RESERVED[53]; __IOM uint32_t CRYPTO_KEYS_START; /*!< (@ 0x00000100) Crypto First position of the AES keys storage memory */ } AES_HASH_Type; /*!< Size = 260 (0x104) */ /* =========================================================================================================================== */ /* ================ ANAMISC_BIF ================ */ /* =========================================================================================================================== */ /** * @brief ANAMISC_BIF registers (ANAMISC_BIF) */ typedef struct { /*!< (@ 0x50030B00) ANAMISC_BIF Structure */ __IM uint32_t RESERVED[4]; __IOM uint32_t CLK_REF_SEL_REG; /*!< (@ 0x00000010) Select clock for oscillator calibration */ __IOM uint32_t CLK_REF_CNT_REG; /*!< (@ 0x00000014) Count value for oscillator calibration */ __IOM uint32_t CLK_REF_VAL_REG; /*!< (@ 0x00000018) DIVN reference cycles, lower 16 bits */ } ANAMISC_BIF_Type; /*!< Size = 28 (0x1c) */ /* =========================================================================================================================== */ /* ================ APU ================ */ /* =========================================================================================================================== */ /** * @brief APU registers (APU) */ typedef struct { /*!< (@ 0x50030600) APU Structure */ __IOM uint32_t SRC1_CTRL_REG; /*!< (@ 0x00000000) SRC1 control register */ __IOM uint32_t SRC1_IN_FS_REG; /*!< (@ 0x00000004) SRC1 Sample input rate */ __IOM uint32_t SRC1_OUT_FS_REG; /*!< (@ 0x00000008) SRC1 Sample output rate */ __IOM uint32_t SRC1_IN1_REG; /*!< (@ 0x0000000C) SRC1 data in 1 */ __IOM uint32_t SRC1_IN2_REG; /*!< (@ 0x00000010) SRC1 data in 2 */ __IOM uint32_t SRC1_OUT1_REG; /*!< (@ 0x00000014) SRC1 data out 1 */ __IOM uint32_t SRC1_OUT2_REG; /*!< (@ 0x00000018) SRC1 data out 2 */ __IOM uint32_t APU_MUX_REG; /*!< (@ 0x0000001C) APU mux register */ __IOM uint32_t COEF10_SET1_REG; /*!< (@ 0x00000020) SRC coefficient 1,0 set 1 */ __IOM uint32_t COEF32_SET1_REG; /*!< (@ 0x00000024) SRC coefficient 3,2 set 1 */ __IOM uint32_t COEF54_SET1_REG; /*!< (@ 0x00000028) SRC coefficient 5,4 set 1 */ __IOM uint32_t COEF76_SET1_REG; /*!< (@ 0x0000002C) SRC coefficient 7,6 set 1 */ __IOM uint32_t COEF98_SET1_REG; /*!< (@ 0x00000030) SRC coefficient 9,8 set 1 */ __IOM uint32_t COEF0A_SET1_REG; /*!< (@ 0x00000034) SRC coefficient 10 set 1 */ __IM uint32_t RESERVED[50]; __IOM uint32_t PCM1_CTRL_REG; /*!< (@ 0x00000100) PCM1 Control register */ __IOM uint32_t PCM1_IN1_REG; /*!< (@ 0x00000104) PCM1 data in 1 */ __IOM uint32_t PCM1_IN2_REG; /*!< (@ 0x00000108) PCM1 data in 2 */ __IOM uint32_t PCM1_OUT1_REG; /*!< (@ 0x0000010C) PCM1 data out 1 */ __IOM uint32_t PCM1_OUT2_REG; /*!< (@ 0x00000110) PCM1 data out 2 */ } APU_Type; /*!< Size = 276 (0x114) */ /* =========================================================================================================================== */ /* ================ CACHE ================ */ /* =========================================================================================================================== */ /** * @brief CACHE registers (CACHE) */ typedef struct { /*!< (@ 0x100C0000) CACHE Structure */ __IOM uint32_t CACHE_CTRL1_REG; /*!< (@ 0x00000000) Cache control register 1 */ __IOM uint32_t CACHE_LNSIZECFG_REG; /*!< (@ 0x00000004) Cache line size configuration register */ __IOM uint32_t CACHE_ASSOCCFG_REG; /*!< (@ 0x00000008) Cache associativity configuration register */ __IM uint32_t RESERVED[5]; __IOM uint32_t CACHE_CTRL2_REG; /*!< (@ 0x00000020) Cache control register 2 */ __IM uint32_t RESERVED1; __IOM uint32_t CACHE_MRM_HITS_REG; /*!< (@ 0x00000028) Cache MRM (Miss Rate Monitor) HITS register */ __IOM uint32_t CACHE_MRM_MISSES_REG; /*!< (@ 0x0000002C) Cache MRM (Miss Rate Monitor) MISSES register */ __IOM uint32_t CACHE_MRM_CTRL_REG; /*!< (@ 0x00000030) Cache MRM (Miss Rate Monitor) CONTROL register */ __IOM uint32_t CACHE_MRM_TINT_REG; /*!< (@ 0x00000034) Cache MRM (Miss Rate Monitor) TIME INTERVAL register */ __IOM uint32_t CACHE_MRM_MISSES_THRES_REG; /*!< (@ 0x00000038) Cache MRM (Miss Rate Monitor) THRESHOLD register */ __IOM uint32_t CACHE_MRM_HITS_THRES_REG; /*!< (@ 0x0000003C) Cache MRM (Miss Rate Monitor) HITS THRESHOLD register */ __IOM uint32_t CACHE_FLASH_REG; /*!< (@ 0x00000040) Cache Flash program size and base address register */ __IM uint32_t RESERVED2[3]; __IOM uint32_t SWD_RESET_REG; /*!< (@ 0x00000050) SWD HW reset control register */ } CACHE_Type; /*!< Size = 84 (0x54) */ /* =========================================================================================================================== */ /* ================ CHARGER ================ */ /* =========================================================================================================================== */ /** * @brief CHARGER registers (CHARGER) */ typedef struct { /*!< (@ 0x50040400) CHARGER Structure */ __IOM uint32_t CHARGER_CTRL_REG; /*!< (@ 0x00000000) Charger main control register */ __IOM uint32_t CHARGER_TEST_CTRL_REG; /*!< (@ 0x00000004) Charger test control register */ __IOM uint32_t CHARGER_STATUS_REG; /*!< (@ 0x00000008) Charger main status register */ __IOM uint32_t CHARGER_VOLTAGE_PARAM_REG; /*!< (@ 0x0000000C) Charger voltage settings register */ __IOM uint32_t CHARGER_CURRENT_PARAM_REG; /*!< (@ 0x00000010) Charger current settings register */ __IOM uint32_t CHARGER_TEMPSET_PARAM_REG; /*!< (@ 0x00000014) Charger battery temperature settings register */ __IOM uint32_t CHARGER_PRE_CHARGE_TIMER_REG; /*!< (@ 0x00000018) Maximum pre-charge time limit register */ __IOM uint32_t CHARGER_CC_CHARGE_TIMER_REG; /*!< (@ 0x0000001C) Maximum CC-charge time limit register */ __IOM uint32_t CHARGER_CV_CHARGE_TIMER_REG; /*!< (@ 0x00000020) Maximum CV-charge time limit register */ __IOM uint32_t CHARGER_TOTAL_CHARGE_TIMER_REG;/*!< (@ 0x00000024) Maximum total charge time limit register */ __IOM uint32_t CHARGER_JEITA_V_CHARGE_REG; /*!< (@ 0x00000028) JEITA-compliant Charge voltage settings register */ __IOM uint32_t CHARGER_JEITA_V_PRECHARGE_REG;/*!< (@ 0x0000002C) JEITA-compliant Pre-Charge voltage settings register */ __IOM uint32_t CHARGER_JEITA_V_REPLENISH_REG;/*!< (@ 0x00000030) JEITA-compliant Replenish settings register */ __IOM uint32_t CHARGER_JEITA_V_OVP_REG; /*!< (@ 0x00000034) JEITA-compliant OVP settings register */ __IOM uint32_t CHARGER_JEITA_CURRENT_REG; /*!< (@ 0x00000038) JEITA-compliant current settings register */ __IOM uint32_t CHARGER_VBAT_COMP_TIMER_REG; /*!< (@ 0x0000003C) Main Vbat comparator timer register */ __IOM uint32_t CHARGER_VOVP_COMP_TIMER_REG; /*!< (@ 0x00000040) Vbat OVP comparator timer register */ __IOM uint32_t CHARGER_TDIE_COMP_TIMER_REG; /*!< (@ 0x00000044) Die temperature comparator timer register */ __IOM uint32_t CHARGER_TBAT_MON_TIMER_REG; /*!< (@ 0x00000048) Battery temperature monitor interval timer */ __IOM uint32_t CHARGER_TBAT_COMP_TIMER_REG; /*!< (@ 0x0000004C) Battery temperature (main) comparator timer */ __IOM uint32_t CHARGER_THOT_COMP_TIMER_REG; /*!< (@ 0x00000050) Battery temperature comparator timer for 'Hot' zone */ __IOM uint32_t CHARGER_PWR_UP_TIMER_REG; /*!< (@ 0x00000054) Charger power-up (settling) timer */ __IOM uint32_t CHARGER_STATE_IRQ_MASK_REG; /*!< (@ 0x00000058) Mask register of Charger FSM IRQs */ __IOM uint32_t CHARGER_ERROR_IRQ_MASK_REG; /*!< (@ 0x0000005C) Mask register of Charger Error IRQs */ __IOM uint32_t CHARGER_STATE_IRQ_STATUS_REG; /*!< (@ 0x00000060) Status register of Charger FSM IRQs */ __IOM uint32_t CHARGER_ERROR_IRQ_STATUS_REG; /*!< (@ 0x00000064) Status register of Charger Error IRQs */ __IOM uint32_t CHARGER_STATE_IRQ_CLR_REG; /*!< (@ 0x00000068) Interrupt clear register of Charger FSM IRQs */ __IOM uint32_t CHARGER_ERROR_IRQ_CLR_REG; /*!< (@ 0x0000006C) Interrupt clear register of Charger Error IRQs */ } CHARGER_Type; /*!< Size = 112 (0x70) */ /* =========================================================================================================================== */ /* ================ CHIP_VERSION ================ */ /* =========================================================================================================================== */ /** * @brief CHIP_VERSION registers (CHIP_VERSION) */ typedef struct { /*!< (@ 0x50040200) CHIP_VERSION Structure */ __IOM uint32_t CHIP_ID1_REG; /*!< (@ 0x00000000) Chip identification register 1. */ __IOM uint32_t CHIP_ID2_REG; /*!< (@ 0x00000004) Chip identification register 2. */ __IOM uint32_t CHIP_ID3_REG; /*!< (@ 0x00000008) Chip identification register 3. */ __IOM uint32_t CHIP_ID4_REG; /*!< (@ 0x0000000C) Chip identification register 4. */ __IOM uint32_t CHIP_SWC_REG; /*!< (@ 0x00000010) Software compatibility register. */ __IOM uint32_t CHIP_REVISION_REG; /*!< (@ 0x00000014) Chip revision register. */ __IM uint32_t RESERVED[56]; __IOM uint32_t CHIP_TEST1_REG; /*!< (@ 0x000000F8) Chip test register 1. */ __IOM uint32_t CHIP_TEST2_REG; /*!< (@ 0x000000FC) Chip test register 2. */ } CHIP_VERSION_Type; /*!< Size = 256 (0x100) */ /* =========================================================================================================================== */ /* ================ CRG_COM ================ */ /* =========================================================================================================================== */ /** * @brief CRG_COM registers (CRG_COM) */ typedef struct { /*!< (@ 0x50020900) CRG_COM Structure */ __IM uint32_t RESERVED; __IOM uint32_t CLK_COM_REG; /*!< (@ 0x00000004) Peripheral divider register */ __IOM uint32_t SET_CLK_COM_REG; /*!< (@ 0x00000008) Peripheral divider register SET register. Reads back 0x0000 */ __IOM uint32_t RESET_CLK_COM_REG; /*!< (@ 0x0000000C) Peripheral divider register RESET register. Reads back 0x0000 */ } CRG_COM_Type; /*!< Size = 16 (0x10) */ /* =========================================================================================================================== */ /* ================ CRG_PER ================ */ /* =========================================================================================================================== */ /** * @brief CRG_PER registers (CRG_PER) */ typedef struct { /*!< (@ 0x50030C00) CRG_PER Structure */ __IM uint32_t RESERVED; __IOM uint32_t CLK_PER_REG; /*!< (@ 0x00000004) Peripheral divider register */ __IOM uint32_t SET_CLK_PER_REG; /*!< (@ 0x00000008) Peripheral divider register SET register, reads 0x0000 */ __IOM uint32_t RESET_CLK_PER_REG; /*!< (@ 0x0000000C) Peripheral divider register RESET register, reads 0x0000 */ __IM uint32_t RESERVED1[12]; __IOM uint32_t PCM_DIV_REG; /*!< (@ 0x00000040) PCM divider and enables */ __IOM uint32_t PCM_FDIV_REG; /*!< (@ 0x00000044) PCM fractional division register */ __IOM uint32_t PDM_DIV_REG; /*!< (@ 0x00000048) PDM divider and enables */ __IOM uint32_t SRC_DIV_REG; /*!< (@ 0x0000004C) SRC divider and enables */ } CRG_PER_Type; /*!< Size = 80 (0x50) */ /* =========================================================================================================================== */ /* ================ CRG_SYS ================ */ /* =========================================================================================================================== */ /** * @brief CRG_SYS registers (CRG_SYS) */ typedef struct { /*!< (@ 0x50040500) CRG_SYS Structure */ __IOM uint32_t CLK_SYS_REG; /*!< (@ 0x00000000) Peripheral divider register */ __IOM uint32_t BATCHECK_REG; /*!< (@ 0x00000004) BATCHECK_REG */ } CRG_SYS_Type; /*!< Size = 8 (0x8) */ /* =========================================================================================================================== */ /* ================ CRG_TOP ================ */ /* =========================================================================================================================== */ /** * @brief CRG_TOP registers (CRG_TOP) */ typedef struct { /*!< (@ 0x50000000) CRG_TOP Structure */ __IOM uint32_t CLK_AMBA_REG; /*!< (@ 0x00000000) HCLK, PCLK, divider and clock gates */ __IM uint32_t RESERVED[3]; __IOM uint32_t CLK_RADIO_REG; /*!< (@ 0x00000010) Radio PLL control register */ __IOM uint32_t CLK_CTRL_REG; /*!< (@ 0x00000014) Clock control register */ __IOM uint32_t CLK_TMR_REG; /*!< (@ 0x00000018) Clock control for the timers */ __IOM uint32_t CLK_SWITCH2XTAL_REG; /*!< (@ 0x0000001C) Switches clock from RC32M to XTAL32M */ __IOM uint32_t PMU_CTRL_REG; /*!< (@ 0x00000020) Power Management Unit control register */ __IOM uint32_t SYS_CTRL_REG; /*!< (@ 0x00000024) System Control register */ __IOM uint32_t SYS_STAT_REG; /*!< (@ 0x00000028) System status register */ __IM uint32_t RESERVED1[4]; __IOM uint32_t CLK_RC32K_REG; /*!< (@ 0x0000003C) 32 kHz RC oscillator register */ __IOM uint32_t CLK_XTAL32K_REG; /*!< (@ 0x00000040) 32 kHz XTAL oscillator register */ __IOM uint32_t CLK_RC32M_REG; /*!< (@ 0x00000044) Fast RC control register */ __IOM uint32_t CLK_RCX_REG; /*!< (@ 0x00000048) RCX-oscillator control register */ __IOM uint32_t CLK_RTCDIV_REG; /*!< (@ 0x0000004C) Divisor for RTC 100Hz clock */ __IOM uint32_t BANDGAP_REG; /*!< (@ 0x00000050) bandgap trimming */ __IOM uint32_t VBUS_IRQ_MASK_REG; /*!< (@ 0x00000054) IRQ masking */ __IOM uint32_t VBUS_IRQ_CLEAR_REG; /*!< (@ 0x00000058) Clear pending IRQ register */ __IM uint32_t RESERVED2; __IOM uint32_t BOD_CTRL_REG; /*!< (@ 0x00000060) Brown Out Detection control register */ __IOM uint32_t BOD_LVL_CTRL0_REG; /*!< (@ 0x00000064) BOD_LVL_CTRL0_REG */ __IOM uint32_t BOD_LVL_CTRL1_REG; /*!< (@ 0x00000068) BOD_LVL_CTRL1_REG */ __IOM uint32_t BOD_LVL_CTRL2_REG; /*!< (@ 0x0000006C) BOD_LVL_CTRL2_REG */ __IOM uint32_t P0_PAD_LATCH_REG; /*!< (@ 0x00000070) Control the state retention of the GPIO ports */ __IOM uint32_t P0_SET_PAD_LATCH_REG; /*!< (@ 0x00000074) Control the state retention of the GPIO ports */ __IOM uint32_t P0_RESET_PAD_LATCH_REG; /*!< (@ 0x00000078) Control the state retention of the GPIO ports */ __IOM uint32_t P1_PAD_LATCH_REG; /*!< (@ 0x0000007C) Control the state retention of the GPIO ports */ __IOM uint32_t P1_SET_PAD_LATCH_REG; /*!< (@ 0x00000080) Control the state retention of the GPIO ports */ __IOM uint32_t P1_RESET_PAD_LATCH_REG; /*!< (@ 0x00000084) Control the state retention of the GPIO ports */ __IM uint32_t RESERVED3[2]; __IOM uint32_t BOD_STATUS_REG; /*!< (@ 0x00000090) BOD_STATUS_REG */ __IOM uint32_t POR_VBAT_CTRL_REG; /*!< (@ 0x00000094) Controls the POR on VBAT */ __IOM uint32_t POR_PIN_REG; /*!< (@ 0x00000098) Selects a GPIO pin for POR generation */ __IOM uint32_t POR_TIMER_REG; /*!< (@ 0x0000009C) Time for POR to happen */ __IOM uint32_t LDO_VDDD_HIGH_CTRL_REG; /*!< (@ 0x000000A0) LDO control register */ __IOM uint32_t BIAS_VREF_SEL_REG; /*!< (@ 0x000000A4) BIAS_VREF_SEL_REG */ __IM uint32_t RESERVED4[5]; __IOM uint32_t RESET_STAT_REG; /*!< (@ 0x000000BC) Reset status register */ __IOM uint32_t RAM_PWR_CTRL_REG; /*!< (@ 0x000000C0) Control power state of System RAMS */ __IM uint32_t RESERVED5[2]; __IOM uint32_t SECURE_BOOT_REG; /*!< (@ 0x000000CC) Controls secure booting */ __IM uint32_t RESERVED6; __IOM uint32_t DISCHARGE_RAIL_REG; /*!< (@ 0x000000D4) Immediate rail resetting. There is no LDO/DCDC gating */ __IM uint32_t RESERVED7[5]; __IOM uint32_t ANA_STATUS_REG; /*!< (@ 0x000000EC) Analog Signals Status Register */ __IOM uint32_t POWER_CTRL_REG; /*!< (@ 0x000000F0) Power control register */ __IOM uint32_t PMU_SLEEP_REG; /*!< (@ 0x000000F4) Configures the sleep/wakeup strategy */ __IOM uint32_t PMU_TRIM_REG; /*!< (@ 0x000000F8) LDO trimming register */ } CRG_TOP_Type; /*!< Size = 252 (0xfc) */ /* =========================================================================================================================== */ /* ================ CRG_XTAL ================ */ /* =========================================================================================================================== */ /** * @brief CRG_XTAL registers (CRG_XTAL) */ typedef struct { /*!< (@ 0x50010000) CRG_XTAL Structure */ __IOM uint32_t CLK_FREQ_TRIM_REG; /*!< (@ 0x00000000) Xtal frequency trimming register. */ __IM uint32_t RESERVED[3]; __IOM uint32_t TRIM_CTRL_REG; /*!< (@ 0x00000010) Control trimming of the XTAL32M */ __IM uint32_t RESERVED1; __IOM uint32_t XTALRDY_CTRL_REG; /*!< (@ 0x00000018) Control register for XTALRDY IRQ */ __IOM uint32_t XTALRDY_STAT_REG; /*!< (@ 0x0000001C) Difference between XTAL_OK and XTALRDY_IRQ in LP clock cycles */ __IM uint32_t RESERVED2[4]; __IOM uint32_t XTAL32M_CTRL0_REG; /*!< (@ 0x00000030) Control register for XTAL32M */ __IOM uint32_t XTAL32M_CTRL1_REG; /*!< (@ 0x00000034) Control register for XTAL32M */ __IOM uint32_t XTAL32M_CTRL2_REG; /*!< (@ 0x00000038) Control register for XTAL32M */ __IOM uint32_t XTAL32M_CTRL3_REG; /*!< (@ 0x0000003C) Control register for XTAL32M */ __IOM uint32_t XTAL32M_CTRL4_REG; /*!< (@ 0x00000040) Control register for XTAL32M */ __IM uint32_t RESERVED3[3]; __IOM uint32_t XTAL32M_STAT0_REG; /*!< (@ 0x00000050) Status register for XTAL32M */ __IOM uint32_t XTAL32M_STAT1_REG; /*!< (@ 0x00000054) Status register for XTAL32M */ __IM uint32_t RESERVED4[2]; __IOM uint32_t PLL_SYS_CTRL1_REG; /*!< (@ 0x00000060) System PLL control register 1. */ __IOM uint32_t PLL_SYS_CTRL2_REG; /*!< (@ 0x00000064) System PLL control register 2. */ __IOM uint32_t PLL_SYS_CTRL3_REG; /*!< (@ 0x00000068) System PLL control register 3. */ __IM uint32_t RESERVED5; __IOM uint32_t PLL_SYS_STATUS_REG; /*!< (@ 0x00000070) System PLL status register. */ } CRG_XTAL_Type; /*!< Size = 116 (0x74) */ /* =========================================================================================================================== */ /* ================ DCDC ================ */ /* =========================================================================================================================== */ /** * @brief DCDC registers (DCDC) */ typedef struct { /*!< (@ 0x50000300) DCDC Structure */ __IM uint32_t RESERVED; __IOM uint32_t DCDC_CTRL1_REG; /*!< (@ 0x00000004) DCDC First Control Register */ __IOM uint32_t DCDC_CTRL2_REG; /*!< (@ 0x00000008) DCDC Second Control Register */ __IOM uint32_t DCDC_V14_REG; /*!< (@ 0x0000000C) DCDC V14 Control Register */ __IOM uint32_t DCDC_VDD_REG; /*!< (@ 0x00000010) DCDC VDD Control Register */ __IOM uint32_t DCDC_V18_REG; /*!< (@ 0x00000014) DCDC V18 Control Register */ __IOM uint32_t DCDC_V18P_REG; /*!< (@ 0x00000018) DCDC V18P Control Register */ __IM uint32_t RESERVED1; __IOM uint32_t DCDC_STATUS1_REG; /*!< (@ 0x00000020) DCDC First Status Register */ __IM uint32_t RESERVED2[3]; __IOM uint32_t DCDC_IRQ_STATUS_REG; /*!< (@ 0x00000030) DCDC Interrupt Status Register */ __IOM uint32_t DCDC_IRQ_CLEAR_REG; /*!< (@ 0x00000034) DCDC Interrupt Clear Register */ __IOM uint32_t DCDC_IRQ_MASK_REG; /*!< (@ 0x00000038) DCDC Interrupt Mask Register */ } DCDC_Type; /*!< Size = 60 (0x3c) */ /* =========================================================================================================================== */ /* ================ DMA ================ */ /* =========================================================================================================================== */ /** * @brief DMA registers (DMA) */ typedef struct { /*!< (@ 0x50040800) DMA Structure */ __IOM uint32_t DMA0_A_START_REG; /*!< (@ 0x00000000) Start address A of DMA channel 0 */ __IOM uint32_t DMA0_B_START_REG; /*!< (@ 0x00000004) Start address B of DMA channel 0 */ __IOM uint32_t DMA0_INT_REG; /*!< (@ 0x00000008) DMA receive interrupt register channel 0 */ __IOM uint32_t DMA0_LEN_REG; /*!< (@ 0x0000000C) DMA receive length register channel 0 */ __IOM uint32_t DMA0_CTRL_REG; /*!< (@ 0x00000010) Control register for the DMA channel 0 */ __IOM uint32_t DMA0_IDX_REG; /*!< (@ 0x00000014) Index value of DMA channel 0 */ __IM uint32_t RESERVED[2]; __IOM uint32_t DMA1_A_START_REG; /*!< (@ 0x00000020) Start address A of DMA channel 1 */ __IOM uint32_t DMA1_B_START_REG; /*!< (@ 0x00000024) Start address B of DMA channel 1 */ __IOM uint32_t DMA1_INT_REG; /*!< (@ 0x00000028) DMA receive interrupt register channel 1 */ __IOM uint32_t DMA1_LEN_REG; /*!< (@ 0x0000002C) DMA receive length register channel 1 */ __IOM uint32_t DMA1_CTRL_REG; /*!< (@ 0x00000030) Control register for the DMA channel 1 */ __IOM uint32_t DMA1_IDX_REG; /*!< (@ 0x00000034) Index value of DMA channel 1 */ __IM uint32_t RESERVED1[2]; __IOM uint32_t DMA2_A_START_REG; /*!< (@ 0x00000040) Start address A of DMA channel 2 */ __IOM uint32_t DMA2_B_START_REG; /*!< (@ 0x00000044) Start address B of DMA channel 2 */ __IOM uint32_t DMA2_INT_REG; /*!< (@ 0x00000048) DMA receive interrupt register channel 2 */ __IOM uint32_t DMA2_LEN_REG; /*!< (@ 0x0000004C) DMA receive length register channel 2 */ __IOM uint32_t DMA2_CTRL_REG; /*!< (@ 0x00000050) Control register for the DMA channel 2 */ __IOM uint32_t DMA2_IDX_REG; /*!< (@ 0x00000054) Index value of DMA channel 2 */ __IM uint32_t RESERVED2[2]; __IOM uint32_t DMA3_A_START_REG; /*!< (@ 0x00000060) Start address A of DMA channel 3 */ __IOM uint32_t DMA3_B_START_REG; /*!< (@ 0x00000064) Start address B of DMA channel 3 */ __IOM uint32_t DMA3_INT_REG; /*!< (@ 0x00000068) DMA receive interrupt register channel 3 */ __IOM uint32_t DMA3_LEN_REG; /*!< (@ 0x0000006C) DMA receive length register channel 3 */ __IOM uint32_t DMA3_CTRL_REG; /*!< (@ 0x00000070) Control register for the DMA channel 3 */ __IOM uint32_t DMA3_IDX_REG; /*!< (@ 0x00000074) Index value of DMA channel 3 */ __IM uint32_t RESERVED3[2]; __IOM uint32_t DMA4_A_START_REG; /*!< (@ 0x00000080) Start address A of DMA channel 4 */ __IOM uint32_t DMA4_B_START_REG; /*!< (@ 0x00000084) Start address B of DMA channel 4 */ __IOM uint32_t DMA4_INT_REG; /*!< (@ 0x00000088) DMA receive interrupt register channel 4 */ __IOM uint32_t DMA4_LEN_REG; /*!< (@ 0x0000008C) DMA receive length register channel 4 */ __IOM uint32_t DMA4_CTRL_REG; /*!< (@ 0x00000090) Control register for the DMA channel 4 */ __IOM uint32_t DMA4_IDX_REG; /*!< (@ 0x00000094) Index value of DMA channel 4 */ __IM uint32_t RESERVED4[2]; __IOM uint32_t DMA5_A_START_REG; /*!< (@ 0x000000A0) Start address A of DMA channel 5 */ __IOM uint32_t DMA5_B_START_REG; /*!< (@ 0x000000A4) Start address B of DMA channel 5 */ __IOM uint32_t DMA5_INT_REG; /*!< (@ 0x000000A8) DMA receive interrupt register channel 5 */ __IOM uint32_t DMA5_LEN_REG; /*!< (@ 0x000000AC) DMA receive length register channel 5 */ __IOM uint32_t DMA5_CTRL_REG; /*!< (@ 0x000000B0) Control register for the DMA channel 5 */ __IOM uint32_t DMA5_IDX_REG; /*!< (@ 0x000000B4) Index value of DMA channel 5 */ __IM uint32_t RESERVED5[2]; __IOM uint32_t DMA6_A_START_REG; /*!< (@ 0x000000C0) Start address A of DMA channel 6 */ __IOM uint32_t DMA6_B_START_REG; /*!< (@ 0x000000C4) Start address B of DMA channel 6 */ __IOM uint32_t DMA6_INT_REG; /*!< (@ 0x000000C8) DMA receive interrupt register channel 6 */ __IOM uint32_t DMA6_LEN_REG; /*!< (@ 0x000000CC) DMA receive length register channel 6 */ __IOM uint32_t DMA6_CTRL_REG; /*!< (@ 0x000000D0) Control register for the DMA channel 6 */ __IOM uint32_t DMA6_IDX_REG; /*!< (@ 0x000000D4) Index value of DMA channel 6 */ __IM uint32_t RESERVED6[2]; __IOM uint32_t DMA7_A_START_REG; /*!< (@ 0x000000E0) Start address A of DMA channel 7 */ __IOM uint32_t DMA7_B_START_REG; /*!< (@ 0x000000E4) Start address B of DMA channel 7 */ __IOM uint32_t DMA7_INT_REG; /*!< (@ 0x000000E8) DMA receive interrupt register channel 7 */ __IOM uint32_t DMA7_LEN_REG; /*!< (@ 0x000000EC) DMA receive length register channel 7 */ __IOM uint32_t DMA7_CTRL_REG; /*!< (@ 0x000000F0) Control register for the DMA channel 7 */ __IOM uint32_t DMA7_IDX_REG; /*!< (@ 0x000000F4) Index value of DMA channel 7 */ __IM uint32_t RESERVED7[2]; __IOM uint32_t DMA_REQ_MUX_REG; /*!< (@ 0x00000100) DMA channel assignments */ __IOM uint32_t DMA_INT_STATUS_REG; /*!< (@ 0x00000104) DMA interrupt status register */ __IOM uint32_t DMA_CLEAR_INT_REG; /*!< (@ 0x00000108) DMA clear interrupt register */ __IOM uint32_t DMA_INT_MASK_REG; /*!< (@ 0x0000010C) DMA Interrupt mask register */ } DMA_Type; /*!< Size = 272 (0x110) */ /* =========================================================================================================================== */ /* ================ DW ================ */ /* =========================================================================================================================== */ /** * @brief DW registers (DW) */ typedef struct { /*!< (@ 0x30020000) DW Structure */ __IOM uint32_t AHB_DMA_PL1_REG; /*!< (@ 0x00000000) AHB-DMA layer priority level for RFTP (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_PL2_REG; /*!< (@ 0x00000004) AHB-DMA layer priority level for LCD (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_PL3_REG; /*!< (@ 0x00000008) AHB-DMA layer Priority level for GEN-DMA (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_PL4_REG; /*!< (@ 0x0000000C) AHB-DMA layer Priority level for CRYPTO-DMA (AHB DMA layer only) */ __IM uint32_t RESERVED[14]; __IOM uint32_t AHB_DMA_DFLT_MASTER_REG; /*!< (@ 0x00000048) Default master ID number (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_WTEN_REG; /*!< (@ 0x0000004C) Weighted-Token Arbitration Scheme Enable (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_TCL_REG; /*!< (@ 0x00000050) Master clock refresh period (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_CCLM1_REG; /*!< (@ 0x00000054) USB Master clock tokens (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_CCLM2_REG; /*!< (@ 0x00000058) GenDMA Master clock tokens (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_CCLM3_REG; /*!< (@ 0x0000005C) CRYPTO Master clock tokens (AHB DMA layer only) */ __IOM uint32_t AHB_DMA_CCLM4_REG; /*!< (@ 0x00000060) CRYPTO Master clock tokens (AHB DMA layer only) */ __IM uint32_t RESERVED1[11]; __IOM uint32_t AHB_DMA_VERSION_REG; /*!< (@ 0x00000090) Version ID (AHB DMA layer only) */ } DW_Type; /*!< Size = 148 (0x94) */ /* =========================================================================================================================== */ /* ================ GPADC ================ */ /* =========================================================================================================================== */ /** * @brief GPADC registers (GPADC) */ typedef struct { /*!< (@ 0x50030900) GPADC Structure */ __IOM uint32_t GP_ADC_CTRL_REG; /*!< (@ 0x00000000) General Purpose ADC Control Register */ __IOM uint32_t GP_ADC_CTRL2_REG; /*!< (@ 0x00000004) General Purpose ADC Second Control Register */ __IOM uint32_t GP_ADC_CTRL3_REG; /*!< (@ 0x00000008) General Purpose ADC Third Control Register */ __IOM uint32_t GP_ADC_OFFP_REG; /*!< (@ 0x0000000C) General Purpose ADC Positive Offset Register */ __IOM uint32_t GP_ADC_OFFN_REG; /*!< (@ 0x00000010) General Purpose ADC Negative Offset Register */ __IOM uint32_t GP_ADC_CLEAR_INT_REG; /*!< (@ 0x00000014) General Purpose ADC Clear Interrupt Register */ __IOM uint32_t GP_ADC_RESULT_REG; /*!< (@ 0x00000018) General Purpose ADC Result Register */ } GPADC_Type; /*!< Size = 28 (0x1c) */ /* =========================================================================================================================== */ /* ================ GPIO ================ */ /* =========================================================================================================================== */ /** * @brief GPIO registers (GPIO) */ typedef struct { /*!< (@ 0x50020A00) GPIO Structure */ __IOM uint32_t P0_DATA_REG; /*!< (@ 0x00000000) P0 Data input / output Register */ __IOM uint32_t P1_DATA_REG; /*!< (@ 0x00000004) P1 Data input / output Register */ __IOM uint32_t P0_SET_DATA_REG; /*!< (@ 0x00000008) P0 Set port pins Register */ __IOM uint32_t P1_SET_DATA_REG; /*!< (@ 0x0000000C) P1 Set port pins Register */ __IOM uint32_t P0_RESET_DATA_REG; /*!< (@ 0x00000010) P0 Reset port pins Register */ __IOM uint32_t P1_RESET_DATA_REG; /*!< (@ 0x00000014) P1 Reset port pins Register */ __IOM uint32_t P0_00_MODE_REG; /*!< (@ 0x00000018) P0_00 Mode Register */ __IOM uint32_t P0_01_MODE_REG; /*!< (@ 0x0000001C) P0_01 Mode Register */ __IOM uint32_t P0_02_MODE_REG; /*!< (@ 0x00000020) P0_02 Mode Register */ __IOM uint32_t P0_03_MODE_REG; /*!< (@ 0x00000024) P0_03 Mode Register */ __IOM uint32_t P0_04_MODE_REG; /*!< (@ 0x00000028) P0_04 Mode Register */ __IOM uint32_t P0_05_MODE_REG; /*!< (@ 0x0000002C) P0_05 Mode Register */ __IOM uint32_t P0_06_MODE_REG; /*!< (@ 0x00000030) P0_06 Mode Register */ __IOM uint32_t P0_07_MODE_REG; /*!< (@ 0x00000034) P0_07 Mode Register */ __IOM uint32_t P0_08_MODE_REG; /*!< (@ 0x00000038) P0_08 Mode Register */ __IOM uint32_t P0_09_MODE_REG; /*!< (@ 0x0000003C) P0_09 Mode Register */ __IOM uint32_t P0_10_MODE_REG; /*!< (@ 0x00000040) P0_10 Mode Register */ __IOM uint32_t P0_11_MODE_REG; /*!< (@ 0x00000044) P0_11 Mode Register */ __IOM uint32_t P0_12_MODE_REG; /*!< (@ 0x00000048) P0_12 Mode Register */ __IOM uint32_t P0_13_MODE_REG; /*!< (@ 0x0000004C) P0_13 Mode Register */ __IOM uint32_t P0_14_MODE_REG; /*!< (@ 0x00000050) P0_14 Mode Register */ __IOM uint32_t P0_15_MODE_REG; /*!< (@ 0x00000054) P0_15 Mode Register */ __IOM uint32_t P0_16_MODE_REG; /*!< (@ 0x00000058) P0_16 Mode Register */ __IOM uint32_t P0_17_MODE_REG; /*!< (@ 0x0000005C) P0_17 Mode Register */ __IOM uint32_t P0_18_MODE_REG; /*!< (@ 0x00000060) P0_18 Mode Register */ __IOM uint32_t P0_19_MODE_REG; /*!< (@ 0x00000064) P0_19 Mode Register */ __IOM uint32_t P0_20_MODE_REG; /*!< (@ 0x00000068) P0_20 Mode Register */ __IOM uint32_t P0_21_MODE_REG; /*!< (@ 0x0000006C) P0_21 Mode Register */ __IOM uint32_t P0_22_MODE_REG; /*!< (@ 0x00000070) P0_22 Mode Register */ __IOM uint32_t P0_23_MODE_REG; /*!< (@ 0x00000074) P0_23 Mode Register */ __IOM uint32_t P0_24_MODE_REG; /*!< (@ 0x00000078) P0_24 Mode Register */ __IOM uint32_t P0_25_MODE_REG; /*!< (@ 0x0000007C) P0_25 Mode Register */ __IOM uint32_t P0_26_MODE_REG; /*!< (@ 0x00000080) P0_26 Mode Register */ __IOM uint32_t P0_27_MODE_REG; /*!< (@ 0x00000084) P0_27 Mode Register */ __IOM uint32_t P0_28_MODE_REG; /*!< (@ 0x00000088) P0_28 Mode Register */ __IOM uint32_t P0_29_MODE_REG; /*!< (@ 0x0000008C) P0_29 Mode Register */ __IOM uint32_t P0_30_MODE_REG; /*!< (@ 0x00000090) P0_30 Mode Register */ __IOM uint32_t P0_31_MODE_REG; /*!< (@ 0x00000094) P0_31 Mode Register */ __IOM uint32_t P1_00_MODE_REG; /*!< (@ 0x00000098) P1_00 Mode Register */ __IOM uint32_t P1_01_MODE_REG; /*!< (@ 0x0000009C) P1_01 Mode Register */ __IOM uint32_t P1_02_MODE_REG; /*!< (@ 0x000000A0) P1_02 Mode Register */ __IOM uint32_t P1_03_MODE_REG; /*!< (@ 0x000000A4) P1_03 Mode Register */ __IOM uint32_t P1_04_MODE_REG; /*!< (@ 0x000000A8) P1_04 Mode Register */ __IOM uint32_t P1_05_MODE_REG; /*!< (@ 0x000000AC) P1_05 Mode Register */ __IOM uint32_t P1_06_MODE_REG; /*!< (@ 0x000000B0) P1_06 Mode Register */ __IOM uint32_t P1_07_MODE_REG; /*!< (@ 0x000000B4) P1_07 Mode Register */ __IOM uint32_t P1_08_MODE_REG; /*!< (@ 0x000000B8) P1_08 Mode Register */ __IOM uint32_t P1_09_MODE_REG; /*!< (@ 0x000000BC) P1_09 Mode Register */ __IOM uint32_t P1_10_MODE_REG; /*!< (@ 0x000000C0) P1_10 Mode Register */ __IOM uint32_t P1_11_MODE_REG; /*!< (@ 0x000000C4) P1_11 Mode Register */ __IOM uint32_t P1_12_MODE_REG; /*!< (@ 0x000000C8) P1_12 Mode Register */ __IOM uint32_t P1_13_MODE_REG; /*!< (@ 0x000000CC) P1_13 Mode Register */ __IOM uint32_t P1_14_MODE_REG; /*!< (@ 0x000000D0) P1_14 Mode Register */ __IOM uint32_t P1_15_MODE_REG; /*!< (@ 0x000000D4) P1_15 Mode Register */ __IOM uint32_t P1_16_MODE_REG; /*!< (@ 0x000000D8) P1_16 Mode Register */ __IOM uint32_t P1_17_MODE_REG; /*!< (@ 0x000000DC) P1_17 Mode Register */ __IOM uint32_t P1_18_MODE_REG; /*!< (@ 0x000000E0) P1_18 Mode Register */ __IOM uint32_t P1_19_MODE_REG; /*!< (@ 0x000000E4) P1_19 Mode Register */ __IOM uint32_t P1_20_MODE_REG; /*!< (@ 0x000000E8) P1_20 Mode Register */ __IOM uint32_t P1_21_MODE_REG; /*!< (@ 0x000000EC) P1_21 Mode Register */ __IOM uint32_t P1_22_MODE_REG; /*!< (@ 0x000000F0) P1_22 Mode Register */ __IOM uint32_t P0_PADPWR_CTRL_REG; /*!< (@ 0x000000F4) P0 Output Power Control Register */ __IOM uint32_t P1_PADPWR_CTRL_REG; /*!< (@ 0x000000F8) P1 Output Power Control Register */ __IOM uint32_t GPIO_CLK_SEL_REG; /*!< (@ 0x000000FC) Select which clock to map on ports P0/P1 */ __IOM uint32_t PAD_WEAK_CTRL_REG; /*!< (@ 0x00000100) Weak Pads Control Register */ } GPIO_Type; /*!< Size = 260 (0x104) */ /* =========================================================================================================================== */ /* ================ GPREG ================ */ /* =========================================================================================================================== */ /** * @brief GPREG registers (GPREG) */ typedef struct { /*!< (@ 0x50040300) GPREG Structure */ __IOM uint32_t SET_FREEZE_REG; /*!< (@ 0x00000000) Controls freezing of various timers/counters (incl. DMA and USB). */ __IOM uint32_t RESET_FREEZE_REG; /*!< (@ 0x00000004) Controls unfreezing of various timers/counters (incl. DMA and USB). */ __IOM uint32_t DEBUG_REG; /*!< (@ 0x00000008) Various debug information register. */ __IOM uint32_t GP_STATUS_REG; /*!< (@ 0x0000000C) General purpose system status register. */ __IOM uint32_t GP_CONTROL_REG; /*!< (@ 0x00000010) General purpose system control register. */ __IM uint32_t RESERVED; __IOM uint32_t USBPAD_REG; /*!< (@ 0x00000018) USB pads control register */ } GPREG_Type; /*!< Size = 28 (0x1c) */ /* =========================================================================================================================== */ /* ================ I2C ================ */ /* =========================================================================================================================== */ /** * @brief I2C registers (I2C) */ typedef struct { /*!< (@ 0x50020600) I2C Structure */ __IOM uint32_t I2C_CON_REG; /*!< (@ 0x00000000) I2C Control Register */ __IOM uint32_t I2C_TAR_REG; /*!< (@ 0x00000004) I2C Target Address Register */ __IOM uint32_t I2C_SAR_REG; /*!< (@ 0x00000008) I2C Slave Address Register */ __IOM uint32_t I2C_HS_MADDR_REG; /*!< (@ 0x0000000C) I2C High Speed Master Mode Code Address Register */ __IOM uint32_t I2C_DATA_CMD_REG; /*!< (@ 0x00000010) I2C Rx/Tx Data Buffer and Command Register */ __IOM uint32_t I2C_SS_SCL_HCNT_REG; /*!< (@ 0x00000014) Standard Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C_SS_SCL_LCNT_REG; /*!< (@ 0x00000018) Standard Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C_FS_SCL_HCNT_REG; /*!< (@ 0x0000001C) Fast Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C_FS_SCL_LCNT_REG; /*!< (@ 0x00000020) Fast Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C_HS_SCL_HCNT_REG; /*!< (@ 0x00000024) High Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C_HS_SCL_LCNT_REG; /*!< (@ 0x00000028) High Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C_INTR_STAT_REG; /*!< (@ 0x0000002C) I2C Interrupt Status Register */ __IOM uint32_t I2C_INTR_MASK_REG; /*!< (@ 0x00000030) I2C Interrupt Mask Register */ __IOM uint32_t I2C_RAW_INTR_STAT_REG; /*!< (@ 0x00000034) I2C Raw Interrupt Status Register */ __IOM uint32_t I2C_RX_TL_REG; /*!< (@ 0x00000038) I2C Receive FIFO Threshold Register */ __IOM uint32_t I2C_TX_TL_REG; /*!< (@ 0x0000003C) I2C Transmit FIFO Threshold Register */ __IOM uint32_t I2C_CLR_INTR_REG; /*!< (@ 0x00000040) Clear Combined and Individual Interrupt Register */ __IOM uint32_t I2C_CLR_RX_UNDER_REG; /*!< (@ 0x00000044) Clear RX_UNDER Interrupt Register */ __IOM uint32_t I2C_CLR_RX_OVER_REG; /*!< (@ 0x00000048) Clear RX_OVER Interrupt Register */ __IOM uint32_t I2C_CLR_TX_OVER_REG; /*!< (@ 0x0000004C) Clear TX_OVER Interrupt Register */ __IOM uint32_t I2C_CLR_RD_REQ_REG; /*!< (@ 0x00000050) Clear RD_REQ Interrupt Register */ __IOM uint32_t I2C_CLR_TX_ABRT_REG; /*!< (@ 0x00000054) Clear TX_ABRT Interrupt Register */ __IOM uint32_t I2C_CLR_RX_DONE_REG; /*!< (@ 0x00000058) Clear RX_DONE Interrupt Register */ __IOM uint32_t I2C_CLR_ACTIVITY_REG; /*!< (@ 0x0000005C) Clear ACTIVITY Interrupt Register */ __IOM uint32_t I2C_CLR_STOP_DET_REG; /*!< (@ 0x00000060) Clear STOP_DET Interrupt Register */ __IOM uint32_t I2C_CLR_START_DET_REG; /*!< (@ 0x00000064) Clear START_DET Interrupt Register */ __IOM uint32_t I2C_CLR_GEN_CALL_REG; /*!< (@ 0x00000068) Clear GEN_CALL Interrupt Register */ __IOM uint32_t I2C_ENABLE_REG; /*!< (@ 0x0000006C) I2C Enable Register */ __IOM uint32_t I2C_STATUS_REG; /*!< (@ 0x00000070) I2C Status Register */ __IOM uint32_t I2C_TXFLR_REG; /*!< (@ 0x00000074) I2C Transmit FIFO Level Register */ __IOM uint32_t I2C_RXFLR_REG; /*!< (@ 0x00000078) I2C Receive FIFO Level Register */ __IOM uint32_t I2C_SDA_HOLD_REG; /*!< (@ 0x0000007C) I2C SDA Hold Time Length Register */ __IOM uint32_t I2C_TX_ABRT_SOURCE_REG; /*!< (@ 0x00000080) I2C Transmit Abort Source Register */ __IM uint32_t RESERVED; __IOM uint32_t I2C_DMA_CR_REG; /*!< (@ 0x00000088) DMA Control Register */ __IOM uint32_t I2C_DMA_TDLR_REG; /*!< (@ 0x0000008C) DMA Transmit Data Level Register */ __IOM uint32_t I2C_DMA_RDLR_REG; /*!< (@ 0x00000090) I2C Receive Data Level Register */ __IOM uint32_t I2C_SDA_SETUP_REG; /*!< (@ 0x00000094) I2C SDA Setup Register */ __IOM uint32_t I2C_ACK_GENERAL_CALL_REG; /*!< (@ 0x00000098) I2C ACK General Call Register */ __IOM uint32_t I2C_ENABLE_STATUS_REG; /*!< (@ 0x0000009C) I2C Enable Status Register */ __IOM uint32_t I2C_IC_FS_SPKLEN_REG; /*!< (@ 0x000000A0) I2C SS and FS spike suppression limit Size */ __IOM uint32_t I2C_IC_HS_SPKLEN_REG; /*!< (@ 0x000000A4) I2C HS spike suppression limit Size */ } I2C_Type; /*!< Size = 168 (0xa8) */ /* =========================================================================================================================== */ /* ================ I2C2 ================ */ /* =========================================================================================================================== */ /** * @brief I2C2 registers (I2C2) */ typedef struct { /*!< (@ 0x50020700) I2C2 Structure */ __IOM uint32_t I2C2_CON_REG; /*!< (@ 0x00000000) I2C Control Register */ __IOM uint32_t I2C2_TAR_REG; /*!< (@ 0x00000004) I2C Target Address Register */ __IOM uint32_t I2C2_SAR_REG; /*!< (@ 0x00000008) I2C Slave Address Register */ __IOM uint32_t I2C2_HS_MADDR_REG; /*!< (@ 0x0000000C) I2C High Speed Master Mode Code Address Register */ __IOM uint32_t I2C2_DATA_CMD_REG; /*!< (@ 0x00000010) I2C Rx/Tx Data Buffer and Command Register */ __IOM uint32_t I2C2_SS_SCL_HCNT_REG; /*!< (@ 0x00000014) Standard Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C2_SS_SCL_LCNT_REG; /*!< (@ 0x00000018) Standard Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C2_FS_SCL_HCNT_REG; /*!< (@ 0x0000001C) Fast Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C2_FS_SCL_LCNT_REG; /*!< (@ 0x00000020) Fast Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C2_HS_SCL_HCNT_REG; /*!< (@ 0x00000024) High Speed I2C Clock SCL High Count Register */ __IOM uint32_t I2C2_HS_SCL_LCNT_REG; /*!< (@ 0x00000028) High Speed I2C Clock SCL Low Count Register */ __IOM uint32_t I2C2_INTR_STAT_REG; /*!< (@ 0x0000002C) I2C Interrupt Status Register */ __IOM uint32_t I2C2_INTR_MASK_REG; /*!< (@ 0x00000030) I2C Interrupt Mask Register */ __IOM uint32_t I2C2_RAW_INTR_STAT_REG; /*!< (@ 0x00000034) I2C Raw Interrupt Status Register */ __IOM uint32_t I2C2_RX_TL_REG; /*!< (@ 0x00000038) I2C Receive FIFO Threshold Register */ __IOM uint32_t I2C2_TX_TL_REG; /*!< (@ 0x0000003C) I2C Transmit FIFO Threshold Register */ __IOM uint32_t I2C2_CLR_INTR_REG; /*!< (@ 0x00000040) Clear Combined and Individual Interrupt Register */ __IOM uint32_t I2C2_CLR_RX_UNDER_REG; /*!< (@ 0x00000044) Clear RX_UNDER Interrupt Register */ __IOM uint32_t I2C2_CLR_RX_OVER_REG; /*!< (@ 0x00000048) Clear RX_OVER Interrupt Register */ __IOM uint32_t I2C2_CLR_TX_OVER_REG; /*!< (@ 0x0000004C) Clear TX_OVER Interrupt Register */ __IOM uint32_t I2C2_CLR_RD_REQ_REG; /*!< (@ 0x00000050) Clear RD_REQ Interrupt Register */ __IOM uint32_t I2C2_CLR_TX_ABRT_REG; /*!< (@ 0x00000054) Clear TX_ABRT Interrupt Register */ __IOM uint32_t I2C2_CLR_RX_DONE_REG; /*!< (@ 0x00000058) Clear RX_DONE Interrupt Register */ __IOM uint32_t I2C2_CLR_ACTIVITY_REG; /*!< (@ 0x0000005C) Clear ACTIVITY Interrupt Register */ __IOM uint32_t I2C2_CLR_STOP_DET_REG; /*!< (@ 0x00000060) Clear STOP_DET Interrupt Register */ __IOM uint32_t I2C2_CLR_START_DET_REG; /*!< (@ 0x00000064) Clear START_DET Interrupt Register */ __IOM uint32_t I2C2_CLR_GEN_CALL_REG; /*!< (@ 0x00000068) Clear GEN_CALL Interrupt Register */ __IOM uint32_t I2C2_ENABLE_REG; /*!< (@ 0x0000006C) I2C Enable Register */ __IOM uint32_t I2C2_STATUS_REG; /*!< (@ 0x00000070) I2C Status Register */ __IOM uint32_t I2C2_TXFLR_REG; /*!< (@ 0x00000074) I2C Transmit FIFO Level Register */ __IOM uint32_t I2C2_RXFLR_REG; /*!< (@ 0x00000078) I2C Receive FIFO Level Register */ __IOM uint32_t I2C2_SDA_HOLD_REG; /*!< (@ 0x0000007C) I2C SDA Hold Time Length Register */ __IOM uint32_t I2C2_TX_ABRT_SOURCE_REG; /*!< (@ 0x00000080) I2C Transmit Abort Source Register */ __IM uint32_t RESERVED; __IOM uint32_t I2C2_DMA_CR_REG; /*!< (@ 0x00000088) DMA Control Register */ __IOM uint32_t I2C2_DMA_TDLR_REG; /*!< (@ 0x0000008C) DMA Transmit Data Level Register */ __IOM uint32_t I2C2_DMA_RDLR_REG; /*!< (@ 0x00000090) I2C Receive Data Level Register */ __IOM uint32_t I2C2_SDA_SETUP_REG; /*!< (@ 0x00000094) I2C SDA Setup Register */ __IOM uint32_t I2C2_ACK_GENERAL_CALL_REG; /*!< (@ 0x00000098) I2C ACK General Call Register */ __IOM uint32_t I2C2_ENABLE_STATUS_REG; /*!< (@ 0x0000009C) I2C Enable Status Register */ __IOM uint32_t I2C2_IC_FS_SPKLEN_REG; /*!< (@ 0x000000A0) I2C SS and FS spike suppression limit Size */ __IOM uint32_t I2C2_IC_HS_SPKLEN_REG; /*!< (@ 0x000000A4) I2C HS spike suppression limit Size */ } I2C2_Type; /*!< Size = 168 (0xa8) */ /* =========================================================================================================================== */ /* ================ LCDC ================ */ /* =========================================================================================================================== */ /** * @brief LCDC registers (LCDC) */ typedef struct { /*!< (@ 0x30030000) LCDC Structure */ __IOM uint32_t LCDC_MODE_REG; /*!< (@ 0x00000000) Display Mode */ __IOM uint32_t LCDC_CLKCTRL_REG; /*!< (@ 0x00000004) Clock Divider */ __IOM uint32_t LCDC_BGCOLOR_REG; /*!< (@ 0x00000008) Background Color */ __IOM uint32_t LCDC_RESXY_REG; /*!< (@ 0x0000000C) Resolution X,Y */ __IM uint32_t RESERVED; __IOM uint32_t LCDC_FRONTPORCHXY_REG; /*!< (@ 0x00000014) Front Porch X and Y */ __IOM uint32_t LCDC_BLANKINGXY_REG; /*!< (@ 0x00000018) Blanking X and Y */ __IOM uint32_t LCDC_BACKPORCHXY_REG; /*!< (@ 0x0000001C) Back Porch X and Y */ __IM uint32_t RESERVED1[2]; __IOM uint32_t LCDC_DBIB_CFG_REG; /*!< (@ 0x00000028) MIPI Config Register */ __IOM uint32_t LCDC_GPIO_REG; /*!< (@ 0x0000002C) General Purpose IO (2-bits) */ __IOM uint32_t LCDC_LAYER0_MODE_REG; /*!< (@ 0x00000030) Layer0 Mode */ __IOM uint32_t LCDC_LAYER0_STARTXY_REG; /*!< (@ 0x00000034) Layer0 Start XY */ __IOM uint32_t LCDC_LAYER0_SIZEXY_REG; /*!< (@ 0x00000038) Layer0 Size XY */ __IOM uint32_t LCDC_LAYER0_BASEADDR_REG; /*!< (@ 0x0000003C) Layer0 Base Addr */ __IOM uint32_t LCDC_LAYER0_STRIDE_REG; /*!< (@ 0x00000040) Layer0 Stride */ __IOM uint32_t LCDC_LAYER0_RESXY_REG; /*!< (@ 0x00000044) Layer0 Res XY */ __IM uint32_t RESERVED2[18]; __IOM uint32_t LCDC_JDI_RESXY_REG; /*!< (@ 0x00000090) Resolution XY for the JDI parallel I/F */ __IOM uint32_t LCDC_JDI_FBX_BLANKING_REG; /*!< (@ 0x00000094) Horizontal front/back blanking (hck half periods) */ __IOM uint32_t LCDC_JDI_FBY_BLANKING_REG; /*!< (@ 0x00000098) Vertical front/back blanking (vck half periods) */ __IOM uint32_t LCDC_JDI_HCK_WIDTH_REG; /*!< (@ 0x0000009C) HCK high/low width */ __IOM uint32_t LCDC_JDI_XRST_WIDTH_REG; /*!< (@ 0x000000A0) XRST width */ __IOM uint32_t LCDC_JDI_VST_DELAY_REG; /*!< (@ 0x000000A4) XRST-to-VST delay */ __IOM uint32_t LCDC_JDI_VST_WIDTH_REG; /*!< (@ 0x000000A8) VST width */ __IOM uint32_t LCDC_JDI_VCK_DELAY_REG; /*!< (@ 0x000000AC) XRST-to-VCK delay */ __IOM uint32_t LCDC_JDI_HST_DELAY_REG; /*!< (@ 0x000000B0) VCK-to-HST delay */ __IOM uint32_t LCDC_JDI_HST_WIDTH_REG; /*!< (@ 0x000000B4) HST width */ __IOM uint32_t LCDC_JDI_ENB_START_HLINE_REG; /*!< (@ 0x000000B8) ENB start horizontal line */ __IOM uint32_t LCDC_JDI_ENB_END_HLINE_REG; /*!< (@ 0x000000BC) ENB end horizontal line */ __IOM uint32_t LCDC_JDI_ENB_START_CLK_REG; /*!< (@ 0x000000C0) ENB start delay */ __IOM uint32_t LCDC_JDI_ENB_WIDTH_CLK_REG; /*!< (@ 0x000000C4) ENB width */ __IM uint32_t RESERVED3[8]; __IOM uint32_t LCDC_DBIB_CMD_REG; /*!< (@ 0x000000E8) MIPI DBIB Command Register */ __IM uint32_t RESERVED4[2]; __IOM uint32_t LCDC_IDREG_REG; /*!< (@ 0x000000F4) Identification Register */ __IOM uint32_t LCDC_INTERRUPT_REG; /*!< (@ 0x000000F8) Interrupt Register */ __IOM uint32_t LCDC_STATUS_REG; /*!< (@ 0x000000FC) Status Register */ __IM uint32_t RESERVED5[33]; __IOM uint32_t LCDC_CRC_REG; /*!< (@ 0x00000184) CRC check */ __IOM uint32_t LCDC_LAYER0_OFFSETX_REG; /*!< (@ 0x00000188) Layer0 OffsetX and DMA prefetch */ } LCDC_Type; /*!< Size = 396 (0x18c) */ /* =========================================================================================================================== */ /* ================ LRA ================ */ /* =========================================================================================================================== */ /** * @brief LRA registers (LRA) */ typedef struct { /*!< (@ 0x50030A00) LRA Structure */ __IOM uint32_t LRA_CTRL1_REG; /*!< (@ 0x00000000) General Purpose LRA Control Register */ __IOM uint32_t LRA_CTRL2_REG; /*!< (@ 0x00000004) General Purpose LRA Control Register */ __IOM uint32_t LRA_CTRL3_REG; /*!< (@ 0x00000008) General Purpose LRA Control Register */ __IOM uint32_t LRA_FLT_SMP1_REG; /*!< (@ 0x0000000C) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP2_REG; /*!< (@ 0x00000010) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP3_REG; /*!< (@ 0x00000014) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP4_REG; /*!< (@ 0x00000018) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP5_REG; /*!< (@ 0x0000001C) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP6_REG; /*!< (@ 0x00000020) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP7_REG; /*!< (@ 0x00000024) LRA Sample Register */ __IOM uint32_t LRA_FLT_SMP8_REG; /*!< (@ 0x00000028) LRA Sample Register */ __IOM uint32_t LRA_FLT_COEF1_REG; /*!< (@ 0x0000002C) LRA Filter Coefficient Register */ __IOM uint32_t LRA_FLT_COEF2_REG; /*!< (@ 0x00000030) LRA Filter Coefficient Register */ __IOM uint32_t LRA_FLT_COEF3_REG; /*!< (@ 0x00000034) LRA Filter Coefficient Register */ __IOM uint32_t LRA_BRD_LS_REG; /*!< (@ 0x00000038) LRA Bridge Register */ __IOM uint32_t LRA_BRD_HS_REG; /*!< (@ 0x0000003C) LRA Bridge Register */ __IOM uint32_t LRA_BRD_STAT_REG; /*!< (@ 0x00000040) LRA Bridge Status Register */ __IOM uint32_t LRA_ADC_CTRL1_REG; /*!< (@ 0x00000044) General Purpose ADC Control Register */ __IM uint32_t RESERVED[2]; __IOM uint32_t LRA_ADC_RESULT_REG; /*!< (@ 0x00000050) General Purpose ADC Result Register */ __IOM uint32_t LRA_LDO_REG; /*!< (@ 0x00000054) LRA LDO Register */ __IOM uint32_t LRA_DFT_REG; /*!< (@ 0x00000058) LRA test Register */ } LRA_Type; /*!< Size = 92 (0x5c) */ /* =========================================================================================================================== */ /* ================ MEMCTRL ================ */ /* =========================================================================================================================== */ /** * @brief MEMCTRL registers (MEMCTRL) */ typedef struct { /*!< (@ 0x50050000) MEMCTRL Structure */ __IM uint32_t RESERVED; __IOM uint32_t MEM_PRIO_REG; /*!< (@ 0x00000004) Priority Control Register */ __IOM uint32_t MEM_STALL_REG; /*!< (@ 0x00000008) Maximum Stall cycles Control Register */ __IOM uint32_t MEM_STATUS_REG; /*!< (@ 0x0000000C) Memory Arbiter Status Register */ __IOM uint32_t MEM_STATUS2_REG; /*!< (@ 0x00000010) RAM cells Status Register */ __IM uint32_t RESERVED1[3]; __IOM uint32_t CMI_CODE_BASE_REG; /*!< (@ 0x00000020) CMAC code Base Address Register */ __IOM uint32_t CMI_DATA_BASE_REG; /*!< (@ 0x00000024) CMAC data Base Address Register */ __IOM uint32_t CMI_SHARED_BASE_REG; /*!< (@ 0x00000028) CMAC shared data Base Address Register */ __IOM uint32_t CMI_END_REG; /*!< (@ 0x0000002C) CMAC end Address Register */ __IOM uint32_t SNC_BASE_REG; /*!< (@ 0x00000030) Sensor Node Controller Base Address Register */ __IM uint32_t RESERVED2[16]; __IOM uint32_t BUSY_SET_REG; /*!< (@ 0x00000074) BSR Set Register */ __IOM uint32_t BUSY_RESET_REG; /*!< (@ 0x00000078) BSR Reset Register */ __IOM uint32_t BUSY_STAT_REG; /*!< (@ 0x0000007C) BSR Status Register */ } MEMCTRL_Type; /*!< Size = 128 (0x80) */ /* =========================================================================================================================== */ /* ================ OTPC ================ */ /* =========================================================================================================================== */ /** * @brief OTPC registers (OTPC) */ typedef struct { /*!< (@ 0x30070000) OTPC Structure */ __IOM uint32_t OTPC_MODE_REG; /*!< (@ 0x00000000) Mode register */ __IOM uint32_t OTPC_STAT_REG; /*!< (@ 0x00000004) Status register */ __IOM uint32_t OTPC_PADDR_REG; /*!< (@ 0x00000008) The address of the word that will be programmed, when the PROG mode is used. */ __IOM uint32_t OTPC_PWORD_REG; /*!< (@ 0x0000000C) The 32-bit word that will be programmed, when the PROG mode is used. */ __IOM uint32_t OTPC_TIM1_REG; /*!< (@ 0x00000010) Various timing parameters of the OTP cell. */ __IOM uint32_t OTPC_TIM2_REG; /*!< (@ 0x00000014) Various timing parameters of the OTP cell. */ } OTPC_Type; /*!< Size = 24 (0x18) */ /* =========================================================================================================================== */ /* ================ PDC ================ */ /* =========================================================================================================================== */ /** * @brief PDC registers (PDC) */ typedef struct { /*!< (@ 0x50000200) PDC Structure */ __IOM uint32_t PDC_CTRL0_REG; /*!< (@ 0x00000000) PDC control register */ __IOM uint32_t PDC_CTRL1_REG; /*!< (@ 0x00000004) PDC control register */ __IOM uint32_t PDC_CTRL2_REG; /*!< (@ 0x00000008) PDC control register */ __IOM uint32_t PDC_CTRL3_REG; /*!< (@ 0x0000000C) PDC control register */ __IOM uint32_t PDC_CTRL4_REG; /*!< (@ 0x00000010) PDC control register */ __IOM uint32_t PDC_CTRL5_REG; /*!< (@ 0x00000014) PDC control register */ __IOM uint32_t PDC_CTRL6_REG; /*!< (@ 0x00000018) PDC control register */ __IOM uint32_t PDC_CTRL7_REG; /*!< (@ 0x0000001C) PDC control register */ __IOM uint32_t PDC_CTRL8_REG; /*!< (@ 0x00000020) PDC control register */ __IOM uint32_t PDC_CTRL9_REG; /*!< (@ 0x00000024) PDC control register */ __IOM uint32_t PDC_CTRL10_REG; /*!< (@ 0x00000028) PDC control register */ __IOM uint32_t PDC_CTRL11_REG; /*!< (@ 0x0000002C) PDC control register */ __IOM uint32_t PDC_CTRL12_REG; /*!< (@ 0x00000030) PDC control register */ __IOM uint32_t PDC_CTRL13_REG; /*!< (@ 0x00000034) PDC control register */ __IOM uint32_t PDC_CTRL14_REG; /*!< (@ 0x00000038) PDC control register */ __IOM uint32_t PDC_CTRL15_REG; /*!< (@ 0x0000003C) PDC control register */ __IM uint32_t RESERVED[16]; __IOM uint32_t PDC_ACKNOWLEDGE_REG; /*!< (@ 0x00000080) Clear a pending PDC bit */ __IOM uint32_t PDC_PENDING_REG; /*!< (@ 0x00000084) Shows any pending wakeup event */ __IOM uint32_t PDC_PENDING_SNC_REG; /*!< (@ 0x00000088) Shows any pending IRQ to SNC */ __IOM uint32_t PDC_PENDING_CM33_REG; /*!< (@ 0x0000008C) Shows any pending IRQ to CM33 */ __IOM uint32_t PDC_PENDING_CMAC_REG; /*!< (@ 0x00000090) Shows any pending IRQ to CM33 */ __IOM uint32_t PDC_SET_PENDING_REG; /*!< (@ 0x00000094) Set a pending PDC bit */ } PDC_Type; /*!< Size = 152 (0x98) */ /* =========================================================================================================================== */ /* ================ PWMLED ================ */ /* =========================================================================================================================== */ /** * @brief PWMLED registers (PWMLED) */ typedef struct { /*!< (@ 0x50030500) PWMLED Structure */ __IOM uint32_t PWMLED_DUTY_CYCLE_LED1_REG; /*!< (@ 0x00000000) Defines duty cycle for PWM1 */ __IOM uint32_t PWMLED_DUTY_CYCLE_LED2_REG; /*!< (@ 0x00000004) Defines duty cycle for PWM2 */ __IOM uint32_t PWMLED_FREQUENCY_REG; /*!< (@ 0x00000008) Defines the PWM frequecny */ __IOM uint32_t PWMLED_CTRL_REG; /*!< (@ 0x0000000C) PWM Control register */ } PWMLED_Type; /*!< Size = 16 (0x10) */ /* =========================================================================================================================== */ /* ================ QSPIC ================ */ /* =========================================================================================================================== */ /** * @brief QSPIC registers (QSPIC) */ typedef struct { /*!< (@ 0x38000000) QSPIC Structure */ __IOM uint32_t QSPIC_CTRLBUS_REG; /*!< (@ 0x00000000) SPI Bus control register for the Manual mode */ __IOM uint32_t QSPIC_CTRLMODE_REG; /*!< (@ 0x00000004) Mode Control register */ __IOM uint32_t QSPIC_RECVDATA_REG; /*!< (@ 0x00000008) Received data for the Manual mode */ __IOM uint32_t QSPIC_BURSTCMDA_REG; /*!< (@ 0x0000000C) The way of reading in Auto mode (command register A) */ __IOM uint32_t QSPIC_BURSTCMDB_REG; /*!< (@ 0x00000010) The way of reading in Auto mode (command register B) */ __IOM uint32_t QSPIC_STATUS_REG; /*!< (@ 0x00000014) The status register of the QSPI controller */ __IOM uint32_t QSPIC_WRITEDATA_REG; /*!< (@ 0x00000018) Write data to SPI Bus for the Manual mode */ __IOM uint32_t QSPIC_READDATA_REG; /*!< (@ 0x0000001C) Read data from SPI Bus for the Manual mode */ __IOM uint32_t QSPIC_DUMMYDATA_REG; /*!< (@ 0x00000020) Send dummy clocks to SPI Bus for the Manual mode */ __IOM uint32_t QSPIC_ERASECTRL_REG; /*!< (@ 0x00000024) QSPI Erase control register */ __IOM uint32_t QSPIC_ERASECMDA_REG; /*!< (@ 0x00000028) The way of erasing in Auto mode (command register A) */ __IOM uint32_t QSPIC_ERASECMDB_REG; /*!< (@ 0x0000002C) The way of erasing in Auto mode (command register B) */ __IOM uint32_t QSPIC_BURSTBRK_REG; /*!< (@ 0x00000030) Read break sequence in Auto mode */ __IOM uint32_t QSPIC_STATUSCMD_REG; /*!< (@ 0x00000034) The way of reading the status of external device in Auto mode */ __IOM uint32_t QSPIC_CHCKERASE_REG; /*!< (@ 0x00000038) Check erase progress in Auto mode */ __IOM uint32_t QSPIC_GP_REG; /*!< (@ 0x0000003C) QSPI General Purpose control register */ __IOM uint32_t QSPIC_UCODE_START; /*!< (@ 0x00000040) QSPIC uCode memory */ __IM uint32_t RESERVED[15]; __IOM uint32_t QSPIC_CTR_CTRL_REG; /*!< (@ 0x00000080) Control register for the decryption engine of the QSPIC */ __IOM uint32_t QSPIC_CTR_SADDR_REG; /*!< (@ 0x00000084) Start address of the encrypted content in the QSPI flash */ __IOM uint32_t QSPIC_CTR_EADDR_REG; /*!< (@ 0x00000088) End address of the encrypted content in the QSPI flash */ __IOM uint32_t QSPIC_CTR_NONCE_0_3_REG; /*!< (@ 0x0000008C) Nonce bytes 0 to 3 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_NONCE_4_7_REG; /*!< (@ 0x00000090) Nonce bytes 4 to 7 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_0_3_REG; /*!< (@ 0x00000094) Key bytes 0 to 3 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_4_7_REG; /*!< (@ 0x00000098) Key bytes 4 to 7 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_8_11_REG; /*!< (@ 0x0000009C) Key bytes 8 to 11 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_12_15_REG; /*!< (@ 0x000000A0) Key bytes 12 to 15 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_16_19_REG; /*!< (@ 0x000000A4) Key bytes 16 to 19 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_20_23_REG; /*!< (@ 0x000000A8) Key bytes 20 to 23 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_24_27_REG; /*!< (@ 0x000000AC) Key bytes 24 to 27 for the AES-CTR algorithm */ __IOM uint32_t QSPIC_CTR_KEY_28_31_REG; /*!< (@ 0x000000B0) Key bytes 28 to 31 for the AES-CTR algorithm */ } QSPIC_Type; /*!< Size = 180 (0xb4) */ /* =========================================================================================================================== */ /* ================ QSPIC2 ================ */ /* =========================================================================================================================== */ /** * @brief QSPIC2 registers (QSPIC2) */ typedef struct { /*!< (@ 0x34000000) QSPIC2 Structure */ __IOM uint32_t QSPIC2_CTRLBUS_REG; /*!< (@ 0x00000000) SPI Bus control register for the Manual mode */ __IOM uint32_t QSPIC2_CTRLMODE_REG; /*!< (@ 0x00000004) Mode control register */ __IOM uint32_t QSPIC2_RECVDATA_REG; /*!< (@ 0x00000008) Received data for the Manual mode */ __IOM uint32_t QSPIC2_BURSTCMDA_REG; /*!< (@ 0x0000000C) The way of reading in Auto mode (command register A) */ __IOM uint32_t QSPIC2_BURSTCMDB_REG; /*!< (@ 0x00000010) The way of reading in Auto mode (command register B) */ __IOM uint32_t QSPIC2_STATUS_REG; /*!< (@ 0x00000014) The status register of the QSPI controller */ __IOM uint32_t QSPIC2_WRITEDATA_REG; /*!< (@ 0x00000018) Write data to SPI Bus for the Manual mode */ __IOM uint32_t QSPIC2_READDATA_REG; /*!< (@ 0x0000001C) Read data from SPI Bus for the Manual mode */ __IOM uint32_t QSPIC2_DUMMYDATA_REG; /*!< (@ 0x00000020) Send dummy clocks to SPI Bus for the Manual mode */ __IOM uint32_t QSPIC2_ERASECTRL_REG; /*!< (@ 0x00000024) Erase control register */ __IOM uint32_t QSPIC2_ERASECMDA_REG; /*!< (@ 0x00000028) The way of erasing in Auto mode (command register A) */ __IOM uint32_t QSPIC2_ERASECMDB_REG; /*!< (@ 0x0000002C) The way of erasing in Auto mode (command register B) */ __IOM uint32_t QSPIC2_BURSTBRK_REG; /*!< (@ 0x00000030) Read break sequence in Auto mode */ __IOM uint32_t QSPIC2_STATUSCMD_REG; /*!< (@ 0x00000034) The way of reading the status of external device in Auto mode */ __IOM uint32_t QSPIC2_CHCKERASE_REG; /*!< (@ 0x00000038) Check erase progress in Auto mode */ __IOM uint32_t QSPIC2_GP_REG; /*!< (@ 0x0000003C) General purpose QSPIC2 register */ __IOM uint32_t QSPIC2_AWRITECMD_REG; /*!< (@ 0x00000040) The way of writing in Auto mode when the external device is a serial SRAM */ __IOM uint32_t QSPIC2_MEMBLEN_REG; /*!< (@ 0x00000044) External memory burst length configuration */ } QSPIC2_Type; /*!< Size = 72 (0x48) */ /* =========================================================================================================================== */ /* ================ RFMON ================ */ /* =========================================================================================================================== */ /** * @brief RFMON registers (RFMON) */ typedef struct { /*!< (@ 0x50040600) RFMON Structure */ __IOM uint32_t RFMON_CTRL_REG; /*!< (@ 0x00000000) Control register */ __IOM uint32_t RFMON_ADDR_REG; /*!< (@ 0x00000004) AHB master start address */ __IOM uint32_t RFMON_LEN_REG; /*!< (@ 0x00000008) Data length register */ __IOM uint32_t RFMON_STAT_REG; /*!< (@ 0x0000000C) Status register */ __IOM uint32_t RFMON_CRV_ADDR_REG; /*!< (@ 0x00000010) AHB master current address */ __IOM uint32_t RFMON_CRV_LEN_REG; /*!< (@ 0x00000014) The remaining data to be transferred */ } RFMON_Type; /*!< Size = 24 (0x18) */ /* =========================================================================================================================== */ /* ================ RTC ================ */ /* =========================================================================================================================== */ /** * @brief RTC registers (RTC) */ typedef struct { /*!< (@ 0x50000400) RTC Structure */ __IOM uint32_t RTC_CONTROL_REG; /*!< (@ 0x00000000) RTC Control Register */ __IOM uint32_t RTC_HOUR_MODE_REG; /*!< (@ 0x00000004) RTC Hour Mode Register */ __IOM uint32_t RTC_TIME_REG; /*!< (@ 0x00000008) RTC Time Register */ __IOM uint32_t RTC_CALENDAR_REG; /*!< (@ 0x0000000C) RTC Calendar Register */ __IOM uint32_t RTC_TIME_ALARM_REG; /*!< (@ 0x00000010) RTC Time Alarm Register */ __IOM uint32_t RTC_CALENDAR_ALARM_REG; /*!< (@ 0x00000014) RTC Calendar Alram Register */ __IOM uint32_t RTC_ALARM_ENABLE_REG; /*!< (@ 0x00000018) RTC Alarm Enable Register */ __IOM uint32_t RTC_EVENT_FLAGS_REG; /*!< (@ 0x0000001C) RTC Event Flags Register */ __IOM uint32_t RTC_INTERRUPT_ENABLE_REG; /*!< (@ 0x00000020) RTC Interrupt Enable Register */ __IOM uint32_t RTC_INTERRUPT_DISABLE_REG; /*!< (@ 0x00000024) RTC Interrupt Disable Register */ __IOM uint32_t RTC_INTERRUPT_MASK_REG; /*!< (@ 0x00000028) RTC Interrupt Mask Register */ __IOM uint32_t RTC_STATUS_REG; /*!< (@ 0x0000002C) RTC Status Register */ __IOM uint32_t RTC_KEEP_RTC_REG; /*!< (@ 0x00000030) RTC Keep RTC Register */ __IM uint32_t RESERVED[19]; __IOM uint32_t RTC_EVENT_CTRL_REG; /*!< (@ 0x00000080) RTC Event Control Register */ __IOM uint32_t RTC_MOTOR_EVENT_PERIOD_REG; /*!< (@ 0x00000084) RTC Motor Event Period Register */ __IOM uint32_t RTC_PDC_EVENT_PERIOD_REG; /*!< (@ 0x00000088) RTC PDC Event Period Register */ __IOM uint32_t RTC_PDC_EVENT_CLEAR_REG; /*!< (@ 0x0000008C) RTC PDC Event Clear Register */ __IOM uint32_t RTC_MOTOR_EVENT_CNT_REG; /*!< (@ 0x00000090) RTC Motor Event Counter Register */ __IOM uint32_t RTC_PDC_EVENT_CNT_REG; /*!< (@ 0x00000094) RTC PDC Event Counter Register */ } RTC_Type; /*!< Size = 152 (0x98) */ /* =========================================================================================================================== */ /* ================ SDADC ================ */ /* =========================================================================================================================== */ /** * @brief SDADC registers (SDADC) */ typedef struct { /*!< (@ 0x50020800) SDADC Structure */ __IOM uint32_t SDADC_CTRL_REG; /*!< (@ 0x00000000) Sigma Delta ADC Control Register */ __IM uint32_t RESERVED; __IOM uint32_t SDADC_TEST_REG; /*!< (@ 0x00000008) Sigma Delta ADC Test Register */ __IOM uint32_t SDADC_GAIN_CORR_REG; /*!< (@ 0x0000000C) Sigma Delta ADC Gain Correction Register */ __IOM uint32_t SDADC_OFFS_CORR_REG; /*!< (@ 0x00000010) Sigma Delta ADC Offset Correction Register */ __IOM uint32_t SDADC_CLEAR_INT_REG; /*!< (@ 0x00000014) Sigma Delta ADC Clear Interrupt Register */ __IOM uint32_t SDADC_RESULT_REG; /*!< (@ 0x00000018) Sigma Delta ADC Result Register */ } SDADC_Type; /*!< Size = 28 (0x1c) */ /* =========================================================================================================================== */ /* ================ SMOTOR ================ */ /* =========================================================================================================================== */ /** * @brief SMOTOR registers (SMOTOR) */ typedef struct { /*!< (@ 0x50030E00) SMOTOR Structure */ __IOM uint32_t SMOTOR_CTRL_REG; /*!< (@ 0x00000000) Motor control register */ __IOM uint32_t PG0_CTRL_REG; /*!< (@ 0x00000004) Pattern generator 0 control register */ __IOM uint32_t PG1_CTRL_REG; /*!< (@ 0x00000008) Pattern generator 1 control register */ __IOM uint32_t PG2_CTRL_REG; /*!< (@ 0x0000000C) Pattern generator 2 control register */ __IOM uint32_t PG3_CTRL_REG; /*!< (@ 0x00000010) Pattern generator 3 control register */ __IOM uint32_t PG4_CTRL_REG; /*!< (@ 0x00000014) Pattern generator 4 control register */ __IOM uint32_t SMOTOR_TRIGGER_REG; /*!< (@ 0x00000018) Motor controller trigger register */ __IM uint32_t RESERVED; __IOM uint32_t SMOTOR_CMD_FIFO_REG; /*!< (@ 0x00000020) Motor control command FIFO register */ __IOM uint32_t SMOTOR_CMD_READ_PTR_REG; /*!< (@ 0x00000024) Command read pointer register */ __IOM uint32_t SMOTOR_CMD_WRITE_PTR_REG; /*!< (@ 0x00000028) Command write pointer register */ __IOM uint32_t SMOTOR_STATUS_REG; /*!< (@ 0x0000002C) Motor controller status register */ __IOM uint32_t SMOTOR_IRQ_CLEAR_REG; /*!< (@ 0x00000030) Motor control IRQ clear register */ __IM uint32_t RESERVED1[3]; __IOM uint32_t WAVETABLE_BASE; /*!< (@ 0x00000040) Base address of the wavetable */ __IM uint32_t RESERVED2[15]; __IOM uint32_t CMD_TABLE_BASE; /*!< (@ 0x00000080) Base address of the command table */ } SMOTOR_Type; /*!< Size = 132 (0x84) */ /* =========================================================================================================================== */ /* ================ SNC ================ */ /* =========================================================================================================================== */ /** * @brief SNC registers (SNC) */ typedef struct { /*!< (@ 0x50020C00) SNC Structure */ __IOM uint32_t SNC_CTRL_REG; /*!< (@ 0x00000000) Sensor Node Control Register */ __IOM uint32_t SNC_STATUS_REG; /*!< (@ 0x00000004) Sensor Node Status Register */ __IOM uint32_t SNC_LP_TIMER_REG; /*!< (@ 0x00000008) Sensor Node Low-Power Timer Register */ __IOM uint32_t SNC_PC_REG; /*!< (@ 0x0000000C) Sensor Node Program Counter */ __IOM uint32_t SNC_R1_REG; /*!< (@ 0x00000010) Sensor Node core - Operand 1 Register */ __IOM uint32_t SNC_R2_REG; /*!< (@ 0x00000014) Sensor Node core - Operand 2 Register */ __IOM uint32_t SNC_TMP1_REG; /*!< (@ 0x00000018) Sensor Node core - Temporary Register 1 */ __IOM uint32_t SNC_TMP2_REG; /*!< (@ 0x0000001C) Sensor Node core - Temporary Register 2 */ } SNC_Type; /*!< Size = 32 (0x20) */ /* =========================================================================================================================== */ /* ================ SPI ================ */ /* =========================================================================================================================== */ /** * @brief SPI registers (SPI) */ typedef struct { /*!< (@ 0x50020300) SPI Structure */ __IOM uint32_t SPI_CTRL_REG; /*!< (@ 0x00000000) SPI control register 0 */ __IOM uint32_t SPI_RX_TX_REG; /*!< (@ 0x00000004) SPI RX/TX register0 */ __IOM uint32_t SPI_CLEAR_INT_REG; /*!< (@ 0x00000008) SPI clear interrupt register */ } SPI_Type; /*!< Size = 12 (0xc) */ /* =========================================================================================================================== */ /* ================ SPI2 ================ */ /* =========================================================================================================================== */ /** * @brief SPI2 registers (SPI2) */ typedef struct { /*!< (@ 0x50020400) SPI2 Structure */ __IOM uint32_t SPI2_CTRL_REG; /*!< (@ 0x00000000) SPI control register 0 */ __IOM uint32_t SPI2_RX_TX_REG; /*!< (@ 0x00000004) SPI RX/TX register0 */ __IOM uint32_t SPI2_CLEAR_INT_REG; /*!< (@ 0x00000008) SPI clear interrupt register */ } SPI2_Type; /*!< Size = 12 (0xc) */ /* =========================================================================================================================== */ /* ================ SYS_WDOG ================ */ /* =========================================================================================================================== */ /** * @brief SYS_WDOG registers (SYS_WDOG) */ typedef struct { /*!< (@ 0x50000700) SYS_WDOG Structure */ __IOM uint32_t WATCHDOG_REG; /*!< (@ 0x00000000) Watchdog timer register. */ __IOM uint32_t WATCHDOG_CTRL_REG; /*!< (@ 0x00000004) Watchdog control register. */ } SYS_WDOG_Type; /*!< Size = 8 (0x8) */ /* =========================================================================================================================== */ /* ================ TIMER ================ */ /* =========================================================================================================================== */ /** * @brief TIMER registers (TIMER) */ typedef struct { /*!< (@ 0x50010200) TIMER Structure */ __IOM uint32_t TIMER_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ __IOM uint32_t TIMER_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ __IOM uint32_t TIMER_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ __IOM uint32_t TIMER_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ __IOM uint32_t TIMER_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ __IOM uint32_t TIMER_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ __IOM uint32_t TIMER_SHOTWIDTH_REG; /*!< (@ 0x00000018) Timer Shot duration in shot mode */ __IOM uint32_t TIMER_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ __IOM uint32_t TIMER_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ __IOM uint32_t TIMER_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ __IOM uint32_t TIMER_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ __IOM uint32_t TIMER_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ __IOM uint32_t TIMER_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ __IOM uint32_t TIMER_GPIO3_CONF_REG; /*!< (@ 0x00000034) Timer gpio3 selection */ __IOM uint32_t TIMER_GPIO4_CONF_REG; /*!< (@ 0x00000038) Timer gpio4 selection */ __IOM uint32_t TIMER_CAPTURE_GPIO3_REG; /*!< (@ 0x0000003C) Timer value for event on GPIO1 */ __IOM uint32_t TIMER_CAPTURE_GPIO4_REG; /*!< (@ 0x00000040) Timer value for event on GPIO1 */ __IOM uint32_t TIMER_CLEAR_GPIO_EVENT_REG; /*!< (@ 0x00000044) Timer clear gpio event register */ __IOM uint32_t TIMER_CLEAR_IRQ_REG; /*!< (@ 0x00000048) Timer clear interrupt */ } TIMER_Type; /*!< Size = 76 (0x4c) */ /* =========================================================================================================================== */ /* ================ TIMER2 ================ */ /* =========================================================================================================================== */ /** * @brief TIMER2 registers (TIMER2) */ typedef struct { /*!< (@ 0x50010300) TIMER2 Structure */ __IOM uint32_t TIMER2_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ __IOM uint32_t TIMER2_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ __IOM uint32_t TIMER2_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ __IOM uint32_t TIMER2_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ __IOM uint32_t TIMER2_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ __IOM uint32_t TIMER2_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ __IOM uint32_t TIMER2_SHOTWIDTH_REG; /*!< (@ 0x00000018) Timer Shot duration in shot mode */ __IOM uint32_t TIMER2_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ __IOM uint32_t TIMER2_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ __IOM uint32_t TIMER2_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ __IOM uint32_t TIMER2_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ __IOM uint32_t TIMER2_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ __IOM uint32_t TIMER2_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ __IOM uint32_t TIMER2_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ } TIMER2_Type; /*!< Size = 56 (0x38) */ /* =========================================================================================================================== */ /* ================ TIMER3 ================ */ /* =========================================================================================================================== */ /** * @brief TIMER3 registers (TIMER3) */ typedef struct { /*!< (@ 0x50040A00) TIMER3 Structure */ __IOM uint32_t TIMER3_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ __IOM uint32_t TIMER3_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ __IOM uint32_t TIMER3_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ __IOM uint32_t TIMER3_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ __IOM uint32_t TIMER3_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ __IOM uint32_t TIMER3_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ __IM uint32_t RESERVED; __IOM uint32_t TIMER3_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ __IOM uint32_t TIMER3_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ __IOM uint32_t TIMER3_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ __IOM uint32_t TIMER3_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ __IOM uint32_t TIMER3_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ __IOM uint32_t TIMER3_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ __IOM uint32_t TIMER3_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ } TIMER3_Type; /*!< Size = 56 (0x38) */ /* =========================================================================================================================== */ /* ================ TIMER4 ================ */ /* =========================================================================================================================== */ /** * @brief TIMER4 registers (TIMER4) */ typedef struct { /*!< (@ 0x50040B00) TIMER4 Structure */ __IOM uint32_t TIMER4_CTRL_REG; /*!< (@ 0x00000000) Timer control register */ __IOM uint32_t TIMER4_TIMER_VAL_REG; /*!< (@ 0x00000004) Timer counter value */ __IOM uint32_t TIMER4_STATUS_REG; /*!< (@ 0x00000008) Timer status register */ __IOM uint32_t TIMER4_GPIO1_CONF_REG; /*!< (@ 0x0000000C) Timer gpio1 selection */ __IOM uint32_t TIMER4_GPIO2_CONF_REG; /*!< (@ 0x00000010) Timer gpio2 selection */ __IOM uint32_t TIMER4_RELOAD_REG; /*!< (@ 0x00000014) Timer reload value and Delay in shot mode */ __IM uint32_t RESERVED; __IOM uint32_t TIMER4_PRESCALER_REG; /*!< (@ 0x0000001C) Timer prescaler value */ __IOM uint32_t TIMER4_CAPTURE_GPIO1_REG; /*!< (@ 0x00000020) Timer value for event on GPIO1 */ __IOM uint32_t TIMER4_CAPTURE_GPIO2_REG; /*!< (@ 0x00000024) Timer value for event on GPIO2 */ __IOM uint32_t TIMER4_PRESCALER_VAL_REG; /*!< (@ 0x00000028) Timer prescaler counter valuew */ __IOM uint32_t TIMER4_PWM_FREQ_REG; /*!< (@ 0x0000002C) Timer pwm frequency register */ __IOM uint32_t TIMER4_PWM_DC_REG; /*!< (@ 0x00000030) Timer pwm dc register */ __IOM uint32_t TIMER4_CLEAR_IRQ_REG; /*!< (@ 0x00000034) Timer clear interrupt */ } TIMER4_Type; /*!< Size = 56 (0x38) */ /* =========================================================================================================================== */ /* ================ TRNG ================ */ /* =========================================================================================================================== */ /** * @brief TRNG registers (TRNG) */ typedef struct { /*!< (@ 0x50040C00) TRNG Structure */ __IOM uint32_t TRNG_CTRL_REG; /*!< (@ 0x00000000) TRNG control register */ __IOM uint32_t TRNG_FIFOLVL_REG; /*!< (@ 0x00000004) TRNG FIFO level register */ __IOM uint32_t TRNG_VER_REG; /*!< (@ 0x00000008) TRNG Version register */ } TRNG_Type; /*!< Size = 12 (0xc) */ /* =========================================================================================================================== */ /* ================ UART ================ */ /* =========================================================================================================================== */ /** * @brief UART registers (UART) */ typedef struct { /*!< (@ 0x50020000) UART Structure */ __IOM uint32_t UART_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ __IOM uint32_t UART_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ __IOM uint32_t UART_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control Register */ __IOM uint32_t UART_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ __IOM uint32_t UART_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ __IOM uint32_t UART_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ __IM uint32_t RESERVED; __IOM uint32_t UART_SCR_REG; /*!< (@ 0x0000001C) Scratchpad Register */ __IM uint32_t RESERVED1[4]; __IOM uint32_t UART_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ __IM uint32_t RESERVED2[3]; __IOM uint32_t UART_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ __IOM uint32_t UART_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ __IOM uint32_t UART_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ __IOM uint32_t UART_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ __IM uint32_t RESERVED3; __IOM uint32_t UART_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ __IOM uint32_t UART_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ __IOM uint32_t UART_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ __IOM uint32_t UART_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ __IOM uint32_t UART_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ __IOM uint32_t UART_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ __IOM uint32_t UART_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ __IM uint32_t RESERVED4[5]; __IOM uint32_t UART_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ __IM uint32_t RESERVED5[13]; __IOM uint32_t UART_UCV_REG; /*!< (@ 0x000000F8) Component Version */ __IOM uint32_t UART_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ } UART_Type; /*!< Size = 256 (0x100) */ /* =========================================================================================================================== */ /* ================ UART2 ================ */ /* =========================================================================================================================== */ /** * @brief UART2 registers (UART2) */ typedef struct { /*!< (@ 0x50020100) UART2 Structure */ __IOM uint32_t UART2_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ __IOM uint32_t UART2_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ __IOM uint32_t UART2_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control Register */ __IOM uint32_t UART2_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ __IOM uint32_t UART2_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ __IOM uint32_t UART2_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ __IOM uint32_t UART2_MSR_REG; /*!< (@ 0x00000018) Modem Status Register */ __IOM uint32_t UART2_SCR_REG; /*!< (@ 0x0000001C) Scratchpad Register */ __IM uint32_t RESERVED[4]; __IOM uint32_t UART2_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART2_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ __IM uint32_t RESERVED1[3]; __IOM uint32_t UART2_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ __IOM uint32_t UART2_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ __IOM uint32_t UART2_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ __IOM uint32_t UART2_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ __IOM uint32_t UART2_SRTS_REG; /*!< (@ 0x0000008C) Shadow Request to Send */ __IOM uint32_t UART2_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ __IOM uint32_t UART2_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ __IOM uint32_t UART2_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ __IOM uint32_t UART2_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ __IOM uint32_t UART2_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ __IOM uint32_t UART2_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ __IOM uint32_t UART2_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ __IM uint32_t RESERVED2[5]; __IOM uint32_t UART2_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ __IOM uint32_t UART2_RAR_REG; /*!< (@ 0x000000C4) Receive Address Register */ __IOM uint32_t UART2_TAR_REG; /*!< (@ 0x000000C8) Transmit Address Register */ __IOM uint32_t UART2_LCR_EXT; /*!< (@ 0x000000CC) Line Extended Control Register */ __IM uint32_t RESERVED3[10]; __IOM uint32_t UART2_UCV_REG; /*!< (@ 0x000000F8) Component Version */ __IOM uint32_t UART2_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ } UART2_Type; /*!< Size = 256 (0x100) */ /* =========================================================================================================================== */ /* ================ UART3 ================ */ /* =========================================================================================================================== */ /** * @brief UART3 registers (UART3) */ typedef struct { /*!< (@ 0x50020200) UART3 Structure */ __IOM uint32_t UART3_RBR_THR_DLL_REG; /*!< (@ 0x00000000) Receive Buffer Register */ __IOM uint32_t UART3_IER_DLH_REG; /*!< (@ 0x00000004) Interrupt Enable Register */ __IOM uint32_t UART3_IIR_FCR_REG; /*!< (@ 0x00000008) Interrupt Identification Register/FIFO Control Register */ __IOM uint32_t UART3_LCR_REG; /*!< (@ 0x0000000C) Line Control Register */ __IOM uint32_t UART3_MCR_REG; /*!< (@ 0x00000010) Modem Control Register */ __IOM uint32_t UART3_LSR_REG; /*!< (@ 0x00000014) Line Status Register */ __IOM uint32_t UART3_MSR_REG; /*!< (@ 0x00000018) Modem Status Register */ __IOM uint32_t UART3_CONFIG_REG; /*!< (@ 0x0000001C) ISO7816 Config Register */ __IM uint32_t RESERVED[4]; __IOM uint32_t UART3_SRBR_STHR0_REG; /*!< (@ 0x00000030) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR1_REG; /*!< (@ 0x00000034) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR2_REG; /*!< (@ 0x00000038) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR3_REG; /*!< (@ 0x0000003C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR4_REG; /*!< (@ 0x00000040) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR5_REG; /*!< (@ 0x00000044) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR6_REG; /*!< (@ 0x00000048) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR7_REG; /*!< (@ 0x0000004C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR8_REG; /*!< (@ 0x00000050) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR9_REG; /*!< (@ 0x00000054) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR10_REG; /*!< (@ 0x00000058) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR11_REG; /*!< (@ 0x0000005C) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR12_REG; /*!< (@ 0x00000060) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR13_REG; /*!< (@ 0x00000064) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR14_REG; /*!< (@ 0x00000068) Shadow Receive/Transmit Buffer Register */ __IOM uint32_t UART3_SRBR_STHR15_REG; /*!< (@ 0x0000006C) Shadow Receive/Transmit Buffer Register */ __IM uint32_t RESERVED1[3]; __IOM uint32_t UART3_USR_REG; /*!< (@ 0x0000007C) UART Status register. */ __IOM uint32_t UART3_TFL_REG; /*!< (@ 0x00000080) Transmit FIFO Level */ __IOM uint32_t UART3_RFL_REG; /*!< (@ 0x00000084) Receive FIFO Level. */ __IOM uint32_t UART3_SRR_REG; /*!< (@ 0x00000088) Software Reset Register. */ __IOM uint32_t UART3_SRTS_REG; /*!< (@ 0x0000008C) Shadow Request to Send */ __IOM uint32_t UART3_SBCR_REG; /*!< (@ 0x00000090) Shadow Break Control Register */ __IOM uint32_t UART3_SDMAM_REG; /*!< (@ 0x00000094) Shadow DMA Mode */ __IOM uint32_t UART3_SFE_REG; /*!< (@ 0x00000098) Shadow FIFO Enable */ __IOM uint32_t UART3_SRT_REG; /*!< (@ 0x0000009C) Shadow RCVR Trigger */ __IOM uint32_t UART3_STET_REG; /*!< (@ 0x000000A0) Shadow TX Empty Trigger */ __IOM uint32_t UART3_HTX_REG; /*!< (@ 0x000000A4) Halt TX */ __IOM uint32_t UART3_DMASA_REG; /*!< (@ 0x000000A8) DMA Software Acknowledge */ __IM uint32_t RESERVED2[5]; __IOM uint32_t UART3_DLF_REG; /*!< (@ 0x000000C0) Divisor Latch Fraction Register */ __IOM uint32_t UART3_RAR_REG; /*!< (@ 0x000000C4) Receive Address Register */ __IOM uint32_t UART3_TAR_REG; /*!< (@ 0x000000C8) Transmit Address Register */ __IOM uint32_t UART3_LCR_EXT; /*!< (@ 0x000000CC) Line Extended Control Register */ __IM uint32_t RESERVED3[4]; __IOM uint32_t UART3_CTRL_REG; /*!< (@ 0x000000E0) ISO7816 Control Register */ __IOM uint32_t UART3_TIMER_REG; /*!< (@ 0x000000E4) ISO7816 Timer Register */ __IOM uint32_t UART3_ERR_CTRL_REG; /*!< (@ 0x000000E8) ISO7816 Error Signal Control Register */ __IOM uint32_t UART3_IRQ_STATUS_REG; /*!< (@ 0x000000EC) ISO7816 Interrupt Status Register */ __IM uint32_t RESERVED4[2]; __IOM uint32_t UART3_UCV_REG; /*!< (@ 0x000000F8) Component Version */ __IOM uint32_t UART3_CTR_REG; /*!< (@ 0x000000FC) Component Type Register */ } UART3_Type; /*!< Size = 256 (0x100) */ /* =========================================================================================================================== */ /* ================ USB ================ */ /* =========================================================================================================================== */ /** * @brief USB registers (USB) */ typedef struct { /*!< (@ 0x50040000) USB Structure */ __IOM uint32_t USB_MCTRL_REG; /*!< (@ 0x00000000) Main Control Register) */ __IOM uint32_t USB_XCVDIAG_REG; /*!< (@ 0x00000004) Transceiver diagnostic Register (for test purpose only) */ __IOM uint32_t USB_TCR_REG; /*!< (@ 0x00000008) Transceiver configuration Register */ __IOM uint32_t USB_UTR_REG; /*!< (@ 0x0000000C) USB test Register (for test purpose only) */ __IOM uint32_t USB_FAR_REG; /*!< (@ 0x00000010) Function Address Register */ __IOM uint32_t USB_NFSR_REG; /*!< (@ 0x00000014) Node Functional State Register */ __IOM uint32_t USB_MAEV_REG; /*!< (@ 0x00000018) Main Event Register */ __IOM uint32_t USB_MAMSK_REG; /*!< (@ 0x0000001C) Main Mask Register */ __IOM uint32_t USB_ALTEV_REG; /*!< (@ 0x00000020) Alternate Event Register */ __IOM uint32_t USB_ALTMSK_REG; /*!< (@ 0x00000024) Alternate Mask Register */ __IOM uint32_t USB_TXEV_REG; /*!< (@ 0x00000028) Transmit Event Register */ __IOM uint32_t USB_TXMSK_REG; /*!< (@ 0x0000002C) Transmit Mask Register */ __IOM uint32_t USB_RXEV_REG; /*!< (@ 0x00000030) Receive Event Register */ __IOM uint32_t USB_RXMSK_REG; /*!< (@ 0x00000034) Receive Mask Register */ __IOM uint32_t USB_NAKEV_REG; /*!< (@ 0x00000038) NAK Event Register */ __IOM uint32_t USB_NAKMSK_REG; /*!< (@ 0x0000003C) NAK Mask Register */ __IOM uint32_t USB_FWEV_REG; /*!< (@ 0x00000040) FIFO Warning Event Register */ __IOM uint32_t USB_FWMSK_REG; /*!< (@ 0x00000044) FIFO Warning Mask Register */ __IOM uint32_t USB_FNH_REG; /*!< (@ 0x00000048) Frame Number High Byte Register */ __IOM uint32_t USB_FNL_REG; /*!< (@ 0x0000004C) Frame Number Low Byte Register */ __IM uint32_t RESERVED[11]; __IOM uint32_t USB_UX20CDR_REG; /*!< (@ 0x0000007C) Transceiver 2.0 Configuration and Diagnostics Register(for test purpose only) */ __IOM uint32_t USB_EPC0_REG; /*!< (@ 0x00000080) Endpoint Control 0 Register */ __IOM uint32_t USB_TXD0_REG; /*!< (@ 0x00000084) Transmit Data 0 Register */ __IOM uint32_t USB_TXS0_REG; /*!< (@ 0x00000088) Transmit Status 0 Register */ __IOM uint32_t USB_TXC0_REG; /*!< (@ 0x0000008C) Transmit command 0 Register */ __IOM uint32_t USB_EP0_NAK_REG; /*!< (@ 0x00000090) EP0 INNAK and OUTNAK Register */ __IOM uint32_t USB_RXD0_REG; /*!< (@ 0x00000094) Receive Data 0 Register */ __IOM uint32_t USB_RXS0_REG; /*!< (@ 0x00000098) Receive Status 0 Register */ __IOM uint32_t USB_RXC0_REG; /*!< (@ 0x0000009C) Receive Command 0 Register */ __IOM uint32_t USB_EPC1_REG; /*!< (@ 0x000000A0) Endpoint Control Register 1 */ __IOM uint32_t USB_TXD1_REG; /*!< (@ 0x000000A4) Transmit Data Register 1 */ __IOM uint32_t USB_TXS1_REG; /*!< (@ 0x000000A8) Transmit Status Register 1 */ __IOM uint32_t USB_TXC1_REG; /*!< (@ 0x000000AC) Transmit Command Register 1 */ __IOM uint32_t USB_EPC2_REG; /*!< (@ 0x000000B0) Endpoint Control Register 2 */ __IOM uint32_t USB_RXD1_REG; /*!< (@ 0x000000B4) Receive Data Register,1 */ __IOM uint32_t USB_RXS1_REG; /*!< (@ 0x000000B8) Receive Status Register 1 */ __IOM uint32_t USB_RXC1_REG; /*!< (@ 0x000000BC) Receive Command Register 1 */ __IOM uint32_t USB_EPC3_REG; /*!< (@ 0x000000C0) Endpoint Control Register 3 */ __IOM uint32_t USB_TXD2_REG; /*!< (@ 0x000000C4) Transmit Data Register 2 */ __IOM uint32_t USB_TXS2_REG; /*!< (@ 0x000000C8) Transmit Status Register 2 */ __IOM uint32_t USB_TXC2_REG; /*!< (@ 0x000000CC) Transmit Command Register 2 */ __IOM uint32_t USB_EPC4_REG; /*!< (@ 0x000000D0) Endpoint Control Register 4 */ __IOM uint32_t USB_RXD2_REG; /*!< (@ 0x000000D4) Receive Data Register 2 */ __IOM uint32_t USB_RXS2_REG; /*!< (@ 0x000000D8) Receive Status Register 2 */ __IOM uint32_t USB_RXC2_REG; /*!< (@ 0x000000DC) Receive Command Register 2 */ __IOM uint32_t USB_EPC5_REG; /*!< (@ 0x000000E0) Endpoint Control Register 5 */ __IOM uint32_t USB_TXD3_REG; /*!< (@ 0x000000E4) Transmit Data Register 3 */ __IOM uint32_t USB_TXS3_REG; /*!< (@ 0x000000E8) Transmit Status Register 3 */ __IOM uint32_t USB_TXC3_REG; /*!< (@ 0x000000EC) Transmit Command Register 3 */ __IOM uint32_t USB_EPC6_REG; /*!< (@ 0x000000F0) Endpoint Control Register 6 */ __IOM uint32_t USB_RXD3_REG; /*!< (@ 0x000000F4) Receive Data Register 3 */ __IOM uint32_t USB_RXS3_REG; /*!< (@ 0x000000F8) Receive Status Register 3 */ __IOM uint32_t USB_RXC3_REG; /*!< (@ 0x000000FC) Receive Command Register 3 */ __IM uint32_t RESERVED1[40]; __IOM uint32_t USB_DMA_CTRL_REG; /*!< (@ 0x000001A0) USB DMA control register */ __IM uint32_t RESERVED2; __IOM uint32_t USB_CHARGER_CTRL_REG; /*!< (@ 0x000001A8) USB Charger Control Register */ __IOM uint32_t USB_CHARGER_STAT_REG; /*!< (@ 0x000001AC) USB Charger Status Register */ } USB_Type; /*!< Size = 432 (0x1b0) */ /* =========================================================================================================================== */ /* ================ WAKEUP ================ */ /* =========================================================================================================================== */ /** * @brief WAKEUP registers (WAKEUP) */ typedef struct { /*!< (@ 0x50000100) WAKEUP Structure */ __IOM uint32_t WKUP_CTRL_REG; /*!< (@ 0x00000000) Control register for the wakeup counter */ __IM uint32_t RESERVED; __IOM uint32_t WKUP_RESET_IRQ_REG; /*!< (@ 0x00000008) Reset wakeup interrupt */ __IM uint32_t RESERVED1[2]; __IOM uint32_t WKUP_SELECT_P0_REG; /*!< (@ 0x00000014) select which inputs from P0 port can trigger wkup counter */ __IOM uint32_t WKUP_SELECT_P1_REG; /*!< (@ 0x00000018) select which inputs from P1 port can trigger wkup counter */ __IM uint32_t RESERVED2[3]; __IOM uint32_t WKUP_POL_P0_REG; /*!< (@ 0x00000028) select the sensitivity polarity for each P0 input */ __IOM uint32_t WKUP_POL_P1_REG; /*!< (@ 0x0000002C) select the sensitivity polarity for each P1 input */ __IM uint32_t RESERVED3[3]; __IOM uint32_t WKUP_STATUS_P0_REG; /*!< (@ 0x0000003C) Event status register for P0 */ __IOM uint32_t WKUP_STATUS_P1_REG; /*!< (@ 0x00000040) Event status register for P1 */ __IM uint32_t RESERVED4; __IOM uint32_t WKUP_CLEAR_P0_REG; /*!< (@ 0x00000048) Clear event register for P0 */ __IOM uint32_t WKUP_CLEAR_P1_REG; /*!< (@ 0x0000004C) Clear event register for P1 */ __IM uint32_t RESERVED5; __IOM uint32_t WKUP_SEL_GPIO_P0_REG; /*!< (@ 0x00000054) select which inputs from P0 port can trigger interrupt */ __IOM uint32_t WKUP_SEL_GPIO_P1_REG; /*!< (@ 0x00000058) select which inputs from P1 port can trigger interrupt */ } WAKEUP_Type; /*!< Size = 92 (0x5c) */ /** @} */ /* End of group Device_Peripheral_peripherals */ /* =========================================================================================================================== */ /* ================ Device Specific Peripheral Address Map ================ */ /* =========================================================================================================================== */ #define AES_HASH_BASE 0x30040000UL #define ANAMISC_BIF_BASE 0x50030B00UL #define APU_BASE 0x50030600UL #define CACHE_BASE 0x100C0000UL #define CHARGER_BASE 0x50040400UL #define CHIP_VERSION_BASE 0x50040200UL #define CRG_COM_BASE 0x50020900UL #define CRG_PER_BASE 0x50030C00UL #define CRG_SYS_BASE 0x50040500UL #define CRG_TOP_BASE 0x50000000UL #define CRG_XTAL_BASE 0x50010000UL #define DCDC_BASE 0x50000300UL #define DMA_BASE 0x50040800UL #define DW_BASE 0x30020000UL #define GPADC_BASE 0x50030900UL #define GPIO_BASE 0x50020A00UL #define GPREG_BASE 0x50040300UL #define I2C_BASE 0x50020600UL #define I2C2_BASE 0x50020700UL #define LCDC_BASE 0x30030000UL #define LRA_BASE 0x50030A00UL #define MEMCTRL_BASE 0x50050000UL #define OTPC_BASE 0x30070000UL #define PDC_BASE 0x50000200UL #define PWMLED_BASE 0x50030500UL #define QSPIC_BASE 0x38000000UL #define QSPIC2_BASE 0x34000000UL #define RFMON_BASE 0x50040600UL #define RTC_BASE 0x50000400UL #define SDADC_BASE 0x50020800UL #define SMOTOR_BASE 0x50030E00UL #define SNC_BASE 0x50020C00UL #define SPI_BASE 0x50020300UL #define SPI2_BASE 0x50020400UL #define SYS_WDOG_BASE 0x50000700UL #define TIMER_BASE 0x50010200UL #define TIMER2_BASE 0x50010300UL #define TIMER3_BASE 0x50040A00UL #define TIMER4_BASE 0x50040B00UL #define TRNG_BASE 0x50040C00UL #define UART_BASE 0x50020000UL #define UART2_BASE 0x50020100UL #define UART3_BASE 0x50020200UL #define USB_BASE 0x50040000UL #define WAKEUP_BASE 0x50000100UL /* =========================================================================================================================== */ /* ================ Peripheral declaration ================ */ /* =========================================================================================================================== */ #define AES_HASH ((AES_HASH_Type*) AES_HASH_BASE) #define ANAMISC_BIF ((ANAMISC_BIF_Type*) ANAMISC_BIF_BASE) #define APU ((APU_Type*) APU_BASE) #define CACHE ((CACHE_Type*) CACHE_BASE) #define CHARGER ((CHARGER_Type*) CHARGER_BASE) #define CHIP_VERSION ((CHIP_VERSION_Type*) CHIP_VERSION_BASE) #define CRG_COM ((CRG_COM_Type*) CRG_COM_BASE) #define CRG_PER ((CRG_PER_Type*) CRG_PER_BASE) #define CRG_SYS ((CRG_SYS_Type*) CRG_SYS_BASE) #define CRG_TOP ((CRG_TOP_Type*) CRG_TOP_BASE) #define CRG_XTAL ((CRG_XTAL_Type*) CRG_XTAL_BASE) #define DCDC ((DCDC_Type*) DCDC_BASE) #define DMA ((DMA_Type*) DMA_BASE) #define DW ((DW_Type*) DW_BASE) #define GPADC ((GPADC_Type*) GPADC_BASE) #define GPIO ((GPIO_Type*) GPIO_BASE) #define GPREG ((GPREG_Type*) GPREG_BASE) #define I2C ((I2C_Type*) I2C_BASE) #define I2C2 ((I2C2_Type*) I2C2_BASE) #define LCDC ((LCDC_Type*) LCDC_BASE) #define LRA ((LRA_Type*) LRA_BASE) #define MEMCTRL ((MEMCTRL_Type*) MEMCTRL_BASE) #define OTPC ((OTPC_Type*) OTPC_BASE) #define PDC ((PDC_Type*) PDC_BASE) #define PWMLED ((PWMLED_Type*) PWMLED_BASE) #define QSPIC ((QSPIC_Type*) QSPIC_BASE) #define QSPIC2 ((QSPIC2_Type*) QSPIC2_BASE) #define RFMON ((RFMON_Type*) RFMON_BASE) #define RTC ((RTC_Type*) RTC_BASE) #define SDADC ((SDADC_Type*) SDADC_BASE) #define SMOTOR ((SMOTOR_Type*) SMOTOR_BASE) #define SNC ((SNC_Type*) SNC_BASE) #define SPI ((SPI_Type*) SPI_BASE) #define SPI2 ((SPI2_Type*) SPI2_BASE) #define SYS_WDOG ((SYS_WDOG_Type*) SYS_WDOG_BASE) #define TIMER ((TIMER_Type*) TIMER_BASE) #define TIMER2 ((TIMER2_Type*) TIMER2_BASE) #define TIMER3 ((TIMER3_Type*) TIMER3_BASE) #define TIMER4 ((TIMER4_Type*) TIMER4_BASE) #define TRNG ((TRNG_Type*) TRNG_BASE) #define UART ((UART_Type*) UART_BASE) #define UART2 ((UART2_Type*) UART2_BASE) #define UART3 ((UART3_Type*) UART3_BASE) #define USB ((USB_Type*) USB_BASE) #define WAKEUP ((WAKEUP_Type*) WAKEUP_BASE) /* =========================================================================================================================== */ /* ================ Pos/Mask Peripheral Section ================ */ /* =========================================================================================================================== */ /** @addtogroup PosMask_peripherals * @{ */ /* =========================================================================================================================== */ /* ================ AES_HASH ================ */ /* =========================================================================================================================== */ /* =================================================== CRYPTO_CLRIRQ_REG =================================================== */ #define AES_HASH_CRYPTO_CLRIRQ_REG_CRYPTO_CLRIRQ_Pos (0UL) /*!< CRYPTO_CLRIRQ (Bit 0) */ #define AES_HASH_CRYPTO_CLRIRQ_REG_CRYPTO_CLRIRQ_Msk (0x1UL) /*!< CRYPTO_CLRIRQ (Bitfield-Mask: 0x01) */ /* ==================================================== CRYPTO_CTRL_REG ==================================================== */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Pos (17UL) /*!< CRYPTO_AES_KEXP (Bit 17) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Msk (0x20000UL) /*!< CRYPTO_AES_KEXP (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Pos (16UL) /*!< CRYPTO_MORE_IN (Bit 16) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk (0x10000UL) /*!< CRYPTO_MORE_IN (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_OUT_LEN_Pos (10UL) /*!< CRYPTO_HASH_OUT_LEN (Bit 10) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_OUT_LEN_Msk (0xfc00UL) /*!< CRYPTO_HASH_OUT_LEN (Bitfield-Mask: 0x3f) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Pos (9UL) /*!< CRYPTO_HASH_SEL (Bit 9) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk (0x200UL) /*!< CRYPTO_HASH_SEL (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Pos (8UL) /*!< CRYPTO_IRQ_EN (Bit 8) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_IRQ_EN_Msk (0x100UL) /*!< CRYPTO_IRQ_EN (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Pos (7UL) /*!< CRYPTO_ENCDEC (Bit 7) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ENCDEC_Msk (0x80UL) /*!< CRYPTO_ENCDEC (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Pos (5UL) /*!< CRYPTO_AES_KEY_SZ (Bit 5) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Msk (0x60UL) /*!< CRYPTO_AES_KEY_SZ (Bitfield-Mask: 0x03) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_OUT_MD_Pos (4UL) /*!< CRYPTO_OUT_MD (Bit 4) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_OUT_MD_Msk (0x10UL) /*!< CRYPTO_OUT_MD (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Pos (2UL) /*!< CRYPTO_ALG_MD (Bit 2) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk (0xcUL) /*!< CRYPTO_ALG_MD (Bitfield-Mask: 0x03) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Pos (0UL) /*!< CRYPTO_ALG (Bit 0) */ #define AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_Msk (0x3UL) /*!< CRYPTO_ALG (Bitfield-Mask: 0x03) */ /* ================================================= CRYPTO_DEST_ADDR_REG ================================================== */ #define AES_HASH_CRYPTO_DEST_ADDR_REG_CRYPTO_DEST_ADDR_Pos (0UL) /*!< CRYPTO_DEST_ADDR (Bit 0) */ #define AES_HASH_CRYPTO_DEST_ADDR_REG_CRYPTO_DEST_ADDR_Msk (0xffffffffUL) /*!< CRYPTO_DEST_ADDR (Bitfield-Mask: 0xffffffff) */ /* ================================================= CRYPTO_FETCH_ADDR_REG ================================================= */ #define AES_HASH_CRYPTO_FETCH_ADDR_REG_CRYPTO_FETCH_ADDR_Pos (0UL) /*!< CRYPTO_FETCH_ADDR (Bit 0) */ #define AES_HASH_CRYPTO_FETCH_ADDR_REG_CRYPTO_FETCH_ADDR_Msk (0xffffffffUL) /*!< CRYPTO_FETCH_ADDR (Bitfield-Mask: 0xffffffff) */ /* =================================================== CRYPTO_KEYS_START =================================================== */ #define AES_HASH_CRYPTO_KEYS_START_CRYPTO_KEY_X_Pos (0UL) /*!< CRYPTO_KEY_X (Bit 0) */ #define AES_HASH_CRYPTO_KEYS_START_CRYPTO_KEY_X_Msk (0xffffffffUL) /*!< CRYPTO_KEY_X (Bitfield-Mask: 0xffffffff) */ /* ==================================================== CRYPTO_LEN_REG ===================================================== */ #define AES_HASH_CRYPTO_LEN_REG_CRYPTO_LEN_Pos (0UL) /*!< CRYPTO_LEN (Bit 0) */ #define AES_HASH_CRYPTO_LEN_REG_CRYPTO_LEN_Msk (0xffffffUL) /*!< CRYPTO_LEN (Bitfield-Mask: 0xffffff) */ /* =================================================== CRYPTO_MREG0_REG ==================================================== */ #define AES_HASH_CRYPTO_MREG0_REG_CRYPTO_MREG0_Pos (0UL) /*!< CRYPTO_MREG0 (Bit 0) */ #define AES_HASH_CRYPTO_MREG0_REG_CRYPTO_MREG0_Msk (0xffffffffUL) /*!< CRYPTO_MREG0 (Bitfield-Mask: 0xffffffff) */ /* =================================================== CRYPTO_MREG1_REG ==================================================== */ #define AES_HASH_CRYPTO_MREG1_REG_CRYPTO_MREG1_Pos (0UL) /*!< CRYPTO_MREG1 (Bit 0) */ #define AES_HASH_CRYPTO_MREG1_REG_CRYPTO_MREG1_Msk (0xffffffffUL) /*!< CRYPTO_MREG1 (Bitfield-Mask: 0xffffffff) */ /* =================================================== CRYPTO_MREG2_REG ==================================================== */ #define AES_HASH_CRYPTO_MREG2_REG_CRYPTO_MREG2_Pos (0UL) /*!< CRYPTO_MREG2 (Bit 0) */ #define AES_HASH_CRYPTO_MREG2_REG_CRYPTO_MREG2_Msk (0xffffffffUL) /*!< CRYPTO_MREG2 (Bitfield-Mask: 0xffffffff) */ /* =================================================== CRYPTO_MREG3_REG ==================================================== */ #define AES_HASH_CRYPTO_MREG3_REG_CRYPTO_MREG3_Pos (0UL) /*!< CRYPTO_MREG3 (Bit 0) */ #define AES_HASH_CRYPTO_MREG3_REG_CRYPTO_MREG3_Msk (0xffffffffUL) /*!< CRYPTO_MREG3 (Bitfield-Mask: 0xffffffff) */ /* =================================================== CRYPTO_START_REG ==================================================== */ #define AES_HASH_CRYPTO_START_REG_CRYPTO_START_Pos (0UL) /*!< CRYPTO_START (Bit 0) */ #define AES_HASH_CRYPTO_START_REG_CRYPTO_START_Msk (0x1UL) /*!< CRYPTO_START (Bitfield-Mask: 0x01) */ /* =================================================== CRYPTO_STATUS_REG =================================================== */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Pos (2UL) /*!< CRYPTO_IRQ_ST (Bit 2) */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Msk (0x4UL) /*!< CRYPTO_IRQ_ST (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_WAIT_FOR_IN_Pos (1UL) /*!< CRYPTO_WAIT_FOR_IN (Bit 1) */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_WAIT_FOR_IN_Msk (0x2UL) /*!< CRYPTO_WAIT_FOR_IN (Bitfield-Mask: 0x01) */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Pos (0UL) /*!< CRYPTO_INACTIVE (Bit 0) */ #define AES_HASH_CRYPTO_STATUS_REG_CRYPTO_INACTIVE_Msk (0x1UL) /*!< CRYPTO_INACTIVE (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ ANAMISC_BIF ================ */ /* =========================================================================================================================== */ /* ==================================================== CLK_REF_CNT_REG ==================================================== */ #define ANAMISC_BIF_CLK_REF_CNT_REG_REF_CNT_VAL_Pos (0UL) /*!< REF_CNT_VAL (Bit 0) */ #define ANAMISC_BIF_CLK_REF_CNT_REG_REF_CNT_VAL_Msk (0xffffUL) /*!< REF_CNT_VAL (Bitfield-Mask: 0xffff) */ /* ==================================================== CLK_REF_SEL_REG ==================================================== */ #define ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Pos (5UL) /*!< CAL_CLK_SEL (Bit 5) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_CAL_CLK_SEL_Msk (0xe0UL) /*!< CAL_CLK_SEL (Bitfield-Mask: 0x07) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_EXT_CNT_EN_SEL_Pos (4UL) /*!< EXT_CNT_EN_SEL (Bit 4) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_EXT_CNT_EN_SEL_Msk (0x10UL) /*!< EXT_CNT_EN_SEL (Bitfield-Mask: 0x01) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Pos (3UL) /*!< REF_CAL_START (Bit 3) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CAL_START_Msk (0x8UL) /*!< REF_CAL_START (Bitfield-Mask: 0x01) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Pos (0UL) /*!< REF_CLK_SEL (Bit 0) */ #define ANAMISC_BIF_CLK_REF_SEL_REG_REF_CLK_SEL_Msk (0x7UL) /*!< REF_CLK_SEL (Bitfield-Mask: 0x07) */ /* ==================================================== CLK_REF_VAL_REG ==================================================== */ #define ANAMISC_BIF_CLK_REF_VAL_REG_XTAL_CNT_VAL_Pos (0UL) /*!< XTAL_CNT_VAL (Bit 0) */ #define ANAMISC_BIF_CLK_REF_VAL_REG_XTAL_CNT_VAL_Msk (0xffffffffUL) /*!< XTAL_CNT_VAL (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ APU ================ */ /* =========================================================================================================================== */ /* ====================================================== APU_MUX_REG ====================================================== */ #define APU_APU_MUX_REG_PDM1_MUX_IN_Pos (6UL) /*!< PDM1_MUX_IN (Bit 6) */ #define APU_APU_MUX_REG_PDM1_MUX_IN_Msk (0x40UL) /*!< PDM1_MUX_IN (Bitfield-Mask: 0x01) */ #define APU_APU_MUX_REG_PCM1_MUX_IN_Pos (3UL) /*!< PCM1_MUX_IN (Bit 3) */ #define APU_APU_MUX_REG_PCM1_MUX_IN_Msk (0x38UL) /*!< PCM1_MUX_IN (Bitfield-Mask: 0x07) */ #define APU_APU_MUX_REG_SRC1_MUX_IN_Pos (0UL) /*!< SRC1_MUX_IN (Bit 0) */ #define APU_APU_MUX_REG_SRC1_MUX_IN_Msk (0x7UL) /*!< SRC1_MUX_IN (Bitfield-Mask: 0x07) */ /* ==================================================== COEF0A_SET1_REG ==================================================== */ #define APU_COEF0A_SET1_REG_SRC_COEF10_Pos (0UL) /*!< SRC_COEF10 (Bit 0) */ #define APU_COEF0A_SET1_REG_SRC_COEF10_Msk (0xffffUL) /*!< SRC_COEF10 (Bitfield-Mask: 0xffff) */ /* ==================================================== COEF10_SET1_REG ==================================================== */ #define APU_COEF10_SET1_REG_SRC_COEF1_Pos (16UL) /*!< SRC_COEF1 (Bit 16) */ #define APU_COEF10_SET1_REG_SRC_COEF1_Msk (0xffff0000UL) /*!< SRC_COEF1 (Bitfield-Mask: 0xffff) */ #define APU_COEF10_SET1_REG_SRC_COEF0_Pos (0UL) /*!< SRC_COEF0 (Bit 0) */ #define APU_COEF10_SET1_REG_SRC_COEF0_Msk (0xffffUL) /*!< SRC_COEF0 (Bitfield-Mask: 0xffff) */ /* ==================================================== COEF32_SET1_REG ==================================================== */ #define APU_COEF32_SET1_REG_SRC_COEF3_Pos (16UL) /*!< SRC_COEF3 (Bit 16) */ #define APU_COEF32_SET1_REG_SRC_COEF3_Msk (0xffff0000UL) /*!< SRC_COEF3 (Bitfield-Mask: 0xffff) */ #define APU_COEF32_SET1_REG_SRC_COEF2_Pos (0UL) /*!< SRC_COEF2 (Bit 0) */ #define APU_COEF32_SET1_REG_SRC_COEF2_Msk (0xffffUL) /*!< SRC_COEF2 (Bitfield-Mask: 0xffff) */ /* ==================================================== COEF54_SET1_REG ==================================================== */ #define APU_COEF54_SET1_REG_SRC_COEF5_Pos (16UL) /*!< SRC_COEF5 (Bit 16) */ #define APU_COEF54_SET1_REG_SRC_COEF5_Msk (0xffff0000UL) /*!< SRC_COEF5 (Bitfield-Mask: 0xffff) */ #define APU_COEF54_SET1_REG_SRC_COEF4_Pos (0UL) /*!< SRC_COEF4 (Bit 0) */ #define APU_COEF54_SET1_REG_SRC_COEF4_Msk (0xffffUL) /*!< SRC_COEF4 (Bitfield-Mask: 0xffff) */ /* ==================================================== COEF76_SET1_REG ==================================================== */ #define APU_COEF76_SET1_REG_SRC_COEF7_Pos (16UL) /*!< SRC_COEF7 (Bit 16) */ #define APU_COEF76_SET1_REG_SRC_COEF7_Msk (0xffff0000UL) /*!< SRC_COEF7 (Bitfield-Mask: 0xffff) */ #define APU_COEF76_SET1_REG_SRC_COEF6_Pos (0UL) /*!< SRC_COEF6 (Bit 0) */ #define APU_COEF76_SET1_REG_SRC_COEF6_Msk (0xffffUL) /*!< SRC_COEF6 (Bitfield-Mask: 0xffff) */ /* ==================================================== COEF98_SET1_REG ==================================================== */ #define APU_COEF98_SET1_REG_SRC_COEF9_Pos (16UL) /*!< SRC_COEF9 (Bit 16) */ #define APU_COEF98_SET1_REG_SRC_COEF9_Msk (0xffff0000UL) /*!< SRC_COEF9 (Bitfield-Mask: 0xffff) */ #define APU_COEF98_SET1_REG_SRC_COEF8_Pos (0UL) /*!< SRC_COEF8 (Bit 0) */ #define APU_COEF98_SET1_REG_SRC_COEF8_Msk (0xffffUL) /*!< SRC_COEF8 (Bitfield-Mask: 0xffff) */ /* ===================================================== PCM1_CTRL_REG ===================================================== */ #define APU_PCM1_CTRL_REG_PCM_FSC_DIV_Pos (20UL) /*!< PCM_FSC_DIV (Bit 20) */ #define APU_PCM1_CTRL_REG_PCM_FSC_DIV_Msk (0xfff00000UL) /*!< PCM_FSC_DIV (Bitfield-Mask: 0xfff) */ #define APU_PCM1_CTRL_REG_PCM_FSC_EDGE_Pos (16UL) /*!< PCM_FSC_EDGE (Bit 16) */ #define APU_PCM1_CTRL_REG_PCM_FSC_EDGE_Msk (0x10000UL) /*!< PCM_FSC_EDGE (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_CH_DEL_Pos (11UL) /*!< PCM_CH_DEL (Bit 11) */ #define APU_PCM1_CTRL_REG_PCM_CH_DEL_Msk (0xf800UL) /*!< PCM_CH_DEL (Bitfield-Mask: 0x1f) */ #define APU_PCM1_CTRL_REG_PCM_CLK_BIT_Pos (10UL) /*!< PCM_CLK_BIT (Bit 10) */ #define APU_PCM1_CTRL_REG_PCM_CLK_BIT_Msk (0x400UL) /*!< PCM_CLK_BIT (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_FSCINV_Pos (9UL) /*!< PCM_FSCINV (Bit 9) */ #define APU_PCM1_CTRL_REG_PCM_FSCINV_Msk (0x200UL) /*!< PCM_FSCINV (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_CLKINV_Pos (8UL) /*!< PCM_CLKINV (Bit 8) */ #define APU_PCM1_CTRL_REG_PCM_CLKINV_Msk (0x100UL) /*!< PCM_CLKINV (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_PPOD_Pos (7UL) /*!< PCM_PPOD (Bit 7) */ #define APU_PCM1_CTRL_REG_PCM_PPOD_Msk (0x80UL) /*!< PCM_PPOD (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_FSCDEL_Pos (6UL) /*!< PCM_FSCDEL (Bit 6) */ #define APU_PCM1_CTRL_REG_PCM_FSCDEL_Msk (0x40UL) /*!< PCM_FSCDEL (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_FSCLEN_Pos (2UL) /*!< PCM_FSCLEN (Bit 2) */ #define APU_PCM1_CTRL_REG_PCM_FSCLEN_Msk (0x3cUL) /*!< PCM_FSCLEN (Bitfield-Mask: 0x0f) */ #define APU_PCM1_CTRL_REG_PCM_MASTER_Pos (1UL) /*!< PCM_MASTER (Bit 1) */ #define APU_PCM1_CTRL_REG_PCM_MASTER_Msk (0x2UL) /*!< PCM_MASTER (Bitfield-Mask: 0x01) */ #define APU_PCM1_CTRL_REG_PCM_EN_Pos (0UL) /*!< PCM_EN (Bit 0) */ #define APU_PCM1_CTRL_REG_PCM_EN_Msk (0x1UL) /*!< PCM_EN (Bitfield-Mask: 0x01) */ /* ===================================================== PCM1_IN1_REG ====================================================== */ #define APU_PCM1_IN1_REG_PCM_IN_Pos (0UL) /*!< PCM_IN (Bit 0) */ #define APU_PCM1_IN1_REG_PCM_IN_Msk (0xffffffffUL) /*!< PCM_IN (Bitfield-Mask: 0xffffffff) */ /* ===================================================== PCM1_IN2_REG ====================================================== */ #define APU_PCM1_IN2_REG_PCM_IN_Pos (0UL) /*!< PCM_IN (Bit 0) */ #define APU_PCM1_IN2_REG_PCM_IN_Msk (0xffffffffUL) /*!< PCM_IN (Bitfield-Mask: 0xffffffff) */ /* ===================================================== PCM1_OUT1_REG ===================================================== */ #define APU_PCM1_OUT1_REG_PCM_OUT_Pos (0UL) /*!< PCM_OUT (Bit 0) */ #define APU_PCM1_OUT1_REG_PCM_OUT_Msk (0xffffffffUL) /*!< PCM_OUT (Bitfield-Mask: 0xffffffff) */ /* ===================================================== PCM1_OUT2_REG ===================================================== */ #define APU_PCM1_OUT2_REG_PCM_OUT_Pos (0UL) /*!< PCM_OUT (Bit 0) */ #define APU_PCM1_OUT2_REG_PCM_OUT_Msk (0xffffffffUL) /*!< PCM_OUT (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SRC1_CTRL_REG ===================================================== */ #define APU_SRC1_CTRL_REG_SRC_PDM_DO_DEL_Pos (30UL) /*!< SRC_PDM_DO_DEL (Bit 30) */ #define APU_SRC1_CTRL_REG_SRC_PDM_DO_DEL_Msk (0xc0000000UL) /*!< SRC_PDM_DO_DEL (Bitfield-Mask: 0x03) */ #define APU_SRC1_CTRL_REG_SRC_PDM_MODE_Pos (28UL) /*!< SRC_PDM_MODE (Bit 28) */ #define APU_SRC1_CTRL_REG_SRC_PDM_MODE_Msk (0x30000000UL) /*!< SRC_PDM_MODE (Bitfield-Mask: 0x03) */ #define APU_SRC1_CTRL_REG_SRC_PDM_DI_DEL_Pos (26UL) /*!< SRC_PDM_DI_DEL (Bit 26) */ #define APU_SRC1_CTRL_REG_SRC_PDM_DI_DEL_Msk (0xc000000UL) /*!< SRC_PDM_DI_DEL (Bitfield-Mask: 0x03) */ #define APU_SRC1_CTRL_REG_SRC_OUT_FLOWCLR_Pos (25UL) /*!< SRC_OUT_FLOWCLR (Bit 25) */ #define APU_SRC1_CTRL_REG_SRC_OUT_FLOWCLR_Msk (0x2000000UL) /*!< SRC_OUT_FLOWCLR (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_FLOWCLR_Pos (24UL) /*!< SRC_IN_FLOWCLR (Bit 24) */ #define APU_SRC1_CTRL_REG_SRC_IN_FLOWCLR_Msk (0x1000000UL) /*!< SRC_IN_FLOWCLR (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_UNFLOW_Pos (23UL) /*!< SRC_OUT_UNFLOW (Bit 23) */ #define APU_SRC1_CTRL_REG_SRC_OUT_UNFLOW_Msk (0x800000UL) /*!< SRC_OUT_UNFLOW (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_OVFLOW_Pos (22UL) /*!< SRC_OUT_OVFLOW (Bit 22) */ #define APU_SRC1_CTRL_REG_SRC_OUT_OVFLOW_Msk (0x400000UL) /*!< SRC_OUT_OVFLOW (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_UNFLOW_Pos (21UL) /*!< SRC_IN_UNFLOW (Bit 21) */ #define APU_SRC1_CTRL_REG_SRC_IN_UNFLOW_Msk (0x200000UL) /*!< SRC_IN_UNFLOW (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_OVFLOW_Pos (20UL) /*!< SRC_IN_OVFLOW (Bit 20) */ #define APU_SRC1_CTRL_REG_SRC_IN_OVFLOW_Msk (0x100000UL) /*!< SRC_IN_OVFLOW (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_RESYNC_Pos (19UL) /*!< SRC_RESYNC (Bit 19) */ #define APU_SRC1_CTRL_REG_SRC_RESYNC_Msk (0x80000UL) /*!< SRC_RESYNC (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_OK_Pos (18UL) /*!< SRC_OUT_OK (Bit 18) */ #define APU_SRC1_CTRL_REG_SRC_OUT_OK_Msk (0x40000UL) /*!< SRC_OUT_OK (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_US_Pos (16UL) /*!< SRC_OUT_US (Bit 16) */ #define APU_SRC1_CTRL_REG_SRC_OUT_US_Msk (0x30000UL) /*!< SRC_OUT_US (Bitfield-Mask: 0x03) */ #define APU_SRC1_CTRL_REG_SRC_OUT_CAL_BYPASS_Pos (14UL) /*!< SRC_OUT_CAL_BYPASS (Bit 14) */ #define APU_SRC1_CTRL_REG_SRC_OUT_CAL_BYPASS_Msk (0x4000UL) /*!< SRC_OUT_CAL_BYPASS (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_AMODE_Pos (13UL) /*!< SRC_OUT_AMODE (Bit 13) */ #define APU_SRC1_CTRL_REG_SRC_OUT_AMODE_Msk (0x2000UL) /*!< SRC_OUT_AMODE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_PDM_OUT_INV_Pos (12UL) /*!< SRC_PDM_OUT_INV (Bit 12) */ #define APU_SRC1_CTRL_REG_SRC_PDM_OUT_INV_Msk (0x1000UL) /*!< SRC_PDM_OUT_INV (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_FIFO_DIRECTION_Pos (11UL) /*!< SRC_FIFO_DIRECTION (Bit 11) */ #define APU_SRC1_CTRL_REG_SRC_FIFO_DIRECTION_Msk (0x800UL) /*!< SRC_FIFO_DIRECTION (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_FIFO_ENABLE_Pos (10UL) /*!< SRC_FIFO_ENABLE (Bit 10) */ #define APU_SRC1_CTRL_REG_SRC_FIFO_ENABLE_Msk (0x400UL) /*!< SRC_FIFO_ENABLE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_OUT_DSD_MODE_Pos (9UL) /*!< SRC_OUT_DSD_MODE (Bit 9) */ #define APU_SRC1_CTRL_REG_SRC_OUT_DSD_MODE_Msk (0x200UL) /*!< SRC_OUT_DSD_MODE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_DSD_MODE_Pos (8UL) /*!< SRC_IN_DSD_MODE (Bit 8) */ #define APU_SRC1_CTRL_REG_SRC_IN_DSD_MODE_Msk (0x100UL) /*!< SRC_IN_DSD_MODE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_DITHER_DISABLE_Pos (7UL) /*!< SRC_DITHER_DISABLE (Bit 7) */ #define APU_SRC1_CTRL_REG_SRC_DITHER_DISABLE_Msk (0x80UL) /*!< SRC_DITHER_DISABLE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_OK_Pos (6UL) /*!< SRC_IN_OK (Bit 6) */ #define APU_SRC1_CTRL_REG_SRC_IN_OK_Msk (0x40UL) /*!< SRC_IN_OK (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_DS_Pos (4UL) /*!< SRC_IN_DS (Bit 4) */ #define APU_SRC1_CTRL_REG_SRC_IN_DS_Msk (0x30UL) /*!< SRC_IN_DS (Bitfield-Mask: 0x03) */ #define APU_SRC1_CTRL_REG_SRC_PDM_IN_INV_Pos (3UL) /*!< SRC_PDM_IN_INV (Bit 3) */ #define APU_SRC1_CTRL_REG_SRC_PDM_IN_INV_Msk (0x8UL) /*!< SRC_PDM_IN_INV (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_CAL_BYPASS_Pos (2UL) /*!< SRC_IN_CAL_BYPASS (Bit 2) */ #define APU_SRC1_CTRL_REG_SRC_IN_CAL_BYPASS_Msk (0x4UL) /*!< SRC_IN_CAL_BYPASS (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_IN_AMODE_Pos (1UL) /*!< SRC_IN_AMODE (Bit 1) */ #define APU_SRC1_CTRL_REG_SRC_IN_AMODE_Msk (0x2UL) /*!< SRC_IN_AMODE (Bitfield-Mask: 0x01) */ #define APU_SRC1_CTRL_REG_SRC_EN_Pos (0UL) /*!< SRC_EN (Bit 0) */ #define APU_SRC1_CTRL_REG_SRC_EN_Msk (0x1UL) /*!< SRC_EN (Bitfield-Mask: 0x01) */ /* ===================================================== SRC1_IN1_REG ====================================================== */ #define APU_SRC1_IN1_REG_SRC_IN_Pos (0UL) /*!< SRC_IN (Bit 0) */ #define APU_SRC1_IN1_REG_SRC_IN_Msk (0xffffffffUL) /*!< SRC_IN (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SRC1_IN2_REG ====================================================== */ #define APU_SRC1_IN2_REG_SRC_IN_Pos (0UL) /*!< SRC_IN (Bit 0) */ #define APU_SRC1_IN2_REG_SRC_IN_Msk (0xffffffffUL) /*!< SRC_IN (Bitfield-Mask: 0xffffffff) */ /* ==================================================== SRC1_IN_FS_REG ===================================================== */ #define APU_SRC1_IN_FS_REG_SRC_IN_FS_Pos (0UL) /*!< SRC_IN_FS (Bit 0) */ #define APU_SRC1_IN_FS_REG_SRC_IN_FS_Msk (0xffffffUL) /*!< SRC_IN_FS (Bitfield-Mask: 0xffffff) */ /* ===================================================== SRC1_OUT1_REG ===================================================== */ #define APU_SRC1_OUT1_REG_SRC_OUT_Pos (0UL) /*!< SRC_OUT (Bit 0) */ #define APU_SRC1_OUT1_REG_SRC_OUT_Msk (0xffffffffUL) /*!< SRC_OUT (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SRC1_OUT2_REG ===================================================== */ #define APU_SRC1_OUT2_REG_SRC_OUT_Pos (0UL) /*!< SRC_OUT (Bit 0) */ #define APU_SRC1_OUT2_REG_SRC_OUT_Msk (0xffffffffUL) /*!< SRC_OUT (Bitfield-Mask: 0xffffffff) */ /* ==================================================== SRC1_OUT_FS_REG ==================================================== */ #define APU_SRC1_OUT_FS_REG_SRC_OUT_FS_Pos (0UL) /*!< SRC_OUT_FS (Bit 0) */ #define APU_SRC1_OUT_FS_REG_SRC_OUT_FS_Msk (0xffffffUL) /*!< SRC_OUT_FS (Bitfield-Mask: 0xffffff) */ /* =========================================================================================================================== */ /* ================ CACHE ================ */ /* =========================================================================================================================== */ /* ================================================== CACHE_ASSOCCFG_REG =================================================== */ #define CACHE_CACHE_ASSOCCFG_REG_CACHE_ASSOC_Pos (0UL) /*!< CACHE_ASSOC (Bit 0) */ #define CACHE_CACHE_ASSOCCFG_REG_CACHE_ASSOC_Msk (0x3UL) /*!< CACHE_ASSOC (Bitfield-Mask: 0x03) */ /* ==================================================== CACHE_CTRL1_REG ==================================================== */ #define CACHE_CACHE_CTRL1_REG_CACHE_RES1_Pos (1UL) /*!< CACHE_RES1 (Bit 1) */ #define CACHE_CACHE_CTRL1_REG_CACHE_RES1_Msk (0x2UL) /*!< CACHE_RES1 (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Pos (0UL) /*!< CACHE_FLUSH (Bit 0) */ #define CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Msk (0x1UL) /*!< CACHE_FLUSH (Bitfield-Mask: 0x01) */ /* ==================================================== CACHE_CTRL2_REG ==================================================== */ #define CACHE_CACHE_CTRL2_REG_CACHE_CGEN_Pos (10UL) /*!< CACHE_CGEN (Bit 10) */ #define CACHE_CACHE_CTRL2_REG_CACHE_CGEN_Msk (0x400UL) /*!< CACHE_CGEN (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_CTRL2_REG_CACHE_WEN_Pos (9UL) /*!< CACHE_WEN (Bit 9) */ #define CACHE_CACHE_CTRL2_REG_CACHE_WEN_Msk (0x200UL) /*!< CACHE_WEN (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_CTRL2_REG_CACHE_LEN_Pos (0UL) /*!< CACHE_LEN (Bit 0) */ #define CACHE_CACHE_CTRL2_REG_CACHE_LEN_Msk (0x1ffUL) /*!< CACHE_LEN (Bitfield-Mask: 0x1ff) */ /* ==================================================== CACHE_FLASH_REG ==================================================== */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Pos (16UL) /*!< FLASH_REGION_BASE (Bit 16) */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Msk (0xffff0000UL) /*!< FLASH_REGION_BASE (Bitfield-Mask: 0xffff) */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Pos (4UL) /*!< FLASH_REGION_OFFSET (Bit 4) */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Msk (0xfff0UL) /*!< FLASH_REGION_OFFSET (Bitfield-Mask: 0xfff) */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Pos (0UL) /*!< FLASH_REGION_SIZE (Bit 0) */ #define CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Msk (0x7UL) /*!< FLASH_REGION_SIZE (Bitfield-Mask: 0x07) */ /* ================================================== CACHE_LNSIZECFG_REG ================================================== */ #define CACHE_CACHE_LNSIZECFG_REG_CACHE_LINE_Pos (0UL) /*!< CACHE_LINE (Bit 0) */ #define CACHE_CACHE_LNSIZECFG_REG_CACHE_LINE_Msk (0x3UL) /*!< CACHE_LINE (Bitfield-Mask: 0x03) */ /* ================================================== CACHE_MRM_CTRL_REG =================================================== */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_HITS_THRES_STATUS_Pos (4UL) /*!< MRM_IRQ_HITS_THRES_STATUS (Bit 4) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_HITS_THRES_STATUS_Msk (0x10UL) /*!< MRM_IRQ_HITS_THRES_STATUS (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MISSES_THRES_STATUS_Pos (3UL) /*!< MRM_IRQ_MISSES_THRES_STATUS (Bit 3) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MISSES_THRES_STATUS_Msk (0x8UL) /*!< MRM_IRQ_MISSES_THRES_STATUS (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_TINT_STATUS_Pos (2UL) /*!< MRM_IRQ_TINT_STATUS (Bit 2) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_TINT_STATUS_Msk (0x4UL) /*!< MRM_IRQ_TINT_STATUS (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MASK_Pos (1UL) /*!< MRM_IRQ_MASK (Bit 1) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_IRQ_MASK_Msk (0x2UL) /*!< MRM_IRQ_MASK (Bitfield-Mask: 0x01) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_START_Pos (0UL) /*!< MRM_START (Bit 0) */ #define CACHE_CACHE_MRM_CTRL_REG_MRM_START_Msk (0x1UL) /*!< MRM_START (Bitfield-Mask: 0x01) */ /* ================================================== CACHE_MRM_HITS_REG =================================================== */ #define CACHE_CACHE_MRM_HITS_REG_MRM_HITS_Pos (0UL) /*!< MRM_HITS (Bit 0) */ #define CACHE_CACHE_MRM_HITS_REG_MRM_HITS_Msk (0xffffffffUL) /*!< MRM_HITS (Bitfield-Mask: 0xffffffff) */ /* =============================================== CACHE_MRM_HITS_THRES_REG ================================================ */ #define CACHE_CACHE_MRM_HITS_THRES_REG_MRM_HITS_THRES_Pos (0UL) /*!< MRM_HITS_THRES (Bit 0) */ #define CACHE_CACHE_MRM_HITS_THRES_REG_MRM_HITS_THRES_Msk (0xffffffffUL) /*!< MRM_HITS_THRES (Bitfield-Mask: 0xffffffff) */ /* ================================================= CACHE_MRM_MISSES_REG ================================================== */ #define CACHE_CACHE_MRM_MISSES_REG_MRM_MISSES_Pos (0UL) /*!< MRM_MISSES (Bit 0) */ #define CACHE_CACHE_MRM_MISSES_REG_MRM_MISSES_Msk (0xffffffffUL) /*!< MRM_MISSES (Bitfield-Mask: 0xffffffff) */ /* ============================================== CACHE_MRM_MISSES_THRES_REG =============================================== */ #define CACHE_CACHE_MRM_MISSES_THRES_REG_MRM_MISSES_THRES_Pos (0UL) /*!< MRM_MISSES_THRES (Bit 0) */ #define CACHE_CACHE_MRM_MISSES_THRES_REG_MRM_MISSES_THRES_Msk (0xffffffffUL) /*!< MRM_MISSES_THRES (Bitfield-Mask: 0xffffffff) */ /* ================================================== CACHE_MRM_TINT_REG =================================================== */ #define CACHE_CACHE_MRM_TINT_REG_MRM_TINT_Pos (0UL) /*!< MRM_TINT (Bit 0) */ #define CACHE_CACHE_MRM_TINT_REG_MRM_TINT_Msk (0x7ffffUL) /*!< MRM_TINT (Bitfield-Mask: 0x7ffff) */ /* ===================================================== SWD_RESET_REG ===================================================== */ #define CACHE_SWD_RESET_REG_SWD_HW_RESET_REQ_Pos (0UL) /*!< SWD_HW_RESET_REQ (Bit 0) */ #define CACHE_SWD_RESET_REG_SWD_HW_RESET_REQ_Msk (0x1UL) /*!< SWD_HW_RESET_REQ (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ CHARGER ================ */ /* =========================================================================================================================== */ /* ============================================== CHARGER_CC_CHARGE_TIMER_REG ============================================== */ #define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_CC_CHARGE_TIMER_Pos (16UL) /*!< CC_CHARGE_TIMER (Bit 16) */ #define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_CC_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< CC_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ #define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_MAX_CC_CHARGE_TIME_Pos (0UL) /*!< MAX_CC_CHARGE_TIME (Bit 0) */ #define CHARGER_CHARGER_CC_CHARGE_TIMER_REG_MAX_CC_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_CC_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ /* =================================================== CHARGER_CTRL_REG ==================================================== */ #define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_TIMER_Pos (22UL) /*!< EOC_INTERVAL_CHECK_TIMER (Bit 22) */ #define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_TIMER_Msk (0xfc00000UL) /*!< EOC_INTERVAL_CHECK_TIMER (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_THRES_Pos (16UL) /*!< EOC_INTERVAL_CHECK_THRES (Bit 16) */ #define CHARGER_CHARGER_CTRL_REG_EOC_INTERVAL_CHECK_THRES_Msk (0x3f0000UL) /*!< EOC_INTERVAL_CHECK_THRES (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_CTRL_REG_REPLENISH_MODE_Pos (15UL) /*!< REPLENISH_MODE (Bit 15) */ #define CHARGER_CHARGER_CTRL_REG_REPLENISH_MODE_Msk (0x8000UL) /*!< REPLENISH_MODE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_PRE_CHARGE_MODE_Pos (14UL) /*!< PRE_CHARGE_MODE (Bit 14) */ #define CHARGER_CHARGER_CTRL_REG_PRE_CHARGE_MODE_Msk (0x4000UL) /*!< PRE_CHARGE_MODE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_LOOP_HOLD_Pos (13UL) /*!< CHARGE_LOOP_HOLD (Bit 13) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_LOOP_HOLD_Msk (0x2000UL) /*!< CHARGE_LOOP_HOLD (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_JEITA_SUPPORT_DISABLED_Pos (12UL) /*!< JEITA_SUPPORT_DISABLED (Bit 12) */ #define CHARGER_CHARGER_CTRL_REG_JEITA_SUPPORT_DISABLED_Msk (0x1000UL) /*!< JEITA_SUPPORT_DISABLED (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_TBAT_MONITOR_MODE_Pos (10UL) /*!< TBAT_MONITOR_MODE (Bit 10) */ #define CHARGER_CHARGER_CTRL_REG_TBAT_MONITOR_MODE_Msk (0xc00UL) /*!< TBAT_MONITOR_MODE (Bitfield-Mask: 0x03) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_TIMERS_HALT_ENABLE_Pos (9UL) /*!< CHARGE_TIMERS_HALT_ENABLE (Bit 9) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_TIMERS_HALT_ENABLE_Msk (0x200UL) /*!< CHARGE_TIMERS_HALT_ENABLE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_NTC_LOW_DISABLE_Pos (7UL) /*!< NTC_LOW_DISABLE (Bit 7) */ #define CHARGER_CHARGER_CTRL_REG_NTC_LOW_DISABLE_Msk (0x80UL) /*!< NTC_LOW_DISABLE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_TBAT_PROT_ENABLE_Pos (6UL) /*!< TBAT_PROT_ENABLE (Bit 6) */ #define CHARGER_CHARGER_CTRL_REG_TBAT_PROT_ENABLE_Msk (0x40UL) /*!< TBAT_PROT_ENABLE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_TDIE_ERROR_RESUME_Pos (5UL) /*!< TDIE_ERROR_RESUME (Bit 5) */ #define CHARGER_CHARGER_CTRL_REG_TDIE_ERROR_RESUME_Msk (0x20UL) /*!< TDIE_ERROR_RESUME (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_TDIE_PROT_ENABLE_Pos (4UL) /*!< TDIE_PROT_ENABLE (Bit 4) */ #define CHARGER_CHARGER_CTRL_REG_TDIE_PROT_ENABLE_Msk (0x10UL) /*!< TDIE_PROT_ENABLE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_RESUME_Pos (3UL) /*!< CHARGER_RESUME (Bit 3) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_RESUME_Msk (0x8UL) /*!< CHARGER_RESUME (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_BYPASS_Pos (2UL) /*!< CHARGER_BYPASS (Bit 2) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_BYPASS_Msk (0x4UL) /*!< CHARGER_BYPASS (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_START_Pos (1UL) /*!< CHARGE_START (Bit 1) */ #define CHARGER_CHARGER_CTRL_REG_CHARGE_START_Msk (0x2UL) /*!< CHARGE_START (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_ENABLE_Pos (0UL) /*!< CHARGER_ENABLE (Bit 0) */ #define CHARGER_CHARGER_CTRL_REG_CHARGER_ENABLE_Msk (0x1UL) /*!< CHARGER_ENABLE (Bitfield-Mask: 0x01) */ /* =============================================== CHARGER_CURRENT_PARAM_REG =============================================== */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_EOC_DOUBLE_RANGE_Pos (15UL) /*!< I_EOC_DOUBLE_RANGE (Bit 15) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_EOC_DOUBLE_RANGE_Msk (0x8000UL) /*!< I_EOC_DOUBLE_RANGE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_END_OF_CHARGE_Pos (12UL) /*!< I_END_OF_CHARGE (Bit 12) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_END_OF_CHARGE_Msk (0x7000UL) /*!< I_END_OF_CHARGE (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_PRECHARGE_Pos (6UL) /*!< I_PRECHARGE (Bit 6) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_PRECHARGE_Msk (0xfc0UL) /*!< I_PRECHARGE (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_CHARGE_Pos (0UL) /*!< I_CHARGE (Bit 0) */ #define CHARGER_CHARGER_CURRENT_PARAM_REG_I_CHARGE_Msk (0x3fUL) /*!< I_CHARGE (Bitfield-Mask: 0x3f) */ /* ============================================== CHARGER_CV_CHARGE_TIMER_REG ============================================== */ #define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_CV_CHARGE_TIMER_Pos (16UL) /*!< CV_CHARGE_TIMER (Bit 16) */ #define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_CV_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< CV_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ #define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_MAX_CV_CHARGE_TIME_Pos (0UL) /*!< MAX_CV_CHARGE_TIME (Bit 0) */ #define CHARGER_CHARGER_CV_CHARGE_TIMER_REG_MAX_CV_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_CV_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ /* =============================================== CHARGER_ERROR_IRQ_CLR_REG =============================================== */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TBAT_ERROR_IRQ_CLR_Pos (6UL) /*!< TBAT_ERROR_IRQ_CLR (Bit 6) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TBAT_ERROR_IRQ_CLR_Msk (0x40UL) /*!< TBAT_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TDIE_ERROR_IRQ_CLR_Pos (5UL) /*!< TDIE_ERROR_IRQ_CLR (Bit 5) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TDIE_ERROR_IRQ_CLR_Msk (0x20UL) /*!< TDIE_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_VBAT_OVP_ERROR_IRQ_CLR_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ_CLR (Bit 4) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_VBAT_OVP_ERROR_IRQ_CLR_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TOTAL_CHARGE_TIMEOUT_IRQ_CLR_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_CLR (Bit 3) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_TOTAL_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CV_CHARGE_TIMEOUT_IRQ_CLR_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ_CLR (Bit 2) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CV_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CC_CHARGE_TIMEOUT_IRQ_CLR_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ_CLR (Bit 1) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_CC_CHARGE_TIMEOUT_IRQ_CLR_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_PRECHARGE_TIMEOUT_IRQ_CLR_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ_CLR (Bit 0) */ #define CHARGER_CHARGER_ERROR_IRQ_CLR_REG_PRECHARGE_TIMEOUT_IRQ_CLR_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ_CLR (Bitfield-Mask: 0x01) */ /* ============================================== CHARGER_ERROR_IRQ_MASK_REG =============================================== */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TBAT_ERROR_IRQ_EN_Pos (6UL) /*!< TBAT_ERROR_IRQ_EN (Bit 6) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TBAT_ERROR_IRQ_EN_Msk (0x40UL) /*!< TBAT_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TDIE_ERROR_IRQ_EN_Pos (5UL) /*!< TDIE_ERROR_IRQ_EN (Bit 5) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TDIE_ERROR_IRQ_EN_Msk (0x20UL) /*!< TDIE_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_VBAT_OVP_ERROR_IRQ_EN_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ_EN (Bit 4) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_VBAT_OVP_ERROR_IRQ_EN_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TOTAL_CHARGE_TIMEOUT_IRQ_EN_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_EN (Bit 3) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_TOTAL_CHARGE_TIMEOUT_IRQ_EN_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CV_CHARGE_TIMEOUT_IRQ_EN_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ_EN (Bit 2) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CV_CHARGE_TIMEOUT_IRQ_EN_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CC_CHARGE_TIMEOUT_IRQ_EN_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ_EN (Bit 1) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_CC_CHARGE_TIMEOUT_IRQ_EN_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_PRECHARGE_TIMEOUT_IRQ_EN_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ_EN (Bit 0) */ #define CHARGER_CHARGER_ERROR_IRQ_MASK_REG_PRECHARGE_TIMEOUT_IRQ_EN_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ_EN (Bitfield-Mask: 0x01) */ /* ============================================= CHARGER_ERROR_IRQ_STATUS_REG ============================================== */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TBAT_ERROR_IRQ_Pos (6UL) /*!< TBAT_ERROR_IRQ (Bit 6) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TBAT_ERROR_IRQ_Msk (0x40UL) /*!< TBAT_ERROR_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TDIE_ERROR_IRQ_Pos (5UL) /*!< TDIE_ERROR_IRQ (Bit 5) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TDIE_ERROR_IRQ_Msk (0x20UL) /*!< TDIE_ERROR_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_VBAT_OVP_ERROR_IRQ_Pos (4UL) /*!< VBAT_OVP_ERROR_IRQ (Bit 4) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_VBAT_OVP_ERROR_IRQ_Msk (0x10UL) /*!< VBAT_OVP_ERROR_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TOTAL_CHARGE_TIMEOUT_IRQ_Pos (3UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ (Bit 3) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_TOTAL_CHARGE_TIMEOUT_IRQ_Msk (0x8UL) /*!< TOTAL_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CV_CHARGE_TIMEOUT_IRQ_Pos (2UL) /*!< CV_CHARGE_TIMEOUT_IRQ (Bit 2) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CV_CHARGE_TIMEOUT_IRQ_Msk (0x4UL) /*!< CV_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CC_CHARGE_TIMEOUT_IRQ_Pos (1UL) /*!< CC_CHARGE_TIMEOUT_IRQ (Bit 1) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_CC_CHARGE_TIMEOUT_IRQ_Msk (0x2UL) /*!< CC_CHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_PRECHARGE_TIMEOUT_IRQ_Pos (0UL) /*!< PRECHARGE_TIMEOUT_IRQ (Bit 0) */ #define CHARGER_CHARGER_ERROR_IRQ_STATUS_REG_PRECHARGE_TIMEOUT_IRQ_Msk (0x1UL) /*!< PRECHARGE_TIMEOUT_IRQ (Bitfield-Mask: 0x01) */ /* =============================================== CHARGER_JEITA_CURRENT_REG =============================================== */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TWARM_Pos (18UL) /*!< I_PRECHARGE_TWARM (Bit 18) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TWARM_Msk (0xfc0000UL) /*!< I_PRECHARGE_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TCOOL_Pos (12UL) /*!< I_PRECHARGE_TCOOL (Bit 12) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_PRECHARGE_TCOOL_Msk (0x3f000UL) /*!< I_PRECHARGE_TCOOL (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TWARM_Pos (6UL) /*!< I_CHARGE_TWARM (Bit 6) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TWARM_Msk (0xfc0UL) /*!< I_CHARGE_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TCOOL_Pos (0UL) /*!< I_CHARGE_TCOOL (Bit 0) */ #define CHARGER_CHARGER_JEITA_CURRENT_REG_I_CHARGE_TCOOL_Msk (0x3fUL) /*!< I_CHARGE_TCOOL (Bitfield-Mask: 0x3f) */ /* ============================================== CHARGER_JEITA_V_CHARGE_REG =============================================== */ #define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TWARM_Pos (6UL) /*!< V_CHARGE_TWARM (Bit 6) */ #define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TWARM_Msk (0xfc0UL) /*!< V_CHARGE_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TCOOL_Pos (0UL) /*!< V_CHARGE_TCOOL (Bit 0) */ #define CHARGER_CHARGER_JEITA_V_CHARGE_REG_V_CHARGE_TCOOL_Msk (0x3fUL) /*!< V_CHARGE_TCOOL (Bitfield-Mask: 0x3f) */ /* ================================================ CHARGER_JEITA_V_OVP_REG ================================================ */ #define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TWARM_Pos (6UL) /*!< V_OVP_TWARM (Bit 6) */ #define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TWARM_Msk (0xfc0UL) /*!< V_OVP_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TCOOL_Pos (0UL) /*!< V_OVP_TCOOL (Bit 0) */ #define CHARGER_CHARGER_JEITA_V_OVP_REG_V_OVP_TCOOL_Msk (0x3fUL) /*!< V_OVP_TCOOL (Bitfield-Mask: 0x3f) */ /* ============================================= CHARGER_JEITA_V_PRECHARGE_REG ============================================= */ #define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TWARM_Pos (6UL) /*!< V_PRECHARGE_TWARM (Bit 6) */ #define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TWARM_Msk (0xfc0UL) /*!< V_PRECHARGE_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TCOOL_Pos (0UL) /*!< V_PRECHARGE_TCOOL (Bit 0) */ #define CHARGER_CHARGER_JEITA_V_PRECHARGE_REG_V_PRECHARGE_TCOOL_Msk (0x3fUL) /*!< V_PRECHARGE_TCOOL (Bitfield-Mask: 0x3f) */ /* ============================================= CHARGER_JEITA_V_REPLENISH_REG ============================================= */ #define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TWARM_Pos (6UL) /*!< V_REPLENISH_TWARM (Bit 6) */ #define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TWARM_Msk (0xfc0UL) /*!< V_REPLENISH_TWARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TCOOL_Pos (0UL) /*!< V_REPLENISH_TCOOL (Bit 0) */ #define CHARGER_CHARGER_JEITA_V_REPLENISH_REG_V_REPLENISH_TCOOL_Msk (0x3fUL) /*!< V_REPLENISH_TCOOL (Bitfield-Mask: 0x3f) */ /* ============================================= CHARGER_PRE_CHARGE_TIMER_REG ============================================== */ #define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_PRE_CHARGE_TIMER_Pos (16UL) /*!< PRE_CHARGE_TIMER (Bit 16) */ #define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_PRE_CHARGE_TIMER_Msk (0x7fff0000UL) /*!< PRE_CHARGE_TIMER (Bitfield-Mask: 0x7fff) */ #define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_MAX_PRE_CHARGE_TIME_Pos (0UL) /*!< MAX_PRE_CHARGE_TIME (Bit 0) */ #define CHARGER_CHARGER_PRE_CHARGE_TIMER_REG_MAX_PRE_CHARGE_TIME_Msk (0x7fffUL) /*!< MAX_PRE_CHARGE_TIME (Bitfield-Mask: 0x7fff) */ /* =============================================== CHARGER_PWR_UP_TIMER_REG ================================================ */ #define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_TIMER_Pos (16UL) /*!< CHARGER_PWR_UP_TIMER (Bit 16) */ #define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_TIMER_Msk (0x3ff0000UL) /*!< CHARGER_PWR_UP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_SETTLING_Pos (0UL) /*!< CHARGER_PWR_UP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_PWR_UP_TIMER_REG_CHARGER_PWR_UP_SETTLING_Msk (0x3ffUL) /*!< CHARGER_PWR_UP_SETTLING (Bitfield-Mask: 0x3ff) */ /* =============================================== CHARGER_STATE_IRQ_CLR_REG =============================================== */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_PRECHARGE_IRQ_CLR_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ_CLR (Bit 11) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_PRECHARGE_IRQ_CLR_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_PRECHARGE_IRQ_CLR_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ_CLR (Bit 10) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_PRECHARGE_IRQ_CLR_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_CC_IRQ_CLR_Pos (9UL) /*!< CV_TO_CC_IRQ_CLR (Bit 9) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_CC_IRQ_CLR_Msk (0x200UL) /*!< CV_TO_CC_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_STATUS_UPDATE_IRQ_CLR_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ_CLR (Bit 8) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_STATUS_UPDATE_IRQ_CLR_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_PROT_TO_PRECHARGE_IRQ_CLR_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_CLR (Bit 7) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TBAT_PROT_TO_PRECHARGE_IRQ_CLR_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TDIE_PROT_TO_PRECHARGE_IRQ_CLR_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_CLR (Bit 6) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_TDIE_PROT_TO_PRECHARGE_IRQ_CLR_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_EOC_TO_PRECHARGE_IRQ_CLR_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ_CLR (Bit 5) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_EOC_TO_PRECHARGE_IRQ_CLR_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_EOC_IRQ_CLR_Pos (4UL) /*!< CV_TO_EOC_IRQ_CLR (Bit 4) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CV_TO_EOC_IRQ_CLR_Msk (0x10UL) /*!< CV_TO_EOC_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_EOC_IRQ_CLR_Pos (3UL) /*!< CC_TO_EOC_IRQ_CLR (Bit 3) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_EOC_IRQ_CLR_Msk (0x8UL) /*!< CC_TO_EOC_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_CV_IRQ_CLR_Pos (2UL) /*!< CC_TO_CV_IRQ_CLR (Bit 2) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_CC_TO_CV_IRQ_CLR_Msk (0x4UL) /*!< CC_TO_CV_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_PRECHARGE_TO_CC_IRQ_CLR_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ_CLR (Bit 1) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_PRECHARGE_TO_CC_IRQ_CLR_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ_CLR (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_DISABLED_TO_PRECHARGE_IRQ_CLR_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ_CLR (Bit 0) */ #define CHARGER_CHARGER_STATE_IRQ_CLR_REG_DISABLED_TO_PRECHARGE_IRQ_CLR_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ_CLR (Bitfield-Mask: 0x01) */ /* ============================================== CHARGER_STATE_IRQ_MASK_REG =============================================== */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_PRECHARGE_IRQ_EN_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ_EN (Bit 11) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_PRECHARGE_IRQ_EN_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_PRECHARGE_IRQ_EN_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ_EN (Bit 10) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_PRECHARGE_IRQ_EN_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_CC_IRQ_EN_Pos (9UL) /*!< CV_TO_CC_IRQ_EN (Bit 9) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_CC_IRQ_EN_Msk (0x200UL) /*!< CV_TO_CC_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_STATUS_UPDATE_IRQ_EN_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ_EN (Bit 8) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_STATUS_UPDATE_IRQ_EN_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_PROT_TO_PRECHARGE_IRQ_EN_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_EN (Bit 7) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TBAT_PROT_TO_PRECHARGE_IRQ_EN_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TDIE_PROT_TO_PRECHARGE_IRQ_EN_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_EN (Bit 6) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_TDIE_PROT_TO_PRECHARGE_IRQ_EN_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_EOC_TO_PRECHARGE_IRQ_EN_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ_EN (Bit 5) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_EOC_TO_PRECHARGE_IRQ_EN_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_EOC_IRQ_EN_Pos (4UL) /*!< CV_TO_EOC_IRQ_EN (Bit 4) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CV_TO_EOC_IRQ_EN_Msk (0x10UL) /*!< CV_TO_EOC_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_EOC_IRQ_EN_Pos (3UL) /*!< CC_TO_EOC_IRQ_EN (Bit 3) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_EOC_IRQ_EN_Msk (0x8UL) /*!< CC_TO_EOC_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_CV_IRQ_EN_Pos (2UL) /*!< CC_TO_CV_IRQ_EN (Bit 2) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_CC_TO_CV_IRQ_EN_Msk (0x4UL) /*!< CC_TO_CV_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_PRECHARGE_TO_CC_IRQ_EN_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ_EN (Bit 1) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_PRECHARGE_TO_CC_IRQ_EN_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ_EN (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_DISABLED_TO_PRECHARGE_IRQ_EN_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ_EN (Bit 0) */ #define CHARGER_CHARGER_STATE_IRQ_MASK_REG_DISABLED_TO_PRECHARGE_IRQ_EN_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ_EN (Bitfield-Mask: 0x01) */ /* ============================================= CHARGER_STATE_IRQ_STATUS_REG ============================================== */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_PRECHARGE_IRQ_Pos (11UL) /*!< CV_TO_PRECHARGE_IRQ (Bit 11) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_PRECHARGE_IRQ_Msk (0x800UL) /*!< CV_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_PRECHARGE_IRQ_Pos (10UL) /*!< CC_TO_PRECHARGE_IRQ (Bit 10) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_PRECHARGE_IRQ_Msk (0x400UL) /*!< CC_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_CC_IRQ_Pos (9UL) /*!< CV_TO_CC_IRQ (Bit 9) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_CC_IRQ_Msk (0x200UL) /*!< CV_TO_CC_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_STATUS_UPDATE_IRQ_Pos (8UL) /*!< TBAT_STATUS_UPDATE_IRQ (Bit 8) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_STATUS_UPDATE_IRQ_Msk (0x100UL) /*!< TBAT_STATUS_UPDATE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_PROT_TO_PRECHARGE_IRQ_Pos (7UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ (Bit 7) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TBAT_PROT_TO_PRECHARGE_IRQ_Msk (0x80UL) /*!< TBAT_PROT_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TDIE_PROT_TO_PRECHARGE_IRQ_Pos (6UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ (Bit 6) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_TDIE_PROT_TO_PRECHARGE_IRQ_Msk (0x40UL) /*!< TDIE_PROT_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_EOC_TO_PRECHARGE_IRQ_Pos (5UL) /*!< EOC_TO_PRECHARGE_IRQ (Bit 5) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_EOC_TO_PRECHARGE_IRQ_Msk (0x20UL) /*!< EOC_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_EOC_IRQ_Pos (4UL) /*!< CV_TO_EOC_IRQ (Bit 4) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CV_TO_EOC_IRQ_Msk (0x10UL) /*!< CV_TO_EOC_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_EOC_IRQ_Pos (3UL) /*!< CC_TO_EOC_IRQ (Bit 3) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_EOC_IRQ_Msk (0x8UL) /*!< CC_TO_EOC_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_CV_IRQ_Pos (2UL) /*!< CC_TO_CV_IRQ (Bit 2) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_CC_TO_CV_IRQ_Msk (0x4UL) /*!< CC_TO_CV_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_PRECHARGE_TO_CC_IRQ_Pos (1UL) /*!< PRECHARGE_TO_CC_IRQ (Bit 1) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_PRECHARGE_TO_CC_IRQ_Msk (0x2UL) /*!< PRECHARGE_TO_CC_IRQ (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_DISABLED_TO_PRECHARGE_IRQ_Pos (0UL) /*!< DISABLED_TO_PRECHARGE_IRQ (Bit 0) */ #define CHARGER_CHARGER_STATE_IRQ_STATUS_REG_DISABLED_TO_PRECHARGE_IRQ_Msk (0x1UL) /*!< DISABLED_TO_PRECHARGE_IRQ (Bitfield-Mask: 0x01) */ /* ================================================== CHARGER_STATUS_REG =================================================== */ #define CHARGER_CHARGER_STATUS_REG_OVP_EVENTS_DEBOUNCE_CNT_Pos (27UL) /*!< OVP_EVENTS_DEBOUNCE_CNT (Bit 27) */ #define CHARGER_CHARGER_STATUS_REG_OVP_EVENTS_DEBOUNCE_CNT_Msk (0x38000000UL) /*!< OVP_EVENTS_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_STATUS_REG_EOC_EVENTS_DEBOUNCE_CNT_Pos (24UL) /*!< EOC_EVENTS_DEBOUNCE_CNT (Bit 24) */ #define CHARGER_CHARGER_STATUS_REG_EOC_EVENTS_DEBOUNCE_CNT_Msk (0x7000000UL) /*!< EOC_EVENTS_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_STATUS_REG_TDIE_ERROR_DEBOUNCE_CNT_Pos (21UL) /*!< TDIE_ERROR_DEBOUNCE_CNT (Bit 21) */ #define CHARGER_CHARGER_STATUS_REG_TDIE_ERROR_DEBOUNCE_CNT_Msk (0xe00000UL) /*!< TDIE_ERROR_DEBOUNCE_CNT (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_JEITA_STATE_Pos (18UL) /*!< CHARGER_JEITA_STATE (Bit 18) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_JEITA_STATE_Msk (0x1c0000UL) /*!< CHARGER_JEITA_STATE (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_STATE_Pos (14UL) /*!< CHARGER_STATE (Bit 14) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_STATE_Msk (0x3c000UL) /*!< CHARGER_STATE (Bitfield-Mask: 0x0f) */ #define CHARGER_CHARGER_STATUS_REG_TBAT_STATUS_Pos (9UL) /*!< TBAT_STATUS (Bit 9) */ #define CHARGER_CHARGER_STATUS_REG_TBAT_STATUS_Msk (0x3e00UL) /*!< TBAT_STATUS (Bitfield-Mask: 0x1f) */ #define CHARGER_CHARGER_STATUS_REG_MAIN_TBAT_COMP_OUT_Pos (8UL) /*!< MAIN_TBAT_COMP_OUT (Bit 8) */ #define CHARGER_CHARGER_STATUS_REG_MAIN_TBAT_COMP_OUT_Msk (0x100UL) /*!< MAIN_TBAT_COMP_OUT (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_TBAT_HOT_COMP_OUT_Pos (7UL) /*!< TBAT_HOT_COMP_OUT (Bit 7) */ #define CHARGER_CHARGER_STATUS_REG_TBAT_HOT_COMP_OUT_Msk (0x80UL) /*!< TBAT_HOT_COMP_OUT (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_TDIE_COMP_OUT_Pos (6UL) /*!< TDIE_COMP_OUT (Bit 6) */ #define CHARGER_CHARGER_STATUS_REG_TDIE_COMP_OUT_Msk (0x40UL) /*!< TDIE_COMP_OUT (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_VBAT_OVP_COMP_OUT_Pos (5UL) /*!< VBAT_OVP_COMP_OUT (Bit 5) */ #define CHARGER_CHARGER_STATUS_REG_VBAT_OVP_COMP_OUT_Msk (0x20UL) /*!< VBAT_OVP_COMP_OUT (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_MAIN_VBAT_COMP_OUT_Pos (4UL) /*!< MAIN_VBAT_COMP_OUT (Bit 4) */ #define CHARGER_CHARGER_STATUS_REG_MAIN_VBAT_COMP_OUT_Msk (0x10UL) /*!< MAIN_VBAT_COMP_OUT (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_END_OF_CHARGE_Pos (3UL) /*!< END_OF_CHARGE (Bit 3) */ #define CHARGER_CHARGER_STATUS_REG_END_OF_CHARGE_Msk (0x8UL) /*!< END_OF_CHARGE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_CV_MODE_Pos (2UL) /*!< CHARGER_CV_MODE (Bit 2) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_CV_MODE_Msk (0x4UL) /*!< CHARGER_CV_MODE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_CC_MODE_Pos (1UL) /*!< CHARGER_CC_MODE (Bit 1) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_CC_MODE_Msk (0x2UL) /*!< CHARGER_CC_MODE (Bitfield-Mask: 0x01) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_IS_POWERED_UP_Pos (0UL) /*!< CHARGER_IS_POWERED_UP (Bit 0) */ #define CHARGER_CHARGER_STATUS_REG_CHARGER_IS_POWERED_UP_Msk (0x1UL) /*!< CHARGER_IS_POWERED_UP (Bitfield-Mask: 0x01) */ /* ============================================== CHARGER_TBAT_COMP_TIMER_REG ============================================== */ #define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_TIMER_Pos (16UL) /*!< TBAT_COMP_TIMER (Bit 16) */ #define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_TIMER_Msk (0x3ff0000UL) /*!< TBAT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_SETTLING_Pos (0UL) /*!< TBAT_COMP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_TBAT_COMP_TIMER_REG_TBAT_COMP_SETTLING_Msk (0x3ffUL) /*!< TBAT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ /* ============================================== CHARGER_TBAT_MON_TIMER_REG =============================================== */ #define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_TIMER_Pos (16UL) /*!< TBAT_MON_TIMER (Bit 16) */ #define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_TIMER_Msk (0x3ff0000UL) /*!< TBAT_MON_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_INTERVAL_Pos (0UL) /*!< TBAT_MON_INTERVAL (Bit 0) */ #define CHARGER_CHARGER_TBAT_MON_TIMER_REG_TBAT_MON_INTERVAL_Msk (0x3ffUL) /*!< TBAT_MON_INTERVAL (Bitfield-Mask: 0x3ff) */ /* ============================================== CHARGER_TDIE_COMP_TIMER_REG ============================================== */ #define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_TIMER_Pos (16UL) /*!< TDIE_COMP_TIMER (Bit 16) */ #define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_TIMER_Msk (0x3ff0000UL) /*!< TDIE_COMP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_SETTLING_Pos (0UL) /*!< TDIE_COMP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_TDIE_COMP_TIMER_REG_TDIE_COMP_SETTLING_Msk (0x3ffUL) /*!< TDIE_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ /* =============================================== CHARGER_TEMPSET_PARAM_REG =============================================== */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TDIE_MAX_Pos (24UL) /*!< TDIE_MAX (Bit 24) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TDIE_MAX_Msk (0x7000000UL) /*!< TDIE_MAX (Bitfield-Mask: 0x07) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_HOT_Pos (18UL) /*!< TBAT_HOT (Bit 18) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_HOT_Msk (0xfc0000UL) /*!< TBAT_HOT (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_WARM_Pos (12UL) /*!< TBAT_WARM (Bit 12) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_WARM_Msk (0x3f000UL) /*!< TBAT_WARM (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COOL_Pos (6UL) /*!< TBAT_COOL (Bit 6) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COOL_Msk (0xfc0UL) /*!< TBAT_COOL (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COLD_Pos (0UL) /*!< TBAT_COLD (Bit 0) */ #define CHARGER_CHARGER_TEMPSET_PARAM_REG_TBAT_COLD_Msk (0x3fUL) /*!< TBAT_COLD (Bitfield-Mask: 0x3f) */ /* ================================================= CHARGER_TEST_CTRL_REG ================================================= */ /* ============================================== CHARGER_THOT_COMP_TIMER_REG ============================================== */ #define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_TIMER_Pos (16UL) /*!< THOT_COMP_TIMER (Bit 16) */ #define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_TIMER_Msk (0x3ff0000UL) /*!< THOT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_SETTLING_Pos (0UL) /*!< THOT_COMP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_THOT_COMP_TIMER_REG_THOT_COMP_SETTLING_Msk (0x3ffUL) /*!< THOT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ /* ============================================ CHARGER_TOTAL_CHARGE_TIMER_REG ============================================= */ #define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_TOTAL_CHARGE_TIMER_Pos (16UL) /*!< TOTAL_CHARGE_TIMER (Bit 16) */ #define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_TOTAL_CHARGE_TIMER_Msk (0xffff0000UL) /*!< TOTAL_CHARGE_TIMER (Bitfield-Mask: 0xffff) */ #define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_MAX_TOTAL_CHARGE_TIME_Pos (0UL) /*!< MAX_TOTAL_CHARGE_TIME (Bit 0) */ #define CHARGER_CHARGER_TOTAL_CHARGE_TIMER_REG_MAX_TOTAL_CHARGE_TIME_Msk (0xffffUL) /*!< MAX_TOTAL_CHARGE_TIME (Bitfield-Mask: 0xffff) */ /* ============================================== CHARGER_VBAT_COMP_TIMER_REG ============================================== */ #define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_TIMER_Pos (16UL) /*!< VBAT_COMP_TIMER (Bit 16) */ #define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_TIMER_Msk (0x3ff0000UL) /*!< VBAT_COMP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_SETTLING_Pos (0UL) /*!< VBAT_COMP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_VBAT_COMP_TIMER_REG_VBAT_COMP_SETTLING_Msk (0x3ffUL) /*!< VBAT_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ /* =============================================== CHARGER_VOLTAGE_PARAM_REG =============================================== */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_OVP_Pos (18UL) /*!< V_OVP (Bit 18) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_OVP_Msk (0xfc0000UL) /*!< V_OVP (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_REPLENISH_Pos (12UL) /*!< V_REPLENISH (Bit 12) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_REPLENISH_Msk (0x3f000UL) /*!< V_REPLENISH (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_PRECHARGE_Pos (6UL) /*!< V_PRECHARGE (Bit 6) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_PRECHARGE_Msk (0xfc0UL) /*!< V_PRECHARGE (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_CHARGE_Pos (0UL) /*!< V_CHARGE (Bit 0) */ #define CHARGER_CHARGER_VOLTAGE_PARAM_REG_V_CHARGE_Msk (0x3fUL) /*!< V_CHARGE (Bitfield-Mask: 0x3f) */ /* ============================================== CHARGER_VOVP_COMP_TIMER_REG ============================================== */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_TIMER_Pos (26UL) /*!< OVP_INTERVAL_CHECK_TIMER (Bit 26) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_TIMER_Msk (0xfc000000UL) /*!< OVP_INTERVAL_CHECK_TIMER (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_TIMER_Pos (16UL) /*!< VBAT_OVP_COMP_TIMER (Bit 16) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_TIMER_Msk (0x3ff0000UL) /*!< VBAT_OVP_COMP_TIMER (Bitfield-Mask: 0x3ff) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_THRES_Pos (10UL) /*!< OVP_INTERVAL_CHECK_THRES (Bit 10) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_OVP_INTERVAL_CHECK_THRES_Msk (0xfc00UL) /*!< OVP_INTERVAL_CHECK_THRES (Bitfield-Mask: 0x3f) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_SETTLING_Pos (0UL) /*!< VBAT_OVP_COMP_SETTLING (Bit 0) */ #define CHARGER_CHARGER_VOVP_COMP_TIMER_REG_VBAT_OVP_COMP_SETTLING_Msk (0x3ffUL) /*!< VBAT_OVP_COMP_SETTLING (Bitfield-Mask: 0x3ff) */ /* =========================================================================================================================== */ /* ================ CHIP_VERSION ================ */ /* =========================================================================================================================== */ /* ===================================================== CHIP_ID1_REG ====================================================== */ #define CHIP_VERSION_CHIP_ID1_REG_CHIP_ID1_Pos (0UL) /*!< CHIP_ID1 (Bit 0) */ #define CHIP_VERSION_CHIP_ID1_REG_CHIP_ID1_Msk (0xffUL) /*!< CHIP_ID1 (Bitfield-Mask: 0xff) */ /* ===================================================== CHIP_ID2_REG ====================================================== */ #define CHIP_VERSION_CHIP_ID2_REG_CHIP_ID2_Pos (0UL) /*!< CHIP_ID2 (Bit 0) */ #define CHIP_VERSION_CHIP_ID2_REG_CHIP_ID2_Msk (0xffUL) /*!< CHIP_ID2 (Bitfield-Mask: 0xff) */ /* ===================================================== CHIP_ID3_REG ====================================================== */ #define CHIP_VERSION_CHIP_ID3_REG_CHIP_ID3_Pos (0UL) /*!< CHIP_ID3 (Bit 0) */ #define CHIP_VERSION_CHIP_ID3_REG_CHIP_ID3_Msk (0xffUL) /*!< CHIP_ID3 (Bitfield-Mask: 0xff) */ /* ===================================================== CHIP_ID4_REG ====================================================== */ #define CHIP_VERSION_CHIP_ID4_REG_CHIP_ID4_Pos (0UL) /*!< CHIP_ID4 (Bit 0) */ #define CHIP_VERSION_CHIP_ID4_REG_CHIP_ID4_Msk (0xffUL) /*!< CHIP_ID4 (Bitfield-Mask: 0xff) */ /* =================================================== CHIP_REVISION_REG =================================================== */ #define CHIP_VERSION_CHIP_REVISION_REG_CHIP_REVISION_Pos (0UL) /*!< CHIP_REVISION (Bit 0) */ #define CHIP_VERSION_CHIP_REVISION_REG_CHIP_REVISION_Msk (0xffUL) /*!< CHIP_REVISION (Bitfield-Mask: 0xff) */ /* ===================================================== CHIP_SWC_REG ====================================================== */ #define CHIP_VERSION_CHIP_SWC_REG_CHIP_SWC_Pos (0UL) /*!< CHIP_SWC (Bit 0) */ #define CHIP_VERSION_CHIP_SWC_REG_CHIP_SWC_Msk (0xfUL) /*!< CHIP_SWC (Bitfield-Mask: 0x0f) */ /* ==================================================== CHIP_TEST1_REG ===================================================== */ #define CHIP_VERSION_CHIP_TEST1_REG_CHIP_LAYOUT_REVISION_Pos (0UL) /*!< CHIP_LAYOUT_REVISION (Bit 0) */ #define CHIP_VERSION_CHIP_TEST1_REG_CHIP_LAYOUT_REVISION_Msk (0xffUL) /*!< CHIP_LAYOUT_REVISION (Bitfield-Mask: 0xff) */ /* ==================================================== CHIP_TEST2_REG ===================================================== */ #define CHIP_VERSION_CHIP_TEST2_REG_CHIP_METAL_OPTION_Pos (0UL) /*!< CHIP_METAL_OPTION (Bit 0) */ #define CHIP_VERSION_CHIP_TEST2_REG_CHIP_METAL_OPTION_Msk (0xfUL) /*!< CHIP_METAL_OPTION (Bitfield-Mask: 0x0f) */ /* =========================================================================================================================== */ /* ================ CRG_COM ================ */ /* =========================================================================================================================== */ /* ====================================================== CLK_COM_REG ====================================================== */ #define CRG_COM_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ #define CRG_COM_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ #define CRG_COM_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ #define CRG_COM_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ #define CRG_COM_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ #define CRG_COM_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ #define CRG_COM_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ #define CRG_COM_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ #define CRG_COM_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ #define CRG_COM_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ #define CRG_COM_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ #define CRG_COM_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ #define CRG_COM_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ #define CRG_COM_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ #define CRG_COM_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ #define CRG_COM_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ #define CRG_COM_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ #define CRG_COM_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ /* =================================================== RESET_CLK_COM_REG =================================================== */ #define CRG_COM_RESET_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ #define CRG_COM_RESET_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ #define CRG_COM_RESET_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ #define CRG_COM_RESET_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ #define CRG_COM_RESET_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ #define CRG_COM_RESET_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ #define CRG_COM_RESET_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ #define CRG_COM_RESET_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ #define CRG_COM_RESET_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ #define CRG_COM_RESET_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ #define CRG_COM_RESET_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ #define CRG_COM_RESET_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ #define CRG_COM_RESET_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ #define CRG_COM_RESET_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ #define CRG_COM_RESET_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ #define CRG_COM_RESET_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ #define CRG_COM_RESET_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_RESET_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ #define CRG_COM_RESET_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ /* ==================================================== SET_CLK_COM_REG ==================================================== */ #define CRG_COM_SET_CLK_COM_REG_LCD_EXT_CLK_SEL_Pos (16UL) /*!< LCD_EXT_CLK_SEL (Bit 16) */ #define CRG_COM_SET_CLK_COM_REG_LCD_EXT_CLK_SEL_Msk (0x30000UL) /*!< LCD_EXT_CLK_SEL (Bitfield-Mask: 0x03) */ #define CRG_COM_SET_CLK_COM_REG_SNC_DIV_Pos (14UL) /*!< SNC_DIV (Bit 14) */ #define CRG_COM_SET_CLK_COM_REG_SNC_DIV_Msk (0xc000UL) /*!< SNC_DIV (Bitfield-Mask: 0x03) */ #define CRG_COM_SET_CLK_COM_REG_I2C2_CLK_SEL_Pos (12UL) /*!< I2C2_CLK_SEL (Bit 12) */ #define CRG_COM_SET_CLK_COM_REG_I2C2_CLK_SEL_Msk (0x1000UL) /*!< I2C2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_I2C2_ENABLE_Pos (11UL) /*!< I2C2_ENABLE (Bit 11) */ #define CRG_COM_SET_CLK_COM_REG_I2C2_ENABLE_Msk (0x800UL) /*!< I2C2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_I2C_CLK_SEL_Pos (10UL) /*!< I2C_CLK_SEL (Bit 10) */ #define CRG_COM_SET_CLK_COM_REG_I2C_CLK_SEL_Msk (0x400UL) /*!< I2C_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_I2C_ENABLE_Pos (9UL) /*!< I2C_ENABLE (Bit 9) */ #define CRG_COM_SET_CLK_COM_REG_I2C_ENABLE_Msk (0x200UL) /*!< I2C_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_SPI2_CLK_SEL_Pos (8UL) /*!< SPI2_CLK_SEL (Bit 8) */ #define CRG_COM_SET_CLK_COM_REG_SPI2_CLK_SEL_Msk (0x100UL) /*!< SPI2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_SPI2_ENABLE_Pos (7UL) /*!< SPI2_ENABLE (Bit 7) */ #define CRG_COM_SET_CLK_COM_REG_SPI2_ENABLE_Msk (0x80UL) /*!< SPI2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_SPI_CLK_SEL_Pos (6UL) /*!< SPI_CLK_SEL (Bit 6) */ #define CRG_COM_SET_CLK_COM_REG_SPI_CLK_SEL_Msk (0x40UL) /*!< SPI_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_SPI_ENABLE_Pos (5UL) /*!< SPI_ENABLE (Bit 5) */ #define CRG_COM_SET_CLK_COM_REG_SPI_ENABLE_Msk (0x20UL) /*!< SPI_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_UART3_CLK_SEL_Pos (4UL) /*!< UART3_CLK_SEL (Bit 4) */ #define CRG_COM_SET_CLK_COM_REG_UART3_CLK_SEL_Msk (0x10UL) /*!< UART3_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_UART3_ENABLE_Pos (3UL) /*!< UART3_ENABLE (Bit 3) */ #define CRG_COM_SET_CLK_COM_REG_UART3_ENABLE_Msk (0x8UL) /*!< UART3_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_UART2_CLK_SEL_Pos (2UL) /*!< UART2_CLK_SEL (Bit 2) */ #define CRG_COM_SET_CLK_COM_REG_UART2_CLK_SEL_Msk (0x4UL) /*!< UART2_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_UART2_ENABLE_Pos (1UL) /*!< UART2_ENABLE (Bit 1) */ #define CRG_COM_SET_CLK_COM_REG_UART2_ENABLE_Msk (0x2UL) /*!< UART2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_COM_SET_CLK_COM_REG_UART_ENABLE_Pos (0UL) /*!< UART_ENABLE (Bit 0) */ #define CRG_COM_SET_CLK_COM_REG_UART_ENABLE_Msk (0x1UL) /*!< UART_ENABLE (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ CRG_PER ================ */ /* =========================================================================================================================== */ /* ====================================================== CLK_PER_REG ====================================================== */ #define CRG_PER_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ #define CRG_PER_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ #define CRG_PER_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ #define CRG_PER_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ #define CRG_PER_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ #define CRG_PER_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ /* ====================================================== PCM_DIV_REG ====================================================== */ #define CRG_PER_PCM_DIV_REG_PCM_SRC_SEL_Pos (13UL) /*!< PCM_SRC_SEL (Bit 13) */ #define CRG_PER_PCM_DIV_REG_PCM_SRC_SEL_Msk (0x2000UL) /*!< PCM_SRC_SEL (Bitfield-Mask: 0x01) */ #define CRG_PER_PCM_DIV_REG_CLK_PCM_EN_Pos (12UL) /*!< CLK_PCM_EN (Bit 12) */ #define CRG_PER_PCM_DIV_REG_CLK_PCM_EN_Msk (0x1000UL) /*!< CLK_PCM_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_PCM_DIV_REG_PCM_DIV_Pos (0UL) /*!< PCM_DIV (Bit 0) */ #define CRG_PER_PCM_DIV_REG_PCM_DIV_Msk (0xfffUL) /*!< PCM_DIV (Bitfield-Mask: 0xfff) */ /* ===================================================== PCM_FDIV_REG ====================================================== */ #define CRG_PER_PCM_FDIV_REG_PCM_FDIV_Pos (0UL) /*!< PCM_FDIV (Bit 0) */ #define CRG_PER_PCM_FDIV_REG_PCM_FDIV_Msk (0xffffUL) /*!< PCM_FDIV (Bitfield-Mask: 0xffff) */ /* ====================================================== PDM_DIV_REG ====================================================== */ #define CRG_PER_PDM_DIV_REG_PDM_MASTER_MODE_Pos (9UL) /*!< PDM_MASTER_MODE (Bit 9) */ #define CRG_PER_PDM_DIV_REG_PDM_MASTER_MODE_Msk (0x200UL) /*!< PDM_MASTER_MODE (Bitfield-Mask: 0x01) */ #define CRG_PER_PDM_DIV_REG_CLK_PDM_EN_Pos (8UL) /*!< CLK_PDM_EN (Bit 8) */ #define CRG_PER_PDM_DIV_REG_CLK_PDM_EN_Msk (0x100UL) /*!< CLK_PDM_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_PDM_DIV_REG_PDM_DIV_Pos (0UL) /*!< PDM_DIV (Bit 0) */ #define CRG_PER_PDM_DIV_REG_PDM_DIV_Msk (0xffUL) /*!< PDM_DIV (Bitfield-Mask: 0xff) */ /* =================================================== RESET_CLK_PER_REG =================================================== */ #define CRG_PER_RESET_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ #define CRG_PER_RESET_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_RESET_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ #define CRG_PER_RESET_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_RESET_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ #define CRG_PER_RESET_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_RESET_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ #define CRG_PER_RESET_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_RESET_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ #define CRG_PER_RESET_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ /* ==================================================== SET_CLK_PER_REG ==================================================== */ #define CRG_PER_SET_CLK_PER_REG_MC_TRIG_DIV_Pos (8UL) /*!< MC_TRIG_DIV (Bit 8) */ #define CRG_PER_SET_CLK_PER_REG_MC_TRIG_DIV_Msk (0x1f00UL) /*!< MC_TRIG_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_SET_CLK_PER_REG_MC_CLK_DIV_Pos (3UL) /*!< MC_CLK_DIV (Bit 3) */ #define CRG_PER_SET_CLK_PER_REG_MC_CLK_DIV_Msk (0xf8UL) /*!< MC_CLK_DIV (Bitfield-Mask: 0x1f) */ #define CRG_PER_SET_CLK_PER_REG_MC_CLK_EN_Pos (2UL) /*!< MC_CLK_EN (Bit 2) */ #define CRG_PER_SET_CLK_PER_REG_MC_CLK_EN_Msk (0x4UL) /*!< MC_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_SET_CLK_PER_REG_LRA_CLK_EN_Pos (1UL) /*!< LRA_CLK_EN (Bit 1) */ #define CRG_PER_SET_CLK_PER_REG_LRA_CLK_EN_Msk (0x2UL) /*!< LRA_CLK_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_SET_CLK_PER_REG_GPADC_CLK_SEL_Pos (0UL) /*!< GPADC_CLK_SEL (Bit 0) */ #define CRG_PER_SET_CLK_PER_REG_GPADC_CLK_SEL_Msk (0x1UL) /*!< GPADC_CLK_SEL (Bitfield-Mask: 0x01) */ /* ====================================================== SRC_DIV_REG ====================================================== */ #define CRG_PER_SRC_DIV_REG_CLK_SRC_EN_Pos (8UL) /*!< CLK_SRC_EN (Bit 8) */ #define CRG_PER_SRC_DIV_REG_CLK_SRC_EN_Msk (0x100UL) /*!< CLK_SRC_EN (Bitfield-Mask: 0x01) */ #define CRG_PER_SRC_DIV_REG_SRC_DIV_Pos (0UL) /*!< SRC_DIV (Bit 0) */ #define CRG_PER_SRC_DIV_REG_SRC_DIV_Msk (0xffUL) /*!< SRC_DIV (Bitfield-Mask: 0xff) */ /* =========================================================================================================================== */ /* ================ CRG_SYS ================ */ /* =========================================================================================================================== */ /* ===================================================== BATCHECK_REG ====================================================== */ #define CRG_SYS_BATCHECK_REG_BATCHECK_LOAD_ENABLE_Pos (7UL) /*!< BATCHECK_LOAD_ENABLE (Bit 7) */ #define CRG_SYS_BATCHECK_REG_BATCHECK_LOAD_ENABLE_Msk (0x80UL) /*!< BATCHECK_LOAD_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_SYS_BATCHECK_REG_BATCHECK_ILOAD_Pos (4UL) /*!< BATCHECK_ILOAD (Bit 4) */ #define CRG_SYS_BATCHECK_REG_BATCHECK_ILOAD_Msk (0x70UL) /*!< BATCHECK_ILOAD (Bitfield-Mask: 0x07) */ #define CRG_SYS_BATCHECK_REG_BATCHECK_TRIM_Pos (0UL) /*!< BATCHECK_TRIM (Bit 0) */ #define CRG_SYS_BATCHECK_REG_BATCHECK_TRIM_Msk (0xfUL) /*!< BATCHECK_TRIM (Bitfield-Mask: 0x0f) */ /* ====================================================== CLK_SYS_REG ====================================================== */ #define CRG_SYS_CLK_SYS_REG_CLK_CHG_EN_Pos (5UL) /*!< CLK_CHG_EN (Bit 5) */ #define CRG_SYS_CLK_SYS_REG_CLK_CHG_EN_Msk (0x20UL) /*!< CLK_CHG_EN (Bitfield-Mask: 0x01) */ #define CRG_SYS_CLK_SYS_REG_LCD_RESET_REQ_Pos (4UL) /*!< LCD_RESET_REQ (Bit 4) */ #define CRG_SYS_CLK_SYS_REG_LCD_RESET_REQ_Msk (0x10UL) /*!< LCD_RESET_REQ (Bitfield-Mask: 0x01) */ #define CRG_SYS_CLK_SYS_REG_LCD_CLK_SEL_Pos (1UL) /*!< LCD_CLK_SEL (Bit 1) */ #define CRG_SYS_CLK_SYS_REG_LCD_CLK_SEL_Msk (0x2UL) /*!< LCD_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_SYS_CLK_SYS_REG_LCD_ENABLE_Pos (0UL) /*!< LCD_ENABLE (Bit 0) */ #define CRG_SYS_CLK_SYS_REG_LCD_ENABLE_Msk (0x1UL) /*!< LCD_ENABLE (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ CRG_TOP ================ */ /* =========================================================================================================================== */ /* ==================================================== ANA_STATUS_REG ===================================================== */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_HIGH_Pos (14UL) /*!< COMP_VBUS_HIGH (Bit 14) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_HIGH_Msk (0x4000UL) /*!< COMP_VBUS_HIGH (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_LOW_Pos (13UL) /*!< COMP_VBUS_LOW (Bit 13) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBUS_LOW_Msk (0x2000UL) /*!< COMP_VBUS_LOW (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_HIGH_Pos (12UL) /*!< COMP_VBAT_HIGH (Bit 12) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_HIGH_Msk (0x1000UL) /*!< COMP_VBAT_HIGH (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_LOW_Pos (11UL) /*!< COMP_VBAT_LOW (Bit 11) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VBAT_LOW_Msk (0x800UL) /*!< COMP_VBAT_LOW (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VDD_OK_Pos (10UL) /*!< COMP_VDD_OK (Bit 10) */ #define CRG_TOP_ANA_STATUS_REG_COMP_VDD_OK_Msk (0x400UL) /*!< COMP_VDD_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Pos (9UL) /*!< VBUS_AVAILABLE (Bit 9) */ #define CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk (0x200UL) /*!< VBUS_AVAILABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_BANDGAP_OK_Pos (8UL) /*!< BANDGAP_OK (Bit 8) */ #define CRG_TOP_ANA_STATUS_REG_BANDGAP_OK_Msk (0x100UL) /*!< BANDGAP_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBAT_OK_Pos (7UL) /*!< LDO_3V0_VBAT_OK (Bit 7) */ #define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBAT_OK_Msk (0x80UL) /*!< LDO_3V0_VBAT_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBUS_OK_Pos (6UL) /*!< LDO_3V0_VBUS_OK (Bit 6) */ #define CRG_TOP_ANA_STATUS_REG_LDO_3V0_VBUS_OK_Msk (0x40UL) /*!< LDO_3V0_VBUS_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_1V8P_OK_Pos (5UL) /*!< LDO_1V8P_OK (Bit 5) */ #define CRG_TOP_ANA_STATUS_REG_LDO_1V8P_OK_Msk (0x20UL) /*!< LDO_1V8P_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_1V8_OK_Pos (4UL) /*!< LDO_1V8_OK (Bit 4) */ #define CRG_TOP_ANA_STATUS_REG_LDO_1V8_OK_Msk (0x10UL) /*!< LDO_1V8_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_RADIO_OK_Pos (3UL) /*!< LDO_RADIO_OK (Bit 3) */ #define CRG_TOP_ANA_STATUS_REG_LDO_RADIO_OK_Msk (0x8UL) /*!< LDO_RADIO_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_CORE_OK_Pos (2UL) /*!< LDO_CORE_OK (Bit 2) */ #define CRG_TOP_ANA_STATUS_REG_LDO_CORE_OK_Msk (0x4UL) /*!< LDO_CORE_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_LDO_VDD_HIGH_OK_Pos (1UL) /*!< LDO_VDD_HIGH_OK (Bit 1) */ #define CRG_TOP_ANA_STATUS_REG_LDO_VDD_HIGH_OK_Msk (0x2UL) /*!< LDO_VDD_HIGH_OK (Bitfield-Mask: 0x01) */ #define CRG_TOP_ANA_STATUS_REG_BOD_VIN_NOK_Pos (0UL) /*!< BOD_VIN_NOK (Bit 0) */ #define CRG_TOP_ANA_STATUS_REG_BOD_VIN_NOK_Msk (0x1UL) /*!< BOD_VIN_NOK (Bitfield-Mask: 0x01) */ /* ====================================================== BANDGAP_REG ====================================================== */ #define CRG_TOP_BANDGAP_REG_BANDGAP_ENABLE_CLAMP_Pos (12UL) /*!< BANDGAP_ENABLE_CLAMP (Bit 12) */ #define CRG_TOP_BANDGAP_REG_BANDGAP_ENABLE_CLAMP_Msk (0x1000UL) /*!< BANDGAP_ENABLE_CLAMP (Bitfield-Mask: 0x01) */ #define CRG_TOP_BANDGAP_REG_BGR_ITRIM_Pos (6UL) /*!< BGR_ITRIM (Bit 6) */ #define CRG_TOP_BANDGAP_REG_BGR_ITRIM_Msk (0xfc0UL) /*!< BGR_ITRIM (Bitfield-Mask: 0x3f) */ #define CRG_TOP_BANDGAP_REG_SYSRAM_LPMX_Pos (5UL) /*!< SYSRAM_LPMX (Bit 5) */ #define CRG_TOP_BANDGAP_REG_SYSRAM_LPMX_Msk (0x20UL) /*!< SYSRAM_LPMX (Bitfield-Mask: 0x01) */ #define CRG_TOP_BANDGAP_REG_BGR_TRIM_Pos (0UL) /*!< BGR_TRIM (Bit 0) */ #define CRG_TOP_BANDGAP_REG_BGR_TRIM_Msk (0x1fUL) /*!< BGR_TRIM (Bitfield-Mask: 0x1f) */ /* =================================================== BIAS_VREF_SEL_REG =================================================== */ #define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF2_SEL_Pos (4UL) /*!< BIAS_VREF_RF2_SEL (Bit 4) */ #define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF2_SEL_Msk (0xf0UL) /*!< BIAS_VREF_RF2_SEL (Bitfield-Mask: 0x0f) */ #define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF1_SEL_Pos (0UL) /*!< BIAS_VREF_RF1_SEL (Bit 0) */ #define CRG_TOP_BIAS_VREF_SEL_REG_BIAS_VREF_RF1_SEL_Msk (0xfUL) /*!< BIAS_VREF_RF1_SEL (Bitfield-Mask: 0x0f) */ /* ===================================================== BOD_CTRL_REG ====================================================== */ #define CRG_TOP_BOD_CTRL_REG_BOD_V14_RST_EN_Pos (16UL) /*!< BOD_V14_RST_EN (Bit 16) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V14_RST_EN_Msk (0x10000UL) /*!< BOD_V14_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18F_RST_EN_Pos (15UL) /*!< BOD_V18F_RST_EN (Bit 15) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18F_RST_EN_Msk (0x8000UL) /*!< BOD_V18F_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VDD_RST_EN_Pos (14UL) /*!< BOD_VDD_RST_EN (Bit 14) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VDD_RST_EN_Msk (0x4000UL) /*!< BOD_VDD_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18P_RST_EN_Pos (13UL) /*!< BOD_V18P_RST_EN (Bit 13) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18P_RST_EN_Msk (0x2000UL) /*!< BOD_V18P_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18_RST_EN_Pos (12UL) /*!< BOD_V18_RST_EN (Bit 12) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18_RST_EN_Msk (0x1000UL) /*!< BOD_V18_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V30_RST_EN_Pos (11UL) /*!< BOD_V30_RST_EN (Bit 11) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V30_RST_EN_Msk (0x800UL) /*!< BOD_V30_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_RST_EN_Pos (10UL) /*!< BOD_VBAT_RST_EN (Bit 10) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_RST_EN_Msk (0x400UL) /*!< BOD_VBAT_RST_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Pos (9UL) /*!< BOD_V14_EN (Bit 9) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Msk (0x200UL) /*!< BOD_V14_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Pos (8UL) /*!< BOD_V18F_EN (Bit 8) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Msk (0x100UL) /*!< BOD_V18F_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Pos (7UL) /*!< BOD_VDD_EN (Bit 7) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Msk (0x80UL) /*!< BOD_VDD_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Pos (6UL) /*!< BOD_V18P_EN (Bit 6) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Msk (0x40UL) /*!< BOD_V18P_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Pos (5UL) /*!< BOD_V18_EN (Bit 5) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Msk (0x20UL) /*!< BOD_V18_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Pos (4UL) /*!< BOD_V30_EN (Bit 4) */ #define CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Msk (0x10UL) /*!< BOD_V30_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Pos (3UL) /*!< BOD_VBAT_EN (Bit 3) */ #define CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Msk (0x8UL) /*!< BOD_VBAT_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_STATUS_CLEAR_Pos (2UL) /*!< BOD_STATUS_CLEAR (Bit 2) */ #define CRG_TOP_BOD_CTRL_REG_BOD_STATUS_CLEAR_Msk (0x4UL) /*!< BOD_STATUS_CLEAR (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_CTRL_REG_BOD_CLK_DIV_Pos (0UL) /*!< BOD_CLK_DIV (Bit 0) */ #define CRG_TOP_BOD_CTRL_REG_BOD_CLK_DIV_Msk (0x3UL) /*!< BOD_CLK_DIV (Bitfield-Mask: 0x03) */ /* =================================================== BOD_LVL_CTRL0_REG =================================================== */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V18_Pos (18UL) /*!< BOD_LVL_V18 (Bit 18) */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V18_Msk (0x7fc0000UL) /*!< BOD_LVL_V18 (Bitfield-Mask: 0x1ff) */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V30_Pos (9UL) /*!< BOD_LVL_V30 (Bit 9) */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_V30_Msk (0x3fe00UL) /*!< BOD_LVL_V30 (Bitfield-Mask: 0x1ff) */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_VBAT_Pos (0UL) /*!< BOD_LVL_VBAT (Bit 0) */ #define CRG_TOP_BOD_LVL_CTRL0_REG_BOD_LVL_VBAT_Msk (0x1ffUL) /*!< BOD_LVL_VBAT (Bitfield-Mask: 0x1ff) */ /* =================================================== BOD_LVL_CTRL1_REG =================================================== */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_RET_Pos (17UL) /*!< BOD_LVL_VDD_RET (Bit 17) */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_RET_Msk (0x1fe0000UL) /*!< BOD_LVL_VDD_RET (Bitfield-Mask: 0xff) */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_ON_Pos (9UL) /*!< BOD_LVL_VDD_ON (Bit 9) */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_VDD_ON_Msk (0x1fe00UL) /*!< BOD_LVL_VDD_ON (Bitfield-Mask: 0xff) */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_V18P_Pos (0UL) /*!< BOD_LVL_V18P (Bit 0) */ #define CRG_TOP_BOD_LVL_CTRL1_REG_BOD_LVL_V18P_Msk (0x1ffUL) /*!< BOD_LVL_V18P (Bitfield-Mask: 0x1ff) */ /* =================================================== BOD_LVL_CTRL2_REG =================================================== */ #define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V14_Pos (9UL) /*!< BOD_LVL_V14 (Bit 9) */ #define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V14_Msk (0x3fe00UL) /*!< BOD_LVL_V14 (Bitfield-Mask: 0x1ff) */ #define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V18F_Pos (0UL) /*!< BOD_LVL_V18F (Bit 0) */ #define CRG_TOP_BOD_LVL_CTRL2_REG_BOD_LVL_V18F_Msk (0x1ffUL) /*!< BOD_LVL_V18F (Bitfield-Mask: 0x1ff) */ /* ==================================================== BOD_STATUS_REG ===================================================== */ #define CRG_TOP_BOD_STATUS_REG_BOD_V14_Pos (6UL) /*!< BOD_V14 (Bit 6) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V14_Msk (0x40UL) /*!< BOD_V14 (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18F_Pos (5UL) /*!< BOD_V18F (Bit 5) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18F_Msk (0x20UL) /*!< BOD_V18F (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_VDD_Pos (4UL) /*!< BOD_VDD (Bit 4) */ #define CRG_TOP_BOD_STATUS_REG_BOD_VDD_Msk (0x10UL) /*!< BOD_VDD (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18P_Pos (3UL) /*!< BOD_V18P (Bit 3) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18P_Msk (0x8UL) /*!< BOD_V18P (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18_Pos (2UL) /*!< BOD_V18 (Bit 2) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V18_Msk (0x4UL) /*!< BOD_V18 (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V30_Pos (1UL) /*!< BOD_V30 (Bit 1) */ #define CRG_TOP_BOD_STATUS_REG_BOD_V30_Msk (0x2UL) /*!< BOD_V30 (Bitfield-Mask: 0x01) */ #define CRG_TOP_BOD_STATUS_REG_BOD_VBAT_Pos (0UL) /*!< BOD_VBAT (Bit 0) */ #define CRG_TOP_BOD_STATUS_REG_BOD_VBAT_Msk (0x1UL) /*!< BOD_VBAT (Bitfield-Mask: 0x01) */ /* ===================================================== CLK_AMBA_REG ====================================================== */ #define CRG_TOP_CLK_AMBA_REG_QSPI2_ENABLE_Pos (15UL) /*!< QSPI2_ENABLE (Bit 15) */ #define CRG_TOP_CLK_AMBA_REG_QSPI2_ENABLE_Msk (0x8000UL) /*!< QSPI2_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_AMBA_REG_QSPI2_DIV_Pos (13UL) /*!< QSPI2_DIV (Bit 13) */ #define CRG_TOP_CLK_AMBA_REG_QSPI2_DIV_Msk (0x6000UL) /*!< QSPI2_DIV (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_AMBA_REG_QSPI_ENABLE_Pos (12UL) /*!< QSPI_ENABLE (Bit 12) */ #define CRG_TOP_CLK_AMBA_REG_QSPI_ENABLE_Msk (0x1000UL) /*!< QSPI_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_AMBA_REG_QSPI_DIV_Pos (10UL) /*!< QSPI_DIV (Bit 10) */ #define CRG_TOP_CLK_AMBA_REG_QSPI_DIV_Msk (0xc00UL) /*!< QSPI_DIV (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Pos (9UL) /*!< OTP_ENABLE (Bit 9) */ #define CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk (0x200UL) /*!< OTP_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Pos (8UL) /*!< TRNG_CLK_ENABLE (Bit 8) */ #define CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Msk (0x100UL) /*!< TRNG_CLK_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Pos (6UL) /*!< AES_CLK_ENABLE (Bit 6) */ #define CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk (0x40UL) /*!< AES_CLK_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Pos (4UL) /*!< PCLK_DIV (Bit 4) */ #define CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk (0x30UL) /*!< PCLK_DIV (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Pos (0UL) /*!< HCLK_DIV (Bit 0) */ #define CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk (0x7UL) /*!< HCLK_DIV (Bitfield-Mask: 0x07) */ /* ===================================================== CLK_CTRL_REG ====================================================== */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Pos (15UL) /*!< RUNNING_AT_PLL96M (Bit 15) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk (0x8000UL) /*!< RUNNING_AT_PLL96M (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Pos (14UL) /*!< RUNNING_AT_XTAL32M (Bit 14) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk (0x4000UL) /*!< RUNNING_AT_XTAL32M (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Pos (13UL) /*!< RUNNING_AT_RC32M (Bit 13) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk (0x2000UL) /*!< RUNNING_AT_RC32M (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Pos (12UL) /*!< RUNNING_AT_LP_CLK (Bit 12) */ #define CRG_TOP_CLK_CTRL_REG_RUNNING_AT_LP_CLK_Msk (0x1000UL) /*!< RUNNING_AT_LP_CLK (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Pos (4UL) /*!< USB_CLK_SRC (Bit 4) */ #define CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk (0x10UL) /*!< USB_CLK_SRC (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos (2UL) /*!< LP_CLK_SEL (Bit 2) */ #define CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk (0xcUL) /*!< LP_CLK_SEL (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos (0UL) /*!< SYS_CLK_SEL (Bit 0) */ #define CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk (0x3UL) /*!< SYS_CLK_SEL (Bitfield-Mask: 0x03) */ /* ===================================================== CLK_RADIO_REG ===================================================== */ #define CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos (5UL) /*!< RFCU_ENABLE (Bit 5) */ #define CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Msk (0x20UL) /*!< RFCU_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos (4UL) /*!< CMAC_SYNCH_RESET (Bit 4) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk (0x10UL) /*!< CMAC_SYNCH_RESET (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos (3UL) /*!< CMAC_CLK_SEL (Bit 3) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Msk (0x8UL) /*!< CMAC_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos (2UL) /*!< CMAC_CLK_ENABLE (Bit 2) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Msk (0x4UL) /*!< CMAC_CLK_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos (0UL) /*!< CMAC_DIV (Bit 0) */ #define CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Msk (0x3UL) /*!< CMAC_DIV (Bitfield-Mask: 0x03) */ /* ===================================================== CLK_RC32K_REG ===================================================== */ #define CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Pos (1UL) /*!< RC32K_TRIM (Bit 1) */ #define CRG_TOP_CLK_RC32K_REG_RC32K_TRIM_Msk (0x1eUL) /*!< RC32K_TRIM (Bitfield-Mask: 0x0f) */ #define CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Pos (0UL) /*!< RC32K_ENABLE (Bit 0) */ #define CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk (0x1UL) /*!< RC32K_ENABLE (Bitfield-Mask: 0x01) */ /* ===================================================== CLK_RC32M_REG ===================================================== */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_RANGE_Pos (20UL) /*!< RC32M_INIT_RANGE (Bit 20) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_RANGE_Msk (0x300000UL) /*!< RC32M_INIT_RANGE (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DEL_Pos (12UL) /*!< RC32M_INIT_DEL (Bit 12) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DEL_Msk (0xff000UL) /*!< RC32M_INIT_DEL (Bitfield-Mask: 0xff) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTCF_Pos (9UL) /*!< RC32M_INIT_DTCF (Bit 9) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTCF_Msk (0xe00UL) /*!< RC32M_INIT_DTCF (Bitfield-Mask: 0x07) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTC_Pos (5UL) /*!< RC32M_INIT_DTC (Bit 5) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_INIT_DTC_Msk (0x1e0UL) /*!< RC32M_INIT_DTC (Bitfield-Mask: 0x0f) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_BIAS_Pos (1UL) /*!< RC32M_BIAS (Bit 1) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_BIAS_Msk (0x1eUL) /*!< RC32M_BIAS (Bitfield-Mask: 0x0f) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Pos (0UL) /*!< RC32M_ENABLE (Bit 0) */ #define CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk (0x1UL) /*!< RC32M_ENABLE (Bitfield-Mask: 0x01) */ /* ====================================================== CLK_RCX_REG ====================================================== */ #define CRG_TOP_CLK_RCX_REG_RCX_BIAS_Pos (8UL) /*!< RCX_BIAS (Bit 8) */ #define CRG_TOP_CLK_RCX_REG_RCX_BIAS_Msk (0xf00UL) /*!< RCX_BIAS (Bitfield-Mask: 0x0f) */ #define CRG_TOP_CLK_RCX_REG_RCX_C0_Pos (7UL) /*!< RCX_C0 (Bit 7) */ #define CRG_TOP_CLK_RCX_REG_RCX_C0_Msk (0x80UL) /*!< RCX_C0 (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RCX_REG_RCX_CADJUST_Pos (2UL) /*!< RCX_CADJUST (Bit 2) */ #define CRG_TOP_CLK_RCX_REG_RCX_CADJUST_Msk (0x7cUL) /*!< RCX_CADJUST (Bitfield-Mask: 0x1f) */ #define CRG_TOP_CLK_RCX_REG_RCX_RADJUST_Pos (1UL) /*!< RCX_RADJUST (Bit 1) */ #define CRG_TOP_CLK_RCX_REG_RCX_RADJUST_Msk (0x2UL) /*!< RCX_RADJUST (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Pos (0UL) /*!< RCX_ENABLE (Bit 0) */ #define CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk (0x1UL) /*!< RCX_ENABLE (Bitfield-Mask: 0x01) */ /* ==================================================== CLK_RTCDIV_REG ===================================================== */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_RESET_REQ_Pos (21UL) /*!< RTC_RESET_REQ (Bit 21) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_RESET_REQ_Msk (0x200000UL) /*!< RTC_RESET_REQ (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Pos (20UL) /*!< RTC_DIV_ENABLE (Bit 20) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_ENABLE_Msk (0x100000UL) /*!< RTC_DIV_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Pos (19UL) /*!< RTC_DIV_DENOM (Bit 19) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_DENOM_Msk (0x80000UL) /*!< RTC_DIV_DENOM (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Pos (10UL) /*!< RTC_DIV_INT (Bit 10) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_INT_Msk (0x7fc00UL) /*!< RTC_DIV_INT (Bitfield-Mask: 0x1ff) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Pos (0UL) /*!< RTC_DIV_FRAC (Bit 0) */ #define CRG_TOP_CLK_RTCDIV_REG_RTC_DIV_FRAC_Msk (0x3ffUL) /*!< RTC_DIV_FRAC (Bitfield-Mask: 0x3ff) */ /* ================================================== CLK_SWITCH2XTAL_REG ================================================== */ #define CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Pos (0UL) /*!< SWITCH2XTAL (Bit 0) */ #define CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk (0x1UL) /*!< SWITCH2XTAL (Bitfield-Mask: 0x01) */ /* ====================================================== CLK_TMR_REG ====================================================== */ #define CRG_TOP_CLK_TMR_REG_TMR2_PWM_AON_MODE_Pos (2UL) /*!< TMR2_PWM_AON_MODE (Bit 2) */ #define CRG_TOP_CLK_TMR_REG_TMR2_PWM_AON_MODE_Msk (0x4UL) /*!< TMR2_PWM_AON_MODE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_TMR_REG_TMR_PWM_AON_MODE_Pos (1UL) /*!< TMR_PWM_AON_MODE (Bit 1) */ #define CRG_TOP_CLK_TMR_REG_TMR_PWM_AON_MODE_Msk (0x2UL) /*!< TMR_PWM_AON_MODE (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Pos (0UL) /*!< WAKEUPCT_ENABLE (Bit 0) */ #define CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk (0x1UL) /*!< WAKEUPCT_ENABLE (Bitfield-Mask: 0x01) */ /* ==================================================== CLK_XTAL32K_REG ==================================================== */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_OUTPUT_Pos (9UL) /*!< XTAL32K_DISABLE_OUTPUT (Bit 9) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_OUTPUT_Msk (0x200UL) /*!< XTAL32K_DISABLE_OUTPUT (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_AMPREG_Pos (7UL) /*!< XTAL32K_DISABLE_AMPREG (Bit 7) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_DISABLE_AMPREG_Msk (0x80UL) /*!< XTAL32K_DISABLE_AMPREG (Bitfield-Mask: 0x01) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_CUR_Pos (3UL) /*!< XTAL32K_CUR (Bit 3) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_CUR_Msk (0x78UL) /*!< XTAL32K_CUR (Bitfield-Mask: 0x0f) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_RBIAS_Pos (1UL) /*!< XTAL32K_RBIAS (Bit 1) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_RBIAS_Msk (0x6UL) /*!< XTAL32K_RBIAS (Bitfield-Mask: 0x03) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Pos (0UL) /*!< XTAL32K_ENABLE (Bit 0) */ #define CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk (0x1UL) /*!< XTAL32K_ENABLE (Bitfield-Mask: 0x01) */ /* ================================================== DISCHARGE_RAIL_REG =================================================== */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18P_Pos (2UL) /*!< RESET_V18P (Bit 2) */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18P_Msk (0x4UL) /*!< RESET_V18P (Bitfield-Mask: 0x01) */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18_Pos (1UL) /*!< RESET_V18 (Bit 1) */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V18_Msk (0x2UL) /*!< RESET_V18 (Bitfield-Mask: 0x01) */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V14_Pos (0UL) /*!< RESET_V14 (Bit 0) */ #define CRG_TOP_DISCHARGE_RAIL_REG_RESET_V14_Msk (0x1UL) /*!< RESET_V14 (Bitfield-Mask: 0x01) */ /* ================================================ LDO_VDDD_HIGH_CTRL_REG ================================================= */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_LOW_ZOUT_DISABLE_Pos (3UL) /*!< LDO_VDDD_HIGH_LOW_ZOUT_DISABLE (Bit 3) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_LOW_ZOUT_DISABLE_Msk (0x8UL) /*!< LDO_VDDD_HIGH_LOW_ZOUT_DISABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_STATIC_LOAD_ENABLE_Pos (2UL) /*!< LDO_VDDD_HIGH_STATIC_LOAD_ENABLE (Bit 2) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_STATIC_LOAD_ENABLE_Msk (0x4UL) /*!< LDO_VDDD_HIGH_STATIC_LOAD_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_ENABLE_Pos (1UL) /*!< LDO_VDDD_HIGH_ENABLE (Bit 1) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_ENABLE_Msk (0x2UL) /*!< LDO_VDDD_HIGH_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_VREF_HOLD_Pos (0UL) /*!< LDO_VDDD_HIGH_VREF_HOLD (Bit 0) */ #define CRG_TOP_LDO_VDDD_HIGH_CTRL_REG_LDO_VDDD_HIGH_VREF_HOLD_Msk (0x1UL) /*!< LDO_VDDD_HIGH_VREF_HOLD (Bitfield-Mask: 0x01) */ /* =================================================== P0_PAD_LATCH_REG ==================================================== */ #define CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Pos (0UL) /*!< P0_LATCH_EN (Bit 0) */ #define CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk (0xffffffffUL) /*!< P0_LATCH_EN (Bitfield-Mask: 0xffffffff) */ /* ================================================ P0_RESET_PAD_LATCH_REG ================================================= */ #define CRG_TOP_P0_RESET_PAD_LATCH_REG_P0_RESET_LATCH_EN_Pos (0UL) /*!< P0_RESET_LATCH_EN (Bit 0) */ #define CRG_TOP_P0_RESET_PAD_LATCH_REG_P0_RESET_LATCH_EN_Msk (0xffffffffUL) /*!< P0_RESET_LATCH_EN (Bitfield-Mask: 0xffffffff) */ /* ================================================= P0_SET_PAD_LATCH_REG ================================================== */ #define CRG_TOP_P0_SET_PAD_LATCH_REG_P0_SET_LATCH_EN_Pos (0UL) /*!< P0_SET_LATCH_EN (Bit 0) */ #define CRG_TOP_P0_SET_PAD_LATCH_REG_P0_SET_LATCH_EN_Msk (0xffffffffUL) /*!< P0_SET_LATCH_EN (Bitfield-Mask: 0xffffffff) */ /* =================================================== P1_PAD_LATCH_REG ==================================================== */ #define CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Pos (0UL) /*!< P1_LATCH_EN (Bit 0) */ #define CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk (0x7fffffUL) /*!< P1_LATCH_EN (Bitfield-Mask: 0x7fffff) */ /* ================================================ P1_RESET_PAD_LATCH_REG ================================================= */ #define CRG_TOP_P1_RESET_PAD_LATCH_REG_P1_RESET_LATCH_EN_Pos (0UL) /*!< P1_RESET_LATCH_EN (Bit 0) */ #define CRG_TOP_P1_RESET_PAD_LATCH_REG_P1_RESET_LATCH_EN_Msk (0x7fffffUL) /*!< P1_RESET_LATCH_EN (Bitfield-Mask: 0x7fffff) */ /* ================================================= P1_SET_PAD_LATCH_REG ================================================== */ #define CRG_TOP_P1_SET_PAD_LATCH_REG_P1_SET_LATCH_EN_Pos (0UL) /*!< P1_SET_LATCH_EN (Bit 0) */ #define CRG_TOP_P1_SET_PAD_LATCH_REG_P1_SET_LATCH_EN_Msk (0x7fffffUL) /*!< P1_SET_LATCH_EN (Bitfield-Mask: 0x7fffff) */ /* ===================================================== PMU_CTRL_REG ====================================================== */ #define CRG_TOP_PMU_CTRL_REG_ENABLE_CLKLESS_Pos (8UL) /*!< ENABLE_CLKLESS (Bit 8) */ #define CRG_TOP_PMU_CTRL_REG_ENABLE_CLKLESS_Msk (0x100UL) /*!< ENABLE_CLKLESS (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_RETAIN_CACHE_Pos (7UL) /*!< RETAIN_CACHE (Bit 7) */ #define CRG_TOP_PMU_CTRL_REG_RETAIN_CACHE_Msk (0x80UL) /*!< RETAIN_CACHE (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_SYS_SLEEP_Pos (6UL) /*!< SYS_SLEEP (Bit 6) */ #define CRG_TOP_PMU_CTRL_REG_SYS_SLEEP_Msk (0x40UL) /*!< SYS_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_RESET_ON_WAKEUP_Pos (5UL) /*!< RESET_ON_WAKEUP (Bit 5) */ #define CRG_TOP_PMU_CTRL_REG_RESET_ON_WAKEUP_Msk (0x20UL) /*!< RESET_ON_WAKEUP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_MAP_BANDGAP_EN_Pos (4UL) /*!< MAP_BANDGAP_EN (Bit 4) */ #define CRG_TOP_PMU_CTRL_REG_MAP_BANDGAP_EN_Msk (0x10UL) /*!< MAP_BANDGAP_EN (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Pos (3UL) /*!< COM_SLEEP (Bit 3) */ #define CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Msk (0x8UL) /*!< COM_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Pos (2UL) /*!< TIM_SLEEP (Bit 2) */ #define CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Msk (0x4UL) /*!< TIM_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Pos (1UL) /*!< RADIO_SLEEP (Bit 1) */ #define CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk (0x2UL) /*!< RADIO_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Pos (0UL) /*!< PERIPH_SLEEP (Bit 0) */ #define CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Msk (0x1UL) /*!< PERIPH_SLEEP (Bitfield-Mask: 0x01) */ /* ===================================================== PMU_SLEEP_REG ===================================================== */ #define CRG_TOP_PMU_SLEEP_REG_CLAMP_VDD_WKUP_MAX_Pos (18UL) /*!< CLAMP_VDD_WKUP_MAX (Bit 18) */ #define CRG_TOP_PMU_SLEEP_REG_CLAMP_VDD_WKUP_MAX_Msk (0x40000UL) /*!< CLAMP_VDD_WKUP_MAX (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_SLEEP_REG_ULTRA_FAST_WAKEUP_Pos (17UL) /*!< ULTRA_FAST_WAKEUP (Bit 17) */ #define CRG_TOP_PMU_SLEEP_REG_ULTRA_FAST_WAKEUP_Msk (0x20000UL) /*!< ULTRA_FAST_WAKEUP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_SLEEP_REG_FAST_WAKEUP_Pos (16UL) /*!< FAST_WAKEUP (Bit 16) */ #define CRG_TOP_PMU_SLEEP_REG_FAST_WAKEUP_Msk (0x10000UL) /*!< FAST_WAKEUP (Bitfield-Mask: 0x01) */ #define CRG_TOP_PMU_SLEEP_REG_BOD_SLEEP_INTERVAL_Pos (12UL) /*!< BOD_SLEEP_INTERVAL (Bit 12) */ #define CRG_TOP_PMU_SLEEP_REG_BOD_SLEEP_INTERVAL_Msk (0xf000UL) /*!< BOD_SLEEP_INTERVAL (Bitfield-Mask: 0x0f) */ #define CRG_TOP_PMU_SLEEP_REG_BG_REFRESH_INTERVAL_Pos (0UL) /*!< BG_REFRESH_INTERVAL (Bit 0) */ #define CRG_TOP_PMU_SLEEP_REG_BG_REFRESH_INTERVAL_Msk (0xfffUL) /*!< BG_REFRESH_INTERVAL (Bitfield-Mask: 0xfff) */ /* ===================================================== PMU_TRIM_REG ====================================================== */ #define CRG_TOP_PMU_TRIM_REG_LDO_1V8_TRIM_Pos (12UL) /*!< LDO_1V8_TRIM (Bit 12) */ #define CRG_TOP_PMU_TRIM_REG_LDO_1V8_TRIM_Msk (0xf000UL) /*!< LDO_1V8_TRIM (Bitfield-Mask: 0x0f) */ #define CRG_TOP_PMU_TRIM_REG_LDO_1V8P_TRIM_Pos (8UL) /*!< LDO_1V8P_TRIM (Bit 8) */ #define CRG_TOP_PMU_TRIM_REG_LDO_1V8P_TRIM_Msk (0xf00UL) /*!< LDO_1V8P_TRIM (Bitfield-Mask: 0x0f) */ #define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBAT_TRIM_Pos (4UL) /*!< LDO_SUPPLY_VBAT_TRIM (Bit 4) */ #define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBAT_TRIM_Msk (0xf0UL) /*!< LDO_SUPPLY_VBAT_TRIM (Bitfield-Mask: 0x0f) */ #define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBUS_TRIM_Pos (0UL) /*!< LDO_SUPPLY_VBUS_TRIM (Bit 0) */ #define CRG_TOP_PMU_TRIM_REG_LDO_SUPPLY_VBUS_TRIM_Msk (0xfUL) /*!< LDO_SUPPLY_VBUS_TRIM (Bitfield-Mask: 0x0f) */ /* ====================================================== POR_PIN_REG ====================================================== */ #define CRG_TOP_POR_PIN_REG_POR_PIN_POLARITY_Pos (7UL) /*!< POR_PIN_POLARITY (Bit 7) */ #define CRG_TOP_POR_PIN_REG_POR_PIN_POLARITY_Msk (0x80UL) /*!< POR_PIN_POLARITY (Bitfield-Mask: 0x01) */ #define CRG_TOP_POR_PIN_REG_POR_PIN_SELECT_Pos (0UL) /*!< POR_PIN_SELECT (Bit 0) */ #define CRG_TOP_POR_PIN_REG_POR_PIN_SELECT_Msk (0x3fUL) /*!< POR_PIN_SELECT (Bitfield-Mask: 0x3f) */ /* ===================================================== POR_TIMER_REG ===================================================== */ #define CRG_TOP_POR_TIMER_REG_POR_TIME_Pos (0UL) /*!< POR_TIME (Bit 0) */ #define CRG_TOP_POR_TIMER_REG_POR_TIME_Msk (0x7fUL) /*!< POR_TIME (Bitfield-Mask: 0x7f) */ /* =================================================== POR_VBAT_CTRL_REG =================================================== */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_MASK_N_Pos (13UL) /*!< POR_VBAT_MASK_N (Bit 13) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_MASK_N_Msk (0x2000UL) /*!< POR_VBAT_MASK_N (Bitfield-Mask: 0x01) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_ENABLE_Pos (12UL) /*!< POR_VBAT_ENABLE (Bit 12) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_ENABLE_Msk (0x1000UL) /*!< POR_VBAT_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_HYST_LOW_Pos (8UL) /*!< POR_VBAT_HYST_LOW (Bit 8) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_HYST_LOW_Msk (0xf00UL) /*!< POR_VBAT_HYST_LOW (Bitfield-Mask: 0x0f) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_HIGH_Pos (4UL) /*!< POR_VBAT_THRES_HIGH (Bit 4) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_HIGH_Msk (0xf0UL) /*!< POR_VBAT_THRES_HIGH (Bitfield-Mask: 0x0f) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_LOW_Pos (0UL) /*!< POR_VBAT_THRES_LOW (Bit 0) */ #define CRG_TOP_POR_VBAT_CTRL_REG_POR_VBAT_THRES_LOW_Msk (0xfUL) /*!< POR_VBAT_THRES_LOW (Bitfield-Mask: 0x0f) */ /* ==================================================== POWER_CTRL_REG ===================================================== */ #define CRG_TOP_POWER_CTRL_REG_VDD_SLEEP_LEVEL_Pos (29UL) /*!< VDD_SLEEP_LEVEL (Bit 29) */ #define CRG_TOP_POWER_CTRL_REG_VDD_SLEEP_LEVEL_Msk (0xe0000000UL) /*!< VDD_SLEEP_LEVEL (Bitfield-Mask: 0x07) */ #define CRG_TOP_POWER_CTRL_REG_VDD_CLAMP_LEVEL_Pos (25UL) /*!< VDD_CLAMP_LEVEL (Bit 25) */ #define CRG_TOP_POWER_CTRL_REG_VDD_CLAMP_LEVEL_Msk (0x1e000000UL) /*!< VDD_CLAMP_LEVEL (Bitfield-Mask: 0x0f) */ #define CRG_TOP_POWER_CTRL_REG_CLAMP_3V0_VBAT_ENABLE_Pos (24UL) /*!< CLAMP_3V0_VBAT_ENABLE (Bit 24) */ #define CRG_TOP_POWER_CTRL_REG_CLAMP_3V0_VBAT_ENABLE_Msk (0x1000000UL) /*!< CLAMP_3V0_VBAT_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_V18_LEVEL_Pos (23UL) /*!< V18_LEVEL (Bit 23) */ #define CRG_TOP_POWER_CTRL_REG_V18_LEVEL_Msk (0x800000UL) /*!< V18_LEVEL (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_V14_LEVEL_Pos (20UL) /*!< V14_LEVEL (Bit 20) */ #define CRG_TOP_POWER_CTRL_REG_V14_LEVEL_Msk (0x700000UL) /*!< V14_LEVEL (Bitfield-Mask: 0x07) */ #define CRG_TOP_POWER_CTRL_REG_V30_LEVEL_Pos (18UL) /*!< V30_LEVEL (Bit 18) */ #define CRG_TOP_POWER_CTRL_REG_V30_LEVEL_Msk (0xc0000UL) /*!< V30_LEVEL (Bitfield-Mask: 0x03) */ #define CRG_TOP_POWER_CTRL_REG_VDD_LEVEL_Pos (16UL) /*!< VDD_LEVEL (Bit 16) */ #define CRG_TOP_POWER_CTRL_REG_VDD_LEVEL_Msk (0x30000UL) /*!< VDD_LEVEL (Bitfield-Mask: 0x03) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Pos (15UL) /*!< LDO_3V0_REF (Bit 15) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Msk (0x8000UL) /*!< LDO_3V0_REF (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Pos (14UL) /*!< LDO_CORE_RET_ENABLE_SLEEP (Bit 14) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Msk (0x4000UL) /*!< LDO_CORE_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_ACTIVE_Pos (13UL) /*!< LDO_CORE_RET_ENABLE_ACTIVE (Bit 13) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_ACTIVE_Msk (0x2000UL) /*!< LDO_CORE_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_ENABLE_Pos (12UL) /*!< LDO_CORE_ENABLE (Bit 12) */ #define CRG_TOP_POWER_CTRL_REG_LDO_CORE_ENABLE_Msk (0x1000UL) /*!< LDO_CORE_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Pos (11UL) /*!< LDO_3V0_RET_ENABLE_SLEEP (Bit 11) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Msk (0x800UL) /*!< LDO_3V0_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_ACTIVE_Pos (10UL) /*!< LDO_3V0_RET_ENABLE_ACTIVE (Bit 10) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_ACTIVE_Msk (0x400UL) /*!< LDO_3V0_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_MODE_Pos (8UL) /*!< LDO_3V0_MODE (Bit 8) */ #define CRG_TOP_POWER_CTRL_REG_LDO_3V0_MODE_Msk (0x300UL) /*!< LDO_3V0_MODE (Bitfield-Mask: 0x03) */ #define CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Pos (7UL) /*!< LDO_RADIO_ENABLE (Bit 7) */ #define CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk (0x80UL) /*!< LDO_RADIO_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Pos (6UL) /*!< LDO_1V8_RET_ENABLE_SLEEP (Bit 6) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Msk (0x40UL) /*!< LDO_1V8_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_ACTIVE_Pos (5UL) /*!< LDO_1V8_RET_ENABLE_ACTIVE (Bit 5) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_ACTIVE_Msk (0x20UL) /*!< LDO_1V8_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_ENABLE_Pos (4UL) /*!< LDO_1V8_ENABLE (Bit 4) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8_ENABLE_Msk (0x10UL) /*!< LDO_1V8_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_SW_1V8F_ENABLE_FORCE_Pos (3UL) /*!< SW_1V8F_ENABLE_FORCE (Bit 3) */ #define CRG_TOP_POWER_CTRL_REG_SW_1V8F_ENABLE_FORCE_Msk (0x8UL) /*!< SW_1V8F_ENABLE_FORCE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Pos (2UL) /*!< LDO_1V8P_RET_ENABLE_SLEEP (Bit 2) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Msk (0x4UL) /*!< LDO_1V8P_RET_ENABLE_SLEEP (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_ACTIVE_Pos (1UL) /*!< LDO_1V8P_RET_ENABLE_ACTIVE (Bit 1) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_ACTIVE_Msk (0x2UL) /*!< LDO_1V8P_RET_ENABLE_ACTIVE (Bitfield-Mask: 0x01) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_ENABLE_Pos (0UL) /*!< LDO_1V8P_ENABLE (Bit 0) */ #define CRG_TOP_POWER_CTRL_REG_LDO_1V8P_ENABLE_Msk (0x1UL) /*!< LDO_1V8P_ENABLE (Bitfield-Mask: 0x01) */ /* =================================================== RAM_PWR_CTRL_REG ==================================================== */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM8_PWR_CTRL_Pos (14UL) /*!< RAM8_PWR_CTRL (Bit 14) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM8_PWR_CTRL_Msk (0xc000UL) /*!< RAM8_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM7_PWR_CTRL_Pos (12UL) /*!< RAM7_PWR_CTRL (Bit 12) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM7_PWR_CTRL_Msk (0x3000UL) /*!< RAM7_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM6_PWR_CTRL_Pos (10UL) /*!< RAM6_PWR_CTRL (Bit 10) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM6_PWR_CTRL_Msk (0xc00UL) /*!< RAM6_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM5_PWR_CTRL_Pos (8UL) /*!< RAM5_PWR_CTRL (Bit 8) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM5_PWR_CTRL_Msk (0x300UL) /*!< RAM5_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM4_PWR_CTRL_Pos (6UL) /*!< RAM4_PWR_CTRL (Bit 6) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM4_PWR_CTRL_Msk (0xc0UL) /*!< RAM4_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM3_PWR_CTRL_Pos (4UL) /*!< RAM3_PWR_CTRL (Bit 4) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM3_PWR_CTRL_Msk (0x30UL) /*!< RAM3_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM2_PWR_CTRL_Pos (2UL) /*!< RAM2_PWR_CTRL (Bit 2) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM2_PWR_CTRL_Msk (0xcUL) /*!< RAM2_PWR_CTRL (Bitfield-Mask: 0x03) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM1_PWR_CTRL_Pos (0UL) /*!< RAM1_PWR_CTRL (Bit 0) */ #define CRG_TOP_RAM_PWR_CTRL_REG_RAM1_PWR_CTRL_Msk (0x3UL) /*!< RAM1_PWR_CTRL (Bitfield-Mask: 0x03) */ /* ==================================================== RESET_STAT_REG ===================================================== */ #define CRG_TOP_RESET_STAT_REG_CMAC_WDOGRESET_STAT_Pos (5UL) /*!< CMAC_WDOGRESET_STAT (Bit 5) */ #define CRG_TOP_RESET_STAT_REG_CMAC_WDOGRESET_STAT_Msk (0x20UL) /*!< CMAC_WDOGRESET_STAT (Bitfield-Mask: 0x01) */ #define CRG_TOP_RESET_STAT_REG_SWD_HWRESET_STAT_Pos (4UL) /*!< SWD_HWRESET_STAT (Bit 4) */ #define CRG_TOP_RESET_STAT_REG_SWD_HWRESET_STAT_Msk (0x10UL) /*!< SWD_HWRESET_STAT (Bitfield-Mask: 0x01) */ #define CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Pos (3UL) /*!< WDOGRESET_STAT (Bit 3) */ #define CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Msk (0x8UL) /*!< WDOGRESET_STAT (Bitfield-Mask: 0x01) */ #define CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Pos (2UL) /*!< SWRESET_STAT (Bit 2) */ #define CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Msk (0x4UL) /*!< SWRESET_STAT (Bitfield-Mask: 0x01) */ #define CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Pos (1UL) /*!< HWRESET_STAT (Bit 1) */ #define CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Msk (0x2UL) /*!< HWRESET_STAT (Bitfield-Mask: 0x01) */ #define CRG_TOP_RESET_STAT_REG_PORESET_STAT_Pos (0UL) /*!< PORESET_STAT (Bit 0) */ #define CRG_TOP_RESET_STAT_REG_PORESET_STAT_Msk (0x1UL) /*!< PORESET_STAT (Bitfield-Mask: 0x01) */ /* ==================================================== SECURE_BOOT_REG ==================================================== */ #define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Pos (7UL) /*!< PROT_QSPI_KEY_READ (Bit 7) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_READ_Msk (0x80UL) /*!< PROT_QSPI_KEY_READ (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_WRITE_Pos (6UL) /*!< PROT_QSPI_KEY_WRITE (Bit 6) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_QSPI_KEY_WRITE_Msk (0x40UL) /*!< PROT_QSPI_KEY_WRITE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Pos (5UL) /*!< PROT_AES_KEY_READ (Bit 5) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_READ_Msk (0x20UL) /*!< PROT_AES_KEY_READ (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_WRITE_Pos (4UL) /*!< PROT_AES_KEY_WRITE (Bit 4) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_AES_KEY_WRITE_Msk (0x10UL) /*!< PROT_AES_KEY_WRITE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_SIG_KEY_WRITE_Pos (3UL) /*!< PROT_SIG_KEY_WRITE (Bit 3) */ #define CRG_TOP_SECURE_BOOT_REG_PROT_SIG_KEY_WRITE_Msk (0x8UL) /*!< PROT_SIG_KEY_WRITE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_FORCE_CMAC_DEBUGGER_OFF_Pos (2UL) /*!< FORCE_CMAC_DEBUGGER_OFF (Bit 2) */ #define CRG_TOP_SECURE_BOOT_REG_FORCE_CMAC_DEBUGGER_OFF_Msk (0x4UL) /*!< FORCE_CMAC_DEBUGGER_OFF (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_FORCE_DEBUGGER_OFF_Pos (1UL) /*!< FORCE_DEBUGGER_OFF (Bit 1) */ #define CRG_TOP_SECURE_BOOT_REG_FORCE_DEBUGGER_OFF_Msk (0x2UL) /*!< FORCE_DEBUGGER_OFF (Bitfield-Mask: 0x01) */ #define CRG_TOP_SECURE_BOOT_REG_SECURE_BOOT_Pos (0UL) /*!< SECURE_BOOT (Bit 0) */ #define CRG_TOP_SECURE_BOOT_REG_SECURE_BOOT_Msk (0x1UL) /*!< SECURE_BOOT (Bitfield-Mask: 0x01) */ /* ===================================================== SYS_CTRL_REG ====================================================== */ #define CRG_TOP_SYS_CTRL_REG_SW_RESET_Pos (15UL) /*!< SW_RESET (Bit 15) */ #define CRG_TOP_SYS_CTRL_REG_SW_RESET_Msk (0x8000UL) /*!< SW_RESET (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Pos (10UL) /*!< CACHERAM_MUX (Bit 10) */ #define CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk (0x400UL) /*!< CACHERAM_MUX (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_TIMEOUT_DISABLE_Pos (9UL) /*!< TIMEOUT_DISABLE (Bit 9) */ #define CRG_TOP_SYS_CTRL_REG_TIMEOUT_DISABLE_Msk (0x200UL) /*!< TIMEOUT_DISABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_DEBUGGER_ENABLE_Pos (7UL) /*!< DEBUGGER_ENABLE (Bit 7) */ #define CRG_TOP_SYS_CTRL_REG_DEBUGGER_ENABLE_Msk (0x80UL) /*!< DEBUGGER_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_QSPI_INIT_Pos (4UL) /*!< QSPI_INIT (Bit 4) */ #define CRG_TOP_SYS_CTRL_REG_QSPI_INIT_Msk (0x10UL) /*!< QSPI_INIT (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Pos (3UL) /*!< REMAP_INTVECT (Bit 3) */ #define CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Msk (0x8UL) /*!< REMAP_INTVECT (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Pos (0UL) /*!< REMAP_ADR0 (Bit 0) */ #define CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Msk (0x7UL) /*!< REMAP_ADR0 (Bitfield-Mask: 0x07) */ /* ===================================================== SYS_STAT_REG ====================================================== */ #define CRG_TOP_SYS_STAT_REG_POWER_IS_UP_Pos (13UL) /*!< POWER_IS_UP (Bit 13) */ #define CRG_TOP_SYS_STAT_REG_POWER_IS_UP_Msk (0x2000UL) /*!< POWER_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Pos (12UL) /*!< DBG_IS_ACTIVE (Bit 12) */ #define CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Msk (0x1000UL) /*!< DBG_IS_ACTIVE (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_COM_IS_UP_Pos (11UL) /*!< COM_IS_UP (Bit 11) */ #define CRG_TOP_SYS_STAT_REG_COM_IS_UP_Msk (0x800UL) /*!< COM_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_COM_IS_DOWN_Pos (10UL) /*!< COM_IS_DOWN (Bit 10) */ #define CRG_TOP_SYS_STAT_REG_COM_IS_DOWN_Msk (0x400UL) /*!< COM_IS_DOWN (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_TIM_IS_UP_Pos (9UL) /*!< TIM_IS_UP (Bit 9) */ #define CRG_TOP_SYS_STAT_REG_TIM_IS_UP_Msk (0x200UL) /*!< TIM_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_TIM_IS_DOWN_Pos (8UL) /*!< TIM_IS_DOWN (Bit 8) */ #define CRG_TOP_SYS_STAT_REG_TIM_IS_DOWN_Msk (0x100UL) /*!< TIM_IS_DOWN (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_MEM_IS_UP_Pos (7UL) /*!< MEM_IS_UP (Bit 7) */ #define CRG_TOP_SYS_STAT_REG_MEM_IS_UP_Msk (0x80UL) /*!< MEM_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_MEM_IS_DOWN_Pos (6UL) /*!< MEM_IS_DOWN (Bit 6) */ #define CRG_TOP_SYS_STAT_REG_MEM_IS_DOWN_Msk (0x40UL) /*!< MEM_IS_DOWN (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_SYS_IS_UP_Pos (5UL) /*!< SYS_IS_UP (Bit 5) */ #define CRG_TOP_SYS_STAT_REG_SYS_IS_UP_Msk (0x20UL) /*!< SYS_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_SYS_IS_DOWN_Pos (4UL) /*!< SYS_IS_DOWN (Bit 4) */ #define CRG_TOP_SYS_STAT_REG_SYS_IS_DOWN_Msk (0x10UL) /*!< SYS_IS_DOWN (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_PER_IS_UP_Pos (3UL) /*!< PER_IS_UP (Bit 3) */ #define CRG_TOP_SYS_STAT_REG_PER_IS_UP_Msk (0x8UL) /*!< PER_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_PER_IS_DOWN_Pos (2UL) /*!< PER_IS_DOWN (Bit 2) */ #define CRG_TOP_SYS_STAT_REG_PER_IS_DOWN_Msk (0x4UL) /*!< PER_IS_DOWN (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_RAD_IS_UP_Pos (1UL) /*!< RAD_IS_UP (Bit 1) */ #define CRG_TOP_SYS_STAT_REG_RAD_IS_UP_Msk (0x2UL) /*!< RAD_IS_UP (Bitfield-Mask: 0x01) */ #define CRG_TOP_SYS_STAT_REG_RAD_IS_DOWN_Pos (0UL) /*!< RAD_IS_DOWN (Bit 0) */ #define CRG_TOP_SYS_STAT_REG_RAD_IS_DOWN_Msk (0x1UL) /*!< RAD_IS_DOWN (Bitfield-Mask: 0x01) */ /* ================================================== VBUS_IRQ_CLEAR_REG =================================================== */ #define CRG_TOP_VBUS_IRQ_CLEAR_REG_VBUS_IRQ_CLEAR_Pos (0UL) /*!< VBUS_IRQ_CLEAR (Bit 0) */ #define CRG_TOP_VBUS_IRQ_CLEAR_REG_VBUS_IRQ_CLEAR_Msk (0xffffUL) /*!< VBUS_IRQ_CLEAR (Bitfield-Mask: 0xffff) */ /* =================================================== VBUS_IRQ_MASK_REG =================================================== */ #define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Pos (1UL) /*!< VBUS_IRQ_EN_RISE (Bit 1) */ #define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk (0x2UL) /*!< VBUS_IRQ_EN_RISE (Bitfield-Mask: 0x01) */ #define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Pos (0UL) /*!< VBUS_IRQ_EN_FALL (Bit 0) */ #define CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk (0x1UL) /*!< VBUS_IRQ_EN_FALL (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ CRG_XTAL ================ */ /* =========================================================================================================================== */ /* =================================================== CLK_FREQ_TRIM_REG =================================================== */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_START_Pos (20UL) /*!< XTAL32M_START (Bit 20) */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_START_Msk (0x3ff00000UL) /*!< XTAL32M_START (Bitfield-Mask: 0x3ff) */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_RAMP_Pos (10UL) /*!< XTAL32M_RAMP (Bit 10) */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_RAMP_Msk (0xffc00UL) /*!< XTAL32M_RAMP (Bitfield-Mask: 0x3ff) */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_TRIM_Pos (0UL) /*!< XTAL32M_TRIM (Bit 0) */ #define CRG_XTAL_CLK_FREQ_TRIM_REG_XTAL32M_TRIM_Msk (0x3ffUL) /*!< XTAL32M_TRIM (Bitfield-Mask: 0x3ff) */ /* =================================================== PLL_SYS_CTRL1_REG =================================================== */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_Pos (14UL) /*!< PLL_SEL_MIN_CUR_INT (Bit 14) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_Msk (0x4000UL) /*!< PLL_SEL_MIN_CUR_INT (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_Pos (11UL) /*!< PLL_PRE_DIV (Bit 11) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_Msk (0x800UL) /*!< PLL_PRE_DIV (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_Pos (4UL) /*!< PLL_N_DIV (Bit 4) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_Msk (0x7f0UL) /*!< PLL_N_DIV (Bitfield-Mask: 0x7f) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_Pos (3UL) /*!< LDO_PLL_VREF_HOLD (Bit 3) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_Msk (0x8UL) /*!< LDO_PLL_VREF_HOLD (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Pos (2UL) /*!< LDO_PLL_ENABLE (Bit 2) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Msk (0x4UL) /*!< LDO_PLL_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Pos (1UL) /*!< PLL_EN (Bit 1) */ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk (0x2UL) /*!< PLL_EN (Bitfield-Mask: 0x01) */ /* =================================================== PLL_SYS_CTRL2_REG =================================================== */ #define CRG_XTAL_PLL_SYS_CTRL2_REG_PLL_RECALIB_Pos (15UL) /*!< PLL_RECALIB (Bit 15) */ #define CRG_XTAL_PLL_SYS_CTRL2_REG_PLL_RECALIB_Msk (0x8000UL) /*!< PLL_RECALIB (Bitfield-Mask: 0x01) */ /* =================================================== PLL_SYS_CTRL3_REG =================================================== */ #define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_TEST_VCTR_Pos (7UL) /*!< PLL_TEST_VCTR (Bit 7) */ #define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_TEST_VCTR_Msk (0x80UL) /*!< PLL_TEST_VCTR (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_MIN_CURRENT_Pos (1UL) /*!< PLL_MIN_CURRENT (Bit 1) */ #define CRG_XTAL_PLL_SYS_CTRL3_REG_PLL_MIN_CURRENT_Msk (0x7eUL) /*!< PLL_MIN_CURRENT (Bitfield-Mask: 0x3f) */ /* ================================================== PLL_SYS_STATUS_REG =================================================== */ #define CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_Pos (15UL) /*!< LDO_PLL_OK (Bit 15) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_Msk (0x8000UL) /*!< LDO_PLL_OK (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_Pos (11UL) /*!< PLL_CALIBRATION_END (Bit 11) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_Msk (0x800UL) /*!< PLL_CALIBRATION_END (Bitfield-Mask: 0x01) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_Pos (5UL) /*!< PLL_BEST_MIN_CUR (Bit 5) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_Msk (0x7e0UL) /*!< PLL_BEST_MIN_CUR (Bitfield-Mask: 0x3f) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Pos (0UL) /*!< PLL_LOCK_FINE (Bit 0) */ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Msk (0x1UL) /*!< PLL_LOCK_FINE (Bitfield-Mask: 0x01) */ /* ===================================================== TRIM_CTRL_REG ===================================================== */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_SETTLE_N_Pos (8UL) /*!< XTAL_SETTLE_N (Bit 8) */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_SETTLE_N_Msk (0x3f00UL) /*!< XTAL_SETTLE_N (Bitfield-Mask: 0x3f) */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_TRIM_SELECT_Pos (6UL) /*!< XTAL_TRIM_SELECT (Bit 6) */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_TRIM_SELECT_Msk (0xc0UL) /*!< XTAL_TRIM_SELECT (Bitfield-Mask: 0x03) */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_COUNT_N_Pos (0UL) /*!< XTAL_COUNT_N (Bit 0) */ #define CRG_XTAL_TRIM_CTRL_REG_XTAL_COUNT_N_Msk (0x3fUL) /*!< XTAL_COUNT_N (Bitfield-Mask: 0x3f) */ /* =================================================== XTAL32M_CTRL0_REG =================================================== */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_DXTAL_SYSPLL_ENABLE_Pos (30UL) /*!< XTAL32M_DXTAL_SYSPLL_ENABLE (Bit 30) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_DXTAL_SYSPLL_ENABLE_Msk (0x40000000UL) /*!< XTAL32M_DXTAL_SYSPLL_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CORE_CUR_SET_Pos (15UL) /*!< XTAL32M_CORE_CUR_SET (Bit 15) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CORE_CUR_SET_Msk (0x38000UL) /*!< XTAL32M_CORE_CUR_SET (Bitfield-Mask: 0x07) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_CALIBRATE_Pos (3UL) /*!< XTAL32M_RCOSC_CALIBRATE (Bit 3) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_CALIBRATE_Msk (0x8UL) /*!< XTAL32M_RCOSC_CALIBRATE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_XTAL_DRIVE_Pos (1UL) /*!< XTAL32M_RCOSC_XTAL_DRIVE (Bit 1) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_RCOSC_XTAL_DRIVE_Msk (0x2UL) /*!< XTAL32M_RCOSC_XTAL_DRIVE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CXCOMP_ENABLE_Pos (0UL) /*!< XTAL32M_CXCOMP_ENABLE (Bit 0) */ #define CRG_XTAL_XTAL32M_CTRL0_REG_XTAL32M_CXCOMP_ENABLE_Msk (0x1UL) /*!< XTAL32M_CXCOMP_ENABLE (Bitfield-Mask: 0x01) */ /* =================================================== XTAL32M_CTRL1_REG =================================================== */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDISCHARGE_Pos (28UL) /*!< XTAL32M_STARTUP_TDISCHARGE (Bit 28) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDISCHARGE_Msk (0x70000000UL) /*!< XTAL32M_STARTUP_TDISCHARGE (Bitfield-Mask: 0x07) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TSETTLE_Pos (24UL) /*!< XTAL32M_STARTUP_TSETTLE (Bit 24) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TSETTLE_Msk (0x7000000UL) /*!< XTAL32M_STARTUP_TSETTLE (Bitfield-Mask: 0x07) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_XTAL_ENABLE_Pos (23UL) /*!< XTAL32M_XTAL_ENABLE (Bit 23) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_XTAL_ENABLE_Msk (0x800000UL) /*!< XTAL32M_XTAL_ENABLE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_LSB_Pos (13UL) /*!< XTAL32M_STARTUP_TDRIVE_LSB (Bit 13) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_LSB_Msk (0x7fe000UL) /*!< XTAL32M_STARTUP_TDRIVE_LSB (Bitfield-Mask: 0x3ff) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_DRIVE_CYCLES_Pos (8UL) /*!< XTAL32M_DRIVE_CYCLES (Bit 8) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_DRIVE_CYCLES_Msk (0x1f00UL) /*!< XTAL32M_DRIVE_CYCLES (Bitfield-Mask: 0x1f) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_Pos (5UL) /*!< XTAL32M_STARTUP_TDRIVE (Bit 5) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_STARTUP_TDRIVE_Msk (0xe0UL) /*!< XTAL32M_STARTUP_TDRIVE (Bitfield-Mask: 0x07) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_RCOSC_SYNC_DELAY_TRIM_Pos (0UL) /*!< XTAL32M_RCOSC_SYNC_DELAY_TRIM (Bit 0) */ #define CRG_XTAL_XTAL32M_CTRL1_REG_XTAL32M_RCOSC_SYNC_DELAY_TRIM_Msk (0x1fUL) /*!< XTAL32M_RCOSC_SYNC_DELAY_TRIM (Bitfield-Mask: 0x1f) */ /* =================================================== XTAL32M_CTRL2_REG =================================================== */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_RCOSC_TRIM_SNS_Pos (14UL) /*!< XTAL32M_RCOSC_TRIM_SNS (Bit 14) */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_RCOSC_TRIM_SNS_Msk (0x3fc000UL) /*!< XTAL32M_RCOSC_TRIM_SNS (Bitfield-Mask: 0xff) */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_PHI_TRIM_Pos (12UL) /*!< XTAL32M_CXCOMP_PHI_TRIM (Bit 12) */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_PHI_TRIM_Msk (0x3000UL) /*!< XTAL32M_CXCOMP_PHI_TRIM (Bitfield-Mask: 0x03) */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_TRIM_CAP_Pos (3UL) /*!< XTAL32M_CXCOMP_TRIM_CAP (Bit 3) */ #define CRG_XTAL_XTAL32M_CTRL2_REG_XTAL32M_CXCOMP_TRIM_CAP_Msk (0xff8UL) /*!< XTAL32M_CXCOMP_TRIM_CAP (Bitfield-Mask: 0x1ff) */ /* =================================================== XTAL32M_CTRL3_REG =================================================== */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_STROBE_Pos (30UL) /*!< XTAL32M_RCOSC_TRIM_STROBE (Bit 30) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_STROBE_Msk (0x40000000UL) /*!< XTAL32M_RCOSC_TRIM_STROBE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_FREQ_DET_START_Pos (22UL) /*!< XTAL32M_FREQ_DET_START (Bit 22) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_FREQ_DET_START_Msk (0x400000UL) /*!< XTAL32M_FREQ_DET_START (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_SW_CTRL_MODE_Pos (18UL) /*!< XTAL32M_SW_CTRL_MODE (Bit 18) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_SW_CTRL_MODE_Msk (0x40000UL) /*!< XTAL32M_SW_CTRL_MODE (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_BAND_SELECT_Pos (14UL) /*!< XTAL32M_RCOSC_BAND_SELECT (Bit 14) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_BAND_SELECT_Msk (0x3c000UL) /*!< XTAL32M_RCOSC_BAND_SELECT (Bitfield-Mask: 0x0f) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Pos (4UL) /*!< XTAL32M_RCOSC_TRIM (Bit 4) */ #define CRG_XTAL_XTAL32M_CTRL3_REG_XTAL32M_RCOSC_TRIM_Msk (0x3ff0UL) /*!< XTAL32M_RCOSC_TRIM (Bitfield-Mask: 0x3ff) */ /* =================================================== XTAL32M_CTRL4_REG =================================================== */ /* =================================================== XTAL32M_STAT0_REG =================================================== */ #define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Pos (28UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bit 28) */ #define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_BAND_SELECT_STAT_Msk (0xf0000000UL) /*!< XTAL32M_RCOSC_BAND_SELECT_STAT (Bitfield-Mask: 0x0f) */ #define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_CALIBRATION_DONE_Pos (15UL) /*!< XTAL32M_RCOSC_CALIBRATION_DONE (Bit 15) */ #define CRG_XTAL_XTAL32M_STAT0_REG_XTAL32M_RCOSC_CALIBRATION_DONE_Msk (0x8000UL) /*!< XTAL32M_RCOSC_CALIBRATION_DONE (Bitfield-Mask: 0x01) */ /* =================================================== XTAL32M_STAT1_REG =================================================== */ #define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_CAL_STATE_Pos (4UL) /*!< XTAL32M_CAL_STATE (Bit 4) */ #define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_CAL_STATE_Msk (0xf0UL) /*!< XTAL32M_CAL_STATE (Bitfield-Mask: 0x0f) */ #define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_STATE_Pos (0UL) /*!< XTAL32M_STATE (Bit 0) */ #define CRG_XTAL_XTAL32M_STAT1_REG_XTAL32M_STATE_Msk (0xfUL) /*!< XTAL32M_STATE (Bitfield-Mask: 0x0f) */ /* =================================================== XTALRDY_CTRL_REG ==================================================== */ #define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Pos (8UL) /*!< XTALRDY_CLK_SEL (Bit 8) */ #define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk (0x100UL) /*!< XTALRDY_CLK_SEL (Bitfield-Mask: 0x01) */ #define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Pos (0UL) /*!< XTALRDY_CNT (Bit 0) */ #define CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk (0xffUL) /*!< XTALRDY_CNT (Bitfield-Mask: 0xff) */ /* =================================================== XTALRDY_STAT_REG ==================================================== */ #define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_COUNT_Pos (8UL) /*!< XTALRDY_COUNT (Bit 8) */ #define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_COUNT_Msk (0xff00UL) /*!< XTALRDY_COUNT (Bitfield-Mask: 0xff) */ #define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_STAT_Pos (0UL) /*!< XTALRDY_STAT (Bit 0) */ #define CRG_XTAL_XTALRDY_STAT_REG_XTALRDY_STAT_Msk (0xffUL) /*!< XTALRDY_STAT (Bitfield-Mask: 0xff) */ /* =========================================================================================================================== */ /* ================ DCDC ================ */ /* =========================================================================================================================== */ /* ==================================================== DCDC_CTRL1_REG ===================================================== */ #define DCDC_DCDC_CTRL1_REG_DCDC_SH_ENABLE_Pos (31UL) /*!< DCDC_SH_ENABLE (Bit 31) */ #define DCDC_DCDC_CTRL1_REG_DCDC_SH_ENABLE_Msk (0x80000000UL) /*!< DCDC_SH_ENABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL1_REG_DCDC_STARTUP_DELAY_Pos (26UL) /*!< DCDC_STARTUP_DELAY (Bit 26) */ #define DCDC_DCDC_CTRL1_REG_DCDC_STARTUP_DELAY_Msk (0x7c000000UL) /*!< DCDC_STARTUP_DELAY (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_MAX_FAST_DOWNRAMP_Pos (20UL) /*!< DCDC_IDLE_MAX_FAST_DOWNRAMP (Bit 20) */ #define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_MAX_FAST_DOWNRAMP_Msk (0x3f00000UL) /*!< DCDC_IDLE_MAX_FAST_DOWNRAMP (Bitfield-Mask: 0x3f) */ #define DCDC_DCDC_CTRL1_REG_DCDC_SW_TIMEOUT_Pos (15UL) /*!< DCDC_SW_TIMEOUT (Bit 15) */ #define DCDC_DCDC_CTRL1_REG_DCDC_SW_TIMEOUT_Msk (0xf8000UL) /*!< DCDC_SW_TIMEOUT (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_CTRL1_REG_DCDC_FAST_STARTUP_Pos (14UL) /*!< DCDC_FAST_STARTUP (Bit 14) */ #define DCDC_DCDC_CTRL1_REG_DCDC_FAST_STARTUP_Msk (0x4000UL) /*!< DCDC_FAST_STARTUP (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL1_REG_DCDC_MAN_LV_MODE_Pos (13UL) /*!< DCDC_MAN_LV_MODE (Bit 13) */ #define DCDC_DCDC_CTRL1_REG_DCDC_MAN_LV_MODE_Msk (0x2000UL) /*!< DCDC_MAN_LV_MODE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL1_REG_DCDC_AUTO_LV_MODE_Pos (12UL) /*!< DCDC_AUTO_LV_MODE (Bit 12) */ #define DCDC_DCDC_CTRL1_REG_DCDC_AUTO_LV_MODE_Msk (0x1000UL) /*!< DCDC_AUTO_LV_MODE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_CLK_DIV_Pos (10UL) /*!< DCDC_IDLE_CLK_DIV (Bit 10) */ #define DCDC_DCDC_CTRL1_REG_DCDC_IDLE_CLK_DIV_Msk (0xc00UL) /*!< DCDC_IDLE_CLK_DIV (Bitfield-Mask: 0x03) */ #define DCDC_DCDC_CTRL1_REG_DCDC_PRIORITY_Pos (2UL) /*!< DCDC_PRIORITY (Bit 2) */ #define DCDC_DCDC_CTRL1_REG_DCDC_PRIORITY_Msk (0x3fcUL) /*!< DCDC_PRIORITY (Bitfield-Mask: 0xff) */ #define DCDC_DCDC_CTRL1_REG_DCDC_FW_ENABLE_Pos (1UL) /*!< DCDC_FW_ENABLE (Bit 1) */ #define DCDC_DCDC_CTRL1_REG_DCDC_FW_ENABLE_Msk (0x2UL) /*!< DCDC_FW_ENABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Pos (0UL) /*!< DCDC_ENABLE (Bit 0) */ #define DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk (0x1UL) /*!< DCDC_ENABLE (Bitfield-Mask: 0x01) */ /* ==================================================== DCDC_CTRL2_REG ===================================================== */ #define DCDC_DCDC_CTRL2_REG_DCDC_V_NOK_CNT_MAX_Pos (24UL) /*!< DCDC_V_NOK_CNT_MAX (Bit 24) */ #define DCDC_DCDC_CTRL2_REG_DCDC_V_NOK_CNT_MAX_Msk (0xf000000UL) /*!< DCDC_V_NOK_CNT_MAX (Bitfield-Mask: 0x0f) */ #define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_MAN_Pos (22UL) /*!< DCDC_N_COMP_TRIM_MAN (Bit 22) */ #define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_MAN_Msk (0x400000UL) /*!< DCDC_N_COMP_TRIM_MAN (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_VAL_Pos (16UL) /*!< DCDC_N_COMP_TRIM_VAL (Bit 16) */ #define DCDC_DCDC_CTRL2_REG_DCDC_N_COMP_TRIM_VAL_Msk (0x3f0000UL) /*!< DCDC_N_COMP_TRIM_VAL (Bitfield-Mask: 0x3f) */ #define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_TRIG_Pos (12UL) /*!< DCDC_TIMEOUT_IRQ_TRIG (Bit 12) */ #define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_TRIG_Msk (0xf000UL) /*!< DCDC_TIMEOUT_IRQ_TRIG (Bitfield-Mask: 0x0f) */ #define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_RES_Pos (8UL) /*!< DCDC_TIMEOUT_IRQ_RES (Bit 8) */ #define DCDC_DCDC_CTRL2_REG_DCDC_TIMEOUT_IRQ_RES_Msk (0xf00UL) /*!< DCDC_TIMEOUT_IRQ_RES (Bitfield-Mask: 0x0f) */ #define DCDC_DCDC_CTRL2_REG_DCDC_SLOPE_CONTROL_Pos (6UL) /*!< DCDC_SLOPE_CONTROL (Bit 6) */ #define DCDC_DCDC_CTRL2_REG_DCDC_SLOPE_CONTROL_Msk (0xc0UL) /*!< DCDC_SLOPE_CONTROL (Bitfield-Mask: 0x03) */ #define DCDC_DCDC_CTRL2_REG_DCDC_VBTSTRP_TRIM_Pos (4UL) /*!< DCDC_VBTSTRP_TRIM (Bit 4) */ #define DCDC_DCDC_CTRL2_REG_DCDC_VBTSTRP_TRIM_Msk (0x30UL) /*!< DCDC_VBTSTRP_TRIM (Bitfield-Mask: 0x03) */ #define DCDC_DCDC_CTRL2_REG_DCDC_LSSUP_TRIM_Pos (2UL) /*!< DCDC_LSSUP_TRIM (Bit 2) */ #define DCDC_DCDC_CTRL2_REG_DCDC_LSSUP_TRIM_Msk (0xcUL) /*!< DCDC_LSSUP_TRIM (Bitfield-Mask: 0x03) */ #define DCDC_DCDC_CTRL2_REG_DCDC_HSGND_TRIM_Pos (0UL) /*!< DCDC_HSGND_TRIM (Bit 0) */ #define DCDC_DCDC_CTRL2_REG_DCDC_HSGND_TRIM_Msk (0x3UL) /*!< DCDC_HSGND_TRIM (Bitfield-Mask: 0x03) */ /* ================================================== DCDC_IRQ_CLEAR_REG =================================================== */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_LOW_VBAT_IRQ_CLEAR_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_CLEAR (Bit 4) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_LOW_VBAT_IRQ_CLEAR_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18P_TIMEOUT_IRQ_CLEAR_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_CLEAR (Bit 3) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18P_TIMEOUT_IRQ_CLEAR_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_VDD_TIMEOUT_IRQ_CLEAR_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_CLEAR (Bit 2) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_VDD_TIMEOUT_IRQ_CLEAR_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18_TIMEOUT_IRQ_CLEAR_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_CLEAR (Bit 1) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V18_TIMEOUT_IRQ_CLEAR_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V14_TIMEOUT_IRQ_CLEAR_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_CLEAR (Bit 0) */ #define DCDC_DCDC_IRQ_CLEAR_REG_DCDC_V14_TIMEOUT_IRQ_CLEAR_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_CLEAR (Bitfield-Mask: 0x01) */ /* =================================================== DCDC_IRQ_MASK_REG =================================================== */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_LOW_VBAT_IRQ_MASK_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_MASK (Bit 4) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_LOW_VBAT_IRQ_MASK_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_MASK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18P_TIMEOUT_IRQ_MASK_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_MASK (Bit 3) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18P_TIMEOUT_IRQ_MASK_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_VDD_TIMEOUT_IRQ_MASK_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_MASK (Bit 2) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_VDD_TIMEOUT_IRQ_MASK_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18_TIMEOUT_IRQ_MASK_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_MASK (Bit 1) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V18_TIMEOUT_IRQ_MASK_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V14_TIMEOUT_IRQ_MASK_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_MASK (Bit 0) */ #define DCDC_DCDC_IRQ_MASK_REG_DCDC_V14_TIMEOUT_IRQ_MASK_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_MASK (Bitfield-Mask: 0x01) */ /* ================================================== DCDC_IRQ_STATUS_REG ================================================== */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_LOW_VBAT_IRQ_STATUS_Pos (4UL) /*!< DCDC_LOW_VBAT_IRQ_STATUS (Bit 4) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_LOW_VBAT_IRQ_STATUS_Msk (0x10UL) /*!< DCDC_LOW_VBAT_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18P_TIMEOUT_IRQ_STATUS_Pos (3UL) /*!< DCDC_V18P_TIMEOUT_IRQ_STATUS (Bit 3) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18P_TIMEOUT_IRQ_STATUS_Msk (0x8UL) /*!< DCDC_V18P_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_VDD_TIMEOUT_IRQ_STATUS_Pos (2UL) /*!< DCDC_VDD_TIMEOUT_IRQ_STATUS (Bit 2) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_VDD_TIMEOUT_IRQ_STATUS_Msk (0x4UL) /*!< DCDC_VDD_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18_TIMEOUT_IRQ_STATUS_Pos (1UL) /*!< DCDC_V18_TIMEOUT_IRQ_STATUS (Bit 1) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V18_TIMEOUT_IRQ_STATUS_Msk (0x2UL) /*!< DCDC_V18_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V14_TIMEOUT_IRQ_STATUS_Pos (0UL) /*!< DCDC_V14_TIMEOUT_IRQ_STATUS (Bit 0) */ #define DCDC_DCDC_IRQ_STATUS_REG_DCDC_V14_TIMEOUT_IRQ_STATUS_Msk (0x1UL) /*!< DCDC_V14_TIMEOUT_IRQ_STATUS (Bitfield-Mask: 0x01) */ /* =================================================== DCDC_STATUS1_REG ==================================================== */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_AVAILABLE_Pos (27UL) /*!< DCDC_V18P_AVAILABLE (Bit 27) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_AVAILABLE_Msk (0x8000000UL) /*!< DCDC_V18P_AVAILABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_AVAILABLE_Pos (26UL) /*!< DCDC_VDD_AVAILABLE (Bit 26) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_AVAILABLE_Msk (0x4000000UL) /*!< DCDC_VDD_AVAILABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_AVAILABLE_Pos (25UL) /*!< DCDC_V18_AVAILABLE (Bit 25) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_AVAILABLE_Msk (0x2000000UL) /*!< DCDC_V18_AVAILABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_AVAILABLE_Pos (24UL) /*!< DCDC_V14_AVAILABLE (Bit 24) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_AVAILABLE_Msk (0x1000000UL) /*!< DCDC_V14_AVAILABLE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_OK_Pos (23UL) /*!< DCDC_V18P_COMP_OK (Bit 23) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_OK_Msk (0x800000UL) /*!< DCDC_V18P_COMP_OK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_OK_Pos (22UL) /*!< DCDC_VDD_COMP_OK (Bit 22) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_OK_Msk (0x400000UL) /*!< DCDC_VDD_COMP_OK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_OK_Pos (21UL) /*!< DCDC_V18_COMP_OK (Bit 21) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_OK_Msk (0x200000UL) /*!< DCDC_V18_COMP_OK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_OK_Pos (20UL) /*!< DCDC_V14_COMP_OK (Bit 20) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_OK_Msk (0x100000UL) /*!< DCDC_V14_COMP_OK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_NOK_Pos (19UL) /*!< DCDC_V18P_COMP_NOK (Bit 19) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_COMP_NOK_Msk (0x80000UL) /*!< DCDC_V18P_COMP_NOK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_NOK_Pos (18UL) /*!< DCDC_VDD_COMP_NOK (Bit 18) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_COMP_NOK_Msk (0x40000UL) /*!< DCDC_VDD_COMP_NOK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_NOK_Pos (17UL) /*!< DCDC_V18_COMP_NOK (Bit 17) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_COMP_NOK_Msk (0x20000UL) /*!< DCDC_V18_COMP_NOK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_NOK_Pos (16UL) /*!< DCDC_V14_COMP_NOK (Bit 16) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_COMP_NOK_Msk (0x10000UL) /*!< DCDC_V14_COMP_NOK (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_P_Pos (11UL) /*!< DCDC_N_COMP_P (Bit 11) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_P_Msk (0x800UL) /*!< DCDC_N_COMP_P (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_N_Pos (10UL) /*!< DCDC_N_COMP_N (Bit 10) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_N_Msk (0x400UL) /*!< DCDC_N_COMP_N (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_P_COMP_Pos (9UL) /*!< DCDC_P_COMP (Bit 9) */ #define DCDC_DCDC_STATUS1_REG_DCDC_P_COMP_Msk (0x200UL) /*!< DCDC_P_COMP (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_Pos (8UL) /*!< DCDC_N_COMP (Bit 8) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_COMP_Msk (0x100UL) /*!< DCDC_N_COMP (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_LV_MODE_Pos (7UL) /*!< DCDC_LV_MODE (Bit 7) */ #define DCDC_DCDC_STATUS1_REG_DCDC_LV_MODE_Msk (0x80UL) /*!< DCDC_LV_MODE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_SW_STATE_Pos (6UL) /*!< DCDC_V18P_SW_STATE (Bit 6) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18P_SW_STATE_Msk (0x40UL) /*!< DCDC_V18P_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_SW_STATE_Pos (5UL) /*!< DCDC_VDD_SW_STATE (Bit 5) */ #define DCDC_DCDC_STATUS1_REG_DCDC_VDD_SW_STATE_Msk (0x20UL) /*!< DCDC_VDD_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_SW_STATE_Pos (4UL) /*!< DCDC_V18_SW_STATE (Bit 4) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V18_SW_STATE_Msk (0x10UL) /*!< DCDC_V18_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_SW_STATE_Pos (3UL) /*!< DCDC_V14_SW_STATE (Bit 3) */ #define DCDC_DCDC_STATUS1_REG_DCDC_V14_SW_STATE_Msk (0x8UL) /*!< DCDC_V14_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_SW_STATE_Pos (2UL) /*!< DCDC_N_SW_STATE (Bit 2) */ #define DCDC_DCDC_STATUS1_REG_DCDC_N_SW_STATE_Msk (0x4UL) /*!< DCDC_N_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_P_SW_STATE_Pos (1UL) /*!< DCDC_P_SW_STATE (Bit 1) */ #define DCDC_DCDC_STATUS1_REG_DCDC_P_SW_STATE_Msk (0x2UL) /*!< DCDC_P_SW_STATE (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_STATUS1_REG_DCDC_STARTUP_COMPLETE_Pos (0UL) /*!< DCDC_STARTUP_COMPLETE (Bit 0) */ #define DCDC_DCDC_STATUS1_REG_DCDC_STARTUP_COMPLETE_Msk (0x1UL) /*!< DCDC_STARTUP_COMPLETE (Bitfield-Mask: 0x01) */ /* ===================================================== DCDC_V14_REG ====================================================== */ #define DCDC_DCDC_V14_REG_DCDC_V14_FAST_RAMPING_Pos (31UL) /*!< DCDC_V14_FAST_RAMPING (Bit 31) */ #define DCDC_DCDC_V14_REG_DCDC_V14_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V14_FAST_RAMPING (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V14_REG_DCDC_V14_TRIM_Pos (27UL) /*!< DCDC_V14_TRIM (Bit 27) */ #define DCDC_DCDC_V14_REG_DCDC_V14_TRIM_Msk (0x8000000UL) /*!< DCDC_V14_TRIM (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V14_CUR_LIM_MAX_HV (Bit 22) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V14_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V14_CUR_LIM_MAX_LV (Bit 17) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V14_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V14_CUR_LIM_MIN (Bit 12) */ #define DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V14_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_HYST_Pos (7UL) /*!< DCDC_V14_IDLE_HYST (Bit 7) */ #define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V14_IDLE_HYST (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_MIN_Pos (2UL) /*!< DCDC_V14_IDLE_MIN (Bit 2) */ #define DCDC_DCDC_V14_REG_DCDC_V14_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V14_IDLE_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Pos (1UL) /*!< DCDC_V14_ENABLE_HV (Bit 1) */ #define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V14_ENABLE_HV (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Pos (0UL) /*!< DCDC_V14_ENABLE_LV (Bit 0) */ #define DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V14_ENABLE_LV (Bitfield-Mask: 0x01) */ /* ===================================================== DCDC_V18P_REG ===================================================== */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_FAST_RAMPING_Pos (31UL) /*!< DCDC_V18P_FAST_RAMPING (Bit 31) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V18P_FAST_RAMPING (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_TRIM_Pos (27UL) /*!< DCDC_V18P_TRIM (Bit 27) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_TRIM_Msk (0x78000000UL) /*!< DCDC_V18P_TRIM (Bitfield-Mask: 0x0f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V18P_CUR_LIM_MAX_HV (Bit 22) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V18P_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V18P_CUR_LIM_MAX_LV (Bit 17) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V18P_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V18P_CUR_LIM_MIN (Bit 12) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V18P_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_HYST_Pos (7UL) /*!< DCDC_V18P_IDLE_HYST (Bit 7) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V18P_IDLE_HYST (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_MIN_Pos (2UL) /*!< DCDC_V18P_IDLE_MIN (Bit 2) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V18P_IDLE_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_HV_Pos (1UL) /*!< DCDC_V18P_ENABLE_HV (Bit 1) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V18P_ENABLE_HV (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_LV_Pos (0UL) /*!< DCDC_V18P_ENABLE_LV (Bit 0) */ #define DCDC_DCDC_V18P_REG_DCDC_V18P_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V18P_ENABLE_LV (Bitfield-Mask: 0x01) */ /* ===================================================== DCDC_V18_REG ====================================================== */ #define DCDC_DCDC_V18_REG_DCDC_V18_FAST_RAMPING_Pos (31UL) /*!< DCDC_V18_FAST_RAMPING (Bit 31) */ #define DCDC_DCDC_V18_REG_DCDC_V18_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_V18_FAST_RAMPING (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V18_REG_DCDC_V18_TRIM_Pos (27UL) /*!< DCDC_V18_TRIM (Bit 27) */ #define DCDC_DCDC_V18_REG_DCDC_V18_TRIM_Msk (0x78000000UL) /*!< DCDC_V18_TRIM (Bitfield-Mask: 0x0f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_V18_CUR_LIM_MAX_HV (Bit 22) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_V18_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_V18_CUR_LIM_MAX_LV (Bit 17) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_V18_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_V18_CUR_LIM_MIN (Bit 12) */ #define DCDC_DCDC_V18_REG_DCDC_V18_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_V18_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_HYST_Pos (7UL) /*!< DCDC_V18_IDLE_HYST (Bit 7) */ #define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_V18_IDLE_HYST (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_MIN_Pos (2UL) /*!< DCDC_V18_IDLE_MIN (Bit 2) */ #define DCDC_DCDC_V18_REG_DCDC_V18_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_V18_IDLE_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_HV_Pos (1UL) /*!< DCDC_V18_ENABLE_HV (Bit 1) */ #define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_HV_Msk (0x2UL) /*!< DCDC_V18_ENABLE_HV (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_LV_Pos (0UL) /*!< DCDC_V18_ENABLE_LV (Bit 0) */ #define DCDC_DCDC_V18_REG_DCDC_V18_ENABLE_LV_Msk (0x1UL) /*!< DCDC_V18_ENABLE_LV (Bitfield-Mask: 0x01) */ /* ===================================================== DCDC_VDD_REG ====================================================== */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_FAST_RAMPING_Pos (31UL) /*!< DCDC_VDD_FAST_RAMPING (Bit 31) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_FAST_RAMPING_Msk (0x80000000UL) /*!< DCDC_VDD_FAST_RAMPING (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_TRIM_Pos (27UL) /*!< DCDC_VDD_TRIM (Bit 27) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_TRIM_Msk (0x38000000UL) /*!< DCDC_VDD_TRIM (Bitfield-Mask: 0x07) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_HV_Pos (22UL) /*!< DCDC_VDD_CUR_LIM_MAX_HV (Bit 22) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_HV_Msk (0x7c00000UL) /*!< DCDC_VDD_CUR_LIM_MAX_HV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_LV_Pos (17UL) /*!< DCDC_VDD_CUR_LIM_MAX_LV (Bit 17) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MAX_LV_Msk (0x3e0000UL) /*!< DCDC_VDD_CUR_LIM_MAX_LV (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MIN_Pos (12UL) /*!< DCDC_VDD_CUR_LIM_MIN (Bit 12) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_CUR_LIM_MIN_Msk (0x1f000UL) /*!< DCDC_VDD_CUR_LIM_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_HYST_Pos (7UL) /*!< DCDC_VDD_IDLE_HYST (Bit 7) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_HYST_Msk (0xf80UL) /*!< DCDC_VDD_IDLE_HYST (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_MIN_Pos (2UL) /*!< DCDC_VDD_IDLE_MIN (Bit 2) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_IDLE_MIN_Msk (0x7cUL) /*!< DCDC_VDD_IDLE_MIN (Bitfield-Mask: 0x1f) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Pos (1UL) /*!< DCDC_VDD_ENABLE_HV (Bit 1) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Msk (0x2UL) /*!< DCDC_VDD_ENABLE_HV (Bitfield-Mask: 0x01) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Pos (0UL) /*!< DCDC_VDD_ENABLE_LV (Bit 0) */ #define DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Msk (0x1UL) /*!< DCDC_VDD_ENABLE_LV (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ DMA ================ */ /* =========================================================================================================================== */ /* =================================================== DMA0_A_START_REG ==================================================== */ #define DMA_DMA0_A_START_REG_DMA0_A_START_Pos (0UL) /*!< DMA0_A_START (Bit 0) */ #define DMA_DMA0_A_START_REG_DMA0_A_START_Msk (0xffffffffUL) /*!< DMA0_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA0_B_START_REG ==================================================== */ #define DMA_DMA0_B_START_REG_DMA0_B_START_Pos (0UL) /*!< DMA0_B_START (Bit 0) */ #define DMA_DMA0_B_START_REG_DMA0_B_START_Msk (0xffffffffUL) /*!< DMA0_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA0_CTRL_REG ===================================================== */ #define DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA0_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA0_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA0_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA0_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA0_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA0_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA0_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA0_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA0_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA0_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA0_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA0_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA0_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA0_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA0_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA0_IDX_REG ====================================================== */ #define DMA_DMA0_IDX_REG_DMA0_IDX_Pos (0UL) /*!< DMA0_IDX (Bit 0) */ #define DMA_DMA0_IDX_REG_DMA0_IDX_Msk (0xffffUL) /*!< DMA0_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA0_INT_REG ====================================================== */ #define DMA_DMA0_INT_REG_DMA0_INT_Pos (0UL) /*!< DMA0_INT (Bit 0) */ #define DMA_DMA0_INT_REG_DMA0_INT_Msk (0xffffUL) /*!< DMA0_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA0_LEN_REG ====================================================== */ #define DMA_DMA0_LEN_REG_DMA0_LEN_Pos (0UL) /*!< DMA0_LEN (Bit 0) */ #define DMA_DMA0_LEN_REG_DMA0_LEN_Msk (0xffffUL) /*!< DMA0_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA1_A_START_REG ==================================================== */ #define DMA_DMA1_A_START_REG_DMA1_A_START_Pos (0UL) /*!< DMA1_A_START (Bit 0) */ #define DMA_DMA1_A_START_REG_DMA1_A_START_Msk (0xffffffffUL) /*!< DMA1_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA1_B_START_REG ==================================================== */ #define DMA_DMA1_B_START_REG_DMA1_B_START_Pos (0UL) /*!< DMA1_B_START (Bit 0) */ #define DMA_DMA1_B_START_REG_DMA1_B_START_Msk (0xffffffffUL) /*!< DMA1_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA1_CTRL_REG ===================================================== */ #define DMA_DMA1_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA1_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA1_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA1_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA1_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA1_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA1_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA1_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA1_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA1_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA1_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA1_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA1_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA1_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA1_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA1_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA1_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA1_IDX_REG ====================================================== */ #define DMA_DMA1_IDX_REG_DMA1_IDX_Pos (0UL) /*!< DMA1_IDX (Bit 0) */ #define DMA_DMA1_IDX_REG_DMA1_IDX_Msk (0xffffUL) /*!< DMA1_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA1_INT_REG ====================================================== */ #define DMA_DMA1_INT_REG_DMA1_INT_Pos (0UL) /*!< DMA1_INT (Bit 0) */ #define DMA_DMA1_INT_REG_DMA1_INT_Msk (0xffffUL) /*!< DMA1_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA1_LEN_REG ====================================================== */ #define DMA_DMA1_LEN_REG_DMA1_LEN_Pos (0UL) /*!< DMA1_LEN (Bit 0) */ #define DMA_DMA1_LEN_REG_DMA1_LEN_Msk (0xffffUL) /*!< DMA1_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA2_A_START_REG ==================================================== */ #define DMA_DMA2_A_START_REG_DMA2_A_START_Pos (0UL) /*!< DMA2_A_START (Bit 0) */ #define DMA_DMA2_A_START_REG_DMA2_A_START_Msk (0xffffffffUL) /*!< DMA2_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA2_B_START_REG ==================================================== */ #define DMA_DMA2_B_START_REG_DMA2_B_START_Pos (0UL) /*!< DMA2_B_START (Bit 0) */ #define DMA_DMA2_B_START_REG_DMA2_B_START_Msk (0xffffffffUL) /*!< DMA2_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA2_CTRL_REG ===================================================== */ #define DMA_DMA2_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA2_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA2_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA2_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA2_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA2_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA2_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA2_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA2_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA2_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA2_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA2_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA2_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA2_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA2_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA2_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA2_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA2_IDX_REG ====================================================== */ #define DMA_DMA2_IDX_REG_DMA2_IDX_Pos (0UL) /*!< DMA2_IDX (Bit 0) */ #define DMA_DMA2_IDX_REG_DMA2_IDX_Msk (0xffffUL) /*!< DMA2_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA2_INT_REG ====================================================== */ #define DMA_DMA2_INT_REG_DMA2_INT_Pos (0UL) /*!< DMA2_INT (Bit 0) */ #define DMA_DMA2_INT_REG_DMA2_INT_Msk (0xffffUL) /*!< DMA2_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA2_LEN_REG ====================================================== */ #define DMA_DMA2_LEN_REG_DMA2_LEN_Pos (0UL) /*!< DMA2_LEN (Bit 0) */ #define DMA_DMA2_LEN_REG_DMA2_LEN_Msk (0xffffUL) /*!< DMA2_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA3_A_START_REG ==================================================== */ #define DMA_DMA3_A_START_REG_DMA3_A_START_Pos (0UL) /*!< DMA3_A_START (Bit 0) */ #define DMA_DMA3_A_START_REG_DMA3_A_START_Msk (0xffffffffUL) /*!< DMA3_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA3_B_START_REG ==================================================== */ #define DMA_DMA3_B_START_REG_DMA3_B_START_Pos (0UL) /*!< DMA3_B_START (Bit 0) */ #define DMA_DMA3_B_START_REG_DMA3_B_START_Msk (0xffffffffUL) /*!< DMA3_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA3_CTRL_REG ===================================================== */ #define DMA_DMA3_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA3_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA3_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA3_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA3_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA3_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA3_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA3_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA3_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA3_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA3_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA3_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA3_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA3_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA3_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA3_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA3_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA3_IDX_REG ====================================================== */ #define DMA_DMA3_IDX_REG_DMA3_IDX_Pos (0UL) /*!< DMA3_IDX (Bit 0) */ #define DMA_DMA3_IDX_REG_DMA3_IDX_Msk (0xffffUL) /*!< DMA3_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA3_INT_REG ====================================================== */ #define DMA_DMA3_INT_REG_DMA3_INT_Pos (0UL) /*!< DMA3_INT (Bit 0) */ #define DMA_DMA3_INT_REG_DMA3_INT_Msk (0xffffUL) /*!< DMA3_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA3_LEN_REG ====================================================== */ #define DMA_DMA3_LEN_REG_DMA3_LEN_Pos (0UL) /*!< DMA3_LEN (Bit 0) */ #define DMA_DMA3_LEN_REG_DMA3_LEN_Msk (0xffffUL) /*!< DMA3_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA4_A_START_REG ==================================================== */ #define DMA_DMA4_A_START_REG_DMA4_A_START_Pos (0UL) /*!< DMA4_A_START (Bit 0) */ #define DMA_DMA4_A_START_REG_DMA4_A_START_Msk (0xffffffffUL) /*!< DMA4_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA4_B_START_REG ==================================================== */ #define DMA_DMA4_B_START_REG_DMA4_B_START_Pos (0UL) /*!< DMA4_B_START (Bit 0) */ #define DMA_DMA4_B_START_REG_DMA4_B_START_Msk (0xffffffffUL) /*!< DMA4_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA4_CTRL_REG ===================================================== */ #define DMA_DMA4_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA4_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA4_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA4_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA4_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA4_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA4_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA4_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA4_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA4_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA4_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA4_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA4_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA4_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA4_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA4_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA4_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA4_IDX_REG ====================================================== */ #define DMA_DMA4_IDX_REG_DMA4_IDX_Pos (0UL) /*!< DMA4_IDX (Bit 0) */ #define DMA_DMA4_IDX_REG_DMA4_IDX_Msk (0xffffUL) /*!< DMA4_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA4_INT_REG ====================================================== */ #define DMA_DMA4_INT_REG_DMA4_INT_Pos (0UL) /*!< DMA4_INT (Bit 0) */ #define DMA_DMA4_INT_REG_DMA4_INT_Msk (0xffffUL) /*!< DMA4_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA4_LEN_REG ====================================================== */ #define DMA_DMA4_LEN_REG_DMA4_LEN_Pos (0UL) /*!< DMA4_LEN (Bit 0) */ #define DMA_DMA4_LEN_REG_DMA4_LEN_Msk (0xffffUL) /*!< DMA4_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA5_A_START_REG ==================================================== */ #define DMA_DMA5_A_START_REG_DMA5_A_START_Pos (0UL) /*!< DMA5_A_START (Bit 0) */ #define DMA_DMA5_A_START_REG_DMA5_A_START_Msk (0xffffffffUL) /*!< DMA5_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA5_B_START_REG ==================================================== */ #define DMA_DMA5_B_START_REG_DMA5_B_START_Pos (0UL) /*!< DMA5_B_START (Bit 0) */ #define DMA_DMA5_B_START_REG_DMA5_B_START_Msk (0xffffffffUL) /*!< DMA5_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA5_CTRL_REG ===================================================== */ #define DMA_DMA5_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA5_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA5_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA5_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA5_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA5_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA5_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA5_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA5_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA5_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA5_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA5_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA5_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA5_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA5_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA5_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA5_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA5_IDX_REG ====================================================== */ #define DMA_DMA5_IDX_REG_DMA5_IDX_Pos (0UL) /*!< DMA5_IDX (Bit 0) */ #define DMA_DMA5_IDX_REG_DMA5_IDX_Msk (0xffffUL) /*!< DMA5_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA5_INT_REG ====================================================== */ #define DMA_DMA5_INT_REG_DMA5_INT_Pos (0UL) /*!< DMA5_INT (Bit 0) */ #define DMA_DMA5_INT_REG_DMA5_INT_Msk (0xffffUL) /*!< DMA5_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA5_LEN_REG ====================================================== */ #define DMA_DMA5_LEN_REG_DMA5_LEN_Pos (0UL) /*!< DMA5_LEN (Bit 0) */ #define DMA_DMA5_LEN_REG_DMA5_LEN_Msk (0xffffUL) /*!< DMA5_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA6_A_START_REG ==================================================== */ #define DMA_DMA6_A_START_REG_DMA6_A_START_Pos (0UL) /*!< DMA6_A_START (Bit 0) */ #define DMA_DMA6_A_START_REG_DMA6_A_START_Msk (0xffffffffUL) /*!< DMA6_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA6_B_START_REG ==================================================== */ #define DMA_DMA6_B_START_REG_DMA6_B_START_Pos (0UL) /*!< DMA6_B_START (Bit 0) */ #define DMA_DMA6_B_START_REG_DMA6_B_START_Msk (0xffffffffUL) /*!< DMA6_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA6_CTRL_REG ===================================================== */ #define DMA_DMA6_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA6_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA6_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA6_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA6_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA6_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA6_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA6_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA6_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA6_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA6_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA6_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA6_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA6_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA6_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA6_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA6_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA6_IDX_REG ====================================================== */ #define DMA_DMA6_IDX_REG_DMA6_IDX_Pos (0UL) /*!< DMA6_IDX (Bit 0) */ #define DMA_DMA6_IDX_REG_DMA6_IDX_Msk (0xffffUL) /*!< DMA6_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA6_INT_REG ====================================================== */ #define DMA_DMA6_INT_REG_DMA6_INT_Pos (0UL) /*!< DMA6_INT (Bit 0) */ #define DMA_DMA6_INT_REG_DMA6_INT_Msk (0xffffUL) /*!< DMA6_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA6_LEN_REG ====================================================== */ #define DMA_DMA6_LEN_REG_DMA6_LEN_Pos (0UL) /*!< DMA6_LEN (Bit 0) */ #define DMA_DMA6_LEN_REG_DMA6_LEN_Msk (0xffffUL) /*!< DMA6_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA7_A_START_REG ==================================================== */ #define DMA_DMA7_A_START_REG_DMA7_A_START_Pos (0UL) /*!< DMA7_A_START (Bit 0) */ #define DMA_DMA7_A_START_REG_DMA7_A_START_Msk (0xffffffffUL) /*!< DMA7_A_START (Bitfield-Mask: 0xffffffff) */ /* =================================================== DMA7_B_START_REG ==================================================== */ #define DMA_DMA7_B_START_REG_DMA7_B_START_Pos (0UL) /*!< DMA7_B_START (Bit 0) */ #define DMA_DMA7_B_START_REG_DMA7_B_START_Msk (0xffffffffUL) /*!< DMA7_B_START (Bitfield-Mask: 0xffffffff) */ /* ===================================================== DMA7_CTRL_REG ===================================================== */ #define DMA_DMA7_CTRL_REG_BUS_ERROR_DETECT_Pos (15UL) /*!< BUS_ERROR_DETECT (Bit 15) */ #define DMA_DMA7_CTRL_REG_BUS_ERROR_DETECT_Msk (0x8000UL) /*!< BUS_ERROR_DETECT (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_BURST_MODE_Pos (13UL) /*!< BURST_MODE (Bit 13) */ #define DMA_DMA7_CTRL_REG_BURST_MODE_Msk (0x6000UL) /*!< BURST_MODE (Bitfield-Mask: 0x03) */ #define DMA_DMA7_CTRL_REG_REQ_SENSE_Pos (12UL) /*!< REQ_SENSE (Bit 12) */ #define DMA_DMA7_CTRL_REG_REQ_SENSE_Msk (0x1000UL) /*!< REQ_SENSE (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_DMA_INIT_Pos (11UL) /*!< DMA_INIT (Bit 11) */ #define DMA_DMA7_CTRL_REG_DMA_INIT_Msk (0x800UL) /*!< DMA_INIT (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_DMA_IDLE_Pos (10UL) /*!< DMA_IDLE (Bit 10) */ #define DMA_DMA7_CTRL_REG_DMA_IDLE_Msk (0x400UL) /*!< DMA_IDLE (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_DMA_PRIO_Pos (7UL) /*!< DMA_PRIO (Bit 7) */ #define DMA_DMA7_CTRL_REG_DMA_PRIO_Msk (0x380UL) /*!< DMA_PRIO (Bitfield-Mask: 0x07) */ #define DMA_DMA7_CTRL_REG_CIRCULAR_Pos (6UL) /*!< CIRCULAR (Bit 6) */ #define DMA_DMA7_CTRL_REG_CIRCULAR_Msk (0x40UL) /*!< CIRCULAR (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_AINC_Pos (5UL) /*!< AINC (Bit 5) */ #define DMA_DMA7_CTRL_REG_AINC_Msk (0x20UL) /*!< AINC (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_BINC_Pos (4UL) /*!< BINC (Bit 4) */ #define DMA_DMA7_CTRL_REG_BINC_Msk (0x10UL) /*!< BINC (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_DREQ_MODE_Pos (3UL) /*!< DREQ_MODE (Bit 3) */ #define DMA_DMA7_CTRL_REG_DREQ_MODE_Msk (0x8UL) /*!< DREQ_MODE (Bitfield-Mask: 0x01) */ #define DMA_DMA7_CTRL_REG_BW_Pos (1UL) /*!< BW (Bit 1) */ #define DMA_DMA7_CTRL_REG_BW_Msk (0x6UL) /*!< BW (Bitfield-Mask: 0x03) */ #define DMA_DMA7_CTRL_REG_DMA_ON_Pos (0UL) /*!< DMA_ON (Bit 0) */ #define DMA_DMA7_CTRL_REG_DMA_ON_Msk (0x1UL) /*!< DMA_ON (Bitfield-Mask: 0x01) */ /* ===================================================== DMA7_IDX_REG ====================================================== */ #define DMA_DMA7_IDX_REG_DMA7_IDX_Pos (0UL) /*!< DMA7_IDX (Bit 0) */ #define DMA_DMA7_IDX_REG_DMA7_IDX_Msk (0xffffUL) /*!< DMA7_IDX (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA7_INT_REG ====================================================== */ #define DMA_DMA7_INT_REG_DMA7_INT_Pos (0UL) /*!< DMA7_INT (Bit 0) */ #define DMA_DMA7_INT_REG_DMA7_INT_Msk (0xffffUL) /*!< DMA7_INT (Bitfield-Mask: 0xffff) */ /* ===================================================== DMA7_LEN_REG ====================================================== */ #define DMA_DMA7_LEN_REG_DMA7_LEN_Pos (0UL) /*!< DMA7_LEN (Bit 0) */ #define DMA_DMA7_LEN_REG_DMA7_LEN_Msk (0xffffUL) /*!< DMA7_LEN (Bitfield-Mask: 0xffff) */ /* =================================================== DMA_CLEAR_INT_REG =================================================== */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH7_Pos (7UL) /*!< DMA_RST_IRQ_CH7 (Bit 7) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH7_Msk (0x80UL) /*!< DMA_RST_IRQ_CH7 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH6_Pos (6UL) /*!< DMA_RST_IRQ_CH6 (Bit 6) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH6_Msk (0x40UL) /*!< DMA_RST_IRQ_CH6 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH5_Pos (5UL) /*!< DMA_RST_IRQ_CH5 (Bit 5) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH5_Msk (0x20UL) /*!< DMA_RST_IRQ_CH5 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH4_Pos (4UL) /*!< DMA_RST_IRQ_CH4 (Bit 4) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH4_Msk (0x10UL) /*!< DMA_RST_IRQ_CH4 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH3_Pos (3UL) /*!< DMA_RST_IRQ_CH3 (Bit 3) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH3_Msk (0x8UL) /*!< DMA_RST_IRQ_CH3 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH2_Pos (2UL) /*!< DMA_RST_IRQ_CH2 (Bit 2) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH2_Msk (0x4UL) /*!< DMA_RST_IRQ_CH2 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH1_Pos (1UL) /*!< DMA_RST_IRQ_CH1 (Bit 1) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH1_Msk (0x2UL) /*!< DMA_RST_IRQ_CH1 (Bitfield-Mask: 0x01) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH0_Pos (0UL) /*!< DMA_RST_IRQ_CH0 (Bit 0) */ #define DMA_DMA_CLEAR_INT_REG_DMA_RST_IRQ_CH0_Msk (0x1UL) /*!< DMA_RST_IRQ_CH0 (Bitfield-Mask: 0x01) */ /* =================================================== DMA_INT_MASK_REG ==================================================== */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE7_Pos (7UL) /*!< DMA_IRQ_ENABLE7 (Bit 7) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE7_Msk (0x80UL) /*!< DMA_IRQ_ENABLE7 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE6_Pos (6UL) /*!< DMA_IRQ_ENABLE6 (Bit 6) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE6_Msk (0x40UL) /*!< DMA_IRQ_ENABLE6 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE5_Pos (5UL) /*!< DMA_IRQ_ENABLE5 (Bit 5) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE5_Msk (0x20UL) /*!< DMA_IRQ_ENABLE5 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE4_Pos (4UL) /*!< DMA_IRQ_ENABLE4 (Bit 4) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE4_Msk (0x10UL) /*!< DMA_IRQ_ENABLE4 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE3_Pos (3UL) /*!< DMA_IRQ_ENABLE3 (Bit 3) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE3_Msk (0x8UL) /*!< DMA_IRQ_ENABLE3 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE2_Pos (2UL) /*!< DMA_IRQ_ENABLE2 (Bit 2) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE2_Msk (0x4UL) /*!< DMA_IRQ_ENABLE2 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE1_Pos (1UL) /*!< DMA_IRQ_ENABLE1 (Bit 1) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE1_Msk (0x2UL) /*!< DMA_IRQ_ENABLE1 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE0_Pos (0UL) /*!< DMA_IRQ_ENABLE0 (Bit 0) */ #define DMA_DMA_INT_MASK_REG_DMA_IRQ_ENABLE0_Msk (0x1UL) /*!< DMA_IRQ_ENABLE0 (Bitfield-Mask: 0x01) */ /* ================================================== DMA_INT_STATUS_REG =================================================== */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR7_Pos (15UL) /*!< DMA_BUS_ERR7 (Bit 15) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR7_Msk (0x8000UL) /*!< DMA_BUS_ERR7 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR6_Pos (14UL) /*!< DMA_BUS_ERR6 (Bit 14) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR6_Msk (0x4000UL) /*!< DMA_BUS_ERR6 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR5_Pos (13UL) /*!< DMA_BUS_ERR5 (Bit 13) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR5_Msk (0x2000UL) /*!< DMA_BUS_ERR5 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR4_Pos (12UL) /*!< DMA_BUS_ERR4 (Bit 12) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR4_Msk (0x1000UL) /*!< DMA_BUS_ERR4 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR3_Pos (11UL) /*!< DMA_BUS_ERR3 (Bit 11) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR3_Msk (0x800UL) /*!< DMA_BUS_ERR3 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR2_Pos (10UL) /*!< DMA_BUS_ERR2 (Bit 10) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR2_Msk (0x400UL) /*!< DMA_BUS_ERR2 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR1_Pos (9UL) /*!< DMA_BUS_ERR1 (Bit 9) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR1_Msk (0x200UL) /*!< DMA_BUS_ERR1 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR0_Pos (8UL) /*!< DMA_BUS_ERR0 (Bit 8) */ #define DMA_DMA_INT_STATUS_REG_DMA_BUS_ERR0_Msk (0x100UL) /*!< DMA_BUS_ERR0 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH7_Pos (7UL) /*!< DMA_IRQ_CH7 (Bit 7) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH7_Msk (0x80UL) /*!< DMA_IRQ_CH7 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH6_Pos (6UL) /*!< DMA_IRQ_CH6 (Bit 6) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH6_Msk (0x40UL) /*!< DMA_IRQ_CH6 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH5_Pos (5UL) /*!< DMA_IRQ_CH5 (Bit 5) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH5_Msk (0x20UL) /*!< DMA_IRQ_CH5 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH4_Pos (4UL) /*!< DMA_IRQ_CH4 (Bit 4) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH4_Msk (0x10UL) /*!< DMA_IRQ_CH4 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH3_Pos (3UL) /*!< DMA_IRQ_CH3 (Bit 3) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH3_Msk (0x8UL) /*!< DMA_IRQ_CH3 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH2_Pos (2UL) /*!< DMA_IRQ_CH2 (Bit 2) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH2_Msk (0x4UL) /*!< DMA_IRQ_CH2 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH1_Pos (1UL) /*!< DMA_IRQ_CH1 (Bit 1) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH1_Msk (0x2UL) /*!< DMA_IRQ_CH1 (Bitfield-Mask: 0x01) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH0_Pos (0UL) /*!< DMA_IRQ_CH0 (Bit 0) */ #define DMA_DMA_INT_STATUS_REG_DMA_IRQ_CH0_Msk (0x1UL) /*!< DMA_IRQ_CH0 (Bitfield-Mask: 0x01) */ /* ==================================================== DMA_REQ_MUX_REG ==================================================== */ #define DMA_DMA_REQ_MUX_REG_DMA67_SEL_Pos (12UL) /*!< DMA67_SEL (Bit 12) */ #define DMA_DMA_REQ_MUX_REG_DMA67_SEL_Msk (0xf000UL) /*!< DMA67_SEL (Bitfield-Mask: 0x0f) */ #define DMA_DMA_REQ_MUX_REG_DMA45_SEL_Pos (8UL) /*!< DMA45_SEL (Bit 8) */ #define DMA_DMA_REQ_MUX_REG_DMA45_SEL_Msk (0xf00UL) /*!< DMA45_SEL (Bitfield-Mask: 0x0f) */ #define DMA_DMA_REQ_MUX_REG_DMA23_SEL_Pos (4UL) /*!< DMA23_SEL (Bit 4) */ #define DMA_DMA_REQ_MUX_REG_DMA23_SEL_Msk (0xf0UL) /*!< DMA23_SEL (Bitfield-Mask: 0x0f) */ #define DMA_DMA_REQ_MUX_REG_DMA01_SEL_Pos (0UL) /*!< DMA01_SEL (Bit 0) */ #define DMA_DMA_REQ_MUX_REG_DMA01_SEL_Msk (0xfUL) /*!< DMA01_SEL (Bitfield-Mask: 0x0f) */ /* =========================================================================================================================== */ /* ================ DW ================ */ /* =========================================================================================================================== */ /* =================================================== AHB_DMA_CCLM1_REG =================================================== */ #define DW_AHB_DMA_CCLM1_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ #define DW_AHB_DMA_CCLM1_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ /* =================================================== AHB_DMA_CCLM2_REG =================================================== */ #define DW_AHB_DMA_CCLM2_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ #define DW_AHB_DMA_CCLM2_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ /* =================================================== AHB_DMA_CCLM3_REG =================================================== */ #define DW_AHB_DMA_CCLM3_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ #define DW_AHB_DMA_CCLM3_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ /* =================================================== AHB_DMA_CCLM4_REG =================================================== */ #define DW_AHB_DMA_CCLM4_REG_AHB_DMA_CCLM_Pos (0UL) /*!< AHB_DMA_CCLM (Bit 0) */ #define DW_AHB_DMA_CCLM4_REG_AHB_DMA_CCLM_Msk (0xffffUL) /*!< AHB_DMA_CCLM (Bitfield-Mask: 0xffff) */ /* ================================================ AHB_DMA_DFLT_MASTER_REG ================================================ */ #define DW_AHB_DMA_DFLT_MASTER_REG_AHB_DMA_DFLT_MASTER_Pos (0UL) /*!< AHB_DMA_DFLT_MASTER (Bit 0) */ #define DW_AHB_DMA_DFLT_MASTER_REG_AHB_DMA_DFLT_MASTER_Msk (0xfUL) /*!< AHB_DMA_DFLT_MASTER (Bitfield-Mask: 0x0f) */ /* ==================================================== AHB_DMA_PL1_REG ==================================================== */ #define DW_AHB_DMA_PL1_REG_AHB_DMA_PL1_Pos (0UL) /*!< AHB_DMA_PL1 (Bit 0) */ #define DW_AHB_DMA_PL1_REG_AHB_DMA_PL1_Msk (0xfUL) /*!< AHB_DMA_PL1 (Bitfield-Mask: 0x0f) */ /* ==================================================== AHB_DMA_PL2_REG ==================================================== */ #define DW_AHB_DMA_PL2_REG_AHB_DMA_PL2_Pos (0UL) /*!< AHB_DMA_PL2 (Bit 0) */ #define DW_AHB_DMA_PL2_REG_AHB_DMA_PL2_Msk (0xfUL) /*!< AHB_DMA_PL2 (Bitfield-Mask: 0x0f) */ /* ==================================================== AHB_DMA_PL3_REG ==================================================== */ #define DW_AHB_DMA_PL3_REG_AHB_DMA_PL3_Pos (0UL) /*!< AHB_DMA_PL3 (Bit 0) */ #define DW_AHB_DMA_PL3_REG_AHB_DMA_PL3_Msk (0xfUL) /*!< AHB_DMA_PL3 (Bitfield-Mask: 0x0f) */ /* ==================================================== AHB_DMA_PL4_REG ==================================================== */ #define DW_AHB_DMA_PL4_REG_AHB_DMA_PL4_Pos (0UL) /*!< AHB_DMA_PL4 (Bit 0) */ #define DW_AHB_DMA_PL4_REG_AHB_DMA_PL4_Msk (0xfUL) /*!< AHB_DMA_PL4 (Bitfield-Mask: 0x0f) */ /* ==================================================== AHB_DMA_TCL_REG ==================================================== */ #define DW_AHB_DMA_TCL_REG_AHB_DMA_TCL_Pos (0UL) /*!< AHB_DMA_TCL (Bit 0) */ #define DW_AHB_DMA_TCL_REG_AHB_DMA_TCL_Msk (0xffffUL) /*!< AHB_DMA_TCL (Bitfield-Mask: 0xffff) */ /* ================================================== AHB_DMA_VERSION_REG ================================================== */ #define DW_AHB_DMA_VERSION_REG_AHB_DMA_VERSION_Pos (0UL) /*!< AHB_DMA_VERSION (Bit 0) */ #define DW_AHB_DMA_VERSION_REG_AHB_DMA_VERSION_Msk (0xffffffffUL) /*!< AHB_DMA_VERSION (Bitfield-Mask: 0xffffffff) */ /* =================================================== AHB_DMA_WTEN_REG ==================================================== */ #define DW_AHB_DMA_WTEN_REG_AHB_DMA_WTEN_Pos (0UL) /*!< AHB_DMA_WTEN (Bit 0) */ #define DW_AHB_DMA_WTEN_REG_AHB_DMA_WTEN_Msk (0x1UL) /*!< AHB_DMA_WTEN (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ GPADC ================ */ /* =========================================================================================================================== */ /* ================================================= GP_ADC_CLEAR_INT_REG ================================================== */ #define GPADC_GP_ADC_CLEAR_INT_REG_GP_ADC_CLR_INT_Pos (0UL) /*!< GP_ADC_CLR_INT (Bit 0) */ #define GPADC_GP_ADC_CLEAR_INT_REG_GP_ADC_CLR_INT_Msk (0xffffUL) /*!< GP_ADC_CLR_INT (Bitfield-Mask: 0xffff) */ /* =================================================== GP_ADC_CTRL2_REG ==================================================== */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_STORE_DEL_Pos (12UL) /*!< GP_ADC_STORE_DEL (Bit 12) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_STORE_DEL_Msk (0xf000UL) /*!< GP_ADC_STORE_DEL (Bitfield-Mask: 0x0f) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_SMPL_TIME_Pos (8UL) /*!< GP_ADC_SMPL_TIME (Bit 8) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_SMPL_TIME_Msk (0xf00UL) /*!< GP_ADC_SMPL_TIME (Bitfield-Mask: 0x0f) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_CONV_NRS_Pos (5UL) /*!< GP_ADC_CONV_NRS (Bit 5) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_CONV_NRS_Msk (0xe0UL) /*!< GP_ADC_CONV_NRS (Bitfield-Mask: 0x07) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_DMA_EN_Pos (3UL) /*!< GP_ADC_DMA_EN (Bit 3) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_DMA_EN_Msk (0x8UL) /*!< GP_ADC_DMA_EN (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_I20U_Pos (2UL) /*!< GP_ADC_I20U (Bit 2) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_I20U_Msk (0x4UL) /*!< GP_ADC_I20U (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_IDYN_Pos (1UL) /*!< GP_ADC_IDYN (Bit 1) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_IDYN_Msk (0x2UL) /*!< GP_ADC_IDYN (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_ATTN3X_Pos (0UL) /*!< GP_ADC_ATTN3X (Bit 0) */ #define GPADC_GP_ADC_CTRL2_REG_GP_ADC_ATTN3X_Msk (0x1UL) /*!< GP_ADC_ATTN3X (Bitfield-Mask: 0x01) */ /* =================================================== GP_ADC_CTRL3_REG ==================================================== */ #define GPADC_GP_ADC_CTRL3_REG_GP_ADC_INTERVAL_Pos (8UL) /*!< GP_ADC_INTERVAL (Bit 8) */ #define GPADC_GP_ADC_CTRL3_REG_GP_ADC_INTERVAL_Msk (0xff00UL) /*!< GP_ADC_INTERVAL (Bitfield-Mask: 0xff) */ #define GPADC_GP_ADC_CTRL3_REG_GP_ADC_EN_DEL_Pos (0UL) /*!< GP_ADC_EN_DEL (Bit 0) */ #define GPADC_GP_ADC_CTRL3_REG_GP_ADC_EN_DEL_Msk (0xffUL) /*!< GP_ADC_EN_DEL (Bitfield-Mask: 0xff) */ /* ==================================================== GP_ADC_CTRL_REG ==================================================== */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_EN_Pos (18UL) /*!< GP_ADC_DIFF_TEMP_EN (Bit 18) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_EN_Msk (0x40000UL) /*!< GP_ADC_DIFF_TEMP_EN (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_SEL_Pos (16UL) /*!< GP_ADC_DIFF_TEMP_SEL (Bit 16) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_DIFF_TEMP_SEL_Msk (0x30000UL) /*!< GP_ADC_DIFF_TEMP_SEL (Bitfield-Mask: 0x03) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_LDO_ZERO_Pos (15UL) /*!< GP_ADC_LDO_ZERO (Bit 15) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_LDO_ZERO_Msk (0x8000UL) /*!< GP_ADC_LDO_ZERO (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CHOP_Pos (14UL) /*!< GP_ADC_CHOP (Bit 14) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CHOP_Msk (0x4000UL) /*!< GP_ADC_CHOP (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SIGN_Pos (13UL) /*!< GP_ADC_SIGN (Bit 13) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SIGN_Msk (0x2000UL) /*!< GP_ADC_SIGN (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SEL_Pos (8UL) /*!< GP_ADC_SEL (Bit 8) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SEL_Msk (0x1f00UL) /*!< GP_ADC_SEL (Bitfield-Mask: 0x1f) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_MUTE_Pos (7UL) /*!< GP_ADC_MUTE (Bit 7) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_MUTE_Msk (0x80UL) /*!< GP_ADC_MUTE (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SE_Pos (6UL) /*!< GP_ADC_SE (Bit 6) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_SE_Msk (0x40UL) /*!< GP_ADC_SE (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_MINT_Pos (5UL) /*!< GP_ADC_MINT (Bit 5) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_MINT_Msk (0x20UL) /*!< GP_ADC_MINT (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_INT_Pos (4UL) /*!< GP_ADC_INT (Bit 4) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_INT_Msk (0x10UL) /*!< GP_ADC_INT (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CLK_SEL_Pos (3UL) /*!< GP_ADC_CLK_SEL (Bit 3) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CLK_SEL_Msk (0x8UL) /*!< GP_ADC_CLK_SEL (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CONT_Pos (2UL) /*!< GP_ADC_CONT (Bit 2) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_CONT_Msk (0x4UL) /*!< GP_ADC_CONT (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_START_Pos (1UL) /*!< GP_ADC_START (Bit 1) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_START_Msk (0x2UL) /*!< GP_ADC_START (Bitfield-Mask: 0x01) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_EN_Pos (0UL) /*!< GP_ADC_EN (Bit 0) */ #define GPADC_GP_ADC_CTRL_REG_GP_ADC_EN_Msk (0x1UL) /*!< GP_ADC_EN (Bitfield-Mask: 0x01) */ /* ==================================================== GP_ADC_OFFN_REG ==================================================== */ #define GPADC_GP_ADC_OFFN_REG_GP_ADC_OFFN_Pos (0UL) /*!< GP_ADC_OFFN (Bit 0) */ #define GPADC_GP_ADC_OFFN_REG_GP_ADC_OFFN_Msk (0x3ffUL) /*!< GP_ADC_OFFN (Bitfield-Mask: 0x3ff) */ /* ==================================================== GP_ADC_OFFP_REG ==================================================== */ #define GPADC_GP_ADC_OFFP_REG_GP_ADC_OFFP_Pos (0UL) /*!< GP_ADC_OFFP (Bit 0) */ #define GPADC_GP_ADC_OFFP_REG_GP_ADC_OFFP_Msk (0x3ffUL) /*!< GP_ADC_OFFP (Bitfield-Mask: 0x3ff) */ /* =================================================== GP_ADC_RESULT_REG =================================================== */ #define GPADC_GP_ADC_RESULT_REG_GP_ADC_VAL_Pos (0UL) /*!< GP_ADC_VAL (Bit 0) */ #define GPADC_GP_ADC_RESULT_REG_GP_ADC_VAL_Msk (0xffffUL) /*!< GP_ADC_VAL (Bitfield-Mask: 0xffff) */ /* =========================================================================================================================== */ /* ================ GPIO ================ */ /* =========================================================================================================================== */ /* =================================================== GPIO_CLK_SEL_REG ==================================================== */ #define GPIO_GPIO_CLK_SEL_REG_DIVN_OUTPUT_EN_Pos (9UL) /*!< DIVN_OUTPUT_EN (Bit 9) */ #define GPIO_GPIO_CLK_SEL_REG_DIVN_OUTPUT_EN_Msk (0x200UL) /*!< DIVN_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_RC32M_OUTPUT_EN_Pos (8UL) /*!< RC32M_OUTPUT_EN (Bit 8) */ #define GPIO_GPIO_CLK_SEL_REG_RC32M_OUTPUT_EN_Msk (0x100UL) /*!< RC32M_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_XTAL32M_OUTPUT_EN_Pos (7UL) /*!< XTAL32M_OUTPUT_EN (Bit 7) */ #define GPIO_GPIO_CLK_SEL_REG_XTAL32M_OUTPUT_EN_Msk (0x80UL) /*!< XTAL32M_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_RCX_OUTPUT_EN_Pos (6UL) /*!< RCX_OUTPUT_EN (Bit 6) */ #define GPIO_GPIO_CLK_SEL_REG_RCX_OUTPUT_EN_Msk (0x40UL) /*!< RCX_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_RC32K_OUTPUT_EN_Pos (5UL) /*!< RC32K_OUTPUT_EN (Bit 5) */ #define GPIO_GPIO_CLK_SEL_REG_RC32K_OUTPUT_EN_Msk (0x20UL) /*!< RC32K_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_XTAL32K_OUTPUT_EN_Pos (4UL) /*!< XTAL32K_OUTPUT_EN (Bit 4) */ #define GPIO_GPIO_CLK_SEL_REG_XTAL32K_OUTPUT_EN_Msk (0x10UL) /*!< XTAL32K_OUTPUT_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_EN_Pos (3UL) /*!< FUNC_CLOCK_EN (Bit 3) */ #define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_EN_Msk (0x8UL) /*!< FUNC_CLOCK_EN (Bitfield-Mask: 0x01) */ #define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_SEL_Pos (0UL) /*!< FUNC_CLOCK_SEL (Bit 0) */ #define GPIO_GPIO_CLK_SEL_REG_FUNC_CLOCK_SEL_Msk (0x7UL) /*!< FUNC_CLOCK_SEL (Bitfield-Mask: 0x07) */ /* ==================================================== P0_00_MODE_REG ===================================================== */ #define GPIO_P0_00_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_00_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_00_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_00_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_00_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_00_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_01_MODE_REG ===================================================== */ #define GPIO_P0_01_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_01_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_01_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_01_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_01_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_01_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_02_MODE_REG ===================================================== */ #define GPIO_P0_02_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_02_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_02_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_02_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_02_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_02_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_03_MODE_REG ===================================================== */ #define GPIO_P0_03_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_03_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_03_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_03_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_03_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_03_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_04_MODE_REG ===================================================== */ #define GPIO_P0_04_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_04_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_04_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_04_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_04_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_04_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_05_MODE_REG ===================================================== */ #define GPIO_P0_05_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_05_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_05_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_05_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_05_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_05_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_06_MODE_REG ===================================================== */ #define GPIO_P0_06_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_06_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_06_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_06_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_06_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_06_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_07_MODE_REG ===================================================== */ #define GPIO_P0_07_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_07_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_07_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_07_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_07_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_07_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_08_MODE_REG ===================================================== */ #define GPIO_P0_08_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_08_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_08_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_08_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_08_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_08_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_09_MODE_REG ===================================================== */ #define GPIO_P0_09_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_09_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_09_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_09_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_09_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_09_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_10_MODE_REG ===================================================== */ #define GPIO_P0_10_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_10_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_10_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_10_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_10_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_10_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_11_MODE_REG ===================================================== */ #define GPIO_P0_11_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_11_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_11_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_11_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_11_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_11_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_12_MODE_REG ===================================================== */ #define GPIO_P0_12_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_12_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_12_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_12_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_12_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_12_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_13_MODE_REG ===================================================== */ #define GPIO_P0_13_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_13_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_13_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_13_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_13_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_13_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_14_MODE_REG ===================================================== */ #define GPIO_P0_14_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_14_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_14_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_14_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_14_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_14_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_15_MODE_REG ===================================================== */ #define GPIO_P0_15_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_15_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_15_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_15_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_15_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_15_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_16_MODE_REG ===================================================== */ #define GPIO_P0_16_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_16_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_16_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_16_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_16_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_16_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_17_MODE_REG ===================================================== */ #define GPIO_P0_17_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_17_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_17_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_17_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_17_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_17_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_18_MODE_REG ===================================================== */ #define GPIO_P0_18_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_18_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_18_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_18_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_18_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_18_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_19_MODE_REG ===================================================== */ #define GPIO_P0_19_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_19_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_19_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_19_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_19_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_19_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_20_MODE_REG ===================================================== */ #define GPIO_P0_20_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_20_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_20_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_20_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_20_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_20_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_21_MODE_REG ===================================================== */ #define GPIO_P0_21_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_21_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_21_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_21_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_21_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_21_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_22_MODE_REG ===================================================== */ #define GPIO_P0_22_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_22_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_22_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_22_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_22_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_22_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_23_MODE_REG ===================================================== */ #define GPIO_P0_23_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_23_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_23_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_23_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_23_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_23_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_24_MODE_REG ===================================================== */ #define GPIO_P0_24_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_24_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_24_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_24_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_24_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_24_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_25_MODE_REG ===================================================== */ #define GPIO_P0_25_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_25_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_25_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_25_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_25_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_25_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_26_MODE_REG ===================================================== */ #define GPIO_P0_26_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_26_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_26_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_26_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_26_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_26_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_27_MODE_REG ===================================================== */ #define GPIO_P0_27_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_27_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_27_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_27_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_27_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_27_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_28_MODE_REG ===================================================== */ #define GPIO_P0_28_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_28_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_28_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_28_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_28_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_28_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_29_MODE_REG ===================================================== */ #define GPIO_P0_29_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_29_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_29_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_29_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_29_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_29_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_30_MODE_REG ===================================================== */ #define GPIO_P0_30_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_30_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_30_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_30_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_30_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_30_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P0_31_MODE_REG ===================================================== */ #define GPIO_P0_31_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P0_31_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P0_31_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P0_31_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P0_31_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P0_31_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ====================================================== P0_DATA_REG ====================================================== */ #define GPIO_P0_DATA_REG_P0_DATA_Pos (0UL) /*!< P0_DATA (Bit 0) */ #define GPIO_P0_DATA_REG_P0_DATA_Msk (0xffffffffUL) /*!< P0_DATA (Bitfield-Mask: 0xffffffff) */ /* ================================================== P0_PADPWR_CTRL_REG =================================================== */ #define GPIO_P0_PADPWR_CTRL_REG_P0_OUT_CTRL_Pos (6UL) /*!< P0_OUT_CTRL (Bit 6) */ #define GPIO_P0_PADPWR_CTRL_REG_P0_OUT_CTRL_Msk (0xffffffc0UL) /*!< P0_OUT_CTRL (Bitfield-Mask: 0x3ffffff) */ /* =================================================== P0_RESET_DATA_REG =================================================== */ #define GPIO_P0_RESET_DATA_REG_P0_RESET_Pos (0UL) /*!< P0_RESET (Bit 0) */ #define GPIO_P0_RESET_DATA_REG_P0_RESET_Msk (0xffffffffUL) /*!< P0_RESET (Bitfield-Mask: 0xffffffff) */ /* ==================================================== P0_SET_DATA_REG ==================================================== */ #define GPIO_P0_SET_DATA_REG_P0_SET_Pos (0UL) /*!< P0_SET (Bit 0) */ #define GPIO_P0_SET_DATA_REG_P0_SET_Msk (0xffffffffUL) /*!< P0_SET (Bitfield-Mask: 0xffffffff) */ /* ==================================================== P1_00_MODE_REG ===================================================== */ #define GPIO_P1_00_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_00_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_00_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_00_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_00_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_00_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_01_MODE_REG ===================================================== */ #define GPIO_P1_01_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_01_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_01_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_01_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_01_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_01_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_02_MODE_REG ===================================================== */ #define GPIO_P1_02_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_02_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_02_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_02_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_02_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_02_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_03_MODE_REG ===================================================== */ #define GPIO_P1_03_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_03_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_03_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_03_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_03_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_03_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_04_MODE_REG ===================================================== */ #define GPIO_P1_04_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_04_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_04_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_04_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_04_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_04_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_05_MODE_REG ===================================================== */ #define GPIO_P1_05_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_05_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_05_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_05_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_05_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_05_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_06_MODE_REG ===================================================== */ #define GPIO_P1_06_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_06_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_06_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_06_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_06_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_06_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_07_MODE_REG ===================================================== */ #define GPIO_P1_07_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_07_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_07_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_07_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_07_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_07_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_08_MODE_REG ===================================================== */ #define GPIO_P1_08_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_08_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_08_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_08_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_08_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_08_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_09_MODE_REG ===================================================== */ #define GPIO_P1_09_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_09_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_09_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_09_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_09_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_09_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_10_MODE_REG ===================================================== */ #define GPIO_P1_10_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_10_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_10_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_10_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_10_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_10_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_11_MODE_REG ===================================================== */ #define GPIO_P1_11_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_11_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_11_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_11_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_11_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_11_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_12_MODE_REG ===================================================== */ #define GPIO_P1_12_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_12_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_12_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_12_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_12_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_12_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_13_MODE_REG ===================================================== */ #define GPIO_P1_13_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_13_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_13_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_13_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_13_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_13_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_14_MODE_REG ===================================================== */ #define GPIO_P1_14_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_14_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_14_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_14_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_14_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_14_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_15_MODE_REG ===================================================== */ #define GPIO_P1_15_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_15_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_15_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_15_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_15_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_15_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_16_MODE_REG ===================================================== */ #define GPIO_P1_16_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_16_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_16_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_16_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_16_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_16_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_17_MODE_REG ===================================================== */ #define GPIO_P1_17_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_17_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_17_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_17_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_17_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_17_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_18_MODE_REG ===================================================== */ #define GPIO_P1_18_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_18_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_18_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_18_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_18_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_18_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_19_MODE_REG ===================================================== */ #define GPIO_P1_19_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_19_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_19_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_19_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_19_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_19_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_20_MODE_REG ===================================================== */ #define GPIO_P1_20_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_20_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_20_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_20_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_20_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_20_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_21_MODE_REG ===================================================== */ #define GPIO_P1_21_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_21_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_21_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_21_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_21_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_21_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ==================================================== P1_22_MODE_REG ===================================================== */ #define GPIO_P1_22_MODE_REG_PPOD_Pos (10UL) /*!< PPOD (Bit 10) */ #define GPIO_P1_22_MODE_REG_PPOD_Msk (0x400UL) /*!< PPOD (Bitfield-Mask: 0x01) */ #define GPIO_P1_22_MODE_REG_PUPD_Pos (8UL) /*!< PUPD (Bit 8) */ #define GPIO_P1_22_MODE_REG_PUPD_Msk (0x300UL) /*!< PUPD (Bitfield-Mask: 0x03) */ #define GPIO_P1_22_MODE_REG_PID_Pos (0UL) /*!< PID (Bit 0) */ #define GPIO_P1_22_MODE_REG_PID_Msk (0x3fUL) /*!< PID (Bitfield-Mask: 0x3f) */ /* ====================================================== P1_DATA_REG ====================================================== */ #define GPIO_P1_DATA_REG_P1_DATA_Pos (0UL) /*!< P1_DATA (Bit 0) */ #define GPIO_P1_DATA_REG_P1_DATA_Msk (0x7fffffUL) /*!< P1_DATA (Bitfield-Mask: 0x7fffff) */ /* ================================================== P1_PADPWR_CTRL_REG =================================================== */ #define GPIO_P1_PADPWR_CTRL_REG_P1_OUT_CTRL_Pos (0UL) /*!< P1_OUT_CTRL (Bit 0) */ #define GPIO_P1_PADPWR_CTRL_REG_P1_OUT_CTRL_Msk (0x7fffffUL) /*!< P1_OUT_CTRL (Bitfield-Mask: 0x7fffff) */ /* =================================================== P1_RESET_DATA_REG =================================================== */ #define GPIO_P1_RESET_DATA_REG_P1_RESET_Pos (0UL) /*!< P1_RESET (Bit 0) */ #define GPIO_P1_RESET_DATA_REG_P1_RESET_Msk (0x7fffffUL) /*!< P1_RESET (Bitfield-Mask: 0x7fffff) */ /* ==================================================== P1_SET_DATA_REG ==================================================== */ #define GPIO_P1_SET_DATA_REG_P1_SET_Pos (0UL) /*!< P1_SET (Bit 0) */ #define GPIO_P1_SET_DATA_REG_P1_SET_Msk (0x7fffffUL) /*!< P1_SET (Bitfield-Mask: 0x7fffff) */ /* =================================================== PAD_WEAK_CTRL_REG =================================================== */ #define GPIO_PAD_WEAK_CTRL_REG_P1_09_LOWDRV_Pos (12UL) /*!< P1_09_LOWDRV (Bit 12) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_09_LOWDRV_Msk (0x1000UL) /*!< P1_09_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_06_LOWDRV_Pos (11UL) /*!< P1_06_LOWDRV (Bit 11) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_06_LOWDRV_Msk (0x800UL) /*!< P1_06_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_02_LOWDRV_Pos (10UL) /*!< P1_02_LOWDRV (Bit 10) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_02_LOWDRV_Msk (0x400UL) /*!< P1_02_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_01_LOWDRV_Pos (9UL) /*!< P1_01_LOWDRV (Bit 9) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_01_LOWDRV_Msk (0x200UL) /*!< P1_01_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_00_LOWDRV_Pos (8UL) /*!< P1_00_LOWDRV (Bit 8) */ #define GPIO_PAD_WEAK_CTRL_REG_P1_00_LOWDRV_Msk (0x100UL) /*!< P1_00_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_27_LOWDRV_Pos (7UL) /*!< P0_27_LOWDRV (Bit 7) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_27_LOWDRV_Msk (0x80UL) /*!< P0_27_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_26_LOWDRV_Pos (6UL) /*!< P0_26_LOWDRV (Bit 6) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_26_LOWDRV_Msk (0x40UL) /*!< P0_26_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_25_LOWDRV_Pos (5UL) /*!< P0_25_LOWDRV (Bit 5) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_25_LOWDRV_Msk (0x20UL) /*!< P0_25_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_18_LOWDRV_Pos (4UL) /*!< P0_18_LOWDRV (Bit 4) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_18_LOWDRV_Msk (0x10UL) /*!< P0_18_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_17_LOWDRV_Pos (3UL) /*!< P0_17_LOWDRV (Bit 3) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_17_LOWDRV_Msk (0x8UL) /*!< P0_17_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_16_LOWDRV_Pos (2UL) /*!< P0_16_LOWDRV (Bit 2) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_16_LOWDRV_Msk (0x4UL) /*!< P0_16_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_07_LOWDRV_Pos (1UL) /*!< P0_07_LOWDRV (Bit 1) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_07_LOWDRV_Msk (0x2UL) /*!< P0_07_LOWDRV (Bitfield-Mask: 0x01) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_06_LOWDRV_Pos (0UL) /*!< P0_06_LOWDRV (Bit 0) */ #define GPIO_PAD_WEAK_CTRL_REG_P0_06_LOWDRV_Msk (0x1UL) /*!< P0_06_LOWDRV (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ GPREG ================ */ /* =========================================================================================================================== */ /* ======================================================= DEBUG_REG ======================================================= */ #define GPREG_DEBUG_REG_CROSS_CPU_HALT_SENSITIVITY_Pos (8UL) /*!< CROSS_CPU_HALT_SENSITIVITY (Bit 8) */ #define GPREG_DEBUG_REG_CROSS_CPU_HALT_SENSITIVITY_Msk (0x100UL) /*!< CROSS_CPU_HALT_SENSITIVITY (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_SYS_CPUWAIT_ON_JTAG_Pos (7UL) /*!< SYS_CPUWAIT_ON_JTAG (Bit 7) */ #define GPREG_DEBUG_REG_SYS_CPUWAIT_ON_JTAG_Msk (0x80UL) /*!< SYS_CPUWAIT_ON_JTAG (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_SYS_CPUWAIT_Pos (6UL) /*!< SYS_CPUWAIT (Bit 6) */ #define GPREG_DEBUG_REG_SYS_CPUWAIT_Msk (0x40UL) /*!< SYS_CPUWAIT (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_CMAC_CPU_IS_HALTED_Pos (5UL) /*!< CMAC_CPU_IS_HALTED (Bit 5) */ #define GPREG_DEBUG_REG_CMAC_CPU_IS_HALTED_Msk (0x20UL) /*!< CMAC_CPU_IS_HALTED (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_SYS_CPU_IS_HALTED_Pos (4UL) /*!< SYS_CPU_IS_HALTED (Bit 4) */ #define GPREG_DEBUG_REG_SYS_CPU_IS_HALTED_Msk (0x10UL) /*!< SYS_CPU_IS_HALTED (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_HALT_CMAC_SYS_CPU_EN_Pos (3UL) /*!< HALT_CMAC_SYS_CPU_EN (Bit 3) */ #define GPREG_DEBUG_REG_HALT_CMAC_SYS_CPU_EN_Msk (0x8UL) /*!< HALT_CMAC_SYS_CPU_EN (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_HALT_SYS_CMAC_CPU_EN_Pos (2UL) /*!< HALT_SYS_CMAC_CPU_EN (Bit 2) */ #define GPREG_DEBUG_REG_HALT_SYS_CMAC_CPU_EN_Msk (0x4UL) /*!< HALT_SYS_CMAC_CPU_EN (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_CMAC_CPU_FREEZE_EN_Pos (1UL) /*!< CMAC_CPU_FREEZE_EN (Bit 1) */ #define GPREG_DEBUG_REG_CMAC_CPU_FREEZE_EN_Msk (0x2UL) /*!< CMAC_CPU_FREEZE_EN (Bitfield-Mask: 0x01) */ #define GPREG_DEBUG_REG_SYS_CPU_FREEZE_EN_Pos (0UL) /*!< SYS_CPU_FREEZE_EN (Bit 0) */ #define GPREG_DEBUG_REG_SYS_CPU_FREEZE_EN_Msk (0x1UL) /*!< SYS_CPU_FREEZE_EN (Bitfield-Mask: 0x01) */ /* ==================================================== GP_CONTROL_REG ===================================================== */ #define GPREG_GP_CONTROL_REG_CMAC_H2H_BRIDGE_BYPASS_Pos (1UL) /*!< CMAC_H2H_BRIDGE_BYPASS (Bit 1) */ #define GPREG_GP_CONTROL_REG_CMAC_H2H_BRIDGE_BYPASS_Msk (0x2UL) /*!< CMAC_H2H_BRIDGE_BYPASS (Bitfield-Mask: 0x01) */ /* ===================================================== GP_STATUS_REG ===================================================== */ #define GPREG_GP_STATUS_REG_CAL_PHASE_Pos (0UL) /*!< CAL_PHASE (Bit 0) */ #define GPREG_GP_STATUS_REG_CAL_PHASE_Msk (0x1UL) /*!< CAL_PHASE (Bitfield-Mask: 0x01) */ /* =================================================== RESET_FREEZE_REG ==================================================== */ #define GPREG_RESET_FREEZE_REG_FRZ_CMAC_WDOG_Pos (10UL) /*!< FRZ_CMAC_WDOG (Bit 10) */ #define GPREG_RESET_FREEZE_REG_FRZ_CMAC_WDOG_Msk (0x400UL) /*!< FRZ_CMAC_WDOG (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM4_Pos (9UL) /*!< FRZ_SWTIM4 (Bit 9) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM4_Msk (0x200UL) /*!< FRZ_SWTIM4 (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM3_Pos (8UL) /*!< FRZ_SWTIM3 (Bit 8) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM3_Msk (0x100UL) /*!< FRZ_SWTIM3 (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_PWMLED_Pos (7UL) /*!< FRZ_PWMLED (Bit 7) */ #define GPREG_RESET_FREEZE_REG_FRZ_PWMLED_Msk (0x80UL) /*!< FRZ_PWMLED (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM2_Pos (6UL) /*!< FRZ_SWTIM2 (Bit 6) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM2_Msk (0x40UL) /*!< FRZ_SWTIM2 (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_DMA_Pos (5UL) /*!< FRZ_DMA (Bit 5) */ #define GPREG_RESET_FREEZE_REG_FRZ_DMA_Msk (0x20UL) /*!< FRZ_DMA (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_USB_Pos (4UL) /*!< FRZ_USB (Bit 4) */ #define GPREG_RESET_FREEZE_REG_FRZ_USB_Msk (0x10UL) /*!< FRZ_USB (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_SYS_WDOG_Pos (3UL) /*!< FRZ_SYS_WDOG (Bit 3) */ #define GPREG_RESET_FREEZE_REG_FRZ_SYS_WDOG_Msk (0x8UL) /*!< FRZ_SYS_WDOG (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_RESERVED_Pos (2UL) /*!< FRZ_RESERVED (Bit 2) */ #define GPREG_RESET_FREEZE_REG_FRZ_RESERVED_Msk (0x4UL) /*!< FRZ_RESERVED (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM_Pos (1UL) /*!< FRZ_SWTIM (Bit 1) */ #define GPREG_RESET_FREEZE_REG_FRZ_SWTIM_Msk (0x2UL) /*!< FRZ_SWTIM (Bitfield-Mask: 0x01) */ #define GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Pos (0UL) /*!< FRZ_WKUPTIM (Bit 0) */ #define GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Msk (0x1UL) /*!< FRZ_WKUPTIM (Bitfield-Mask: 0x01) */ /* ==================================================== SET_FREEZE_REG ===================================================== */ #define GPREG_SET_FREEZE_REG_FRZ_CMAC_WDOG_Pos (10UL) /*!< FRZ_CMAC_WDOG (Bit 10) */ #define GPREG_SET_FREEZE_REG_FRZ_CMAC_WDOG_Msk (0x400UL) /*!< FRZ_CMAC_WDOG (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM4_Pos (9UL) /*!< FRZ_SWTIM4 (Bit 9) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM4_Msk (0x200UL) /*!< FRZ_SWTIM4 (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM3_Pos (8UL) /*!< FRZ_SWTIM3 (Bit 8) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM3_Msk (0x100UL) /*!< FRZ_SWTIM3 (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_PWMLED_Pos (7UL) /*!< FRZ_PWMLED (Bit 7) */ #define GPREG_SET_FREEZE_REG_FRZ_PWMLED_Msk (0x80UL) /*!< FRZ_PWMLED (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM2_Pos (6UL) /*!< FRZ_SWTIM2 (Bit 6) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM2_Msk (0x40UL) /*!< FRZ_SWTIM2 (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_DMA_Pos (5UL) /*!< FRZ_DMA (Bit 5) */ #define GPREG_SET_FREEZE_REG_FRZ_DMA_Msk (0x20UL) /*!< FRZ_DMA (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_USB_Pos (4UL) /*!< FRZ_USB (Bit 4) */ #define GPREG_SET_FREEZE_REG_FRZ_USB_Msk (0x10UL) /*!< FRZ_USB (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Pos (3UL) /*!< FRZ_SYS_WDOG (Bit 3) */ #define GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk (0x8UL) /*!< FRZ_SYS_WDOG (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_RESERVED_Pos (2UL) /*!< FRZ_RESERVED (Bit 2) */ #define GPREG_SET_FREEZE_REG_FRZ_RESERVED_Msk (0x4UL) /*!< FRZ_RESERVED (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM_Pos (1UL) /*!< FRZ_SWTIM (Bit 1) */ #define GPREG_SET_FREEZE_REG_FRZ_SWTIM_Msk (0x2UL) /*!< FRZ_SWTIM (Bitfield-Mask: 0x01) */ #define GPREG_SET_FREEZE_REG_FRZ_WKUPTIM_Pos (0UL) /*!< FRZ_WKUPTIM (Bit 0) */ #define GPREG_SET_FREEZE_REG_FRZ_WKUPTIM_Msk (0x1UL) /*!< FRZ_WKUPTIM (Bitfield-Mask: 0x01) */ /* ====================================================== USBPAD_REG ======================================================= */ #define GPREG_USBPAD_REG_USBPHY_FORCE_SW2_ON_Pos (2UL) /*!< USBPHY_FORCE_SW2_ON (Bit 2) */ #define GPREG_USBPAD_REG_USBPHY_FORCE_SW2_ON_Msk (0x4UL) /*!< USBPHY_FORCE_SW2_ON (Bitfield-Mask: 0x01) */ #define GPREG_USBPAD_REG_USBPHY_FORCE_SW1_OFF_Pos (1UL) /*!< USBPHY_FORCE_SW1_OFF (Bit 1) */ #define GPREG_USBPAD_REG_USBPHY_FORCE_SW1_OFF_Msk (0x2UL) /*!< USBPHY_FORCE_SW1_OFF (Bitfield-Mask: 0x01) */ #define GPREG_USBPAD_REG_USBPAD_EN_Pos (0UL) /*!< USBPAD_EN (Bit 0) */ #define GPREG_USBPAD_REG_USBPAD_EN_Msk (0x1UL) /*!< USBPAD_EN (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ I2C ================ */ /* =========================================================================================================================== */ /* =============================================== I2C_ACK_GENERAL_CALL_REG ================================================ */ #define I2C_I2C_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Pos (0UL) /*!< ACK_GEN_CALL (Bit 0) */ #define I2C_I2C_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Msk (0x1UL) /*!< ACK_GEN_CALL (Bitfield-Mask: 0x01) */ /* ================================================= I2C_CLR_ACTIVITY_REG ================================================== */ #define I2C_I2C_CLR_ACTIVITY_REG_CLR_ACTIVITY_Pos (0UL) /*!< CLR_ACTIVITY (Bit 0) */ #define I2C_I2C_CLR_ACTIVITY_REG_CLR_ACTIVITY_Msk (0x1UL) /*!< CLR_ACTIVITY (Bitfield-Mask: 0x01) */ /* ================================================= I2C_CLR_GEN_CALL_REG ================================================== */ #define I2C_I2C_CLR_GEN_CALL_REG_CLR_GEN_CALL_Pos (0UL) /*!< CLR_GEN_CALL (Bit 0) */ #define I2C_I2C_CLR_GEN_CALL_REG_CLR_GEN_CALL_Msk (0x1UL) /*!< CLR_GEN_CALL (Bitfield-Mask: 0x01) */ /* =================================================== I2C_CLR_INTR_REG ==================================================== */ #define I2C_I2C_CLR_INTR_REG_CLR_INTR_Pos (0UL) /*!< CLR_INTR (Bit 0) */ #define I2C_I2C_CLR_INTR_REG_CLR_INTR_Msk (0x1UL) /*!< CLR_INTR (Bitfield-Mask: 0x01) */ /* ================================================== I2C_CLR_RD_REQ_REG =================================================== */ #define I2C_I2C_CLR_RD_REQ_REG_CLR_RD_REQ_Pos (0UL) /*!< CLR_RD_REQ (Bit 0) */ #define I2C_I2C_CLR_RD_REQ_REG_CLR_RD_REQ_Msk (0x1UL) /*!< CLR_RD_REQ (Bitfield-Mask: 0x01) */ /* ================================================== I2C_CLR_RX_DONE_REG ================================================== */ #define I2C_I2C_CLR_RX_DONE_REG_CLR_RX_DONE_Pos (0UL) /*!< CLR_RX_DONE (Bit 0) */ #define I2C_I2C_CLR_RX_DONE_REG_CLR_RX_DONE_Msk (0x1UL) /*!< CLR_RX_DONE (Bitfield-Mask: 0x01) */ /* ================================================== I2C_CLR_RX_OVER_REG ================================================== */ #define I2C_I2C_CLR_RX_OVER_REG_CLR_RX_OVER_Pos (0UL) /*!< CLR_RX_OVER (Bit 0) */ #define I2C_I2C_CLR_RX_OVER_REG_CLR_RX_OVER_Msk (0x1UL) /*!< CLR_RX_OVER (Bitfield-Mask: 0x01) */ /* ================================================= I2C_CLR_RX_UNDER_REG ================================================== */ #define I2C_I2C_CLR_RX_UNDER_REG_CLR_RX_UNDER_Pos (0UL) /*!< CLR_RX_UNDER (Bit 0) */ #define I2C_I2C_CLR_RX_UNDER_REG_CLR_RX_UNDER_Msk (0x1UL) /*!< CLR_RX_UNDER (Bitfield-Mask: 0x01) */ /* ================================================= I2C_CLR_START_DET_REG ================================================= */ #define I2C_I2C_CLR_START_DET_REG_CLR_START_DET_Pos (0UL) /*!< CLR_START_DET (Bit 0) */ #define I2C_I2C_CLR_START_DET_REG_CLR_START_DET_Msk (0x1UL) /*!< CLR_START_DET (Bitfield-Mask: 0x01) */ /* ================================================= I2C_CLR_STOP_DET_REG ================================================== */ #define I2C_I2C_CLR_STOP_DET_REG_CLR_STOP_DET_Pos (0UL) /*!< CLR_STOP_DET (Bit 0) */ #define I2C_I2C_CLR_STOP_DET_REG_CLR_STOP_DET_Msk (0x1UL) /*!< CLR_STOP_DET (Bitfield-Mask: 0x01) */ /* ================================================== I2C_CLR_TX_ABRT_REG ================================================== */ #define I2C_I2C_CLR_TX_ABRT_REG_CLR_TX_ABRT_Pos (0UL) /*!< CLR_TX_ABRT (Bit 0) */ #define I2C_I2C_CLR_TX_ABRT_REG_CLR_TX_ABRT_Msk (0x1UL) /*!< CLR_TX_ABRT (Bitfield-Mask: 0x01) */ /* ================================================== I2C_CLR_TX_OVER_REG ================================================== */ #define I2C_I2C_CLR_TX_OVER_REG_CLR_TX_OVER_Pos (0UL) /*!< CLR_TX_OVER (Bit 0) */ #define I2C_I2C_CLR_TX_OVER_REG_CLR_TX_OVER_Msk (0x1UL) /*!< CLR_TX_OVER (Bitfield-Mask: 0x01) */ /* ====================================================== I2C_CON_REG ====================================================== */ #define I2C_I2C_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Pos (10UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bit 10) */ #define I2C_I2C_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Msk (0x400UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Pos (9UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bit 9) */ #define I2C_I2C_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Msk (0x200UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_TX_EMPTY_CTRL_Pos (8UL) /*!< I2C_TX_EMPTY_CTRL (Bit 8) */ #define I2C_I2C_CON_REG_I2C_TX_EMPTY_CTRL_Msk (0x100UL) /*!< I2C_TX_EMPTY_CTRL (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_STOP_DET_IFADDRESSED_Pos (7UL) /*!< I2C_STOP_DET_IFADDRESSED (Bit 7) */ #define I2C_I2C_CON_REG_I2C_STOP_DET_IFADDRESSED_Msk (0x80UL) /*!< I2C_STOP_DET_IFADDRESSED (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_SLAVE_DISABLE_Pos (6UL) /*!< I2C_SLAVE_DISABLE (Bit 6) */ #define I2C_I2C_CON_REG_I2C_SLAVE_DISABLE_Msk (0x40UL) /*!< I2C_SLAVE_DISABLE (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_RESTART_EN_Pos (5UL) /*!< I2C_RESTART_EN (Bit 5) */ #define I2C_I2C_CON_REG_I2C_RESTART_EN_Msk (0x20UL) /*!< I2C_RESTART_EN (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_10BITADDR_MASTER_Pos (4UL) /*!< I2C_10BITADDR_MASTER (Bit 4) */ #define I2C_I2C_CON_REG_I2C_10BITADDR_MASTER_Msk (0x10UL) /*!< I2C_10BITADDR_MASTER (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_10BITADDR_SLAVE_Pos (3UL) /*!< I2C_10BITADDR_SLAVE (Bit 3) */ #define I2C_I2C_CON_REG_I2C_10BITADDR_SLAVE_Msk (0x8UL) /*!< I2C_10BITADDR_SLAVE (Bitfield-Mask: 0x01) */ #define I2C_I2C_CON_REG_I2C_SPEED_Pos (1UL) /*!< I2C_SPEED (Bit 1) */ #define I2C_I2C_CON_REG_I2C_SPEED_Msk (0x6UL) /*!< I2C_SPEED (Bitfield-Mask: 0x03) */ #define I2C_I2C_CON_REG_I2C_MASTER_MODE_Pos (0UL) /*!< I2C_MASTER_MODE (Bit 0) */ #define I2C_I2C_CON_REG_I2C_MASTER_MODE_Msk (0x1UL) /*!< I2C_MASTER_MODE (Bitfield-Mask: 0x01) */ /* =================================================== I2C_DATA_CMD_REG ==================================================== */ #define I2C_I2C_DATA_CMD_REG_I2C_RESTART_Pos (10UL) /*!< I2C_RESTART (Bit 10) */ #define I2C_I2C_DATA_CMD_REG_I2C_RESTART_Msk (0x400UL) /*!< I2C_RESTART (Bitfield-Mask: 0x01) */ #define I2C_I2C_DATA_CMD_REG_I2C_STOP_Pos (9UL) /*!< I2C_STOP (Bit 9) */ #define I2C_I2C_DATA_CMD_REG_I2C_STOP_Msk (0x200UL) /*!< I2C_STOP (Bitfield-Mask: 0x01) */ #define I2C_I2C_DATA_CMD_REG_I2C_CMD_Pos (8UL) /*!< I2C_CMD (Bit 8) */ #define I2C_I2C_DATA_CMD_REG_I2C_CMD_Msk (0x100UL) /*!< I2C_CMD (Bitfield-Mask: 0x01) */ #define I2C_I2C_DATA_CMD_REG_I2C_DAT_Pos (0UL) /*!< I2C_DAT (Bit 0) */ #define I2C_I2C_DATA_CMD_REG_I2C_DAT_Msk (0xffUL) /*!< I2C_DAT (Bitfield-Mask: 0xff) */ /* ==================================================== I2C_DMA_CR_REG ===================================================== */ #define I2C_I2C_DMA_CR_REG_TDMAE_Pos (1UL) /*!< TDMAE (Bit 1) */ #define I2C_I2C_DMA_CR_REG_TDMAE_Msk (0x2UL) /*!< TDMAE (Bitfield-Mask: 0x01) */ #define I2C_I2C_DMA_CR_REG_RDMAE_Pos (0UL) /*!< RDMAE (Bit 0) */ #define I2C_I2C_DMA_CR_REG_RDMAE_Msk (0x1UL) /*!< RDMAE (Bitfield-Mask: 0x01) */ /* =================================================== I2C_DMA_RDLR_REG ==================================================== */ #define I2C_I2C_DMA_RDLR_REG_DMARDL_Pos (0UL) /*!< DMARDL (Bit 0) */ #define I2C_I2C_DMA_RDLR_REG_DMARDL_Msk (0x1fUL) /*!< DMARDL (Bitfield-Mask: 0x1f) */ /* =================================================== I2C_DMA_TDLR_REG ==================================================== */ #define I2C_I2C_DMA_TDLR_REG_DMATDL_Pos (0UL) /*!< DMATDL (Bit 0) */ #define I2C_I2C_DMA_TDLR_REG_DMATDL_Msk (0x1fUL) /*!< DMATDL (Bitfield-Mask: 0x1f) */ /* ==================================================== I2C_ENABLE_REG ===================================================== */ #define I2C_I2C_ENABLE_REG_I2C_TX_CMD_BLOCK_Pos (2UL) /*!< I2C_TX_CMD_BLOCK (Bit 2) */ #define I2C_I2C_ENABLE_REG_I2C_TX_CMD_BLOCK_Msk (0x4UL) /*!< I2C_TX_CMD_BLOCK (Bitfield-Mask: 0x01) */ #define I2C_I2C_ENABLE_REG_I2C_ABORT_Pos (1UL) /*!< I2C_ABORT (Bit 1) */ #define I2C_I2C_ENABLE_REG_I2C_ABORT_Msk (0x2UL) /*!< I2C_ABORT (Bitfield-Mask: 0x01) */ #define I2C_I2C_ENABLE_REG_I2C_EN_Pos (0UL) /*!< I2C_EN (Bit 0) */ #define I2C_I2C_ENABLE_REG_I2C_EN_Msk (0x1UL) /*!< I2C_EN (Bitfield-Mask: 0x01) */ /* ================================================= I2C_ENABLE_STATUS_REG ================================================= */ #define I2C_I2C_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Pos (2UL) /*!< SLV_RX_DATA_LOST (Bit 2) */ #define I2C_I2C_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Msk (0x4UL) /*!< SLV_RX_DATA_LOST (Bitfield-Mask: 0x01) */ #define I2C_I2C_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Pos (1UL) /*!< SLV_DISABLED_WHILE_BUSY (Bit 1) */ #define I2C_I2C_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Msk (0x2UL) /*!< SLV_DISABLED_WHILE_BUSY (Bitfield-Mask: 0x01) */ #define I2C_I2C_ENABLE_STATUS_REG_IC_EN_Pos (0UL) /*!< IC_EN (Bit 0) */ #define I2C_I2C_ENABLE_STATUS_REG_IC_EN_Msk (0x1UL) /*!< IC_EN (Bitfield-Mask: 0x01) */ /* ================================================== I2C_FS_SCL_HCNT_REG ================================================== */ #define I2C_I2C_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Pos (0UL) /*!< IC_FS_SCL_HCNT (Bit 0) */ #define I2C_I2C_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Msk (0xffffUL) /*!< IC_FS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================== I2C_FS_SCL_LCNT_REG ================================================== */ #define I2C_I2C_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Pos (0UL) /*!< IC_FS_SCL_LCNT (Bit 0) */ #define I2C_I2C_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Msk (0xffffUL) /*!< IC_FS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* =================================================== I2C_HS_MADDR_REG ==================================================== */ #define I2C_I2C_HS_MADDR_REG_I2C_IC_HS_MAR_Pos (0UL) /*!< I2C_IC_HS_MAR (Bit 0) */ #define I2C_I2C_HS_MADDR_REG_I2C_IC_HS_MAR_Msk (0x7UL) /*!< I2C_IC_HS_MAR (Bitfield-Mask: 0x07) */ /* ================================================== I2C_HS_SCL_HCNT_REG ================================================== */ #define I2C_I2C_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Pos (0UL) /*!< IC_HS_SCL_HCNT (Bit 0) */ #define I2C_I2C_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Msk (0xffffUL) /*!< IC_HS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================== I2C_HS_SCL_LCNT_REG ================================================== */ #define I2C_I2C_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Pos (0UL) /*!< IC_HS_SCL_LCNT (Bit 0) */ #define I2C_I2C_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Msk (0xffffUL) /*!< IC_HS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* ================================================= I2C_IC_FS_SPKLEN_REG ================================================== */ #define I2C_I2C_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Pos (0UL) /*!< I2C_FS_SPKLEN (Bit 0) */ #define I2C_I2C_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Msk (0xffUL) /*!< I2C_FS_SPKLEN (Bitfield-Mask: 0xff) */ /* ================================================= I2C_IC_HS_SPKLEN_REG ================================================== */ #define I2C_I2C_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Pos (0UL) /*!< I2C_HS_SPKLEN (Bit 0) */ #define I2C_I2C_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Msk (0xffUL) /*!< I2C_HS_SPKLEN (Bitfield-Mask: 0xff) */ /* =================================================== I2C_INTR_MASK_REG =================================================== */ #define I2C_I2C_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Pos (14UL) /*!< M_SCL_STUCK_AT_LOW (Bit 14) */ #define I2C_I2C_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< M_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_MASTER_ON_HOLD_Pos (13UL) /*!< M_MASTER_ON_HOLD (Bit 13) */ #define I2C_I2C_INTR_MASK_REG_M_MASTER_ON_HOLD_Msk (0x2000UL) /*!< M_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RESTART_DET_Pos (12UL) /*!< M_RESTART_DET (Bit 12) */ #define I2C_I2C_INTR_MASK_REG_M_RESTART_DET_Msk (0x1000UL) /*!< M_RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_GEN_CALL_Pos (11UL) /*!< M_GEN_CALL (Bit 11) */ #define I2C_I2C_INTR_MASK_REG_M_GEN_CALL_Msk (0x800UL) /*!< M_GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_START_DET_Pos (10UL) /*!< M_START_DET (Bit 10) */ #define I2C_I2C_INTR_MASK_REG_M_START_DET_Msk (0x400UL) /*!< M_START_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_STOP_DET_Pos (9UL) /*!< M_STOP_DET (Bit 9) */ #define I2C_I2C_INTR_MASK_REG_M_STOP_DET_Msk (0x200UL) /*!< M_STOP_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_ACTIVITY_Pos (8UL) /*!< M_ACTIVITY (Bit 8) */ #define I2C_I2C_INTR_MASK_REG_M_ACTIVITY_Msk (0x100UL) /*!< M_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RX_DONE_Pos (7UL) /*!< M_RX_DONE (Bit 7) */ #define I2C_I2C_INTR_MASK_REG_M_RX_DONE_Msk (0x80UL) /*!< M_RX_DONE (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_TX_ABRT_Pos (6UL) /*!< M_TX_ABRT (Bit 6) */ #define I2C_I2C_INTR_MASK_REG_M_TX_ABRT_Msk (0x40UL) /*!< M_TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RD_REQ_Pos (5UL) /*!< M_RD_REQ (Bit 5) */ #define I2C_I2C_INTR_MASK_REG_M_RD_REQ_Msk (0x20UL) /*!< M_RD_REQ (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Pos (4UL) /*!< M_TX_EMPTY (Bit 4) */ #define I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Msk (0x10UL) /*!< M_TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_TX_OVER_Pos (3UL) /*!< M_TX_OVER (Bit 3) */ #define I2C_I2C_INTR_MASK_REG_M_TX_OVER_Msk (0x8UL) /*!< M_TX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RX_FULL_Pos (2UL) /*!< M_RX_FULL (Bit 2) */ #define I2C_I2C_INTR_MASK_REG_M_RX_FULL_Msk (0x4UL) /*!< M_RX_FULL (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RX_OVER_Pos (1UL) /*!< M_RX_OVER (Bit 1) */ #define I2C_I2C_INTR_MASK_REG_M_RX_OVER_Msk (0x2UL) /*!< M_RX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_MASK_REG_M_RX_UNDER_Pos (0UL) /*!< M_RX_UNDER (Bit 0) */ #define I2C_I2C_INTR_MASK_REG_M_RX_UNDER_Msk (0x1UL) /*!< M_RX_UNDER (Bitfield-Mask: 0x01) */ /* =================================================== I2C_INTR_STAT_REG =================================================== */ #define I2C_I2C_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Pos (14UL) /*!< R_SCL_STUCK_AT_LOW (Bit 14) */ #define I2C_I2C_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< R_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_MASTER_ON_HOLD_Pos (13UL) /*!< R_MASTER_ON_HOLD (Bit 13) */ #define I2C_I2C_INTR_STAT_REG_R_MASTER_ON_HOLD_Msk (0x2000UL) /*!< R_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RESTART_DET_Pos (12UL) /*!< R_RESTART_DET (Bit 12) */ #define I2C_I2C_INTR_STAT_REG_R_RESTART_DET_Msk (0x1000UL) /*!< R_RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_GEN_CALL_Pos (11UL) /*!< R_GEN_CALL (Bit 11) */ #define I2C_I2C_INTR_STAT_REG_R_GEN_CALL_Msk (0x800UL) /*!< R_GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_START_DET_Pos (10UL) /*!< R_START_DET (Bit 10) */ #define I2C_I2C_INTR_STAT_REG_R_START_DET_Msk (0x400UL) /*!< R_START_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_STOP_DET_Pos (9UL) /*!< R_STOP_DET (Bit 9) */ #define I2C_I2C_INTR_STAT_REG_R_STOP_DET_Msk (0x200UL) /*!< R_STOP_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_ACTIVITY_Pos (8UL) /*!< R_ACTIVITY (Bit 8) */ #define I2C_I2C_INTR_STAT_REG_R_ACTIVITY_Msk (0x100UL) /*!< R_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RX_DONE_Pos (7UL) /*!< R_RX_DONE (Bit 7) */ #define I2C_I2C_INTR_STAT_REG_R_RX_DONE_Msk (0x80UL) /*!< R_RX_DONE (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_TX_ABRT_Pos (6UL) /*!< R_TX_ABRT (Bit 6) */ #define I2C_I2C_INTR_STAT_REG_R_TX_ABRT_Msk (0x40UL) /*!< R_TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RD_REQ_Pos (5UL) /*!< R_RD_REQ (Bit 5) */ #define I2C_I2C_INTR_STAT_REG_R_RD_REQ_Msk (0x20UL) /*!< R_RD_REQ (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_TX_EMPTY_Pos (4UL) /*!< R_TX_EMPTY (Bit 4) */ #define I2C_I2C_INTR_STAT_REG_R_TX_EMPTY_Msk (0x10UL) /*!< R_TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_TX_OVER_Pos (3UL) /*!< R_TX_OVER (Bit 3) */ #define I2C_I2C_INTR_STAT_REG_R_TX_OVER_Msk (0x8UL) /*!< R_TX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RX_FULL_Pos (2UL) /*!< R_RX_FULL (Bit 2) */ #define I2C_I2C_INTR_STAT_REG_R_RX_FULL_Msk (0x4UL) /*!< R_RX_FULL (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RX_OVER_Pos (1UL) /*!< R_RX_OVER (Bit 1) */ #define I2C_I2C_INTR_STAT_REG_R_RX_OVER_Msk (0x2UL) /*!< R_RX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_INTR_STAT_REG_R_RX_UNDER_Pos (0UL) /*!< R_RX_UNDER (Bit 0) */ #define I2C_I2C_INTR_STAT_REG_R_RX_UNDER_Msk (0x1UL) /*!< R_RX_UNDER (Bitfield-Mask: 0x01) */ /* ================================================= I2C_RAW_INTR_STAT_REG ================================================= */ #define I2C_I2C_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Pos (14UL) /*!< SCL_STUCK_AT_LOW (Bit 14) */ #define I2C_I2C_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Pos (13UL) /*!< MASTER_ON_HOLD (Bit 13) */ #define I2C_I2C_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Msk (0x2000UL) /*!< MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RESTART_DET_Pos (12UL) /*!< RESTART_DET (Bit 12) */ #define I2C_I2C_RAW_INTR_STAT_REG_RESTART_DET_Msk (0x1000UL) /*!< RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_GEN_CALL_Pos (11UL) /*!< GEN_CALL (Bit 11) */ #define I2C_I2C_RAW_INTR_STAT_REG_GEN_CALL_Msk (0x800UL) /*!< GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_START_DET_Pos (10UL) /*!< START_DET (Bit 10) */ #define I2C_I2C_RAW_INTR_STAT_REG_START_DET_Msk (0x400UL) /*!< START_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_STOP_DET_Pos (9UL) /*!< STOP_DET (Bit 9) */ #define I2C_I2C_RAW_INTR_STAT_REG_STOP_DET_Msk (0x200UL) /*!< STOP_DET (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_ACTIVITY_Pos (8UL) /*!< ACTIVITY (Bit 8) */ #define I2C_I2C_RAW_INTR_STAT_REG_ACTIVITY_Msk (0x100UL) /*!< ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_DONE_Pos (7UL) /*!< RX_DONE (Bit 7) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_DONE_Msk (0x80UL) /*!< RX_DONE (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_ABRT_Pos (6UL) /*!< TX_ABRT (Bit 6) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_ABRT_Msk (0x40UL) /*!< TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RD_REQ_Pos (5UL) /*!< RD_REQ (Bit 5) */ #define I2C_I2C_RAW_INTR_STAT_REG_RD_REQ_Msk (0x20UL) /*!< RD_REQ (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_EMPTY_Pos (4UL) /*!< TX_EMPTY (Bit 4) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_EMPTY_Msk (0x10UL) /*!< TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_OVER_Pos (3UL) /*!< TX_OVER (Bit 3) */ #define I2C_I2C_RAW_INTR_STAT_REG_TX_OVER_Msk (0x8UL) /*!< TX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_FULL_Pos (2UL) /*!< RX_FULL (Bit 2) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_FULL_Msk (0x4UL) /*!< RX_FULL (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_OVER_Pos (1UL) /*!< RX_OVER (Bit 1) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_OVER_Msk (0x2UL) /*!< RX_OVER (Bitfield-Mask: 0x01) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_UNDER_Pos (0UL) /*!< RX_UNDER (Bit 0) */ #define I2C_I2C_RAW_INTR_STAT_REG_RX_UNDER_Msk (0x1UL) /*!< RX_UNDER (Bitfield-Mask: 0x01) */ /* ===================================================== I2C_RXFLR_REG ===================================================== */ #define I2C_I2C_RXFLR_REG_RXFLR_Pos (0UL) /*!< RXFLR (Bit 0) */ #define I2C_I2C_RXFLR_REG_RXFLR_Msk (0x3fUL) /*!< RXFLR (Bitfield-Mask: 0x3f) */ /* ===================================================== I2C_RX_TL_REG ===================================================== */ #define I2C_I2C_RX_TL_REG_RX_TL_Pos (0UL) /*!< RX_TL (Bit 0) */ #define I2C_I2C_RX_TL_REG_RX_TL_Msk (0x1fUL) /*!< RX_TL (Bitfield-Mask: 0x1f) */ /* ====================================================== I2C_SAR_REG ====================================================== */ #define I2C_I2C_SAR_REG_IC_SAR_Pos (0UL) /*!< IC_SAR (Bit 0) */ #define I2C_I2C_SAR_REG_IC_SAR_Msk (0x3ffUL) /*!< IC_SAR (Bitfield-Mask: 0x3ff) */ /* =================================================== I2C_SDA_HOLD_REG ==================================================== */ #define I2C_I2C_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Pos (16UL) /*!< I2C_SDA_RX_HOLD (Bit 16) */ #define I2C_I2C_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Msk (0xff0000UL) /*!< I2C_SDA_RX_HOLD (Bitfield-Mask: 0xff) */ #define I2C_I2C_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Pos (0UL) /*!< I2C_SDA_TX_HOLD (Bit 0) */ #define I2C_I2C_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Msk (0xffffUL) /*!< I2C_SDA_TX_HOLD (Bitfield-Mask: 0xffff) */ /* =================================================== I2C_SDA_SETUP_REG =================================================== */ #define I2C_I2C_SDA_SETUP_REG_SDA_SETUP_Pos (0UL) /*!< SDA_SETUP (Bit 0) */ #define I2C_I2C_SDA_SETUP_REG_SDA_SETUP_Msk (0xffUL) /*!< SDA_SETUP (Bitfield-Mask: 0xff) */ /* ================================================== I2C_SS_SCL_HCNT_REG ================================================== */ #define I2C_I2C_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Pos (0UL) /*!< IC_SS_SCL_HCNT (Bit 0) */ #define I2C_I2C_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Msk (0xffffUL) /*!< IC_SS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================== I2C_SS_SCL_LCNT_REG ================================================== */ #define I2C_I2C_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Pos (0UL) /*!< IC_SS_SCL_LCNT (Bit 0) */ #define I2C_I2C_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Msk (0xffffUL) /*!< IC_SS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* ==================================================== I2C_STATUS_REG ===================================================== */ #define I2C_I2C_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Pos (10UL) /*!< LV_HOLD_RX_FIFO_FULL (Bit 10) */ #define I2C_I2C_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Msk (0x400UL) /*!< LV_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Pos (9UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bit 9) */ #define I2C_I2C_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Msk (0x200UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Pos (8UL) /*!< MST_HOLD_RX_FIFO_FULL (Bit 8) */ #define I2C_I2C_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Msk (0x100UL) /*!< MST_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Pos (7UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bit 7) */ #define I2C_I2C_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Msk (0x80UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_SLV_ACTIVITY_Pos (6UL) /*!< SLV_ACTIVITY (Bit 6) */ #define I2C_I2C_STATUS_REG_SLV_ACTIVITY_Msk (0x40UL) /*!< SLV_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_MST_ACTIVITY_Pos (5UL) /*!< MST_ACTIVITY (Bit 5) */ #define I2C_I2C_STATUS_REG_MST_ACTIVITY_Msk (0x20UL) /*!< MST_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_RFF_Pos (4UL) /*!< RFF (Bit 4) */ #define I2C_I2C_STATUS_REG_RFF_Msk (0x10UL) /*!< RFF (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_RFNE_Pos (3UL) /*!< RFNE (Bit 3) */ #define I2C_I2C_STATUS_REG_RFNE_Msk (0x8UL) /*!< RFNE (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_TFE_Pos (2UL) /*!< TFE (Bit 2) */ #define I2C_I2C_STATUS_REG_TFE_Msk (0x4UL) /*!< TFE (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_TFNF_Pos (1UL) /*!< TFNF (Bit 1) */ #define I2C_I2C_STATUS_REG_TFNF_Msk (0x2UL) /*!< TFNF (Bitfield-Mask: 0x01) */ #define I2C_I2C_STATUS_REG_I2C_ACTIVITY_Pos (0UL) /*!< I2C_ACTIVITY (Bit 0) */ #define I2C_I2C_STATUS_REG_I2C_ACTIVITY_Msk (0x1UL) /*!< I2C_ACTIVITY (Bitfield-Mask: 0x01) */ /* ====================================================== I2C_TAR_REG ====================================================== */ #define I2C_I2C_TAR_REG_SPECIAL_Pos (11UL) /*!< SPECIAL (Bit 11) */ #define I2C_I2C_TAR_REG_SPECIAL_Msk (0x800UL) /*!< SPECIAL (Bitfield-Mask: 0x01) */ #define I2C_I2C_TAR_REG_GC_OR_START_Pos (10UL) /*!< GC_OR_START (Bit 10) */ #define I2C_I2C_TAR_REG_GC_OR_START_Msk (0x400UL) /*!< GC_OR_START (Bitfield-Mask: 0x01) */ #define I2C_I2C_TAR_REG_IC_TAR_Pos (0UL) /*!< IC_TAR (Bit 0) */ #define I2C_I2C_TAR_REG_IC_TAR_Msk (0x3ffUL) /*!< IC_TAR (Bitfield-Mask: 0x3ff) */ /* ===================================================== I2C_TXFLR_REG ===================================================== */ #define I2C_I2C_TXFLR_REG_TXFLR_Pos (0UL) /*!< TXFLR (Bit 0) */ #define I2C_I2C_TXFLR_REG_TXFLR_Msk (0x3fUL) /*!< TXFLR (Bitfield-Mask: 0x3f) */ /* ================================================ I2C_TX_ABRT_SOURCE_REG ================================================= */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Pos (16UL) /*!< ABRT_USER_ABRT (Bit 16) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk (0x10000UL) /*!< ABRT_USER_ABRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Pos (15UL) /*!< ABRT_SLVRD_INTX (Bit 15) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Msk (0x8000UL) /*!< ABRT_SLVRD_INTX (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Pos (14UL) /*!< ABRT_SLV_ARBLOST (Bit 14) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Msk (0x4000UL) /*!< ABRT_SLV_ARBLOST (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Pos (13UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bit 13) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Msk (0x2000UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ARB_LOST_Pos (12UL) /*!< ARB_LOST (Bit 12) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ARB_LOST_Msk (0x1000UL) /*!< ARB_LOST (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Pos (11UL) /*!< ABRT_MASTER_DIS (Bit 11) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Msk (0x800UL) /*!< ABRT_MASTER_DIS (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Pos (10UL) /*!< ABRT_10B_RD_NORSTRT (Bit 10) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Msk (0x400UL) /*!< ABRT_10B_RD_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Pos (9UL) /*!< ABRT_SBYTE_NORSTRT (Bit 9) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Msk (0x200UL) /*!< ABRT_SBYTE_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Pos (8UL) /*!< ABRT_HS_NORSTRT (Bit 8) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Msk (0x100UL) /*!< ABRT_HS_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Pos (7UL) /*!< ABRT_SBYTE_ACKDET (Bit 7) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Msk (0x80UL) /*!< ABRT_SBYTE_ACKDET (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Pos (6UL) /*!< ABRT_HS_ACKDET (Bit 6) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Msk (0x40UL) /*!< ABRT_HS_ACKDET (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Pos (5UL) /*!< ABRT_GCALL_READ (Bit 5) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Msk (0x20UL) /*!< ABRT_GCALL_READ (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Pos (4UL) /*!< ABRT_GCALL_NOACK (Bit 4) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Msk (0x10UL) /*!< ABRT_GCALL_NOACK (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Pos (3UL) /*!< ABRT_TXDATA_NOACK (Bit 3) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Msk (0x8UL) /*!< ABRT_TXDATA_NOACK (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Pos (2UL) /*!< ABRT_10ADDR2_NOACK (Bit 2) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Msk (0x4UL) /*!< ABRT_10ADDR2_NOACK (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Pos (1UL) /*!< ABRT_10ADDR1_NOACK (Bit 1) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Msk (0x2UL) /*!< ABRT_10ADDR1_NOACK (Bitfield-Mask: 0x01) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Pos (0UL) /*!< ABRT_7B_ADDR_NOACK (Bit 0) */ #define I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Msk (0x1UL) /*!< ABRT_7B_ADDR_NOACK (Bitfield-Mask: 0x01) */ /* ===================================================== I2C_TX_TL_REG ===================================================== */ #define I2C_I2C_TX_TL_REG_TX_TL_Pos (0UL) /*!< TX_TL (Bit 0) */ #define I2C_I2C_TX_TL_REG_TX_TL_Msk (0x1fUL) /*!< TX_TL (Bitfield-Mask: 0x1f) */ /* =========================================================================================================================== */ /* ================ I2C2 ================ */ /* =========================================================================================================================== */ /* =============================================== I2C2_ACK_GENERAL_CALL_REG =============================================== */ #define I2C2_I2C2_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Pos (0UL) /*!< ACK_GEN_CALL (Bit 0) */ #define I2C2_I2C2_ACK_GENERAL_CALL_REG_ACK_GEN_CALL_Msk (0x1UL) /*!< ACK_GEN_CALL (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_ACTIVITY_REG ================================================= */ #define I2C2_I2C2_CLR_ACTIVITY_REG_CLR_ACTIVITY_Pos (0UL) /*!< CLR_ACTIVITY (Bit 0) */ #define I2C2_I2C2_CLR_ACTIVITY_REG_CLR_ACTIVITY_Msk (0x1UL) /*!< CLR_ACTIVITY (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_GEN_CALL_REG ================================================= */ #define I2C2_I2C2_CLR_GEN_CALL_REG_CLR_GEN_CALL_Pos (0UL) /*!< CLR_GEN_CALL (Bit 0) */ #define I2C2_I2C2_CLR_GEN_CALL_REG_CLR_GEN_CALL_Msk (0x1UL) /*!< CLR_GEN_CALL (Bitfield-Mask: 0x01) */ /* =================================================== I2C2_CLR_INTR_REG =================================================== */ #define I2C2_I2C2_CLR_INTR_REG_CLR_INTR_Pos (0UL) /*!< CLR_INTR (Bit 0) */ #define I2C2_I2C2_CLR_INTR_REG_CLR_INTR_Msk (0x1UL) /*!< CLR_INTR (Bitfield-Mask: 0x01) */ /* ================================================== I2C2_CLR_RD_REQ_REG ================================================== */ #define I2C2_I2C2_CLR_RD_REQ_REG_CLR_RD_REQ_Pos (0UL) /*!< CLR_RD_REQ (Bit 0) */ #define I2C2_I2C2_CLR_RD_REQ_REG_CLR_RD_REQ_Msk (0x1UL) /*!< CLR_RD_REQ (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_RX_DONE_REG ================================================== */ #define I2C2_I2C2_CLR_RX_DONE_REG_CLR_RX_DONE_Pos (0UL) /*!< CLR_RX_DONE (Bit 0) */ #define I2C2_I2C2_CLR_RX_DONE_REG_CLR_RX_DONE_Msk (0x1UL) /*!< CLR_RX_DONE (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_RX_OVER_REG ================================================== */ #define I2C2_I2C2_CLR_RX_OVER_REG_CLR_RX_OVER_Pos (0UL) /*!< CLR_RX_OVER (Bit 0) */ #define I2C2_I2C2_CLR_RX_OVER_REG_CLR_RX_OVER_Msk (0x1UL) /*!< CLR_RX_OVER (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_RX_UNDER_REG ================================================= */ #define I2C2_I2C2_CLR_RX_UNDER_REG_CLR_RX_UNDER_Pos (0UL) /*!< CLR_RX_UNDER (Bit 0) */ #define I2C2_I2C2_CLR_RX_UNDER_REG_CLR_RX_UNDER_Msk (0x1UL) /*!< CLR_RX_UNDER (Bitfield-Mask: 0x01) */ /* ================================================ I2C2_CLR_START_DET_REG ================================================= */ #define I2C2_I2C2_CLR_START_DET_REG_CLR_START_DET_Pos (0UL) /*!< CLR_START_DET (Bit 0) */ #define I2C2_I2C2_CLR_START_DET_REG_CLR_START_DET_Msk (0x1UL) /*!< CLR_START_DET (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_STOP_DET_REG ================================================= */ #define I2C2_I2C2_CLR_STOP_DET_REG_CLR_STOP_DET_Pos (0UL) /*!< CLR_STOP_DET (Bit 0) */ #define I2C2_I2C2_CLR_STOP_DET_REG_CLR_STOP_DET_Msk (0x1UL) /*!< CLR_STOP_DET (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_TX_ABRT_REG ================================================== */ #define I2C2_I2C2_CLR_TX_ABRT_REG_CLR_TX_ABRT_Pos (0UL) /*!< CLR_TX_ABRT (Bit 0) */ #define I2C2_I2C2_CLR_TX_ABRT_REG_CLR_TX_ABRT_Msk (0x1UL) /*!< CLR_TX_ABRT (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_CLR_TX_OVER_REG ================================================== */ #define I2C2_I2C2_CLR_TX_OVER_REG_CLR_TX_OVER_Pos (0UL) /*!< CLR_TX_OVER (Bit 0) */ #define I2C2_I2C2_CLR_TX_OVER_REG_CLR_TX_OVER_Msk (0x1UL) /*!< CLR_TX_OVER (Bitfield-Mask: 0x01) */ /* ===================================================== I2C2_CON_REG ====================================================== */ #define I2C2_I2C2_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Pos (10UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bit 10) */ #define I2C2_I2C2_CON_REG_I2C_STOP_DET_IF_MASTER_ACTIVE_Msk (0x400UL) /*!< I2C_STOP_DET_IF_MASTER_ACTIVE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Pos (9UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bit 9) */ #define I2C2_I2C2_CON_REG_I2C_RX_FIFO_FULL_HLD_CTRL_Msk (0x200UL) /*!< I2C_RX_FIFO_FULL_HLD_CTRL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_TX_EMPTY_CTRL_Pos (8UL) /*!< I2C_TX_EMPTY_CTRL (Bit 8) */ #define I2C2_I2C2_CON_REG_I2C_TX_EMPTY_CTRL_Msk (0x100UL) /*!< I2C_TX_EMPTY_CTRL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_STOP_DET_IFADDRESSED_Pos (7UL) /*!< I2C_STOP_DET_IFADDRESSED (Bit 7) */ #define I2C2_I2C2_CON_REG_I2C_STOP_DET_IFADDRESSED_Msk (0x80UL) /*!< I2C_STOP_DET_IFADDRESSED (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_SLAVE_DISABLE_Pos (6UL) /*!< I2C_SLAVE_DISABLE (Bit 6) */ #define I2C2_I2C2_CON_REG_I2C_SLAVE_DISABLE_Msk (0x40UL) /*!< I2C_SLAVE_DISABLE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_RESTART_EN_Pos (5UL) /*!< I2C_RESTART_EN (Bit 5) */ #define I2C2_I2C2_CON_REG_I2C_RESTART_EN_Msk (0x20UL) /*!< I2C_RESTART_EN (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_10BITADDR_MASTER_Pos (4UL) /*!< I2C_10BITADDR_MASTER (Bit 4) */ #define I2C2_I2C2_CON_REG_I2C_10BITADDR_MASTER_Msk (0x10UL) /*!< I2C_10BITADDR_MASTER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_10BITADDR_SLAVE_Pos (3UL) /*!< I2C_10BITADDR_SLAVE (Bit 3) */ #define I2C2_I2C2_CON_REG_I2C_10BITADDR_SLAVE_Msk (0x8UL) /*!< I2C_10BITADDR_SLAVE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_CON_REG_I2C_SPEED_Pos (1UL) /*!< I2C_SPEED (Bit 1) */ #define I2C2_I2C2_CON_REG_I2C_SPEED_Msk (0x6UL) /*!< I2C_SPEED (Bitfield-Mask: 0x03) */ #define I2C2_I2C2_CON_REG_I2C_MASTER_MODE_Pos (0UL) /*!< I2C_MASTER_MODE (Bit 0) */ #define I2C2_I2C2_CON_REG_I2C_MASTER_MODE_Msk (0x1UL) /*!< I2C_MASTER_MODE (Bitfield-Mask: 0x01) */ /* =================================================== I2C2_DATA_CMD_REG =================================================== */ #define I2C2_I2C2_DATA_CMD_REG_I2C_RESTART_Pos (10UL) /*!< I2C_RESTART (Bit 10) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_RESTART_Msk (0x400UL) /*!< I2C_RESTART (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_STOP_Pos (9UL) /*!< I2C_STOP (Bit 9) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_STOP_Msk (0x200UL) /*!< I2C_STOP (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_CMD_Pos (8UL) /*!< I2C_CMD (Bit 8) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_CMD_Msk (0x100UL) /*!< I2C_CMD (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_DAT_Pos (0UL) /*!< I2C_DAT (Bit 0) */ #define I2C2_I2C2_DATA_CMD_REG_I2C_DAT_Msk (0xffUL) /*!< I2C_DAT (Bitfield-Mask: 0xff) */ /* ==================================================== I2C2_DMA_CR_REG ==================================================== */ #define I2C2_I2C2_DMA_CR_REG_TDMAE_Pos (1UL) /*!< TDMAE (Bit 1) */ #define I2C2_I2C2_DMA_CR_REG_TDMAE_Msk (0x2UL) /*!< TDMAE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_DMA_CR_REG_RDMAE_Pos (0UL) /*!< RDMAE (Bit 0) */ #define I2C2_I2C2_DMA_CR_REG_RDMAE_Msk (0x1UL) /*!< RDMAE (Bitfield-Mask: 0x01) */ /* =================================================== I2C2_DMA_RDLR_REG =================================================== */ #define I2C2_I2C2_DMA_RDLR_REG_DMARDL_Pos (0UL) /*!< DMARDL (Bit 0) */ #define I2C2_I2C2_DMA_RDLR_REG_DMARDL_Msk (0x1fUL) /*!< DMARDL (Bitfield-Mask: 0x1f) */ /* =================================================== I2C2_DMA_TDLR_REG =================================================== */ #define I2C2_I2C2_DMA_TDLR_REG_DMATDL_Pos (0UL) /*!< DMATDL (Bit 0) */ #define I2C2_I2C2_DMA_TDLR_REG_DMATDL_Msk (0x1fUL) /*!< DMATDL (Bitfield-Mask: 0x1f) */ /* ==================================================== I2C2_ENABLE_REG ==================================================== */ #define I2C2_I2C2_ENABLE_REG_I2C_TX_CMD_BLOCK_Pos (2UL) /*!< I2C_TX_CMD_BLOCK (Bit 2) */ #define I2C2_I2C2_ENABLE_REG_I2C_TX_CMD_BLOCK_Msk (0x4UL) /*!< I2C_TX_CMD_BLOCK (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_ENABLE_REG_I2C_ABORT_Pos (1UL) /*!< I2C_ABORT (Bit 1) */ #define I2C2_I2C2_ENABLE_REG_I2C_ABORT_Msk (0x2UL) /*!< I2C_ABORT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_ENABLE_REG_I2C_EN_Pos (0UL) /*!< I2C_EN (Bit 0) */ #define I2C2_I2C2_ENABLE_REG_I2C_EN_Msk (0x1UL) /*!< I2C_EN (Bitfield-Mask: 0x01) */ /* ================================================ I2C2_ENABLE_STATUS_REG ================================================= */ #define I2C2_I2C2_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Pos (2UL) /*!< SLV_RX_DATA_LOST (Bit 2) */ #define I2C2_I2C2_ENABLE_STATUS_REG_SLV_RX_DATA_LOST_Msk (0x4UL) /*!< SLV_RX_DATA_LOST (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Pos (1UL) /*!< SLV_DISABLED_WHILE_BUSY (Bit 1) */ #define I2C2_I2C2_ENABLE_STATUS_REG_SLV_DISABLED_WHILE_BUSY_Msk (0x2UL) /*!< SLV_DISABLED_WHILE_BUSY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_ENABLE_STATUS_REG_IC_EN_Pos (0UL) /*!< IC_EN (Bit 0) */ #define I2C2_I2C2_ENABLE_STATUS_REG_IC_EN_Msk (0x1UL) /*!< IC_EN (Bitfield-Mask: 0x01) */ /* ================================================= I2C2_FS_SCL_HCNT_REG ================================================== */ #define I2C2_I2C2_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Pos (0UL) /*!< IC_FS_SCL_HCNT (Bit 0) */ #define I2C2_I2C2_FS_SCL_HCNT_REG_IC_FS_SCL_HCNT_Msk (0xffffUL) /*!< IC_FS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================= I2C2_FS_SCL_LCNT_REG ================================================== */ #define I2C2_I2C2_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Pos (0UL) /*!< IC_FS_SCL_LCNT (Bit 0) */ #define I2C2_I2C2_FS_SCL_LCNT_REG_IC_FS_SCL_LCNT_Msk (0xffffUL) /*!< IC_FS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* =================================================== I2C2_HS_MADDR_REG =================================================== */ #define I2C2_I2C2_HS_MADDR_REG_I2C_IC_HS_MAR_Pos (0UL) /*!< I2C_IC_HS_MAR (Bit 0) */ #define I2C2_I2C2_HS_MADDR_REG_I2C_IC_HS_MAR_Msk (0x7UL) /*!< I2C_IC_HS_MAR (Bitfield-Mask: 0x07) */ /* ================================================= I2C2_HS_SCL_HCNT_REG ================================================== */ #define I2C2_I2C2_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Pos (0UL) /*!< IC_HS_SCL_HCNT (Bit 0) */ #define I2C2_I2C2_HS_SCL_HCNT_REG_IC_HS_SCL_HCNT_Msk (0xffffUL) /*!< IC_HS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================= I2C2_HS_SCL_LCNT_REG ================================================== */ #define I2C2_I2C2_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Pos (0UL) /*!< IC_HS_SCL_LCNT (Bit 0) */ #define I2C2_I2C2_HS_SCL_LCNT_REG_IC_HS_SCL_LCNT_Msk (0xffffUL) /*!< IC_HS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* ================================================= I2C2_IC_FS_SPKLEN_REG ================================================= */ #define I2C2_I2C2_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Pos (0UL) /*!< I2C_FS_SPKLEN (Bit 0) */ #define I2C2_I2C2_IC_FS_SPKLEN_REG_I2C_FS_SPKLEN_Msk (0xffUL) /*!< I2C_FS_SPKLEN (Bitfield-Mask: 0xff) */ /* ================================================= I2C2_IC_HS_SPKLEN_REG ================================================= */ #define I2C2_I2C2_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Pos (0UL) /*!< I2C_HS_SPKLEN (Bit 0) */ #define I2C2_I2C2_IC_HS_SPKLEN_REG_I2C_HS_SPKLEN_Msk (0xffUL) /*!< I2C_HS_SPKLEN (Bitfield-Mask: 0xff) */ /* ================================================== I2C2_INTR_MASK_REG =================================================== */ #define I2C2_I2C2_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Pos (14UL) /*!< M_SCL_STUCK_AT_LOW (Bit 14) */ #define I2C2_I2C2_INTR_MASK_REG_M_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< M_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_MASTER_ON_HOLD_Pos (13UL) /*!< M_MASTER_ON_HOLD (Bit 13) */ #define I2C2_I2C2_INTR_MASK_REG_M_MASTER_ON_HOLD_Msk (0x2000UL) /*!< M_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RESTART_DET_Pos (12UL) /*!< M_RESTART_DET (Bit 12) */ #define I2C2_I2C2_INTR_MASK_REG_M_RESTART_DET_Msk (0x1000UL) /*!< M_RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_GEN_CALL_Pos (11UL) /*!< M_GEN_CALL (Bit 11) */ #define I2C2_I2C2_INTR_MASK_REG_M_GEN_CALL_Msk (0x800UL) /*!< M_GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_START_DET_Pos (10UL) /*!< M_START_DET (Bit 10) */ #define I2C2_I2C2_INTR_MASK_REG_M_START_DET_Msk (0x400UL) /*!< M_START_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_STOP_DET_Pos (9UL) /*!< M_STOP_DET (Bit 9) */ #define I2C2_I2C2_INTR_MASK_REG_M_STOP_DET_Msk (0x200UL) /*!< M_STOP_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_ACTIVITY_Pos (8UL) /*!< M_ACTIVITY (Bit 8) */ #define I2C2_I2C2_INTR_MASK_REG_M_ACTIVITY_Msk (0x100UL) /*!< M_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_DONE_Pos (7UL) /*!< M_RX_DONE (Bit 7) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_DONE_Msk (0x80UL) /*!< M_RX_DONE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_ABRT_Pos (6UL) /*!< M_TX_ABRT (Bit 6) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_ABRT_Msk (0x40UL) /*!< M_TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RD_REQ_Pos (5UL) /*!< M_RD_REQ (Bit 5) */ #define I2C2_I2C2_INTR_MASK_REG_M_RD_REQ_Msk (0x20UL) /*!< M_RD_REQ (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_EMPTY_Pos (4UL) /*!< M_TX_EMPTY (Bit 4) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_EMPTY_Msk (0x10UL) /*!< M_TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_OVER_Pos (3UL) /*!< M_TX_OVER (Bit 3) */ #define I2C2_I2C2_INTR_MASK_REG_M_TX_OVER_Msk (0x8UL) /*!< M_TX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_FULL_Pos (2UL) /*!< M_RX_FULL (Bit 2) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_FULL_Msk (0x4UL) /*!< M_RX_FULL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_OVER_Pos (1UL) /*!< M_RX_OVER (Bit 1) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_OVER_Msk (0x2UL) /*!< M_RX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_UNDER_Pos (0UL) /*!< M_RX_UNDER (Bit 0) */ #define I2C2_I2C2_INTR_MASK_REG_M_RX_UNDER_Msk (0x1UL) /*!< M_RX_UNDER (Bitfield-Mask: 0x01) */ /* ================================================== I2C2_INTR_STAT_REG =================================================== */ #define I2C2_I2C2_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Pos (14UL) /*!< R_SCL_STUCK_AT_LOW (Bit 14) */ #define I2C2_I2C2_INTR_STAT_REG_R_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< R_SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_MASTER_ON_HOLD_Pos (13UL) /*!< R_MASTER_ON_HOLD (Bit 13) */ #define I2C2_I2C2_INTR_STAT_REG_R_MASTER_ON_HOLD_Msk (0x2000UL) /*!< R_MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RESTART_DET_Pos (12UL) /*!< R_RESTART_DET (Bit 12) */ #define I2C2_I2C2_INTR_STAT_REG_R_RESTART_DET_Msk (0x1000UL) /*!< R_RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_GEN_CALL_Pos (11UL) /*!< R_GEN_CALL (Bit 11) */ #define I2C2_I2C2_INTR_STAT_REG_R_GEN_CALL_Msk (0x800UL) /*!< R_GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_START_DET_Pos (10UL) /*!< R_START_DET (Bit 10) */ #define I2C2_I2C2_INTR_STAT_REG_R_START_DET_Msk (0x400UL) /*!< R_START_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_STOP_DET_Pos (9UL) /*!< R_STOP_DET (Bit 9) */ #define I2C2_I2C2_INTR_STAT_REG_R_STOP_DET_Msk (0x200UL) /*!< R_STOP_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_ACTIVITY_Pos (8UL) /*!< R_ACTIVITY (Bit 8) */ #define I2C2_I2C2_INTR_STAT_REG_R_ACTIVITY_Msk (0x100UL) /*!< R_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_DONE_Pos (7UL) /*!< R_RX_DONE (Bit 7) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_DONE_Msk (0x80UL) /*!< R_RX_DONE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_ABRT_Pos (6UL) /*!< R_TX_ABRT (Bit 6) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_ABRT_Msk (0x40UL) /*!< R_TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RD_REQ_Pos (5UL) /*!< R_RD_REQ (Bit 5) */ #define I2C2_I2C2_INTR_STAT_REG_R_RD_REQ_Msk (0x20UL) /*!< R_RD_REQ (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_EMPTY_Pos (4UL) /*!< R_TX_EMPTY (Bit 4) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_EMPTY_Msk (0x10UL) /*!< R_TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_OVER_Pos (3UL) /*!< R_TX_OVER (Bit 3) */ #define I2C2_I2C2_INTR_STAT_REG_R_TX_OVER_Msk (0x8UL) /*!< R_TX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_FULL_Pos (2UL) /*!< R_RX_FULL (Bit 2) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_FULL_Msk (0x4UL) /*!< R_RX_FULL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_OVER_Pos (1UL) /*!< R_RX_OVER (Bit 1) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_OVER_Msk (0x2UL) /*!< R_RX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_UNDER_Pos (0UL) /*!< R_RX_UNDER (Bit 0) */ #define I2C2_I2C2_INTR_STAT_REG_R_RX_UNDER_Msk (0x1UL) /*!< R_RX_UNDER (Bitfield-Mask: 0x01) */ /* ================================================ I2C2_RAW_INTR_STAT_REG ================================================= */ #define I2C2_I2C2_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Pos (14UL) /*!< SCL_STUCK_AT_LOW (Bit 14) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_SCL_STUCK_AT_LOW_Msk (0x4000UL) /*!< SCL_STUCK_AT_LOW (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Pos (13UL) /*!< MASTER_ON_HOLD (Bit 13) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_MASTER_ON_HOLD_Msk (0x2000UL) /*!< MASTER_ON_HOLD (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RESTART_DET_Pos (12UL) /*!< RESTART_DET (Bit 12) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RESTART_DET_Msk (0x1000UL) /*!< RESTART_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_GEN_CALL_Pos (11UL) /*!< GEN_CALL (Bit 11) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_GEN_CALL_Msk (0x800UL) /*!< GEN_CALL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_START_DET_Pos (10UL) /*!< START_DET (Bit 10) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_START_DET_Msk (0x400UL) /*!< START_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_STOP_DET_Pos (9UL) /*!< STOP_DET (Bit 9) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_STOP_DET_Msk (0x200UL) /*!< STOP_DET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_ACTIVITY_Pos (8UL) /*!< ACTIVITY (Bit 8) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_ACTIVITY_Msk (0x100UL) /*!< ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_DONE_Pos (7UL) /*!< RX_DONE (Bit 7) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_DONE_Msk (0x80UL) /*!< RX_DONE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_ABRT_Pos (6UL) /*!< TX_ABRT (Bit 6) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_ABRT_Msk (0x40UL) /*!< TX_ABRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RD_REQ_Pos (5UL) /*!< RD_REQ (Bit 5) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RD_REQ_Msk (0x20UL) /*!< RD_REQ (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_EMPTY_Pos (4UL) /*!< TX_EMPTY (Bit 4) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_EMPTY_Msk (0x10UL) /*!< TX_EMPTY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_OVER_Pos (3UL) /*!< TX_OVER (Bit 3) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_TX_OVER_Msk (0x8UL) /*!< TX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_FULL_Pos (2UL) /*!< RX_FULL (Bit 2) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_FULL_Msk (0x4UL) /*!< RX_FULL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_OVER_Pos (1UL) /*!< RX_OVER (Bit 1) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_OVER_Msk (0x2UL) /*!< RX_OVER (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_UNDER_Pos (0UL) /*!< RX_UNDER (Bit 0) */ #define I2C2_I2C2_RAW_INTR_STAT_REG_RX_UNDER_Msk (0x1UL) /*!< RX_UNDER (Bitfield-Mask: 0x01) */ /* ==================================================== I2C2_RXFLR_REG ===================================================== */ #define I2C2_I2C2_RXFLR_REG_RXFLR_Pos (0UL) /*!< RXFLR (Bit 0) */ #define I2C2_I2C2_RXFLR_REG_RXFLR_Msk (0x3fUL) /*!< RXFLR (Bitfield-Mask: 0x3f) */ /* ==================================================== I2C2_RX_TL_REG ===================================================== */ #define I2C2_I2C2_RX_TL_REG_RX_TL_Pos (0UL) /*!< RX_TL (Bit 0) */ #define I2C2_I2C2_RX_TL_REG_RX_TL_Msk (0x1fUL) /*!< RX_TL (Bitfield-Mask: 0x1f) */ /* ===================================================== I2C2_SAR_REG ====================================================== */ #define I2C2_I2C2_SAR_REG_IC_SAR_Pos (0UL) /*!< IC_SAR (Bit 0) */ #define I2C2_I2C2_SAR_REG_IC_SAR_Msk (0x3ffUL) /*!< IC_SAR (Bitfield-Mask: 0x3ff) */ /* =================================================== I2C2_SDA_HOLD_REG =================================================== */ #define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Pos (16UL) /*!< I2C_SDA_RX_HOLD (Bit 16) */ #define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_RX_HOLD_Msk (0xff0000UL) /*!< I2C_SDA_RX_HOLD (Bitfield-Mask: 0xff) */ #define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Pos (0UL) /*!< I2C_SDA_TX_HOLD (Bit 0) */ #define I2C2_I2C2_SDA_HOLD_REG_I2C_SDA_TX_HOLD_Msk (0xffffUL) /*!< I2C_SDA_TX_HOLD (Bitfield-Mask: 0xffff) */ /* ================================================== I2C2_SDA_SETUP_REG =================================================== */ #define I2C2_I2C2_SDA_SETUP_REG_SDA_SETUP_Pos (0UL) /*!< SDA_SETUP (Bit 0) */ #define I2C2_I2C2_SDA_SETUP_REG_SDA_SETUP_Msk (0xffUL) /*!< SDA_SETUP (Bitfield-Mask: 0xff) */ /* ================================================= I2C2_SS_SCL_HCNT_REG ================================================== */ #define I2C2_I2C2_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Pos (0UL) /*!< IC_SS_SCL_HCNT (Bit 0) */ #define I2C2_I2C2_SS_SCL_HCNT_REG_IC_SS_SCL_HCNT_Msk (0xffffUL) /*!< IC_SS_SCL_HCNT (Bitfield-Mask: 0xffff) */ /* ================================================= I2C2_SS_SCL_LCNT_REG ================================================== */ #define I2C2_I2C2_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Pos (0UL) /*!< IC_SS_SCL_LCNT (Bit 0) */ #define I2C2_I2C2_SS_SCL_LCNT_REG_IC_SS_SCL_LCNT_Msk (0xffffUL) /*!< IC_SS_SCL_LCNT (Bitfield-Mask: 0xffff) */ /* ==================================================== I2C2_STATUS_REG ==================================================== */ #define I2C2_I2C2_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Pos (10UL) /*!< LV_HOLD_RX_FIFO_FULL (Bit 10) */ #define I2C2_I2C2_STATUS_REG_LV_HOLD_RX_FIFO_FULL_Msk (0x400UL) /*!< LV_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Pos (9UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bit 9) */ #define I2C2_I2C2_STATUS_REG_SLV_HOLD_TX_FIFO_EMPTY_Msk (0x200UL) /*!< SLV_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Pos (8UL) /*!< MST_HOLD_RX_FIFO_FULL (Bit 8) */ #define I2C2_I2C2_STATUS_REG_MST_HOLD_RX_FIFO_FULL_Msk (0x100UL) /*!< MST_HOLD_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Pos (7UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bit 7) */ #define I2C2_I2C2_STATUS_REG_MST_HOLD_TX_FIFO_EMPTY_Msk (0x80UL) /*!< MST_HOLD_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_SLV_ACTIVITY_Pos (6UL) /*!< SLV_ACTIVITY (Bit 6) */ #define I2C2_I2C2_STATUS_REG_SLV_ACTIVITY_Msk (0x40UL) /*!< SLV_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_MST_ACTIVITY_Pos (5UL) /*!< MST_ACTIVITY (Bit 5) */ #define I2C2_I2C2_STATUS_REG_MST_ACTIVITY_Msk (0x20UL) /*!< MST_ACTIVITY (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_RFF_Pos (4UL) /*!< RFF (Bit 4) */ #define I2C2_I2C2_STATUS_REG_RFF_Msk (0x10UL) /*!< RFF (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_RFNE_Pos (3UL) /*!< RFNE (Bit 3) */ #define I2C2_I2C2_STATUS_REG_RFNE_Msk (0x8UL) /*!< RFNE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_TFE_Pos (2UL) /*!< TFE (Bit 2) */ #define I2C2_I2C2_STATUS_REG_TFE_Msk (0x4UL) /*!< TFE (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_TFNF_Pos (1UL) /*!< TFNF (Bit 1) */ #define I2C2_I2C2_STATUS_REG_TFNF_Msk (0x2UL) /*!< TFNF (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_STATUS_REG_I2C_ACTIVITY_Pos (0UL) /*!< I2C_ACTIVITY (Bit 0) */ #define I2C2_I2C2_STATUS_REG_I2C_ACTIVITY_Msk (0x1UL) /*!< I2C_ACTIVITY (Bitfield-Mask: 0x01) */ /* ===================================================== I2C2_TAR_REG ====================================================== */ #define I2C2_I2C2_TAR_REG_SPECIAL_Pos (11UL) /*!< SPECIAL (Bit 11) */ #define I2C2_I2C2_TAR_REG_SPECIAL_Msk (0x800UL) /*!< SPECIAL (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TAR_REG_GC_OR_START_Pos (10UL) /*!< GC_OR_START (Bit 10) */ #define I2C2_I2C2_TAR_REG_GC_OR_START_Msk (0x400UL) /*!< GC_OR_START (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TAR_REG_IC_TAR_Pos (0UL) /*!< IC_TAR (Bit 0) */ #define I2C2_I2C2_TAR_REG_IC_TAR_Msk (0x3ffUL) /*!< IC_TAR (Bitfield-Mask: 0x3ff) */ /* ==================================================== I2C2_TXFLR_REG ===================================================== */ #define I2C2_I2C2_TXFLR_REG_TXFLR_Pos (0UL) /*!< TXFLR (Bit 0) */ #define I2C2_I2C2_TXFLR_REG_TXFLR_Msk (0x3fUL) /*!< TXFLR (Bitfield-Mask: 0x3f) */ /* ================================================ I2C2_TX_ABRT_SOURCE_REG ================================================ */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Pos (16UL) /*!< ABRT_USER_ABRT (Bit 16) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk (0x10000UL) /*!< ABRT_USER_ABRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Pos (15UL) /*!< ABRT_SLVRD_INTX (Bit 15) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVRD_INTX_Msk (0x8000UL) /*!< ABRT_SLVRD_INTX (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Pos (14UL) /*!< ABRT_SLV_ARBLOST (Bit 14) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLV_ARBLOST_Msk (0x4000UL) /*!< ABRT_SLV_ARBLOST (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Pos (13UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bit 13) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SLVFLUSH_TXFIFO_Msk (0x2000UL) /*!< ABRT_SLVFLUSH_TXFIFO (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ARB_LOST_Pos (12UL) /*!< ARB_LOST (Bit 12) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ARB_LOST_Msk (0x1000UL) /*!< ARB_LOST (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Pos (11UL) /*!< ABRT_MASTER_DIS (Bit 11) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_MASTER_DIS_Msk (0x800UL) /*!< ABRT_MASTER_DIS (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Pos (10UL) /*!< ABRT_10B_RD_NORSTRT (Bit 10) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10B_RD_NORSTRT_Msk (0x400UL) /*!< ABRT_10B_RD_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Pos (9UL) /*!< ABRT_SBYTE_NORSTRT (Bit 9) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_NORSTRT_Msk (0x200UL) /*!< ABRT_SBYTE_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Pos (8UL) /*!< ABRT_HS_NORSTRT (Bit 8) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_NORSTRT_Msk (0x100UL) /*!< ABRT_HS_NORSTRT (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Pos (7UL) /*!< ABRT_SBYTE_ACKDET (Bit 7) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_SBYTE_ACKDET_Msk (0x80UL) /*!< ABRT_SBYTE_ACKDET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Pos (6UL) /*!< ABRT_HS_ACKDET (Bit 6) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_HS_ACKDET_Msk (0x40UL) /*!< ABRT_HS_ACKDET (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Pos (5UL) /*!< ABRT_GCALL_READ (Bit 5) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_READ_Msk (0x20UL) /*!< ABRT_GCALL_READ (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Pos (4UL) /*!< ABRT_GCALL_NOACK (Bit 4) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_GCALL_NOACK_Msk (0x10UL) /*!< ABRT_GCALL_NOACK (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Pos (3UL) /*!< ABRT_TXDATA_NOACK (Bit 3) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_TXDATA_NOACK_Msk (0x8UL) /*!< ABRT_TXDATA_NOACK (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Pos (2UL) /*!< ABRT_10ADDR2_NOACK (Bit 2) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR2_NOACK_Msk (0x4UL) /*!< ABRT_10ADDR2_NOACK (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Pos (1UL) /*!< ABRT_10ADDR1_NOACK (Bit 1) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_10ADDR1_NOACK_Msk (0x2UL) /*!< ABRT_10ADDR1_NOACK (Bitfield-Mask: 0x01) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Pos (0UL) /*!< ABRT_7B_ADDR_NOACK (Bit 0) */ #define I2C2_I2C2_TX_ABRT_SOURCE_REG_ABRT_7B_ADDR_NOACK_Msk (0x1UL) /*!< ABRT_7B_ADDR_NOACK (Bitfield-Mask: 0x01) */ /* ==================================================== I2C2_TX_TL_REG ===================================================== */ #define I2C2_I2C2_TX_TL_REG_TX_TL_Pos (0UL) /*!< TX_TL (Bit 0) */ #define I2C2_I2C2_TX_TL_REG_TX_TL_Msk (0x1fUL) /*!< TX_TL (Bitfield-Mask: 0x1f) */ /* =========================================================================================================================== */ /* ================ LCDC ================ */ /* =========================================================================================================================== */ /* ================================================= LCDC_BACKPORCHXY_REG ================================================== */ #define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_X_Pos (16UL) /*!< LCDC_BPORCH_X (Bit 16) */ #define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_X_Msk (0xffff0000UL) /*!< LCDC_BPORCH_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_Y_Pos (0UL) /*!< LCDC_BPORCH_Y (Bit 0) */ #define LCDC_LCDC_BACKPORCHXY_REG_LCDC_BPORCH_Y_Msk (0xffffUL) /*!< LCDC_BPORCH_Y (Bitfield-Mask: 0xffff) */ /* =================================================== LCDC_BGCOLOR_REG ==================================================== */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_RED_Pos (24UL) /*!< LCDC_BG_RED (Bit 24) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_RED_Msk (0xff000000UL) /*!< LCDC_BG_RED (Bitfield-Mask: 0xff) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_GREEN_Pos (16UL) /*!< LCDC_BG_GREEN (Bit 16) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_GREEN_Msk (0xff0000UL) /*!< LCDC_BG_GREEN (Bitfield-Mask: 0xff) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_BLUE_Pos (8UL) /*!< LCDC_BG_BLUE (Bit 8) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_BLUE_Msk (0xff00UL) /*!< LCDC_BG_BLUE (Bitfield-Mask: 0xff) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_ALPHA_Pos (0UL) /*!< LCDC_BG_ALPHA (Bit 0) */ #define LCDC_LCDC_BGCOLOR_REG_LCDC_BG_ALPHA_Msk (0xffUL) /*!< LCDC_BG_ALPHA (Bitfield-Mask: 0xff) */ /* ================================================== LCDC_BLANKINGXY_REG ================================================== */ #define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_X_Pos (16UL) /*!< LCDC_BLANKING_X (Bit 16) */ #define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_X_Msk (0xffff0000UL) /*!< LCDC_BLANKING_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_Y_Pos (0UL) /*!< LCDC_BLANKING_Y (Bit 0) */ #define LCDC_LCDC_BLANKINGXY_REG_LCDC_BLANKING_Y_Msk (0xffffUL) /*!< LCDC_BLANKING_Y (Bitfield-Mask: 0xffff) */ /* =================================================== LCDC_CLKCTRL_REG ==================================================== */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_SEC_CLK_DIV_Pos (27UL) /*!< LCDC_SEC_CLK_DIV (Bit 27) */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_SEC_CLK_DIV_Msk (0xf8000000UL) /*!< LCDC_SEC_CLK_DIV (Bitfield-Mask: 0x1f) */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_DMA_HOLD_Pos (8UL) /*!< LCDC_DMA_HOLD (Bit 8) */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_DMA_HOLD_Msk (0x3f00UL) /*!< LCDC_DMA_HOLD (Bitfield-Mask: 0x3f) */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_CLK_DIV_Pos (0UL) /*!< LCDC_CLK_DIV (Bit 0) */ #define LCDC_LCDC_CLKCTRL_REG_LCDC_CLK_DIV_Msk (0x3fUL) /*!< LCDC_CLK_DIV (Bitfield-Mask: 0x3f) */ /* ===================================================== LCDC_CRC_REG ====================================================== */ #define LCDC_LCDC_CRC_REG_LCDC_CRC_Pos (0UL) /*!< LCDC_CRC (Bit 0) */ #define LCDC_LCDC_CRC_REG_LCDC_CRC_Msk (0xffffffffUL) /*!< LCDC_CRC (Bitfield-Mask: 0xffffffff) */ /* =================================================== LCDC_DBIB_CFG_REG =================================================== */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_TE_DIS_Pos (31UL) /*!< LCDC_DBIB_TE_DIS (Bit 31) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_TE_DIS_Msk (0x80000000UL) /*!< LCDC_DBIB_TE_DIS (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_Pos (30UL) /*!< LCDC_DBIB_CSX_FORCE (Bit 30) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_Msk (0x40000000UL) /*!< LCDC_DBIB_CSX_FORCE (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_VAL_Pos (29UL) /*!< LCDC_DBIB_CSX_FORCE_VAL (Bit 29) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_CSX_FORCE_VAL_Msk (0x20000000UL) /*!< LCDC_DBIB_CSX_FORCE_VAL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_PAD_Pos (28UL) /*!< LCDC_DBIB_SPI_PAD (Bit 28) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_PAD_Msk (0x10000000UL) /*!< LCDC_DBIB_SPI_PAD (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_RESX_Pos (25UL) /*!< LCDC_DBIB_RESX (Bit 25) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_RESX_Msk (0x2000000UL) /*!< LCDC_DBIB_RESX (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_DMA_EN_Pos (24UL) /*!< LCDC_DBIB_DMA_EN (Bit 24) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_DMA_EN_Msk (0x1000000UL) /*!< LCDC_DBIB_DMA_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI3_EN_Pos (23UL) /*!< LCDC_DBIB_SPI3_EN (Bit 23) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI3_EN_Msk (0x800000UL) /*!< LCDC_DBIB_SPI3_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI4_EN_Pos (22UL) /*!< LCDC_DBIB_SPI4_EN (Bit 22) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI4_EN_Msk (0x400000UL) /*!< LCDC_DBIB_SPI4_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPHA_Pos (20UL) /*!< LCDC_DBIB_SPI_CPHA (Bit 20) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPHA_Msk (0x100000UL) /*!< LCDC_DBIB_SPI_CPHA (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPOL_Pos (19UL) /*!< LCDC_DBIB_SPI_CPOL (Bit 19) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_CPOL_Msk (0x80000UL) /*!< LCDC_DBIB_SPI_CPOL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_JDI_Pos (18UL) /*!< LCDC_DBIB_SPI_JDI (Bit 18) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_JDI_Msk (0x40000UL) /*!< LCDC_DBIB_SPI_JDI (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_HOLD_Pos (17UL) /*!< LCDC_DBIB_SPI_HOLD (Bit 17) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_HOLD_Msk (0x20000UL) /*!< LCDC_DBIB_SPI_HOLD (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_INV_ADDR_Pos (16UL) /*!< LCDC_DBIB_SPI_INV_ADDR (Bit 16) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_SPI_INV_ADDR_Msk (0x10000UL) /*!< LCDC_DBIB_SPI_INV_ADDR (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_INV_DATA_Pos (15UL) /*!< LCDC_DBIB_INV_DATA (Bit 15) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_INV_DATA_Msk (0x8000UL) /*!< LCDC_DBIB_INV_DATA (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_INV_PIX_Pos (14UL) /*!< LCDC_DBIB_JDI_INV_PIX (Bit 14) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_INV_PIX_Msk (0x4000UL) /*!< LCDC_DBIB_JDI_INV_PIX (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_SOFT_RST_Pos (13UL) /*!< LCDC_DBIB_JDI_SOFT_RST (Bit 13) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_JDI_SOFT_RST_Msk (0x2000UL) /*!< LCDC_DBIB_JDI_SOFT_RST (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_FMT_Pos (0UL) /*!< LCDC_DBIB_FMT (Bit 0) */ #define LCDC_LCDC_DBIB_CFG_REG_LCDC_DBIB_FMT_Msk (0x1fUL) /*!< LCDC_DBIB_FMT (Bitfield-Mask: 0x1f) */ /* =================================================== LCDC_DBIB_CMD_REG =================================================== */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_SEND_Pos (30UL) /*!< LCDC_DBIB_CMD_SEND (Bit 30) */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_SEND_Msk (0x40000000UL) /*!< LCDC_DBIB_CMD_SEND (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_STORE_Pos (27UL) /*!< LCDC_DBIB_CMD_STORE (Bit 27) */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_STORE_Msk (0x8000000UL) /*!< LCDC_DBIB_CMD_STORE (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_VAL_Pos (0UL) /*!< LCDC_DBIB_CMD_VAL (Bit 0) */ #define LCDC_LCDC_DBIB_CMD_REG_LCDC_DBIB_CMD_VAL_Msk (0xffffUL) /*!< LCDC_DBIB_CMD_VAL (Bitfield-Mask: 0xffff) */ /* ================================================= LCDC_FRONTPORCHXY_REG ================================================= */ #define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_X_Pos (16UL) /*!< LCDC_FPORCH_X (Bit 16) */ #define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_X_Msk (0xffff0000UL) /*!< LCDC_FPORCH_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_Y_Pos (0UL) /*!< LCDC_FPORCH_Y (Bit 0) */ #define LCDC_LCDC_FRONTPORCHXY_REG_LCDC_FPORCH_Y_Msk (0xffffUL) /*!< LCDC_FPORCH_Y (Bitfield-Mask: 0xffff) */ /* ===================================================== LCDC_GPIO_REG ===================================================== */ #define LCDC_LCDC_GPIO_REG_LCDC_TE_INV_Pos (1UL) /*!< LCDC_TE_INV (Bit 1) */ #define LCDC_LCDC_GPIO_REG_LCDC_TE_INV_Msk (0x2UL) /*!< LCDC_TE_INV (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_GPIO_REG_LCDC_PARIF_SEL_Pos (0UL) /*!< LCDC_PARIF_SEL (Bit 0) */ #define LCDC_LCDC_GPIO_REG_LCDC_PARIF_SEL_Msk (0x1UL) /*!< LCDC_PARIF_SEL (Bitfield-Mask: 0x01) */ /* ==================================================== LCDC_IDREG_REG ===================================================== */ #define LCDC_LCDC_IDREG_REG_LCDC_ID_Pos (0UL) /*!< LCDC_ID (Bit 0) */ #define LCDC_LCDC_IDREG_REG_LCDC_ID_Msk (0xffffffffUL) /*!< LCDC_ID (Bitfield-Mask: 0xffffffff) */ /* ================================================== LCDC_INTERRUPT_REG =================================================== */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_IRQ_TRIGGER_SEL_Pos (31UL) /*!< LCDC_IRQ_TRIGGER_SEL (Bit 31) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_IRQ_TRIGGER_SEL_Msk (0x80000000UL) /*!< LCDC_IRQ_TRIGGER_SEL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_FRAME_END_IRQ_EN_Pos (5UL) /*!< LCDC_FRAME_END_IRQ_EN (Bit 5) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_FRAME_END_IRQ_EN_Msk (0x20UL) /*!< LCDC_FRAME_END_IRQ_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_TE_IRQ_EN_Pos (3UL) /*!< LCDC_TE_IRQ_EN (Bit 3) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_TE_IRQ_EN_Msk (0x8UL) /*!< LCDC_TE_IRQ_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_HSYNC_IRQ_EN_Pos (1UL) /*!< LCDC_HSYNC_IRQ_EN (Bit 1) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_HSYNC_IRQ_EN_Msk (0x2UL) /*!< LCDC_HSYNC_IRQ_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Pos (0UL) /*!< LCDC_VSYNC_IRQ_EN (Bit 0) */ #define LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Msk (0x1UL) /*!< LCDC_VSYNC_IRQ_EN (Bitfield-Mask: 0x01) */ /* ============================================== LCDC_JDI_ENB_END_HLINE_REG =============================================== */ #define LCDC_LCDC_JDI_ENB_END_HLINE_REG_LCDC_JDI_ENB_END_HLINE_Pos (0UL) /*!< LCDC_JDI_ENB_END_HLINE (Bit 0) */ #define LCDC_LCDC_JDI_ENB_END_HLINE_REG_LCDC_JDI_ENB_END_HLINE_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_END_HLINE (Bitfield-Mask: 0xffffffff) */ /* ============================================== LCDC_JDI_ENB_START_CLK_REG =============================================== */ #define LCDC_LCDC_JDI_ENB_START_CLK_REG_LCDC_JDI_ENB_START_CLK_Pos (0UL) /*!< LCDC_JDI_ENB_START_CLK (Bit 0) */ #define LCDC_LCDC_JDI_ENB_START_CLK_REG_LCDC_JDI_ENB_START_CLK_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_START_CLK (Bitfield-Mask: 0xffffffff) */ /* ============================================= LCDC_JDI_ENB_START_HLINE_REG ============================================== */ #define LCDC_LCDC_JDI_ENB_START_HLINE_REG_LCDC_JDI_ENB_START_HLINE_Pos (0UL) /*!< LCDC_JDI_ENB_START_HLINE (Bit 0) */ #define LCDC_LCDC_JDI_ENB_START_HLINE_REG_LCDC_JDI_ENB_START_HLINE_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_START_HLINE (Bitfield-Mask: 0xffffffff) */ /* ============================================== LCDC_JDI_ENB_WIDTH_CLK_REG =============================================== */ #define LCDC_LCDC_JDI_ENB_WIDTH_CLK_REG_LCDC_JDI_ENB_WIDTH_CLK_Pos (0UL) /*!< LCDC_JDI_ENB_WIDTH_CLK (Bit 0) */ #define LCDC_LCDC_JDI_ENB_WIDTH_CLK_REG_LCDC_JDI_ENB_WIDTH_CLK_Msk (0xffffffffUL) /*!< LCDC_JDI_ENB_WIDTH_CLK (Bitfield-Mask: 0xffffffff) */ /* =============================================== LCDC_JDI_FBX_BLANKING_REG =============================================== */ #define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_FXBLANKING_Pos (16UL) /*!< LCDC_JDI_FXBLANKING (Bit 16) */ #define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_FXBLANKING_Msk (0xffff0000UL) /*!< LCDC_JDI_FXBLANKING (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_BXBLANKING_Pos (0UL) /*!< LCDC_JDI_BXBLANKING (Bit 0) */ #define LCDC_LCDC_JDI_FBX_BLANKING_REG_LCDC_JDI_BXBLANKING_Msk (0xffffUL) /*!< LCDC_JDI_BXBLANKING (Bitfield-Mask: 0xffff) */ /* =============================================== LCDC_JDI_FBY_BLANKING_REG =============================================== */ #define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_FYBLANKING_Pos (16UL) /*!< LCDC_JDI_FYBLANKING (Bit 16) */ #define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_FYBLANKING_Msk (0xffff0000UL) /*!< LCDC_JDI_FYBLANKING (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_BYBLANKING_Pos (0UL) /*!< LCDC_JDI_BYBLANKING (Bit 0) */ #define LCDC_LCDC_JDI_FBY_BLANKING_REG_LCDC_JDI_BYBLANKING_Msk (0xffffUL) /*!< LCDC_JDI_BYBLANKING (Bitfield-Mask: 0xffff) */ /* ================================================ LCDC_JDI_HCK_WIDTH_REG ================================================= */ #define LCDC_LCDC_JDI_HCK_WIDTH_REG_LCDC_JDI_HCK_WIDTH_Pos (0UL) /*!< LCDC_JDI_HCK_WIDTH (Bit 0) */ #define LCDC_LCDC_JDI_HCK_WIDTH_REG_LCDC_JDI_HCK_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_HCK_WIDTH (Bitfield-Mask: 0xffffffff) */ /* ================================================ LCDC_JDI_HST_DELAY_REG ================================================= */ #define LCDC_LCDC_JDI_HST_DELAY_REG_LCDC_JDI_HST_DELAY_Pos (0UL) /*!< LCDC_JDI_HST_DELAY (Bit 0) */ #define LCDC_LCDC_JDI_HST_DELAY_REG_LCDC_JDI_HST_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_HST_DELAY (Bitfield-Mask: 0xffffffff) */ /* ================================================ LCDC_JDI_HST_WIDTH_REG ================================================= */ #define LCDC_LCDC_JDI_HST_WIDTH_REG_LCDC_JDI_HST_WIDTH_Pos (0UL) /*!< LCDC_JDI_HST_WIDTH (Bit 0) */ #define LCDC_LCDC_JDI_HST_WIDTH_REG_LCDC_JDI_HST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_HST_WIDTH (Bitfield-Mask: 0xffffffff) */ /* ================================================== LCDC_JDI_RESXY_REG =================================================== */ #define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_X_Pos (16UL) /*!< LCDC_JDI_RES_X (Bit 16) */ #define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_X_Msk (0xffff0000UL) /*!< LCDC_JDI_RES_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_Y_Pos (0UL) /*!< LCDC_JDI_RES_Y (Bit 0) */ #define LCDC_LCDC_JDI_RESXY_REG_LCDC_JDI_RES_Y_Msk (0xffffUL) /*!< LCDC_JDI_RES_Y (Bitfield-Mask: 0xffff) */ /* ================================================ LCDC_JDI_VCK_DELAY_REG ================================================= */ #define LCDC_LCDC_JDI_VCK_DELAY_REG_LCDC_JDI_VCK_DELAY_Pos (0UL) /*!< LCDC_JDI_VCK_DELAY (Bit 0) */ #define LCDC_LCDC_JDI_VCK_DELAY_REG_LCDC_JDI_VCK_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_VCK_DELAY (Bitfield-Mask: 0xffffffff) */ /* ================================================ LCDC_JDI_VST_DELAY_REG ================================================= */ #define LCDC_LCDC_JDI_VST_DELAY_REG_LCDC_JDI_VST_DELAY_Pos (0UL) /*!< LCDC_JDI_VST_DELAY (Bit 0) */ #define LCDC_LCDC_JDI_VST_DELAY_REG_LCDC_JDI_VST_DELAY_Msk (0xffffffffUL) /*!< LCDC_JDI_VST_DELAY (Bitfield-Mask: 0xffffffff) */ /* ================================================ LCDC_JDI_VST_WIDTH_REG ================================================= */ #define LCDC_LCDC_JDI_VST_WIDTH_REG_LCDC_JDI_VST_WIDTH_Pos (0UL) /*!< LCDC_JDI_VST_WIDTH (Bit 0) */ #define LCDC_LCDC_JDI_VST_WIDTH_REG_LCDC_JDI_VST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_VST_WIDTH (Bitfield-Mask: 0xffffffff) */ /* ================================================ LCDC_JDI_XRST_WIDTH_REG ================================================ */ #define LCDC_LCDC_JDI_XRST_WIDTH_REG_LCDC_JDI_XRST_WIDTH_Pos (0UL) /*!< LCDC_JDI_XRST_WIDTH (Bit 0) */ #define LCDC_LCDC_JDI_XRST_WIDTH_REG_LCDC_JDI_XRST_WIDTH_Msk (0xffffffffUL) /*!< LCDC_JDI_XRST_WIDTH (Bitfield-Mask: 0xffffffff) */ /* =============================================== LCDC_LAYER0_BASEADDR_REG ================================================ */ #define LCDC_LCDC_LAYER0_BASEADDR_REG_LCDC_L0_FB_ADDR_Pos (0UL) /*!< LCDC_L0_FB_ADDR (Bit 0) */ #define LCDC_LCDC_LAYER0_BASEADDR_REG_LCDC_L0_FB_ADDR_Msk (0xffffffffUL) /*!< LCDC_L0_FB_ADDR (Bitfield-Mask: 0xffffffff) */ /* ================================================= LCDC_LAYER0_MODE_REG ================================================== */ #define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_EN_Pos (31UL) /*!< LCDC_L0_EN (Bit 31) */ #define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_EN_Msk (0x80000000UL) /*!< LCDC_L0_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_COLOUR_MODE_Pos (0UL) /*!< LCDC_L0_COLOUR_MODE (Bit 0) */ #define LCDC_LCDC_LAYER0_MODE_REG_LCDC_L0_COLOUR_MODE_Msk (0x1fUL) /*!< LCDC_L0_COLOUR_MODE (Bitfield-Mask: 0x1f) */ /* ================================================ LCDC_LAYER0_OFFSETX_REG ================================================ */ #define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_DMA_PREFETCH_Pos (16UL) /*!< LCDC_L0_DMA_PREFETCH (Bit 16) */ #define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_DMA_PREFETCH_Msk (0xffff0000UL) /*!< LCDC_L0_DMA_PREFETCH (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_OFFSETX_Pos (0UL) /*!< LCDC_L0_OFFSETX (Bit 0) */ #define LCDC_LCDC_LAYER0_OFFSETX_REG_LCDC_L0_OFFSETX_Msk (0xffffUL) /*!< LCDC_L0_OFFSETX (Bitfield-Mask: 0xffff) */ /* ================================================= LCDC_LAYER0_RESXY_REG ================================================= */ #define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_X_Pos (16UL) /*!< LCDC_L0_RES_X (Bit 16) */ #define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_X_Msk (0xffff0000UL) /*!< LCDC_L0_RES_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_Y_Pos (0UL) /*!< LCDC_L0_RES_Y (Bit 0) */ #define LCDC_LCDC_LAYER0_RESXY_REG_LCDC_L0_RES_Y_Msk (0xffffUL) /*!< LCDC_L0_RES_Y (Bitfield-Mask: 0xffff) */ /* ================================================ LCDC_LAYER0_SIZEXY_REG ================================================= */ #define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_X_Pos (16UL) /*!< LCDC_L0_SIZE_X (Bit 16) */ #define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_X_Msk (0xffff0000UL) /*!< LCDC_L0_SIZE_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_Y_Pos (0UL) /*!< LCDC_L0_SIZE_Y (Bit 0) */ #define LCDC_LCDC_LAYER0_SIZEXY_REG_LCDC_L0_SIZE_Y_Msk (0xffffUL) /*!< LCDC_L0_SIZE_Y (Bitfield-Mask: 0xffff) */ /* ================================================ LCDC_LAYER0_STARTXY_REG ================================================ */ #define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_X_Pos (16UL) /*!< LCDC_L0_START_X (Bit 16) */ #define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_X_Msk (0xffff0000UL) /*!< LCDC_L0_START_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_Y_Pos (0UL) /*!< LCDC_L0_START_Y (Bit 0) */ #define LCDC_LCDC_LAYER0_STARTXY_REG_LCDC_L0_START_Y_Msk (0xffffUL) /*!< LCDC_L0_START_Y (Bitfield-Mask: 0xffff) */ /* ================================================ LCDC_LAYER0_STRIDE_REG ================================================= */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_FIFO_THR_Pos (19UL) /*!< LCDC_L0_FIFO_THR (Bit 19) */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_FIFO_THR_Msk (0x180000UL) /*!< LCDC_L0_FIFO_THR (Bitfield-Mask: 0x03) */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_BURST_LEN_Pos (16UL) /*!< LCDC_L0_BURST_LEN (Bit 16) */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_BURST_LEN_Msk (0x70000UL) /*!< LCDC_L0_BURST_LEN (Bitfield-Mask: 0x07) */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_STRIDE_Pos (0UL) /*!< LCDC_L0_STRIDE (Bit 0) */ #define LCDC_LCDC_LAYER0_STRIDE_REG_LCDC_L0_STRIDE_Msk (0xffffUL) /*!< LCDC_L0_STRIDE (Bitfield-Mask: 0xffff) */ /* ===================================================== LCDC_MODE_REG ===================================================== */ #define LCDC_LCDC_MODE_REG_LCDC_MODE_EN_Pos (31UL) /*!< LCDC_MODE_EN (Bit 31) */ #define LCDC_LCDC_MODE_REG_LCDC_MODE_EN_Msk (0x80000000UL) /*!< LCDC_MODE_EN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_VSYNC_POL_Pos (28UL) /*!< LCDC_VSYNC_POL (Bit 28) */ #define LCDC_LCDC_MODE_REG_LCDC_VSYNC_POL_Msk (0x10000000UL) /*!< LCDC_VSYNC_POL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_HSYNC_POL_Pos (27UL) /*!< LCDC_HSYNC_POL (Bit 27) */ #define LCDC_LCDC_MODE_REG_LCDC_HSYNC_POL_Msk (0x8000000UL) /*!< LCDC_HSYNC_POL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_DE_POL_Pos (26UL) /*!< LCDC_DE_POL (Bit 26) */ #define LCDC_LCDC_MODE_REG_LCDC_DE_POL_Msk (0x4000000UL) /*!< LCDC_DE_POL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_VSYNC_SCPL_Pos (23UL) /*!< LCDC_VSYNC_SCPL (Bit 23) */ #define LCDC_LCDC_MODE_REG_LCDC_VSYNC_SCPL_Msk (0x800000UL) /*!< LCDC_VSYNC_SCPL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_POL_Pos (22UL) /*!< LCDC_PIXCLKOUT_POL (Bit 22) */ #define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_POL_Msk (0x400000UL) /*!< LCDC_PIXCLKOUT_POL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Pos (19UL) /*!< LCDC_FORCE_BLANK (Bit 19) */ #define LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Msk (0x80000UL) /*!< LCDC_FORCE_BLANK (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_SFRAME_UPD_Pos (17UL) /*!< LCDC_SFRAME_UPD (Bit 17) */ #define LCDC_LCDC_MODE_REG_LCDC_SFRAME_UPD_Msk (0x20000UL) /*!< LCDC_SFRAME_UPD (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_SEL_Pos (11UL) /*!< LCDC_PIXCLKOUT_SEL (Bit 11) */ #define LCDC_LCDC_MODE_REG_LCDC_PIXCLKOUT_SEL_Msk (0x800UL) /*!< LCDC_PIXCLKOUT_SEL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_OUT_MODE_Pos (5UL) /*!< LCDC_OUT_MODE (Bit 5) */ #define LCDC_LCDC_MODE_REG_LCDC_OUT_MODE_Msk (0x1e0UL) /*!< LCDC_OUT_MODE (Bitfield-Mask: 0x0f) */ #define LCDC_LCDC_MODE_REG_LCDC_MIPI_OFF_Pos (4UL) /*!< LCDC_MIPI_OFF (Bit 4) */ #define LCDC_LCDC_MODE_REG_LCDC_MIPI_OFF_Msk (0x10UL) /*!< LCDC_MIPI_OFF (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_FORM_OFF_Pos (3UL) /*!< LCDC_FORM_OFF (Bit 3) */ #define LCDC_LCDC_MODE_REG_LCDC_FORM_OFF_Msk (0x8UL) /*!< LCDC_FORM_OFF (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_DSCAN_Pos (1UL) /*!< LCDC_DSCAN (Bit 1) */ #define LCDC_LCDC_MODE_REG_LCDC_DSCAN_Msk (0x2UL) /*!< LCDC_DSCAN (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_MODE_REG_LCDC_TMODE_Pos (0UL) /*!< LCDC_TMODE (Bit 0) */ #define LCDC_LCDC_MODE_REG_LCDC_TMODE_Msk (0x1UL) /*!< LCDC_TMODE (Bitfield-Mask: 0x01) */ /* ==================================================== LCDC_RESXY_REG ===================================================== */ #define LCDC_LCDC_RESXY_REG_LCDC_RES_X_Pos (16UL) /*!< LCDC_RES_X (Bit 16) */ #define LCDC_LCDC_RESXY_REG_LCDC_RES_X_Msk (0xffff0000UL) /*!< LCDC_RES_X (Bitfield-Mask: 0xffff) */ #define LCDC_LCDC_RESXY_REG_LCDC_RES_Y_Pos (0UL) /*!< LCDC_RES_Y (Bit 0) */ #define LCDC_LCDC_RESXY_REG_LCDC_RES_Y_Msk (0xffffUL) /*!< LCDC_RES_Y (Bitfield-Mask: 0xffff) */ /* ==================================================== LCDC_STATUS_REG ==================================================== */ #define LCDC_LCDC_STATUS_REG_LCDC_JDI_TIM_SW_RST_Pos (15UL) /*!< LCDC_JDI_TIM_SW_RST (Bit 15) */ #define LCDC_LCDC_STATUS_REG_LCDC_JDI_TIM_SW_RST_Msk (0x8000UL) /*!< LCDC_JDI_TIM_SW_RST (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAME_START_Pos (14UL) /*!< LCDC_FRAME_START (Bit 14) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAME_START_Msk (0x4000UL) /*!< LCDC_FRAME_START (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAME_END_Pos (13UL) /*!< LCDC_FRAME_END (Bit 13) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAME_END_Msk (0x2000UL) /*!< LCDC_FRAME_END (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_PENDING_Pos (12UL) /*!< LCDC_DBIB_CMD_PENDING (Bit 12) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_PENDING_Msk (0x1000UL) /*!< LCDC_DBIB_CMD_PENDING (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_FULL_Pos (11UL) /*!< LCDC_DBIB_CMD_FIFO_FULL (Bit 11) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_FULL_Msk (0x800UL) /*!< LCDC_DBIB_CMD_FIFO_FULL (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_EMPTY_N_Pos (10UL) /*!< LCDC_DBIB_CMD_FIFO_EMPTY_N (Bit 10) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_CMD_FIFO_EMPTY_N_Msk (0x400UL) /*!< LCDC_DBIB_CMD_FIFO_EMPTY_N (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_TE_Pos (8UL) /*!< LCDC_DBIB_TE (Bit 8) */ #define LCDC_LCDC_STATUS_REG_LCDC_DBIB_TE_Msk (0x100UL) /*!< LCDC_DBIB_TE (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_STICKY_UNDERFLOW_Pos (7UL) /*!< LCDC_STICKY_UNDERFLOW (Bit 7) */ #define LCDC_LCDC_STATUS_REG_LCDC_STICKY_UNDERFLOW_Msk (0x80UL) /*!< LCDC_STICKY_UNDERFLOW (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_UNDERFLOW_Pos (6UL) /*!< LCDC_UNDERFLOW (Bit 6) */ #define LCDC_LCDC_STATUS_REG_LCDC_UNDERFLOW_Msk (0x40UL) /*!< LCDC_UNDERFLOW (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_LAST_ROW_Pos (5UL) /*!< LCDC_LAST_ROW (Bit 5) */ #define LCDC_LCDC_STATUS_REG_LCDC_LAST_ROW_Msk (0x20UL) /*!< LCDC_LAST_ROW (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_CSYNC_Pos (4UL) /*!< LCDC_STAT_CSYNC (Bit 4) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_CSYNC_Msk (0x10UL) /*!< LCDC_STAT_CSYNC (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_VSYNC_Pos (3UL) /*!< LCDC_STAT_VSYNC (Bit 3) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_VSYNC_Msk (0x8UL) /*!< LCDC_STAT_VSYNC (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_HSYNC_Pos (2UL) /*!< LCDC_STAT_HSYNC (Bit 2) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_HSYNC_Msk (0x4UL) /*!< LCDC_STAT_HSYNC (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAMEGEN_BUSY_Pos (1UL) /*!< LCDC_FRAMEGEN_BUSY (Bit 1) */ #define LCDC_LCDC_STATUS_REG_LCDC_FRAMEGEN_BUSY_Msk (0x2UL) /*!< LCDC_FRAMEGEN_BUSY (Bitfield-Mask: 0x01) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_ACTIVE_Pos (0UL) /*!< LCDC_STAT_ACTIVE (Bit 0) */ #define LCDC_LCDC_STATUS_REG_LCDC_STAT_ACTIVE_Msk (0x1UL) /*!< LCDC_STAT_ACTIVE (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ LRA ================ */ /* =========================================================================================================================== */ /* =================================================== LRA_ADC_CTRL1_REG =================================================== */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_BUSY_Pos (31UL) /*!< LRA_ADC_BUSY (Bit 31) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_BUSY_Msk (0x80000000UL) /*!< LRA_ADC_BUSY (Bitfield-Mask: 0x01) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_OFFSET_Pos (9UL) /*!< LRA_ADC_OFFSET (Bit 9) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_OFFSET_Msk (0x1fe00UL) /*!< LRA_ADC_OFFSET (Bitfield-Mask: 0xff) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_PARAM_Pos (8UL) /*!< LRA_ADC_TEST_PARAM (Bit 8) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_PARAM_Msk (0x100UL) /*!< LRA_ADC_TEST_PARAM (Bitfield-Mask: 0x01) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_IN_SEL_Pos (7UL) /*!< LRA_ADC_TEST_IN_SEL (Bit 7) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_TEST_IN_SEL_Msk (0x80UL) /*!< LRA_ADC_TEST_IN_SEL (Bitfield-Mask: 0x01) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_FREQ_Pos (3UL) /*!< LRA_ADC_FREQ (Bit 3) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_FREQ_Msk (0x78UL) /*!< LRA_ADC_FREQ (Bitfield-Mask: 0x0f) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_SIGN_Pos (2UL) /*!< LRA_ADC_SIGN (Bit 2) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_SIGN_Msk (0x4UL) /*!< LRA_ADC_SIGN (Bitfield-Mask: 0x01) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_MUTE_Pos (1UL) /*!< LRA_ADC_MUTE (Bit 1) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_MUTE_Msk (0x2UL) /*!< LRA_ADC_MUTE (Bitfield-Mask: 0x01) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_START_Pos (0UL) /*!< LRA_ADC_START (Bit 0) */ #define LRA_LRA_ADC_CTRL1_REG_LRA_ADC_START_Msk (0x1UL) /*!< LRA_ADC_START (Bitfield-Mask: 0x01) */ /* ================================================== LRA_ADC_RESULT_REG =================================================== */ #define LRA_LRA_ADC_RESULT_REG_MAN_FLT_IN_Pos (16UL) /*!< MAN_FLT_IN (Bit 16) */ #define LRA_LRA_ADC_RESULT_REG_MAN_FLT_IN_Msk (0xffff0000UL) /*!< MAN_FLT_IN (Bitfield-Mask: 0xffff) */ #define LRA_LRA_ADC_RESULT_REG_GP_ADC_VAL_Pos (0UL) /*!< GP_ADC_VAL (Bit 0) */ #define LRA_LRA_ADC_RESULT_REG_GP_ADC_VAL_Msk (0xffffUL) /*!< GP_ADC_VAL (Bitfield-Mask: 0xffff) */ /* ==================================================== LRA_BRD_HS_REG ===================================================== */ #define LRA_LRA_BRD_HS_REG_TRIM_GAIN_Pos (11UL) /*!< TRIM_GAIN (Bit 11) */ #define LRA_LRA_BRD_HS_REG_TRIM_GAIN_Msk (0x7800UL) /*!< TRIM_GAIN (Bitfield-Mask: 0x0f) */ #define LRA_LRA_BRD_HS_REG_HSGND_TRIM_Pos (8UL) /*!< HSGND_TRIM (Bit 8) */ #define LRA_LRA_BRD_HS_REG_HSGND_TRIM_Msk (0x700UL) /*!< HSGND_TRIM (Bitfield-Mask: 0x07) */ #define LRA_LRA_BRD_HS_REG_SCP_HS_TRIM_Pos (4UL) /*!< SCP_HS_TRIM (Bit 4) */ #define LRA_LRA_BRD_HS_REG_SCP_HS_TRIM_Msk (0xf0UL) /*!< SCP_HS_TRIM (Bitfield-Mask: 0x0f) */ #define LRA_LRA_BRD_HS_REG_SCP_HS_EN_Pos (3UL) /*!< SCP_HS_EN (Bit 3) */ #define LRA_LRA_BRD_HS_REG_SCP_HS_EN_Msk (0x8UL) /*!< SCP_HS_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_HS_REG_ERC_HS_TRIM_Pos (1UL) /*!< ERC_HS_TRIM (Bit 1) */ #define LRA_LRA_BRD_HS_REG_ERC_HS_TRIM_Msk (0x6UL) /*!< ERC_HS_TRIM (Bitfield-Mask: 0x03) */ #define LRA_LRA_BRD_HS_REG_ERC_HS_EN_Pos (0UL) /*!< ERC_HS_EN (Bit 0) */ #define LRA_LRA_BRD_HS_REG_ERC_HS_EN_Msk (0x1UL) /*!< ERC_HS_EN (Bitfield-Mask: 0x01) */ /* ==================================================== LRA_BRD_LS_REG ===================================================== */ #define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_N_Pos (8UL) /*!< SCP_LS_TRIM_N (Bit 8) */ #define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_N_Msk (0xf00UL) /*!< SCP_LS_TRIM_N (Bitfield-Mask: 0x0f) */ #define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_P_Pos (4UL) /*!< SCP_LS_TRIM_P (Bit 4) */ #define LRA_LRA_BRD_LS_REG_SCP_LS_TRIM_P_Msk (0xf0UL) /*!< SCP_LS_TRIM_P (Bitfield-Mask: 0x0f) */ #define LRA_LRA_BRD_LS_REG_SCP_LS_EN_Pos (3UL) /*!< SCP_LS_EN (Bit 3) */ #define LRA_LRA_BRD_LS_REG_SCP_LS_EN_Msk (0x8UL) /*!< SCP_LS_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_LS_REG_ERC_LS_TRIM_Pos (1UL) /*!< ERC_LS_TRIM (Bit 1) */ #define LRA_LRA_BRD_LS_REG_ERC_LS_TRIM_Msk (0x6UL) /*!< ERC_LS_TRIM (Bitfield-Mask: 0x03) */ #define LRA_LRA_BRD_LS_REG_ERC_LS_EN_Pos (0UL) /*!< ERC_LS_EN (Bit 0) */ #define LRA_LRA_BRD_LS_REG_ERC_LS_EN_Msk (0x1UL) /*!< ERC_LS_EN (Bitfield-Mask: 0x01) */ /* =================================================== LRA_BRD_STAT_REG ==================================================== */ #define LRA_LRA_BRD_STAT_REG_SCP_HS_OUT_Pos (13UL) /*!< SCP_HS_OUT (Bit 13) */ #define LRA_LRA_BRD_STAT_REG_SCP_HS_OUT_Msk (0x2000UL) /*!< SCP_HS_OUT (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_N_Pos (12UL) /*!< SCP_LS_COMP_OUT_N (Bit 12) */ #define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_N_Msk (0x1000UL) /*!< SCP_LS_COMP_OUT_N (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_P_Pos (11UL) /*!< SCP_LS_COMP_OUT_P (Bit 11) */ #define LRA_LRA_BRD_STAT_REG_SCP_LS_COMP_OUT_P_Msk (0x800UL) /*!< SCP_LS_COMP_OUT_P (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_SC_EVENT_LS_Pos (10UL) /*!< SC_EVENT_LS (Bit 10) */ #define LRA_LRA_BRD_STAT_REG_SC_EVENT_LS_Msk (0x400UL) /*!< SC_EVENT_LS (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_SC_EVENT_HS_Pos (9UL) /*!< SC_EVENT_HS (Bit 9) */ #define LRA_LRA_BRD_STAT_REG_SC_EVENT_HS_Msk (0x200UL) /*!< SC_EVENT_HS (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_LOOP_STAT_Pos (8UL) /*!< LOOP_STAT (Bit 8) */ #define LRA_LRA_BRD_STAT_REG_LOOP_STAT_Msk (0x100UL) /*!< LOOP_STAT (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_LSN_ON_Pos (7UL) /*!< LSN_ON (Bit 7) */ #define LRA_LRA_BRD_STAT_REG_LSN_ON_Msk (0x80UL) /*!< LSN_ON (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_LSP_ON_Pos (6UL) /*!< LSP_ON (Bit 6) */ #define LRA_LRA_BRD_STAT_REG_LSP_ON_Msk (0x40UL) /*!< LSP_ON (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_HSN_ON_Pos (5UL) /*!< HSN_ON (Bit 5) */ #define LRA_LRA_BRD_STAT_REG_HSN_ON_Msk (0x20UL) /*!< HSN_ON (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_HSP_ON_Pos (4UL) /*!< HSP_ON (Bit 4) */ #define LRA_LRA_BRD_STAT_REG_HSP_ON_Msk (0x10UL) /*!< HSP_ON (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_LSN_STAT_Pos (3UL) /*!< LSN_STAT (Bit 3) */ #define LRA_LRA_BRD_STAT_REG_LSN_STAT_Msk (0x8UL) /*!< LSN_STAT (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_LSP_STAT_Pos (2UL) /*!< LSP_STAT (Bit 2) */ #define LRA_LRA_BRD_STAT_REG_LSP_STAT_Msk (0x4UL) /*!< LSP_STAT (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_HSN_STAT_Pos (1UL) /*!< HSN_STAT (Bit 1) */ #define LRA_LRA_BRD_STAT_REG_HSN_STAT_Msk (0x2UL) /*!< HSN_STAT (Bitfield-Mask: 0x01) */ #define LRA_LRA_BRD_STAT_REG_HSP_STAT_Pos (0UL) /*!< HSP_STAT (Bit 0) */ #define LRA_LRA_BRD_STAT_REG_HSP_STAT_Msk (0x1UL) /*!< HSP_STAT (Bitfield-Mask: 0x01) */ /* ===================================================== LRA_CTRL1_REG ===================================================== */ #define LRA_LRA_CTRL1_REG_SMP_IDX_Pos (24UL) /*!< SMP_IDX (Bit 24) */ #define LRA_LRA_CTRL1_REG_SMP_IDX_Msk (0xf000000UL) /*!< SMP_IDX (Bitfield-Mask: 0x0f) */ #define LRA_LRA_CTRL1_REG_IRQ_SCP_EVENT_EN_Pos (18UL) /*!< IRQ_SCP_EVENT_EN (Bit 18) */ #define LRA_LRA_CTRL1_REG_IRQ_SCP_EVENT_EN_Msk (0x40000UL) /*!< IRQ_SCP_EVENT_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_IRQ_ADC_EN_Pos (17UL) /*!< IRQ_ADC_EN (Bit 17) */ #define LRA_LRA_CTRL1_REG_IRQ_ADC_EN_Msk (0x20000UL) /*!< IRQ_ADC_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_IRQ_CTRL_EN_Pos (16UL) /*!< IRQ_CTRL_EN (Bit 16) */ #define LRA_LRA_CTRL1_REG_IRQ_CTRL_EN_Msk (0x10000UL) /*!< IRQ_CTRL_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_IRQ_IDX_Pos (12UL) /*!< IRQ_IDX (Bit 12) */ #define LRA_LRA_CTRL1_REG_IRQ_IDX_Msk (0xf000UL) /*!< IRQ_IDX (Bitfield-Mask: 0x0f) */ #define LRA_LRA_CTRL1_REG_IRQ_DIV_Pos (8UL) /*!< IRQ_DIV (Bit 8) */ #define LRA_LRA_CTRL1_REG_IRQ_DIV_Msk (0xf00UL) /*!< IRQ_DIV (Bitfield-Mask: 0x0f) */ #define LRA_LRA_CTRL1_REG_SMP_SEL_Pos (6UL) /*!< SMP_SEL (Bit 6) */ #define LRA_LRA_CTRL1_REG_SMP_SEL_Msk (0xc0UL) /*!< SMP_SEL (Bitfield-Mask: 0x03) */ #define LRA_LRA_CTRL1_REG_PULLDOWN_EN_Pos (5UL) /*!< PULLDOWN_EN (Bit 5) */ #define LRA_LRA_CTRL1_REG_PULLDOWN_EN_Msk (0x20UL) /*!< PULLDOWN_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_LOOP_EN_Pos (4UL) /*!< LOOP_EN (Bit 4) */ #define LRA_LRA_CTRL1_REG_LOOP_EN_Msk (0x10UL) /*!< LOOP_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_LDO_EN_Pos (3UL) /*!< LDO_EN (Bit 3) */ #define LRA_LRA_CTRL1_REG_LDO_EN_Msk (0x8UL) /*!< LDO_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_ADC_EN_Pos (2UL) /*!< ADC_EN (Bit 2) */ #define LRA_LRA_CTRL1_REG_ADC_EN_Msk (0x4UL) /*!< ADC_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_HBRIDGE_EN_Pos (1UL) /*!< HBRIDGE_EN (Bit 1) */ #define LRA_LRA_CTRL1_REG_HBRIDGE_EN_Msk (0x2UL) /*!< HBRIDGE_EN (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL1_REG_LRA_EN_Pos (0UL) /*!< LRA_EN (Bit 0) */ #define LRA_LRA_CTRL1_REG_LRA_EN_Msk (0x1UL) /*!< LRA_EN (Bitfield-Mask: 0x01) */ /* ===================================================== LRA_CTRL2_REG ===================================================== */ #define LRA_LRA_CTRL2_REG_HALF_PERIOD_Pos (16UL) /*!< HALF_PERIOD (Bit 16) */ #define LRA_LRA_CTRL2_REG_HALF_PERIOD_Msk (0xffff0000UL) /*!< HALF_PERIOD (Bitfield-Mask: 0xffff) */ #define LRA_LRA_CTRL2_REG_AUTO_MODE_Pos (5UL) /*!< AUTO_MODE (Bit 5) */ #define LRA_LRA_CTRL2_REG_AUTO_MODE_Msk (0x20UL) /*!< AUTO_MODE (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL2_REG_SMP_MODE_Pos (4UL) /*!< SMP_MODE (Bit 4) */ #define LRA_LRA_CTRL2_REG_SMP_MODE_Msk (0x10UL) /*!< SMP_MODE (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL2_REG_POLARITY_Pos (3UL) /*!< POLARITY (Bit 3) */ #define LRA_LRA_CTRL2_REG_POLARITY_Msk (0x8UL) /*!< POLARITY (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL2_REG_FLT_IN_SEL_Pos (2UL) /*!< FLT_IN_SEL (Bit 2) */ #define LRA_LRA_CTRL2_REG_FLT_IN_SEL_Msk (0x4UL) /*!< FLT_IN_SEL (Bitfield-Mask: 0x01) */ #define LRA_LRA_CTRL2_REG_PWM_MODE_Pos (0UL) /*!< PWM_MODE (Bit 0) */ #define LRA_LRA_CTRL2_REG_PWM_MODE_Msk (0x3UL) /*!< PWM_MODE (Bitfield-Mask: 0x03) */ /* ===================================================== LRA_CTRL3_REG ===================================================== */ #define LRA_LRA_CTRL3_REG_VREF_Pos (16UL) /*!< VREF (Bit 16) */ #define LRA_LRA_CTRL3_REG_VREF_Msk (0xffff0000UL) /*!< VREF (Bitfield-Mask: 0xffff) */ #define LRA_LRA_CTRL3_REG_DREF_Pos (0UL) /*!< DREF (Bit 0) */ #define LRA_LRA_CTRL3_REG_DREF_Msk (0xffffUL) /*!< DREF (Bitfield-Mask: 0xffff) */ /* ====================================================== LRA_DFT_REG ====================================================== */ #define LRA_LRA_DFT_REG_SPARE_Pos (29UL) /*!< SPARE (Bit 29) */ #define LRA_LRA_DFT_REG_SPARE_Msk (0xe0000000UL) /*!< SPARE (Bitfield-Mask: 0x07) */ #define LRA_LRA_DFT_REG_SWM_SEL_Pos (28UL) /*!< SWM_SEL (Bit 28) */ #define LRA_LRA_DFT_REG_SWM_SEL_Msk (0x10000000UL) /*!< SWM_SEL (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_SWM_MAN_Pos (27UL) /*!< SWM_MAN (Bit 27) */ #define LRA_LRA_DFT_REG_SWM_MAN_Msk (0x8000000UL) /*!< SWM_MAN (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_PWM_SEL_Pos (26UL) /*!< PWM_SEL (Bit 26) */ #define LRA_LRA_DFT_REG_PWM_SEL_Msk (0x4000000UL) /*!< PWM_SEL (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_PWM_MAN_Pos (25UL) /*!< PWM_MAN (Bit 25) */ #define LRA_LRA_DFT_REG_PWM_MAN_Msk (0x2000000UL) /*!< PWM_MAN (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_TIMER_TRIM_Pos (23UL) /*!< TIMER_TRIM (Bit 23) */ #define LRA_LRA_DFT_REG_TIMER_TRIM_Msk (0x1800000UL) /*!< TIMER_TRIM (Bitfield-Mask: 0x03) */ #define LRA_LRA_DFT_REG_TIMER_SCALE_TRIM_Pos (21UL) /*!< TIMER_SCALE_TRIM (Bit 21) */ #define LRA_LRA_DFT_REG_TIMER_SCALE_TRIM_Msk (0x600000UL) /*!< TIMER_SCALE_TRIM (Bitfield-Mask: 0x03) */ #define LRA_LRA_DFT_REG_DFT_SEL_Pos (20UL) /*!< DFT_SEL (Bit 20) */ #define LRA_LRA_DFT_REG_DFT_SEL_Msk (0x100000UL) /*!< DFT_SEL (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_DFT_FORCE_HSPN_Pos (19UL) /*!< DFT_FORCE_HSPN (Bit 19) */ #define LRA_LRA_DFT_REG_DFT_FORCE_HSPN_Msk (0x80000UL) /*!< DFT_FORCE_HSPN (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_DFT_EN_TIMER_Pos (18UL) /*!< DFT_EN_TIMER (Bit 18) */ #define LRA_LRA_DFT_REG_DFT_EN_TIMER_Msk (0x40000UL) /*!< DFT_EN_TIMER (Bitfield-Mask: 0x01) */ #define LRA_LRA_DFT_REG_DFT_STALL_Pos (16UL) /*!< DFT_STALL (Bit 16) */ #define LRA_LRA_DFT_REG_DFT_STALL_Msk (0x30000UL) /*!< DFT_STALL (Bitfield-Mask: 0x03) */ #define LRA_LRA_DFT_REG_DFT_CTRL_Pos (0UL) /*!< DFT_CTRL (Bit 0) */ #define LRA_LRA_DFT_REG_DFT_CTRL_Msk (0xffffUL) /*!< DFT_CTRL (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_COEF1_REG =================================================== */ #define LRA_LRA_FLT_COEF1_REG_FLT_COEF_01_Pos (16UL) /*!< FLT_COEF_01 (Bit 16) */ #define LRA_LRA_FLT_COEF1_REG_FLT_COEF_01_Msk (0xffff0000UL) /*!< FLT_COEF_01 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_COEF1_REG_FLT_COEF_00_Pos (0UL) /*!< FLT_COEF_00 (Bit 0) */ #define LRA_LRA_FLT_COEF1_REG_FLT_COEF_00_Msk (0xffffUL) /*!< FLT_COEF_00 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_COEF2_REG =================================================== */ #define LRA_LRA_FLT_COEF2_REG_FLT_COEF_10_Pos (16UL) /*!< FLT_COEF_10 (Bit 16) */ #define LRA_LRA_FLT_COEF2_REG_FLT_COEF_10_Msk (0xffff0000UL) /*!< FLT_COEF_10 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_COEF2_REG_FLT_COEF_02_Pos (0UL) /*!< FLT_COEF_02 (Bit 0) */ #define LRA_LRA_FLT_COEF2_REG_FLT_COEF_02_Msk (0xffffUL) /*!< FLT_COEF_02 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_COEF3_REG =================================================== */ #define LRA_LRA_FLT_COEF3_REG_FLT_COEF_12_Pos (16UL) /*!< FLT_COEF_12 (Bit 16) */ #define LRA_LRA_FLT_COEF3_REG_FLT_COEF_12_Msk (0xffff0000UL) /*!< FLT_COEF_12 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_COEF3_REG_FLT_COEF_11_Pos (0UL) /*!< FLT_COEF_11 (Bit 0) */ #define LRA_LRA_FLT_COEF3_REG_FLT_COEF_11_Msk (0xffffUL) /*!< FLT_COEF_11 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP1_REG ==================================================== */ #define LRA_LRA_FLT_SMP1_REG_LRA_SMP_2_Pos (16UL) /*!< LRA_SMP_2 (Bit 16) */ #define LRA_LRA_FLT_SMP1_REG_LRA_SMP_2_Msk (0xffff0000UL) /*!< LRA_SMP_2 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP1_REG_LRA_SMP_1_Pos (0UL) /*!< LRA_SMP_1 (Bit 0) */ #define LRA_LRA_FLT_SMP1_REG_LRA_SMP_1_Msk (0xffffUL) /*!< LRA_SMP_1 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP2_REG ==================================================== */ #define LRA_LRA_FLT_SMP2_REG_LRA_SMP_4_Pos (16UL) /*!< LRA_SMP_4 (Bit 16) */ #define LRA_LRA_FLT_SMP2_REG_LRA_SMP_4_Msk (0xffff0000UL) /*!< LRA_SMP_4 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP2_REG_LRA_SMP_3_Pos (0UL) /*!< LRA_SMP_3 (Bit 0) */ #define LRA_LRA_FLT_SMP2_REG_LRA_SMP_3_Msk (0xffffUL) /*!< LRA_SMP_3 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP3_REG ==================================================== */ #define LRA_LRA_FLT_SMP3_REG_LRA_SMP_6_Pos (16UL) /*!< LRA_SMP_6 (Bit 16) */ #define LRA_LRA_FLT_SMP3_REG_LRA_SMP_6_Msk (0xffff0000UL) /*!< LRA_SMP_6 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP3_REG_LRA_SMP_5_Pos (0UL) /*!< LRA_SMP_5 (Bit 0) */ #define LRA_LRA_FLT_SMP3_REG_LRA_SMP_5_Msk (0xffffUL) /*!< LRA_SMP_5 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP4_REG ==================================================== */ #define LRA_LRA_FLT_SMP4_REG_LRA_SMP_8_Pos (16UL) /*!< LRA_SMP_8 (Bit 16) */ #define LRA_LRA_FLT_SMP4_REG_LRA_SMP_8_Msk (0xffff0000UL) /*!< LRA_SMP_8 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP4_REG_LRA_SMP_7_Pos (0UL) /*!< LRA_SMP_7 (Bit 0) */ #define LRA_LRA_FLT_SMP4_REG_LRA_SMP_7_Msk (0xffffUL) /*!< LRA_SMP_7 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP5_REG ==================================================== */ #define LRA_LRA_FLT_SMP5_REG_LRA_SMP_10_Pos (16UL) /*!< LRA_SMP_10 (Bit 16) */ #define LRA_LRA_FLT_SMP5_REG_LRA_SMP_10_Msk (0xffff0000UL) /*!< LRA_SMP_10 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP5_REG_LRA_SMP_9_Pos (0UL) /*!< LRA_SMP_9 (Bit 0) */ #define LRA_LRA_FLT_SMP5_REG_LRA_SMP_9_Msk (0xffffUL) /*!< LRA_SMP_9 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP6_REG ==================================================== */ #define LRA_LRA_FLT_SMP6_REG_LRA_SMP_12_Pos (16UL) /*!< LRA_SMP_12 (Bit 16) */ #define LRA_LRA_FLT_SMP6_REG_LRA_SMP_12_Msk (0xffff0000UL) /*!< LRA_SMP_12 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP6_REG_LRA_SMP_11_Pos (0UL) /*!< LRA_SMP_11 (Bit 0) */ #define LRA_LRA_FLT_SMP6_REG_LRA_SMP_11_Msk (0xffffUL) /*!< LRA_SMP_11 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP7_REG ==================================================== */ #define LRA_LRA_FLT_SMP7_REG_LRA_SMP_14_Pos (16UL) /*!< LRA_SMP_14 (Bit 16) */ #define LRA_LRA_FLT_SMP7_REG_LRA_SMP_14_Msk (0xffff0000UL) /*!< LRA_SMP_14 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP7_REG_LRA_SMP_13_Pos (0UL) /*!< LRA_SMP_13 (Bit 0) */ #define LRA_LRA_FLT_SMP7_REG_LRA_SMP_13_Msk (0xffffUL) /*!< LRA_SMP_13 (Bitfield-Mask: 0xffff) */ /* =================================================== LRA_FLT_SMP8_REG ==================================================== */ #define LRA_LRA_FLT_SMP8_REG_LRA_SMP_16_Pos (16UL) /*!< LRA_SMP_16 (Bit 16) */ #define LRA_LRA_FLT_SMP8_REG_LRA_SMP_16_Msk (0xffff0000UL) /*!< LRA_SMP_16 (Bitfield-Mask: 0xffff) */ #define LRA_LRA_FLT_SMP8_REG_LRA_SMP_15_Pos (0UL) /*!< LRA_SMP_15 (Bit 0) */ #define LRA_LRA_FLT_SMP8_REG_LRA_SMP_15_Msk (0xffffUL) /*!< LRA_SMP_15 (Bitfield-Mask: 0xffff) */ /* ====================================================== LRA_LDO_REG ====================================================== */ #define LRA_LRA_LDO_REG_LDO_OK_Pos (31UL) /*!< LDO_OK (Bit 31) */ #define LRA_LRA_LDO_REG_LDO_OK_Msk (0x80000000UL) /*!< LDO_OK (Bitfield-Mask: 0x01) */ #define LRA_LRA_LDO_REG_LDO_TST_Pos (1UL) /*!< LDO_TST (Bit 1) */ #define LRA_LRA_LDO_REG_LDO_TST_Msk (0x2UL) /*!< LDO_TST (Bitfield-Mask: 0x01) */ #define LRA_LRA_LDO_REG_LDO_VREF_HOLD_Pos (0UL) /*!< LDO_VREF_HOLD (Bit 0) */ #define LRA_LRA_LDO_REG_LDO_VREF_HOLD_Msk (0x1UL) /*!< LDO_VREF_HOLD (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ MEMCTRL ================ */ /* =========================================================================================================================== */ /* ==================================================== BUSY_RESET_REG ===================================================== */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ #define MEMCTRL_BUSY_RESET_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ /* ===================================================== BUSY_SET_REG ====================================================== */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ #define MEMCTRL_BUSY_SET_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ #define MEMCTRL_BUSY_SET_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ #define MEMCTRL_BUSY_SET_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ #define MEMCTRL_BUSY_SET_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ #define MEMCTRL_BUSY_SET_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ #define MEMCTRL_BUSY_SET_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ #define MEMCTRL_BUSY_SET_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ #define MEMCTRL_BUSY_SET_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ #define MEMCTRL_BUSY_SET_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ #define MEMCTRL_BUSY_SET_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ /* ===================================================== BUSY_STAT_REG ===================================================== */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPARE_Pos (30UL) /*!< BUSY_SPARE (Bit 30) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPARE_Msk (0xc0000000UL) /*!< BUSY_SPARE (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_MOTOR_Pos (28UL) /*!< BUSY_MOTOR (Bit 28) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_MOTOR_Msk (0x30000000UL) /*!< BUSY_MOTOR (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER2_Pos (26UL) /*!< BUSY_TIMER2 (Bit 26) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER2_Msk (0xc000000UL) /*!< BUSY_TIMER2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER_Pos (24UL) /*!< BUSY_TIMER (Bit 24) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_TIMER_Msk (0x3000000UL) /*!< BUSY_TIMER (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART3_Pos (22UL) /*!< BUSY_UART3 (Bit 22) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART3_Msk (0xc00000UL) /*!< BUSY_UART3 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_GPADC_Pos (20UL) /*!< BUSY_GPADC (Bit 20) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_GPADC_Msk (0x300000UL) /*!< BUSY_GPADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_PDM_Pos (18UL) /*!< BUSY_PDM (Bit 18) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_PDM_Msk (0xc0000UL) /*!< BUSY_PDM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SRC_Pos (16UL) /*!< BUSY_SRC (Bit 16) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SRC_Msk (0x30000UL) /*!< BUSY_SRC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_PCM_Pos (14UL) /*!< BUSY_PCM (Bit 14) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_PCM_Msk (0xc000UL) /*!< BUSY_PCM (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SDADC_Pos (12UL) /*!< BUSY_SDADC (Bit 12) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SDADC_Msk (0x3000UL) /*!< BUSY_SDADC (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_I2C2_Pos (10UL) /*!< BUSY_I2C2 (Bit 10) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_I2C2_Msk (0xc00UL) /*!< BUSY_I2C2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_I2C_Pos (8UL) /*!< BUSY_I2C (Bit 8) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_I2C_Msk (0x300UL) /*!< BUSY_I2C (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPI2_Pos (6UL) /*!< BUSY_SPI2 (Bit 6) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPI2_Msk (0xc0UL) /*!< BUSY_SPI2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPI_Pos (4UL) /*!< BUSY_SPI (Bit 4) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_SPI_Msk (0x30UL) /*!< BUSY_SPI (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART2_Pos (2UL) /*!< BUSY_UART2 (Bit 2) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART2_Msk (0xcUL) /*!< BUSY_UART2 (Bitfield-Mask: 0x03) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART_Pos (0UL) /*!< BUSY_UART (Bit 0) */ #define MEMCTRL_BUSY_STAT_REG_BUSY_UART_Msk (0x3UL) /*!< BUSY_UART (Bitfield-Mask: 0x03) */ /* =================================================== CMI_CODE_BASE_REG =================================================== */ #define MEMCTRL_CMI_CODE_BASE_REG_CMI_CODE_BASE_ADDR_Pos (10UL) /*!< CMI_CODE_BASE_ADDR (Bit 10) */ #define MEMCTRL_CMI_CODE_BASE_REG_CMI_CODE_BASE_ADDR_Msk (0x7fc00UL) /*!< CMI_CODE_BASE_ADDR (Bitfield-Mask: 0x1ff) */ /* =================================================== CMI_DATA_BASE_REG =================================================== */ #define MEMCTRL_CMI_DATA_BASE_REG_CMI_DATA_BASE_ADDR_Pos (2UL) /*!< CMI_DATA_BASE_ADDR (Bit 2) */ #define MEMCTRL_CMI_DATA_BASE_REG_CMI_DATA_BASE_ADDR_Msk (0x7fffcUL) /*!< CMI_DATA_BASE_ADDR (Bitfield-Mask: 0x1ffff) */ /* ====================================================== CMI_END_REG ====================================================== */ #define MEMCTRL_CMI_END_REG_CMI_END_ADDR_Pos (10UL) /*!< CMI_END_ADDR (Bit 10) */ #define MEMCTRL_CMI_END_REG_CMI_END_ADDR_Msk (0x7fc00UL) /*!< CMI_END_ADDR (Bitfield-Mask: 0x1ff) */ /* ================================================== CMI_SHARED_BASE_REG ================================================== */ #define MEMCTRL_CMI_SHARED_BASE_REG_CMI_SHARED_BASE_ADDR_Pos (10UL) /*!< CMI_SHARED_BASE_ADDR (Bit 10) */ #define MEMCTRL_CMI_SHARED_BASE_REG_CMI_SHARED_BASE_ADDR_Msk (0x7fc00UL) /*!< CMI_SHARED_BASE_ADDR (Bitfield-Mask: 0x1ff) */ /* ===================================================== MEM_PRIO_REG ====================================================== */ #define MEMCTRL_MEM_PRIO_REG_AHB_PRIO_Pos (4UL) /*!< AHB_PRIO (Bit 4) */ #define MEMCTRL_MEM_PRIO_REG_AHB_PRIO_Msk (0x30UL) /*!< AHB_PRIO (Bitfield-Mask: 0x03) */ #define MEMCTRL_MEM_PRIO_REG_AHB2_PRIO_Pos (2UL) /*!< AHB2_PRIO (Bit 2) */ #define MEMCTRL_MEM_PRIO_REG_AHB2_PRIO_Msk (0xcUL) /*!< AHB2_PRIO (Bitfield-Mask: 0x03) */ #define MEMCTRL_MEM_PRIO_REG_SNC_PRIO_Pos (0UL) /*!< SNC_PRIO (Bit 0) */ #define MEMCTRL_MEM_PRIO_REG_SNC_PRIO_Msk (0x3UL) /*!< SNC_PRIO (Bitfield-Mask: 0x03) */ /* ===================================================== MEM_STALL_REG ===================================================== */ #define MEMCTRL_MEM_STALL_REG_AHB_MAX_STALL_Pos (8UL) /*!< AHB_MAX_STALL (Bit 8) */ #define MEMCTRL_MEM_STALL_REG_AHB_MAX_STALL_Msk (0xf00UL) /*!< AHB_MAX_STALL (Bitfield-Mask: 0x0f) */ #define MEMCTRL_MEM_STALL_REG_AHB2_MAX_STALL_Pos (4UL) /*!< AHB2_MAX_STALL (Bit 4) */ #define MEMCTRL_MEM_STALL_REG_AHB2_MAX_STALL_Msk (0xf0UL) /*!< AHB2_MAX_STALL (Bitfield-Mask: 0x0f) */ #define MEMCTRL_MEM_STALL_REG_SNC_MAX_STALL_Pos (0UL) /*!< SNC_MAX_STALL (Bit 0) */ #define MEMCTRL_MEM_STALL_REG_SNC_MAX_STALL_Msk (0xfUL) /*!< SNC_MAX_STALL (Bitfield-Mask: 0x0f) */ /* ==================================================== MEM_STATUS2_REG ==================================================== */ #define MEMCTRL_MEM_STATUS2_REG_RAM8_OFF_BUT_ACCESS_Pos (7UL) /*!< RAM8_OFF_BUT_ACCESS (Bit 7) */ #define MEMCTRL_MEM_STATUS2_REG_RAM8_OFF_BUT_ACCESS_Msk (0x80UL) /*!< RAM8_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM7_OFF_BUT_ACCESS_Pos (6UL) /*!< RAM7_OFF_BUT_ACCESS (Bit 6) */ #define MEMCTRL_MEM_STATUS2_REG_RAM7_OFF_BUT_ACCESS_Msk (0x40UL) /*!< RAM7_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM6_OFF_BUT_ACCESS_Pos (5UL) /*!< RAM6_OFF_BUT_ACCESS (Bit 5) */ #define MEMCTRL_MEM_STATUS2_REG_RAM6_OFF_BUT_ACCESS_Msk (0x20UL) /*!< RAM6_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM5_OFF_BUT_ACCESS_Pos (4UL) /*!< RAM5_OFF_BUT_ACCESS (Bit 4) */ #define MEMCTRL_MEM_STATUS2_REG_RAM5_OFF_BUT_ACCESS_Msk (0x10UL) /*!< RAM5_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM4_OFF_BUT_ACCESS_Pos (3UL) /*!< RAM4_OFF_BUT_ACCESS (Bit 3) */ #define MEMCTRL_MEM_STATUS2_REG_RAM4_OFF_BUT_ACCESS_Msk (0x8UL) /*!< RAM4_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM3_OFF_BUT_ACCESS_Pos (2UL) /*!< RAM3_OFF_BUT_ACCESS (Bit 2) */ #define MEMCTRL_MEM_STATUS2_REG_RAM3_OFF_BUT_ACCESS_Msk (0x4UL) /*!< RAM3_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM2_OFF_BUT_ACCESS_Pos (1UL) /*!< RAM2_OFF_BUT_ACCESS (Bit 1) */ #define MEMCTRL_MEM_STATUS2_REG_RAM2_OFF_BUT_ACCESS_Msk (0x2UL) /*!< RAM2_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS2_REG_RAM1_OFF_BUT_ACCESS_Pos (0UL) /*!< RAM1_OFF_BUT_ACCESS (Bit 0) */ #define MEMCTRL_MEM_STATUS2_REG_RAM1_OFF_BUT_ACCESS_Msk (0x1UL) /*!< RAM1_OFF_BUT_ACCESS (Bitfield-Mask: 0x01) */ /* ==================================================== MEM_STATUS_REG ===================================================== */ #define MEMCTRL_MEM_STATUS_REG_CMI_CLEAR_READY_Pos (13UL) /*!< CMI_CLEAR_READY (Bit 13) */ #define MEMCTRL_MEM_STATUS_REG_CMI_CLEAR_READY_Msk (0x2000UL) /*!< CMI_CLEAR_READY (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS_REG_CMI_NOT_READY_Pos (12UL) /*!< CMI_NOT_READY (Bit 12) */ #define MEMCTRL_MEM_STATUS_REG_CMI_NOT_READY_Msk (0x1000UL) /*!< CMI_NOT_READY (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_WR_BUFF_CNT_Pos (8UL) /*!< AHB2_WR_BUFF_CNT (Bit 8) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_WR_BUFF_CNT_Msk (0xf00UL) /*!< AHB2_WR_BUFF_CNT (Bitfield-Mask: 0x0f) */ #define MEMCTRL_MEM_STATUS_REG_AHB_WR_BUFF_CNT_Pos (4UL) /*!< AHB_WR_BUFF_CNT (Bit 4) */ #define MEMCTRL_MEM_STATUS_REG_AHB_WR_BUFF_CNT_Msk (0xf0UL) /*!< AHB_WR_BUFF_CNT (Bitfield-Mask: 0x0f) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_CLR_WR_BUFF_Pos (3UL) /*!< AHB2_CLR_WR_BUFF (Bit 3) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_CLR_WR_BUFF_Msk (0x8UL) /*!< AHB2_CLR_WR_BUFF (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS_REG_AHB_CLR_WR_BUFF_Pos (2UL) /*!< AHB_CLR_WR_BUFF (Bit 2) */ #define MEMCTRL_MEM_STATUS_REG_AHB_CLR_WR_BUFF_Msk (0x4UL) /*!< AHB_CLR_WR_BUFF (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_WRITE_BUFF_Pos (1UL) /*!< AHB2_WRITE_BUFF (Bit 1) */ #define MEMCTRL_MEM_STATUS_REG_AHB2_WRITE_BUFF_Msk (0x2UL) /*!< AHB2_WRITE_BUFF (Bitfield-Mask: 0x01) */ #define MEMCTRL_MEM_STATUS_REG_AHB_WRITE_BUFF_Pos (0UL) /*!< AHB_WRITE_BUFF (Bit 0) */ #define MEMCTRL_MEM_STATUS_REG_AHB_WRITE_BUFF_Msk (0x1UL) /*!< AHB_WRITE_BUFF (Bitfield-Mask: 0x01) */ /* ===================================================== SNC_BASE_REG ====================================================== */ #define MEMCTRL_SNC_BASE_REG_SNC_BASE_ADDRESS_Pos (2UL) /*!< SNC_BASE_ADDRESS (Bit 2) */ #define MEMCTRL_SNC_BASE_REG_SNC_BASE_ADDRESS_Msk (0x7fffcUL) /*!< SNC_BASE_ADDRESS (Bitfield-Mask: 0x1ffff) */ /* =========================================================================================================================== */ /* ================ OTPC ================ */ /* =========================================================================================================================== */ /* ===================================================== OTPC_MODE_REG ===================================================== */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_PRG_SEL_Pos (6UL) /*!< OTPC_MODE_PRG_SEL (Bit 6) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_PRG_SEL_Msk (0xc0UL) /*!< OTPC_MODE_PRG_SEL (Bitfield-Mask: 0x03) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_HT_MARG_EN_Pos (5UL) /*!< OTPC_MODE_HT_MARG_EN (Bit 5) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_HT_MARG_EN_Msk (0x20UL) /*!< OTPC_MODE_HT_MARG_EN (Bitfield-Mask: 0x01) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_USE_TST_ROW_Pos (4UL) /*!< OTPC_MODE_USE_TST_ROW (Bit 4) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_USE_TST_ROW_Msk (0x10UL) /*!< OTPC_MODE_USE_TST_ROW (Bitfield-Mask: 0x01) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Pos (0UL) /*!< OTPC_MODE_MODE (Bit 0) */ #define OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Msk (0x7UL) /*!< OTPC_MODE_MODE (Bitfield-Mask: 0x07) */ /* ==================================================== OTPC_PADDR_REG ===================================================== */ #define OTPC_OTPC_PADDR_REG_OTPC_PADDR_Pos (0UL) /*!< OTPC_PADDR (Bit 0) */ #define OTPC_OTPC_PADDR_REG_OTPC_PADDR_Msk (0x3ffUL) /*!< OTPC_PADDR (Bitfield-Mask: 0x3ff) */ /* ==================================================== OTPC_PWORD_REG ===================================================== */ #define OTPC_OTPC_PWORD_REG_OTPC_PWORD_Pos (0UL) /*!< OTPC_PWORD (Bit 0) */ #define OTPC_OTPC_PWORD_REG_OTPC_PWORD_Msk (0xffffffffUL) /*!< OTPC_PWORD (Bitfield-Mask: 0xffffffff) */ /* ===================================================== OTPC_STAT_REG ===================================================== */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_MRDY_Pos (2UL) /*!< OTPC_STAT_MRDY (Bit 2) */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_MRDY_Msk (0x4UL) /*!< OTPC_STAT_MRDY (Bitfield-Mask: 0x01) */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_PBUF_EMPTY_Pos (1UL) /*!< OTPC_STAT_PBUF_EMPTY (Bit 1) */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_PBUF_EMPTY_Msk (0x2UL) /*!< OTPC_STAT_PBUF_EMPTY (Bitfield-Mask: 0x01) */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_PRDY_Pos (0UL) /*!< OTPC_STAT_PRDY (Bit 0) */ #define OTPC_OTPC_STAT_REG_OTPC_STAT_PRDY_Msk (0x1UL) /*!< OTPC_STAT_PRDY (Bitfield-Mask: 0x01) */ /* ===================================================== OTPC_TIM1_REG ===================================================== */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CSP_Pos (24UL) /*!< OTPC_TIM1_US_T_CSP (Bit 24) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CSP_Msk (0x7f000000UL) /*!< OTPC_TIM1_US_T_CSP (Bitfield-Mask: 0x7f) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CS_Pos (20UL) /*!< OTPC_TIM1_US_T_CS (Bit 20) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_CS_Msk (0xf00000UL) /*!< OTPC_TIM1_US_T_CS (Bitfield-Mask: 0x0f) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_PL_Pos (16UL) /*!< OTPC_TIM1_US_T_PL (Bit 16) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_US_T_PL_Msk (0xf0000UL) /*!< OTPC_TIM1_US_T_PL (Bitfield-Mask: 0x0f) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_RD_Pos (12UL) /*!< OTPC_TIM1_CC_T_RD (Bit 12) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_RD_Msk (0x7000UL) /*!< OTPC_TIM1_CC_T_RD (Bitfield-Mask: 0x07) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_20NS_Pos (8UL) /*!< OTPC_TIM1_CC_T_20NS (Bit 8) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_20NS_Msk (0x300UL) /*!< OTPC_TIM1_CC_T_20NS (Bitfield-Mask: 0x03) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos (0UL) /*!< OTPC_TIM1_CC_T_1US (Bit 0) */ #define OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Msk (0x7fUL) /*!< OTPC_TIM1_CC_T_1US (Bitfield-Mask: 0x7f) */ /* ===================================================== OTPC_TIM2_REG ===================================================== */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_ADD_CC_EN_Pos (31UL) /*!< OTPC_TIM2_US_ADD_CC_EN (Bit 31) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_ADD_CC_EN_Msk (0x80000000UL) /*!< OTPC_TIM2_US_ADD_CC_EN (Bitfield-Mask: 0x01) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_SAS_Pos (29UL) /*!< OTPC_TIM2_US_T_SAS (Bit 29) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_SAS_Msk (0x60000000UL) /*!< OTPC_TIM2_US_T_SAS (Bitfield-Mask: 0x03) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPH_Pos (24UL) /*!< OTPC_TIM2_US_T_PPH (Bit 24) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPH_Msk (0x1f000000UL) /*!< OTPC_TIM2_US_T_PPH (Bitfield-Mask: 0x1f) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_VDS_Pos (21UL) /*!< OTPC_TIM2_US_T_VDS (Bit 21) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_VDS_Msk (0xe00000UL) /*!< OTPC_TIM2_US_T_VDS (Bitfield-Mask: 0x07) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPS_Pos (16UL) /*!< OTPC_TIM2_US_T_PPS (Bit 16) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPS_Msk (0x1f0000UL) /*!< OTPC_TIM2_US_T_PPS (Bitfield-Mask: 0x1f) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPR_Pos (8UL) /*!< OTPC_TIM2_US_T_PPR (Bit 8) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PPR_Msk (0x7f00UL) /*!< OTPC_TIM2_US_T_PPR (Bitfield-Mask: 0x7f) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PWI_Pos (5UL) /*!< OTPC_TIM2_US_T_PWI (Bit 5) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PWI_Msk (0xe0UL) /*!< OTPC_TIM2_US_T_PWI (Bitfield-Mask: 0x07) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PW_Pos (0UL) /*!< OTPC_TIM2_US_T_PW (Bit 0) */ #define OTPC_OTPC_TIM2_REG_OTPC_TIM2_US_T_PW_Msk (0x1fUL) /*!< OTPC_TIM2_US_T_PW (Bitfield-Mask: 0x1f) */ /* =========================================================================================================================== */ /* ================ PDC ================ */ /* =========================================================================================================================== */ /* ================================================== PDC_ACKNOWLEDGE_REG ================================================== */ #define PDC_PDC_ACKNOWLEDGE_REG_PDC_ACKNOWLEDGE_Pos (0UL) /*!< PDC_ACKNOWLEDGE (Bit 0) */ #define PDC_PDC_ACKNOWLEDGE_REG_PDC_ACKNOWLEDGE_Msk (0x1fUL) /*!< PDC_ACKNOWLEDGE (Bitfield-Mask: 0x1f) */ /* ===================================================== PDC_CTRL0_REG ===================================================== */ #define PDC_PDC_CTRL0_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL0_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL0_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL0_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL0_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL0_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL0_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL0_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL0_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL0_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL0_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL0_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL0_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL0_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL10_REG ===================================================== */ #define PDC_PDC_CTRL10_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL10_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL10_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL10_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL10_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL10_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL10_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL10_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL10_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL10_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL10_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL10_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL10_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL10_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL11_REG ===================================================== */ #define PDC_PDC_CTRL11_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL11_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL11_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL11_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL11_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL11_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL11_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL11_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL11_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL11_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL11_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL11_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL11_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL11_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL12_REG ===================================================== */ #define PDC_PDC_CTRL12_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL12_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL12_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL12_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL12_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL12_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL12_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL12_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL12_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL12_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL12_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL12_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL12_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL12_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL13_REG ===================================================== */ #define PDC_PDC_CTRL13_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL13_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL13_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL13_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL13_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL13_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL13_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL13_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL13_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL13_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL13_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL13_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL13_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL13_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL14_REG ===================================================== */ #define PDC_PDC_CTRL14_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL14_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL14_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL14_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL14_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL14_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL14_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL14_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL14_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL14_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL14_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL14_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL14_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL14_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ==================================================== PDC_CTRL15_REG ===================================================== */ #define PDC_PDC_CTRL15_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL15_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL15_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL15_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL15_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL15_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL15_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL15_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL15_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL15_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL15_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL15_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL15_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL15_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL1_REG ===================================================== */ #define PDC_PDC_CTRL1_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL1_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL1_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL1_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL1_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL1_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL1_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL1_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL1_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL1_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL1_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL1_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL1_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL1_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL2_REG ===================================================== */ #define PDC_PDC_CTRL2_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL2_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL2_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL2_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL2_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL2_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL2_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL2_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL2_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL2_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL2_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL2_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL2_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL2_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL3_REG ===================================================== */ #define PDC_PDC_CTRL3_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL3_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL3_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL3_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL3_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL3_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL3_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL3_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL3_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL3_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL3_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL3_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL3_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL3_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL4_REG ===================================================== */ #define PDC_PDC_CTRL4_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL4_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL4_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL4_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL4_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL4_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL4_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL4_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL4_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL4_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL4_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL4_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL4_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL4_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL5_REG ===================================================== */ #define PDC_PDC_CTRL5_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL5_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL5_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL5_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL5_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL5_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL5_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL5_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL5_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL5_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL5_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL5_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL5_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL5_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL6_REG ===================================================== */ #define PDC_PDC_CTRL6_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL6_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL6_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL6_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL6_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL6_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL6_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL6_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL6_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL6_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL6_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL6_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL6_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL6_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL7_REG ===================================================== */ #define PDC_PDC_CTRL7_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL7_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL7_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL7_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL7_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL7_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL7_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL7_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL7_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL7_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL7_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL7_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL7_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL7_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL8_REG ===================================================== */ #define PDC_PDC_CTRL8_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL8_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL8_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL8_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL8_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL8_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL8_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL8_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL8_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL8_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL8_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL8_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL8_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL8_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ===================================================== PDC_CTRL9_REG ===================================================== */ #define PDC_PDC_CTRL9_REG_PDC_MASTER_Pos (11UL) /*!< PDC_MASTER (Bit 11) */ #define PDC_PDC_CTRL9_REG_PDC_MASTER_Msk (0x1800UL) /*!< PDC_MASTER (Bitfield-Mask: 0x03) */ #define PDC_PDC_CTRL9_REG_EN_COM_Pos (10UL) /*!< EN_COM (Bit 10) */ #define PDC_PDC_CTRL9_REG_EN_COM_Msk (0x400UL) /*!< EN_COM (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL9_REG_EN_PER_Pos (9UL) /*!< EN_PER (Bit 9) */ #define PDC_PDC_CTRL9_REG_EN_PER_Msk (0x200UL) /*!< EN_PER (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL9_REG_EN_TMR_Pos (8UL) /*!< EN_TMR (Bit 8) */ #define PDC_PDC_CTRL9_REG_EN_TMR_Msk (0x100UL) /*!< EN_TMR (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL9_REG_EN_XTAL_Pos (7UL) /*!< EN_XTAL (Bit 7) */ #define PDC_PDC_CTRL9_REG_EN_XTAL_Msk (0x80UL) /*!< EN_XTAL (Bitfield-Mask: 0x01) */ #define PDC_PDC_CTRL9_REG_TRIG_ID_Pos (2UL) /*!< TRIG_ID (Bit 2) */ #define PDC_PDC_CTRL9_REG_TRIG_ID_Msk (0x7cUL) /*!< TRIG_ID (Bitfield-Mask: 0x1f) */ #define PDC_PDC_CTRL9_REG_TRIG_SELECT_Pos (0UL) /*!< TRIG_SELECT (Bit 0) */ #define PDC_PDC_CTRL9_REG_TRIG_SELECT_Msk (0x3UL) /*!< TRIG_SELECT (Bitfield-Mask: 0x03) */ /* ================================================= PDC_PENDING_CM33_REG ================================================== */ #define PDC_PDC_PENDING_CM33_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ #define PDC_PDC_PENDING_CM33_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ /* ================================================= PDC_PENDING_CMAC_REG ================================================== */ #define PDC_PDC_PENDING_CMAC_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ #define PDC_PDC_PENDING_CMAC_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ /* ==================================================== PDC_PENDING_REG ==================================================== */ #define PDC_PDC_PENDING_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ #define PDC_PDC_PENDING_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ /* ================================================== PDC_PENDING_SNC_REG ================================================== */ #define PDC_PDC_PENDING_SNC_REG_PDC_PENDING_Pos (0UL) /*!< PDC_PENDING (Bit 0) */ #define PDC_PDC_PENDING_SNC_REG_PDC_PENDING_Msk (0xffffUL) /*!< PDC_PENDING (Bitfield-Mask: 0xffff) */ /* ================================================== PDC_SET_PENDING_REG ================================================== */ #define PDC_PDC_SET_PENDING_REG_PDC_SET_PENDING_Pos (0UL) /*!< PDC_SET_PENDING (Bit 0) */ #define PDC_PDC_SET_PENDING_REG_PDC_SET_PENDING_Msk (0x1fUL) /*!< PDC_SET_PENDING (Bitfield-Mask: 0x1f) */ /* =========================================================================================================================== */ /* ================ PWMLED ================ */ /* =========================================================================================================================== */ /* ==================================================== PWMLED_CTRL_REG ==================================================== */ #define PWMLED_PWMLED_CTRL_REG_LED2_LOAD_SEL_Pos (11UL) /*!< LED2_LOAD_SEL (Bit 11) */ #define PWMLED_PWMLED_CTRL_REG_LED2_LOAD_SEL_Msk (0x3800UL) /*!< LED2_LOAD_SEL (Bitfield-Mask: 0x07) */ #define PWMLED_PWMLED_CTRL_REG_LED1_LOAD_SEL_Pos (8UL) /*!< LED1_LOAD_SEL (Bit 8) */ #define PWMLED_PWMLED_CTRL_REG_LED1_LOAD_SEL_Msk (0x700UL) /*!< LED1_LOAD_SEL (Bitfield-Mask: 0x07) */ #define PWMLED_PWMLED_CTRL_REG_LED2_EN_Pos (7UL) /*!< LED2_EN (Bit 7) */ #define PWMLED_PWMLED_CTRL_REG_LED2_EN_Msk (0x80UL) /*!< LED2_EN (Bitfield-Mask: 0x01) */ #define PWMLED_PWMLED_CTRL_REG_LED1_EN_Pos (6UL) /*!< LED1_EN (Bit 6) */ #define PWMLED_PWMLED_CTRL_REG_LED1_EN_Msk (0x40UL) /*!< LED1_EN (Bitfield-Mask: 0x01) */ #define PWMLED_PWMLED_CTRL_REG_LED_TRIM_Pos (2UL) /*!< LED_TRIM (Bit 2) */ #define PWMLED_PWMLED_CTRL_REG_LED_TRIM_Msk (0x3cUL) /*!< LED_TRIM (Bitfield-Mask: 0x0f) */ #define PWMLED_PWMLED_CTRL_REG_SW_PAUSE_EN_Pos (1UL) /*!< SW_PAUSE_EN (Bit 1) */ #define PWMLED_PWMLED_CTRL_REG_SW_PAUSE_EN_Msk (0x2UL) /*!< SW_PAUSE_EN (Bitfield-Mask: 0x01) */ #define PWMLED_PWMLED_CTRL_REG_PWM_ENABLE_Pos (0UL) /*!< PWM_ENABLE (Bit 0) */ #define PWMLED_PWMLED_CTRL_REG_PWM_ENABLE_Msk (0x1UL) /*!< PWM_ENABLE (Bitfield-Mask: 0x01) */ /* ============================================== PWMLED_DUTY_CYCLE_LED1_REG =============================================== */ #define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_START_CYCLE_Pos (8UL) /*!< LED1_PWM_START_CYCLE (Bit 8) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_START_CYCLE_Msk (0xff00UL) /*!< LED1_PWM_START_CYCLE (Bitfield-Mask: 0xff) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_END_CYCLE_Pos (0UL) /*!< LED1_PWM_END_CYCLE (Bit 0) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED1_REG_LED1_PWM_END_CYCLE_Msk (0xffUL) /*!< LED1_PWM_END_CYCLE (Bitfield-Mask: 0xff) */ /* ============================================== PWMLED_DUTY_CYCLE_LED2_REG =============================================== */ #define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_START_CYCLE_Pos (8UL) /*!< LED2_PWM_START_CYCLE (Bit 8) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_START_CYCLE_Msk (0xff00UL) /*!< LED2_PWM_START_CYCLE (Bitfield-Mask: 0xff) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_END_CYCLE_Pos (0UL) /*!< LED2_PWM_END_CYCLE (Bit 0) */ #define PWMLED_PWMLED_DUTY_CYCLE_LED2_REG_LED2_PWM_END_CYCLE_Msk (0xffUL) /*!< LED2_PWM_END_CYCLE (Bitfield-Mask: 0xff) */ /* ================================================= PWMLED_FREQUENCY_REG ================================================== */ #define PWMLED_PWMLED_FREQUENCY_REG_LED_PWM_FREQUENCY_Pos (0UL) /*!< LED_PWM_FREQUENCY (Bit 0) */ #define PWMLED_PWMLED_FREQUENCY_REG_LED_PWM_FREQUENCY_Msk (0xffUL) /*!< LED_PWM_FREQUENCY (Bitfield-Mask: 0xff) */ /* =========================================================================================================================== */ /* ================ QSPIC ================ */ /* =========================================================================================================================== */ /* ================================================== QSPIC_BURSTBRK_REG =================================================== */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_SEC_HF_DS_Pos (20UL) /*!< QSPIC_SEC_HF_DS (Bit 20) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_SEC_HF_DS_Msk (0x100000UL) /*!< QSPIC_SEC_HF_DS (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_TX_MD_Pos (18UL) /*!< QSPIC_BRK_TX_MD (Bit 18) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_TX_MD_Msk (0xc0000UL) /*!< QSPIC_BRK_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_SZ_Pos (17UL) /*!< QSPIC_BRK_SZ (Bit 17) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_SZ_Msk (0x20000UL) /*!< QSPIC_BRK_SZ (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_EN_Pos (16UL) /*!< QSPIC_BRK_EN (Bit 16) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_EN_Msk (0x10000UL) /*!< QSPIC_BRK_EN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_WRD_Pos (0UL) /*!< QSPIC_BRK_WRD (Bit 0) */ #define QSPIC_QSPIC_BURSTBRK_REG_QSPIC_BRK_WRD_Msk (0xffffUL) /*!< QSPIC_BRK_WRD (Bitfield-Mask: 0xffff) */ /* ================================================== QSPIC_BURSTCMDA_REG ================================================== */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Pos (30UL) /*!< QSPIC_DMY_TX_MD (Bit 30) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Msk (0xc0000000UL) /*!< QSPIC_DMY_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Pos (28UL) /*!< QSPIC_EXT_TX_MD (Bit 28) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Msk (0x30000000UL) /*!< QSPIC_EXT_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Pos (26UL) /*!< QSPIC_ADR_TX_MD (Bit 26) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Msk (0xc000000UL) /*!< QSPIC_ADR_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_TX_MD_Pos (24UL) /*!< QSPIC_INST_TX_MD (Bit 24) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_TX_MD_Msk (0x3000000UL) /*!< QSPIC_INST_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_BYTE_Pos (16UL) /*!< QSPIC_EXT_BYTE (Bit 16) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_EXT_BYTE_Msk (0xff0000UL) /*!< QSPIC_EXT_BYTE (Bitfield-Mask: 0xff) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_WB_Pos (8UL) /*!< QSPIC_INST_WB (Bit 8) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_WB_Msk (0xff00UL) /*!< QSPIC_INST_WB (Bitfield-Mask: 0xff) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_Pos (0UL) /*!< QSPIC_INST (Bit 0) */ #define QSPIC_QSPIC_BURSTCMDA_REG_QSPIC_INST_Msk (0xffUL) /*!< QSPIC_INST (Bitfield-Mask: 0xff) */ /* ================================================== QSPIC_BURSTCMDB_REG ================================================== */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_FORCE_Pos (15UL) /*!< QSPIC_DMY_FORCE (Bit 15) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_FORCE_Msk (0x8000UL) /*!< QSPIC_DMY_FORCE (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos (12UL) /*!< QSPIC_CS_HIGH_MIN (Bit 12) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk (0x7000UL) /*!< QSPIC_CS_HIGH_MIN (Bitfield-Mask: 0x07) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Pos (10UL) /*!< QSPIC_WRAP_SIZE (Bit 10) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Msk (0xc00UL) /*!< QSPIC_WRAP_SIZE (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_LEN_Pos (8UL) /*!< QSPIC_WRAP_LEN (Bit 8) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_LEN_Msk (0x300UL) /*!< QSPIC_WRAP_LEN (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_MD_Pos (7UL) /*!< QSPIC_WRAP_MD (Bit 7) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_WRAP_MD_Msk (0x80UL) /*!< QSPIC_WRAP_MD (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_INST_MD_Pos (6UL) /*!< QSPIC_INST_MD (Bit 6) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_INST_MD_Msk (0x40UL) /*!< QSPIC_INST_MD (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_NUM_Pos (4UL) /*!< QSPIC_DMY_NUM (Bit 4) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DMY_NUM_Msk (0x30UL) /*!< QSPIC_DMY_NUM (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Pos (3UL) /*!< QSPIC_EXT_HF_DS (Bit 3) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Msk (0x8UL) /*!< QSPIC_EXT_HF_DS (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Pos (2UL) /*!< QSPIC_EXT_BYTE_EN (Bit 2) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Msk (0x4UL) /*!< QSPIC_EXT_BYTE_EN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Pos (0UL) /*!< QSPIC_DAT_RX_MD (Bit 0) */ #define QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Msk (0x3UL) /*!< QSPIC_DAT_RX_MD (Bitfield-Mask: 0x03) */ /* ================================================== QSPIC_CHCKERASE_REG ================================================== */ #define QSPIC_QSPIC_CHCKERASE_REG_QSPIC_CHCKERASE_Pos (0UL) /*!< QSPIC_CHCKERASE (Bit 0) */ #define QSPIC_QSPIC_CHCKERASE_REG_QSPIC_CHCKERASE_Msk (0xffffffffUL) /*!< QSPIC_CHCKERASE (Bitfield-Mask: 0xffffffff) */ /* =================================================== QSPIC_CTRLBUS_REG =================================================== */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Pos (4UL) /*!< QSPIC_DIS_CS (Bit 4) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Msk (0x10UL) /*!< QSPIC_DIS_CS (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Pos (3UL) /*!< QSPIC_EN_CS (Bit 3) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Msk (0x8UL) /*!< QSPIC_EN_CS (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_QUAD_Pos (2UL) /*!< QSPIC_SET_QUAD (Bit 2) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_QUAD_Msk (0x4UL) /*!< QSPIC_SET_QUAD (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_DUAL_Pos (1UL) /*!< QSPIC_SET_DUAL (Bit 1) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_DUAL_Msk (0x2UL) /*!< QSPIC_SET_DUAL (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_SINGLE_Pos (0UL) /*!< QSPIC_SET_SINGLE (Bit 0) */ #define QSPIC_QSPIC_CTRLBUS_REG_QSPIC_SET_SINGLE_Msk (0x1UL) /*!< QSPIC_SET_SINGLE (Bitfield-Mask: 0x01) */ /* ================================================== QSPIC_CTRLMODE_REG =================================================== */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_USE_32BA_Pos (13UL) /*!< QSPIC_USE_32BA (Bit 13) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_USE_32BA_Msk (0x2000UL) /*!< QSPIC_USE_32BA (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_BUF_LIM_EN_Pos (12UL) /*!< QSPIC_BUF_LIM_EN (Bit 12) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_BUF_LIM_EN_Msk (0x1000UL) /*!< QSPIC_BUF_LIM_EN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Pos (9UL) /*!< QSPIC_PCLK_MD (Bit 9) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Msk (0xe00UL) /*!< QSPIC_PCLK_MD (Bitfield-Mask: 0x07) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Pos (8UL) /*!< QSPIC_RPIPE_EN (Bit 8) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk (0x100UL) /*!< QSPIC_RPIPE_EN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RXD_NEG_Pos (7UL) /*!< QSPIC_RXD_NEG (Bit 7) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RXD_NEG_Msk (0x80UL) /*!< QSPIC_RXD_NEG (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_HRDY_MD_Pos (6UL) /*!< QSPIC_HRDY_MD (Bit 6) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_HRDY_MD_Msk (0x40UL) /*!< QSPIC_HRDY_MD (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_DAT_Pos (5UL) /*!< QSPIC_IO3_DAT (Bit 5) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_DAT_Msk (0x20UL) /*!< QSPIC_IO3_DAT (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_DAT_Pos (4UL) /*!< QSPIC_IO2_DAT (Bit 4) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_DAT_Msk (0x10UL) /*!< QSPIC_IO2_DAT (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_OEN_Pos (3UL) /*!< QSPIC_IO3_OEN (Bit 3) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO3_OEN_Msk (0x8UL) /*!< QSPIC_IO3_OEN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_OEN_Pos (2UL) /*!< QSPIC_IO2_OEN (Bit 2) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_IO2_OEN_Msk (0x4UL) /*!< QSPIC_IO2_OEN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_CLK_MD_Pos (1UL) /*!< QSPIC_CLK_MD (Bit 1) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_CLK_MD_Msk (0x2UL) /*!< QSPIC_CLK_MD (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_AUTO_MD_Pos (0UL) /*!< QSPIC_AUTO_MD (Bit 0) */ #define QSPIC_QSPIC_CTRLMODE_REG_QSPIC_AUTO_MD_Msk (0x1UL) /*!< QSPIC_AUTO_MD (Bitfield-Mask: 0x01) */ /* ================================================== QSPIC_CTR_CTRL_REG =================================================== */ #define QSPIC_QSPIC_CTR_CTRL_REG_QSPIC_CTR_EN_Pos (0UL) /*!< QSPIC_CTR_EN (Bit 0) */ #define QSPIC_QSPIC_CTR_CTRL_REG_QSPIC_CTR_EN_Msk (0x1UL) /*!< QSPIC_CTR_EN (Bitfield-Mask: 0x01) */ /* ================================================== QSPIC_CTR_EADDR_REG ================================================== */ #define QSPIC_QSPIC_CTR_EADDR_REG_QSPIC_CTR_EADDR_Pos (10UL) /*!< QSPIC_CTR_EADDR (Bit 10) */ #define QSPIC_QSPIC_CTR_EADDR_REG_QSPIC_CTR_EADDR_Msk (0xfffffc00UL) /*!< QSPIC_CTR_EADDR (Bitfield-Mask: 0x3fffff) */ /* ================================================= QSPIC_CTR_KEY_0_3_REG ================================================= */ #define QSPIC_QSPIC_CTR_KEY_0_3_REG_QSPIC_CTR_KEY_0_3_Pos (0UL) /*!< QSPIC_CTR_KEY_0_3 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_0_3_REG_QSPIC_CTR_KEY_0_3_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_0_3 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_12_15_REG ================================================ */ #define QSPIC_QSPIC_CTR_KEY_12_15_REG_QSPIC_CTR_KEY_12_15_Pos (0UL) /*!< QSPIC_CTR_KEY_12_15 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_12_15_REG_QSPIC_CTR_KEY_12_15_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_12_15 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_16_19_REG ================================================ */ #define QSPIC_QSPIC_CTR_KEY_16_19_REG_QSPIC_CTR_KEY_16_19_Pos (0UL) /*!< QSPIC_CTR_KEY_16_19 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_16_19_REG_QSPIC_CTR_KEY_16_19_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_16_19 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_20_23_REG ================================================ */ #define QSPIC_QSPIC_CTR_KEY_20_23_REG_QSPIC_CTR_KEY_20_23_Pos (0UL) /*!< QSPIC_CTR_KEY_20_23 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_20_23_REG_QSPIC_CTR_KEY_20_23_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_20_23 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_24_27_REG ================================================ */ #define QSPIC_QSPIC_CTR_KEY_24_27_REG_QSPIC_CTR_KEY_24_27_Pos (0UL) /*!< QSPIC_CTR_KEY_24_27 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_24_27_REG_QSPIC_CTR_KEY_24_27_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_24_27 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_28_31_REG ================================================ */ #define QSPIC_QSPIC_CTR_KEY_28_31_REG_QSPIC_CTR_KEY_28_31_Pos (0UL) /*!< QSPIC_CTR_KEY_28_31 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_28_31_REG_QSPIC_CTR_KEY_28_31_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_28_31 (Bitfield-Mask: 0xffffffff) */ /* ================================================= QSPIC_CTR_KEY_4_7_REG ================================================= */ #define QSPIC_QSPIC_CTR_KEY_4_7_REG_QSPIC_CTR_KEY_4_7_Pos (0UL) /*!< QSPIC_CTR_KEY_4_7 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_4_7_REG_QSPIC_CTR_KEY_4_7_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_4_7 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_KEY_8_11_REG ================================================= */ #define QSPIC_QSPIC_CTR_KEY_8_11_REG_QSPIC_CTR_KEY_8_11_Pos (0UL) /*!< QSPIC_CTR_KEY_8_11 (Bit 0) */ #define QSPIC_QSPIC_CTR_KEY_8_11_REG_QSPIC_CTR_KEY_8_11_Msk (0xffffffffUL) /*!< QSPIC_CTR_KEY_8_11 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_NONCE_0_3_REG ================================================ */ #define QSPIC_QSPIC_CTR_NONCE_0_3_REG_QSPIC_CTR_NONCE_0_3_Pos (0UL) /*!< QSPIC_CTR_NONCE_0_3 (Bit 0) */ #define QSPIC_QSPIC_CTR_NONCE_0_3_REG_QSPIC_CTR_NONCE_0_3_Msk (0xffffffffUL) /*!< QSPIC_CTR_NONCE_0_3 (Bitfield-Mask: 0xffffffff) */ /* ================================================ QSPIC_CTR_NONCE_4_7_REG ================================================ */ #define QSPIC_QSPIC_CTR_NONCE_4_7_REG_QSPIC_CTR_NONCE_4_7_Pos (0UL) /*!< QSPIC_CTR_NONCE_4_7 (Bit 0) */ #define QSPIC_QSPIC_CTR_NONCE_4_7_REG_QSPIC_CTR_NONCE_4_7_Msk (0xffffffffUL) /*!< QSPIC_CTR_NONCE_4_7 (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC_CTR_SADDR_REG ================================================== */ #define QSPIC_QSPIC_CTR_SADDR_REG_QSPIC_CTR_SADDR_Pos (10UL) /*!< QSPIC_CTR_SADDR (Bit 10) */ #define QSPIC_QSPIC_CTR_SADDR_REG_QSPIC_CTR_SADDR_Msk (0xfffffc00UL) /*!< QSPIC_CTR_SADDR (Bitfield-Mask: 0x3fffff) */ /* ================================================== QSPIC_DUMMYDATA_REG ================================================== */ #define QSPIC_QSPIC_DUMMYDATA_REG_QSPIC_DUMMYDATA_Pos (0UL) /*!< QSPIC_DUMMYDATA (Bit 0) */ #define QSPIC_QSPIC_DUMMYDATA_REG_QSPIC_DUMMYDATA_Msk (0xffffffffUL) /*!< QSPIC_DUMMYDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC_ERASECMDA_REG ================================================== */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_RES_INST_Pos (24UL) /*!< QSPIC_RES_INST (Bit 24) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_RES_INST_Msk (0xff000000UL) /*!< QSPIC_RES_INST (Bitfield-Mask: 0xff) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_SUS_INST_Pos (16UL) /*!< QSPIC_SUS_INST (Bit 16) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_SUS_INST_Msk (0xff0000UL) /*!< QSPIC_SUS_INST (Bitfield-Mask: 0xff) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_WEN_INST_Pos (8UL) /*!< QSPIC_WEN_INST (Bit 8) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_WEN_INST_Msk (0xff00UL) /*!< QSPIC_WEN_INST (Bitfield-Mask: 0xff) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_ERS_INST_Pos (0UL) /*!< QSPIC_ERS_INST (Bit 0) */ #define QSPIC_QSPIC_ERASECMDA_REG_QSPIC_ERS_INST_Msk (0xffUL) /*!< QSPIC_ERS_INST (Bitfield-Mask: 0xff) */ /* ================================================== QSPIC_ERASECMDB_REG ================================================== */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RESSUS_DLY_Pos (24UL) /*!< QSPIC_RESSUS_DLY (Bit 24) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RESSUS_DLY_Msk (0x3f000000UL) /*!< QSPIC_RESSUS_DLY (Bitfield-Mask: 0x3f) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERSRES_HLD_Pos (16UL) /*!< QSPIC_ERSRES_HLD (Bit 16) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERSRES_HLD_Msk (0xf0000UL) /*!< QSPIC_ERSRES_HLD (Bitfield-Mask: 0x0f) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos (10UL) /*!< QSPIC_ERS_CS_HI (Bit 10) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk (0x7c00UL) /*!< QSPIC_ERS_CS_HI (Bitfield-Mask: 0x1f) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_EAD_TX_MD_Pos (8UL) /*!< QSPIC_EAD_TX_MD (Bit 8) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_EAD_TX_MD_Msk (0x300UL) /*!< QSPIC_EAD_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RES_TX_MD_Pos (6UL) /*!< QSPIC_RES_TX_MD (Bit 6) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_RES_TX_MD_Msk (0xc0UL) /*!< QSPIC_RES_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_SUS_TX_MD_Pos (4UL) /*!< QSPIC_SUS_TX_MD (Bit 4) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_SUS_TX_MD_Msk (0x30UL) /*!< QSPIC_SUS_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_WEN_TX_MD_Pos (2UL) /*!< QSPIC_WEN_TX_MD (Bit 2) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_WEN_TX_MD_Msk (0xcUL) /*!< QSPIC_WEN_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_TX_MD_Pos (0UL) /*!< QSPIC_ERS_TX_MD (Bit 0) */ #define QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_TX_MD_Msk (0x3UL) /*!< QSPIC_ERS_TX_MD (Bitfield-Mask: 0x03) */ /* ================================================== QSPIC_ERASECTRL_REG ================================================== */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_STATE_Pos (25UL) /*!< QSPIC_ERS_STATE (Bit 25) */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_STATE_Msk (0xe000000UL) /*!< QSPIC_ERS_STATE (Bitfield-Mask: 0x07) */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERASE_EN_Pos (24UL) /*!< QSPIC_ERASE_EN (Bit 24) */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERASE_EN_Msk (0x1000000UL) /*!< QSPIC_ERASE_EN (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_ADDR_Pos (4UL) /*!< QSPIC_ERS_ADDR (Bit 4) */ #define QSPIC_QSPIC_ERASECTRL_REG_QSPIC_ERS_ADDR_Msk (0xfffff0UL) /*!< QSPIC_ERS_ADDR (Bitfield-Mask: 0xfffff) */ /* ===================================================== QSPIC_GP_REG ====================================================== */ #define QSPIC_QSPIC_GP_REG_QSPIC_PADS_SLEW_Pos (3UL) /*!< QSPIC_PADS_SLEW (Bit 3) */ #define QSPIC_QSPIC_GP_REG_QSPIC_PADS_SLEW_Msk (0x18UL) /*!< QSPIC_PADS_SLEW (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_GP_REG_QSPIC_PADS_DRV_Pos (1UL) /*!< QSPIC_PADS_DRV (Bit 1) */ #define QSPIC_QSPIC_GP_REG_QSPIC_PADS_DRV_Msk (0x6UL) /*!< QSPIC_PADS_DRV (Bitfield-Mask: 0x03) */ /* ================================================== QSPIC_READDATA_REG =================================================== */ #define QSPIC_QSPIC_READDATA_REG_QSPIC_READDATA_Pos (0UL) /*!< QSPIC_READDATA (Bit 0) */ #define QSPIC_QSPIC_READDATA_REG_QSPIC_READDATA_Msk (0xffffffffUL) /*!< QSPIC_READDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC_RECVDATA_REG =================================================== */ #define QSPIC_QSPIC_RECVDATA_REG_QSPIC_RECVDATA_Pos (0UL) /*!< QSPIC_RECVDATA (Bit 0) */ #define QSPIC_QSPIC_RECVDATA_REG_QSPIC_RECVDATA_Msk (0xffffffffUL) /*!< QSPIC_RECVDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC_STATUSCMD_REG ================================================== */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_STSDLY_SEL_Pos (22UL) /*!< QSPIC_STSDLY_SEL (Bit 22) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_STSDLY_SEL_Msk (0x400000UL) /*!< QSPIC_STSDLY_SEL (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RESSTS_DLY_Pos (16UL) /*!< QSPIC_RESSTS_DLY (Bit 16) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RESSTS_DLY_Msk (0x3f0000UL) /*!< QSPIC_RESSTS_DLY (Bitfield-Mask: 0x3f) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_VAL_Pos (15UL) /*!< QSPIC_BUSY_VAL (Bit 15) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_VAL_Msk (0x8000UL) /*!< QSPIC_BUSY_VAL (Bitfield-Mask: 0x01) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_POS_Pos (12UL) /*!< QSPIC_BUSY_POS (Bit 12) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_BUSY_POS_Msk (0x7000UL) /*!< QSPIC_BUSY_POS (Bitfield-Mask: 0x07) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Pos (10UL) /*!< QSPIC_RSTAT_RX_MD (Bit 10) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Msk (0xc00UL) /*!< QSPIC_RSTAT_RX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Pos (8UL) /*!< QSPIC_RSTAT_TX_MD (Bit 8) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Msk (0x300UL) /*!< QSPIC_RSTAT_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_INST_Pos (0UL) /*!< QSPIC_RSTAT_INST (Bit 0) */ #define QSPIC_QSPIC_STATUSCMD_REG_QSPIC_RSTAT_INST_Msk (0xffUL) /*!< QSPIC_RSTAT_INST (Bitfield-Mask: 0xff) */ /* =================================================== QSPIC_STATUS_REG ==================================================== */ #define QSPIC_QSPIC_STATUS_REG_QSPIC_BUSY_Pos (0UL) /*!< QSPIC_BUSY (Bit 0) */ #define QSPIC_QSPIC_STATUS_REG_QSPIC_BUSY_Msk (0x1UL) /*!< QSPIC_BUSY (Bitfield-Mask: 0x01) */ /* =================================================== QSPIC_UCODE_START =================================================== */ #define QSPIC_QSPIC_UCODE_START_QSPIC_UCODE_X_Pos (0UL) /*!< QSPIC_UCODE_X (Bit 0) */ #define QSPIC_QSPIC_UCODE_START_QSPIC_UCODE_X_Msk (0xffffffffUL) /*!< QSPIC_UCODE_X (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC_WRITEDATA_REG ================================================== */ #define QSPIC_QSPIC_WRITEDATA_REG_QSPIC_WRITEDATA_Pos (0UL) /*!< QSPIC_WRITEDATA (Bit 0) */ #define QSPIC_QSPIC_WRITEDATA_REG_QSPIC_WRITEDATA_Msk (0xffffffffUL) /*!< QSPIC_WRITEDATA (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ QSPIC2 ================ */ /* =========================================================================================================================== */ /* ================================================= QSPIC2_AWRITECMD_REG ================================================== */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_CS_HIGH_MIN_Pos (14UL) /*!< QSPIC_WR_CS_HIGH_MIN (Bit 14) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_CS_HIGH_MIN_Msk (0x7c000UL) /*!< QSPIC_WR_CS_HIGH_MIN (Bitfield-Mask: 0x1f) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_DAT_TX_MD_Pos (12UL) /*!< QSPIC_WR_DAT_TX_MD (Bit 12) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_DAT_TX_MD_Msk (0x3000UL) /*!< QSPIC_WR_DAT_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_ADR_TX_MD_Pos (10UL) /*!< QSPIC_WR_ADR_TX_MD (Bit 10) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_ADR_TX_MD_Msk (0xc00UL) /*!< QSPIC_WR_ADR_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_TX_MD_Pos (8UL) /*!< QSPIC_WR_INST_TX_MD (Bit 8) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_TX_MD_Msk (0x300UL) /*!< QSPIC_WR_INST_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_Pos (0UL) /*!< QSPIC_WR_INST (Bit 0) */ #define QSPIC2_QSPIC2_AWRITECMD_REG_QSPIC_WR_INST_Msk (0xffUL) /*!< QSPIC_WR_INST (Bitfield-Mask: 0xff) */ /* ================================================== QSPIC2_BURSTBRK_REG ================================================== */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_SEC_HF_DS_Pos (20UL) /*!< QSPIC_SEC_HF_DS (Bit 20) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_SEC_HF_DS_Msk (0x100000UL) /*!< QSPIC_SEC_HF_DS (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_TX_MD_Pos (18UL) /*!< QSPIC_BRK_TX_MD (Bit 18) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_TX_MD_Msk (0xc0000UL) /*!< QSPIC_BRK_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_SZ_Pos (17UL) /*!< QSPIC_BRK_SZ (Bit 17) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_SZ_Msk (0x20000UL) /*!< QSPIC_BRK_SZ (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_EN_Pos (16UL) /*!< QSPIC_BRK_EN (Bit 16) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_EN_Msk (0x10000UL) /*!< QSPIC_BRK_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_WRD_Pos (0UL) /*!< QSPIC_BRK_WRD (Bit 0) */ #define QSPIC2_QSPIC2_BURSTBRK_REG_QSPIC_BRK_WRD_Msk (0xffffUL) /*!< QSPIC_BRK_WRD (Bitfield-Mask: 0xffff) */ /* ================================================= QSPIC2_BURSTCMDA_REG ================================================== */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Pos (30UL) /*!< QSPIC_DMY_TX_MD (Bit 30) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_DMY_TX_MD_Msk (0xc0000000UL) /*!< QSPIC_DMY_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Pos (28UL) /*!< QSPIC_EXT_TX_MD (Bit 28) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_TX_MD_Msk (0x30000000UL) /*!< QSPIC_EXT_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Pos (26UL) /*!< QSPIC_ADR_TX_MD (Bit 26) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_ADR_TX_MD_Msk (0xc000000UL) /*!< QSPIC_ADR_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_TX_MD_Pos (24UL) /*!< QSPIC_INST_TX_MD (Bit 24) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_TX_MD_Msk (0x3000000UL) /*!< QSPIC_INST_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_BYTE_Pos (16UL) /*!< QSPIC_EXT_BYTE (Bit 16) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_EXT_BYTE_Msk (0xff0000UL) /*!< QSPIC_EXT_BYTE (Bitfield-Mask: 0xff) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_WB_Pos (8UL) /*!< QSPIC_INST_WB (Bit 8) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_WB_Msk (0xff00UL) /*!< QSPIC_INST_WB (Bitfield-Mask: 0xff) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_Pos (0UL) /*!< QSPIC_INST (Bit 0) */ #define QSPIC2_QSPIC2_BURSTCMDA_REG_QSPIC_INST_Msk (0xffUL) /*!< QSPIC_INST (Bitfield-Mask: 0xff) */ /* ================================================= QSPIC2_BURSTCMDB_REG ================================================== */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_FORCE_Pos (15UL) /*!< QSPIC_DMY_FORCE (Bit 15) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_FORCE_Msk (0x8000UL) /*!< QSPIC_DMY_FORCE (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos (12UL) /*!< QSPIC_CS_HIGH_MIN (Bit 12) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk (0x7000UL) /*!< QSPIC_CS_HIGH_MIN (Bitfield-Mask: 0x07) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Pos (10UL) /*!< QSPIC_WRAP_SIZE (Bit 10) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_SIZE_Msk (0xc00UL) /*!< QSPIC_WRAP_SIZE (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_LEN_Pos (8UL) /*!< QSPIC_WRAP_LEN (Bit 8) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_LEN_Msk (0x300UL) /*!< QSPIC_WRAP_LEN (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_MD_Pos (7UL) /*!< QSPIC_WRAP_MD (Bit 7) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_WRAP_MD_Msk (0x80UL) /*!< QSPIC_WRAP_MD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_INST_MD_Pos (6UL) /*!< QSPIC_INST_MD (Bit 6) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_INST_MD_Msk (0x40UL) /*!< QSPIC_INST_MD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_NUM_Pos (4UL) /*!< QSPIC_DMY_NUM (Bit 4) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DMY_NUM_Msk (0x30UL) /*!< QSPIC_DMY_NUM (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Pos (3UL) /*!< QSPIC_EXT_HF_DS (Bit 3) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_HF_DS_Msk (0x8UL) /*!< QSPIC_EXT_HF_DS (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Pos (2UL) /*!< QSPIC_EXT_BYTE_EN (Bit 2) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_EXT_BYTE_EN_Msk (0x4UL) /*!< QSPIC_EXT_BYTE_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Pos (0UL) /*!< QSPIC_DAT_RX_MD (Bit 0) */ #define QSPIC2_QSPIC2_BURSTCMDB_REG_QSPIC_DAT_RX_MD_Msk (0x3UL) /*!< QSPIC_DAT_RX_MD (Bitfield-Mask: 0x03) */ /* ================================================= QSPIC2_CHCKERASE_REG ================================================== */ #define QSPIC2_QSPIC2_CHCKERASE_REG_QSPIC_CHCKERASE_Pos (0UL) /*!< QSPIC_CHCKERASE (Bit 0) */ #define QSPIC2_QSPIC2_CHCKERASE_REG_QSPIC_CHCKERASE_Msk (0xffffffffUL) /*!< QSPIC_CHCKERASE (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC2_CTRLBUS_REG =================================================== */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_DIS_CS_Pos (4UL) /*!< QSPIC_DIS_CS (Bit 4) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_DIS_CS_Msk (0x10UL) /*!< QSPIC_DIS_CS (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_EN_CS_Pos (3UL) /*!< QSPIC_EN_CS (Bit 3) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_EN_CS_Msk (0x8UL) /*!< QSPIC_EN_CS (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_QUAD_Pos (2UL) /*!< QSPIC_SET_QUAD (Bit 2) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_QUAD_Msk (0x4UL) /*!< QSPIC_SET_QUAD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_DUAL_Pos (1UL) /*!< QSPIC_SET_DUAL (Bit 1) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_DUAL_Msk (0x2UL) /*!< QSPIC_SET_DUAL (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_SINGLE_Pos (0UL) /*!< QSPIC_SET_SINGLE (Bit 0) */ #define QSPIC2_QSPIC2_CTRLBUS_REG_QSPIC_SET_SINGLE_Msk (0x1UL) /*!< QSPIC_SET_SINGLE (Bitfield-Mask: 0x01) */ /* ================================================== QSPIC2_CTRLMODE_REG ================================================== */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_FREE_EN_Pos (16UL) /*!< QSPIC_CLK_FREE_EN (Bit 16) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_FREE_EN_Msk (0x10000UL) /*!< QSPIC_CLK_FREE_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CS_MD_Pos (15UL) /*!< QSPIC_CS_MD (Bit 15) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CS_MD_Msk (0x8000UL) /*!< QSPIC_CS_MD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_SRAM_EN_Pos (14UL) /*!< QSPIC_SRAM_EN (Bit 14) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_SRAM_EN_Msk (0x4000UL) /*!< QSPIC_SRAM_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_USE_32BA_Pos (13UL) /*!< QSPIC_USE_32BA (Bit 13) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_USE_32BA_Msk (0x2000UL) /*!< QSPIC_USE_32BA (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_FORCENSEQ_EN_Pos (12UL) /*!< QSPIC_FORCENSEQ_EN (Bit 12) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_FORCENSEQ_EN_Msk (0x1000UL) /*!< QSPIC_FORCENSEQ_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_PCLK_MD_Pos (9UL) /*!< QSPIC_PCLK_MD (Bit 9) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_PCLK_MD_Msk (0xe00UL) /*!< QSPIC_PCLK_MD (Bitfield-Mask: 0x07) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RPIPE_EN_Pos (8UL) /*!< QSPIC_RPIPE_EN (Bit 8) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk (0x100UL) /*!< QSPIC_RPIPE_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RXD_NEG_Pos (7UL) /*!< QSPIC_RXD_NEG (Bit 7) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_RXD_NEG_Msk (0x80UL) /*!< QSPIC_RXD_NEG (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_HRDY_MD_Pos (6UL) /*!< QSPIC_HRDY_MD (Bit 6) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_HRDY_MD_Msk (0x40UL) /*!< QSPIC_HRDY_MD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_DAT_Pos (5UL) /*!< QSPIC_IO3_DAT (Bit 5) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_DAT_Msk (0x20UL) /*!< QSPIC_IO3_DAT (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_DAT_Pos (4UL) /*!< QSPIC_IO2_DAT (Bit 4) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_DAT_Msk (0x10UL) /*!< QSPIC_IO2_DAT (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_OEN_Pos (3UL) /*!< QSPIC_IO3_OEN (Bit 3) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO3_OEN_Msk (0x8UL) /*!< QSPIC_IO3_OEN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_OEN_Pos (2UL) /*!< QSPIC_IO2_OEN (Bit 2) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_IO2_OEN_Msk (0x4UL) /*!< QSPIC_IO2_OEN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_MD_Pos (1UL) /*!< QSPIC_CLK_MD (Bit 1) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_CLK_MD_Msk (0x2UL) /*!< QSPIC_CLK_MD (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_AUTO_MD_Pos (0UL) /*!< QSPIC_AUTO_MD (Bit 0) */ #define QSPIC2_QSPIC2_CTRLMODE_REG_QSPIC_AUTO_MD_Msk (0x1UL) /*!< QSPIC_AUTO_MD (Bitfield-Mask: 0x01) */ /* ================================================= QSPIC2_DUMMYDATA_REG ================================================== */ #define QSPIC2_QSPIC2_DUMMYDATA_REG_QSPIC_DUMMYDATA_Pos (0UL) /*!< QSPIC_DUMMYDATA (Bit 0) */ #define QSPIC2_QSPIC2_DUMMYDATA_REG_QSPIC_DUMMYDATA_Msk (0xffffffffUL) /*!< QSPIC_DUMMYDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================= QSPIC2_ERASECMDA_REG ================================================== */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_RES_INST_Pos (24UL) /*!< QSPIC_RES_INST (Bit 24) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_RES_INST_Msk (0xff000000UL) /*!< QSPIC_RES_INST (Bitfield-Mask: 0xff) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_SUS_INST_Pos (16UL) /*!< QSPIC_SUS_INST (Bit 16) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_SUS_INST_Msk (0xff0000UL) /*!< QSPIC_SUS_INST (Bitfield-Mask: 0xff) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_WEN_INST_Pos (8UL) /*!< QSPIC_WEN_INST (Bit 8) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_WEN_INST_Msk (0xff00UL) /*!< QSPIC_WEN_INST (Bitfield-Mask: 0xff) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_ERS_INST_Pos (0UL) /*!< QSPIC_ERS_INST (Bit 0) */ #define QSPIC2_QSPIC2_ERASECMDA_REG_QSPIC_ERS_INST_Msk (0xffUL) /*!< QSPIC_ERS_INST (Bitfield-Mask: 0xff) */ /* ================================================= QSPIC2_ERASECMDB_REG ================================================== */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RESSUS_DLY_Pos (24UL) /*!< QSPIC_RESSUS_DLY (Bit 24) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RESSUS_DLY_Msk (0x3f000000UL) /*!< QSPIC_RESSUS_DLY (Bitfield-Mask: 0x3f) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERSRES_HLD_Pos (16UL) /*!< QSPIC_ERSRES_HLD (Bit 16) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERSRES_HLD_Msk (0xf0000UL) /*!< QSPIC_ERSRES_HLD (Bitfield-Mask: 0x0f) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos (10UL) /*!< QSPIC_ERS_CS_HI (Bit 10) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk (0x7c00UL) /*!< QSPIC_ERS_CS_HI (Bitfield-Mask: 0x1f) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_EAD_TX_MD_Pos (8UL) /*!< QSPIC_EAD_TX_MD (Bit 8) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_EAD_TX_MD_Msk (0x300UL) /*!< QSPIC_EAD_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RES_TX_MD_Pos (6UL) /*!< QSPIC_RES_TX_MD (Bit 6) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_RES_TX_MD_Msk (0xc0UL) /*!< QSPIC_RES_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_SUS_TX_MD_Pos (4UL) /*!< QSPIC_SUS_TX_MD (Bit 4) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_SUS_TX_MD_Msk (0x30UL) /*!< QSPIC_SUS_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_WEN_TX_MD_Pos (2UL) /*!< QSPIC_WEN_TX_MD (Bit 2) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_WEN_TX_MD_Msk (0xcUL) /*!< QSPIC_WEN_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_TX_MD_Pos (0UL) /*!< QSPIC_ERS_TX_MD (Bit 0) */ #define QSPIC2_QSPIC2_ERASECMDB_REG_QSPIC_ERS_TX_MD_Msk (0x3UL) /*!< QSPIC_ERS_TX_MD (Bitfield-Mask: 0x03) */ /* ================================================= QSPIC2_ERASECTRL_REG ================================================== */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_STATE_Pos (25UL) /*!< QSPIC_ERS_STATE (Bit 25) */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_STATE_Msk (0xe000000UL) /*!< QSPIC_ERS_STATE (Bitfield-Mask: 0x07) */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERASE_EN_Pos (24UL) /*!< QSPIC_ERASE_EN (Bit 24) */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERASE_EN_Msk (0x1000000UL) /*!< QSPIC_ERASE_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_ADDR_Pos (4UL) /*!< QSPIC_ERS_ADDR (Bit 4) */ #define QSPIC2_QSPIC2_ERASECTRL_REG_QSPIC_ERS_ADDR_Msk (0xfffff0UL) /*!< QSPIC_ERS_ADDR (Bitfield-Mask: 0xfffff) */ /* ===================================================== QSPIC2_GP_REG ===================================================== */ #define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_SLEW_Pos (3UL) /*!< QSPIC_PADS_SLEW (Bit 3) */ #define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_SLEW_Msk (0x18UL) /*!< QSPIC_PADS_SLEW (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_DRV_Pos (1UL) /*!< QSPIC_PADS_DRV (Bit 1) */ #define QSPIC2_QSPIC2_GP_REG_QSPIC_PADS_DRV_Msk (0x6UL) /*!< QSPIC_PADS_DRV (Bitfield-Mask: 0x03) */ /* ================================================== QSPIC2_MEMBLEN_REG =================================================== */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_CC_Pos (4UL) /*!< QSPIC_T_CEM_CC (Bit 4) */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_CC_Msk (0x3ff0UL) /*!< QSPIC_T_CEM_CC (Bitfield-Mask: 0x3ff) */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_EN_Pos (3UL) /*!< QSPIC_T_CEM_EN (Bit 3) */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_T_CEM_EN_Msk (0x8UL) /*!< QSPIC_T_CEM_EN (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_MEMBLEN_Pos (0UL) /*!< QSPIC_MEMBLEN (Bit 0) */ #define QSPIC2_QSPIC2_MEMBLEN_REG_QSPIC_MEMBLEN_Msk (0x7UL) /*!< QSPIC_MEMBLEN (Bitfield-Mask: 0x07) */ /* ================================================== QSPIC2_READDATA_REG ================================================== */ #define QSPIC2_QSPIC2_READDATA_REG_QSPIC_READDATA_Pos (0UL) /*!< QSPIC_READDATA (Bit 0) */ #define QSPIC2_QSPIC2_READDATA_REG_QSPIC_READDATA_Msk (0xffffffffUL) /*!< QSPIC_READDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================== QSPIC2_RECVDATA_REG ================================================== */ #define QSPIC2_QSPIC2_RECVDATA_REG_QSPIC_RECVDATA_Pos (0UL) /*!< QSPIC_RECVDATA (Bit 0) */ #define QSPIC2_QSPIC2_RECVDATA_REG_QSPIC_RECVDATA_Msk (0xffffffffUL) /*!< QSPIC_RECVDATA (Bitfield-Mask: 0xffffffff) */ /* ================================================= QSPIC2_STATUSCMD_REG ================================================== */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_STSDLY_SEL_Pos (22UL) /*!< QSPIC_STSDLY_SEL (Bit 22) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_STSDLY_SEL_Msk (0x400000UL) /*!< QSPIC_STSDLY_SEL (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RESSTS_DLY_Pos (16UL) /*!< QSPIC_RESSTS_DLY (Bit 16) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RESSTS_DLY_Msk (0x3f0000UL) /*!< QSPIC_RESSTS_DLY (Bitfield-Mask: 0x3f) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_VAL_Pos (15UL) /*!< QSPIC_BUSY_VAL (Bit 15) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_VAL_Msk (0x8000UL) /*!< QSPIC_BUSY_VAL (Bitfield-Mask: 0x01) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_POS_Pos (12UL) /*!< QSPIC_BUSY_POS (Bit 12) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_BUSY_POS_Msk (0x7000UL) /*!< QSPIC_BUSY_POS (Bitfield-Mask: 0x07) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Pos (10UL) /*!< QSPIC_RSTAT_RX_MD (Bit 10) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_RX_MD_Msk (0xc00UL) /*!< QSPIC_RSTAT_RX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Pos (8UL) /*!< QSPIC_RSTAT_TX_MD (Bit 8) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_TX_MD_Msk (0x300UL) /*!< QSPIC_RSTAT_TX_MD (Bitfield-Mask: 0x03) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_INST_Pos (0UL) /*!< QSPIC_RSTAT_INST (Bit 0) */ #define QSPIC2_QSPIC2_STATUSCMD_REG_QSPIC_RSTAT_INST_Msk (0xffUL) /*!< QSPIC_RSTAT_INST (Bitfield-Mask: 0xff) */ /* =================================================== QSPIC2_STATUS_REG =================================================== */ #define QSPIC2_QSPIC2_STATUS_REG_QSPIC_BUSY_Pos (0UL) /*!< QSPIC_BUSY (Bit 0) */ #define QSPIC2_QSPIC2_STATUS_REG_QSPIC_BUSY_Msk (0x1UL) /*!< QSPIC_BUSY (Bitfield-Mask: 0x01) */ /* ================================================= QSPIC2_WRITEDATA_REG ================================================== */ #define QSPIC2_QSPIC2_WRITEDATA_REG_QSPIC_WRITEDATA_Pos (0UL) /*!< QSPIC_WRITEDATA (Bit 0) */ #define QSPIC2_QSPIC2_WRITEDATA_REG_QSPIC_WRITEDATA_Msk (0xffffffffUL) /*!< QSPIC_WRITEDATA (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ RFMON ================ */ /* =========================================================================================================================== */ /* ==================================================== RFMON_ADDR_REG ===================================================== */ #define RFMON_RFMON_ADDR_REG_RFMON_ADDR_Pos (2UL) /*!< RFMON_ADDR (Bit 2) */ #define RFMON_RFMON_ADDR_REG_RFMON_ADDR_Msk (0xfffffffcUL) /*!< RFMON_ADDR (Bitfield-Mask: 0x3fffffff) */ /* ================================================== RFMON_CRV_ADDR_REG =================================================== */ #define RFMON_RFMON_CRV_ADDR_REG_RFMON_CRV_ADDR_Pos (2UL) /*!< RFMON_CRV_ADDR (Bit 2) */ #define RFMON_RFMON_CRV_ADDR_REG_RFMON_CRV_ADDR_Msk (0xfffffffcUL) /*!< RFMON_CRV_ADDR (Bitfield-Mask: 0x3fffffff) */ /* =================================================== RFMON_CRV_LEN_REG =================================================== */ #define RFMON_RFMON_CRV_LEN_REG_RFMON_CRV_LEN_Pos (0UL) /*!< RFMON_CRV_LEN (Bit 0) */ #define RFMON_RFMON_CRV_LEN_REG_RFMON_CRV_LEN_Msk (0x1ffffUL) /*!< RFMON_CRV_LEN (Bitfield-Mask: 0x1ffff) */ /* ==================================================== RFMON_CTRL_REG ===================================================== */ #define RFMON_RFMON_CTRL_REG_RFMON_BREQ_FORCE_Pos (2UL) /*!< RFMON_BREQ_FORCE (Bit 2) */ #define RFMON_RFMON_CTRL_REG_RFMON_BREQ_FORCE_Msk (0x4UL) /*!< RFMON_BREQ_FORCE (Bitfield-Mask: 0x01) */ #define RFMON_RFMON_CTRL_REG_RFMON_CIRC_EN_Pos (1UL) /*!< RFMON_CIRC_EN (Bit 1) */ #define RFMON_RFMON_CTRL_REG_RFMON_CIRC_EN_Msk (0x2UL) /*!< RFMON_CIRC_EN (Bitfield-Mask: 0x01) */ #define RFMON_RFMON_CTRL_REG_RFMON_PACK_EN_Pos (0UL) /*!< RFMON_PACK_EN (Bit 0) */ #define RFMON_RFMON_CTRL_REG_RFMON_PACK_EN_Msk (0x1UL) /*!< RFMON_PACK_EN (Bitfield-Mask: 0x01) */ /* ===================================================== RFMON_LEN_REG ===================================================== */ #define RFMON_RFMON_LEN_REG_RFMON_LEN_Pos (0UL) /*!< RFMON_LEN (Bit 0) */ #define RFMON_RFMON_LEN_REG_RFMON_LEN_Msk (0x1ffffUL) /*!< RFMON_LEN (Bitfield-Mask: 0x1ffff) */ /* ==================================================== RFMON_STAT_REG ===================================================== */ #define RFMON_RFMON_STAT_REG_RFMON_OFLOW_STK_Pos (1UL) /*!< RFMON_OFLOW_STK (Bit 1) */ #define RFMON_RFMON_STAT_REG_RFMON_OFLOW_STK_Msk (0x2UL) /*!< RFMON_OFLOW_STK (Bitfield-Mask: 0x01) */ #define RFMON_RFMON_STAT_REG_RFMON_ACTIVE_Pos (0UL) /*!< RFMON_ACTIVE (Bit 0) */ #define RFMON_RFMON_STAT_REG_RFMON_ACTIVE_Msk (0x1UL) /*!< RFMON_ACTIVE (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ RTC ================ */ /* =========================================================================================================================== */ /* ================================================= RTC_ALARM_ENABLE_REG ================================================== */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Pos (5UL) /*!< RTC_ALARM_MNTH_EN (Bit 5) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MNTH_EN_Msk (0x20UL) /*!< RTC_ALARM_MNTH_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Pos (4UL) /*!< RTC_ALARM_DATE_EN (Bit 4) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_DATE_EN_Msk (0x10UL) /*!< RTC_ALARM_DATE_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Pos (3UL) /*!< RTC_ALARM_HOUR_EN (Bit 3) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOUR_EN_Msk (0x8UL) /*!< RTC_ALARM_HOUR_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Pos (2UL) /*!< RTC_ALARM_MIN_EN (Bit 2) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_MIN_EN_Msk (0x4UL) /*!< RTC_ALARM_MIN_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Pos (1UL) /*!< RTC_ALARM_SEC_EN (Bit 1) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_SEC_EN_Msk (0x2UL) /*!< RTC_ALARM_SEC_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOS_EN_Pos (0UL) /*!< RTC_ALARM_HOS_EN (Bit 0) */ #define RTC_RTC_ALARM_ENABLE_REG_RTC_ALARM_HOS_EN_Msk (0x1UL) /*!< RTC_ALARM_HOS_EN (Bitfield-Mask: 0x01) */ /* ================================================ RTC_CALENDAR_ALARM_REG ================================================= */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_T_Pos (12UL) /*!< RTC_CAL_D_T (Bit 12) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_T_Msk (0x3000UL) /*!< RTC_CAL_D_T (Bitfield-Mask: 0x03) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_U_Pos (8UL) /*!< RTC_CAL_D_U (Bit 8) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_D_U_Msk (0xf00UL) /*!< RTC_CAL_D_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_T_Pos (7UL) /*!< RTC_CAL_M_T (Bit 7) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_T_Msk (0x80UL) /*!< RTC_CAL_M_T (Bitfield-Mask: 0x01) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_U_Pos (3UL) /*!< RTC_CAL_M_U (Bit 3) */ #define RTC_RTC_CALENDAR_ALARM_REG_RTC_CAL_M_U_Msk (0x78UL) /*!< RTC_CAL_M_U (Bitfield-Mask: 0x0f) */ /* =================================================== RTC_CALENDAR_REG ==================================================== */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_CH_Pos (31UL) /*!< RTC_CAL_CH (Bit 31) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_CH_Msk (0x80000000UL) /*!< RTC_CAL_CH (Bitfield-Mask: 0x01) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_C_T_Pos (28UL) /*!< RTC_CAL_C_T (Bit 28) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_C_T_Msk (0x30000000UL) /*!< RTC_CAL_C_T (Bitfield-Mask: 0x03) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_C_U_Pos (24UL) /*!< RTC_CAL_C_U (Bit 24) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_C_U_Msk (0xf000000UL) /*!< RTC_CAL_C_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_T_Pos (20UL) /*!< RTC_CAL_Y_T (Bit 20) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_T_Msk (0xf00000UL) /*!< RTC_CAL_Y_T (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_U_Pos (16UL) /*!< RTC_CAL_Y_U (Bit 16) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_Y_U_Msk (0xf0000UL) /*!< RTC_CAL_Y_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_D_T_Pos (12UL) /*!< RTC_CAL_D_T (Bit 12) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_D_T_Msk (0x3000UL) /*!< RTC_CAL_D_T (Bitfield-Mask: 0x03) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_D_U_Pos (8UL) /*!< RTC_CAL_D_U (Bit 8) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_D_U_Msk (0xf00UL) /*!< RTC_CAL_D_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_M_T_Pos (7UL) /*!< RTC_CAL_M_T (Bit 7) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_M_T_Msk (0x80UL) /*!< RTC_CAL_M_T (Bitfield-Mask: 0x01) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_M_U_Pos (3UL) /*!< RTC_CAL_M_U (Bit 3) */ #define RTC_RTC_CALENDAR_REG_RTC_CAL_M_U_Msk (0x78UL) /*!< RTC_CAL_M_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_CALENDAR_REG_RTC_DAY_Pos (0UL) /*!< RTC_DAY (Bit 0) */ #define RTC_RTC_CALENDAR_REG_RTC_DAY_Msk (0x7UL) /*!< RTC_DAY (Bitfield-Mask: 0x07) */ /* ==================================================== RTC_CONTROL_REG ==================================================== */ #define RTC_RTC_CONTROL_REG_RTC_CAL_DISABLE_Pos (1UL) /*!< RTC_CAL_DISABLE (Bit 1) */ #define RTC_RTC_CONTROL_REG_RTC_CAL_DISABLE_Msk (0x2UL) /*!< RTC_CAL_DISABLE (Bitfield-Mask: 0x01) */ #define RTC_RTC_CONTROL_REG_RTC_TIME_DISABLE_Pos (0UL) /*!< RTC_TIME_DISABLE (Bit 0) */ #define RTC_RTC_CONTROL_REG_RTC_TIME_DISABLE_Msk (0x1UL) /*!< RTC_TIME_DISABLE (Bitfield-Mask: 0x01) */ /* ================================================== RTC_EVENT_CTRL_REG =================================================== */ #define RTC_RTC_EVENT_CTRL_REG_RTC_PDC_EVENT_EN_Pos (1UL) /*!< RTC_PDC_EVENT_EN (Bit 1) */ #define RTC_RTC_EVENT_CTRL_REG_RTC_PDC_EVENT_EN_Msk (0x2UL) /*!< RTC_PDC_EVENT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_CTRL_REG_RTC_MOTOR_EVENT_EN_Pos (0UL) /*!< RTC_MOTOR_EVENT_EN (Bit 0) */ #define RTC_RTC_EVENT_CTRL_REG_RTC_MOTOR_EVENT_EN_Msk (0x1UL) /*!< RTC_MOTOR_EVENT_EN (Bitfield-Mask: 0x01) */ /* ================================================== RTC_EVENT_FLAGS_REG ================================================== */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_ALRM_Pos (6UL) /*!< RTC_EVENT_ALRM (Bit 6) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_ALRM_Msk (0x40UL) /*!< RTC_EVENT_ALRM (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MNTH_Pos (5UL) /*!< RTC_EVENT_MNTH (Bit 5) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MNTH_Msk (0x20UL) /*!< RTC_EVENT_MNTH (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_DATE_Pos (4UL) /*!< RTC_EVENT_DATE (Bit 4) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_DATE_Msk (0x10UL) /*!< RTC_EVENT_DATE (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOUR_Pos (3UL) /*!< RTC_EVENT_HOUR (Bit 3) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOUR_Msk (0x8UL) /*!< RTC_EVENT_HOUR (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MIN_Pos (2UL) /*!< RTC_EVENT_MIN (Bit 2) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_MIN_Msk (0x4UL) /*!< RTC_EVENT_MIN (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_SEC_Pos (1UL) /*!< RTC_EVENT_SEC (Bit 1) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_SEC_Msk (0x2UL) /*!< RTC_EVENT_SEC (Bitfield-Mask: 0x01) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOS_Pos (0UL) /*!< RTC_EVENT_HOS (Bit 0) */ #define RTC_RTC_EVENT_FLAGS_REG_RTC_EVENT_HOS_Msk (0x1UL) /*!< RTC_EVENT_HOS (Bitfield-Mask: 0x01) */ /* =================================================== RTC_HOUR_MODE_REG =================================================== */ #define RTC_RTC_HOUR_MODE_REG_RTC_HMS_Pos (0UL) /*!< RTC_HMS (Bit 0) */ #define RTC_RTC_HOUR_MODE_REG_RTC_HMS_Msk (0x1UL) /*!< RTC_HMS (Bitfield-Mask: 0x01) */ /* =============================================== RTC_INTERRUPT_DISABLE_REG =============================================== */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_ALRM_INT_DIS_Pos (6UL) /*!< RTC_ALRM_INT_DIS (Bit 6) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_ALRM_INT_DIS_Msk (0x40UL) /*!< RTC_ALRM_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MNTH_INT_DIS_Pos (5UL) /*!< RTC_MNTH_INT_DIS (Bit 5) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MNTH_INT_DIS_Msk (0x20UL) /*!< RTC_MNTH_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_DATE_INT_DIS_Pos (4UL) /*!< RTC_DATE_INT_DIS (Bit 4) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_DATE_INT_DIS_Msk (0x10UL) /*!< RTC_DATE_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOUR_INT_DIS_Pos (3UL) /*!< RTC_HOUR_INT_DIS (Bit 3) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOUR_INT_DIS_Msk (0x8UL) /*!< RTC_HOUR_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MIN_INT_DIS_Pos (2UL) /*!< RTC_MIN_INT_DIS (Bit 2) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_MIN_INT_DIS_Msk (0x4UL) /*!< RTC_MIN_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_SEC_INT_DIS_Pos (1UL) /*!< RTC_SEC_INT_DIS (Bit 1) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_SEC_INT_DIS_Msk (0x2UL) /*!< RTC_SEC_INT_DIS (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOS_INT_DIS_Pos (0UL) /*!< RTC_HOS_INT_DIS (Bit 0) */ #define RTC_RTC_INTERRUPT_DISABLE_REG_RTC_HOS_INT_DIS_Msk (0x1UL) /*!< RTC_HOS_INT_DIS (Bitfield-Mask: 0x01) */ /* =============================================== RTC_INTERRUPT_ENABLE_REG ================================================ */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_ALRM_INT_EN_Pos (6UL) /*!< RTC_ALRM_INT_EN (Bit 6) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_ALRM_INT_EN_Msk (0x40UL) /*!< RTC_ALRM_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MNTH_INT_EN_Pos (5UL) /*!< RTC_MNTH_INT_EN (Bit 5) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MNTH_INT_EN_Msk (0x20UL) /*!< RTC_MNTH_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_DATE_INT_EN_Pos (4UL) /*!< RTC_DATE_INT_EN (Bit 4) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_DATE_INT_EN_Msk (0x10UL) /*!< RTC_DATE_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOUR_INT_EN_Pos (3UL) /*!< RTC_HOUR_INT_EN (Bit 3) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOUR_INT_EN_Msk (0x8UL) /*!< RTC_HOUR_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MIN_INT_EN_Pos (2UL) /*!< RTC_MIN_INT_EN (Bit 2) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_MIN_INT_EN_Msk (0x4UL) /*!< RTC_MIN_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_SEC_INT_EN_Pos (1UL) /*!< RTC_SEC_INT_EN (Bit 1) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_SEC_INT_EN_Msk (0x2UL) /*!< RTC_SEC_INT_EN (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOS_INT_EN_Pos (0UL) /*!< RTC_HOS_INT_EN (Bit 0) */ #define RTC_RTC_INTERRUPT_ENABLE_REG_RTC_HOS_INT_EN_Msk (0x1UL) /*!< RTC_HOS_INT_EN (Bitfield-Mask: 0x01) */ /* ================================================ RTC_INTERRUPT_MASK_REG ================================================= */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_ALRM_INT_MSK_Pos (6UL) /*!< RTC_ALRM_INT_MSK (Bit 6) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_ALRM_INT_MSK_Msk (0x40UL) /*!< RTC_ALRM_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_MNTH_INT_MSK_Pos (5UL) /*!< RTC_MNTH_INT_MSK (Bit 5) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_MNTH_INT_MSK_Msk (0x20UL) /*!< RTC_MNTH_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_DATE_INT_MSK_Pos (4UL) /*!< RTC_DATE_INT_MSK (Bit 4) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_DATE_INT_MSK_Msk (0x10UL) /*!< RTC_DATE_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOUR_INT_MSK_Pos (3UL) /*!< RTC_HOUR_INT_MSK (Bit 3) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOUR_INT_MSK_Msk (0x8UL) /*!< RTC_HOUR_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_MIN_INT_MSK_Pos (2UL) /*!< RTC_MIN_INT_MSK (Bit 2) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_MIN_INT_MSK_Msk (0x4UL) /*!< RTC_MIN_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_SEC_INT_MSK_Pos (1UL) /*!< RTC_SEC_INT_MSK (Bit 1) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_SEC_INT_MSK_Msk (0x2UL) /*!< RTC_SEC_INT_MSK (Bitfield-Mask: 0x01) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOS_INT_MSK_Pos (0UL) /*!< RTC_HOS_INT_MSK (Bit 0) */ #define RTC_RTC_INTERRUPT_MASK_REG_RTC_HOS_INT_MSK_Msk (0x1UL) /*!< RTC_HOS_INT_MSK (Bitfield-Mask: 0x01) */ /* =================================================== RTC_KEEP_RTC_REG ==================================================== */ #define RTC_RTC_KEEP_RTC_REG_RTC_KEEP_Pos (0UL) /*!< RTC_KEEP (Bit 0) */ #define RTC_RTC_KEEP_RTC_REG_RTC_KEEP_Msk (0x1UL) /*!< RTC_KEEP (Bitfield-Mask: 0x01) */ /* ================================================ RTC_MOTOR_EVENT_CNT_REG ================================================ */ #define RTC_RTC_MOTOR_EVENT_CNT_REG_RTC_MOTOR_EVENT_CNT_Pos (0UL) /*!< RTC_MOTOR_EVENT_CNT (Bit 0) */ #define RTC_RTC_MOTOR_EVENT_CNT_REG_RTC_MOTOR_EVENT_CNT_Msk (0xfffUL) /*!< RTC_MOTOR_EVENT_CNT (Bitfield-Mask: 0xfff) */ /* ============================================== RTC_MOTOR_EVENT_PERIOD_REG =============================================== */ #define RTC_RTC_MOTOR_EVENT_PERIOD_REG_RTC_MOTOR_EVENT_PERIOD_Pos (0UL) /*!< RTC_MOTOR_EVENT_PERIOD (Bit 0) */ #define RTC_RTC_MOTOR_EVENT_PERIOD_REG_RTC_MOTOR_EVENT_PERIOD_Msk (0xfffUL) /*!< RTC_MOTOR_EVENT_PERIOD (Bitfield-Mask: 0xfff) */ /* ================================================ RTC_PDC_EVENT_CLEAR_REG ================================================ */ #define RTC_RTC_PDC_EVENT_CLEAR_REG_PDC_EVENT_CLEAR_Pos (0UL) /*!< PDC_EVENT_CLEAR (Bit 0) */ #define RTC_RTC_PDC_EVENT_CLEAR_REG_PDC_EVENT_CLEAR_Msk (0x1UL) /*!< PDC_EVENT_CLEAR (Bitfield-Mask: 0x01) */ /* ================================================= RTC_PDC_EVENT_CNT_REG ================================================= */ #define RTC_RTC_PDC_EVENT_CNT_REG_RTC_PDC_EVENT_CNT_Pos (0UL) /*!< RTC_PDC_EVENT_CNT (Bit 0) */ #define RTC_RTC_PDC_EVENT_CNT_REG_RTC_PDC_EVENT_CNT_Msk (0x1fffUL) /*!< RTC_PDC_EVENT_CNT (Bitfield-Mask: 0x1fff) */ /* =============================================== RTC_PDC_EVENT_PERIOD_REG ================================================ */ #define RTC_RTC_PDC_EVENT_PERIOD_REG_RTC_PDC_EVENT_PERIOD_Pos (0UL) /*!< RTC_PDC_EVENT_PERIOD (Bit 0) */ #define RTC_RTC_PDC_EVENT_PERIOD_REG_RTC_PDC_EVENT_PERIOD_Msk (0x1fffUL) /*!< RTC_PDC_EVENT_PERIOD (Bitfield-Mask: 0x1fff) */ /* ==================================================== RTC_STATUS_REG ===================================================== */ #define RTC_RTC_STATUS_REG_RTC_VALID_CAL_ALM_Pos (3UL) /*!< RTC_VALID_CAL_ALM (Bit 3) */ #define RTC_RTC_STATUS_REG_RTC_VALID_CAL_ALM_Msk (0x8UL) /*!< RTC_VALID_CAL_ALM (Bitfield-Mask: 0x01) */ #define RTC_RTC_STATUS_REG_RTC_VALID_TIME_ALM_Pos (2UL) /*!< RTC_VALID_TIME_ALM (Bit 2) */ #define RTC_RTC_STATUS_REG_RTC_VALID_TIME_ALM_Msk (0x4UL) /*!< RTC_VALID_TIME_ALM (Bitfield-Mask: 0x01) */ #define RTC_RTC_STATUS_REG_RTC_VALID_CAL_Pos (1UL) /*!< RTC_VALID_CAL (Bit 1) */ #define RTC_RTC_STATUS_REG_RTC_VALID_CAL_Msk (0x2UL) /*!< RTC_VALID_CAL (Bitfield-Mask: 0x01) */ #define RTC_RTC_STATUS_REG_RTC_VALID_TIME_Pos (0UL) /*!< RTC_VALID_TIME (Bit 0) */ #define RTC_RTC_STATUS_REG_RTC_VALID_TIME_Msk (0x1UL) /*!< RTC_VALID_TIME (Bitfield-Mask: 0x01) */ /* ================================================== RTC_TIME_ALARM_REG =================================================== */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_PM_Pos (30UL) /*!< RTC_TIME_PM (Bit 30) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_PM_Msk (0x40000000UL) /*!< RTC_TIME_PM (Bitfield-Mask: 0x01) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_T_Pos (28UL) /*!< RTC_TIME_HR_T (Bit 28) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_T_Msk (0x30000000UL) /*!< RTC_TIME_HR_T (Bitfield-Mask: 0x03) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_U_Pos (24UL) /*!< RTC_TIME_HR_U (Bit 24) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_HR_U_Msk (0xf000000UL) /*!< RTC_TIME_HR_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_T_Pos (20UL) /*!< RTC_TIME_M_T (Bit 20) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_T_Msk (0x700000UL) /*!< RTC_TIME_M_T (Bitfield-Mask: 0x07) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_U_Pos (16UL) /*!< RTC_TIME_M_U (Bit 16) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_M_U_Msk (0xf0000UL) /*!< RTC_TIME_M_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_T_Pos (12UL) /*!< RTC_TIME_S_T (Bit 12) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_T_Msk (0x7000UL) /*!< RTC_TIME_S_T (Bitfield-Mask: 0x07) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_U_Pos (8UL) /*!< RTC_TIME_S_U (Bit 8) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_S_U_Msk (0xf00UL) /*!< RTC_TIME_S_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_T_Pos (4UL) /*!< RTC_TIME_H_T (Bit 4) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_T_Msk (0xf0UL) /*!< RTC_TIME_H_T (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_U_Pos (0UL) /*!< RTC_TIME_H_U (Bit 0) */ #define RTC_RTC_TIME_ALARM_REG_RTC_TIME_H_U_Msk (0xfUL) /*!< RTC_TIME_H_U (Bitfield-Mask: 0x0f) */ /* ===================================================== RTC_TIME_REG ====================================================== */ #define RTC_RTC_TIME_REG_RTC_TIME_CH_Pos (31UL) /*!< RTC_TIME_CH (Bit 31) */ #define RTC_RTC_TIME_REG_RTC_TIME_CH_Msk (0x80000000UL) /*!< RTC_TIME_CH (Bitfield-Mask: 0x01) */ #define RTC_RTC_TIME_REG_RTC_TIME_PM_Pos (30UL) /*!< RTC_TIME_PM (Bit 30) */ #define RTC_RTC_TIME_REG_RTC_TIME_PM_Msk (0x40000000UL) /*!< RTC_TIME_PM (Bitfield-Mask: 0x01) */ #define RTC_RTC_TIME_REG_RTC_TIME_HR_T_Pos (28UL) /*!< RTC_TIME_HR_T (Bit 28) */ #define RTC_RTC_TIME_REG_RTC_TIME_HR_T_Msk (0x30000000UL) /*!< RTC_TIME_HR_T (Bitfield-Mask: 0x03) */ #define RTC_RTC_TIME_REG_RTC_TIME_HR_U_Pos (24UL) /*!< RTC_TIME_HR_U (Bit 24) */ #define RTC_RTC_TIME_REG_RTC_TIME_HR_U_Msk (0xf000000UL) /*!< RTC_TIME_HR_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_REG_RTC_TIME_M_T_Pos (20UL) /*!< RTC_TIME_M_T (Bit 20) */ #define RTC_RTC_TIME_REG_RTC_TIME_M_T_Msk (0x700000UL) /*!< RTC_TIME_M_T (Bitfield-Mask: 0x07) */ #define RTC_RTC_TIME_REG_RTC_TIME_M_U_Pos (16UL) /*!< RTC_TIME_M_U (Bit 16) */ #define RTC_RTC_TIME_REG_RTC_TIME_M_U_Msk (0xf0000UL) /*!< RTC_TIME_M_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_REG_RTC_TIME_S_T_Pos (12UL) /*!< RTC_TIME_S_T (Bit 12) */ #define RTC_RTC_TIME_REG_RTC_TIME_S_T_Msk (0x7000UL) /*!< RTC_TIME_S_T (Bitfield-Mask: 0x07) */ #define RTC_RTC_TIME_REG_RTC_TIME_S_U_Pos (8UL) /*!< RTC_TIME_S_U (Bit 8) */ #define RTC_RTC_TIME_REG_RTC_TIME_S_U_Msk (0xf00UL) /*!< RTC_TIME_S_U (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_REG_RTC_TIME_H_T_Pos (4UL) /*!< RTC_TIME_H_T (Bit 4) */ #define RTC_RTC_TIME_REG_RTC_TIME_H_T_Msk (0xf0UL) /*!< RTC_TIME_H_T (Bitfield-Mask: 0x0f) */ #define RTC_RTC_TIME_REG_RTC_TIME_H_U_Pos (0UL) /*!< RTC_TIME_H_U (Bit 0) */ #define RTC_RTC_TIME_REG_RTC_TIME_H_U_Msk (0xfUL) /*!< RTC_TIME_H_U (Bitfield-Mask: 0x0f) */ /* =========================================================================================================================== */ /* ================ SDADC ================ */ /* =========================================================================================================================== */ /* ================================================== SDADC_CLEAR_INT_REG ================================================== */ #define SDADC_SDADC_CLEAR_INT_REG_SDADC_CLR_INT_Pos (0UL) /*!< SDADC_CLR_INT (Bit 0) */ #define SDADC_SDADC_CLEAR_INT_REG_SDADC_CLR_INT_Msk (0xffffUL) /*!< SDADC_CLR_INT (Bitfield-Mask: 0xffff) */ /* ==================================================== SDADC_CTRL_REG ===================================================== */ #define SDADC_SDADC_CTRL_REG_SDADC_DMA_EN_Pos (17UL) /*!< SDADC_DMA_EN (Bit 17) */ #define SDADC_SDADC_CTRL_REG_SDADC_DMA_EN_Msk (0x20000UL) /*!< SDADC_DMA_EN (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_MINT_Pos (16UL) /*!< SDADC_MINT (Bit 16) */ #define SDADC_SDADC_CTRL_REG_SDADC_MINT_Msk (0x10000UL) /*!< SDADC_MINT (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_INT_Pos (15UL) /*!< SDADC_INT (Bit 15) */ #define SDADC_SDADC_CTRL_REG_SDADC_INT_Msk (0x8000UL) /*!< SDADC_INT (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_LDO_OK_Pos (14UL) /*!< SDADC_LDO_OK (Bit 14) */ #define SDADC_SDADC_CTRL_REG_SDADC_LDO_OK_Msk (0x4000UL) /*!< SDADC_LDO_OK (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_VREF_SEL_Pos (13UL) /*!< SDADC_VREF_SEL (Bit 13) */ #define SDADC_SDADC_CTRL_REG_SDADC_VREF_SEL_Msk (0x2000UL) /*!< SDADC_VREF_SEL (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_CONT_Pos (12UL) /*!< SDADC_CONT (Bit 12) */ #define SDADC_SDADC_CTRL_REG_SDADC_CONT_Msk (0x1000UL) /*!< SDADC_CONT (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_OSR_Pos (10UL) /*!< SDADC_OSR (Bit 10) */ #define SDADC_SDADC_CTRL_REG_SDADC_OSR_Msk (0xc00UL) /*!< SDADC_OSR (Bitfield-Mask: 0x03) */ #define SDADC_SDADC_CTRL_REG_SDADC_SE_Pos (9UL) /*!< SDADC_SE (Bit 9) */ #define SDADC_SDADC_CTRL_REG_SDADC_SE_Msk (0x200UL) /*!< SDADC_SE (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_INN_SEL_Pos (6UL) /*!< SDADC_INN_SEL (Bit 6) */ #define SDADC_SDADC_CTRL_REG_SDADC_INN_SEL_Msk (0x1c0UL) /*!< SDADC_INN_SEL (Bitfield-Mask: 0x07) */ #define SDADC_SDADC_CTRL_REG_SDADC_INP_SEL_Pos (2UL) /*!< SDADC_INP_SEL (Bit 2) */ #define SDADC_SDADC_CTRL_REG_SDADC_INP_SEL_Msk (0x3cUL) /*!< SDADC_INP_SEL (Bitfield-Mask: 0x0f) */ #define SDADC_SDADC_CTRL_REG_SDADC_START_Pos (1UL) /*!< SDADC_START (Bit 1) */ #define SDADC_SDADC_CTRL_REG_SDADC_START_Msk (0x2UL) /*!< SDADC_START (Bitfield-Mask: 0x01) */ #define SDADC_SDADC_CTRL_REG_SDADC_EN_Pos (0UL) /*!< SDADC_EN (Bit 0) */ #define SDADC_SDADC_CTRL_REG_SDADC_EN_Msk (0x1UL) /*!< SDADC_EN (Bitfield-Mask: 0x01) */ /* ================================================== SDADC_GAIN_CORR_REG ================================================== */ #define SDADC_SDADC_GAIN_CORR_REG_SDADC_GAIN_CORR_Pos (0UL) /*!< SDADC_GAIN_CORR (Bit 0) */ #define SDADC_SDADC_GAIN_CORR_REG_SDADC_GAIN_CORR_Msk (0x3ffUL) /*!< SDADC_GAIN_CORR (Bitfield-Mask: 0x3ff) */ /* ================================================== SDADC_OFFS_CORR_REG ================================================== */ #define SDADC_SDADC_OFFS_CORR_REG_SDADC_OFFS_CORR_Pos (0UL) /*!< SDADC_OFFS_CORR (Bit 0) */ #define SDADC_SDADC_OFFS_CORR_REG_SDADC_OFFS_CORR_Msk (0x3ffUL) /*!< SDADC_OFFS_CORR (Bitfield-Mask: 0x3ff) */ /* =================================================== SDADC_RESULT_REG ==================================================== */ #define SDADC_SDADC_RESULT_REG_SDADC_VAL_Pos (0UL) /*!< SDADC_VAL (Bit 0) */ #define SDADC_SDADC_RESULT_REG_SDADC_VAL_Msk (0xffffUL) /*!< SDADC_VAL (Bitfield-Mask: 0xffff) */ /* ==================================================== SDADC_TEST_REG ===================================================== */ #define SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Pos (6UL) /*!< SDADC_CLK_FREQ (Bit 6) */ #define SDADC_SDADC_TEST_REG_SDADC_CLK_FREQ_Msk (0xc0UL) /*!< SDADC_CLK_FREQ (Bitfield-Mask: 0x03) */ /* =========================================================================================================================== */ /* ================ SMOTOR ================ */ /* =========================================================================================================================== */ /* ==================================================== CMD_TABLE_BASE ===================================================== */ /* ===================================================== PG0_CTRL_REG ====================================================== */ #define SMOTOR_PG0_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ #define SMOTOR_PG0_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ #define SMOTOR_PG0_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ #define SMOTOR_PG0_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ #define SMOTOR_PG0_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ #define SMOTOR_PG0_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ #define SMOTOR_PG0_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ #define SMOTOR_PG0_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ #define SMOTOR_PG0_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG0_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ #define SMOTOR_PG0_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG0_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ #define SMOTOR_PG0_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG0_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ #define SMOTOR_PG0_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG0_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ #define SMOTOR_PG0_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ /* ===================================================== PG1_CTRL_REG ====================================================== */ #define SMOTOR_PG1_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ #define SMOTOR_PG1_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ #define SMOTOR_PG1_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ #define SMOTOR_PG1_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ #define SMOTOR_PG1_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ #define SMOTOR_PG1_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ #define SMOTOR_PG1_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ #define SMOTOR_PG1_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ #define SMOTOR_PG1_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG1_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ #define SMOTOR_PG1_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG1_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ #define SMOTOR_PG1_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG1_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ #define SMOTOR_PG1_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG1_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ #define SMOTOR_PG1_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ /* ===================================================== PG2_CTRL_REG ====================================================== */ #define SMOTOR_PG2_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ #define SMOTOR_PG2_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ #define SMOTOR_PG2_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ #define SMOTOR_PG2_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ #define SMOTOR_PG2_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ #define SMOTOR_PG2_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ #define SMOTOR_PG2_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ #define SMOTOR_PG2_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ #define SMOTOR_PG2_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG2_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ #define SMOTOR_PG2_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG2_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ #define SMOTOR_PG2_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG2_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ #define SMOTOR_PG2_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG2_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ #define SMOTOR_PG2_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ /* ===================================================== PG3_CTRL_REG ====================================================== */ #define SMOTOR_PG3_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ #define SMOTOR_PG3_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ #define SMOTOR_PG3_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ #define SMOTOR_PG3_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ #define SMOTOR_PG3_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ #define SMOTOR_PG3_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ #define SMOTOR_PG3_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ #define SMOTOR_PG3_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ #define SMOTOR_PG3_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG3_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ #define SMOTOR_PG3_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG3_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ #define SMOTOR_PG3_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG3_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ #define SMOTOR_PG3_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG3_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ #define SMOTOR_PG3_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ /* ===================================================== PG4_CTRL_REG ====================================================== */ #define SMOTOR_PG4_CTRL_REG_GENEND_IRQ_EN_Pos (15UL) /*!< GENEND_IRQ_EN (Bit 15) */ #define SMOTOR_PG4_CTRL_REG_GENEND_IRQ_EN_Msk (0x8000UL) /*!< GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_GENSTART_IRQ_EN_Pos (14UL) /*!< GENSTART_IRQ_EN (Bit 14) */ #define SMOTOR_PG4_CTRL_REG_GENSTART_IRQ_EN_Msk (0x4000UL) /*!< GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_PG_START_MODE_Pos (13UL) /*!< PG_START_MODE (Bit 13) */ #define SMOTOR_PG4_CTRL_REG_PG_START_MODE_Msk (0x2000UL) /*!< PG_START_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_PG_MODE_Pos (12UL) /*!< PG_MODE (Bit 12) */ #define SMOTOR_PG4_CTRL_REG_PG_MODE_Msk (0x1000UL) /*!< PG_MODE (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_SIG3_EN_Pos (11UL) /*!< SIG3_EN (Bit 11) */ #define SMOTOR_PG4_CTRL_REG_SIG3_EN_Msk (0x800UL) /*!< SIG3_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_SIG2_EN_Pos (10UL) /*!< SIG2_EN (Bit 10) */ #define SMOTOR_PG4_CTRL_REG_SIG2_EN_Msk (0x400UL) /*!< SIG2_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_SIG1_EN_Pos (9UL) /*!< SIG1_EN (Bit 9) */ #define SMOTOR_PG4_CTRL_REG_SIG1_EN_Msk (0x200UL) /*!< SIG1_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_SIG0_EN_Pos (8UL) /*!< SIG0_EN (Bit 8) */ #define SMOTOR_PG4_CTRL_REG_SIG0_EN_Msk (0x100UL) /*!< SIG0_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_PG4_CTRL_REG_OUT3_SIG_Pos (6UL) /*!< OUT3_SIG (Bit 6) */ #define SMOTOR_PG4_CTRL_REG_OUT3_SIG_Msk (0xc0UL) /*!< OUT3_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG4_CTRL_REG_OUT2_SIG_Pos (4UL) /*!< OUT2_SIG (Bit 4) */ #define SMOTOR_PG4_CTRL_REG_OUT2_SIG_Msk (0x30UL) /*!< OUT2_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG4_CTRL_REG_OUT1_SIG_Pos (2UL) /*!< OUT1_SIG (Bit 2) */ #define SMOTOR_PG4_CTRL_REG_OUT1_SIG_Msk (0xcUL) /*!< OUT1_SIG (Bitfield-Mask: 0x03) */ #define SMOTOR_PG4_CTRL_REG_OUT0_SIG_Pos (0UL) /*!< OUT0_SIG (Bit 0) */ #define SMOTOR_PG4_CTRL_REG_OUT0_SIG_Msk (0x3UL) /*!< OUT0_SIG (Bitfield-Mask: 0x03) */ /* ================================================== SMOTOR_CMD_FIFO_REG ================================================== */ #define SMOTOR_SMOTOR_CMD_FIFO_REG_SMOTOR_CMD_FIFO_Pos (0UL) /*!< SMOTOR_CMD_FIFO (Bit 0) */ #define SMOTOR_SMOTOR_CMD_FIFO_REG_SMOTOR_CMD_FIFO_Msk (0xffffUL) /*!< SMOTOR_CMD_FIFO (Bitfield-Mask: 0xffff) */ /* ================================================ SMOTOR_CMD_READ_PTR_REG ================================================ */ #define SMOTOR_SMOTOR_CMD_READ_PTR_REG_SMOTOR_CMD_READ_PTR_Pos (0UL) /*!< SMOTOR_CMD_READ_PTR (Bit 0) */ #define SMOTOR_SMOTOR_CMD_READ_PTR_REG_SMOTOR_CMD_READ_PTR_Msk (0x3fUL) /*!< SMOTOR_CMD_READ_PTR (Bitfield-Mask: 0x3f) */ /* =============================================== SMOTOR_CMD_WRITE_PTR_REG ================================================ */ #define SMOTOR_SMOTOR_CMD_WRITE_PTR_REG_SMOTOR_CMD_WRITE_PTR_Pos (0UL) /*!< SMOTOR_CMD_WRITE_PTR (Bit 0) */ #define SMOTOR_SMOTOR_CMD_WRITE_PTR_REG_SMOTOR_CMD_WRITE_PTR_Msk (0x3fUL) /*!< SMOTOR_CMD_WRITE_PTR (Bitfield-Mask: 0x3f) */ /* ==================================================== SMOTOR_CTRL_REG ==================================================== */ #define SMOTOR_SMOTOR_CTRL_REG_TRIG_RTC_EVENT_EN_Pos (28UL) /*!< TRIG_RTC_EVENT_EN (Bit 28) */ #define SMOTOR_SMOTOR_CTRL_REG_TRIG_RTC_EVENT_EN_Msk (0x10000000UL) /*!< TRIG_RTC_EVENT_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_MC_LP_CLK_TRIG_EN_Pos (27UL) /*!< MC_LP_CLK_TRIG_EN (Bit 27) */ #define SMOTOR_SMOTOR_CTRL_REG_MC_LP_CLK_TRIG_EN_Msk (0x8000000UL) /*!< MC_LP_CLK_TRIG_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_IRQ_EN_Pos (26UL) /*!< SMOTOR_THRESHOLD_IRQ_EN (Bit 26) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_IRQ_EN_Msk (0x4000000UL) /*!< SMOTOR_THRESHOLD_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_Pos (21UL) /*!< SMOTOR_THRESHOLD (Bit 21) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_THRESHOLD_Msk (0x3e00000UL) /*!< SMOTOR_THRESHOLD (Bitfield-Mask: 0x1f) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_UNR_IRQ_EN_Pos (20UL) /*!< SMOTOR_FIFO_UNR_IRQ_EN (Bit 20) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_UNR_IRQ_EN_Msk (0x100000UL) /*!< SMOTOR_FIFO_UNR_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_OVF_IRQ_EN_Pos (19UL) /*!< SMOTOR_FIFO_OVF_IRQ_EN (Bit 19) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_FIFO_OVF_IRQ_EN_Msk (0x80000UL) /*!< SMOTOR_FIFO_OVF_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENEND_IRQ_EN_Pos (18UL) /*!< SMOTOR_GENEND_IRQ_EN (Bit 18) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENEND_IRQ_EN_Msk (0x40000UL) /*!< SMOTOR_GENEND_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENSTART_IRQ_EN_Pos (17UL) /*!< SMOTOR_GENSTART_IRQ_EN (Bit 17) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_GENSTART_IRQ_EN_Msk (0x20000UL) /*!< SMOTOR_GENSTART_IRQ_EN (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_MOI_Pos (7UL) /*!< SMOTOR_MOI (Bit 7) */ #define SMOTOR_SMOTOR_CTRL_REG_SMOTOR_MOI_Msk (0x1ff80UL) /*!< SMOTOR_MOI (Bitfield-Mask: 0x3ff) */ #define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_SIZE_Pos (1UL) /*!< CYCLIC_SIZE (Bit 1) */ #define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_SIZE_Msk (0x7eUL) /*!< CYCLIC_SIZE (Bitfield-Mask: 0x3f) */ #define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_MODE_Pos (0UL) /*!< CYCLIC_MODE (Bit 0) */ #define SMOTOR_SMOTOR_CTRL_REG_CYCLIC_MODE_Msk (0x1UL) /*!< CYCLIC_MODE (Bitfield-Mask: 0x01) */ /* ================================================= SMOTOR_IRQ_CLEAR_REG ================================================== */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_THRESHOLD_IRQ_CLEAR_Pos (4UL) /*!< THRESHOLD_IRQ_CLEAR (Bit 4) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_THRESHOLD_IRQ_CLEAR_Msk (0x10UL) /*!< THRESHOLD_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_UNR_IRQ_CLEAR_Pos (3UL) /*!< FIFO_UNR_IRQ_CLEAR (Bit 3) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_UNR_IRQ_CLEAR_Msk (0x8UL) /*!< FIFO_UNR_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_OVF_IRQ_CLEAR_Pos (2UL) /*!< FIFO_OVF_IRQ_CLEAR (Bit 2) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_FIFO_OVF_IRQ_CLEAR_Msk (0x4UL) /*!< FIFO_OVF_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENEND_IRQ_CLEAR_Pos (1UL) /*!< GENEND_IRQ_CLEAR (Bit 1) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENEND_IRQ_CLEAR_Msk (0x2UL) /*!< GENEND_IRQ_CLEAR (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENSTART_IRQ_CLEAR_Pos (0UL) /*!< GENSTART_IRQ_CLEAR (Bit 0) */ #define SMOTOR_SMOTOR_IRQ_CLEAR_REG_GENSTART_IRQ_CLEAR_Msk (0x1UL) /*!< GENSTART_IRQ_CLEAR (Bitfield-Mask: 0x01) */ /* =================================================== SMOTOR_STATUS_REG =================================================== */ #define SMOTOR_SMOTOR_STATUS_REG_PG4_BUSY_Pos (9UL) /*!< PG4_BUSY (Bit 9) */ #define SMOTOR_SMOTOR_STATUS_REG_PG4_BUSY_Msk (0x200UL) /*!< PG4_BUSY (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_PG3_BUSY_Pos (8UL) /*!< PG3_BUSY (Bit 8) */ #define SMOTOR_SMOTOR_STATUS_REG_PG3_BUSY_Msk (0x100UL) /*!< PG3_BUSY (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_PG2_BUSY_Pos (7UL) /*!< PG2_BUSY (Bit 7) */ #define SMOTOR_SMOTOR_STATUS_REG_PG2_BUSY_Msk (0x80UL) /*!< PG2_BUSY (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_PG1_BUSY_Pos (6UL) /*!< PG1_BUSY (Bit 6) */ #define SMOTOR_SMOTOR_STATUS_REG_PG1_BUSY_Msk (0x40UL) /*!< PG1_BUSY (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_PG0_BUSY_Pos (5UL) /*!< PG0_BUSY (Bit 5) */ #define SMOTOR_SMOTOR_STATUS_REG_PG0_BUSY_Msk (0x20UL) /*!< PG0_BUSY (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_THRESHOLD_IRQ_STATUS_Pos (4UL) /*!< THRESHOLD_IRQ_STATUS (Bit 4) */ #define SMOTOR_SMOTOR_STATUS_REG_THRESHOLD_IRQ_STATUS_Msk (0x10UL) /*!< THRESHOLD_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_FIFO_UNR_IRQ_STATUS_Pos (3UL) /*!< FIFO_UNR_IRQ_STATUS (Bit 3) */ #define SMOTOR_SMOTOR_STATUS_REG_FIFO_UNR_IRQ_STATUS_Msk (0x8UL) /*!< FIFO_UNR_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_FIFO_OVF_IRQ_STATUS_Pos (2UL) /*!< FIFO_OVF_IRQ_STATUS (Bit 2) */ #define SMOTOR_SMOTOR_STATUS_REG_FIFO_OVF_IRQ_STATUS_Msk (0x4UL) /*!< FIFO_OVF_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_GENEND_IRQ_STATUS_Pos (1UL) /*!< GENEND_IRQ_STATUS (Bit 1) */ #define SMOTOR_SMOTOR_STATUS_REG_GENEND_IRQ_STATUS_Msk (0x2UL) /*!< GENEND_IRQ_STATUS (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_STATUS_REG_GENSTART_IRQ_STATUS_Pos (0UL) /*!< GENSTART_IRQ_STATUS (Bit 0) */ #define SMOTOR_SMOTOR_STATUS_REG_GENSTART_IRQ_STATUS_Msk (0x1UL) /*!< GENSTART_IRQ_STATUS (Bitfield-Mask: 0x01) */ /* ================================================== SMOTOR_TRIGGER_REG =================================================== */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG4_START_Pos (5UL) /*!< PG4_START (Bit 5) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG4_START_Msk (0x20UL) /*!< PG4_START (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG3_START_Pos (4UL) /*!< PG3_START (Bit 4) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG3_START_Msk (0x10UL) /*!< PG3_START (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG2_START_Pos (3UL) /*!< PG2_START (Bit 3) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG2_START_Msk (0x8UL) /*!< PG2_START (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG1_START_Pos (2UL) /*!< PG1_START (Bit 2) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG1_START_Msk (0x4UL) /*!< PG1_START (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG0_START_Pos (1UL) /*!< PG0_START (Bit 1) */ #define SMOTOR_SMOTOR_TRIGGER_REG_PG0_START_Msk (0x2UL) /*!< PG0_START (Bitfield-Mask: 0x01) */ #define SMOTOR_SMOTOR_TRIGGER_REG_POP_CMD_Pos (0UL) /*!< POP_CMD (Bit 0) */ #define SMOTOR_SMOTOR_TRIGGER_REG_POP_CMD_Msk (0x1UL) /*!< POP_CMD (Bitfield-Mask: 0x01) */ /* ==================================================== WAVETABLE_BASE ===================================================== */ /* =========================================================================================================================== */ /* ================ SNC ================ */ /* =========================================================================================================================== */ /* ===================================================== SNC_CTRL_REG ====================================================== */ #define SNC_SNC_CTRL_REG_SNC_IRQ_ACK_Pos (8UL) /*!< SNC_IRQ_ACK (Bit 8) */ #define SNC_SNC_CTRL_REG_SNC_IRQ_ACK_Msk (0x100UL) /*!< SNC_IRQ_ACK (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_SNC_IRQ_CONFIG_Pos (6UL) /*!< SNC_IRQ_CONFIG (Bit 6) */ #define SNC_SNC_CTRL_REG_SNC_IRQ_CONFIG_Msk (0xc0UL) /*!< SNC_IRQ_CONFIG (Bitfield-Mask: 0x03) */ #define SNC_SNC_CTRL_REG_SNC_IRQ_EN_Pos (5UL) /*!< SNC_IRQ_EN (Bit 5) */ #define SNC_SNC_CTRL_REG_SNC_IRQ_EN_Msk (0x20UL) /*!< SNC_IRQ_EN (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_SNC_BRANCH_LOOP_INIT_Pos (4UL) /*!< SNC_BRANCH_LOOP_INIT (Bit 4) */ #define SNC_SNC_CTRL_REG_SNC_BRANCH_LOOP_INIT_Msk (0x10UL) /*!< SNC_BRANCH_LOOP_INIT (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_SNC_RESET_Pos (3UL) /*!< SNC_RESET (Bit 3) */ #define SNC_SNC_CTRL_REG_SNC_RESET_Msk (0x8UL) /*!< SNC_RESET (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_BUS_ERROR_DETECT_EN_Pos (2UL) /*!< BUS_ERROR_DETECT_EN (Bit 2) */ #define SNC_SNC_CTRL_REG_BUS_ERROR_DETECT_EN_Msk (0x4UL) /*!< BUS_ERROR_DETECT_EN (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_SNC_SW_CTRL_Pos (1UL) /*!< SNC_SW_CTRL (Bit 1) */ #define SNC_SNC_CTRL_REG_SNC_SW_CTRL_Msk (0x2UL) /*!< SNC_SW_CTRL (Bitfield-Mask: 0x01) */ #define SNC_SNC_CTRL_REG_SNC_EN_Pos (0UL) /*!< SNC_EN (Bit 0) */ #define SNC_SNC_CTRL_REG_SNC_EN_Msk (0x1UL) /*!< SNC_EN (Bitfield-Mask: 0x01) */ /* =================================================== SNC_LP_TIMER_REG ==================================================== */ #define SNC_SNC_LP_TIMER_REG_LP_TIMER_Pos (0UL) /*!< LP_TIMER (Bit 0) */ #define SNC_SNC_LP_TIMER_REG_LP_TIMER_Msk (0xffUL) /*!< LP_TIMER (Bitfield-Mask: 0xff) */ /* ====================================================== SNC_PC_REG ======================================================= */ #define SNC_SNC_PC_REG_PC_REG_Pos (2UL) /*!< PC_REG (Bit 2) */ #define SNC_SNC_PC_REG_PC_REG_Msk (0x7fffcUL) /*!< PC_REG (Bitfield-Mask: 0x1ffff) */ /* ====================================================== SNC_R1_REG ======================================================= */ #define SNC_SNC_R1_REG_R1_REG_Pos (0UL) /*!< R1_REG (Bit 0) */ #define SNC_SNC_R1_REG_R1_REG_Msk (0xffffffffUL) /*!< R1_REG (Bitfield-Mask: 0xffffffff) */ /* ====================================================== SNC_R2_REG ======================================================= */ #define SNC_SNC_R2_REG_R2_REG_Pos (0UL) /*!< R2_REG (Bit 0) */ #define SNC_SNC_R2_REG_R2_REG_Msk (0xffffffffUL) /*!< R2_REG (Bitfield-Mask: 0xffffffff) */ /* ==================================================== SNC_STATUS_REG ===================================================== */ #define SNC_SNC_STATUS_REG_SNC_PC_LOADED_Pos (6UL) /*!< SNC_PC_LOADED (Bit 6) */ #define SNC_SNC_STATUS_REG_SNC_PC_LOADED_Msk (0x40UL) /*!< SNC_PC_LOADED (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_SNC_IS_STOPPED_Pos (5UL) /*!< SNC_IS_STOPPED (Bit 5) */ #define SNC_SNC_STATUS_REG_SNC_IS_STOPPED_Msk (0x20UL) /*!< SNC_IS_STOPPED (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_HARD_FAULT_STATUS_Pos (4UL) /*!< HARD_FAULT_STATUS (Bit 4) */ #define SNC_SNC_STATUS_REG_HARD_FAULT_STATUS_Msk (0x10UL) /*!< HARD_FAULT_STATUS (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_BUS_ERROR_STATUS_Pos (3UL) /*!< BUS_ERROR_STATUS (Bit 3) */ #define SNC_SNC_STATUS_REG_BUS_ERROR_STATUS_Msk (0x8UL) /*!< BUS_ERROR_STATUS (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_SNC_DONE_STATUS_Pos (2UL) /*!< SNC_DONE_STATUS (Bit 2) */ #define SNC_SNC_STATUS_REG_SNC_DONE_STATUS_Msk (0x4UL) /*!< SNC_DONE_STATUS (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_GR_FLAG_Pos (1UL) /*!< GR_FLAG (Bit 1) */ #define SNC_SNC_STATUS_REG_GR_FLAG_Msk (0x2UL) /*!< GR_FLAG (Bitfield-Mask: 0x01) */ #define SNC_SNC_STATUS_REG_EQ_FLAG_Pos (0UL) /*!< EQ_FLAG (Bit 0) */ #define SNC_SNC_STATUS_REG_EQ_FLAG_Msk (0x1UL) /*!< EQ_FLAG (Bitfield-Mask: 0x01) */ /* ===================================================== SNC_TMP1_REG ====================================================== */ #define SNC_SNC_TMP1_REG_TMP1_REG_Pos (0UL) /*!< TMP1_REG (Bit 0) */ #define SNC_SNC_TMP1_REG_TMP1_REG_Msk (0xffffffffUL) /*!< TMP1_REG (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SNC_TMP2_REG ====================================================== */ #define SNC_SNC_TMP2_REG_TMP2_REG_Pos (0UL) /*!< TMP2_REG (Bit 0) */ #define SNC_SNC_TMP2_REG_TMP2_REG_Msk (0xffffffffUL) /*!< TMP2_REG (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ SPI ================ */ /* =========================================================================================================================== */ /* =================================================== SPI_CLEAR_INT_REG =================================================== */ #define SPI_SPI_CLEAR_INT_REG_SPI_CLEAR_INT_Pos (0UL) /*!< SPI_CLEAR_INT (Bit 0) */ #define SPI_SPI_CLEAR_INT_REG_SPI_CLEAR_INT_Msk (0xffffffffUL) /*!< SPI_CLEAR_INT (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SPI_CTRL_REG ====================================================== */ #define SPI_SPI_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Pos (25UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bit 25) */ #define SPI_SPI_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Msk (0x2000000UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_DMA_TXREQ_MODE_Pos (24UL) /*!< SPI_DMA_TXREQ_MODE (Bit 24) */ #define SPI_SPI_CTRL_REG_SPI_DMA_TXREQ_MODE_Msk (0x1000000UL) /*!< SPI_DMA_TXREQ_MODE (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_TX_FIFO_EMPTY_Pos (23UL) /*!< SPI_TX_FIFO_EMPTY (Bit 23) */ #define SPI_SPI_CTRL_REG_SPI_TX_FIFO_EMPTY_Msk (0x800000UL) /*!< SPI_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_RX_FIFO_FULL_Pos (22UL) /*!< SPI_RX_FIFO_FULL (Bit 22) */ #define SPI_SPI_CTRL_REG_SPI_RX_FIFO_FULL_Msk (0x400000UL) /*!< SPI_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_RX_FIFO_EMPTY_Pos (21UL) /*!< SPI_RX_FIFO_EMPTY (Bit 21) */ #define SPI_SPI_CTRL_REG_SPI_RX_FIFO_EMPTY_Msk (0x200000UL) /*!< SPI_RX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_9BIT_VAL_Pos (20UL) /*!< SPI_9BIT_VAL (Bit 20) */ #define SPI_SPI_CTRL_REG_SPI_9BIT_VAL_Msk (0x100000UL) /*!< SPI_9BIT_VAL (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_BUSY_Pos (19UL) /*!< SPI_BUSY (Bit 19) */ #define SPI_SPI_CTRL_REG_SPI_BUSY_Msk (0x80000UL) /*!< SPI_BUSY (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_PRIORITY_Pos (18UL) /*!< SPI_PRIORITY (Bit 18) */ #define SPI_SPI_CTRL_REG_SPI_PRIORITY_Msk (0x40000UL) /*!< SPI_PRIORITY (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_FIFO_MODE_Pos (16UL) /*!< SPI_FIFO_MODE (Bit 16) */ #define SPI_SPI_CTRL_REG_SPI_FIFO_MODE_Msk (0x30000UL) /*!< SPI_FIFO_MODE (Bitfield-Mask: 0x03) */ #define SPI_SPI_CTRL_REG_SPI_EN_CTRL_Pos (15UL) /*!< SPI_EN_CTRL (Bit 15) */ #define SPI_SPI_CTRL_REG_SPI_EN_CTRL_Msk (0x8000UL) /*!< SPI_EN_CTRL (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_MINT_Pos (14UL) /*!< SPI_MINT (Bit 14) */ #define SPI_SPI_CTRL_REG_SPI_MINT_Msk (0x4000UL) /*!< SPI_MINT (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_INT_BIT_Pos (13UL) /*!< SPI_INT_BIT (Bit 13) */ #define SPI_SPI_CTRL_REG_SPI_INT_BIT_Msk (0x2000UL) /*!< SPI_INT_BIT (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_DI_Pos (12UL) /*!< SPI_DI (Bit 12) */ #define SPI_SPI_CTRL_REG_SPI_DI_Msk (0x1000UL) /*!< SPI_DI (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_TXH_Pos (11UL) /*!< SPI_TXH (Bit 11) */ #define SPI_SPI_CTRL_REG_SPI_TXH_Msk (0x800UL) /*!< SPI_TXH (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_FORCE_DO_Pos (10UL) /*!< SPI_FORCE_DO (Bit 10) */ #define SPI_SPI_CTRL_REG_SPI_FORCE_DO_Msk (0x400UL) /*!< SPI_FORCE_DO (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_WORD_Pos (8UL) /*!< SPI_WORD (Bit 8) */ #define SPI_SPI_CTRL_REG_SPI_WORD_Msk (0x300UL) /*!< SPI_WORD (Bitfield-Mask: 0x03) */ #define SPI_SPI_CTRL_REG_SPI_RST_Pos (7UL) /*!< SPI_RST (Bit 7) */ #define SPI_SPI_CTRL_REG_SPI_RST_Msk (0x80UL) /*!< SPI_RST (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_SMN_Pos (6UL) /*!< SPI_SMN (Bit 6) */ #define SPI_SPI_CTRL_REG_SPI_SMN_Msk (0x40UL) /*!< SPI_SMN (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_DO_Pos (5UL) /*!< SPI_DO (Bit 5) */ #define SPI_SPI_CTRL_REG_SPI_DO_Msk (0x20UL) /*!< SPI_DO (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_CLK_Pos (3UL) /*!< SPI_CLK (Bit 3) */ #define SPI_SPI_CTRL_REG_SPI_CLK_Msk (0x18UL) /*!< SPI_CLK (Bitfield-Mask: 0x03) */ #define SPI_SPI_CTRL_REG_SPI_POL_Pos (2UL) /*!< SPI_POL (Bit 2) */ #define SPI_SPI_CTRL_REG_SPI_POL_Msk (0x4UL) /*!< SPI_POL (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_PHA_Pos (1UL) /*!< SPI_PHA (Bit 1) */ #define SPI_SPI_CTRL_REG_SPI_PHA_Msk (0x2UL) /*!< SPI_PHA (Bitfield-Mask: 0x01) */ #define SPI_SPI_CTRL_REG_SPI_ON_Pos (0UL) /*!< SPI_ON (Bit 0) */ #define SPI_SPI_CTRL_REG_SPI_ON_Msk (0x1UL) /*!< SPI_ON (Bitfield-Mask: 0x01) */ /* ===================================================== SPI_RX_TX_REG ===================================================== */ #define SPI_SPI_RX_TX_REG_SPI_DATA_Pos (0UL) /*!< SPI_DATA (Bit 0) */ #define SPI_SPI_RX_TX_REG_SPI_DATA_Msk (0xffffffffUL) /*!< SPI_DATA (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ SPI2 ================ */ /* =========================================================================================================================== */ /* ================================================== SPI2_CLEAR_INT_REG =================================================== */ #define SPI2_SPI2_CLEAR_INT_REG_SPI_CLEAR_INT_Pos (0UL) /*!< SPI_CLEAR_INT (Bit 0) */ #define SPI2_SPI2_CLEAR_INT_REG_SPI_CLEAR_INT_Msk (0xffffffffUL) /*!< SPI_CLEAR_INT (Bitfield-Mask: 0xffffffff) */ /* ===================================================== SPI2_CTRL_REG ===================================================== */ #define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Pos (25UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bit 25) */ #define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Msk (0x2000000UL) /*!< SPI_TX_FIFO_NOTFULL_MASK (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_DMA_TXREQ_MODE_Pos (24UL) /*!< SPI_DMA_TXREQ_MODE (Bit 24) */ #define SPI2_SPI2_CTRL_REG_SPI_DMA_TXREQ_MODE_Msk (0x1000000UL) /*!< SPI_DMA_TXREQ_MODE (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_EMPTY_Pos (23UL) /*!< SPI_TX_FIFO_EMPTY (Bit 23) */ #define SPI2_SPI2_CTRL_REG_SPI_TX_FIFO_EMPTY_Msk (0x800000UL) /*!< SPI_TX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_FULL_Pos (22UL) /*!< SPI_RX_FIFO_FULL (Bit 22) */ #define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_FULL_Msk (0x400000UL) /*!< SPI_RX_FIFO_FULL (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_EMPTY_Pos (21UL) /*!< SPI_RX_FIFO_EMPTY (Bit 21) */ #define SPI2_SPI2_CTRL_REG_SPI_RX_FIFO_EMPTY_Msk (0x200000UL) /*!< SPI_RX_FIFO_EMPTY (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_9BIT_VAL_Pos (20UL) /*!< SPI_9BIT_VAL (Bit 20) */ #define SPI2_SPI2_CTRL_REG_SPI_9BIT_VAL_Msk (0x100000UL) /*!< SPI_9BIT_VAL (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_BUSY_Pos (19UL) /*!< SPI_BUSY (Bit 19) */ #define SPI2_SPI2_CTRL_REG_SPI_BUSY_Msk (0x80000UL) /*!< SPI_BUSY (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_PRIORITY_Pos (18UL) /*!< SPI_PRIORITY (Bit 18) */ #define SPI2_SPI2_CTRL_REG_SPI_PRIORITY_Msk (0x40000UL) /*!< SPI_PRIORITY (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_FIFO_MODE_Pos (16UL) /*!< SPI_FIFO_MODE (Bit 16) */ #define SPI2_SPI2_CTRL_REG_SPI_FIFO_MODE_Msk (0x30000UL) /*!< SPI_FIFO_MODE (Bitfield-Mask: 0x03) */ #define SPI2_SPI2_CTRL_REG_SPI_EN_CTRL_Pos (15UL) /*!< SPI_EN_CTRL (Bit 15) */ #define SPI2_SPI2_CTRL_REG_SPI_EN_CTRL_Msk (0x8000UL) /*!< SPI_EN_CTRL (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_MINT_Pos (14UL) /*!< SPI_MINT (Bit 14) */ #define SPI2_SPI2_CTRL_REG_SPI_MINT_Msk (0x4000UL) /*!< SPI_MINT (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_INT_BIT_Pos (13UL) /*!< SPI_INT_BIT (Bit 13) */ #define SPI2_SPI2_CTRL_REG_SPI_INT_BIT_Msk (0x2000UL) /*!< SPI_INT_BIT (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_DI_Pos (12UL) /*!< SPI_DI (Bit 12) */ #define SPI2_SPI2_CTRL_REG_SPI_DI_Msk (0x1000UL) /*!< SPI_DI (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_TXH_Pos (11UL) /*!< SPI_TXH (Bit 11) */ #define SPI2_SPI2_CTRL_REG_SPI_TXH_Msk (0x800UL) /*!< SPI_TXH (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_FORCE_DO_Pos (10UL) /*!< SPI_FORCE_DO (Bit 10) */ #define SPI2_SPI2_CTRL_REG_SPI_FORCE_DO_Msk (0x400UL) /*!< SPI_FORCE_DO (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_WORD_Pos (8UL) /*!< SPI_WORD (Bit 8) */ #define SPI2_SPI2_CTRL_REG_SPI_WORD_Msk (0x300UL) /*!< SPI_WORD (Bitfield-Mask: 0x03) */ #define SPI2_SPI2_CTRL_REG_SPI_RST_Pos (7UL) /*!< SPI_RST (Bit 7) */ #define SPI2_SPI2_CTRL_REG_SPI_RST_Msk (0x80UL) /*!< SPI_RST (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_SMN_Pos (6UL) /*!< SPI_SMN (Bit 6) */ #define SPI2_SPI2_CTRL_REG_SPI_SMN_Msk (0x40UL) /*!< SPI_SMN (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_DO_Pos (5UL) /*!< SPI_DO (Bit 5) */ #define SPI2_SPI2_CTRL_REG_SPI_DO_Msk (0x20UL) /*!< SPI_DO (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_CLK_Pos (3UL) /*!< SPI_CLK (Bit 3) */ #define SPI2_SPI2_CTRL_REG_SPI_CLK_Msk (0x18UL) /*!< SPI_CLK (Bitfield-Mask: 0x03) */ #define SPI2_SPI2_CTRL_REG_SPI_POL_Pos (2UL) /*!< SPI_POL (Bit 2) */ #define SPI2_SPI2_CTRL_REG_SPI_POL_Msk (0x4UL) /*!< SPI_POL (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_PHA_Pos (1UL) /*!< SPI_PHA (Bit 1) */ #define SPI2_SPI2_CTRL_REG_SPI_PHA_Msk (0x2UL) /*!< SPI_PHA (Bitfield-Mask: 0x01) */ #define SPI2_SPI2_CTRL_REG_SPI_ON_Pos (0UL) /*!< SPI_ON (Bit 0) */ #define SPI2_SPI2_CTRL_REG_SPI_ON_Msk (0x1UL) /*!< SPI_ON (Bitfield-Mask: 0x01) */ /* ==================================================== SPI2_RX_TX_REG ===================================================== */ #define SPI2_SPI2_RX_TX_REG_SPI_DATA_Pos (0UL) /*!< SPI_DATA (Bit 0) */ #define SPI2_SPI2_RX_TX_REG_SPI_DATA_Msk (0xffffffffUL) /*!< SPI_DATA (Bitfield-Mask: 0xffffffff) */ /* =========================================================================================================================== */ /* ================ SYS_WDOG ================ */ /* =========================================================================================================================== */ /* =================================================== WATCHDOG_CTRL_REG =================================================== */ #define SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Pos (3UL) /*!< WRITE_BUSY (Bit 3) */ #define SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Msk (0x8UL) /*!< WRITE_BUSY (Bitfield-Mask: 0x01) */ #define SYS_WDOG_WATCHDOG_CTRL_REG_WDOG_FREEZE_EN_Pos (2UL) /*!< WDOG_FREEZE_EN (Bit 2) */ #define SYS_WDOG_WATCHDOG_CTRL_REG_WDOG_FREEZE_EN_Msk (0x4UL) /*!< WDOG_FREEZE_EN (Bitfield-Mask: 0x01) */ #define SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Pos (0UL) /*!< NMI_RST (Bit 0) */ #define SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Msk (0x1UL) /*!< NMI_RST (Bitfield-Mask: 0x01) */ /* ===================================================== WATCHDOG_REG ====================================================== */ #define SYS_WDOG_WATCHDOG_REG_WDOG_WEN_Pos (14UL) /*!< WDOG_WEN (Bit 14) */ #define SYS_WDOG_WATCHDOG_REG_WDOG_WEN_Msk (0xffffc000UL) /*!< WDOG_WEN (Bitfield-Mask: 0x3ffff) */ #define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Pos (13UL) /*!< WDOG_VAL_NEG (Bit 13) */ #define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Msk (0x2000UL) /*!< WDOG_VAL_NEG (Bitfield-Mask: 0x01) */ #define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Pos (0UL) /*!< WDOG_VAL (Bit 0) */ #define SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Msk (0x1fffUL) /*!< WDOG_VAL (Bitfield-Mask: 0x1fff) */ /* =========================================================================================================================== */ /* ================ TIMER ================ */ /* =========================================================================================================================== */ /* ================================================ TIMER_CAPTURE_GPIO1_REG ================================================ */ #define TIMER_TIMER_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ #define TIMER_TIMER_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ /* ================================================ TIMER_CAPTURE_GPIO2_REG ================================================ */ #define TIMER_TIMER_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ #define TIMER_TIMER_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ /* ================================================ TIMER_CAPTURE_GPIO3_REG ================================================ */ #define TIMER_TIMER_CAPTURE_GPIO3_REG_TIM_CAPTURE_GPIO3_Pos (0UL) /*!< TIM_CAPTURE_GPIO3 (Bit 0) */ #define TIMER_TIMER_CAPTURE_GPIO3_REG_TIM_CAPTURE_GPIO3_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO3 (Bitfield-Mask: 0xffffff) */ /* ================================================ TIMER_CAPTURE_GPIO4_REG ================================================ */ #define TIMER_TIMER_CAPTURE_GPIO4_REG_TIM_CAPTURE_GPIO4_Pos (0UL) /*!< TIM_CAPTURE_GPIO4 (Bit 0) */ #define TIMER_TIMER_CAPTURE_GPIO4_REG_TIM_CAPTURE_GPIO4_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO4 (Bitfield-Mask: 0xffffff) */ /* ============================================== TIMER_CLEAR_GPIO_EVENT_REG =============================================== */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO4_EVENT_Pos (3UL) /*!< TIM_CLEAR_GPIO4_EVENT (Bit 3) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO4_EVENT_Msk (0x8UL) /*!< TIM_CLEAR_GPIO4_EVENT (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO3_EVENT_Pos (2UL) /*!< TIM_CLEAR_GPIO3_EVENT (Bit 2) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO3_EVENT_Msk (0x4UL) /*!< TIM_CLEAR_GPIO3_EVENT (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO2_EVENT_Pos (1UL) /*!< TIM_CLEAR_GPIO2_EVENT (Bit 1) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO2_EVENT_Msk (0x2UL) /*!< TIM_CLEAR_GPIO2_EVENT (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO1_EVENT_Pos (0UL) /*!< TIM_CLEAR_GPIO1_EVENT (Bit 0) */ #define TIMER_TIMER_CLEAR_GPIO_EVENT_REG_TIM_CLEAR_GPIO1_EVENT_Msk (0x1UL) /*!< TIM_CLEAR_GPIO1_EVENT (Bitfield-Mask: 0x01) */ /* ================================================== TIMER_CLEAR_IRQ_REG ================================================== */ #define TIMER_TIMER_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ #define TIMER_TIMER_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ /* ==================================================== TIMER_CTRL_REG ===================================================== */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO4_IRQ_EN_Pos (14UL) /*!< TIM_CAP_GPIO4_IRQ_EN (Bit 14) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO4_IRQ_EN_Msk (0x4000UL) /*!< TIM_CAP_GPIO4_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO3_IRQ_EN_Pos (13UL) /*!< TIM_CAP_GPIO3_IRQ_EN (Bit 13) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO3_IRQ_EN_Msk (0x2000UL) /*!< TIM_CAP_GPIO3_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO2_IRQ_EN_Pos (12UL) /*!< TIM_CAP_GPIO2_IRQ_EN (Bit 12) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO2_IRQ_EN_Msk (0x1000UL) /*!< TIM_CAP_GPIO2_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO1_IRQ_EN_Pos (11UL) /*!< TIM_CAP_GPIO1_IRQ_EN (Bit 11) */ #define TIMER_TIMER_CTRL_REG_TIM_CAP_GPIO1_IRQ_EN_Msk (0x800UL) /*!< TIM_CAP_GPIO1_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_IN4_EVENT_FALL_EN_Pos (10UL) /*!< TIM_IN4_EVENT_FALL_EN (Bit 10) */ #define TIMER_TIMER_CTRL_REG_TIM_IN4_EVENT_FALL_EN_Msk (0x400UL) /*!< TIM_IN4_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_IN3_EVENT_FALL_EN_Pos (9UL) /*!< TIM_IN3_EVENT_FALL_EN (Bit 9) */ #define TIMER_TIMER_CTRL_REG_TIM_IN3_EVENT_FALL_EN_Msk (0x200UL) /*!< TIM_IN3_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ #define TIMER_TIMER_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ #define TIMER_TIMER_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ #define TIMER_TIMER_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ #define TIMER_TIMER_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ #define TIMER_TIMER_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ #define TIMER_TIMER_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ #define TIMER_TIMER_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_ONESHOT_MODE_EN_Pos (1UL) /*!< TIM_ONESHOT_MODE_EN (Bit 1) */ #define TIMER_TIMER_CTRL_REG_TIM_ONESHOT_MODE_EN_Msk (0x2UL) /*!< TIM_ONESHOT_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ #define TIMER_TIMER_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ /* ================================================= TIMER_GPIO1_CONF_REG ================================================== */ #define TIMER_TIMER_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ #define TIMER_TIMER_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER_GPIO2_CONF_REG ================================================== */ #define TIMER_TIMER_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ #define TIMER_TIMER_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER_GPIO3_CONF_REG ================================================== */ #define TIMER_TIMER_GPIO3_CONF_REG_TIM_GPIO3_CONF_Pos (0UL) /*!< TIM_GPIO3_CONF (Bit 0) */ #define TIMER_TIMER_GPIO3_CONF_REG_TIM_GPIO3_CONF_Msk (0x3fUL) /*!< TIM_GPIO3_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER_GPIO4_CONF_REG ================================================== */ #define TIMER_TIMER_GPIO4_CONF_REG_TIM_GPIO4_CONF_Pos (0UL) /*!< TIM_GPIO4_CONF (Bit 0) */ #define TIMER_TIMER_GPIO4_CONF_REG_TIM_GPIO4_CONF_Msk (0x3fUL) /*!< TIM_GPIO4_CONF (Bitfield-Mask: 0x3f) */ /* ================================================== TIMER_PRESCALER_REG ================================================== */ #define TIMER_TIMER_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ #define TIMER_TIMER_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ /* ================================================ TIMER_PRESCALER_VAL_REG ================================================ */ #define TIMER_TIMER_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ #define TIMER_TIMER_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ /* =================================================== TIMER_PWM_DC_REG ==================================================== */ #define TIMER_TIMER_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ #define TIMER_TIMER_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ /* ================================================== TIMER_PWM_FREQ_REG =================================================== */ #define TIMER_TIMER_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ #define TIMER_TIMER_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ /* =================================================== TIMER_RELOAD_REG ==================================================== */ #define TIMER_TIMER_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ #define TIMER_TIMER_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ /* ================================================== TIMER_SHOTWIDTH_REG ================================================== */ #define TIMER_TIMER_SHOTWIDTH_REG_TIM_SHOTWIDTH_Pos (0UL) /*!< TIM_SHOTWIDTH (Bit 0) */ #define TIMER_TIMER_SHOTWIDTH_REG_TIM_SHOTWIDTH_Msk (0xffffffUL) /*!< TIM_SHOTWIDTH (Bitfield-Mask: 0xffffff) */ /* =================================================== TIMER_STATUS_REG ==================================================== */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO4_EVENT_PENDING_Pos (7UL) /*!< TIM_GPIO4_EVENT_PENDING (Bit 7) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO4_EVENT_PENDING_Msk (0x80UL) /*!< TIM_GPIO4_EVENT_PENDING (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO3_EVENT_PENDING_Pos (6UL) /*!< TIM_GPIO3_EVENT_PENDING (Bit 6) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO3_EVENT_PENDING_Msk (0x40UL) /*!< TIM_GPIO3_EVENT_PENDING (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO2_EVENT_PENDING_Pos (5UL) /*!< TIM_GPIO2_EVENT_PENDING (Bit 5) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO2_EVENT_PENDING_Msk (0x20UL) /*!< TIM_GPIO2_EVENT_PENDING (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO1_EVENT_PENDING_Pos (4UL) /*!< TIM_GPIO1_EVENT_PENDING (Bit 4) */ #define TIMER_TIMER_STATUS_REG_TIM_GPIO1_EVENT_PENDING_Msk (0x10UL) /*!< TIM_GPIO1_EVENT_PENDING (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ #define TIMER_TIMER_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ #define TIMER_TIMER_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ #define TIMER_TIMER_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ #define TIMER_TIMER_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ #define TIMER_TIMER_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ /* ================================================== TIMER_TIMER_VAL_REG ================================================== */ #define TIMER_TIMER_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ #define TIMER_TIMER_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ /* =========================================================================================================================== */ /* ================ TIMER2 ================ */ /* =========================================================================================================================== */ /* =============================================== TIMER2_CAPTURE_GPIO1_REG ================================================ */ #define TIMER2_TIMER2_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ #define TIMER2_TIMER2_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ /* =============================================== TIMER2_CAPTURE_GPIO2_REG ================================================ */ #define TIMER2_TIMER2_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ #define TIMER2_TIMER2_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ /* ================================================= TIMER2_CLEAR_IRQ_REG ================================================== */ #define TIMER2_TIMER2_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ #define TIMER2_TIMER2_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ /* ==================================================== TIMER2_CTRL_REG ==================================================== */ #define TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ #define TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ #define TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ #define TIMER2_TIMER2_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ #define TIMER2_TIMER2_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ #define TIMER2_TIMER2_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_ONESHOT_MODE_EN_Pos (1UL) /*!< TIM_ONESHOT_MODE_EN (Bit 1) */ #define TIMER2_TIMER2_CTRL_REG_TIM_ONESHOT_MODE_EN_Msk (0x2UL) /*!< TIM_ONESHOT_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ #define TIMER2_TIMER2_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ /* ================================================= TIMER2_GPIO1_CONF_REG ================================================= */ #define TIMER2_TIMER2_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ #define TIMER2_TIMER2_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER2_GPIO2_CONF_REG ================================================= */ #define TIMER2_TIMER2_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ #define TIMER2_TIMER2_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER2_PRESCALER_REG ================================================== */ #define TIMER2_TIMER2_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ #define TIMER2_TIMER2_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ /* =============================================== TIMER2_PRESCALER_VAL_REG ================================================ */ #define TIMER2_TIMER2_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ #define TIMER2_TIMER2_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ /* =================================================== TIMER2_PWM_DC_REG =================================================== */ #define TIMER2_TIMER2_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ #define TIMER2_TIMER2_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ /* ================================================== TIMER2_PWM_FREQ_REG ================================================== */ #define TIMER2_TIMER2_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ #define TIMER2_TIMER2_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ /* =================================================== TIMER2_RELOAD_REG =================================================== */ #define TIMER2_TIMER2_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ #define TIMER2_TIMER2_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ /* ================================================= TIMER2_SHOTWIDTH_REG ================================================== */ #define TIMER2_TIMER2_SHOTWIDTH_REG_TIM_SHOTWIDTH_Pos (0UL) /*!< TIM_SHOTWIDTH (Bit 0) */ #define TIMER2_TIMER2_SHOTWIDTH_REG_TIM_SHOTWIDTH_Msk (0xffffffUL) /*!< TIM_SHOTWIDTH (Bitfield-Mask: 0xffffff) */ /* =================================================== TIMER2_STATUS_REG =================================================== */ #define TIMER2_TIMER2_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ #define TIMER2_TIMER2_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ #define TIMER2_TIMER2_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ #define TIMER2_TIMER2_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ #define TIMER2_TIMER2_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ #define TIMER2_TIMER2_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ /* ================================================= TIMER2_TIMER_VAL_REG ================================================== */ #define TIMER2_TIMER2_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ #define TIMER2_TIMER2_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ /* =========================================================================================================================== */ /* ================ TIMER3 ================ */ /* =========================================================================================================================== */ /* =============================================== TIMER3_CAPTURE_GPIO1_REG ================================================ */ #define TIMER3_TIMER3_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ #define TIMER3_TIMER3_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ /* =============================================== TIMER3_CAPTURE_GPIO2_REG ================================================ */ #define TIMER3_TIMER3_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ #define TIMER3_TIMER3_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ /* ================================================= TIMER3_CLEAR_IRQ_REG ================================================== */ #define TIMER3_TIMER3_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ #define TIMER3_TIMER3_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ /* ==================================================== TIMER3_CTRL_REG ==================================================== */ #define TIMER3_TIMER3_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ #define TIMER3_TIMER3_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ #define TIMER3_TIMER3_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ #define TIMER3_TIMER3_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ #define TIMER3_TIMER3_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ #define TIMER3_TIMER3_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ #define TIMER3_TIMER3_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ /* ================================================= TIMER3_GPIO1_CONF_REG ================================================= */ #define TIMER3_TIMER3_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ #define TIMER3_TIMER3_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER3_GPIO2_CONF_REG ================================================= */ #define TIMER3_TIMER3_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ #define TIMER3_TIMER3_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER3_PRESCALER_REG ================================================== */ #define TIMER3_TIMER3_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ #define TIMER3_TIMER3_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ /* =============================================== TIMER3_PRESCALER_VAL_REG ================================================ */ #define TIMER3_TIMER3_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ #define TIMER3_TIMER3_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ /* =================================================== TIMER3_PWM_DC_REG =================================================== */ #define TIMER3_TIMER3_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ #define TIMER3_TIMER3_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ /* ================================================== TIMER3_PWM_FREQ_REG ================================================== */ #define TIMER3_TIMER3_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ #define TIMER3_TIMER3_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ /* =================================================== TIMER3_RELOAD_REG =================================================== */ #define TIMER3_TIMER3_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ #define TIMER3_TIMER3_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ /* =================================================== TIMER3_STATUS_REG =================================================== */ #define TIMER3_TIMER3_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ #define TIMER3_TIMER3_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ #define TIMER3_TIMER3_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ #define TIMER3_TIMER3_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ #define TIMER3_TIMER3_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ #define TIMER3_TIMER3_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ /* ================================================= TIMER3_TIMER_VAL_REG ================================================== */ #define TIMER3_TIMER3_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ #define TIMER3_TIMER3_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ /* =========================================================================================================================== */ /* ================ TIMER4 ================ */ /* =========================================================================================================================== */ /* =============================================== TIMER4_CAPTURE_GPIO1_REG ================================================ */ #define TIMER4_TIMER4_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Pos (0UL) /*!< TIM_CAPTURE_GPIO1 (Bit 0) */ #define TIMER4_TIMER4_CAPTURE_GPIO1_REG_TIM_CAPTURE_GPIO1_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO1 (Bitfield-Mask: 0xffffff) */ /* =============================================== TIMER4_CAPTURE_GPIO2_REG ================================================ */ #define TIMER4_TIMER4_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Pos (0UL) /*!< TIM_CAPTURE_GPIO2 (Bit 0) */ #define TIMER4_TIMER4_CAPTURE_GPIO2_REG_TIM_CAPTURE_GPIO2_Msk (0xffffffUL) /*!< TIM_CAPTURE_GPIO2 (Bitfield-Mask: 0xffffff) */ /* ================================================= TIMER4_CLEAR_IRQ_REG ================================================== */ #define TIMER4_TIMER4_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Pos (0UL) /*!< TIM_CLEAR_IRQ (Bit 0) */ #define TIMER4_TIMER4_CLEAR_IRQ_REG_TIM_CLEAR_IRQ_Msk (0x1UL) /*!< TIM_CLEAR_IRQ (Bitfield-Mask: 0x01) */ /* ==================================================== TIMER4_CTRL_REG ==================================================== */ #define TIMER4_TIMER4_CTRL_REG_TIM_CLK_EN_Pos (8UL) /*!< TIM_CLK_EN (Bit 8) */ #define TIMER4_TIMER4_CTRL_REG_TIM_CLK_EN_Msk (0x100UL) /*!< TIM_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_SYS_CLK_EN_Pos (7UL) /*!< TIM_SYS_CLK_EN (Bit 7) */ #define TIMER4_TIMER4_CTRL_REG_TIM_SYS_CLK_EN_Msk (0x80UL) /*!< TIM_SYS_CLK_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_FREE_RUN_MODE_EN_Pos (6UL) /*!< TIM_FREE_RUN_MODE_EN (Bit 6) */ #define TIMER4_TIMER4_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk (0x40UL) /*!< TIM_FREE_RUN_MODE_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IRQ_EN_Pos (5UL) /*!< TIM_IRQ_EN (Bit 5) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IRQ_EN_Msk (0x20UL) /*!< TIM_IRQ_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Pos (4UL) /*!< TIM_IN2_EVENT_FALL_EN (Bit 4) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IN2_EVENT_FALL_EN_Msk (0x10UL) /*!< TIM_IN2_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Pos (3UL) /*!< TIM_IN1_EVENT_FALL_EN (Bit 3) */ #define TIMER4_TIMER4_CTRL_REG_TIM_IN1_EVENT_FALL_EN_Msk (0x8UL) /*!< TIM_IN1_EVENT_FALL_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_COUNT_DOWN_EN_Pos (2UL) /*!< TIM_COUNT_DOWN_EN (Bit 2) */ #define TIMER4_TIMER4_CTRL_REG_TIM_COUNT_DOWN_EN_Msk (0x4UL) /*!< TIM_COUNT_DOWN_EN (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_CTRL_REG_TIM_EN_Pos (0UL) /*!< TIM_EN (Bit 0) */ #define TIMER4_TIMER4_CTRL_REG_TIM_EN_Msk (0x1UL) /*!< TIM_EN (Bitfield-Mask: 0x01) */ /* ================================================= TIMER4_GPIO1_CONF_REG ================================================= */ #define TIMER4_TIMER4_GPIO1_CONF_REG_TIM_GPIO1_CONF_Pos (0UL) /*!< TIM_GPIO1_CONF (Bit 0) */ #define TIMER4_TIMER4_GPIO1_CONF_REG_TIM_GPIO1_CONF_Msk (0x3fUL) /*!< TIM_GPIO1_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER4_GPIO2_CONF_REG ================================================= */ #define TIMER4_TIMER4_GPIO2_CONF_REG_TIM_GPIO2_CONF_Pos (0UL) /*!< TIM_GPIO2_CONF (Bit 0) */ #define TIMER4_TIMER4_GPIO2_CONF_REG_TIM_GPIO2_CONF_Msk (0x3fUL) /*!< TIM_GPIO2_CONF (Bitfield-Mask: 0x3f) */ /* ================================================= TIMER4_PRESCALER_REG ================================================== */ #define TIMER4_TIMER4_PRESCALER_REG_TIM_PRESCALER_Pos (0UL) /*!< TIM_PRESCALER (Bit 0) */ #define TIMER4_TIMER4_PRESCALER_REG_TIM_PRESCALER_Msk (0x1fUL) /*!< TIM_PRESCALER (Bitfield-Mask: 0x1f) */ /* =============================================== TIMER4_PRESCALER_VAL_REG ================================================ */ #define TIMER4_TIMER4_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Pos (0UL) /*!< TIM_PRESCALER_VAL (Bit 0) */ #define TIMER4_TIMER4_PRESCALER_VAL_REG_TIM_PRESCALER_VAL_Msk (0x1fUL) /*!< TIM_PRESCALER_VAL (Bitfield-Mask: 0x1f) */ /* =================================================== TIMER4_PWM_DC_REG =================================================== */ #define TIMER4_TIMER4_PWM_DC_REG_TIM_PWM_DC_Pos (0UL) /*!< TIM_PWM_DC (Bit 0) */ #define TIMER4_TIMER4_PWM_DC_REG_TIM_PWM_DC_Msk (0xffffUL) /*!< TIM_PWM_DC (Bitfield-Mask: 0xffff) */ /* ================================================== TIMER4_PWM_FREQ_REG ================================================== */ #define TIMER4_TIMER4_PWM_FREQ_REG_TIM_PWM_FREQ_Pos (0UL) /*!< TIM_PWM_FREQ (Bit 0) */ #define TIMER4_TIMER4_PWM_FREQ_REG_TIM_PWM_FREQ_Msk (0xffffUL) /*!< TIM_PWM_FREQ (Bitfield-Mask: 0xffff) */ /* =================================================== TIMER4_RELOAD_REG =================================================== */ #define TIMER4_TIMER4_RELOAD_REG_TIM_RELOAD_Pos (0UL) /*!< TIM_RELOAD (Bit 0) */ #define TIMER4_TIMER4_RELOAD_REG_TIM_RELOAD_Msk (0xffffffUL) /*!< TIM_RELOAD (Bitfield-Mask: 0xffffff) */ /* =================================================== TIMER4_STATUS_REG =================================================== */ #define TIMER4_TIMER4_STATUS_REG_TIM_ONESHOT_PHASE_Pos (2UL) /*!< TIM_ONESHOT_PHASE (Bit 2) */ #define TIMER4_TIMER4_STATUS_REG_TIM_ONESHOT_PHASE_Msk (0xcUL) /*!< TIM_ONESHOT_PHASE (Bitfield-Mask: 0x03) */ #define TIMER4_TIMER4_STATUS_REG_TIM_IN2_STATE_Pos (1UL) /*!< TIM_IN2_STATE (Bit 1) */ #define TIMER4_TIMER4_STATUS_REG_TIM_IN2_STATE_Msk (0x2UL) /*!< TIM_IN2_STATE (Bitfield-Mask: 0x01) */ #define TIMER4_TIMER4_STATUS_REG_TIM_IN1_STATE_Pos (0UL) /*!< TIM_IN1_STATE (Bit 0) */ #define TIMER4_TIMER4_STATUS_REG_TIM_IN1_STATE_Msk (0x1UL) /*!< TIM_IN1_STATE (Bitfield-Mask: 0x01) */ /* ================================================= TIMER4_TIMER_VAL_REG ================================================== */ #define TIMER4_TIMER4_TIMER_VAL_REG_TIM_TIMER_VALUE_Pos (0UL) /*!< TIM_TIMER_VALUE (Bit 0) */ #define TIMER4_TIMER4_TIMER_VAL_REG_TIM_TIMER_VALUE_Msk (0xffffffUL) /*!< TIM_TIMER_VALUE (Bitfield-Mask: 0xffffff) */ /* =========================================================================================================================== */ /* ================ TRNG ================ */ /* =========================================================================================================================== */ /* ===================================================== TRNG_CTRL_REG ===================================================== */ #define TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Pos (0UL) /*!< TRNG_ENABLE (Bit 0) */ #define TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Msk (0x1UL) /*!< TRNG_ENABLE (Bitfield-Mask: 0x01) */ /* =================================================== TRNG_FIFOLVL_REG ==================================================== */ #define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOFULL_Pos (5UL) /*!< TRNG_FIFOFULL (Bit 5) */ #define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOFULL_Msk (0x20UL) /*!< TRNG_FIFOFULL (Bitfield-Mask: 0x01) */ #define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Pos (0UL) /*!< TRNG_FIFOLVL (Bit 0) */ #define TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Msk (0x1fUL) /*!< TRNG_FIFOLVL (Bitfield-Mask: 0x1f) */ /* ===================================================== TRNG_VER_REG ====================================================== */ #define TRNG_TRNG_VER_REG_TRNG_MAJ_Pos (24UL) /*!< TRNG_MAJ (Bit 24) */ #define TRNG_TRNG_VER_REG_TRNG_MAJ_Msk (0xff000000UL) /*!< TRNG_MAJ (Bitfield-Mask: 0xff) */ #define TRNG_TRNG_VER_REG_TRNG_MIN_Pos (16UL) /*!< TRNG_MIN (Bit 16) */ #define TRNG_TRNG_VER_REG_TRNG_MIN_Msk (0xff0000UL) /*!< TRNG_MIN (Bitfield-Mask: 0xff) */ #define TRNG_TRNG_VER_REG_TRNG_SVN_Pos (0UL) /*!< TRNG_SVN (Bit 0) */ #define TRNG_TRNG_VER_REG_TRNG_SVN_Msk (0xffffUL) /*!< TRNG_SVN (Bitfield-Mask: 0xffff) */ /* =========================================================================================================================== */ /* ================ UART ================ */ /* =========================================================================================================================== */ /* ===================================================== UART_CTR_REG ====================================================== */ #define UART_UART_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ #define UART_UART_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART_DLF_REG ====================================================== */ #define UART_UART_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ #define UART_UART_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ /* ==================================================== UART_DMASA_REG ===================================================== */ #define UART_UART_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ #define UART_UART_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ /* ===================================================== UART_HTX_REG ====================================================== */ #define UART_UART_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ #define UART_UART_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ /* =================================================== UART_IER_DLH_REG ==================================================== */ #define UART_UART_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ #define UART_UART_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ #define UART_UART_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ #define UART_UART_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ #define UART_UART_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ #define UART_UART_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ #define UART_UART_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ #define UART_UART_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ #define UART_UART_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ #define UART_UART_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ #define UART_UART_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ #define UART_UART_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ #define UART_UART_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ #define UART_UART_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ /* =================================================== UART_IIR_FCR_REG ==================================================== */ #define UART_UART_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ #define UART_UART_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ /* ===================================================== UART_LCR_REG ====================================================== */ #define UART_UART_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ #define UART_UART_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ #define UART_UART_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ #define UART_UART_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ #define UART_UART_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ #define UART_UART_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ #define UART_UART_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ #define UART_UART_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ #define UART_UART_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ #define UART_UART_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ #define UART_UART_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ #define UART_UART_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ /* ===================================================== UART_LSR_REG ====================================================== */ #define UART_UART_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ #define UART_UART_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ #define UART_UART_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ #define UART_UART_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ #define UART_UART_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ #define UART_UART_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ #define UART_UART_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ #define UART_UART_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ #define UART_UART_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ #define UART_UART_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ /* ===================================================== UART_MCR_REG ====================================================== */ #define UART_UART_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ #define UART_UART_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ /* ================================================= UART_RBR_THR_DLL_REG ================================================== */ #define UART_UART_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ #define UART_UART_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ /* ===================================================== UART_RFL_REG ====================================================== */ #define UART_UART_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ #define UART_UART_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ===================================================== UART_SBCR_REG ===================================================== */ #define UART_UART_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ #define UART_UART_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ /* ===================================================== UART_SCR_REG ====================================================== */ #define UART_UART_SCR_REG_UART_SCRATCH_PAD_Pos (0UL) /*!< UART_SCRATCH_PAD (Bit 0) */ #define UART_UART_SCR_REG_UART_SCRATCH_PAD_Msk (0xffUL) /*!< UART_SCRATCH_PAD (Bitfield-Mask: 0xff) */ /* ==================================================== UART_SDMAM_REG ===================================================== */ #define UART_UART_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ #define UART_UART_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ /* ===================================================== UART_SFE_REG ====================================================== */ #define UART_UART_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ #define UART_UART_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ /* ================================================== UART_SRBR_STHR0_REG ================================================== */ #define UART_UART_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR10_REG ================================================== */ #define UART_UART_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR11_REG ================================================== */ #define UART_UART_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR12_REG ================================================== */ #define UART_UART_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR13_REG ================================================== */ #define UART_UART_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR14_REG ================================================== */ #define UART_UART_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART_SRBR_STHR15_REG ================================================== */ #define UART_UART_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR1_REG ================================================== */ #define UART_UART_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR2_REG ================================================== */ #define UART_UART_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR3_REG ================================================== */ #define UART_UART_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR4_REG ================================================== */ #define UART_UART_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR5_REG ================================================== */ #define UART_UART_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR6_REG ================================================== */ #define UART_UART_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR7_REG ================================================== */ #define UART_UART_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR8_REG ================================================== */ #define UART_UART_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================== UART_SRBR_STHR9_REG ================================================== */ #define UART_UART_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART_UART_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ===================================================== UART_SRR_REG ====================================================== */ #define UART_UART_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ #define UART_UART_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ #define UART_UART_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ #define UART_UART_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ #define UART_UART_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ #define UART_UART_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ /* ===================================================== UART_SRT_REG ====================================================== */ #define UART_UART_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ #define UART_UART_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ /* ===================================================== UART_STET_REG ===================================================== */ #define UART_UART_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ #define UART_UART_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ /* ===================================================== UART_TFL_REG ====================================================== */ #define UART_UART_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ #define UART_UART_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ===================================================== UART_UCV_REG ====================================================== */ #define UART_UART_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ #define UART_UART_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART_USR_REG ====================================================== */ #define UART_UART_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ #define UART_UART_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ #define UART_UART_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ #define UART_UART_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ #define UART_UART_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ #define UART_UART_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ #define UART_UART_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ #define UART_UART_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ #define UART_UART_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ #define UART_UART_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ UART2 ================ */ /* =========================================================================================================================== */ /* ===================================================== UART2_CTR_REG ===================================================== */ #define UART2_UART2_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ #define UART2_UART2_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART2_DLF_REG ===================================================== */ #define UART2_UART2_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ #define UART2_UART2_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ /* ==================================================== UART2_DMASA_REG ==================================================== */ #define UART2_UART2_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ #define UART2_UART2_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_HTX_REG ===================================================== */ #define UART2_UART2_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ #define UART2_UART2_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ /* =================================================== UART2_IER_DLH_REG =================================================== */ #define UART2_UART2_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ #define UART2_UART2_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ #define UART2_UART2_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ #define UART2_UART2_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ #define UART2_UART2_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ #define UART2_UART2_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ #define UART2_UART2_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ #define UART2_UART2_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ #define UART2_UART2_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ #define UART2_UART2_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ #define UART2_UART2_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ #define UART2_UART2_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ #define UART2_UART2_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ #define UART2_UART2_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ /* =================================================== UART2_IIR_FCR_REG =================================================== */ #define UART2_UART2_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ #define UART2_UART2_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ /* ===================================================== UART2_LCR_EXT ===================================================== */ #define UART2_UART2_LCR_EXT_UART_TRANSMIT_MODE_Pos (3UL) /*!< UART_TRANSMIT_MODE (Bit 3) */ #define UART2_UART2_LCR_EXT_UART_TRANSMIT_MODE_Msk (0x8UL) /*!< UART_TRANSMIT_MODE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_EXT_UART_SEND_ADDR_Pos (2UL) /*!< UART_SEND_ADDR (Bit 2) */ #define UART2_UART2_LCR_EXT_UART_SEND_ADDR_Msk (0x4UL) /*!< UART_SEND_ADDR (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_EXT_UART_ADDR_MATCH_Pos (1UL) /*!< UART_ADDR_MATCH (Bit 1) */ #define UART2_UART2_LCR_EXT_UART_ADDR_MATCH_Msk (0x2UL) /*!< UART_ADDR_MATCH (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_EXT_UART_DLS_E_Pos (0UL) /*!< UART_DLS_E (Bit 0) */ #define UART2_UART2_LCR_EXT_UART_DLS_E_Msk (0x1UL) /*!< UART_DLS_E (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_LCR_REG ===================================================== */ #define UART2_UART2_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ #define UART2_UART2_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ #define UART2_UART2_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_SP_Pos (5UL) /*!< UART_SP (Bit 5) */ #define UART2_UART2_LCR_REG_UART_SP_Msk (0x20UL) /*!< UART_SP (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ #define UART2_UART2_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ #define UART2_UART2_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ #define UART2_UART2_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ #define UART2_UART2_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ #define UART2_UART2_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ /* ===================================================== UART2_LSR_REG ===================================================== */ #define UART2_UART2_LSR_REG_UART_ADDR_RCVD_Pos (8UL) /*!< UART_ADDR_RCVD (Bit 8) */ #define UART2_UART2_LSR_REG_UART_ADDR_RCVD_Msk (0x100UL) /*!< UART_ADDR_RCVD (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ #define UART2_UART2_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ #define UART2_UART2_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ #define UART2_UART2_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ #define UART2_UART2_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ #define UART2_UART2_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ #define UART2_UART2_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ #define UART2_UART2_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ #define UART2_UART2_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ #define UART2_UART2_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_MCR_REG ===================================================== */ #define UART2_UART2_MCR_REG_UART_AFCE_Pos (5UL) /*!< UART_AFCE (Bit 5) */ #define UART2_UART2_MCR_REG_UART_AFCE_Msk (0x20UL) /*!< UART_AFCE (Bitfield-Mask: 0x01) */ #define UART2_UART2_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ #define UART2_UART2_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ #define UART2_UART2_MCR_REG_UART_RTS_Pos (1UL) /*!< UART_RTS (Bit 1) */ #define UART2_UART2_MCR_REG_UART_RTS_Msk (0x2UL) /*!< UART_RTS (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_MSR_REG ===================================================== */ #define UART2_UART2_MSR_REG_UART_CTS_Pos (4UL) /*!< UART_CTS (Bit 4) */ #define UART2_UART2_MSR_REG_UART_CTS_Msk (0x10UL) /*!< UART_CTS (Bitfield-Mask: 0x01) */ #define UART2_UART2_MSR_REG_UART_DCTS_Pos (0UL) /*!< UART_DCTS (Bit 0) */ #define UART2_UART2_MSR_REG_UART_DCTS_Msk (0x1UL) /*!< UART_DCTS (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_RAR_REG ===================================================== */ #define UART2_UART2_RAR_REG_UART_RAR_Pos (0UL) /*!< UART_RAR (Bit 0) */ #define UART2_UART2_RAR_REG_UART_RAR_Msk (0xffUL) /*!< UART_RAR (Bitfield-Mask: 0xff) */ /* ================================================= UART2_RBR_THR_DLL_REG ================================================= */ #define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_9BIT_Pos (8UL) /*!< RBR_THR_9BIT (Bit 8) */ #define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_9BIT_Msk (0x100UL) /*!< RBR_THR_9BIT (Bitfield-Mask: 0x01) */ #define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ #define UART2_UART2_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ /* ===================================================== UART2_RFL_REG ===================================================== */ #define UART2_UART2_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ #define UART2_UART2_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ==================================================== UART2_SBCR_REG ===================================================== */ #define UART2_UART2_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ #define UART2_UART2_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_SCR_REG ===================================================== */ #define UART2_UART2_SCR_REG_UART_SCRATCH_PAD_Pos (0UL) /*!< UART_SCRATCH_PAD (Bit 0) */ #define UART2_UART2_SCR_REG_UART_SCRATCH_PAD_Msk (0xffUL) /*!< UART_SCRATCH_PAD (Bitfield-Mask: 0xff) */ /* ==================================================== UART2_SDMAM_REG ==================================================== */ #define UART2_UART2_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ #define UART2_UART2_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_SFE_REG ===================================================== */ #define UART2_UART2_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ #define UART2_UART2_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ /* ================================================= UART2_SRBR_STHR0_REG ================================================== */ #define UART2_UART2_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR10_REG ================================================= */ #define UART2_UART2_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR11_REG ================================================= */ #define UART2_UART2_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR12_REG ================================================= */ #define UART2_UART2_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR13_REG ================================================= */ #define UART2_UART2_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR14_REG ================================================= */ #define UART2_UART2_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR15_REG ================================================= */ #define UART2_UART2_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR1_REG ================================================== */ #define UART2_UART2_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR2_REG ================================================== */ #define UART2_UART2_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR3_REG ================================================== */ #define UART2_UART2_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR4_REG ================================================== */ #define UART2_UART2_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR5_REG ================================================== */ #define UART2_UART2_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR6_REG ================================================== */ #define UART2_UART2_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR7_REG ================================================== */ #define UART2_UART2_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR8_REG ================================================== */ #define UART2_UART2_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART2_SRBR_STHR9_REG ================================================== */ #define UART2_UART2_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART2_UART2_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ===================================================== UART2_SRR_REG ===================================================== */ #define UART2_UART2_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ #define UART2_UART2_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ #define UART2_UART2_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ #define UART2_UART2_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ #define UART2_UART2_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ #define UART2_UART2_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ /* ==================================================== UART2_SRTS_REG ===================================================== */ #define UART2_UART2_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Pos (0UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bit 0) */ #define UART2_UART2_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Msk (0x1UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bitfield-Mask: 0x01) */ /* ===================================================== UART2_SRT_REG ===================================================== */ #define UART2_UART2_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ #define UART2_UART2_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ /* ==================================================== UART2_STET_REG ===================================================== */ #define UART2_UART2_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ #define UART2_UART2_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ /* ===================================================== UART2_TAR_REG ===================================================== */ #define UART2_UART2_TAR_REG_UART_TAR_Pos (0UL) /*!< UART_TAR (Bit 0) */ #define UART2_UART2_TAR_REG_UART_TAR_Msk (0xffUL) /*!< UART_TAR (Bitfield-Mask: 0xff) */ /* ===================================================== UART2_TFL_REG ===================================================== */ #define UART2_UART2_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ #define UART2_UART2_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ===================================================== UART2_UCV_REG ===================================================== */ #define UART2_UART2_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ #define UART2_UART2_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART2_USR_REG ===================================================== */ #define UART2_UART2_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ #define UART2_UART2_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ #define UART2_UART2_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ #define UART2_UART2_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ #define UART2_UART2_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ #define UART2_UART2_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ #define UART2_UART2_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ #define UART2_UART2_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ #define UART2_UART2_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ #define UART2_UART2_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ UART3 ================ */ /* =========================================================================================================================== */ /* =================================================== UART3_CONFIG_REG ==================================================== */ #define UART3_UART3_CONFIG_REG_ISO7816_SCRATCH_PAD_Pos (3UL) /*!< ISO7816_SCRATCH_PAD (Bit 3) */ #define UART3_UART3_CONFIG_REG_ISO7816_SCRATCH_PAD_Msk (0xf8UL) /*!< ISO7816_SCRATCH_PAD (Bitfield-Mask: 0x1f) */ #define UART3_UART3_CONFIG_REG_ISO7816_ENABLE_Pos (2UL) /*!< ISO7816_ENABLE (Bit 2) */ #define UART3_UART3_CONFIG_REG_ISO7816_ENABLE_Msk (0x4UL) /*!< ISO7816_ENABLE (Bitfield-Mask: 0x01) */ #define UART3_UART3_CONFIG_REG_ISO7816_ERR_SIG_EN_Pos (1UL) /*!< ISO7816_ERR_SIG_EN (Bit 1) */ #define UART3_UART3_CONFIG_REG_ISO7816_ERR_SIG_EN_Msk (0x2UL) /*!< ISO7816_ERR_SIG_EN (Bitfield-Mask: 0x01) */ #define UART3_UART3_CONFIG_REG_ISO7816_CONVENTION_Pos (0UL) /*!< ISO7816_CONVENTION (Bit 0) */ #define UART3_UART3_CONFIG_REG_ISO7816_CONVENTION_Msk (0x1UL) /*!< ISO7816_CONVENTION (Bitfield-Mask: 0x01) */ /* ==================================================== UART3_CTRL_REG ===================================================== */ #define UART3_UART3_CTRL_REG_ISO7816_AUTO_GT_Pos (11UL) /*!< ISO7816_AUTO_GT (Bit 11) */ #define UART3_UART3_CTRL_REG_ISO7816_AUTO_GT_Msk (0x800UL) /*!< ISO7816_AUTO_GT (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_VALUE_IRQMASK_Pos (10UL) /*!< ISO7816_ERR_TX_VALUE_IRQMASK (Bit 10) */ #define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_VALUE_IRQMASK_Msk (0x400UL) /*!< ISO7816_ERR_TX_VALUE_IRQMASK (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_TIME_IRQMASK_Pos (9UL) /*!< ISO7816_ERR_TX_TIME_IRQMASK (Bit 9) */ #define UART3_UART3_CTRL_REG_ISO7816_ERR_TX_TIME_IRQMASK_Msk (0x200UL) /*!< ISO7816_ERR_TX_TIME_IRQMASK (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_TIM_EXPIRED_IRQMASK_Pos (8UL) /*!< ISO7816_TIM_EXPIRED_IRQMASK (Bit 8) */ #define UART3_UART3_CTRL_REG_ISO7816_TIM_EXPIRED_IRQMASK_Msk (0x100UL) /*!< ISO7816_TIM_EXPIRED_IRQMASK (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_STATUS_Pos (7UL) /*!< ISO7816_CLK_STATUS (Bit 7) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_STATUS_Msk (0x80UL) /*!< ISO7816_CLK_STATUS (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_LEVEL_Pos (6UL) /*!< ISO7816_CLK_LEVEL (Bit 6) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_LEVEL_Msk (0x40UL) /*!< ISO7816_CLK_LEVEL (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_EN_Pos (5UL) /*!< ISO7816_CLK_EN (Bit 5) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_EN_Msk (0x20UL) /*!< ISO7816_CLK_EN (Bitfield-Mask: 0x01) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_DIV_Pos (0UL) /*!< ISO7816_CLK_DIV (Bit 0) */ #define UART3_UART3_CTRL_REG_ISO7816_CLK_DIV_Msk (0x1fUL) /*!< ISO7816_CLK_DIV (Bitfield-Mask: 0x1f) */ /* ===================================================== UART3_CTR_REG ===================================================== */ #define UART3_UART3_CTR_REG_UART_CTR_Pos (0UL) /*!< UART_CTR (Bit 0) */ #define UART3_UART3_CTR_REG_UART_CTR_Msk (0xffffffffUL) /*!< UART_CTR (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART3_DLF_REG ===================================================== */ #define UART3_UART3_DLF_REG_UART_DLF_Pos (0UL) /*!< UART_DLF (Bit 0) */ #define UART3_UART3_DLF_REG_UART_DLF_Msk (0xfUL) /*!< UART_DLF (Bitfield-Mask: 0x0f) */ /* ==================================================== UART3_DMASA_REG ==================================================== */ #define UART3_UART3_DMASA_REG_UART_DMASA_Pos (0UL) /*!< UART_DMASA (Bit 0) */ #define UART3_UART3_DMASA_REG_UART_DMASA_Msk (0x1UL) /*!< UART_DMASA (Bitfield-Mask: 0x01) */ /* ================================================== UART3_ERR_CTRL_REG =================================================== */ #define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_WIDTH_Pos (4UL) /*!< ISO7816_ERR_PULSE_WIDTH (Bit 4) */ #define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_WIDTH_Msk (0x1f0UL) /*!< ISO7816_ERR_PULSE_WIDTH (Bitfield-Mask: 0x1f) */ #define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_OFFSET_Pos (0UL) /*!< ISO7816_ERR_PULSE_OFFSET (Bit 0) */ #define UART3_UART3_ERR_CTRL_REG_ISO7816_ERR_PULSE_OFFSET_Msk (0xfUL) /*!< ISO7816_ERR_PULSE_OFFSET (Bitfield-Mask: 0x0f) */ /* ===================================================== UART3_HTX_REG ===================================================== */ #define UART3_UART3_HTX_REG_UART_HALT_TX_Pos (0UL) /*!< UART_HALT_TX (Bit 0) */ #define UART3_UART3_HTX_REG_UART_HALT_TX_Msk (0x1UL) /*!< UART_HALT_TX (Bitfield-Mask: 0x01) */ /* =================================================== UART3_IER_DLH_REG =================================================== */ #define UART3_UART3_IER_DLH_REG_PTIME_DLH7_Pos (7UL) /*!< PTIME_DLH7 (Bit 7) */ #define UART3_UART3_IER_DLH_REG_PTIME_DLH7_Msk (0x80UL) /*!< PTIME_DLH7 (Bitfield-Mask: 0x01) */ #define UART3_UART3_IER_DLH_REG_DLH6_5_Pos (5UL) /*!< DLH6_5 (Bit 5) */ #define UART3_UART3_IER_DLH_REG_DLH6_5_Msk (0x60UL) /*!< DLH6_5 (Bitfield-Mask: 0x03) */ #define UART3_UART3_IER_DLH_REG_ELCOLR_DLH4_Pos (4UL) /*!< ELCOLR_DLH4 (Bit 4) */ #define UART3_UART3_IER_DLH_REG_ELCOLR_DLH4_Msk (0x10UL) /*!< ELCOLR_DLH4 (Bitfield-Mask: 0x01) */ #define UART3_UART3_IER_DLH_REG_EDSSI_DLH3_Pos (3UL) /*!< EDSSI_DLH3 (Bit 3) */ #define UART3_UART3_IER_DLH_REG_EDSSI_DLH3_Msk (0x8UL) /*!< EDSSI_DLH3 (Bitfield-Mask: 0x01) */ #define UART3_UART3_IER_DLH_REG_ELSI_DLH2_Pos (2UL) /*!< ELSI_DLH2 (Bit 2) */ #define UART3_UART3_IER_DLH_REG_ELSI_DLH2_Msk (0x4UL) /*!< ELSI_DLH2 (Bitfield-Mask: 0x01) */ #define UART3_UART3_IER_DLH_REG_ETBEI_DLH1_Pos (1UL) /*!< ETBEI_DLH1 (Bit 1) */ #define UART3_UART3_IER_DLH_REG_ETBEI_DLH1_Msk (0x2UL) /*!< ETBEI_DLH1 (Bitfield-Mask: 0x01) */ #define UART3_UART3_IER_DLH_REG_ERBFI_DLH0_Pos (0UL) /*!< ERBFI_DLH0 (Bit 0) */ #define UART3_UART3_IER_DLH_REG_ERBFI_DLH0_Msk (0x1UL) /*!< ERBFI_DLH0 (Bitfield-Mask: 0x01) */ /* =================================================== UART3_IIR_FCR_REG =================================================== */ #define UART3_UART3_IIR_FCR_REG_IIR_FCR_Pos (0UL) /*!< IIR_FCR (Bit 0) */ #define UART3_UART3_IIR_FCR_REG_IIR_FCR_Msk (0xffUL) /*!< IIR_FCR (Bitfield-Mask: 0xff) */ /* ================================================= UART3_IRQ_STATUS_REG ================================================== */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_VALUE_IRQ_Pos (2UL) /*!< ISO7816_ERR_TX_VALUE_IRQ (Bit 2) */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_VALUE_IRQ_Msk (0x4UL) /*!< ISO7816_ERR_TX_VALUE_IRQ (Bitfield-Mask: 0x01) */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_TIME_IRQ_Pos (1UL) /*!< ISO7816_ERR_TX_TIME_IRQ (Bit 1) */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_ERR_TX_TIME_IRQ_Msk (0x2UL) /*!< ISO7816_ERR_TX_TIME_IRQ (Bitfield-Mask: 0x01) */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_TIM_EXPIRED_IRQ_Pos (0UL) /*!< ISO7816_TIM_EXPIRED_IRQ (Bit 0) */ #define UART3_UART3_IRQ_STATUS_REG_ISO7816_TIM_EXPIRED_IRQ_Msk (0x1UL) /*!< ISO7816_TIM_EXPIRED_IRQ (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_LCR_EXT ===================================================== */ #define UART3_UART3_LCR_EXT_UART_TRANSMIT_MODE_Pos (3UL) /*!< UART_TRANSMIT_MODE (Bit 3) */ #define UART3_UART3_LCR_EXT_UART_TRANSMIT_MODE_Msk (0x8UL) /*!< UART_TRANSMIT_MODE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_EXT_UART_SEND_ADDR_Pos (2UL) /*!< UART_SEND_ADDR (Bit 2) */ #define UART3_UART3_LCR_EXT_UART_SEND_ADDR_Msk (0x4UL) /*!< UART_SEND_ADDR (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_EXT_UART_ADDR_MATCH_Pos (1UL) /*!< UART_ADDR_MATCH (Bit 1) */ #define UART3_UART3_LCR_EXT_UART_ADDR_MATCH_Msk (0x2UL) /*!< UART_ADDR_MATCH (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_EXT_UART_DLS_E_Pos (0UL) /*!< UART_DLS_E (Bit 0) */ #define UART3_UART3_LCR_EXT_UART_DLS_E_Msk (0x1UL) /*!< UART_DLS_E (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_LCR_REG ===================================================== */ #define UART3_UART3_LCR_REG_UART_DLAB_Pos (7UL) /*!< UART_DLAB (Bit 7) */ #define UART3_UART3_LCR_REG_UART_DLAB_Msk (0x80UL) /*!< UART_DLAB (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_BC_Pos (6UL) /*!< UART_BC (Bit 6) */ #define UART3_UART3_LCR_REG_UART_BC_Msk (0x40UL) /*!< UART_BC (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_SP_Pos (5UL) /*!< UART_SP (Bit 5) */ #define UART3_UART3_LCR_REG_UART_SP_Msk (0x20UL) /*!< UART_SP (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_EPS_Pos (4UL) /*!< UART_EPS (Bit 4) */ #define UART3_UART3_LCR_REG_UART_EPS_Msk (0x10UL) /*!< UART_EPS (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_PEN_Pos (3UL) /*!< UART_PEN (Bit 3) */ #define UART3_UART3_LCR_REG_UART_PEN_Msk (0x8UL) /*!< UART_PEN (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_STOP_Pos (2UL) /*!< UART_STOP (Bit 2) */ #define UART3_UART3_LCR_REG_UART_STOP_Msk (0x4UL) /*!< UART_STOP (Bitfield-Mask: 0x01) */ #define UART3_UART3_LCR_REG_UART_DLS_Pos (0UL) /*!< UART_DLS (Bit 0) */ #define UART3_UART3_LCR_REG_UART_DLS_Msk (0x3UL) /*!< UART_DLS (Bitfield-Mask: 0x03) */ /* ===================================================== UART3_LSR_REG ===================================================== */ #define UART3_UART3_LSR_REG_UART_ADDR_RCVD_Pos (8UL) /*!< UART_ADDR_RCVD (Bit 8) */ #define UART3_UART3_LSR_REG_UART_ADDR_RCVD_Msk (0x100UL) /*!< UART_ADDR_RCVD (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_RFE_Pos (7UL) /*!< UART_RFE (Bit 7) */ #define UART3_UART3_LSR_REG_UART_RFE_Msk (0x80UL) /*!< UART_RFE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_TEMT_Pos (6UL) /*!< UART_TEMT (Bit 6) */ #define UART3_UART3_LSR_REG_UART_TEMT_Msk (0x40UL) /*!< UART_TEMT (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_THRE_Pos (5UL) /*!< UART_THRE (Bit 5) */ #define UART3_UART3_LSR_REG_UART_THRE_Msk (0x20UL) /*!< UART_THRE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_BI_Pos (4UL) /*!< UART_BI (Bit 4) */ #define UART3_UART3_LSR_REG_UART_BI_Msk (0x10UL) /*!< UART_BI (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_FE_Pos (3UL) /*!< UART_FE (Bit 3) */ #define UART3_UART3_LSR_REG_UART_FE_Msk (0x8UL) /*!< UART_FE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_PE_Pos (2UL) /*!< UART_PE (Bit 2) */ #define UART3_UART3_LSR_REG_UART_PE_Msk (0x4UL) /*!< UART_PE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_OE_Pos (1UL) /*!< UART_OE (Bit 1) */ #define UART3_UART3_LSR_REG_UART_OE_Msk (0x2UL) /*!< UART_OE (Bitfield-Mask: 0x01) */ #define UART3_UART3_LSR_REG_UART_DR_Pos (0UL) /*!< UART_DR (Bit 0) */ #define UART3_UART3_LSR_REG_UART_DR_Msk (0x1UL) /*!< UART_DR (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_MCR_REG ===================================================== */ #define UART3_UART3_MCR_REG_UART_AFCE_Pos (5UL) /*!< UART_AFCE (Bit 5) */ #define UART3_UART3_MCR_REG_UART_AFCE_Msk (0x20UL) /*!< UART_AFCE (Bitfield-Mask: 0x01) */ #define UART3_UART3_MCR_REG_UART_LB_Pos (4UL) /*!< UART_LB (Bit 4) */ #define UART3_UART3_MCR_REG_UART_LB_Msk (0x10UL) /*!< UART_LB (Bitfield-Mask: 0x01) */ #define UART3_UART3_MCR_REG_UART_RTS_Pos (1UL) /*!< UART_RTS (Bit 1) */ #define UART3_UART3_MCR_REG_UART_RTS_Msk (0x2UL) /*!< UART_RTS (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_MSR_REG ===================================================== */ #define UART3_UART3_MSR_REG_UART_CTS_Pos (4UL) /*!< UART_CTS (Bit 4) */ #define UART3_UART3_MSR_REG_UART_CTS_Msk (0x10UL) /*!< UART_CTS (Bitfield-Mask: 0x01) */ #define UART3_UART3_MSR_REG_UART_DCTS_Pos (0UL) /*!< UART_DCTS (Bit 0) */ #define UART3_UART3_MSR_REG_UART_DCTS_Msk (0x1UL) /*!< UART_DCTS (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_RAR_REG ===================================================== */ #define UART3_UART3_RAR_REG_UART_RAR_Pos (0UL) /*!< UART_RAR (Bit 0) */ #define UART3_UART3_RAR_REG_UART_RAR_Msk (0xffUL) /*!< UART_RAR (Bitfield-Mask: 0xff) */ /* ================================================= UART3_RBR_THR_DLL_REG ================================================= */ #define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_9BIT_Pos (8UL) /*!< RBR_THR_9BIT (Bit 8) */ #define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_9BIT_Msk (0x100UL) /*!< RBR_THR_9BIT (Bitfield-Mask: 0x01) */ #define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_DLL_Pos (0UL) /*!< RBR_THR_DLL (Bit 0) */ #define UART3_UART3_RBR_THR_DLL_REG_RBR_THR_DLL_Msk (0xffUL) /*!< RBR_THR_DLL (Bitfield-Mask: 0xff) */ /* ===================================================== UART3_RFL_REG ===================================================== */ #define UART3_UART3_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Pos (0UL) /*!< UART_RECEIVE_FIFO_LEVEL (Bit 0) */ #define UART3_UART3_RFL_REG_UART_RECEIVE_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_RECEIVE_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ==================================================== UART3_SBCR_REG ===================================================== */ #define UART3_UART3_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Pos (0UL) /*!< UART_SHADOW_BREAK_CONTROL (Bit 0) */ #define UART3_UART3_SBCR_REG_UART_SHADOW_BREAK_CONTROL_Msk (0x1UL) /*!< UART_SHADOW_BREAK_CONTROL (Bitfield-Mask: 0x01) */ /* ==================================================== UART3_SDMAM_REG ==================================================== */ #define UART3_UART3_SDMAM_REG_UART_SHADOW_DMA_MODE_Pos (0UL) /*!< UART_SHADOW_DMA_MODE (Bit 0) */ #define UART3_UART3_SDMAM_REG_UART_SHADOW_DMA_MODE_Msk (0x1UL) /*!< UART_SHADOW_DMA_MODE (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_SFE_REG ===================================================== */ #define UART3_UART3_SFE_REG_UART_SHADOW_FIFO_ENABLE_Pos (0UL) /*!< UART_SHADOW_FIFO_ENABLE (Bit 0) */ #define UART3_UART3_SFE_REG_UART_SHADOW_FIFO_ENABLE_Msk (0x1UL) /*!< UART_SHADOW_FIFO_ENABLE (Bitfield-Mask: 0x01) */ /* ================================================= UART3_SRBR_STHR0_REG ================================================== */ #define UART3_UART3_SRBR_STHR0_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR0_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR10_REG ================================================= */ #define UART3_UART3_SRBR_STHR10_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR10_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR11_REG ================================================= */ #define UART3_UART3_SRBR_STHR11_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR11_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR12_REG ================================================= */ #define UART3_UART3_SRBR_STHR12_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR12_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR13_REG ================================================= */ #define UART3_UART3_SRBR_STHR13_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR13_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR14_REG ================================================= */ #define UART3_UART3_SRBR_STHR14_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR14_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR15_REG ================================================= */ #define UART3_UART3_SRBR_STHR15_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR15_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR1_REG ================================================== */ #define UART3_UART3_SRBR_STHR1_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR1_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR2_REG ================================================== */ #define UART3_UART3_SRBR_STHR2_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR2_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR3_REG ================================================== */ #define UART3_UART3_SRBR_STHR3_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR3_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR4_REG ================================================== */ #define UART3_UART3_SRBR_STHR4_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR4_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR5_REG ================================================== */ #define UART3_UART3_SRBR_STHR5_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR5_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR6_REG ================================================== */ #define UART3_UART3_SRBR_STHR6_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR6_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR7_REG ================================================== */ #define UART3_UART3_SRBR_STHR7_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR7_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR8_REG ================================================== */ #define UART3_UART3_SRBR_STHR8_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR8_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ================================================= UART3_SRBR_STHR9_REG ================================================== */ #define UART3_UART3_SRBR_STHR9_REG_SRBR_STHRx_Pos (0UL) /*!< SRBR_STHRx (Bit 0) */ #define UART3_UART3_SRBR_STHR9_REG_SRBR_STHRx_Msk (0xffUL) /*!< SRBR_STHRx (Bitfield-Mask: 0xff) */ /* ===================================================== UART3_SRR_REG ===================================================== */ #define UART3_UART3_SRR_REG_UART_XFR_Pos (2UL) /*!< UART_XFR (Bit 2) */ #define UART3_UART3_SRR_REG_UART_XFR_Msk (0x4UL) /*!< UART_XFR (Bitfield-Mask: 0x01) */ #define UART3_UART3_SRR_REG_UART_RFR_Pos (1UL) /*!< UART_RFR (Bit 1) */ #define UART3_UART3_SRR_REG_UART_RFR_Msk (0x2UL) /*!< UART_RFR (Bitfield-Mask: 0x01) */ #define UART3_UART3_SRR_REG_UART_UR_Pos (0UL) /*!< UART_UR (Bit 0) */ #define UART3_UART3_SRR_REG_UART_UR_Msk (0x1UL) /*!< UART_UR (Bitfield-Mask: 0x01) */ /* ==================================================== UART3_SRTS_REG ===================================================== */ #define UART3_UART3_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Pos (0UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bit 0) */ #define UART3_UART3_SRTS_REG_UART_SHADOW_REQUEST_TO_SEND_Msk (0x1UL) /*!< UART_SHADOW_REQUEST_TO_SEND (Bitfield-Mask: 0x01) */ /* ===================================================== UART3_SRT_REG ===================================================== */ #define UART3_UART3_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Pos (0UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bit 0) */ #define UART3_UART3_SRT_REG_UART_SHADOW_RCVR_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_RCVR_TRIGGER (Bitfield-Mask: 0x03) */ /* ==================================================== UART3_STET_REG ===================================================== */ #define UART3_UART3_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Pos (0UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bit 0) */ #define UART3_UART3_STET_REG_UART_SHADOW_TX_EMPTY_TRIGGER_Msk (0x3UL) /*!< UART_SHADOW_TX_EMPTY_TRIGGER (Bitfield-Mask: 0x03) */ /* ===================================================== UART3_TAR_REG ===================================================== */ #define UART3_UART3_TAR_REG_UART_TAR_Pos (0UL) /*!< UART_TAR (Bit 0) */ #define UART3_UART3_TAR_REG_UART_TAR_Msk (0xffUL) /*!< UART_TAR (Bitfield-Mask: 0xff) */ /* ===================================================== UART3_TFL_REG ===================================================== */ #define UART3_UART3_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Pos (0UL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bit 0) */ #define UART3_UART3_TFL_REG_UART_TRANSMIT_FIFO_LEVEL_Msk (0x1fUL) /*!< UART_TRANSMIT_FIFO_LEVEL (Bitfield-Mask: 0x1f) */ /* ==================================================== UART3_TIMER_REG ==================================================== */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_MODE_Pos (17UL) /*!< ISO7816_TIM_MODE (Bit 17) */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_MODE_Msk (0x20000UL) /*!< ISO7816_TIM_MODE (Bitfield-Mask: 0x01) */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_EN_Pos (16UL) /*!< ISO7816_TIM_EN (Bit 16) */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_EN_Msk (0x10000UL) /*!< ISO7816_TIM_EN (Bitfield-Mask: 0x01) */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_MAX_Pos (0UL) /*!< ISO7816_TIM_MAX (Bit 0) */ #define UART3_UART3_TIMER_REG_ISO7816_TIM_MAX_Msk (0xffffUL) /*!< ISO7816_TIM_MAX (Bitfield-Mask: 0xffff) */ /* ===================================================== UART3_UCV_REG ===================================================== */ #define UART3_UART3_UCV_REG_UART_UCV_Pos (0UL) /*!< UART_UCV (Bit 0) */ #define UART3_UART3_UCV_REG_UART_UCV_Msk (0xffffffffUL) /*!< UART_UCV (Bitfield-Mask: 0xffffffff) */ /* ===================================================== UART3_USR_REG ===================================================== */ #define UART3_UART3_USR_REG_UART_RFF_Pos (4UL) /*!< UART_RFF (Bit 4) */ #define UART3_UART3_USR_REG_UART_RFF_Msk (0x10UL) /*!< UART_RFF (Bitfield-Mask: 0x01) */ #define UART3_UART3_USR_REG_UART_RFNE_Pos (3UL) /*!< UART_RFNE (Bit 3) */ #define UART3_UART3_USR_REG_UART_RFNE_Msk (0x8UL) /*!< UART_RFNE (Bitfield-Mask: 0x01) */ #define UART3_UART3_USR_REG_UART_TFE_Pos (2UL) /*!< UART_TFE (Bit 2) */ #define UART3_UART3_USR_REG_UART_TFE_Msk (0x4UL) /*!< UART_TFE (Bitfield-Mask: 0x01) */ #define UART3_UART3_USR_REG_UART_TFNF_Pos (1UL) /*!< UART_TFNF (Bit 1) */ #define UART3_UART3_USR_REG_UART_TFNF_Msk (0x2UL) /*!< UART_TFNF (Bitfield-Mask: 0x01) */ #define UART3_UART3_USR_REG_UART_BUSY_Pos (0UL) /*!< UART_BUSY (Bit 0) */ #define UART3_UART3_USR_REG_UART_BUSY_Msk (0x1UL) /*!< UART_BUSY (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ USB ================ */ /* =========================================================================================================================== */ /* ===================================================== USB_ALTEV_REG ===================================================== */ #define USB_USB_ALTEV_REG_USB_RESUME_Pos (7UL) /*!< USB_RESUME (Bit 7) */ #define USB_USB_ALTEV_REG_USB_RESUME_Msk (0x80UL) /*!< USB_RESUME (Bitfield-Mask: 0x01) */ #define USB_USB_ALTEV_REG_USB_RESET_Pos (6UL) /*!< USB_RESET (Bit 6) */ #define USB_USB_ALTEV_REG_USB_RESET_Msk (0x40UL) /*!< USB_RESET (Bitfield-Mask: 0x01) */ #define USB_USB_ALTEV_REG_USB_SD5_Pos (5UL) /*!< USB_SD5 (Bit 5) */ #define USB_USB_ALTEV_REG_USB_SD5_Msk (0x20UL) /*!< USB_SD5 (Bitfield-Mask: 0x01) */ #define USB_USB_ALTEV_REG_USB_SD3_Pos (4UL) /*!< USB_SD3 (Bit 4) */ #define USB_USB_ALTEV_REG_USB_SD3_Msk (0x10UL) /*!< USB_SD3 (Bitfield-Mask: 0x01) */ #define USB_USB_ALTEV_REG_USB_EOP_Pos (3UL) /*!< USB_EOP (Bit 3) */ #define USB_USB_ALTEV_REG_USB_EOP_Msk (0x8UL) /*!< USB_EOP (Bitfield-Mask: 0x01) */ /* ==================================================== USB_ALTMSK_REG ===================================================== */ #define USB_USB_ALTMSK_REG_USB_M_RESUME_Pos (7UL) /*!< USB_M_RESUME (Bit 7) */ #define USB_USB_ALTMSK_REG_USB_M_RESUME_Msk (0x80UL) /*!< USB_M_RESUME (Bitfield-Mask: 0x01) */ #define USB_USB_ALTMSK_REG_USB_M_RESET_Pos (6UL) /*!< USB_M_RESET (Bit 6) */ #define USB_USB_ALTMSK_REG_USB_M_RESET_Msk (0x40UL) /*!< USB_M_RESET (Bitfield-Mask: 0x01) */ #define USB_USB_ALTMSK_REG_USB_M_SD5_Pos (5UL) /*!< USB_M_SD5 (Bit 5) */ #define USB_USB_ALTMSK_REG_USB_M_SD5_Msk (0x20UL) /*!< USB_M_SD5 (Bitfield-Mask: 0x01) */ #define USB_USB_ALTMSK_REG_USB_M_SD3_Pos (4UL) /*!< USB_M_SD3 (Bit 4) */ #define USB_USB_ALTMSK_REG_USB_M_SD3_Msk (0x10UL) /*!< USB_M_SD3 (Bitfield-Mask: 0x01) */ #define USB_USB_ALTMSK_REG_USB_M_EOP_Pos (3UL) /*!< USB_M_EOP (Bit 3) */ #define USB_USB_ALTMSK_REG_USB_M_EOP_Msk (0x8UL) /*!< USB_M_EOP (Bitfield-Mask: 0x01) */ /* ================================================= USB_CHARGER_CTRL_REG ================================================== */ #define USB_USB_CHARGER_CTRL_REG_IDM_SINK_ON_Pos (5UL) /*!< IDM_SINK_ON (Bit 5) */ #define USB_USB_CHARGER_CTRL_REG_IDM_SINK_ON_Msk (0x20UL) /*!< IDM_SINK_ON (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_CTRL_REG_IDP_SINK_ON_Pos (4UL) /*!< IDP_SINK_ON (Bit 4) */ #define USB_USB_CHARGER_CTRL_REG_IDP_SINK_ON_Msk (0x10UL) /*!< IDP_SINK_ON (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_CTRL_REG_VDM_SRC_ON_Pos (3UL) /*!< VDM_SRC_ON (Bit 3) */ #define USB_USB_CHARGER_CTRL_REG_VDM_SRC_ON_Msk (0x8UL) /*!< VDM_SRC_ON (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_CTRL_REG_VDP_SRC_ON_Pos (2UL) /*!< VDP_SRC_ON (Bit 2) */ #define USB_USB_CHARGER_CTRL_REG_VDP_SRC_ON_Msk (0x4UL) /*!< VDP_SRC_ON (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_CTRL_REG_IDP_SRC_ON_Pos (1UL) /*!< IDP_SRC_ON (Bit 1) */ #define USB_USB_CHARGER_CTRL_REG_IDP_SRC_ON_Msk (0x2UL) /*!< IDP_SRC_ON (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_CTRL_REG_USB_CHARGE_ON_Pos (0UL) /*!< USB_CHARGE_ON (Bit 0) */ #define USB_USB_CHARGER_CTRL_REG_USB_CHARGE_ON_Msk (0x1UL) /*!< USB_CHARGE_ON (Bitfield-Mask: 0x01) */ /* ================================================= USB_CHARGER_STAT_REG ================================================== */ #define USB_USB_CHARGER_STAT_REG_USB_DM_VAL2_Pos (5UL) /*!< USB_DM_VAL2 (Bit 5) */ #define USB_USB_CHARGER_STAT_REG_USB_DM_VAL2_Msk (0x20UL) /*!< USB_DM_VAL2 (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_STAT_REG_USB_DP_VAL2_Pos (4UL) /*!< USB_DP_VAL2 (Bit 4) */ #define USB_USB_CHARGER_STAT_REG_USB_DP_VAL2_Msk (0x10UL) /*!< USB_DP_VAL2 (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_STAT_REG_USB_DM_VAL_Pos (3UL) /*!< USB_DM_VAL (Bit 3) */ #define USB_USB_CHARGER_STAT_REG_USB_DM_VAL_Msk (0x8UL) /*!< USB_DM_VAL (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_STAT_REG_USB_DP_VAL_Pos (2UL) /*!< USB_DP_VAL (Bit 2) */ #define USB_USB_CHARGER_STAT_REG_USB_DP_VAL_Msk (0x4UL) /*!< USB_DP_VAL (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_STAT_REG_USB_CHG_DET_Pos (1UL) /*!< USB_CHG_DET (Bit 1) */ #define USB_USB_CHARGER_STAT_REG_USB_CHG_DET_Msk (0x2UL) /*!< USB_CHG_DET (Bitfield-Mask: 0x01) */ #define USB_USB_CHARGER_STAT_REG_USB_DCP_DET_Pos (0UL) /*!< USB_DCP_DET (Bit 0) */ #define USB_USB_CHARGER_STAT_REG_USB_DCP_DET_Msk (0x1UL) /*!< USB_DCP_DET (Bitfield-Mask: 0x01) */ /* =================================================== USB_DMA_CTRL_REG ==================================================== */ #define USB_USB_DMA_CTRL_REG_USB_DMA_EN_Pos (6UL) /*!< USB_DMA_EN (Bit 6) */ #define USB_USB_DMA_CTRL_REG_USB_DMA_EN_Msk (0x40UL) /*!< USB_DMA_EN (Bitfield-Mask: 0x01) */ #define USB_USB_DMA_CTRL_REG_USB_DMA_TX_Pos (3UL) /*!< USB_DMA_TX (Bit 3) */ #define USB_USB_DMA_CTRL_REG_USB_DMA_TX_Msk (0x38UL) /*!< USB_DMA_TX (Bitfield-Mask: 0x07) */ #define USB_USB_DMA_CTRL_REG_USB_DMA_RX_Pos (0UL) /*!< USB_DMA_RX (Bit 0) */ #define USB_USB_DMA_CTRL_REG_USB_DMA_RX_Msk (0x7UL) /*!< USB_DMA_RX (Bitfield-Mask: 0x07) */ /* ==================================================== USB_EP0_NAK_REG ==================================================== */ #define USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK_Pos (1UL) /*!< USB_EP0_OUTNAK (Bit 1) */ #define USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK_Msk (0x2UL) /*!< USB_EP0_OUTNAK (Bitfield-Mask: 0x01) */ #define USB_USB_EP0_NAK_REG_USB_EP0_INNAK_Pos (0UL) /*!< USB_EP0_INNAK (Bit 0) */ #define USB_USB_EP0_NAK_REG_USB_EP0_INNAK_Msk (0x1UL) /*!< USB_EP0_INNAK (Bitfield-Mask: 0x01) */ /* ===================================================== USB_EPC0_REG ====================================================== */ #define USB_USB_EPC0_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC0_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC0_REG_USB_DEF_Pos (6UL) /*!< USB_DEF (Bit 6) */ #define USB_USB_EPC0_REG_USB_DEF_Msk (0x40UL) /*!< USB_DEF (Bitfield-Mask: 0x01) */ #define USB_USB_EPC0_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC0_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC1_REG ====================================================== */ #define USB_USB_EPC1_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC1_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC1_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC1_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC1_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC1_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC1_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC1_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC2_REG ====================================================== */ #define USB_USB_EPC2_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC2_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC2_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC2_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC2_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC2_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC2_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC2_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC3_REG ====================================================== */ #define USB_USB_EPC3_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC3_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC3_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC3_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC3_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC3_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC3_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC3_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC4_REG ====================================================== */ #define USB_USB_EPC4_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC4_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC4_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC4_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC4_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC4_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC4_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC4_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC5_REG ====================================================== */ #define USB_USB_EPC5_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC5_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC5_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC5_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC5_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC5_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC5_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC5_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_EPC6_REG ====================================================== */ #define USB_USB_EPC6_REG_USB_STALL_Pos (7UL) /*!< USB_STALL (Bit 7) */ #define USB_USB_EPC6_REG_USB_STALL_Msk (0x80UL) /*!< USB_STALL (Bitfield-Mask: 0x01) */ #define USB_USB_EPC6_REG_USB_ISO_Pos (5UL) /*!< USB_ISO (Bit 5) */ #define USB_USB_EPC6_REG_USB_ISO_Msk (0x20UL) /*!< USB_ISO (Bitfield-Mask: 0x01) */ #define USB_USB_EPC6_REG_USB_EP_EN_Pos (4UL) /*!< USB_EP_EN (Bit 4) */ #define USB_USB_EPC6_REG_USB_EP_EN_Msk (0x10UL) /*!< USB_EP_EN (Bitfield-Mask: 0x01) */ #define USB_USB_EPC6_REG_USB_EP_Pos (0UL) /*!< USB_EP (Bit 0) */ #define USB_USB_EPC6_REG_USB_EP_Msk (0xfUL) /*!< USB_EP (Bitfield-Mask: 0x0f) */ /* ====================================================== USB_FAR_REG ====================================================== */ #define USB_USB_FAR_REG_USB_AD_EN_Pos (7UL) /*!< USB_AD_EN (Bit 7) */ #define USB_USB_FAR_REG_USB_AD_EN_Msk (0x80UL) /*!< USB_AD_EN (Bitfield-Mask: 0x01) */ #define USB_USB_FAR_REG_USB_AD_Pos (0UL) /*!< USB_AD (Bit 0) */ #define USB_USB_FAR_REG_USB_AD_Msk (0x7fUL) /*!< USB_AD (Bitfield-Mask: 0x7f) */ /* ====================================================== USB_FNH_REG ====================================================== */ #define USB_USB_FNH_REG_USB_MF_Pos (7UL) /*!< USB_MF (Bit 7) */ #define USB_USB_FNH_REG_USB_MF_Msk (0x80UL) /*!< USB_MF (Bitfield-Mask: 0x01) */ #define USB_USB_FNH_REG_USB_UL_Pos (6UL) /*!< USB_UL (Bit 6) */ #define USB_USB_FNH_REG_USB_UL_Msk (0x40UL) /*!< USB_UL (Bitfield-Mask: 0x01) */ #define USB_USB_FNH_REG_USB_RFC_Pos (5UL) /*!< USB_RFC (Bit 5) */ #define USB_USB_FNH_REG_USB_RFC_Msk (0x20UL) /*!< USB_RFC (Bitfield-Mask: 0x01) */ #define USB_USB_FNH_REG_USB_FN_10_8_Pos (0UL) /*!< USB_FN_10_8 (Bit 0) */ #define USB_USB_FNH_REG_USB_FN_10_8_Msk (0x7UL) /*!< USB_FN_10_8 (Bitfield-Mask: 0x07) */ /* ====================================================== USB_FNL_REG ====================================================== */ #define USB_USB_FNL_REG_USB_FN_Pos (0UL) /*!< USB_FN (Bit 0) */ #define USB_USB_FNL_REG_USB_FN_Msk (0xffUL) /*!< USB_FN (Bitfield-Mask: 0xff) */ /* ===================================================== USB_FWEV_REG ====================================================== */ #define USB_USB_FWEV_REG_USB_RXWARN31_Pos (4UL) /*!< USB_RXWARN31 (Bit 4) */ #define USB_USB_FWEV_REG_USB_RXWARN31_Msk (0x70UL) /*!< USB_RXWARN31 (Bitfield-Mask: 0x07) */ #define USB_USB_FWEV_REG_USB_TXWARN31_Pos (0UL) /*!< USB_TXWARN31 (Bit 0) */ #define USB_USB_FWEV_REG_USB_TXWARN31_Msk (0x7UL) /*!< USB_TXWARN31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_FWMSK_REG ===================================================== */ #define USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos (4UL) /*!< USB_M_RXWARN31 (Bit 4) */ #define USB_USB_FWMSK_REG_USB_M_RXWARN31_Msk (0x70UL) /*!< USB_M_RXWARN31 (Bitfield-Mask: 0x07) */ #define USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos (0UL) /*!< USB_M_TXWARN31 (Bit 0) */ #define USB_USB_FWMSK_REG_USB_M_TXWARN31_Msk (0x7UL) /*!< USB_M_TXWARN31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_MAEV_REG ====================================================== */ #define USB_USB_MAEV_REG_USB_CH_EV_Pos (11UL) /*!< USB_CH_EV (Bit 11) */ #define USB_USB_MAEV_REG_USB_CH_EV_Msk (0x800UL) /*!< USB_CH_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_EP0_NAK_Pos (10UL) /*!< USB_EP0_NAK (Bit 10) */ #define USB_USB_MAEV_REG_USB_EP0_NAK_Msk (0x400UL) /*!< USB_EP0_NAK (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_EP0_RX_Pos (9UL) /*!< USB_EP0_RX (Bit 9) */ #define USB_USB_MAEV_REG_USB_EP0_RX_Msk (0x200UL) /*!< USB_EP0_RX (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_EP0_TX_Pos (8UL) /*!< USB_EP0_TX (Bit 8) */ #define USB_USB_MAEV_REG_USB_EP0_TX_Msk (0x100UL) /*!< USB_EP0_TX (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_INTR_Pos (7UL) /*!< USB_INTR (Bit 7) */ #define USB_USB_MAEV_REG_USB_INTR_Msk (0x80UL) /*!< USB_INTR (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_RX_EV_Pos (6UL) /*!< USB_RX_EV (Bit 6) */ #define USB_USB_MAEV_REG_USB_RX_EV_Msk (0x40UL) /*!< USB_RX_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_ULD_Pos (5UL) /*!< USB_ULD (Bit 5) */ #define USB_USB_MAEV_REG_USB_ULD_Msk (0x20UL) /*!< USB_ULD (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_NAK_Pos (4UL) /*!< USB_NAK (Bit 4) */ #define USB_USB_MAEV_REG_USB_NAK_Msk (0x10UL) /*!< USB_NAK (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_FRAME_Pos (3UL) /*!< USB_FRAME (Bit 3) */ #define USB_USB_MAEV_REG_USB_FRAME_Msk (0x8UL) /*!< USB_FRAME (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_TX_EV_Pos (2UL) /*!< USB_TX_EV (Bit 2) */ #define USB_USB_MAEV_REG_USB_TX_EV_Msk (0x4UL) /*!< USB_TX_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_ALT_Pos (1UL) /*!< USB_ALT (Bit 1) */ #define USB_USB_MAEV_REG_USB_ALT_Msk (0x2UL) /*!< USB_ALT (Bitfield-Mask: 0x01) */ #define USB_USB_MAEV_REG_USB_WARN_Pos (0UL) /*!< USB_WARN (Bit 0) */ #define USB_USB_MAEV_REG_USB_WARN_Msk (0x1UL) /*!< USB_WARN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_MAMSK_REG ===================================================== */ #define USB_USB_MAMSK_REG_USB_M_CH_EV_Pos (11UL) /*!< USB_M_CH_EV (Bit 11) */ #define USB_USB_MAMSK_REG_USB_M_CH_EV_Msk (0x800UL) /*!< USB_M_CH_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_EP0_NAK_Pos (10UL) /*!< USB_M_EP0_NAK (Bit 10) */ #define USB_USB_MAMSK_REG_USB_M_EP0_NAK_Msk (0x400UL) /*!< USB_M_EP0_NAK (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_EP0_RX_Pos (9UL) /*!< USB_M_EP0_RX (Bit 9) */ #define USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk (0x200UL) /*!< USB_M_EP0_RX (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_EP0_TX_Pos (8UL) /*!< USB_M_EP0_TX (Bit 8) */ #define USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk (0x100UL) /*!< USB_M_EP0_TX (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_INTR_Pos (7UL) /*!< USB_M_INTR (Bit 7) */ #define USB_USB_MAMSK_REG_USB_M_INTR_Msk (0x80UL) /*!< USB_M_INTR (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_RX_EV_Pos (6UL) /*!< USB_M_RX_EV (Bit 6) */ #define USB_USB_MAMSK_REG_USB_M_RX_EV_Msk (0x40UL) /*!< USB_M_RX_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_ULD_Pos (5UL) /*!< USB_M_ULD (Bit 5) */ #define USB_USB_MAMSK_REG_USB_M_ULD_Msk (0x20UL) /*!< USB_M_ULD (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_NAK_Pos (4UL) /*!< USB_M_NAK (Bit 4) */ #define USB_USB_MAMSK_REG_USB_M_NAK_Msk (0x10UL) /*!< USB_M_NAK (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_FRAME_Pos (3UL) /*!< USB_M_FRAME (Bit 3) */ #define USB_USB_MAMSK_REG_USB_M_FRAME_Msk (0x8UL) /*!< USB_M_FRAME (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_TX_EV_Pos (2UL) /*!< USB_M_TX_EV (Bit 2) */ #define USB_USB_MAMSK_REG_USB_M_TX_EV_Msk (0x4UL) /*!< USB_M_TX_EV (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_ALT_Pos (1UL) /*!< USB_M_ALT (Bit 1) */ #define USB_USB_MAMSK_REG_USB_M_ALT_Msk (0x2UL) /*!< USB_M_ALT (Bitfield-Mask: 0x01) */ #define USB_USB_MAMSK_REG_USB_M_WARN_Pos (0UL) /*!< USB_M_WARN (Bit 0) */ #define USB_USB_MAMSK_REG_USB_M_WARN_Msk (0x1UL) /*!< USB_M_WARN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_MCTRL_REG ===================================================== */ #define USB_USB_MCTRL_REG_LSMODE_Pos (4UL) /*!< LSMODE (Bit 4) */ #define USB_USB_MCTRL_REG_LSMODE_Msk (0x10UL) /*!< LSMODE (Bitfield-Mask: 0x01) */ #define USB_USB_MCTRL_REG_USB_NAT_Pos (3UL) /*!< USB_NAT (Bit 3) */ #define USB_USB_MCTRL_REG_USB_NAT_Msk (0x8UL) /*!< USB_NAT (Bitfield-Mask: 0x01) */ #define USB_USB_MCTRL_REG_USB_DBG_Pos (1UL) /*!< USB_DBG (Bit 1) */ #define USB_USB_MCTRL_REG_USB_DBG_Msk (0x2UL) /*!< USB_DBG (Bitfield-Mask: 0x01) */ #define USB_USB_MCTRL_REG_USBEN_Pos (0UL) /*!< USBEN (Bit 0) */ #define USB_USB_MCTRL_REG_USBEN_Msk (0x1UL) /*!< USBEN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_NAKEV_REG ===================================================== */ #define USB_USB_NAKEV_REG_USB_OUT31_Pos (4UL) /*!< USB_OUT31 (Bit 4) */ #define USB_USB_NAKEV_REG_USB_OUT31_Msk (0x70UL) /*!< USB_OUT31 (Bitfield-Mask: 0x07) */ #define USB_USB_NAKEV_REG_USB_IN31_Pos (0UL) /*!< USB_IN31 (Bit 0) */ #define USB_USB_NAKEV_REG_USB_IN31_Msk (0x7UL) /*!< USB_IN31 (Bitfield-Mask: 0x07) */ /* ==================================================== USB_NAKMSK_REG ===================================================== */ #define USB_USB_NAKMSK_REG_USB_M_OUT31_Pos (4UL) /*!< USB_M_OUT31 (Bit 4) */ #define USB_USB_NAKMSK_REG_USB_M_OUT31_Msk (0x70UL) /*!< USB_M_OUT31 (Bitfield-Mask: 0x07) */ #define USB_USB_NAKMSK_REG_USB_M_IN31_Pos (0UL) /*!< USB_M_IN31 (Bit 0) */ #define USB_USB_NAKMSK_REG_USB_M_IN31_Msk (0x7UL) /*!< USB_M_IN31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_NFSR_REG ====================================================== */ #define USB_USB_NFSR_REG_USB_NFS_Pos (0UL) /*!< USB_NFS (Bit 0) */ #define USB_USB_NFSR_REG_USB_NFS_Msk (0x3UL) /*!< USB_NFS (Bitfield-Mask: 0x03) */ /* ===================================================== USB_RXC0_REG ====================================================== */ #define USB_USB_RXC0_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_RXC0_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_RXC0_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ #define USB_USB_RXC0_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXC0_REG_USB_IGN_OUT_Pos (1UL) /*!< USB_IGN_OUT (Bit 1) */ #define USB_USB_RXC0_REG_USB_IGN_OUT_Msk (0x2UL) /*!< USB_IGN_OUT (Bitfield-Mask: 0x01) */ #define USB_USB_RXC0_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ #define USB_USB_RXC0_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_RXC1_REG ====================================================== */ #define USB_USB_RXC1_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ #define USB_USB_RXC1_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ #define USB_USB_RXC1_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_RXC1_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_RXC1_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ #define USB_USB_RXC1_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXC1_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ #define USB_USB_RXC1_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_RXC2_REG ====================================================== */ #define USB_USB_RXC2_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ #define USB_USB_RXC2_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ #define USB_USB_RXC2_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_RXC2_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_RXC2_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ #define USB_USB_RXC2_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXC2_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ #define USB_USB_RXC2_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_RXC3_REG ====================================================== */ #define USB_USB_RXC3_REG_USB_RFWL_Pos (5UL) /*!< USB_RFWL (Bit 5) */ #define USB_USB_RXC3_REG_USB_RFWL_Msk (0x60UL) /*!< USB_RFWL (Bitfield-Mask: 0x03) */ #define USB_USB_RXC3_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_RXC3_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_RXC3_REG_USB_IGN_SETUP_Pos (2UL) /*!< USB_IGN_SETUP (Bit 2) */ #define USB_USB_RXC3_REG_USB_IGN_SETUP_Msk (0x4UL) /*!< USB_IGN_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXC3_REG_USB_RX_EN_Pos (0UL) /*!< USB_RX_EN (Bit 0) */ #define USB_USB_RXC3_REG_USB_RX_EN_Msk (0x1UL) /*!< USB_RX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_RXD0_REG ====================================================== */ #define USB_USB_RXD0_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ #define USB_USB_RXD0_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_RXD1_REG ====================================================== */ #define USB_USB_RXD1_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ #define USB_USB_RXD1_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_RXD2_REG ====================================================== */ #define USB_USB_RXD2_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ #define USB_USB_RXD2_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_RXD3_REG ====================================================== */ #define USB_USB_RXD3_REG_USB_RXFD_Pos (0UL) /*!< USB_RXFD (Bit 0) */ #define USB_USB_RXD3_REG_USB_RXFD_Msk (0xffUL) /*!< USB_RXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_RXEV_REG ====================================================== */ #define USB_USB_RXEV_REG_USB_RXOVRRN31_Pos (4UL) /*!< USB_RXOVRRN31 (Bit 4) */ #define USB_USB_RXEV_REG_USB_RXOVRRN31_Msk (0x70UL) /*!< USB_RXOVRRN31 (Bitfield-Mask: 0x07) */ #define USB_USB_RXEV_REG_USB_RXFIFO31_Pos (0UL) /*!< USB_RXFIFO31 (Bit 0) */ #define USB_USB_RXEV_REG_USB_RXFIFO31_Msk (0x7UL) /*!< USB_RXFIFO31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_RXMSK_REG ===================================================== */ #define USB_USB_RXMSK_REG_USB_M_RXOVRRN31_Pos (4UL) /*!< USB_M_RXOVRRN31 (Bit 4) */ #define USB_USB_RXMSK_REG_USB_M_RXOVRRN31_Msk (0x70UL) /*!< USB_M_RXOVRRN31 (Bitfield-Mask: 0x07) */ #define USB_USB_RXMSK_REG_USB_M_RXFIFO31_Pos (0UL) /*!< USB_M_RXFIFO31 (Bit 0) */ #define USB_USB_RXMSK_REG_USB_M_RXFIFO31_Msk (0x7UL) /*!< USB_M_RXFIFO31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_RXS0_REG ====================================================== */ #define USB_USB_RXS0_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ #define USB_USB_RXS0_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXS0_REG_USB_TOGGLE_RX0_Pos (5UL) /*!< USB_TOGGLE_RX0 (Bit 5) */ #define USB_USB_RXS0_REG_USB_TOGGLE_RX0_Msk (0x20UL) /*!< USB_TOGGLE_RX0 (Bitfield-Mask: 0x01) */ #define USB_USB_RXS0_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ #define USB_USB_RXS0_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_RXS0_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ #define USB_USB_RXS0_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_RXS1_REG ====================================================== */ #define USB_USB_RXS1_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ #define USB_USB_RXS1_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ #define USB_USB_RXS1_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ #define USB_USB_RXS1_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ #define USB_USB_RXS1_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ #define USB_USB_RXS1_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXS1_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ #define USB_USB_RXS1_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ #define USB_USB_RXS1_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ #define USB_USB_RXS1_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_RXS1_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ #define USB_USB_RXS1_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_RXS2_REG ====================================================== */ #define USB_USB_RXS2_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ #define USB_USB_RXS2_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ #define USB_USB_RXS2_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ #define USB_USB_RXS2_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ #define USB_USB_RXS2_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ #define USB_USB_RXS2_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXS2_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ #define USB_USB_RXS2_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ #define USB_USB_RXS2_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ #define USB_USB_RXS2_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_RXS2_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ #define USB_USB_RXS2_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ /* ===================================================== USB_RXS3_REG ====================================================== */ #define USB_USB_RXS3_REG_USB_RXCOUNT_Pos (8UL) /*!< USB_RXCOUNT (Bit 8) */ #define USB_USB_RXS3_REG_USB_RXCOUNT_Msk (0x7f00UL) /*!< USB_RXCOUNT (Bitfield-Mask: 0x7f) */ #define USB_USB_RXS3_REG_USB_RX_ERR_Pos (7UL) /*!< USB_RX_ERR (Bit 7) */ #define USB_USB_RXS3_REG_USB_RX_ERR_Msk (0x80UL) /*!< USB_RX_ERR (Bitfield-Mask: 0x01) */ #define USB_USB_RXS3_REG_USB_SETUP_Pos (6UL) /*!< USB_SETUP (Bit 6) */ #define USB_USB_RXS3_REG_USB_SETUP_Msk (0x40UL) /*!< USB_SETUP (Bitfield-Mask: 0x01) */ #define USB_USB_RXS3_REG_USB_TOGGLE_RX_Pos (5UL) /*!< USB_TOGGLE_RX (Bit 5) */ #define USB_USB_RXS3_REG_USB_TOGGLE_RX_Msk (0x20UL) /*!< USB_TOGGLE_RX (Bitfield-Mask: 0x01) */ #define USB_USB_RXS3_REG_USB_RX_LAST_Pos (4UL) /*!< USB_RX_LAST (Bit 4) */ #define USB_USB_RXS3_REG_USB_RX_LAST_Msk (0x10UL) /*!< USB_RX_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_RXS3_REG_USB_RCOUNT_Pos (0UL) /*!< USB_RCOUNT (Bit 0) */ #define USB_USB_RXS3_REG_USB_RCOUNT_Msk (0xfUL) /*!< USB_RCOUNT (Bitfield-Mask: 0x0f) */ /* ====================================================== USB_TCR_REG ====================================================== */ #define USB_USB_TCR_REG_USB_VADJ_Pos (5UL) /*!< USB_VADJ (Bit 5) */ #define USB_USB_TCR_REG_USB_VADJ_Msk (0xe0UL) /*!< USB_VADJ (Bitfield-Mask: 0x07) */ #define USB_USB_TCR_REG_USB_CADJ_Pos (0UL) /*!< USB_CADJ (Bit 0) */ #define USB_USB_TCR_REG_USB_CADJ_Msk (0x1fUL) /*!< USB_CADJ (Bitfield-Mask: 0x1f) */ /* ===================================================== USB_TXC0_REG ====================================================== */ #define USB_USB_TXC0_REG_USB_IGN_IN_Pos (4UL) /*!< USB_IGN_IN (Bit 4) */ #define USB_USB_TXC0_REG_USB_IGN_IN_Msk (0x10UL) /*!< USB_IGN_IN (Bitfield-Mask: 0x01) */ #define USB_USB_TXC0_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_TXC0_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_TXC0_REG_USB_TOGGLE_TX0_Pos (2UL) /*!< USB_TOGGLE_TX0 (Bit 2) */ #define USB_USB_TXC0_REG_USB_TOGGLE_TX0_Msk (0x4UL) /*!< USB_TOGGLE_TX0 (Bitfield-Mask: 0x01) */ #define USB_USB_TXC0_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ #define USB_USB_TXC0_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_TXC1_REG ====================================================== */ #define USB_USB_TXC1_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ #define USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ #define USB_USB_TXC1_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ #define USB_USB_TXC1_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ #define USB_USB_TXC1_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ #define USB_USB_TXC1_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ #define USB_USB_TXC1_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_TXC1_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_TXC1_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ #define USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ #define USB_USB_TXC1_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ #define USB_USB_TXC1_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_TXC1_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ #define USB_USB_TXC1_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_TXC2_REG ====================================================== */ #define USB_USB_TXC2_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ #define USB_USB_TXC2_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ #define USB_USB_TXC2_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ #define USB_USB_TXC2_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ #define USB_USB_TXC2_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ #define USB_USB_TXC2_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ #define USB_USB_TXC2_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_TXC2_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_TXC2_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ #define USB_USB_TXC2_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ #define USB_USB_TXC2_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ #define USB_USB_TXC2_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_TXC2_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ #define USB_USB_TXC2_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_TXC3_REG ====================================================== */ #define USB_USB_TXC3_REG_USB_IGN_ISOMSK_Pos (7UL) /*!< USB_IGN_ISOMSK (Bit 7) */ #define USB_USB_TXC3_REG_USB_IGN_ISOMSK_Msk (0x80UL) /*!< USB_IGN_ISOMSK (Bitfield-Mask: 0x01) */ #define USB_USB_TXC3_REG_USB_TFWL_Pos (5UL) /*!< USB_TFWL (Bit 5) */ #define USB_USB_TXC3_REG_USB_TFWL_Msk (0x60UL) /*!< USB_TFWL (Bitfield-Mask: 0x03) */ #define USB_USB_TXC3_REG_USB_RFF_Pos (4UL) /*!< USB_RFF (Bit 4) */ #define USB_USB_TXC3_REG_USB_RFF_Msk (0x10UL) /*!< USB_RFF (Bitfield-Mask: 0x01) */ #define USB_USB_TXC3_REG_USB_FLUSH_Pos (3UL) /*!< USB_FLUSH (Bit 3) */ #define USB_USB_TXC3_REG_USB_FLUSH_Msk (0x8UL) /*!< USB_FLUSH (Bitfield-Mask: 0x01) */ #define USB_USB_TXC3_REG_USB_TOGGLE_TX_Pos (2UL) /*!< USB_TOGGLE_TX (Bit 2) */ #define USB_USB_TXC3_REG_USB_TOGGLE_TX_Msk (0x4UL) /*!< USB_TOGGLE_TX (Bitfield-Mask: 0x01) */ #define USB_USB_TXC3_REG_USB_LAST_Pos (1UL) /*!< USB_LAST (Bit 1) */ #define USB_USB_TXC3_REG_USB_LAST_Msk (0x2UL) /*!< USB_LAST (Bitfield-Mask: 0x01) */ #define USB_USB_TXC3_REG_USB_TX_EN_Pos (0UL) /*!< USB_TX_EN (Bit 0) */ #define USB_USB_TXC3_REG_USB_TX_EN_Msk (0x1UL) /*!< USB_TX_EN (Bitfield-Mask: 0x01) */ /* ===================================================== USB_TXD0_REG ====================================================== */ #define USB_USB_TXD0_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ #define USB_USB_TXD0_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_TXD1_REG ====================================================== */ #define USB_USB_TXD1_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ #define USB_USB_TXD1_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_TXD2_REG ====================================================== */ #define USB_USB_TXD2_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ #define USB_USB_TXD2_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_TXD3_REG ====================================================== */ #define USB_USB_TXD3_REG_USB_TXFD_Pos (0UL) /*!< USB_TXFD (Bit 0) */ #define USB_USB_TXD3_REG_USB_TXFD_Msk (0xffUL) /*!< USB_TXFD (Bitfield-Mask: 0xff) */ /* ===================================================== USB_TXEV_REG ====================================================== */ #define USB_USB_TXEV_REG_USB_TXUDRRN31_Pos (4UL) /*!< USB_TXUDRRN31 (Bit 4) */ #define USB_USB_TXEV_REG_USB_TXUDRRN31_Msk (0x70UL) /*!< USB_TXUDRRN31 (Bitfield-Mask: 0x07) */ #define USB_USB_TXEV_REG_USB_TXFIFO31_Pos (0UL) /*!< USB_TXFIFO31 (Bit 0) */ #define USB_USB_TXEV_REG_USB_TXFIFO31_Msk (0x7UL) /*!< USB_TXFIFO31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_TXMSK_REG ===================================================== */ #define USB_USB_TXMSK_REG_USB_M_TXUDRRN31_Pos (4UL) /*!< USB_M_TXUDRRN31 (Bit 4) */ #define USB_USB_TXMSK_REG_USB_M_TXUDRRN31_Msk (0x70UL) /*!< USB_M_TXUDRRN31 (Bitfield-Mask: 0x07) */ #define USB_USB_TXMSK_REG_USB_M_TXFIFO31_Pos (0UL) /*!< USB_M_TXFIFO31 (Bit 0) */ #define USB_USB_TXMSK_REG_USB_M_TXFIFO31_Msk (0x7UL) /*!< USB_M_TXFIFO31 (Bitfield-Mask: 0x07) */ /* ===================================================== USB_TXS0_REG ====================================================== */ #define USB_USB_TXS0_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ #define USB_USB_TXS0_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ #define USB_USB_TXS0_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ #define USB_USB_TXS0_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ #define USB_USB_TXS0_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ #define USB_USB_TXS0_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ /* ===================================================== USB_TXS1_REG ====================================================== */ #define USB_USB_TXS1_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ #define USB_USB_TXS1_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ #define USB_USB_TXS1_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ #define USB_USB_TXS1_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ #define USB_USB_TXS1_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ #define USB_USB_TXS1_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ #define USB_USB_TXS1_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ #define USB_USB_TXS1_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ /* ===================================================== USB_TXS2_REG ====================================================== */ #define USB_USB_TXS2_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ #define USB_USB_TXS2_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ #define USB_USB_TXS2_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ #define USB_USB_TXS2_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ #define USB_USB_TXS2_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ #define USB_USB_TXS2_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ #define USB_USB_TXS2_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ #define USB_USB_TXS2_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ /* ===================================================== USB_TXS3_REG ====================================================== */ #define USB_USB_TXS3_REG_USB_TX_URUN_Pos (7UL) /*!< USB_TX_URUN (Bit 7) */ #define USB_USB_TXS3_REG_USB_TX_URUN_Msk (0x80UL) /*!< USB_TX_URUN (Bitfield-Mask: 0x01) */ #define USB_USB_TXS3_REG_USB_ACK_STAT_Pos (6UL) /*!< USB_ACK_STAT (Bit 6) */ #define USB_USB_TXS3_REG_USB_ACK_STAT_Msk (0x40UL) /*!< USB_ACK_STAT (Bitfield-Mask: 0x01) */ #define USB_USB_TXS3_REG_USB_TX_DONE_Pos (5UL) /*!< USB_TX_DONE (Bit 5) */ #define USB_USB_TXS3_REG_USB_TX_DONE_Msk (0x20UL) /*!< USB_TX_DONE (Bitfield-Mask: 0x01) */ #define USB_USB_TXS3_REG_USB_TCOUNT_Pos (0UL) /*!< USB_TCOUNT (Bit 0) */ #define USB_USB_TXS3_REG_USB_TCOUNT_Msk (0x1fUL) /*!< USB_TCOUNT (Bitfield-Mask: 0x1f) */ /* ====================================================== USB_UTR_REG ====================================================== */ #define USB_USB_UTR_REG_USB_DIAG_Pos (7UL) /*!< USB_DIAG (Bit 7) */ #define USB_USB_UTR_REG_USB_DIAG_Msk (0x80UL) /*!< USB_DIAG (Bitfield-Mask: 0x01) */ #define USB_USB_UTR_REG_USB_NCRC_Pos (6UL) /*!< USB_NCRC (Bit 6) */ #define USB_USB_UTR_REG_USB_NCRC_Msk (0x40UL) /*!< USB_NCRC (Bitfield-Mask: 0x01) */ #define USB_USB_UTR_REG_USB_SF_Pos (5UL) /*!< USB_SF (Bit 5) */ #define USB_USB_UTR_REG_USB_SF_Msk (0x20UL) /*!< USB_SF (Bitfield-Mask: 0x01) */ #define USB_USB_UTR_REG_USB_UTR_RES_Pos (0UL) /*!< USB_UTR_RES (Bit 0) */ #define USB_USB_UTR_REG_USB_UTR_RES_Msk (0x1fUL) /*!< USB_UTR_RES (Bitfield-Mask: 0x1f) */ /* ==================================================== USB_UX20CDR_REG ==================================================== */ #define USB_USB_UX20CDR_REG_RPU_TEST7_Pos (7UL) /*!< RPU_TEST7 (Bit 7) */ #define USB_USB_UX20CDR_REG_RPU_TEST7_Msk (0x80UL) /*!< RPU_TEST7 (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW2_Pos (6UL) /*!< RPU_TEST_SW2 (Bit 6) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW2_Msk (0x40UL) /*!< RPU_TEST_SW2 (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW1_Pos (5UL) /*!< RPU_TEST_SW1 (Bit 5) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW1_Msk (0x20UL) /*!< RPU_TEST_SW1 (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_TEST_EN_Pos (4UL) /*!< RPU_TEST_EN (Bit 4) */ #define USB_USB_UX20CDR_REG_RPU_TEST_EN_Msk (0x10UL) /*!< RPU_TEST_EN (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW1DM_Pos (2UL) /*!< RPU_TEST_SW1DM (Bit 2) */ #define USB_USB_UX20CDR_REG_RPU_TEST_SW1DM_Msk (0x4UL) /*!< RPU_TEST_SW1DM (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_RCDELAY_Pos (1UL) /*!< RPU_RCDELAY (Bit 1) */ #define USB_USB_UX20CDR_REG_RPU_RCDELAY_Msk (0x2UL) /*!< RPU_RCDELAY (Bitfield-Mask: 0x01) */ #define USB_USB_UX20CDR_REG_RPU_SSPROTEN_Pos (0UL) /*!< RPU_SSPROTEN (Bit 0) */ #define USB_USB_UX20CDR_REG_RPU_SSPROTEN_Msk (0x1UL) /*!< RPU_SSPROTEN (Bitfield-Mask: 0x01) */ /* ==================================================== USB_XCVDIAG_REG ==================================================== */ #define USB_USB_XCVDIAG_REG_USB_VPIN_Pos (7UL) /*!< USB_VPIN (Bit 7) */ #define USB_USB_XCVDIAG_REG_USB_VPIN_Msk (0x80UL) /*!< USB_VPIN (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_VMIN_Pos (6UL) /*!< USB_VMIN (Bit 6) */ #define USB_USB_XCVDIAG_REG_USB_VMIN_Msk (0x40UL) /*!< USB_VMIN (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_RCV_Pos (5UL) /*!< USB_RCV (Bit 5) */ #define USB_USB_XCVDIAG_REG_USB_RCV_Msk (0x20UL) /*!< USB_RCV (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXEN_Pos (3UL) /*!< USB_XCV_TXEN (Bit 3) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXEN_Msk (0x8UL) /*!< USB_XCV_TXEN (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXn_Pos (2UL) /*!< USB_XCV_TXn (Bit 2) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXn_Msk (0x4UL) /*!< USB_XCV_TXn (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXp_Pos (1UL) /*!< USB_XCV_TXp (Bit 1) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TXp_Msk (0x2UL) /*!< USB_XCV_TXp (Bitfield-Mask: 0x01) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TEST_Pos (0UL) /*!< USB_XCV_TEST (Bit 0) */ #define USB_USB_XCVDIAG_REG_USB_XCV_TEST_Msk (0x1UL) /*!< USB_XCV_TEST (Bitfield-Mask: 0x01) */ /* =========================================================================================================================== */ /* ================ WAKEUP ================ */ /* =========================================================================================================================== */ /* =================================================== WKUP_CLEAR_P0_REG =================================================== */ #define WAKEUP_WKUP_CLEAR_P0_REG_WKUP_CLEAR_P0_Pos (0UL) /*!< WKUP_CLEAR_P0 (Bit 0) */ #define WAKEUP_WKUP_CLEAR_P0_REG_WKUP_CLEAR_P0_Msk (0xffffffffUL) /*!< WKUP_CLEAR_P0 (Bitfield-Mask: 0xffffffff) */ /* =================================================== WKUP_CLEAR_P1_REG =================================================== */ #define WAKEUP_WKUP_CLEAR_P1_REG_WKUP_CLEAR_P1_Pos (0UL) /*!< WKUP_CLEAR_P1 (Bit 0) */ #define WAKEUP_WKUP_CLEAR_P1_REG_WKUP_CLEAR_P1_Msk (0x7fffffUL) /*!< WKUP_CLEAR_P1 (Bitfield-Mask: 0x7fffff) */ /* ===================================================== WKUP_CTRL_REG ===================================================== */ #define WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Pos (7UL) /*!< WKUP_ENABLE_IRQ (Bit 7) */ #define WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Msk (0x80UL) /*!< WKUP_ENABLE_IRQ (Bitfield-Mask: 0x01) */ #define WAKEUP_WKUP_CTRL_REG_WKUP_SFT_KEYHIT_Pos (6UL) /*!< WKUP_SFT_KEYHIT (Bit 6) */ #define WAKEUP_WKUP_CTRL_REG_WKUP_SFT_KEYHIT_Msk (0x40UL) /*!< WKUP_SFT_KEYHIT (Bitfield-Mask: 0x01) */ #define WAKEUP_WKUP_CTRL_REG_WKUP_DEB_VALUE_Pos (0UL) /*!< WKUP_DEB_VALUE (Bit 0) */ #define WAKEUP_WKUP_CTRL_REG_WKUP_DEB_VALUE_Msk (0x3fUL) /*!< WKUP_DEB_VALUE (Bitfield-Mask: 0x3f) */ /* ==================================================== WKUP_POL_P0_REG ==================================================== */ #define WAKEUP_WKUP_POL_P0_REG_WKUP_POL_P0_Pos (0UL) /*!< WKUP_POL_P0 (Bit 0) */ #define WAKEUP_WKUP_POL_P0_REG_WKUP_POL_P0_Msk (0xffffffffUL) /*!< WKUP_POL_P0 (Bitfield-Mask: 0xffffffff) */ /* ==================================================== WKUP_POL_P1_REG ==================================================== */ #define WAKEUP_WKUP_POL_P1_REG_WKUP_POL_P1_Pos (0UL) /*!< WKUP_POL_P1 (Bit 0) */ #define WAKEUP_WKUP_POL_P1_REG_WKUP_POL_P1_Msk (0x7fffffUL) /*!< WKUP_POL_P1 (Bitfield-Mask: 0x7fffff) */ /* ================================================== WKUP_RESET_IRQ_REG =================================================== */ #define WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Pos (0UL) /*!< WKUP_IRQ_RST (Bit 0) */ #define WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Msk (0xffffUL) /*!< WKUP_IRQ_RST (Bitfield-Mask: 0xffff) */ /* ================================================== WKUP_SELECT_P0_REG =================================================== */ #define WAKEUP_WKUP_SELECT_P0_REG_WKUP_SELECT_P0_Pos (0UL) /*!< WKUP_SELECT_P0 (Bit 0) */ #define WAKEUP_WKUP_SELECT_P0_REG_WKUP_SELECT_P0_Msk (0xffffffffUL) /*!< WKUP_SELECT_P0 (Bitfield-Mask: 0xffffffff) */ /* ================================================== WKUP_SELECT_P1_REG =================================================== */ #define WAKEUP_WKUP_SELECT_P1_REG_WKUP_SELECT_P1_Pos (0UL) /*!< WKUP_SELECT_P1 (Bit 0) */ #define WAKEUP_WKUP_SELECT_P1_REG_WKUP_SELECT_P1_Msk (0x7fffffUL) /*!< WKUP_SELECT_P1 (Bitfield-Mask: 0x7fffff) */ /* ================================================= WKUP_SEL_GPIO_P0_REG ================================================== */ #define WAKEUP_WKUP_SEL_GPIO_P0_REG_WKUP_SEL_GPIO_P0_Pos (0UL) /*!< WKUP_SEL_GPIO_P0 (Bit 0) */ #define WAKEUP_WKUP_SEL_GPIO_P0_REG_WKUP_SEL_GPIO_P0_Msk (0xffffffffUL) /*!< WKUP_SEL_GPIO_P0 (Bitfield-Mask: 0xffffffff) */ /* ================================================= WKUP_SEL_GPIO_P1_REG ================================================== */ #define WAKEUP_WKUP_SEL_GPIO_P1_REG_WKUP_SEL_GPIO_P1_Pos (0UL) /*!< WKUP_SEL_GPIO_P1 (Bit 0) */ #define WAKEUP_WKUP_SEL_GPIO_P1_REG_WKUP_SEL_GPIO_P1_Msk (0x7fffffUL) /*!< WKUP_SEL_GPIO_P1 (Bitfield-Mask: 0x7fffff) */ /* ================================================== WKUP_STATUS_P0_REG =================================================== */ #define WAKEUP_WKUP_STATUS_P0_REG_WKUP_STAT_P0_Pos (0UL) /*!< WKUP_STAT_P0 (Bit 0) */ #define WAKEUP_WKUP_STATUS_P0_REG_WKUP_STAT_P0_Msk (0xffffffffUL) /*!< WKUP_STAT_P0 (Bitfield-Mask: 0xffffffff) */ /* ================================================== WKUP_STATUS_P1_REG =================================================== */ #define WAKEUP_WKUP_STATUS_P1_REG_WKUP_STAT_P1_Pos (0UL) /*!< WKUP_STAT_P1 (Bit 0) */ #define WAKEUP_WKUP_STATUS_P1_REG_WKUP_STAT_P1_Msk (0x7fffffUL) /*!< WKUP_STAT_P1 (Bitfield-Mask: 0x7fffff) */ /** @} */ /* End of group PosMask_peripherals */ #ifdef __cplusplus } #endif #endif /* DA1469X_H */ /** @} */ /* End of group DA1469x */ /** @} */ /* End of group PLA_BSP_REGISTERS */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_compiler.h ================================================ /**************************************************************************//** * @file cmsis_compiler.h * @brief CMSIS compiler generic header file * @version V5.1.0 * @date 09. October 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __CMSIS_COMPILER_H #define __CMSIS_COMPILER_H #include /* * Arm Compiler 4/5 */ #if defined ( __CC_ARM ) #include "cmsis_armcc.h" /* * Arm Compiler 6.6 LTM (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) #include "cmsis_armclang_ltm.h" /* * Arm Compiler above 6.10.1 (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) #include "cmsis_armclang.h" /* * GNU Compiler */ #elif defined ( __GNUC__ ) #include "cmsis_gcc.h" /* * IAR Compiler */ #elif defined ( __ICCARM__ ) #include /* * TI Arm Compiler */ #elif defined ( __TI_ARM__ ) #include #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed)) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed)) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed)) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif /* * TASKING Compiler */ #elif defined ( __TASKING__ ) /* * The CMSIS functions have been implemented as intrinsics in the compiler. * Please use "carm -?i" to get an up to date list of all intrinsics, * Including the CMSIS ones. */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __packed__ #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __packed__ #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __packed__ #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __packed__ T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __align(x) #endif #ifndef __RESTRICT #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. #define __RESTRICT #endif /* * COSMIC Compiler */ #elif defined ( __CSMC__ ) #include #ifndef __ASM #define __ASM _asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN // NO RETURN is automatically detected hence no warning here #define __NO_RETURN #endif #ifndef __USED #warning No compiler specific solution for __USED. __USED is ignored. #define __USED #endif #ifndef __WEAK #define __WEAK __weak #endif #ifndef __PACKED #define __PACKED @packed #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT @packed struct #endif #ifndef __PACKED_UNION #define __PACKED_UNION @packed union #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ @packed struct T_UINT32 { uint32_t v; }; #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. #define __ALIGNED(x) #endif #ifndef __RESTRICT #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. #define __RESTRICT #endif #else #error Unknown compiler. #endif #endif /* __CMSIS_COMPILER_H */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_gcc.h ================================================ /**************************************************************************//** * @file cmsis_gcc.h * @brief CMSIS compiler GCC header file * @version V5.1.0 * @date 20. December 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (c) 2019 Modified by Dialog Semiconductor */ #ifndef __CMSIS_GCC_H #define __CMSIS_GCC_H /* ignore some GCC warnings */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" /* Fallback for __has_builtin */ #ifndef __has_builtin #define __has_builtin(x) (0) #endif /* CMSIS compiler specific defines */ #ifndef __ASM #define __ASM __asm #endif #ifndef __INLINE #define __INLINE inline #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline #endif #ifndef __STATIC_FORCEINLINE #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline #endif #ifndef __NO_RETURN #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED #define __USED __attribute__((used)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED #define __PACKED __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_STRUCT #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) #endif #ifndef __PACKED_UNION #define __PACKED_UNION union __attribute__((packed, aligned(1))) #endif #ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif #ifndef __UNALIGNED_UINT16_WRITE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT16_READ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif #ifndef __UNALIGNED_UINT32_WRITE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif #ifndef __UNALIGNED_UINT32_READ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; #pragma GCC diagnostic pop #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __attribute__((aligned(x))) #endif #ifndef __RESTRICT #define __RESTRICT __restrict #endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions @{ */ /** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); } /** \brief Get Control Register \details Returns the content of the Control Register. \return Control Register value */ __STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; __ASM volatile ("MRS %0, control" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Control Register (non-secure) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Control Register (non-secure) \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } #endif /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); return(result); } /** \brief Get APSR Register \details Returns the content of the APSR Register. \return APSR Register value */ __STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; __ASM volatile ("MRS %0, apsr" : "=r" (result) ); return(result); } /** \brief Get xPSR Register \details Returns the content of the xPSR Register. \return xPSR Register value */ __STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); return(result); } /** \brief Get Process Stack Pointer \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __get_PSP(void) { uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer (non-secure) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Process Stack Pointer \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } #endif /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __get_MSP(void) { uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer (non-secure) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer (non-secure) \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Stack Pointer (non-secure) \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. \return SP Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) { uint32_t result; __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); return(result); } /** \brief Set Stack Pointer (non-secure) \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. \param [in] topOfStack Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) { __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); } #endif /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Priority Mask (non-secure) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); return(result); } #endif /** \brief Set Priority Mask \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Priority Mask (non-secure) \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } #endif #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f" : : : "memory"); } /** \brief Disable FIQ \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f" : : : "memory"); } /** \brief Get Base Priority \details Returns the current value of the Base Priority register. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; __ASM volatile ("MRS %0, basepri" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Base Priority (non-secure) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Base Priority (non-secure) \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } #endif /** \brief Set Base Priority with condition \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ __STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } /** \brief Get Fault Mask \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); return(result); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Fault Mask (non-secure) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); return(result); } #endif /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Fault Mask (non-secure) \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } #endif #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Get Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Process Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure PSPLIM is RAZ/WI (void)ProcStackPtrLimit; #else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); #endif } #endif /** \brief Get Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always in non-secure mode. \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); return result; #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence zero is returned always. \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI return 0U; #else uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); return result; #endif } #endif /** \brief Set Main Stack Pointer Limit Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored in non-secure mode. \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ __STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); #endif } #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure Stack Pointer Limit register hence the write is silently ignored. \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) // without main extensions, the non-secure MSPLIM is RAZ/WI (void)MainStackPtrLimit; #else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); #endif } #endif #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ __STATIC_FORCEINLINE uint32_t __get_FPSCR(void) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #if __has_builtin(__builtin_arm_get_fpscr) // Re-enable using built-in when GCC has been fixed // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ return __builtin_arm_get_fpscr(); #else uint32_t result; __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); return(result); #endif #else return(0U); #endif } /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) #if __has_builtin(__builtin_arm_set_fpscr) // Re-enable using built-in when GCC has been fixed // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ __builtin_arm_set_fpscr(fpscr); #else __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); #endif #else (void)fpscr; #endif } /*@} end of CMSIS_Core_RegAccFunctions */ /* ########################## Core Instruction Access ######################### */ /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface Access to dedicated instructions @{ */ /* Define macros for porting to both thumb1 and thumb2. * For thumb1, use low register (r0-r7), specified by constraint "l" * Otherwise, use general registers, specified by constraint "r" */ #if defined (__thumb__) && !defined (__thumb2__) #define __CMSIS_GCC_OUT_REG(r) "=l" (r) #define __CMSIS_GCC_RW_REG(r) "+l" (r) #define __CMSIS_GCC_USE_REG(r) "l" (r) #else #define __CMSIS_GCC_OUT_REG(r) "=r" (r) #define __CMSIS_GCC_RW_REG(r) "+r" (r) #define __CMSIS_GCC_USE_REG(r) "r" (r) #endif /** \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ #define __NOP() __ASM volatile ("nop") /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ #define __WFI() __ASM volatile ("wfi") /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ #define __WFE() __ASM volatile ("wfe") /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ #define __SEV() __ASM volatile ("sev") /** \brief Instruction Synchronization Barrier \details Instruction Synchronization Barrier flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ __STATIC_FORCEINLINE void __ISB(void) { __ASM volatile ("isb 0xF":::"memory"); } /** \brief Data Synchronization Barrier \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ __STATIC_FORCEINLINE void __DSB(void) { __ASM volatile ("dsb 0xF":::"memory"); } /** \brief Data Memory Barrier \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ __STATIC_FORCEINLINE void __DMB(void) { __ASM volatile ("dmb 0xF":::"memory"); } /** \brief Reverse byte order (32 bit) \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __REV(uint32_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) return __builtin_bswap32(value); #else uint32_t result; __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; #endif } /** \brief Reverse byte order (16 bit) \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) { uint32_t result; __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; } /** \brief Reverse byte order (16 bit) \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE int16_t __REVSH(int16_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) return (int16_t)__builtin_bswap16(value); #else int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return result; #endif } /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. \param [in] op1 Value to rotate \param [in] op2 Number of Bits to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { op2 %= 32U; if (op2 == 0U) { return op1; } return (op1 >> op2) | (op1 << (32U - op2)); } /** \brief Breakpoint \details Causes the processor to enter Debug state. Debug tools can use this to investigate system state when the instruction at a particular address is reached. \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ #define __BKPT(value) __ASM volatile ("bkpt "#value) /** \brief Reverse bit order of value \details Reverses the bit order of the given value. \param [in] value Value to reverse \return Reversed value */ __STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) { uint32_t result; #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); #else uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; s--; } result <<= s; /* shift when v's highest bits are zero */ #endif return result; } /** \brief Count leading zeros \details Counts the number of leading zeros of a data value. \param [in] value Value to count the leading zeros \return number of leading zeros in value */ __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) { /* Even though __builtin_clz produces a CLZ instruction on ARM, formally __builtin_clz(0) is undefined behaviour, so handle this case specially. This guarantees ARM-compatible results if happening to compile on a non-ARM target, and ensures the compiler doesn't decide to activate any optimisations using the logic "value was passed to __builtin_clz, so it is non-zero". ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a single CLZ instruction. */ if (value == 0U) { return 32U; } return __builtin_clz(value); } #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); #endif return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDR Exclusive (16 bit) \details Executes a exclusive LDR instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); #endif return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDR Exclusive (32 bit) \details Executes a exclusive LDR instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) { uint32_t result; __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); return(result); } /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) { uint32_t result; __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); return(result); } /** \brief STR Exclusive (16 bit) \details Executes a exclusive STR instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) { uint32_t result; __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); return(result); } /** \brief STR Exclusive (32 bit) \details Executes a exclusive STR instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) { uint32_t result; __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); return(result); } /** \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ __STATIC_FORCEINLINE void __CLREX(void) { __ASM volatile ("clrex" ::: "memory"); } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Signed Saturate \details Saturates a signed value. \param [in] ARG1 Value to be saturated \param [in] ARG2 Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT(ARG1,ARG2) \ __extension__ \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] ARG1 Value to be saturated \param [in] ARG2 Bit position to saturate to (0..31) \return Saturated value */ #define __USAT(ARG1,ARG2) \ __extension__ \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) /** \brief Rotate Right with Extend (32 bit) \details Moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. \param [in] value Value to rotate \return Rotated value */ __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); } /** \brief LDRT Unprivileged (8 bit) \details Executes a Unprivileged LDRT instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint8_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (16 bit) \details Executes a Unprivileged LDRT instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint16_t) result); /* Add explicit type cast here */ } /** \brief LDRT Unprivileged (32 bit) \details Executes a Unprivileged LDRT instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief STRT Unprivileged (8 bit) \details Executes a Unprivileged STRT instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (16 bit) \details Executes a Unprivileged STRT instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief STRT Unprivileged (32 bit) \details Executes a Unprivileged STRT instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ /** \brief Signed Saturate \details Saturates a signed value. \param [in] val Value to be saturated \param [in] sat Bit position to saturate to (1..32) \return Saturated value */ __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) { if ((sat >= 1U) && (sat <= 32U)) { const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); const int32_t min = -1 - max ; if (val > max) { return max; } else if (val < min) { return min; } } return val; } /** \brief Unsigned Saturate \details Saturates an unsigned value. \param [in] val Value to be saturated \param [in] sat Bit position to saturate to (0..31) \return Saturated value */ __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) { if (sat <= 31U) { const uint32_t max = ((1U << sat) - 1U); if (val > (int32_t)max) { return max; } else if (val < 0) { return 0U; } } return (uint32_t)val; } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief Load-Acquire (8 bit) \details Executes a LDAB instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire (16 bit) \details Executes a LDAH instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire (32 bit) \details Executes a LDA instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release (8 bit) \details Executes a STLB instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (16 bit) \details Executes a STLH instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Store-Release (32 bit) \details Executes a STL instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location */ __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } /** \brief Load-Acquire Exclusive (8 bit) \details Executes a LDAB exclusive instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ __STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint8_t) result); } /** \brief Load-Acquire Exclusive (16 bit) \details Executes a LDAH exclusive instruction for 16 bit values. \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ __STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); return ((uint16_t) result); } /** \brief Load-Acquire Exclusive (32 bit) \details Executes a LDA exclusive instruction for 32 bit values. \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ __STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } /** \brief Store-Release Exclusive (8 bit) \details Executes a STLB exclusive instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) { uint32_t result; __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } /** \brief Store-Release Exclusive (16 bit) \details Executes a STLH exclusive instruction for 16 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) { uint32_t result; __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } /** \brief Store-Release Exclusive (32 bit) \details Executes a STL exclusive instruction for 32 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ __STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) { uint32_t result; __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); return(result); } #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics Access to dedicated SIMD instructions @{ */ #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) __STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } #define __SSAT16(ARG1,ARG2) \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) #define __USAT16(ARG1,ARG2) \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) __STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); return(result); } __STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); } __STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; uint64_t w64; } llr; llr.w64 = acc; #ifndef __ARMEB__ /* Little endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); #else /* Big endian */ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); #endif return(llr.w64); } __STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); return(result); } #if 0 #define __PKHBT(ARG1,ARG2,ARG3) \ ({ \ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ __RES; \ }) #define __PKHTB(ARG1,ARG2,ARG3) \ ({ \ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ if (ARG3 == 0) \ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ else \ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ __RES; \ }) #endif #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); return(result); } #endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ #pragma GCC diagnostic pop #endif /* __CMSIS_GCC_H */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/cmsis_version.h ================================================ /**************************************************************************//** * @file cmsis_version.h * @brief CMSIS Core(M) Version definitions * @version V5.0.2 * @date 19. April 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CMSIS_VERSION_H #define __CMSIS_VERSION_H /* CMSIS Version definitions */ #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ #define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ #endif ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm0.h ================================================ /**************************************************************************//** * @file core_cm0.h * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File * @version V5.0.6 * @date 13. March 2019 ******************************************************************************/ /* * Copyright (c) 2009-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (c) 2019 Modified by Dialog Semiconductor */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM0_H_GENERIC #define __CORE_CM0_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M0 @{ */ #include "cmsis_version.h" /* CMSIS CM0 definitions */ #define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all */ #define __FPU_USED 0U #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM0_H_DEPENDANT #define __CORE_CM0_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM0_REV #define __CM0_REV 0x0000U #warning "__CM0_REV not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 2U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M0 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t _reserved0:1; /*!< bit: 0 Reserved */ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[31U]; __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RESERVED1[31U]; __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[31U]; __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[31U]; uint32_t RESERVED4[64U]; __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ } NVIC_Type; /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ uint32_t RESERVED0; __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ uint32_t RESERVED1; __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. Therefore they are not covered by the Cortex-M0 header file. @{ */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ /* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } else { SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } else { return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref __NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with the function \ref __NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. Address 0 must be mapped to SRAM. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t vectors = 0x0U; (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t vectors = 0x0U; return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } /*@} end of CMSIS_Core_FpuFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /*@} end of CMSIS_Core_SysTickFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM0_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/core_cm33.h ================================================ /**************************************************************************//** * @file core_cm33.h * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File * @version V5.1.0 * @date 12. November 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (c) 2019 Modified by Dialog Semiconductor */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM33_H_GENERIC #define __CORE_CM33_H_GENERIC #include #ifdef __cplusplus extern "C" { #endif /** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions CMSIS violates the following MISRA-C:2004 rules: \li Required Rule 8.5, object/function definition in header file.
Function definitions in header files are used to allow 'inlining'. \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
Unions are used for effective representation of core registers. \li Advisory Rule 19.7, Function-like macro defined.
Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ /** \ingroup Cortex_M33 @{ */ #include "cmsis_version.h" /* CMSIS CM33 definitions */ #define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ #define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (33U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined (__TARGET_FPU_VFP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined (__ARM_FP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __ICCARM__ ) #if defined (__ARMVFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) #define __DSP_USED 1U #else #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" #define __DSP_USED 0U #endif #else #define __DSP_USED 0U #endif #elif defined ( __TI_ARM__ ) #if defined (__TI_VFP_SUPPORT__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __TASKING__ ) #if defined (__FPU_VFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #define __FPU_USED 0U #endif #else #define __FPU_USED 0U #endif #endif #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ #ifdef __cplusplus } #endif #endif /* __CORE_CM33_H_GENERIC */ #ifndef __CMSIS_GENERIC #ifndef __CORE_CM33_H_DEPENDANT #define __CORE_CM33_H_DEPENDANT #ifdef __cplusplus extern "C" { #endif /* check device defines and use defaults */ #if defined __CHECK_DEVICE_DEFINES #ifndef __CM33_REV #define __CM33_REV 0x0000U #warning "__CM33_REV not defined in device header file; using default!" #endif #ifndef __FPU_PRESENT #define __FPU_PRESENT 0U #warning "__FPU_PRESENT not defined in device header file; using default!" #endif #ifndef __MPU_PRESENT #define __MPU_PRESENT 0U #warning "__MPU_PRESENT not defined in device header file; using default!" #endif #ifndef __SAUREGION_PRESENT #define __SAUREGION_PRESENT 0U #warning "__SAUREGION_PRESENT not defined in device header file; using default!" #endif #ifndef __DSP_PRESENT #define __DSP_PRESENT 0U #warning "__DSP_PRESENT not defined in device header file; using default!" #endif #ifndef __NVIC_PRIO_BITS #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif #ifndef __Vendor_SysTickConfig #define __Vendor_SysTickConfig 0U #warning "__Vendor_SysTickConfig not defined in device header file; using default!" #endif #endif /* IO definitions (access restrictions to peripheral registers) */ /** \defgroup CMSIS_glob_defs CMSIS Global Defines IO Type Qualifiers are used \li to specify the access to peripheral variables. \li for automatic generation of peripheral register debug information. */ #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ #define __IM volatile const /*! Defines 'read only' structure member permissions */ #define __OM volatile /*! Defines 'write only' structure member permissions */ #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M33 */ /******************************************************************************* * Register Abstraction Core Register contain: - Core Register - Core NVIC Register - Core SCB Register - Core SysTick Register - Core Debug Register - Core MPU Register - Core SAU Register - Core FPU Register ******************************************************************************/ /** \defgroup CMSIS_core_register Defines and Type Definitions \brief Type definitions and defines for Cortex-M processor based devices. */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CORE Status and Control Registers \brief Core Register type definitions. @{ */ /** \brief Union type to access the Application Program Status Register (APSR). */ typedef union { struct { uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } APSR_Type; /* APSR Register Definitions */ #define APSR_N_Pos 31U /*!< APSR: N Position */ #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ #define APSR_Z_Pos 30U /*!< APSR: Z Position */ #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ #define APSR_C_Pos 29U /*!< APSR: C Position */ #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ #define APSR_V_Pos 28U /*!< APSR: V Position */ #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ #define APSR_Q_Pos 27U /*!< APSR: Q Position */ #define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ #define APSR_GE_Pos 16U /*!< APSR: GE Position */ #define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ /** \brief Union type to access the Interrupt Program Status Register (IPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } IPSR_Type; /* IPSR Register Definitions */ #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ typedef union { struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ uint32_t N:1; /*!< bit: 31 Negative condition code flag */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } xPSR_Type; /* xPSR Register Definitions */ #define xPSR_N_Pos 31U /*!< xPSR: N Position */ #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ #define xPSR_C_Pos 29U /*!< xPSR: C Position */ #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ #define xPSR_V_Pos 28U /*!< xPSR: V Position */ #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ #define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ #define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ /** \brief Union type to access the Control Registers (CONTROL). */ typedef union { struct { uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ } b; /*!< Structure used for bit access */ uint32_t w; /*!< Type used for word access */ } CONTROL_Type; /* CONTROL Register Definitions */ #define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ #define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ #define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ #define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ #define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** \ingroup CMSIS_core_register \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) \brief Type definitions for the NVIC Registers @{ */ /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ typedef struct { __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[16U]; __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ uint32_t RSERVED1[16U]; __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[16U]; __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ uint32_t RESERVED3[16U]; __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ uint32_t RESERVED4[16U]; __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ uint32_t RESERVED5[16U]; __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ uint32_t RESERVED6[580U]; __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ #define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCB System Control Block (SCB) \brief Type definitions for the System Control Block Registers @{ */ /** \brief Structure type to access the System Control Block (SCB). */ typedef struct { __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ uint32_t RESERVED3[92U]; __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ } SCB_Type; /* SCB CPUID Register Definitions */ #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ #define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ #define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ #define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ #define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ #define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ /* SCB Application Interrupt and Reset Control Register Definitions */ #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ #define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ #define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ #define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ #define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ #define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ #define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ #define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ /* SCB System Control Register Definitions */ #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ #define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ #define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ #define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ #define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ #define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ #define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ #define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ #define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ #define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ #define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ #define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ #define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ #define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ /* SCB System Handler Control and State Register Definitions */ #define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ #define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ #define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ #define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ #define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ #define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ #define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ #define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ #define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ #define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ #define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ #define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ #define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ #define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ #define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ #define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ #define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ #define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ #define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ #define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ #define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ #define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ #define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ #define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ #define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ #define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ #define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ #define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ #define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ #define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ #define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ #define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ #define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ #define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ #define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ #define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ #define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ #define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ #define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ #define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ #define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ #define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ #define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ #define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ #define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ #define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ #define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ #define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ #define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ #define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ #define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ #define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ #define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ #define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ #define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ #define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ #define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ #define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ #define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ #define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ #define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ #define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ #define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ #define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ #define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ #define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ #define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ #define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ #define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ #define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ #define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ /* SCB Non-Secure Access Control Register Definitions */ #define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ #define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ #define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ #define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ #define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ #define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ /* SCB Cache Level ID Register Definitions */ #define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ #define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ #define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ #define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ /* SCB Cache Type Register Definitions */ #define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ #define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ #define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ #define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ #define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ #define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ #define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ #define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ #define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ #define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ /* SCB Cache Size ID Register Definitions */ #define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ #define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ #define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ #define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ #define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ #define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ #define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ #define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ #define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ #define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ #define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ #define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ #define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ #define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ /* SCB Cache Size Selection Register Definitions */ #define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ #define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ #define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ #define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ /* SCB Software Triggered Interrupt Register Definitions */ #define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ #define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ /* SCB D-Cache Invalidate by Set-way Register Definitions */ #define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ #define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ #define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ #define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ /* SCB D-Cache Clean by Set-way Register Definitions */ #define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ #define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ #define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ #define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ /* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ #define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ #define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ #define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ #define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ /*@} end of group CMSIS_SCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) \brief Type definitions for the System Control and ID Register not in the SCB @{ */ /** \brief Structure type to access the System Control and ID Register not in the SCB. */ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /*@} end of group CMSIS_SCnotSCB */ /** \ingroup CMSIS_core_register \defgroup CMSIS_SysTick System Tick Timer (SysTick) \brief Type definitions for the System Timer Registers. @{ */ /** \brief Structure type to access the System Timer (SysTick). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** \ingroup CMSIS_core_register \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) \brief Type definitions for the Instrumentation Trace Macrocell (ITM) @{ */ /** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ typedef struct { __OM union { __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ uint32_t RESERVED0[864U]; __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ uint32_t RESERVED1[15U]; __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ uint32_t RESERVED5[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ uint32_t RESERVED6[4U]; __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ } ITM_Type; /* ITM Stimulus Port Register Definitions */ #define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ #define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ #define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ #define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ #define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ #define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ #define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ #define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ #define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ #define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ #define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ #define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ #define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ #define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ #define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ #define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ #define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ #define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ #define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** \ingroup CMSIS_core_register \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) \brief Type definitions for the Data Watchpoint and Trace (DWT) @{ */ /** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ uint32_t RESERVED1[1U]; __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ uint32_t RESERVED2[1U]; __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ uint32_t RESERVED3[1U]; __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ uint32_t RESERVED4[1U]; __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ uint32_t RESERVED5[1U]; __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ uint32_t RESERVED6[1U]; __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ uint32_t RESERVED7[1U]; __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ uint32_t RESERVED8[1U]; __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ uint32_t RESERVED9[1U]; __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ uint32_t RESERVED10[1U]; __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ uint32_t RESERVED11[1U]; __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ uint32_t RESERVED12[1U]; __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ uint32_t RESERVED13[1U]; __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ uint32_t RESERVED14[1U]; __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ uint32_t RESERVED15[1U]; __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ uint32_t RESERVED16[1U]; __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ uint32_t RESERVED17[1U]; __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ uint32_t RESERVED18[1U]; __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ uint32_t RESERVED19[1U]; __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ uint32_t RESERVED20[1U]; __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ uint32_t RESERVED21[1U]; __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ uint32_t RESERVED22[1U]; __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ uint32_t RESERVED23[1U]; __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ uint32_t RESERVED24[1U]; __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ uint32_t RESERVED25[1U]; __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ uint32_t RESERVED26[1U]; __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ uint32_t RESERVED27[1U]; __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ uint32_t RESERVED28[1U]; __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ uint32_t RESERVED29[1U]; __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ uint32_t RESERVED30[1U]; __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ uint32_t RESERVED31[1U]; __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ uint32_t RESERVED32[934U]; __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ uint32_t RESERVED33[1U]; __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ } DWT_Type; /* DWT Control Register Definitions */ #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ #define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ #define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ #define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ #define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ #define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ #define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ #define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ #define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ #define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ #define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ #define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ #define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ #define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ #define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ #define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ #define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ #define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ #define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ #define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ #define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ #define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ #define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ #define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ #define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ #define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Function Register Definitions */ #define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ #define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ #define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ #define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ #define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ #define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ #define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ #define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** \ingroup CMSIS_core_register \defgroup CMSIS_TPI Trace Port Interface (TPI) \brief Type definitions for the Trace Port Interface (TPI) @{ */ /** \brief Structure type to access the Trace Port Interface Register (TPI). */ typedef struct { __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ #define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ #define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ #define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ #define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ #define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ #define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ #define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ #define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration Test FIFO Test Data 0 Register Definitions */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ #define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ #define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ #define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ #define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ #define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ #define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ #define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ #define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ /* TPI Integration Test ATB Control Register 2 Register Definitions */ #define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ #define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ #define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ #define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ #define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ #define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ #define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ #define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ /* TPI Integration Test FIFO Test Data 1 Register Definitions */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ #define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ #define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ #define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ #define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ #define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ #define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ #define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ #define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ #define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ /* TPI Integration Test ATB Control Register 0 Definitions */ #define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ #define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ #define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ #define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ #define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ #define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ #define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ #define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ #define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ #define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ #define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ #define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ #define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ #define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ #define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) \brief Type definitions for the Memory Protection Unit (MPU) @{ */ /** \brief Structure type to access the Memory Protection Unit (MPU). */ typedef struct { __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; union { __IOM uint32_t MAIR[2]; struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ }; }; } MPU_Type; #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ #define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ #define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ #define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ #define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ #define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ #define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ #define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ #define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ #define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ #define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ /* MPU Region Limit Address Register Definitions */ #define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ #define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ #define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ #define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ #define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ /* MPU Memory Attribute Indirection Register 0 Definitions */ #define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ #define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ #define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ #define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ #define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ #define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ #define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ #define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ /* MPU Memory Attribute Indirection Register 1 Definitions */ #define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ #define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ #define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ #define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ #define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ #define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ #define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ #define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ /*@} end of group CMSIS_MPU */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \ingroup CMSIS_core_register \defgroup CMSIS_SAU Security Attribution Unit (SAU) \brief Type definitions for the Security Attribution Unit (SAU) @{ */ /** \brief Structure type to access the Security Attribution Unit (SAU). */ typedef struct { __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ #else uint32_t RESERVED0[3]; #endif __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ } SAU_Type; /* SAU Control Register Definitions */ #define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ #define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ #define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ #define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ /* SAU Type Register Definitions */ #define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ #define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) /* SAU Region Number Register Definitions */ #define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ #define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ /* SAU Region Base Address Register Definitions */ #define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ #define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ /* SAU Region Limit Address Register Definitions */ #define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ #define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ #define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ #define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ #define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ #define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ #endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ /* Secure Fault Status Register Definitions */ #define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ #define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ #define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ #define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ #define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ #define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ #define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ #define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ #define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ #define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ #define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ #define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ #define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ #define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ #define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ #define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ /*@} end of group CMSIS_SAU */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) \brief Type definitions for the Floating Point Unit (FPU) @{ */ /** \brief Structure type to access the Floating Point Unit (FPU). */ typedef struct { uint32_t RESERVED0[1U]; __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ #define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ #define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ #define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ #define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ #define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ #define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ #define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ #define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ #define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ #define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ #define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ #define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ #define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ #define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ #define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ #define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ #define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ #define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ #define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ #define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ #define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ #define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ #define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ #define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ #define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ #define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ #define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ #define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ #define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ #define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ #define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ #define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ #define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ #define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ /* Floating-Point Context Address Register Definitions */ #define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ #define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ /* Floating-Point Default Status Control Register Definitions */ #define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ #define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ #define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ #define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ #define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ #define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ #define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ #define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ /* Media and FP Feature Register 0 Definitions */ #define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ #define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ #define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ #define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ #define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ #define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ #define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ #define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ #define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ #define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ #define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ #define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ #define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ #define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ #define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ #define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ /* Media and FP Feature Register 1 Definitions */ #define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ #define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ #define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ #define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ #define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ #define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ /*@} end of group CMSIS_FPU */ /** \ingroup CMSIS_core_register \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) \brief Type definitions for the Core Debug Registers @{ */ /** \brief Structure type to access the Core Debug Register (CoreDebug). */ typedef struct { __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ uint32_t RESERVED4[1U]; __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ #define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ #define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ #define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ #define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ #define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ #define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ #define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ #define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ #define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ #define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ #define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ #define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ #define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ #define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ #define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ #define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ #define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ #define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ #define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ #define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ #define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ #define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ #define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ #define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ #define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ #define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ #define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /* Debug Authentication Control Register Definitions */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ #define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ #define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ #define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ /* Debug Security Control and Status Register Definitions */ #define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ #define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ #define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ #define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ #define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ #define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ /*@} end of group CMSIS_CoreDebug */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_bitfield Core register bit field macros \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). @{ */ /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ /** \ingroup CMSIS_core_register \defgroup CMSIS_core_base Core Definitions \brief Definitions for base addresses, unions, and structures. @{ */ /* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ #endif #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ #endif #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} */ /******************************************************************************* * Hardware Abstraction Layer Core Function Interface contains: - Core NVIC Functions - Core SysTick Functions - Core Debug Functions - Core Register Access Functions ******************************************************************************/ /** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference */ /* ########################## NVIC functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_NVICFunctions NVIC Functions \brief Functions that manage interrupts and exceptions via the NVIC. @{ */ #ifdef CMSIS_NVIC_VIRTUAL #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" #endif #include CMSIS_NVIC_VIRTUAL_HEADER_FILE #else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ #ifdef CMSIS_VECTAB_VIRTUAL #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" #endif #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE #else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ #define NVIC_USER_IRQ_OFFSET 16 /* Special LR values for Secure/Non-Secure call handling and exception handling */ /* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ #define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ /* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ #define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ #define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ #define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ #define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ #define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ #define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ #define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ /* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ #define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ #else #define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ #endif /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } /** \brief Get Priority Grouping \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status \details Returns a device specific interrupt enable status from the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt \details Disables a device specific interrupt in the NVIC interrupt controller. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } } /** \brief Get Pending Interrupt \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt \details Sets the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt \details Clears the pending bit of a device specific interrupt in the NVIC pending register. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Get Interrupt Target State \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure \return 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Target State \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Clear Interrupt Target State \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 if interrupt is assigned to Secure 1 if interrupt is assigned to Non Secure \note IRQn must not be negative. */ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /** \brief Set Interrupt Priority \details Sets the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority \details Reads the priority of a device specific interrupt or a processor exception. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } /** \brief Encode Priority \details Encodes the priority for an interrupt with the given priority group, preemptive priority value, and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Used priority group. \param [in] PreemptPriority Preemptive priority value (starting from 0). \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref __NVIC_SetPriority(). */ __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); return ( ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) ); } /** \brief Decode Priority \details Decodes an interrupt priority value with a given priority group to preemptive priority value and subpriority value. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. \param [in] Priority Priority value, which can be retrieved with \ref __NVIC_GetPriority(). \param [in] PriorityGroup Used priority group. \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; uint32_t SubPriorityBits; PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); } /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. VTOR must been relocated to SRAM before. \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; } /** \brief Get Interrupt Vector \details Reads an interrupt vector from interrupt vector table. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; } /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ for(;;) /* wait until reset */ { __NOP(); } } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Set Priority Grouping (non-secure) \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. In case of a conflict between priority grouping and available priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ reg_value = SCB_NS->AIRCR; /* read old register configuration */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB_NS->AIRCR = reg_value; } /** \brief Get Priority Grouping (non-secure) \details Reads the priority grouping field from the non-secure NVIC when in secure state. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) { return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** \brief Enable Interrupt (non-secure) \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Interrupt Enable status (non-secure) \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt is not enabled. \return 1 Interrupt is enabled. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Disable Interrupt (non-secure) \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Pending Interrupt (non-secure) \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Pending Interrupt (non-secure) \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Clear Pending Interrupt (non-secure) \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } /** \brief Get Active Interrupt (non-secure) \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. \note IRQn must not be negative. */ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { return(0U); } } /** \brief Set Interrupt Priority (non-secure) \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. \note The priority cannot be set for every non-secure processor exception. */ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority (non-secure) \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. The interrupt number can be positive to specify a device specific interrupt, or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #include "mpu_armv8.h" #endif /* ########################## FPU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_FpuFunctions FPU Functions \brief Function that provides FPU type. @{ */ /** \brief get FPU type \details returns the FPU type \returns - \b 0: No FPU - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ __STATIC_INLINE uint32_t SCB_GetFPUType(void) { uint32_t mvfr0; mvfr0 = FPU->MVFR0; if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) { return 2U; /* Double + Single precision FPU */ } else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) { return 1U; /* Single precision FPU */ } else { return 0U; /* No FPU */ } } /*@} end of CMSIS_Core_FpuFunctions */ /* ########################## SAU functions #################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SAUFunctions SAU Functions \brief Functions that configure the SAU. @{ */ #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief Enable SAU \details Enables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Enable(void) { SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); } /** \brief Disable SAU \details Disables the Security Attribution Unit (SAU). */ __STATIC_INLINE void TZ_SAU_Disable(void) { SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_SAUFunctions */ /* ################################## SysTick function ############################################ */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_Core_SysTickFunctions SysTick Functions \brief Functions that configure the System. @{ */ #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) /** \brief System Tick Configuration (non-secure) \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable __Vendor_SysTickConfig is set to 1, then the function TZ_SysTick_Config_NS is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ __STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ } #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ #endif /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ /** \ingroup CMSIS_Core_FunctionInterface \defgroup CMSIS_core_DebugFunctions ITM Functions \brief Functions that access the ITM debug interface. @{ */ extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ #define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** \brief ITM Send Character \details Transmits a character via the ITM channel 0, and \li Just returns when no debugger is connected that has booked the output. \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. \param [in] ch Character to transmit. \returns Character to transmit. */ __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ { while (ITM->PORT[0U].u32 == 0UL) { __NOP(); } ITM->PORT[0U].u8 = (uint8_t)ch; } return (ch); } /** \brief ITM Receive Character \details Inputs a character via the external variable \ref ITM_RxBuffer. \return Received character. \return -1 No character pending. */ __STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { ch = ITM_RxBuffer; ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ } return (ch); } /** \brief ITM Check Character \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. \return 0 No character available. \return 1 Character available. */ __STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { return (0); /* no character available */ } else { return (1); /* character available */ } } /*@} end of CMSIS_core_DebugFunctions */ #ifdef __cplusplus } #endif #endif /* __CORE_CM33_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/mpu_armv8.h ================================================ /****************************************************************************** * @file mpu_armv8.h * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU * @version V5.1.0 * @date 08. March 2019 ******************************************************************************/ /* * Copyright (c) 2017-2019 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (c) 2019 Modified by Dialog Semiconductor */ #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef ARM_MPU_ARMV8_H #define ARM_MPU_ARMV8_H /** \brief Attribute for device memory (outer only) */ #define ARM_MPU_ATTR_DEVICE ( 0U ) /** \brief Attribute for non-cacheable, normal memory */ #define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) /** \brief Attribute for normal memory (outer and inner) * \param NT Non-Transient: Set to 1 for non-transient data. * \param WB Write-Back: Set to 1 to use write-back update policy. * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. */ #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGnRE (1U) /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_nGRE (2U) /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ #define ARM_MPU_ATTR_DEVICE_GRE (3U) /** \brief Memory Attribute * \param O Outer memory attributes * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes */ #define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) /** \brief Normal memory non-shareable */ #define ARM_MPU_SH_NON (0U) /** \brief Normal memory outer shareable */ #define ARM_MPU_SH_OUTER (2U) /** \brief Normal memory inner shareable */ #define ARM_MPU_SH_INNER (3U) /** \brief Memory access permissions * \param RO Read-Only: Set to 1 for read-only memory. * \param NP Non-Privileged: Set to 1 for non-privileged memory. */ #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) /** \brief Region Base Address Register value * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. * \param SH Defines the Shareability domain for this memory region. * \param RO Read-Only: Set to 1 for a read-only memory region. * \param NP Non-Privileged: Set to 1 for a non-privileged memory region. * \param XN eXecute Never: Set to 1 for a non-executable memory region. */ #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ ((BASE & MPU_RBAR_BASE_Msk) | \ ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) /** \brief Region Limit Address Register value * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. * \param IDX The attribute index to be associated with this memory region. */ #define ARM_MPU_RLAR(LIMIT, IDX) \ ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ (MPU_RLAR_EN_Msk)) #if defined(MPU_RLAR_PXN_Pos) /** \brief Region Limit Address Register with PXN value * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. * \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. * \param IDX The attribute index to be associated with this memory region. */ #define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ (MPU_RLAR_EN_Msk)) #endif /** * Struct for a single MPU Region */ typedef struct { uint32_t RBAR; /*!< Region Base Address Register value */ uint32_t RLAR; /*!< Region Limit Address Register value */ } ARM_MPU_Region_t; /** Enable the MPU. * \param MPU_Control Default access permissions for unconfigured regions. */ __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) { MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; #endif __DSB(); __ISB(); } /** Disable the MPU. */ __STATIC_INLINE void ARM_MPU_Disable(void) { __DMB(); #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; #endif MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; } #ifdef MPU_NS /** Enable the Non-secure MPU. * \param MPU_Control Default access permissions for unconfigured regions. */ __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) { MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; #endif __DSB(); __ISB(); } /** Disable the Non-secure MPU. */ __STATIC_INLINE void ARM_MPU_Disable_NS(void) { __DMB(); #ifdef SCB_SHCSR_MEMFAULTENA_Msk SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; #endif MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; } #endif /** Set the memory attribute encoding to the given MPU. * \param mpu Pointer to the MPU to be configured. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) { const uint8_t reg = idx / 4U; const uint32_t pos = ((idx % 4U) * 8U); const uint32_t mask = 0xFFU << pos; if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { return; // invalid index } mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); } /** Set the memory attribute encoding. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) { ARM_MPU_SetMemAttrEx(MPU, idx, attr); } #ifdef MPU_NS /** Set the memory attribute encoding to the Non-secure MPU. * \param idx The attribute index to be set [0-7] * \param attr The attribute value to be set. */ __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) { ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); } #endif /** Clear and disable the given MPU region of the given MPU. * \param mpu Pointer to MPU to be used. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) { mpu->RNR = rnr; mpu->RLAR = 0U; } /** Clear and disable the given MPU region. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) { ARM_MPU_ClrRegionEx(MPU, rnr); } #ifdef MPU_NS /** Clear and disable the given Non-secure MPU region. * \param rnr Region number to be cleared. */ __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) { ARM_MPU_ClrRegionEx(MPU_NS, rnr); } #endif /** Configure the given MPU region of the given MPU. * \param mpu Pointer to MPU to be used. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) { mpu->RNR = rnr; mpu->RBAR = rbar; mpu->RLAR = rlar; } /** Configure the given MPU region. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) { ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); } #ifdef MPU_NS /** Configure the given Non-secure MPU region. * \param rnr Region number to be configured. * \param rbar Value for RBAR register. * \param rlar Value for RLAR register. */ __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) { ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); } #endif /** Memcopy with strictly ordered memory access, e.g. for register targets. * \param dst Destination data is copied to. * \param src Source data is copied from. * \param len Amount of data words to be copied. */ __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) { uint32_t i; for (i = 0U; i < len; ++i) { dst[i] = src[i]; } } /** Load the given number of MPU regions from a table to the given MPU. * \param mpu Pointer to the MPU registers to be used. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; if (cnt == 1U) { mpu->RNR = rnr; ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); } else { uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; mpu->RNR = rnrBase; while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { uint32_t c = MPU_TYPE_RALIASES - rnrOffset; ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); table += c; cnt -= c; rnrOffset = 0U; rnrBase += MPU_TYPE_RALIASES; mpu->RNR = rnrBase; } ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); } } /** Load the given number of MPU regions from a table. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { ARM_MPU_LoadEx(MPU, rnr, table, cnt); } #ifdef MPU_NS /** Load the given number of MPU regions from a table to the Non-secure MPU. * \param rnr First region number to be configured. * \param table Pointer to the MPU configuration table. * \param cnt Amount of regions to be configured. */ __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) { ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); } #endif #endif ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_ARMCM0.h ================================================ /**************************************************************************//** * @file system_ARMCM0.h * @brief CMSIS Device System Header File for * ARMCM0 Device * @version V5.3.1 * @date 09. July 2018 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SYSTEM_ARMCM0_H #define SYSTEM_ARMCM0_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ /** \brief Setup the microcontroller system. Initialize the System and update the SystemCoreClock variable. */ extern void SystemInit (void); /** \brief Update SystemCoreClock variable. Updates the SystemCoreClock with current core Clock retrieved from cpu registers. */ extern void SystemCoreClockUpdate (void); #ifdef __cplusplus } #endif #endif /* SYSTEM_ARMCM0_H */ ================================================ FILE: hw/mcu/dialog/da1469x/SDK_10.0.8.105/sdk/bsp/include/system_DA1469x.h ================================================ /**************************************************************************//** * @file system_DA1469x.h * @brief CMSIS Device System Header File for DA1469x Device * @version V5.3.1 * @date 17. May 2019 ******************************************************************************/ /* * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (c) 2017 Modified by Dialog Semiconductor */ #ifndef SYSTEM_DA1469x_H #define SYSTEM_DA1469x_H #ifdef __cplusplus extern "C" { #endif #include #include extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ /** \brief Setup the microcontroller system. Initialize the System and update the SystemCoreClock variable. */ extern void SystemInit (void); /** \brief Update SystemCoreClock variable. Updates the SystemCoreClock with current core Clock retrieved from cpu registers. */ extern void SystemCoreClockUpdate (void); /** * \brief Convert a CPU address to a physical address * * To calculate the physical address, the current remapping (SYS_CTRL_REG.REMAP_ADR0) * is used. * * \param [in] addr address seen by CPU * * \return physical address (for DMA, AES/HASH etc.) -- can be same or different as addr * */ extern uint32_t black_orca_phy_addr(uint32_t addr); #ifdef __cplusplus } #endif #endif /* SYSTEM_DA1469x_H */ ================================================ FILE: hw/mcu/dialog/da1469x/da1469x.ld ================================================ /* Linker script for Dialog DA1469x devices * * Version: Sourcery G++ 4.5-1 * Support: https://support.codesourcery.com/GNUToolchain/ * * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this * notice is included verbatim in any distributions. No written agreement, * license, or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their authors * and need not follow the licensing terms described here, provided that * the new terms are clearly indicated on the first page of each file where * they apply. */ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __HeapBase * __HeapLimit * __StackLimit * __StackTop * __stack * __bssnz_start__ * __bssnz_end__ */ ENTRY(Reset_Handler) SECTIONS { .imghdr (NOLOAD): { . = . + _imghdr_size; } > FLASH __text = .; .text : { __isr_vector_start = .; KEEP(*(.isr_vector)) /* ISR vector shall have exactly 512 bytes */ . = __isr_vector_start + 0x200; __isr_vector_end = .; *(.text) *(.text.*) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) *(.eh_frame*) . = ALIGN(4); } > FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) . = ALIGN(4); } > FLASH __exidx_end = .; .intvect : { . = ALIGN(4); __intvect_start__ = .; . = . + (__isr_vector_end - __isr_vector_start); . = ALIGN(4); } > RAM .sleep_state (NOLOAD) : { . = ALIGN(4); *(sleep_state) } > RAM /* This section will be zeroed by RTT package init */ .rtt (NOLOAD): { . = ALIGN(4); *(.rtt) . = ALIGN(4); } > RAM __text_ram_addr = LOADADDR(.text_ram); .text_ram : { . = ALIGN(4); __text_ram_start__ = .; *(.text_ram*) . = ALIGN(4); __text_ram_end__ = .; } > RAM AT > FLASH __etext = LOADADDR(.data); .data : { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); *(.preinit_array) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); *(SORT(.init_array.*)) *(.init_array) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); *(SORT(.fini_array.*)) *(.fini_array) PROVIDE_HIDDEN (__fini_array_end = .); *(.jcr) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT > FLASH .bssnz : { . = ALIGN(4); __bssnz_start__ = .; *(.bss.core.nz*) . = ALIGN(4); __bssnz_end__ = .; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM .cmac (NOLOAD) : { . = ALIGN(0x400); *(.libcmac.ram) } > RAM /* Heap starts after BSS */ . = ALIGN(8); __HeapBase = .; /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ .stack_dummy (COPY): { *(.stack*) } > RAM _ram_start = ORIGIN(RAM); /* Set stack top to end of RAM, and stack limit move down by * size of stack_dummy section */ __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); /* Top of head is the bottom of the stack */ __HeapLimit = __StackLimit; /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") /* Check that intvect is at the beginning of RAM */ ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM") } ================================================ FILE: hw/mcu/dialog/da1469x/include/hal/hal_gpio.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * @addtogroup HAL * @{ * @defgroup HALGpio HAL GPIO * @{ */ #ifndef H_HAL_GPIO_ #define H_HAL_GPIO_ #ifdef __cplusplus extern "C" { #endif /** * The "mode" of the gpio. The gpio is either an input, output, or it is * "not connected" (the pin specified is not functioning as a gpio) */ enum hal_gpio_mode_e { /** Not connected */ HAL_GPIO_MODE_NC = -1, /** Input */ HAL_GPIO_MODE_IN = 0, /** Output */ HAL_GPIO_MODE_OUT = 1 }; typedef enum hal_gpio_mode_e hal_gpio_mode_t; /* * The "pull" of the gpio. This is either an input or an output. */ enum hal_gpio_pull { /** Pull-up/down not enabled */ HAL_GPIO_PULL_NONE = 0, /** Pull-up enabled */ HAL_GPIO_PULL_UP = 1, /** Pull-down enabled */ HAL_GPIO_PULL_DOWN = 2 }; typedef enum hal_gpio_pull hal_gpio_pull_t; /* * IRQ trigger type. */ enum hal_gpio_irq_trigger { HAL_GPIO_TRIG_NONE = 0, /** IRQ occurs on rising edge */ HAL_GPIO_TRIG_RISING = 1, /** IRQ occurs on falling edge */ HAL_GPIO_TRIG_FALLING = 2, /** IRQ occurs on either edge */ HAL_GPIO_TRIG_BOTH = 3, /** IRQ occurs when line is low */ HAL_GPIO_TRIG_LOW = 4, /** IRQ occurs when line is high */ HAL_GPIO_TRIG_HIGH = 5 }; typedef enum hal_gpio_irq_trigger hal_gpio_irq_trig_t; /* Function proto for GPIO irq handler functions */ typedef void (*hal_gpio_irq_handler_t)(void *arg); /** * Initializes the specified pin as an input * * @param pin Pin number to set as input * @param pull pull type * * @return int 0: no error; -1 otherwise. */ int hal_gpio_init_in(int pin, hal_gpio_pull_t pull); /** * Initialize the specified pin as an output, setting the pin to the specified * value. * * @param pin Pin number to set as output * @param val Value to set pin * * @return int 0: no error; -1 otherwise. */ int hal_gpio_init_out(int pin, int val); /** * Deinitialize the specified pin to revert the previous initialization * * @param pin Pin number to unset * * @return int 0: no error; -1 otherwise. */ int hal_gpio_deinit(int pin); /** * Write a value (either high or low) to the specified pin. * * @param pin Pin to set * @param val Value to set pin (0:low 1:high) */ void hal_gpio_write(int pin, int val); /** * Reads the specified pin. * * @param pin Pin number to read * * @return int 0: low, 1: high */ int hal_gpio_read(int pin); /** * Toggles the specified pin * * @param pin Pin number to toggle * * @return current gpio state int 0: low, 1: high */ int hal_gpio_toggle(int pin); /** * Initialize a given pin to trigger a GPIO IRQ callback. * * @param pin The pin to trigger GPIO interrupt on * @param handler The handler function to call * @param arg The argument to provide to the IRQ handler * @param trig The trigger mode (e.g. rising, falling) * @param pull The mode of the pin (e.g. pullup, pulldown) * * @return 0 on success, non-zero error code on failure. */ int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull); /** * Release a pin from being configured to trigger IRQ on state change. * * @param pin The pin to release */ void hal_gpio_irq_release(int pin); /** * Enable IRQs on the passed pin * * @param pin The pin to enable IRQs on */ void hal_gpio_irq_enable(int pin); /** * Disable IRQs on the passed pin * * @param pin The pin to disable IRQs on */ void hal_gpio_irq_disable(int pin); #ifdef __cplusplus } #endif #endif /* H_HAL_GPIO_ */ /** * @} HALGpio * @} HAL */ ================================================ FILE: hw/mcu/dialog/da1469x/include/mcu/da1469x_clock.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef __MCU_DA1469X_CLOCK_H_ #define __MCU_DA1469X_CLOCK_H_ #include #include "mcu/da1469x_hal.h" #ifdef __cplusplus extern "C" { #endif /** * Initialize XTAL32M */ void da1469x_clock_sys_xtal32m_init(void); /** * Enable XTAL32M */ void da1469x_clock_sys_xtal32m_enable(void); /** * Wait for XTAL32M to settle */ void da1469x_clock_sys_xtal32m_wait_to_settle(void); /** * Switch sys_clk to XTAL32M * * Caller shall ensure that XTAL32M is already settled. */ void da1469x_clock_sys_xtal32m_switch(void); /** * Switch sys_clk to XTAL32M * * Waits for XTAL32M to settle before switching. */ void da1469x_clock_sys_xtal32m_switch_safe(void); /** * Disable RC32M */ void da1469x_clock_sys_rc32m_disable(void); /** * Enable AMBA clock(s) * * @param mask */ static inline void da1469x_clock_amba_enable(uint32_t mask) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); CRG_TOP->CLK_AMBA_REG |= mask; __HAL_ENABLE_INTERRUPTS(primask); } /** * Disable AMBA clock(s) * * @param uint32_t mask */ static inline void da1469x_clock_amba_disable(uint32_t mask) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); CRG_TOP->CLK_AMBA_REG &= ~mask; __HAL_ENABLE_INTERRUPTS(primask); } /** * Enable PLL96 */ static inline void da1469x_clock_sys_pll_enable(void) { CRG_XTAL->PLL_SYS_CTRL1_REG |= CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk | CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Msk; } /** * Disable PLL96 * * If PLL was used as SYS_CLOCK switches to XTAL32M. */ void da1469x_clock_sys_pll_disable(void); /** * Checks whether PLL96 is locked and can be use as system clock or USB clock * * @return 0 if PLL is off, non-0 it its running */ static inline int da1469x_clock_is_pll_locked(void) { return 0 != (CRG_XTAL->PLL_SYS_STATUS_REG & CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Msk); } /** * Waits for PLL96 to lock. */ void da1469x_clock_pll_wait_to_lock(void); /** * Switches system clock to PLL96 * * Caller shall ensure that PLL is already locked. */ void da1469x_clock_sys_pll_switch(void); #ifdef __cplusplus } #endif #endif /* __MCU_DA1469X_CLOCK_H_ */ ================================================ FILE: hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef __MCU_DA1469X_HAL_H_ #define __MCU_DA1469X_HAL_H_ #include #include "mcu/mcu.h" #ifdef __cplusplus extern "C" { #endif /* Helper functions to enable/disable interrupts. */ #define __HAL_DISABLE_INTERRUPTS(x) \ do { \ x = __get_PRIMASK(); \ __disable_irq(); \ } while (0) #define __HAL_ENABLE_INTERRUPTS(x) \ do { \ if (!x) { \ __enable_irq(); \ } \ } while (0) #define __HAL_ASSERT_CRITICAL() \ do { \ assert(__get_PRIMASK() & 1); \ } while (0) #ifdef __cplusplus } #endif #endif /* __MCU_DA1469X_HAL_H_ */ ================================================ FILE: hw/mcu/dialog/da1469x/include/mcu/mcu.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef __MCU_MCU_H_ #define __MCU_MCU_H_ #ifdef __cplusplus extern "C" { #endif #include "DA1469xAB.h" #define sec_text_ram_core __attribute__((section(".text_ram"))) __attribute__((noinline)) #define MCU_SYSVIEW_INTERRUPTS \ "I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \ "I#7=SecureFault,I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \ "I#16=SENSOR_NODE,I#17=DMA,I#18=CHARGER_STATE,I#19=CHARGER_ERROR," \ "I#20=CMAC2SYS,I#21=UART,I#22=UART2,I#23=UART3,I#24=I2C,I#25=I2C2,I#26=SPI," \ "I#27=SPI2,I#28=PCM,I#29=SRC_IN,I#30=SRC_OUT,I#31=USB,I#32=TIMER," \ "I#33=TIMER2,I#34=RTC,I#35=KEY_WKUP_GPIO,I#36=PDC,I#37=VBUS,I#38=MRM," \ "I#39=MOTOR_CONTROLLER,I#40=TRNG,I#41=DCDC,I#42=XTAL32M_RDY,I#43=ADC," \ "I#44=ADC2,I#45=CRYPTO,I#46=CAPTIMER1,I#47=RFDIAG,I#48=LCD_CONTROLLER," \ "I#49=PLL_LOCK,I#50=TIMER3,I#51=TIMER4,I#52=LRA,I#53=RTC_EVENT," \ "I#54=GPIO_P0,I#55=GPIO_P1" /** * \brief GPIO function * */ typedef enum { MCU_GPIO_FUNC_GPIO = 0, /**< GPIO */ MCU_GPIO_FUNC_UART_RX = 1, /**< GPIO as UART RX */ MCU_GPIO_FUNC_UART_TX = 2, /**< GPIO as UART TX */ MCU_GPIO_FUNC_UART2_RX = 3, /**< GPIO as UART2 RX */ MCU_GPIO_FUNC_UART2_TX = 4, /**< GPIO as UART2 TX */ MCU_GPIO_FUNC_UART2_CTSN = 5, /**< GPIO as UART2 CTSN */ MCU_GPIO_FUNC_UART2_RTSN = 6, /**< GPIO as UART2 RTSN */ MCU_GPIO_FUNC_UART3_RX = 7, /**< GPIO as UART3 RX */ MCU_GPIO_FUNC_UART3_TX = 8, /**< GPIO as UART3 TX */ MCU_GPIO_FUNC_UART3_CTSN = 9, /**< GPIO as UART3 CTSN */ MCU_GPIO_FUNC_UART3_RTSN = 10, /**< GPIO as UART3 RTSN */ MCU_GPIO_FUNC_ISO_CLK = 11, /**< GPIO as ISO CLK */ MCU_GPIO_FUNC_ISO_DATA = 12, /**< GPIO as ISO DATA */ MCU_GPIO_FUNC_SPI_DI = 13, /**< GPIO as SPI DI */ MCU_GPIO_FUNC_SPI_DO = 14, /**< GPIO as SPI DO */ MCU_GPIO_FUNC_SPI_CLK = 15, /**< GPIO as SPI CLK */ MCU_GPIO_FUNC_SPI_EN = 16, /**< GPIO as SPI EN */ MCU_GPIO_FUNC_SPI2_DI = 17, /**< GPIO as SPI2 DI */ MCU_GPIO_FUNC_SPI2_DO = 18, /**< GPIO as SPI2 DO */ MCU_GPIO_FUNC_SPI2_CLK = 19, /**< GPIO as SPI2 CLK */ MCU_GPIO_FUNC_SPI2_EN = 20, /**< GPIO as SPI2 EN */ MCU_GPIO_FUNC_I2C_SCL = 21, /**< GPIO as I2C SCL */ MCU_GPIO_FUNC_I2C_SDA = 22, /**< GPIO as I2C SDA */ MCU_GPIO_FUNC_I2C2_SCL = 23, /**< GPIO as I2C2 SCL */ MCU_GPIO_FUNC_I2C2_SDA = 24, /**< GPIO as I2C2 SDA */ MCU_GPIO_FUNC_USB_SOF = 25, /**< GPIO as USB SOF */ MCU_GPIO_FUNC_ADC = 26, /**< GPIO as ADC (dedicated pin) */ MCU_GPIO_FUNC_USB = 27, /**< GPIO as USB */ MCU_GPIO_FUNC_PCM_DI = 28, /**< GPIO as PCM DI */ MCU_GPIO_FUNC_PCM_DO = 29, /**< GPIO as PCM DO */ MCU_GPIO_FUNC_PCM_FSC = 30, /**< GPIO as PCM FSC */ MCU_GPIO_FUNC_PCM_CLK = 31, /**< GPIO as PCM CLK */ MCU_GPIO_FUNC_PDM_DATA = 32, /**< GPIO as PDM DATA */ MCU_GPIO_FUNC_PDM_CLK = 33, /**< GPIO as PDM CLK */ MCU_GPIO_FUNC_COEX_EXT_ACT = 34, /**< GPIO as COEX EXT ACT0 */ MCU_GPIO_FUNC_COEX_SMART_ACT = 35, /**< GPIO as COEX SMART ACT */ MCU_GPIO_FUNC_COEX_SMART_PRI = 36, /**< GPIO as COEX SMART PRI */ MCU_GPIO_FUNC_PORT0_DCF = 37, /**< GPIO as PORT0 DCF */ MCU_GPIO_FUNC_PORT1_DCF = 38, /**< GPIO as PORT1 DCF */ MCU_GPIO_FUNC_PORT2_DCF = 39, /**< GPIO as PORT2 DCF */ MCU_GPIO_FUNC_PORT3_DCF = 40, /**< GPIO as PORT3 DCF */ MCU_GPIO_FUNC_PORT4_DCF = 41, /**< GPIO as PORT4 DCF */ MCU_GPIO_FUNC_CLOCK = 42, /**< GPIO as CLOCK */ MCU_GPIO_FUNC_PG = 43, /**< GPIO as PG */ MCU_GPIO_FUNC_LCD = 44, /**< GPIO as LCD */ MCU_GPIO_FUNC_LCD_SPI_DC = 45, /**< GPIO as LCD SPI DC */ MCU_GPIO_FUNC_LCD_SPI_DO = 46, /**< GPIO as LCD SPI DO */ MCU_GPIO_FUNC_LCD_SPI_CLK = 47, /**< GPIO as LCD SPI CLK */ MCU_GPIO_FUNC_LCD_SPI_EN = 48, /**< GPIO as LCD SPI EN */ MCU_GPIO_FUNC_TIM_PWM = 49, /**< GPIO as TIM PWM */ MCU_GPIO_FUNC_TIM2_PWM = 50, /**< GPIO as TIM2 PWM */ MCU_GPIO_FUNC_TIM_1SHOT = 51, /**< GPIO as TIM 1SHOT */ MCU_GPIO_FUNC_TIM2_1SHOT = 52, /**< GPIO as TIM2 1SHOT */ MCU_GPIO_FUNC_TIM3_PWM = 53, /**< GPIO as TIM3 PWM */ MCU_GPIO_FUNC_TIM4_PWM = 54, /**< GPIO as TIM4 PWM */ MCU_GPIO_FUNC_AGC_EXT = 55, /**< GPIO as AGC EXT */ MCU_GPIO_FUNC_CMAC_DIAG0 = 56, /**< GPIO as CMAC DIAG0 */ MCU_GPIO_FUNC_CMAC_DIAG1 = 57, /**< GPIO as CMAC DIAG1 */ MCU_GPIO_FUNC_CMAC_DIAG2 = 58, /**< GPIO as CMAC DIAG2 */ MCU_GPIO_FUNC_CMAC_DIAGX = 59, /**< GPIO as CMAC DIAGX */ MCU_GPIO_FUNC_LAST, } mcu_gpio_func; #define MCU_GPIO_MODE_INPUT 0x000 /**< GPIO as an input */ #define MCU_GPIO_MODE_INPUT_PULLUP 0x100 /**< GPIO as an input with pull-up */ #define MCU_GPIO_MODE_INPUT_PULLDOWN 0x200 /**< GPIO as an input with pull-down */ #define MCU_GPIO_MODE_OUTPUT 0x300 /**< GPIO as an output */ #define MCU_GPIO_MODE_OUTPUT_OPEN_DRAIN 0x700 /**< GPIO as an open-drain output */ #define MCU_GPIO_PORT0_PIN_COUNT 32 #define MCU_GPIO_PORT0(pin) ((0 * 32) + (pin)) #define MCU_GPIO_PORT1(pin) ((1 * 32) + (pin)) #define MCU_DMA_CHAN_MAX 8 #define MCU_PIN_GPADC_SEL0 MCU_GPIO_PORT1(9) #define MCU_PIN_GPADC_SEL1 MCU_GPIO_PORT0(25) #define MCU_PIN_GPADC_SEL2 MCU_GPIO_PORT0(8) #define MCU_PIN_GPADC_SEL3 MCU_GPIO_PORT0(9) #define MCU_PIN_GPADC_SEL16 MCU_GPIO_PORT1(13) #define MCU_PIN_GPADC_SEL17 MCU_GPIO_PORT1(12) #define MCU_PIN_GPADC_SEL18 MCU_GPIO_PORT1(18) #define MCU_PIN_GPADC_SEL19 MCU_GPIO_PORT1(19) #define MCU_PIN_GPADC_DIFF0_P0 MCU_GPIO_PORT1(9) #define MCU_PIN_GPADC_DIFF0_P1 MCU_GPIO_PORT0(25) #define MCU_PIN_GPADC_DIFF1_P0 MCU_GPIO_PORT0(8) #define MCU_PIN_GPADC_DIFF1_P1 MCU_GPIO_PORT0(9) #define MCU_PIN_SDADC0 MCU_GPIO_PORT1(9) #define MCU_PIN_SDADC1 MCU_GPIO_PORT0(25) #define MCU_PIN_SDADC2 MCU_GPIO_PORT0(8) #define MCU_PIN_SDADC3 MCU_GPIO_PORT0(9) #define MCU_PIN_SDADC4 MCU_GPIO_PORT1(14) #define MCU_PIN_SDADC5 MCU_GPIO_PORT1(20) #define MCU_PIN_SDADC6 MCU_GPIO_PORT1(21) #define MCU_PIN_SDADC7 MCU_GPIO_PORT1(22) void mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func); void mcu_gpio_enter_sleep(void); void mcu_gpio_exit_sleep(void); #define MCU_MEM_QSPIF_M_END_REMAP_ADDRESS (0x800000) #define MCU_MEM_QSPIF_M_START_ADDRESS (0x16000000) #define MCU_MEM_QSPIF_M_END_ADDRESS (0x18000000) #define MCU_MEM_SYSRAM_START_ADDRESS (0x20000000) #define MCU_MEM_SYSRAM_END_ADDRESS (0x20080000) #define MCU_OTPM_BASE 0x30080000UL #define MCU_OTPM_SIZE 4096 /* Largest group id seen on a DA14699 was 18 so far */ #define MCU_TRIMV_GROUP_ID_MAX (18) #ifdef __cplusplus } #endif #endif /* __MCU_MCU_H_ */ ================================================ FILE: hw/mcu/dialog/da1469x/src/da1469x_clock.c ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include #include #include #include "syscfg/syscfg.h" #include "mcu/da1469x_hal.h" #include "mcu/da1469x_clock.h" static inline bool da1469x_clock_is_xtal32m_settled(void) { return ((*(uint32_t *)0x5001001c & 0xff00) == 0) && ((*(uint32_t *)0x50010054 & 0x000f) != 0xb); } void da1469x_clock_sys_xtal32m_init(void) { uint32_t reg; int xtalrdy_cnt; /* Number of lp_clk cycles (~30.5us) */ xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 10 / 305; reg = CRG_XTAL->XTALRDY_CTRL_REG; reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk | CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk); reg |= xtalrdy_cnt; CRG_XTAL->XTALRDY_CTRL_REG = reg; } void da1469x_clock_sys_xtal32m_enable(void) { PDC->PDC_CTRL0_REG = (2 << PDC_PDC_CTRL0_REG_TRIG_SELECT_Pos) | (15 << PDC_PDC_CTRL0_REG_TRIG_ID_Pos) | (1 << PDC_PDC_CTRL0_REG_PDC_MASTER_Pos) | (1 << PDC_PDC_CTRL0_REG_EN_XTAL_Pos); PDC->PDC_SET_PENDING_REG = 0; PDC->PDC_ACKNOWLEDGE_REG = 0; } void da1469x_clock_sys_xtal32m_switch(void) { if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) { CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk; } else { CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; } while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk)); } void da1469x_clock_sys_xtal32m_wait_to_settle(void) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); NVIC_ClearPendingIRQ(XTAL32M_RDY_IRQn); if (!da1469x_clock_is_xtal32m_settled()) { NVIC_EnableIRQ(XTAL32M_RDY_IRQn); while (!NVIC_GetPendingIRQ(XTAL32M_RDY_IRQn)) { __WFI(); } NVIC_DisableIRQ(XTAL32M_RDY_IRQn); } __HAL_ENABLE_INTERRUPTS(primask); } void da1469x_clock_sys_xtal32m_switch_safe(void) { da1469x_clock_sys_xtal32m_wait_to_settle(); da1469x_clock_sys_xtal32m_switch(); } void da1469x_clock_sys_rc32m_disable(void) { CRG_TOP->CLK_RC32M_REG &= ~CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk; } void da1469x_clock_lp_xtal32k_enable(void) { CRG_TOP->CLK_XTAL32K_REG |= CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk; } void da1469x_clock_lp_xtal32k_switch(void) { CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) | (2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos); } void da1469x_clock_pll_disable(void) { while (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk) { CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk; } CRG_XTAL->PLL_SYS_CTRL1_REG &= ~CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk; } void da1469x_clock_pll_wait_to_lock(void) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); NVIC_ClearPendingIRQ(PLL_LOCK_IRQn); if (!da1469x_clock_is_pll_locked()) { NVIC_EnableIRQ(PLL_LOCK_IRQn); while (!NVIC_GetPendingIRQ(PLL_LOCK_IRQn)) { __WFI(); } NVIC_DisableIRQ(PLL_LOCK_IRQn); } __HAL_ENABLE_INTERRUPTS(primask); } void da1469x_clock_sys_pll_switch(void) { /* CLK_SEL_Msk == 3 means PLL */ CRG_TOP->CLK_CTRL_REG |= CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk; while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk)); } ================================================ FILE: hw/mcu/dialog/da1469x/src/hal_gpio.c ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include #include #include "syscfg/syscfg.h" #include "mcu/da1469x_hal.h" #include #include "hal/hal_gpio.h" /* GPIO interrupts */ #define HAL_GPIO_MAX_IRQ MYNEWT_VAL(MCU_GPIO_MAX_IRQ) #define GPIO_REG(name) ((__IO uint32_t *)(GPIO_BASE + offsetof(GPIO_Type, name))) #define WAKEUP_REG(name) ((__IO uint32_t *)(WAKEUP_BASE + offsetof(WAKEUP_Type, name))) #define CRG_TOP_REG(name) ((__IO uint32_t *)(CRG_TOP_BASE + offsetof(CRG_TOP_Type, name))) #ifndef MCU_GPIO_PORT0_PIN_COUNT #define MCU_GPIO_PORT0_PIN_COUNT 32 #endif #if (MCU_GPIO_PORT0_PIN_COUNT) == 32 #define GPIO_PORT(pin) (((unsigned)(pin)) >> 5U) #define GPIO_PORT_PIN(pin) (((unsigned)(pin)) & 31U) #else #define GPIO_PORT(pin) (((unsigned)(pin)) < MCU_GPIO_PORT0_PIN_COUNT ? 0 : 1) #define GPIO_PORT_PIN(pin) ((unsigned)(pin) < MCU_GPIO_PORT0_PIN_COUNT ? \ (pin) : (pin) - MCU_GPIO_PORT0_PIN_COUNT) #endif #define GPIO_PIN_BIT(pin) (1 << GPIO_PORT_PIN(pin)) #define GPIO_PIN_DATA_REG_ADDR(pin) (GPIO_REG(P0_DATA_REG) + GPIO_PORT(pin)) #define GPIO_PIN_DATA_REG(pin) *GPIO_PIN_DATA_REG_ADDR(pin) #define GPIO_PIN_SET_DATA_REG_ADDR(pin) (GPIO_REG(P0_SET_DATA_REG) + GPIO_PORT(pin)) #define GPIO_PIN_SET_DATA_REG(pin) *GPIO_PIN_SET_DATA_REG_ADDR(pin) #define GPIO_PIN_RESET_DATA_REG_ADDR(pin) (GPIO_REG(P0_RESET_DATA_REG) + GPIO_PORT(pin)) #define GPIO_PIN_RESET_DATA_REG(pin) *GPIO_PIN_RESET_DATA_REG_ADDR(pin) #define GPIO_PIN_MODE_REG_ADDR(pin) (GPIO_REG(P0_00_MODE_REG) + (pin)) #define GPIO_PIN_MODE_REG(pin) *GPIO_PIN_MODE_REG_ADDR(pin) #define GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin) (GPIO_REG(P0_PADPWR_CTRL_REG) + GPIO_PORT(pin)) #define GPIO_PIN_PADPWR_CTRL_REG(pin) *GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin) #define GPIO_PIN_UNLATCH_ADDR(pin) (CRG_TOP_REG(P0_SET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3) #define GPIO_PIN_LATCH_ADDR(pin) (CRG_TOP_REG(P0_RESET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3) #define WKUP_CTRL_REG_ADDR (WAKEUP_REG(WKUP_CTRL_REG)) #define WKUP_RESET_IRQ_REG_ADDR (WAKEUP_REG(WKUP_RESET_IRQ_REG)) #define WKUP_SELECT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SELECT_P0_REG) + GPIO_PORT(pin)) #define WKUP_SELECT_PX_REG(pin) *(WKUP_SELECT_PX_REG_ADDR(pin)) #define WKUP_POL_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_POL_P0_REG) + GPIO_PORT(pin)) #define WKUP_POL_PX_SET_FALLING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) |= GPIO_PIN_BIT(pin); } while (0) #define WKUP_POL_PX_SET_RISING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) &= ~GPIO_PIN_BIT(pin); } while (0) #define WKUP_STAT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_STATUS_P0_REG) + GPIO_PORT(pin)) #define WKUP_STAT(pin) ((*(WKUP_STAT_PX_REG_ADDR(pin)) >> GPIO_PORT_PIN(pin)) & 1) #define WKUP_CLEAR_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_CLEAR_P0_REG) + GPIO_PORT(pin)) #define WKUP_CLEAR_PX(pin) do { (*(WKUP_CLEAR_PX_REG_ADDR(pin)) = GPIO_PIN_BIT(pin)); } while (0) #define WKUP_SEL_GPIO_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SEL_GPIO_P0_REG) + GPIO_PORT(pin)) #define WKUP_SEL_GPIO_PX_REG(pin) *(WKUP_SEL_GPIO_PX_REG_ADDR(pin)) /* Storage for GPIO callbacks. */ struct hal_gpio_irq { int pin; hal_gpio_irq_handler_t func; void *arg; }; static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; #if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 static uint32_t g_mcu_gpio_latch_state[2]; static uint8_t g_mcu_gpio_retained_num; static struct da1469x_retreg g_mcu_gpio_retained[MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM)]; #endif /* * We assume that any latched pin has default configuration, i.e. was either * not configured or was deinited. Any unlatched pin is considered to be used * by someone. * * By default, all pins are assumed to have default configuration and are * latched. This allows PD_COM to be disabled (if no other peripheral needs * it) since we do not need GPIO mux to be active. * * Configuration of any pin shall be done as follows, with interrupts disabled: * 1. call mcu_gpio_unlatch_prepare() to enable PD_COM if needed * 2. configure pin * 3. call mcu_gpio_unlatch() to actually unlatch pin * * Once pin is restored to default configuration it shall be latched again by * calling mcu_gpio_latch(). */ #if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 static void mcu_gpio_retained_add_port(uint32_t latch_val, volatile uint32_t *base_reg) { struct da1469x_retreg *retreg; int pin; retreg = &g_mcu_gpio_retained[g_mcu_gpio_retained_num]; while (latch_val) { assert(g_mcu_gpio_retained_num < MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM)); pin = __builtin_ctz(latch_val); latch_val &= ~(1 << pin); da1469x_retreg_assign(retreg, &base_reg[pin]); g_mcu_gpio_retained_num++; retreg++; } } #endif static void mcu_gpio_retained_refresh(void) { #if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 g_mcu_gpio_retained_num = 0; mcu_gpio_retained_add_port(CRG_TOP->P0_PAD_LATCH_REG, &GPIO->P0_00_MODE_REG); mcu_gpio_retained_add_port(CRG_TOP->P1_PAD_LATCH_REG, &GPIO->P1_00_MODE_REG); #endif } static inline void mcu_gpio_unlatch_prepare(int pin) { __HAL_ASSERT_CRITICAL(); (void)pin; /* Acquire PD_COM if first pin will be unlatched */ // if ((CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG) == 0) { // da1469x_pd_acquire(MCU_PD_DOMAIN_COM); // } } static inline void mcu_gpio_unlatch(int pin) { __HAL_ASSERT_CRITICAL(); *GPIO_PIN_UNLATCH_ADDR(pin) = GPIO_PIN_BIT(pin); mcu_gpio_retained_refresh(); } static inline void mcu_gpio_latch(int pin) { (void)pin; // uint32_t primask; // uint32_t latch_pre; // uint32_t latch_post; // // __HAL_DISABLE_INTERRUPTS(primask); // // latch_pre = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG; // // *GPIO_PIN_LATCH_ADDR(pin) = GPIO_PIN_BIT(pin); // mcu_gpio_retained_refresh(); // // latch_post = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG; // // /* Release PD_COM if last pin was latched */ // if (latch_pre && !latch_post) { // da1469x_pd_release(MCU_PD_DOMAIN_COM); // } // // __HAL_ENABLE_INTERRUPTS(primask); } int hal_gpio_init_in(int pin, hal_gpio_pull_t pull) { volatile uint32_t *px_xx_mod_reg = GPIO_PIN_MODE_REG_ADDR(pin); uint32_t regval; uint32_t primask; switch (pull) { case HAL_GPIO_PULL_UP: regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLUP; break; case HAL_GPIO_PULL_DOWN: regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLDOWN; break; case HAL_GPIO_PULL_NONE: regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT; break; default: return -1; } __HAL_DISABLE_INTERRUPTS(primask); mcu_gpio_unlatch_prepare(pin); *px_xx_mod_reg = regval; mcu_gpio_unlatch(pin); __HAL_ENABLE_INTERRUPTS(primask); return 0; } int hal_gpio_init_out(int pin, int val) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); mcu_gpio_unlatch_prepare(pin); GPIO_PIN_MODE_REG(pin) = MCU_GPIO_MODE_OUTPUT; if (val) { GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin); } else { GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); } mcu_gpio_unlatch(pin); __HAL_ENABLE_INTERRUPTS(primask); return 0; } int hal_gpio_deinit(int pin) { /* Reset mode to default value and latch pin */ GPIO_PIN_MODE_REG(pin) = 0x200; GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); mcu_gpio_latch(pin); return 0; } void hal_gpio_write(int pin, int val) { if (val) { GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin); } else { GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin); } } int hal_gpio_read(int pin) { return (GPIO_PIN_DATA_REG(pin) >> GPIO_PORT_PIN(pin)) & 1; } int hal_gpio_toggle(int pin) { int new_value = hal_gpio_read(pin) == 0; hal_gpio_write(pin, new_value); return new_value; } static void hal_gpio_irq_handler(void) { struct hal_gpio_irq *irq; uint32_t stat; int i; *WKUP_RESET_IRQ_REG_ADDR = 1; NVIC_ClearPendingIRQ(KEY_WKUP_GPIO_IRQn); for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { irq = &hal_gpio_irqs[i]; /* Read latched status value from relevant GPIO port */ stat = WKUP_STAT(irq->pin); if (irq->func && stat) { irq->func(irq->arg); } WKUP_CLEAR_PX(irq->pin); } } static void hal_gpio_irq_setup(void) { static uint8_t irq_setup; int sr; if (!irq_setup) { __HAL_DISABLE_INTERRUPTS(sr); irq_setup = 1; NVIC_ClearPendingIRQ(GPIO_P0_IRQn); NVIC_ClearPendingIRQ(GPIO_P1_IRQn); NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)hal_gpio_irq_handler); NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)hal_gpio_irq_handler); WAKEUP->WKUP_CTRL_REG = 0; WAKEUP->WKUP_CLEAR_P0_REG = 0xFFFFFFFF; WAKEUP->WKUP_CLEAR_P1_REG = 0x007FFFFF; WAKEUP->WKUP_SELECT_P0_REG = 0; WAKEUP->WKUP_SELECT_P1_REG = 0; WAKEUP->WKUP_SEL_GPIO_P0_REG = 0; WAKEUP->WKUP_SEL_GPIO_P1_REG = 0; WAKEUP->WKUP_RESET_IRQ_REG = 0; CRG_TOP->CLK_TMR_REG |= CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk; __HAL_ENABLE_INTERRUPTS(sr); NVIC_EnableIRQ(GPIO_P0_IRQn); NVIC_EnableIRQ(GPIO_P1_IRQn); } } static int hal_gpio_find_empty_slot(void) { int i; for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { if (hal_gpio_irqs[i].func == NULL) { return i; } } return -1; } int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) { int i; hal_gpio_irq_setup(); i = hal_gpio_find_empty_slot(); /* If assert failed increase syscfg value MCU_GPIO_MAX_IRQ */ assert(i >= 0); if (i < 0) { return -1; } hal_gpio_init_in(pin, pull); switch (trig) { case HAL_GPIO_TRIG_RISING: WKUP_POL_PX_SET_RISING(pin); break; case HAL_GPIO_TRIG_FALLING: WKUP_POL_PX_SET_FALLING(pin); break; case HAL_GPIO_TRIG_BOTH: /* Not supported */ default: return -1; } hal_gpio_irqs[i].pin = pin; hal_gpio_irqs[i].func = handler; hal_gpio_irqs[i].arg = arg; return 0; } void hal_gpio_irq_release(int pin) { int i; hal_gpio_irq_disable(pin); for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { if (hal_gpio_irqs[i].pin == pin && hal_gpio_irqs[i].func) { hal_gpio_irqs[i].pin = -1; hal_gpio_irqs[i].arg = NULL; hal_gpio_irqs[i].func = NULL; } } } void hal_gpio_irq_enable(int pin) { WKUP_SEL_GPIO_PX_REG(pin) |= GPIO_PIN_BIT(pin); } void hal_gpio_irq_disable(int pin) { WKUP_SEL_GPIO_PX_REG(pin) &= ~GPIO_PIN_BIT(pin); WKUP_CLEAR_PX(pin); } void mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func) { uint32_t primask; __HAL_DISABLE_INTERRUPTS(primask); mcu_gpio_unlatch_prepare(pin); GPIO_PIN_MODE_REG(pin) = (func & GPIO_P0_00_MODE_REG_PID_Msk) | (mode & (GPIO_P0_00_MODE_REG_PUPD_Msk | GPIO_P0_00_MODE_REG_PPOD_Msk)); mcu_gpio_unlatch(pin); __HAL_ENABLE_INTERRUPTS(primask); } void mcu_gpio_enter_sleep(void) { #if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 if (g_mcu_gpio_retained_num == 0) { return; } g_mcu_gpio_latch_state[0] = CRG_TOP->P0_PAD_LATCH_REG; g_mcu_gpio_latch_state[1] = CRG_TOP->P1_PAD_LATCH_REG; da1469x_retreg_update(g_mcu_gpio_retained, g_mcu_gpio_retained_num); CRG_TOP->P0_RESET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk; CRG_TOP->P1_RESET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk; da1469x_pd_release(MCU_PD_DOMAIN_COM); #endif } void mcu_gpio_exit_sleep(void) { #if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0 if (g_mcu_gpio_retained_num == 0) { return; } da1469x_pd_acquire(MCU_PD_DOMAIN_COM); da1469x_retreg_restore(g_mcu_gpio_retained, g_mcu_gpio_retained_num); /* Set pins states to their latched values */ GPIO->P0_DATA_REG = GPIO->P0_DATA_REG; GPIO->P1_DATA_REG = GPIO->P1_DATA_REG; CRG_TOP->P0_PAD_LATCH_REG = g_mcu_gpio_latch_state[0]; CRG_TOP->P1_PAD_LATCH_REG = g_mcu_gpio_latch_state[1]; #endif } ================================================ FILE: hw/mcu/dialog/da1469x/src/hal_system.c ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include #include "syscfg/syscfg.h" #include "mcu/da1469x_clock.h" #include "mcu/da1469x_lpclk.h" #include "mcu/da1469x_pd.h" #include "mcu/da1469x_pdc.h" #include "mcu/da1469x_prail.h" #include "hal/hal_system.h" #include "os/os_cputime.h" #if !MYNEWT_VAL(BOOT_LOADER) static enum hal_reset_reason g_hal_reset_reason; #endif void hal_system_init(void) { #if MYNEWT_VAL(MCU_DCDC_ENABLE) da1469x_prail_dcdc_enable(); #endif /* * RESET_STAT_REG has to be cleared to allow HW set bits during next reset * so we should read it now and keep result for application to check at any * time. This does not happen for bootloader since reading reset reason in * bootloader would prevent application from reading it. */ #if !MYNEWT_VAL(BOOT_LOADER) uint32_t reg; reg = CRG_TOP->RESET_STAT_REG; CRG_TOP->RESET_STAT_REG = 0; if (reg & CRG_TOP_RESET_STAT_REG_PORESET_STAT_Msk) { g_hal_reset_reason = HAL_RESET_POR; } else if (reg & CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Msk) { g_hal_reset_reason = HAL_RESET_WATCHDOG; } else if (reg & CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Msk) { g_hal_reset_reason = HAL_RESET_SOFT; } else if (reg & CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Msk) { g_hal_reset_reason = HAL_RESET_PIN; } else { g_hal_reset_reason = 0; } #endif } void hal_system_reset(void) { #if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) hal_system_reset_cb(); #endif while (1) { HAL_DEBUG_BREAK(); CRG_TOP->SYS_CTRL_REG = 0x20; NVIC_SystemReset(); } } int hal_debugger_connected(void) { return CRG_TOP->SYS_STAT_REG & CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Msk; } void hal_system_clock_start(void) { /* Reset clock dividers to 0 */ CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk); /* PD_TIM is already started in SystemInit */ da1469x_clock_sys_xtal32m_init(); da1469x_clock_sys_xtal32m_enable(); #if MYNEWT_VAL(MCU_PLL_ENABLE) da1469x_clock_sys_pll_enable(); #endif #if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, PLL96) da1469x_clock_pll_wait_to_lock(); da1469x_clock_sys_pll_switch(); #endif #if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, XTAL32M) /* Switch to XTAL32M and disable RC32M */ da1469x_clock_sys_xtal32m_switch_safe(); #endif da1469x_clock_sys_rc32m_disable(); #if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) /* Switch to RCX and calibrate it */ da1469x_clock_lp_rcx_enable(); da1469x_clock_lp_rcx_switch(); da1469x_clock_lp_rcx_calibrate(); da1469x_lpclk_enabled(); #else /* * We cannot switch lp_clk to XTAL32K here since it needs some time to * settle, so we just disable RCX (we don't need it) and then we'll handle * switch to XTAL32K from sysinit since we need os_cputime for this. */ da1469x_clock_lp_rcx_disable(); #endif } enum hal_reset_reason hal_reset_cause(void) { #if MYNEWT_VAL(BOOT_LOADER) return 0; #else return g_hal_reset_reason; #endif } ================================================ FILE: hw/mcu/dialog/da1469x/src/hal_system_start.c ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include #include #include "mcu/mcu.h" #include "mcu/da1469x_hal.h" #include #include #if MCUBOOT_MYNEWT #include "bootutil/bootutil.h" #include "bootutil/image.h" #include "bootutil/bootutil_log.h" #include "mcu/da1469x_dma.h" #include "mcu/da1469x_otp.h" #endif #if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT sec_text_ram_core #endif void __attribute__((naked)) hal_system_start(void *img_start) { uint32_t img_data_addr; uint32_t *img_data; img_data_addr = MCU_MEM_QSPIF_M_START_ADDRESS + (uint32_t)img_start; assert(img_data_addr < MCU_MEM_QSPIF_M_END_ADDRESS); img_data = (uint32_t *)img_data_addr; asm volatile (".syntax unified \n" /* 1st word is stack pointer */ " msr msp, %0 \n" /* 2nd word is a reset handler (image entry) */ " bx %1 \n" : /* no output */ : "r" (img_data[0]), "r" (img_data[1])); } void hal_system_restart(void *img_start) { uint32_t primask __attribute__((unused)); int i; /* * Disable interrupts, and leave them disabled. * They get re-enabled when system starts coming back again. */ __HAL_DISABLE_INTERRUPTS(primask); for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { NVIC->ICER[i] = 0xffffffff; } hal_system_start(img_start); } #if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT #define IMAGE_TLV_AES_NONCE 0x50 #define IMAGE_TLV_SECRET_ID 0x60 sec_text_ram_core void boot_custom_start(uintptr_t flash_base, struct boot_rsp *rsp) { int rc; struct image_tlv_iter it; const struct flash_area *fap; uint32_t off; uint16_t len; uint16_t type; uint8_t buf[8]; uint8_t key; uint32_t nonce[2]; bool has_aes_nonce; bool has_secret_id; DMA_Type *dma_regs = DMA; uint32_t jump_offset = rsp->br_image_off + rsp->br_hdr->ih_hdr_size; BOOT_LOG_INF("Custom initialization"); /* skip to booting if we are running nonsecure mode */ if (!(CRG_TOP->SECURE_BOOT_REG & 0x1)) { hal_system_start((void *)(flash_base + jump_offset)); } rc = flash_area_open(flash_area_id_from_image_slot(0), &fap); assert(rc == 0); rc = bootutil_tlv_iter_begin(&it, rsp->br_hdr, fap, IMAGE_TLV_ANY, true); assert(rc == 0); has_aes_nonce = has_secret_id = false; while (true) { rc = bootutil_tlv_iter_next(&it, &off, &len, &type); assert(rc >= 0); if (rc > 0) { break; } if (type == IMAGE_TLV_AES_NONCE) { assert(len == 8); rc = flash_area_read(fap, off, buf, len); assert(rc == 0); nonce[0] = __builtin_bswap32(*(uint32_t *)buf); nonce[1] = __builtin_bswap32(*(uint32_t *)(buf + 4)); has_aes_nonce = true; } else if (type == IMAGE_TLV_SECRET_ID) { assert(len == 4); rc = flash_area_read(fap, off, buf, len); assert(rc == 0); key = buf[0]; has_secret_id = true; } } assert(has_aes_nonce && has_secret_id && key <= 7); /* enable OTP clock and set in read mode */ da1469x_clock_amba_enable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk); da1469x_otp_set_mode(OTPC_MODE_READ); /* disable decrypt on the fly and program start and end addresses */ QSPIC->QSPIC_CTR_CTRL_REG = 0; QSPIC->QSPIC_CTR_SADDR_REG = jump_offset; QSPIC->QSPIC_CTR_EADDR_REG = QSPIC->QSPIC_CTR_SADDR_REG + rsp->br_hdr->ih_img_size - 1; /* securely DMA hardware key from secret storage to QSPI decrypt engine */ dma_regs->DMA_REQ_MUX_REG |= 0xf000; dma_regs->DMA7_LEN_REG = 8; dma_regs->DMA7_A_START_REG = MCU_OTPM_BASE + OTP_SEGMENT_QSPI_FW_KEYS + (32 * key); dma_regs->DMA7_B_START_REG = (uint32_t)&QSPIC->QSPIC_CTR_KEY_0_3_REG; dma_regs->DMA7_CTRL_REG = DMA_DMA7_CTRL_REG_AINC_Msk | DMA_DMA7_CTRL_REG_BINC_Msk | (MCU_DMA_BUS_WIDTH_4B << DMA_DMA7_CTRL_REG_BW_Pos) | DMA_DMA7_CTRL_REG_DMA_ON_Msk; while (dma_regs->DMA7_IDX_REG != 8); /* program NONCE */ QSPIC->QSPIC_CTR_NONCE_0_3_REG = nonce[0]; QSPIC->QSPIC_CTR_NONCE_4_7_REG = nonce[1]; /* turn back on decrypt on the fly */ QSPIC->QSPIC_CTR_CTRL_REG = 1; /* set OTP to standby and turn off clock */ da1469x_otp_set_mode(OTPC_MODE_STBY); da1469x_clock_amba_disable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk); hal_system_start((void *)(flash_base + jump_offset)); } #endif ================================================ FILE: hw/mcu/dialog/da1469x/src/system_da1469x.c ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "mcu/mcu.h" #include extern uint8_t __StackLimit; uint32_t SystemCoreClock = 32000000; void SystemInit(void) { /* Enable FPU when using hard-float */ #if (__FPU_USED == 1) SCB->CPACR |= (3UL << 20) | (3UL << 22); __DSB(); __ISB(); #endif /* Freeze watchdog */ GPREG->SET_FREEZE_REG |= GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk; /* Initialize power domains (disable radio only) */ CRG_TOP->PMU_CTRL_REG = CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk; CRG_TOP->P0_SET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk; CRG_TOP->P1_SET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk; /* Reset clock dividers to 0 */ CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk); /* PD_TIM is already started in SystemInit */ da1469x_clock_sys_xtal32m_init(); da1469x_clock_sys_xtal32m_enable(); da1469x_clock_sys_pll_enable(); da1469x_clock_pll_wait_to_lock(); /* Switch to XTAL32M and disable RC32M */ da1469x_clock_sys_xtal32m_switch_safe(); da1469x_clock_sys_rc32m_disable(); } void _init(void) { } ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble.h ================================================ /* * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_COMMON BLE SoftDevice Common @{ @defgroup ble_api Events, type definitions and API calls @{ @brief Module independent events, type definitions and API calls for the BLE SoftDevice. */ #ifndef BLE_H__ #define BLE_H__ #include #include "nrf_svc.h" #include "nrf_error.h" #include "ble_err.h" #include "ble_gap.h" #include "ble_l2cap.h" #include "ble_gatt.h" #include "ble_gattc.h" #include "ble_gatts.h" #ifdef __cplusplus extern "C" { #endif /** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations * @{ */ /** * @brief Common API SVC numbers. */ enum BLE_COMMON_SVCS { SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific base UUID. */ SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ SD_BLE_OPT_SET, /**< Set a BLE option. */ SD_BLE_OPT_GET, /**< Get a BLE option. */ SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ SD_BLE_UUID_VS_REMOVE, /**< Remove a Vendor Specific base UUID. */ }; /** * @brief BLE Module Independent Event IDs. */ enum BLE_COMMON_EVTS { BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */ BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */ }; /**@brief BLE Connection Configuration IDs. * * IDs that uniquely identify a connection configuration. */ enum BLE_CONN_CFGS { BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */ BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */ BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */ BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */ BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */ }; /**@brief BLE Common Configuration IDs. * * IDs that uniquely identify a common configuration. */ enum BLE_COMMON_CFGS { BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific base UUID configuration */ }; /**@brief Common Option IDs. * IDs that uniquely identify a common option. */ enum BLE_COMMON_OPTS { BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */ BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */ BLE_COMMON_OPT_EXTENDED_RC_CAL = BLE_OPT_BASE + 2, /**< Extended RC calibration option */ BLE_COMMON_OPT_ADV_SCHED_CFG = BLE_OPT_BASE + 3, /**< Advertiser role scheduling configuration option */ }; /** @} */ /** @addtogroup BLE_COMMON_DEFINES Defines * @{ */ /** @brief Required pointer alignment for BLE Events. */ #define BLE_EVT_PTR_ALIGNMENT 4 /** @brief Leaves the maximum of the two arguments. */ #define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) /** @brief Maximum possible length for BLE Events. * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. */ #define BLE_EVT_LEN_MAX(ATT_MTU) ( \ offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \ ) /** @defgroup ADV_SCHED_CFG Advertiser Role Scheduling Configuration * @{ */ #define ADV_SCHED_CFG_DEFAULT 0 /**< Default advertiser role scheduling configuration. */ #define ADV_SCHED_CFG_IMPROVED 1 /**< Improved advertiser role scheduling configuration in which the housekeeping time is reduced. */ /** @} */ /** @defgroup BLE_USER_MEM_TYPES User Memory Types * @{ */ #define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ #define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ /** @} */ /** @defgroup BLE_UUID_VS_COUNTS Vendor Specific base UUID counts * @{ */ #define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ #define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ /** @} */ /** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. * @{ */ #define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ /** @} */ /** @} */ /** @addtogroup BLE_COMMON_STRUCTURES Structures * @{ */ /**@brief User Memory Block. */ typedef struct { uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ uint16_t len; /**< Length in bytes of the user memory block. */ } ble_user_mem_block_t; /**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ typedef struct { uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ } ble_evt_user_mem_request_t; /**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ typedef struct { uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ ble_user_mem_block_t mem_block; /**< User memory block */ } ble_evt_user_mem_release_t; /**@brief Event structure for events not associated with a specific function module. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ union { ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ } params; /**< Event parameter union. */ } ble_common_evt_t; /**@brief BLE Event header. */ typedef struct { uint16_t evt_id; /**< Value from a BLE__EVT series. */ uint16_t evt_len; /**< Length in octets including this header. */ } ble_evt_hdr_t; /**@brief Common BLE Event type, wrapping the module specific event reports. */ typedef struct { ble_evt_hdr_t header; /**< Event header. */ union { ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ } evt; /**< Event union. */ } ble_evt_t; /** * @brief Version Information. */ typedef struct { uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ } ble_version_t; /** * @brief Configuration parameters for the PA and LNA. */ typedef struct { uint8_t enable :1; /**< Enable toggling for this amplifier */ uint8_t active_high :1; /**< Set the pin to be active high */ uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ } ble_pa_lna_cfg_t; /** * @brief PA & LNA GPIO toggle configuration * * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or * a low noise amplifier. * * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. * * @note @ref sd_ble_opt_get is not supported for this option. * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences * and must be avoided by the application. */ typedef struct { ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ } ble_common_opt_pa_lna_t; /** * @brief Configuration of extended BLE connection events. * * When enabled the SoftDevice will dynamically extend the connection event when possible. * * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, * and if there are no conflicts with other BLE roles requesting radio time. * * @note @ref sd_ble_opt_get is not supported for this option. */ typedef struct { uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ } ble_common_opt_conn_evt_ext_t; /** * @brief Enable/disable extended RC calibration. * * If extended RC calibration is enabled and the internal RC oscillator (@ref NRF_CLOCK_LF_SRC_RC) is used as the SoftDevice * LFCLK source, the SoftDevice as a peripheral will by default try to increase the receive window if two consecutive packets * are not received. If it turns out that the packets were not received due to clock drift, the RC calibration is started. * This calibration comes in addition to the periodic calibration that is configured by @ref sd_softdevice_enable(). When * using only peripheral connections, the periodic calibration can therefore be configured with a much longer interval as the * peripheral will be able to detect and adjust automatically to clock drift, and calibrate on demand. * * If extended RC calibration is disabled and the internal RC oscillator is used as the SoftDevice LFCLK source, the * RC oscillator is calibrated periodically as configured by @ref sd_softdevice_enable(). * * @note @ref sd_ble_opt_get is not supported for this option. */ typedef struct { uint8_t enable : 1; /**< Enable extended RC calibration, enabled by default. */ } ble_common_opt_extended_rc_cal_t; /** * @brief Configuration of BLE advertiser role scheduling. * * @note @ref sd_ble_opt_get is not supported for this option. */ typedef struct { uint8_t sched_cfg; /**< See @ref ADV_SCHED_CFG. */ } ble_common_opt_adv_sched_cfg_t; /**@brief Option structure for common options. */ typedef union { ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ ble_common_opt_extended_rc_cal_t extended_rc_cal; /**< Parameters for enabling extended RC calibration. */ ble_common_opt_adv_sched_cfg_t adv_sched_cfg; /**< Parameters for configuring advertiser role scheduling. */ } ble_common_opt_t; /**@brief Common BLE Option type, wrapping the module specific options. */ typedef union { ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ } ble_opt_t; /**@brief BLE connection configuration type, wrapping the module specific configurations, set with * @ref sd_ble_cfg_set. * * @note Connection configurations don't have to be set. * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, * the default connection configuration will be automatically added for the remaining connections. * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in * place of @ref ble_conn_cfg_t::conn_cfg_tag. * * @sa sd_ble_gap_adv_start() * @sa sd_ble_gap_connect() * * @mscs * @mmsc{@ref BLE_CONN_CFG} * @endmscs */ typedef struct { uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls to select this configuration when creating a connection. Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ union { ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ } params; /**< Connection configuration union. */ } ble_conn_cfg_t; /** * @brief Configuration of Vendor Specific base UUIDs, set with @ref sd_ble_cfg_set. * * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. */ typedef struct { uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific base UUID bases to allocate memory for. Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is @ref BLE_UUID_VS_COUNT_MAX. */ } ble_common_cfg_vs_uuid_t; /**@brief Common BLE Configuration type, wrapping the common configurations. */ typedef union { ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor Specific base UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ } ble_common_cfg_t; /**@brief BLE Configuration type, wrapping the module specific configurations. */ typedef union { ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ } ble_cfg_t; /** @} */ /** @addtogroup BLE_COMMON_FUNCTIONS Functions * @{ */ /**@brief Enable the BLE stack * * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the * application RAM region (APP_RAM_BASE). On return, this will * contain the minimum start address of the application RAM region * required by the SoftDevice for this configuration. * * @note The memory requirement for a specific configuration will not increase between SoftDevices * with the same major version number. * * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between * APP_RAM_BASE and the start of the call stack. * * @details This call initializes the BLE stack, no BLE related function other than @ref * sd_ble_cfg_set can be called before this one. * * @mscs * @mmsc{@ref BLE_COMMON_ENABLE} * @endmscs * * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. * @retval ::NRF_ERROR_NO_MEM One or more of the following is true: * - The amount of memory assigned to the SoftDevice by *p_app_ram_base is not * large enough to fit this configuration's memory requirement. Check *p_app_ram_base * and set the start address of the application RAM region accordingly. * - Dynamic part of the SoftDevice RAM region is larger then 64 kB which * is currently not supported. * @retval ::NRF_ERROR_RESOURCES The total number of L2CAP Channels configured using @ref sd_ble_cfg_set is too large. */ SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); /**@brief Add configurations for the BLE stack * * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). * See @ref sd_ble_enable for details about APP_RAM_BASE. * * @note The memory requirement for a specific configuration will not increase between SoftDevices * with the same major version number. * * @note If a configuration is set more than once, the last one set is the one that takes effect on * @ref sd_ble_enable. * * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default * configuration. * * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref * sd_ble_enable). * * @note Error codes for the configurations are described in the configuration structs. * * @mscs * @mmsc{@ref BLE_COMMON_ENABLE} * @endmscs * * @retval ::NRF_SUCCESS The configuration has been added successfully. * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not * large enough to fit this configuration's memory requirement. */ SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); /**@brief Get an event from the pending events queue. * * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. * The buffer should be interpreted as a @ref ble_evt_t struct. * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. * * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. * The application is free to choose whether to call this function from thread mode (main context) or directly from the * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so * could potentially leave events in the internal queue without the application being aware of this fact. * * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: * * \code * uint16_t len; * errcode = sd_ble_evt_get(NULL, &len); * \endcode * * @mscs * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} * @endmscs * * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. */ SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); /**@brief Add a Vendor Specific base UUID. * * @details This call enables the application to add a Vendor Specific base UUID to the BLE stack's table, for later * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. * * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by * the 16-bit uuid field in @ref ble_uuid_t. * * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in * p_uuid_type along with an @ref NRF_SUCCESS error code. * * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific base UUID disregarding * bytes 12 and 13. * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. * * @retval ::NRF_SUCCESS Successfully added the Vendor Specific base UUID. * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. */ SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); /**@brief Remove a Vendor Specific base UUID. * * @details This call removes a Vendor Specific base UUID that has been added with @ref sd_ble_uuid_vs_add. This function allows * the application to reuse memory allocated for Vendor Specific base UUIDs. * * @note Currently this function can only be called with a p_uuid_type set to @ref BLE_UUID_TYPE_UNKNOWN or the last added UUID type. * * @param[in] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t::type corresponds to the UUID type that * shall be removed. If the type is set to @ref BLE_UUID_TYPE_UNKNOWN, or the pointer is NULL, the last * Vendor Specific base UUID will be removed. * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponds to the UUID type that was * removed. If function returns with a failure, it contains the last type that is in use by the ATT Server. * * @retval ::NRF_SUCCESS Successfully removed the Vendor Specific base UUID. * @retval ::NRF_ERROR_INVALID_ADDR If p_uuid_type is invalid. * @retval ::NRF_ERROR_INVALID_PARAM If p_uuid_type points to a non-valid UUID type. * @retval ::NRF_ERROR_FORBIDDEN If the Vendor Specific base UUID is in use by the ATT Server. */ SVCALL(SD_BLE_UUID_VS_REMOVE, uint32_t, sd_ble_uuid_vs_remove(uint8_t *p_uuid_type)); /** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. * * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared * to the corresponding ones in each entry of the table of Vendor Specific base UUIDs populated with @ref sd_ble_uuid_vs_add * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. * * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. * * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. * * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. */ SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); /** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). * * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. * * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. * * @retval ::NRF_SUCCESS Successfully encoded into the buffer. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. */ SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); /**@brief Get Version Information. * * @details This call allows the application to get the BLE stack version information. * * @param[out] p_version Pointer to a ble_version_t structure to be filled in. * * @retval ::NRF_SUCCESS Version information stored successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). */ SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); /**@brief Provide a user memory block. * * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. * * @param[in] conn_handle Connection handle. * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. * * @mscs * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} * @endmscs * * @retval ::NRF_SUCCESS Successfully queued a response to the peer. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. */ SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); /**@brief Set a BLE option. * * @details This call allows the application to set the value of an option. * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} * @endmscs * * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. * * @retval ::NRF_SUCCESS Option set successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. */ SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); /**@brief Get a BLE option. * * @details This call allows the application to retrieve the value of an option. * * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. * * @retval ::NRF_SUCCESS Option retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. * */ SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); /** @} */ #ifdef __cplusplus } #endif #endif /* BLE_H__ */ /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_err.h ================================================ /* * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_COMMON @{ @addtogroup nrf_error @{ @ingroup BLE_COMMON @} @defgroup ble_err General error codes @{ @brief General error code definitions for the BLE API. @ingroup BLE_COMMON */ #ifndef NRF_BLE_ERR_H__ #define NRF_BLE_ERR_H__ #include "nrf_error.h" #ifdef __cplusplus extern "C" { #endif /* @defgroup BLE_ERRORS Error Codes * @{ */ #define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ #define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ #define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ #define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */ #define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ #define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ /** @} */ /** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges * @brief Assignment of subranges for module specific error codes. * @note For specific error codes, see ble_.h or ble_error_.h. * @{ */ #define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ #define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ #define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ #define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ /** @} */ #ifdef __cplusplus } #endif #endif /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gap.h ================================================ /* * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_GAP Generic Access Profile (GAP) @{ @brief Definitions and prototypes for the GAP interface. */ #ifndef BLE_GAP_H__ #define BLE_GAP_H__ #include #include "nrf_svc.h" #include "nrf_error.h" #include "ble_hci.h" #include "ble_ranges.h" #include "ble_types.h" #include "ble_err.h" #ifdef __cplusplus extern "C" { #endif /**@addtogroup BLE_GAP_ENUMERATIONS Enumerations * @{ */ /**@brief GAP API SVC numbers. */ enum BLE_GAP_SVCS { SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */ SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */ SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */ SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/ SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/ SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */ SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */ SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */ SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */ SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */ SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */ SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */ SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */ SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */ SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */ SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */ SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */ SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */ SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */ SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */ SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */ SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */ SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */ SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */ SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */ SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */ SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */ SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */ SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */ SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */ SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */ SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */ SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */ SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */ SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */ SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */ SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */ SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */ SD_BLE_GAP_ADV_ADDR_GET = BLE_GAP_SVC_BASE + 39, /**< Get the Address used on air while Advertising. */ }; /**@brief GAP Event IDs. * IDs that uniquely identify an event coming from the stack to the application. */ enum BLE_GAP_EVTS { BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connected to peer. \n See @ref ble_gap_evt_connected_t */ BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ BLE_GAP_EVT_ADV_REPORT = BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */ BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ BLE_GAP_EVT_DATA_LENGTH_UPDATE = BLE_GAP_EVT_BASE + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = BLE_GAP_EVT_BASE + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */ BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */ }; /**@brief GAP Option IDs. * IDs that uniquely identify a GAP option. */ enum BLE_GAP_OPTS { BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */ BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ }; /**@brief GAP Configuration IDs. * * IDs that uniquely identify a GAP configuration. */ enum BLE_GAP_CFGS { BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */ }; /**@brief GAP TX Power roles. */ enum BLE_GAP_TX_POWER_ROLES { BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */ BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */ BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */ }; /** @} */ /**@addtogroup BLE_GAP_DEFINES Defines * @{ */ /**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP * @{ */ #define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ #define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ #define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ #define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ #define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ #define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ /**@} */ /**@defgroup BLE_GAP_ROLES GAP Roles * @{ */ #define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ #define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ #define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ /**@} */ /**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources * @{ */ #define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ #define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ #define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ /**@} */ /**@defgroup BLE_GAP_ADDR_TYPES GAP Address types * @{ */ #define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ #define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ #define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ #define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ #define BLE_GAP_ADDR_TYPE_ANONYMOUS 0x7F /**< An advertiser may advertise without its address. This type of advertising is called anonymous. */ /**@} */ /**@brief The default interval in seconds at which a private address is refreshed. */ #define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ /**@brief The maximum interval in seconds at which a private address can be refreshed. */ #define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ /** @brief BLE address length. */ #define BLE_GAP_ADDR_LEN (6) /**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes * @{ */ #define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ #define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ #define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address, and will not accept a peer using identity address as sender address when the peer IRK is exchanged, non-zero and added to the identity list. */ /**@} */ /** @brief Invalid power level. */ #define BLE_GAP_POWER_LEVEL_INVALID 127 /** @brief Advertising set handle not set. */ #define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF) /** @brief The default number of advertising sets. */ #define BLE_GAP_ADV_SET_COUNT_DEFAULT (1) /** @brief The maximum number of advertising sets supported by this SoftDevice. */ #define BLE_GAP_ADV_SET_COUNT_MAX (1) /**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes. * @{ */ #define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. If more advertising data is required, use extended advertising instead. */ #define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for an extended advertising set. */ #define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED (238) /**< Maximum supported data length for an extended connectable advertising set. */ /**@}. */ /** @brief Set ID not available in advertising report. */ #define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF /**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons * @{ */ #define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */ #define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */ /**@} */ /**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm * @{ */ #define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ #define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ #define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ #define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ #define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ #define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ #define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ #define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ #define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ #define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ #define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ #define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ #define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ #define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ #define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ /**@} */ /**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags * @{ */ #define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ #define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ #define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ #define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ #define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ #define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ #define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ /**@} */ /**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min * @{ */ #define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ #define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ /**@} */ /**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min * @{ */ #define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ #define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */ /** @} */ /**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min * @{ */ #define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ #define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */ /** @} */ /**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min * @{ */ #define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */ #define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */ /** @} */ /**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size * * Scan buffers are used for storing advertising data received from an advertiser. * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length. * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN. * @{ */ #define BLE_GAP_SCAN_BUFFER_MIN (31) /**< Minimum data length for an advertising set. */ #define BLE_GAP_SCAN_BUFFER_MAX (31) /**< Maximum data length for an advertising set. */ #define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN (255) /**< Minimum data length for an extended advertising set. */ #define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX (1650) /**< Maximum data length for an extended advertising set. */ #define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for an extended advertising set. */ /** @} */ /**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types * * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2. * * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX. * The maximum supported data length for an extended advertiser is defined by * @ref BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * Note that some of the advertising types do not support advertising data. Non-scannable types do not support * scan response data. * * @{ */ #define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected advertising events. */ #define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising events. Advertising interval is less that 3.75 ms. Use this type for fast reconnections. @note Advertising data is not supported. */ #define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising events. @note Advertising data is not supported. */ #define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected advertising events. */ #define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected advertising events. */ #define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED 0x06 /**< Connectable non-scannable undirected advertising events using extended advertising PDUs. */ #define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED 0x07 /**< Connectable non-scannable directed advertising events using extended advertising PDUs. */ #define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x08 /**< Non-connectable scannable undirected advertising events using extended advertising PDUs. @note Only scan response data is supported. */ #define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED 0x09 /**< Non-connectable scannable directed advertising events using extended advertising PDUs. @note Only scan response data is supported. */ #define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x0A /**< Non-connectable non-scannable undirected advertising events using extended advertising PDUs. */ #define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED 0x0B /**< Non-connectable non-scannable directed advertising events using extended advertising PDUs. */ /**@} */ /**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies * @{ */ #define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ #define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ #define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ #define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ /**@} */ /**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status * @{ */ #define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */ #define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA 0x01 /**< More data to be received. @note This value will only be used if @ref ble_gap_scan_params_t::report_incomplete_evts and @ref ble_gap_adv_report_type_t::extended_pdu are set to true. */ #define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED 0x02 /**< Incomplete data. Buffer size insufficient to receive more. @note This value will only be used if @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ #define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED 0x03 /**< Failed to receive the remaining data. @note This value will only be used if @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ /**@} */ /**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies * @{ */ #define BLE_GAP_SCAN_FP_ACCEPT_ALL 0x00 /**< Accept all advertising packets except directed advertising packets not addressed to this device. */ #define BLE_GAP_SCAN_FP_WHITELIST 0x01 /**< Accept advertising packets from devices in the whitelist except directed packets not addressed to this device. */ #define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL. In addition, accept directed advertising packets, where the advertiser's address is a resolvable private address that cannot be resolved. */ #define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST. In addition, accept directed advertising packets, where the advertiser's address is a resolvable private address that cannot be resolved. */ /**@} */ /**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units * @{ */ #define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */ #define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */ #define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */ /**@} */ /**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes * @{ */ #define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ #define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ #define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ /**@} */ /**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities * @{ */ #define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ #define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ #define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ #define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ #define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ /**@} */ /**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types * @{ */ #define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ #define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ #define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ /**@} */ /**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types * @{ */ #define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ #define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ #define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ #define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ #define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ /**@} */ /**@defgroup BLE_GAP_SEC_STATUS GAP Security status * @{ */ #define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ #define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ #define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ #define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ #define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ #define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ #define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ #define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ #define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ #define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ #define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ #define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ #define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ #define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ #define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ #define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ #define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ #define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ #define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ #define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ #define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ /**@} */ /**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources * @{ */ #define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ #define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ /**@} */ /**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits * @{ */ #define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ #define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ #define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ #define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ #define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ #define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ #define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ /**@} */ /**@defgroup BLE_GAP_DEVNAME GAP device name defines. * @{ */ #define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ #define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ #define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ /**@} */ /**@brief Disable RSSI events for connections */ #define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF /**@defgroup BLE_GAP_PHYS GAP PHYs * @{ */ #define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ #define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ #define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ #define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ #define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */ /**@brief Supported PHYs in connections, for scanning, and for advertising. */ #define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_CODED) /**< All PHYs are supported. */ /**@} */ /**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters * * See @ref ble_gap_conn_sec_mode_t. * @{ */ /**@brief Set sec_mode pointed to by ptr to have no access rights.*/ #define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) /**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ #define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ #define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ #define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) /**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ #define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ #define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ #define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) /**@} */ /**@brief GAP Security Random Number Length. */ #define BLE_GAP_SEC_RAND_LEN 8 /**@brief GAP Security Key Length. */ #define BLE_GAP_SEC_KEY_LEN 16 /**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ #define BLE_GAP_LESC_P256_PK_LEN 64 /**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ #define BLE_GAP_LESC_DHKEY_LEN 32 /**@brief GAP Passkey Length. */ #define BLE_GAP_PASSKEY_LEN 6 /**@brief Maximum amount of addresses in the whitelist. */ #define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) /**@brief Maximum amount of identities in the device identities list. */ #define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) /**@brief Default connection count for a configuration. */ #define BLE_GAP_CONN_COUNT_DEFAULT (1) /**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. * @{ */ #define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ #define BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN (6) /**< The shortest event length in 1.25 ms units supporting LE Coded PHY. */ #define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ /**@} */ /**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. * @{ */ #define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ #define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ #define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ #define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ /**@} */ /**@brief Automatic data length parameter. */ #define BLE_GAP_DATA_LENGTH_AUTO 0 /**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. * @{ */ #define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ #define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ /**@} */ /**@defgroup GAP_SEC_MODES GAP Security Modes * @{ */ #define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ /**@} */ /**@brief The total number of channels in Bluetooth Low Energy. */ #define BLE_GAP_CHANNEL_COUNT (40) /**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines * @{ */ #define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */ #define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */ #define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */ /**@} */ /** @} */ /**@addtogroup BLE_GAP_STRUCTURES Structures * @{ */ /**@brief Advertising event properties. */ typedef struct { uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */ uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs. @note Anonymous advertising is only available for @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */ uint8_t include_tx_power : 1; /**< This feature is not supported on this SoftDevice. */ } ble_gap_adv_properties_t; /**@brief Advertising report type. */ typedef struct { uint16_t connectable : 1; /**< Connectable advertising event type. */ uint16_t scannable : 1; /**< Scannable advertising event type. */ uint16_t directed : 1; /**< Directed advertising event type. */ uint16_t scan_response : 1; /**< Received a scan response. */ uint16_t extended_pdu : 1; /**< Received an extended advertising set. */ uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */ uint16_t reserved : 9; /**< Reserved for future use. */ } ble_gap_adv_report_type_t; /**@brief Advertising Auxiliary Pointer. */ typedef struct { uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */ uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */ } ble_gap_aux_pointer_t; /**@brief Bluetooth Low Energy address. */ typedef struct { uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. This bit is set by the SoftDevice to indicate whether the address has been resolved from a Resolvable Private Address (when the peer is using privacy). If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address. This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. */ uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. @ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */ } ble_gap_addr_t; /**@brief GAP connection parameters. * * @note When ble_conn_params_t is received in an event, both min_conn_interval and * max_conn_interval will be equal to the connection interval set by the central. * * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval * that corresponds to the following Bluetooth Spec requirement: * The Supervision_Timeout in milliseconds shall be larger than * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. */ typedef struct { uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ } ble_gap_conn_params_t; /**@brief GAP connection security modes. * * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n * Security Mode 1 Level 1: No security is needed (aka open link).\n * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n * Security Mode 1 Level 3: MITM protected encrypted link required.\n * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n */ typedef struct { uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ } ble_gap_conn_sec_mode_t; /**@brief GAP connection security status.*/ typedef struct { ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ } ble_gap_conn_sec_t; /**@brief Identity Resolving Key. */ typedef struct { uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ } ble_gap_irk_t; /**@brief Channel mask (40 bits). * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0, * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents * channel index 39. If a bit is set to 1, the channel is not used. */ typedef uint8_t ble_gap_ch_mask_t[5]; /**@brief GAP advertising parameters. */ typedef struct { ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */ ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. @note ble_gap_addr_t::addr_type cannot be @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. - When privacy is enabled and the local device uses @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertising packet. - If @ref ble_gap_adv_properties_t::type is directed, this must be set to the targeted scanner or initiator. If the peer address is in the device identity list, the peer IRK for that device will be used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE target addresses used in the advertising event PDUs. */ uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS. @note If @ref ble_gap_adv_properties_t::type is set to @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE advertising, this parameter is ignored. */ uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached, an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. @sa BLE_GAP_ADV_TIMEOUT_VALUES. @note The SoftDevice will always complete at least one advertising event even if the duration is set too low. */ uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling advertising. Setting the value to 0 disables the limitation. When the count of advertising events specified by this parameter (if not 0) is reached, advertising will be automatically stopped and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised @note If @ref ble_gap_adv_properties_t::type is set to @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE, this parameter is ignored. */ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. At least one of the primary channels, that is channel index 37-39, must be used. Masking away secondary advertising channels is not supported. */ uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used. Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED. @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used. Valid values are @ref BLE_GAP_PHY_1MBPS, @ref BLE_GAP_PHY_2MBPS, and @ref BLE_GAP_PHY_CODED. If @ref ble_gap_adv_properties_t::type is an extended advertising type and connectable, this is the PHY that will be used to establish a connection and send AUX_ADV_IND packets on. @note This parameter will be ignored when @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ uint8_t set_id:4; /**< The advertising set identifier distinguishes this advertising set from other advertising sets transmitted by this and other devices. @note This parameter will be ignored when @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a scan request is received and the scanner address is allowed by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised. @note This parameter will be ignored when @ref ble_gap_adv_properties_t::type is a non-scannable advertising type. */ } ble_gap_adv_params_t; /**@brief GAP advertising data buffers. * * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and * shall never be modified while advertising. The data shall be kept alive until either: * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding * advertising handle. * - Advertising is stopped. * - Advertising data is changed. * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */ typedef struct { ble_data_t adv_data; /**< Advertising data. @note Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type that is allowed to contain advertising data. */ ble_data_t scan_rsp_data; /**< Scan response data. @note Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type that is scannable. */ } ble_gap_adv_data_t; /**@brief GAP scanning parameters. */ typedef struct { uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets. If set to 0, the scanner will not receive advertising packets on secondary advertising channels, and will not be able to receive long advertising PDUs. */ uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have @ref ble_gap_adv_report_type_t::status set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. This parameter is ignored when used with @ref sd_ble_gap_connect @note This may be used to abort receiving more packets from an extended advertising event, and is only available for extended scanning, see @ref sd_ble_gap_scan_start. @note This feature is not supported by this SoftDevice. */ uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests. This parameter is ignored when used with @ref sd_ble_gap_connect. */ uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES. @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with @ref sd_ble_gap_connect */ uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO, scan_phys will default to @ref BLE_GAP_PHY_1MBPS. - If @ref ble_gap_scan_params_t::extended is set to 0, the only supported PHY is @ref BLE_GAP_PHY_1MBPS. - When used with @ref sd_ble_gap_scan_start, the bitfield indicates the PHYs the scanner will use for scanning on primary advertising channels. The scanner will accept @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs. - When used with @ref sd_ble_gap_connect, the bitfield indicates the PHYs the initiator will use for scanning on primary advertising channels. The initiator will accept connections initiated on either of the @ref BLE_GAP_PHYS_SUPPORTED PHYs. If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS, the primary scan PHY is @ref BLE_GAP_PHY_1MBPS. If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scan PHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is @ref BLE_GAP_PHY_CODED, the primary scan PHY is @ref BLE_GAP_PHY_CODED only. */ uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */ uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. If scan_phys contains both @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED interval shall be larger than or equal to twice the scan window. */ uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. At least one of the primary channels, that is channel index 37-39, must be set to 0. Masking away secondary channels is not supported. */ } ble_gap_scan_params_t; /**@brief Privacy. * * The privacy feature provides a way for the device to avoid being tracked over a period of time. * The privacy feature, when enabled, hides the local device identity and replaces it with a private address * that is automatically refreshed at a specified interval. * * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, * and devices can establish connections without revealing their real identities. * * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) * are supported. * * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. */ typedef struct { uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ } ble_gap_privacy_params_t; /**@brief PHY preferences for TX and RX * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction. * @code * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; * @endcode * */ typedef struct { uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ } ble_gap_phys_t; /** @brief Keys that can be exchanged during a bonding procedure. */ typedef struct { uint8_t enc : 1; /**< Long Term Key and Master Identification. */ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ uint8_t sign : 1; /**< Connection Signature Resolving Key. */ uint8_t link : 1; /**< Derive the Link Key from the LTK. */ } ble_gap_sec_kdist_t; /**@brief GAP security parameters. */ typedef struct { uint8_t bond : 1; /**< Perform bonding. */ uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ uint8_t oob : 1; /**< The OOB data flag. - In LE legacy pairing, this flag is set if a device has out of band authentication data. The OOB method is used if both of the devices have out of band authentication data. - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. The OOB method is used if at least one device has the peer device's OOB data available. */ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ } ble_gap_sec_params_t; /**@brief GAP Encryption Information. */ typedef struct { uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ uint8_t auth : 1; /**< Authenticated Key. */ uint8_t ltk_len : 6; /**< LTK length in octets. */ } ble_gap_enc_info_t; /**@brief GAP Master Identification. */ typedef struct { uint16_t ediv; /**< Encrypted Diversifier. */ uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ } ble_gap_master_id_t; /**@brief GAP Signing Information. */ typedef struct { uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ } ble_gap_sign_info_t; /**@brief GAP LE Secure Connections P-256 Public Key. */ typedef struct { uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ } ble_gap_lesc_p256_pk_t; /**@brief GAP LE Secure Connections DHKey. */ typedef struct { uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ } ble_gap_lesc_dhkey_t; /**@brief GAP LE Secure Connections OOB data. */ typedef struct { ble_gap_addr_t addr; /**< Bluetooth address of the device. */ uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ } ble_gap_lesc_oob_data_t; /**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ typedef struct { ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the device's identity address. */ uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ uint8_t adv_handle; /**< Advertising handle in which advertising has ended. This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated advertising set. The advertising buffers provided in @ref sd_ble_gap_adv_set_configure are now released. This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ } ble_gap_evt_connected_t; /**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ typedef struct { uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ } ble_gap_evt_disconnected_t; /**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ typedef struct { ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ } ble_gap_evt_conn_param_update_t; /**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ typedef struct { ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ } ble_gap_evt_phy_update_request_t; /**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ typedef struct { uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ } ble_gap_evt_phy_update_t; /**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ typedef struct { ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ } ble_gap_evt_sec_params_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ typedef struct { ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ uint8_t id_info : 1; /**< If 1, Identity Information required. */ uint8_t sign_info : 1; /**< If 1, Signing Information required. */ } ble_gap_evt_sec_info_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ typedef struct { uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ } ble_gap_evt_passkey_display_t; /**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ typedef struct { uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ } ble_gap_evt_key_pressed_t; /**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ typedef struct { uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ } ble_gap_evt_auth_key_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ typedef struct { ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ } ble_gap_evt_lesc_dhkey_request_t; /**@brief Security levels supported. * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. */ typedef struct { uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ } ble_gap_sec_levels_t; /**@brief Encryption Key. */ typedef struct { ble_gap_enc_info_t enc_info; /**< Encryption Information. */ ble_gap_master_id_t master_id; /**< Master Identification. */ } ble_gap_enc_key_t; /**@brief Identity Key. */ typedef struct { ble_gap_irk_t id_info; /**< Identity Resolving Key. */ ble_gap_addr_t id_addr_info; /**< Identity Address. */ } ble_gap_id_key_t; /**@brief Security Keys. */ typedef struct { ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ } ble_gap_sec_keys_t; /**@brief Security key set for both local and peer keys. */ typedef struct { ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ } ble_gap_sec_keyset_t; /**@brief Data Length Update Procedure parameters. */ typedef struct { uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ } ble_gap_data_length_params_t; /**@brief Data Length Update Procedure local limitation. */ typedef struct { uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ } ble_gap_data_length_limitation_t; /**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ typedef struct { uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ uint8_t bonded : 1; /**< Procedure resulted in a bond. */ uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ } ble_gap_evt_auth_status_t; /**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ typedef struct { ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ } ble_gap_evt_conn_sec_update_t; /**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ typedef struct { uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ union { ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released scan buffer is contained in this field. */ } params; /**< Event Parameters. */ } ble_gap_evt_timeout_t; /**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ typedef struct { int8_t rssi; /**< Received Signal Strength Indication in dBm. @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */ } ble_gap_evt_rssi_changed_t; /**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */ typedef struct { uint8_t reason; /**< Reason for why the advertising set terminated. See @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */ uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */ uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0, this field indicates the number of completed advertising events. */ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated advertising set. The advertising buffers provided in @ref sd_ble_gap_adv_set_configure are now released. */ } ble_gap_evt_adv_set_terminated_t; /**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. * * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, * not all fields in the advertising report may be available. * * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start. */ typedef struct { ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the peer's identity address. */ ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if @ref ble_gap_adv_report_type_t::directed is set to 1. If the SoftDevice was able to resolve the address, @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr contains the local identity address. If the target address of the advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, and the SoftDevice was unable to resolve it, the application may try to resolve this address to find out if the advertising event was directed to us. */ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received. See @ref BLE_GAP_PHYS. */ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received. See @ref BLE_GAP_PHYS. This field is set to @ref BLE_GAP_PHY_NOT_SET if no packets were received on a secondary advertising channel. */ int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received. This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the last received packet did not contain the Tx Power field. @note TX Power is only included in extended advertising packets. */ int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received. @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */ uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ uint16_t data_id:12; /**< The advertising data ID of the received advertising data. Data ID is not present if @ref ble_gap_evt_adv_report_t::set_id is set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ ble_data_t data; /**< Received advertising or scan response data. If @ref ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided in @ref sd_ble_gap_scan_start is now released. */ ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising event. @note This field is only set if @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */ } ble_gap_evt_adv_report_t; /**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ typedef struct { uint8_t bond : 1; /**< Perform bonding. */ uint8_t mitm : 1; /**< Man In The Middle protection requested. */ uint8_t lesc : 1; /**< LE Secure Connections requested. */ uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ } ble_gap_evt_sec_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ typedef struct { ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ } ble_gap_evt_conn_param_update_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ typedef struct { uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */ int8_t rssi; /**< Received Signal Strength Indication in dBm. @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the device's identity address. */ } ble_gap_evt_scan_req_report_t; /**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ typedef struct { ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ } ble_gap_evt_data_length_update_request_t; /**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ typedef struct { ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ } ble_gap_evt_data_length_update_t; /**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */ typedef struct { int8_t channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy channels, in dBm, indexed by Channel Index. If no measurement is available for the given channel, channel_energy is set to @ref BLE_GAP_POWER_LEVEL_INVALID. */ } ble_gap_evt_qos_channel_survey_report_t; /**@brief GAP event structure. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which event occurred. */ union /**< union alternative identified by evt_id in enclosing struct. */ { ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */ ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ ble_gap_evt_qos_channel_survey_report_t qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */ } params; /**< Event Parameters. */ } ble_gap_evt_t; /** * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. * * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. */ typedef struct { uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. The event length and the connection interval are the primary parameters for setting the throughput of a connection. See the SoftDevice Specification for details on throughput. */ } ble_gap_conn_cfg_t; /** * @brief Configuration of maximum concurrent connections in the different connected roles, set with * @ref sd_ble_cfg_set. * * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too * large. The maximum supported sum of concurrent connections is * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum * supported advertising handles is * @ref BLE_GAP_ADV_SET_COUNT_MAX. */ typedef struct { uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */ uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ uint8_t qos_channel_survey_role_available:1; /**< If set, the Quality of Service (QoS) channel survey module is available to the application using @ref sd_ble_gap_qos_channel_survey_start. */ } ble_gap_cfg_role_count_t; /** * @brief Device name and its properties, set with @ref sd_ble_cfg_set. * * @note If the device name is not configured, the default device name will be * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name * will have no write access. * * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, * the attribute table size must be increased to have room for the longer device name (see * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). * * @note If vloc is @ref BLE_GATTS_VLOC_STACK : * - p_value must point to non-volatile memory (flash) or be NULL. * - If p_value is NULL, the device name will initially be empty. * * @note If vloc is @ref BLE_GATTS_VLOC_USER : * - p_value cannot be NULL. * - If the device name is writable, p_value must point to volatile memory (RAM). * * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: * - Invalid device name location (vloc). * - Invalid device name security mode. * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). * - The device name length is too long for the given Attribute Table. * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. */ typedef struct { ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ } ble_gap_cfg_device_name_t; /**@brief Configuration structure for GAP configurations. */ typedef union { ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ } ble_gap_cfg_t; /**@brief Channel Map option. * * @details Used with @ref sd_ble_opt_get to get the current channel map * or @ref sd_ble_opt_set to set a new channel map. When setting the * channel map, it applies to all current and future connections. When getting the * current channel map, it applies to a single connection and the connection handle * must be supplied. * * @note Setting the channel map may take some time, depending on connection parameters. * The time taken may be different for each connection and the get operation will * return the previous channel map until the new one has taken effect. * * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. * * @retval ::NRF_SUCCESS Get or set successful. * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: * - Less then two bits in @ref ch_map are set. * - Bits for primary advertising channels (37-39) are set. * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. * */ typedef struct { uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ uint8_t ch_map[5]; /**< Channel Map (37-bit). */ } ble_gap_opt_ch_map_t; /**@brief Local connection latency option. * * @details Local connection latency is a feature which enables the slave to improve * current consumption by ignoring the slave latency set by the peer. The * local connection latency can only be set to a multiple of the slave latency, * and cannot be longer than half of the supervision timeout. * * @details Used with @ref sd_ble_opt_set to set the local connection latency. The * @ref sd_ble_opt_get is not supported for this option, but the actual * local connection latency (unless set to NULL) is set as a return parameter * when setting the option. * * @note The latency set will be truncated down to the closest slave latency event * multiple, or the nearest multiple before half of the supervision timeout. * * @note The local connection latency is disabled by default, and needs to be enabled for new * connections and whenever the connection is updated. * * @retval ::NRF_SUCCESS Set successfully. * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. */ typedef struct { uint16_t conn_handle; /**< Connection Handle */ uint16_t requested_latency; /**< Requested local connection latency. */ uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ } ble_gap_opt_local_conn_latency_t; /**@brief Disable slave latency * * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the * peripheral will ignore the slave_latency set by the central. * * @note Shall only be called on peripheral links. * * @retval ::NRF_SUCCESS Set successfully. * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. */ typedef struct { uint16_t conn_handle; /**< Connection Handle */ uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ } ble_gap_opt_slave_latency_disable_t; /**@brief Passkey Option. * * @details Structure containing the passkey to be used during pairing. This can be used with @ref * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication * instead of generating a random one. * * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. * * @note @ref sd_ble_opt_get is not supported for this option. * */ typedef struct { uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ } ble_gap_opt_passkey_t; /**@brief Compatibility mode 1 option. * * @details This can be used with @ref sd_ble_opt_set to enable and disable * compatibility mode 1. Compatibility mode 1 is disabled by default. * * @note Compatibility mode 1 enables interoperability with devices that do not support a value of * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a * limited set of legacy peripheral devices from another vendor. Enabling this compatibility * mode will only have an effect if the local device will act as a central device and * initiate a connection to a peripheral device. In that case it may lead to the connection * creation taking up to one connection interval longer to complete for all connections. * * @retval ::NRF_SUCCESS Set successfully. * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. */ typedef struct { uint8_t enable : 1; /**< Enable compatibility mode 1.*/ } ble_gap_opt_compat_mode_1_t; /**@brief Authenticated payload timeout option. * * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. * * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted * link. * * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance * to reset the timer. In addition the stack will try to prioritize running of LE ping over other * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects * on other activities, it is recommended to use high timeout values. * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). * * @retval ::NRF_SUCCESS Set successfully. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. */ typedef struct { uint16_t conn_handle; /**< Connection Handle */ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ } ble_gap_opt_auth_payload_timeout_t; /**@brief Option structure for GAP options. */ typedef union { ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ } ble_gap_opt_t; /**@} */ /**@addtogroup BLE_GAP_FUNCTIONS Functions * @{ */ /**@brief Set the local Bluetooth identity address. * * The local Bluetooth identity address is the address that identifies this device to other peers. * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. * * @note The identity address cannot be changed while advertising, scanning or creating a connection. * * @note This address will be distributed to the peer during bonding. * If the address changes, the address stored in the peer device will not be valid and the ability to * reconnect using the old address will be lost. * * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged * for the lifetime of each IC. * * @mscs * @mmsc{@ref BLE_GAP_ADV_MSC} * @endmscs * * @param[in] p_addr Pointer to address structure. * * @retval ::NRF_SUCCESS Address successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, * scanning or creating a connection. */ SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); /**@brief Get local Bluetooth identity address. * * @note This will always return the identity address irrespective of the privacy settings, * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. * * @param[out] p_addr Pointer to address structure to be filled in. * * @retval ::NRF_SUCCESS Address successfully retrieved. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. */ SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); /**@brief Get the Bluetooth device address used by the advertiser. * * @note This function will return the local Bluetooth address used in advertising PDUs. When * using privacy, the SoftDevice will generate a new private address every * @ref ble_gap_privacy_params_t::private_addr_cycle_s configured using * @ref sd_ble_gap_privacy_set. Hence depending on when the application calls this API, the * address returned may not be the latest address that is used in the advertising PDUs. * * @param[in] adv_handle The advertising handle to get the address from. * @param[out] p_addr Pointer to address structure to be filled in. * * @retval ::NRF_SUCCESS Address successfully retrieved. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. * @retval ::NRF_ERROR_INVALID_STATE The advertising set is currently not advertising. */ SVCALL(SD_BLE_GAP_ADV_ADDR_GET, uint32_t, sd_ble_gap_adv_addr_get(uint8_t adv_handle, ble_gap_addr_t *p_addr)); /**@brief Set the active whitelist in the SoftDevice. * * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. * The whitelist cannot be set if a BLE role is using the whitelist. * * @note If an address is resolved using the information in the device identity list, then the whitelist * filter policy applies to the peer identity address and not the resolvable address sent on air. * * @mscs * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} * @endmscs * * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. * * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when * pp_wl_addrs is not NULL. */ SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); /**@brief Set device identity list. * * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. * The device identity list cannot be set if a BLE role is using the list. * * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. * To fill in the list with the currently set device IRK for all peers, set to NULL. * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. * * @mscs * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} * @endmscs * * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. * This code may be returned if the local IRK list also has an invalid entry. * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can * only return when pp_id_keys is not NULL. */ SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); /**@brief Set privacy settings. * * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. * * @param[in] p_privacy_params Privacy settings. * * @mscs * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} * @endmscs * * @retval ::NRF_SUCCESS Set successfully. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning * or creating a connection. */ SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); /**@brief Get privacy settings. * * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. * * @param[in,out] p_privacy_params Privacy settings. * * @retval ::NRF_SUCCESS Privacy settings read. * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. */ SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); /**@brief Configure an advertising set. Set, clear or update advertising and scan response data. * * @note The format of the advertising data will be checked by this call to ensure interoperability. * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and * duplicating the local name in the advertising data and scan response data. * * @note In order to update advertising data while advertising, new advertising buffers must be provided. * * @mscs * @mmsc{@ref BLE_GAP_ADV_MSC} * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @endmscs * * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure * a new advertising set. On success, a new handle is then returned through the pointer. * Provide a pointer to an existing advertising handle to configure an existing advertising set. * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t. * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising, * this parameter must be NULL. See @ref ble_gap_adv_params_t. * * @retval ::NRF_SUCCESS Advertising set successfully configured. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t. * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. * - Use of whitelist requested but whitelist has not been set, * see @ref sd_ble_gap_whitelist_set. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - It is invalid to provide non-NULL advertising set parameters while advertising. * - It is invalid to provide the same data buffers while advertising. To update * advertising data, provide new advertising buffers. * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to * configure a new advertising handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11. * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration. * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an * existing advertising handle instead. * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. */ SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params)); /**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). * * @note Only one advertiser may be active at any time. * * @events * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.} * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_ADV_MSC} * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @endmscs * * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure. * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable * advertising, this is ignored. * * @retval ::NRF_SUCCESS The BLE stack has started advertising. * @retval ::NRF_ERROR_INVALID_STATE adv_handle is not configured or already advertising. * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure. * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. * @retval ::NRF_ERROR_RESOURCES Either: * - adv_handle is configured with connectable advertising, but the event_length parameter * associated with conn_cfg_tag is too small to be able to establish a connection on * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. * - Not enough BLE role slots available. Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) and try again. * - p_adv_params is configured with connectable advertising, but the event_length parameter * associated with conn_cfg_tag is too small to be able to establish a connection on * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. */ SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)); /**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). * * @mscs * @mmsc{@ref BLE_GAP_ADV_MSC} * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @endmscs * * @param[in] adv_handle The advertising handle that should stop advertising. * * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle. * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising. */ SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle)); /**@brief Update connection parameters. * * @details In the central role this will initiate a Link Layer connection parameter update procedure, * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for * the central to perform the procedure. In both cases, and regardless of success or failure, the application * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. * * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. * * @events * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_CPU_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, * the parameters in the PPCP characteristic of the GAP service will be used instead. * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected * * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. */ SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); /**@brief Disconnect (GAP Link Termination). * * @details This call initiates the disconnection procedure, and its completion will be communicated to the application * with a @ref BLE_GAP_EVT_DISCONNECTED event. * * @events * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_CONN_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). * * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. */ SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); /**@brief Set the radio's transmit power. * * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for * possible roles. * @param[in] handle The handle parameter is interpreted depending on role: * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle. * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle, * will use the specified transmit power, and include it in the advertising packet headers if * @ref ble_gap_adv_properties_t::include_tx_power set. * - For all other roles handle is ignored. * @param[in] tx_power Radio transmit power in dBm (see note for accepted values). * * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm and +8dBm. * @note The initiator will have the same transmit power as the scanner. * @note When a connection is created it will inherit the transmit power from the initiator or * advertiser leading to the connection. * * @retval ::NRF_SUCCESS Successfully changed the transmit power. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power)); /**@brief Set GAP Appearance value. * * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. * * @retval ::NRF_SUCCESS Appearance value set successfully. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. */ SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); /**@brief Get GAP Appearance value. * * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. * * @retval ::NRF_SUCCESS Appearance value retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. */ SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); /**@brief Set GAP Peripheral Preferred Connection Parameters. * * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. * * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. */ SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); /**@brief Get GAP Peripheral Preferred Connection Parameters. * * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. * * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. */ SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); /**@brief Set GAP device name. * * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. * * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). * * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. */ SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); /**@brief Get GAP device name. * * @note If the device name is longer than the size of the supplied buffer, * p_len will return the complete device name length, * and not the number of bytes actually returned in p_dev_name. * The application may use this information to allocate a suitable buffer size. * * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. * * @retval ::NRF_SUCCESS GAP device name retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. */ SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); /**@brief Initiate the GAP Authentication procedure. * * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), * otherwise in the peripheral role, an SMP Security Request will be sent. * * @events * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} * @event{@ref BLE_GAP_EVT_KEY_PRESSED} * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} * @event{@ref BLE_GAP_EVT_AUTH_STATUS} * @event{@ref BLE_GAP_EVT_TIMEOUT} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. * In the central role, this pointer may be NULL to reject a Security Request. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - No link has been established. * - An encryption is already executing or queued. * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. */ SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); /**@brief Reply with GAP security parameters. * * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. * * @events * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have * already been provided during a previous call to @ref sd_ble_gap_authenticate. * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. * Note that the SoftDevice expects the application to provide memory for storing the * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the * @ref BLE_GAP_EVT_AUTH_STATUS event. * * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Security parameters has not been requested. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. */ SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); /**@brief Reply with an authentication key. * * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. * * @events * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) * or NULL when confirming LE Secure Connections Numeric Comparison. * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. * * @retval ::NRF_SUCCESS Authentication key successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Authentication key has not been requested. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); /**@brief Reply with an LE Secure connections DHKey. * * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. * * @events * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_dhkey LE Secure Connections DHKey. * * @retval ::NRF_SUCCESS DHKey successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - The peer is not authenticated. * - The application has not pulled a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); /**@brief Notify the peer of a local keypress. * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. * * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - Authentication key not requested. * - Passkey has not been entered. * - Keypresses have not been enabled by both peers. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. */ SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); /**@brief Generate a set of OOB data to send to a peer out of band. * * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, * the one used during connection setup). The application may manually overwrite it with an updated value. * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} * @endmscs * * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. * * @retval ::NRF_SUCCESS OOB data successfully generated. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); /**@brief Provide the OOB data sent/received out of band. * * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. * * @events * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. * Must correspond to @ref ble_gap_sec_params_t::oob flag * in @ref sd_ble_gap_authenticate in the central role or * in @ref sd_ble_gap_sec_params_reply in the peripheral role. * * @retval ::NRF_SUCCESS OOB data accepted. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - Authentication key not requested * - Not expecting LESC OOB data * - Have not actually exchanged passkeys. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); /**@brief Initiate GAP Encryption procedure. * * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. * * @events * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE No link has been established. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. */ SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); /**@brief Reply with GAP security information. * * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. * * @mscs * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. * * @retval ::NRF_SUCCESS Successfully accepted security information. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - No link has been established. * - No @ref BLE_GAP_EVT_SEC_REQUEST pending. * - LE long term key requested command not allowed. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); /**@brief Get the current connection security. * * @param[in] conn_handle Connection handle. * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. * * @retval ::NRF_SUCCESS Current connection security successfully retrieved. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); /**@brief Start reporting the received signal strength to the application. * * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. * * @events * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is * dependent on the settings of the threshold_dbm * and skip_count input parameters.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. * * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); /**@brief Stop reporting the received signal strength. * * @note An RSSI change detected before the call but not yet received by the application * may be reported after @ref sd_ble_gap_rssi_stop has been called. * * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. */ SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); /**@brief Get the received signal strength for the last connection event. * * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. * @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored. * * @retval ::NRF_SUCCESS Successfully read the RSSI. * @retval ::NRF_ERROR_NOT_FOUND No sample is available. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. */ SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index)); /**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure). * * @note A call to this function will require the application to keep the memory pointed by * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped * or when this function is called with another buffer. * * @note The scanner will automatically stop in the following cases: * - @ref sd_ble_gap_scan_stop is called. * - @ref sd_ble_gap_connect is called. * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received. * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application * access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop * to stop scanning. * * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will * receive more reports from this advertising event. The following reports will include the old and new received data. * * @events * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_SCAN_MSC} * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @endmscs * * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue * scanning, this parameter must be NULL. * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data. * The memory pointed to should be kept alive until the scanning is stopped. * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size. * If the scanner receives advertising data larger than can be stored in the buffer, * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED. * * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: * - Scanning is already ongoing and p_scan_params was not NULL * - Scanning is not running and p_scan_params was NULL. * - The scanner has timed out when this function is called to continue scanning. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t. * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t. * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN. * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again */ SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer)); /**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). * * @note The buffer provided in @ref sd_ble_gap_scan_start is released. * * @mscs * @mmsc{@ref BLE_GAP_SCAN_MSC} * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @endmscs * * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. * @retval ::NRF_ERROR_INVALID_STATE Not in the scanning state. */ SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); /**@brief Create a connection (GAP Link Establishment). * * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. * The scanning procedure will be stopped even if the function returns an error. * * @events * @event{@ref BLE_GAP_EVT_CONNECTED, A connection was established.} * @event{@ref BLE_GAP_EVT_TIMEOUT, Failed to establish a connection.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} * @endmscs * * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use * whitelist, then p_peer_addr is ignored. * @param[in] p_scan_params Pointer to scan parameters structure. * @param[in] p_conn_params Pointer to desired connection parameters. * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. * * @retval ::NRF_SUCCESS Successfully initiated connection procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * - Invalid parameter(s) in p_scan_params or p_conn_params. * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an * existing locally initiated connect procedure, which must complete before initiating again. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. * @retval ::NRF_ERROR_RESOURCES Either: * - Not enough BLE role slots available. * Stop one or more currently active roles (Central, Peripheral or Observer) and try again. * - The event_length parameter associated with conn_cfg_tag is too small to be able to * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys. * Use @ref sd_ble_cfg_set to increase the event length. */ SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); /**@brief Cancel a connection establishment. * * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} * @endmscs * * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. * @retval ::NRF_ERROR_INVALID_STATE No locally initiated connect procedure started or connection * completed occurred. */ SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); /**@brief Initiate or respond to a PHY Update Procedure * * @details This function is used to initiate or respond to a PHY Update Procedure. It will always * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. * If this function is used to initiate a PHY Update procedure and the only option * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the * currently active PHYs in the respective directions, the SoftDevice will generate a * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the * procedure in the Link Layer. * * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO, * then the stack will select PHYs based on the peer's PHY preferences and the local link * configuration. The PHY Update procedure will for this case result in a PHY combination * that respects the time constraints configured with @ref sd_ble_cfg_set and the current * link layer data length. * * When acting as a central, the SoftDevice will select the fastest common PHY in each direction. * * If the peer does not support the PHY Update Procedure, then the resulting * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. * * If the PHY procedure was rejected by the peer due to a procedure collision, the status * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. * If the peer responds to the PHY Update procedure with invalid parameters, the status * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. * If the PHY procedure was rejected by the peer for a different reason, the status will * contain the reason as specified by the peer. * * @events * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} * @endevents * * @mscs * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} * @endmscs * * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. * @param[in] p_gap_phys Pointer to PHY structure. * * @retval ::NRF_SUCCESS Successfully requested a PHY Update. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE No link has been established. * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the combination of * @ref ble_gap_phys_t::tx_phys, @ref ble_gap_phys_t::rx_phys, and @ref ble_gap_data_length_params_t. * The connection event length is configured with @ref BLE_CONN_CFG_GAP using @ref sd_ble_cfg_set. * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. * */ SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); /**@brief Initiate or respond to a Data Length Update Procedure. * * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of * p_dl_params, the SoftDevice will choose the highest value supported in current * configuration and connection parameters. * @note If the link PHY is Coded, the SoftDevice will ensure that the MaxTxTime and/or MaxRxTime * used in the Data Length Update procedure is at least 2704 us. Otherwise, MaxTxTime and * MaxRxTime will be limited to maximum 2120 us. * * @param[in] conn_handle Connection handle. * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let * the SoftDevice automatically decide the value for that member. * Set to NULL to use automatic values for all members. * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not * have enough resources or does not support the requested Data Length * Update parameters. Ignored if NULL. * * @mscs * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} * @endmscs * * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. * @retval ::NRF_ERROR_INVALID_STATE No link has been established. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect * p_dl_limitation to see which parameter is not supported. * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested parameters. * Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length. * Inspect p_dl_limitation to see where the limitation is. * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. */ SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); /**@brief Start the Quality of Service (QoS) channel survey module. * * @details The channel survey module provides measurements of the energy levels on * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT * events will periodically report the measured energy levels for each channel. * * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles, * Radio Timeslot API events and Flash API events. * * @note The channel survey module will attempt to do measurements so that the average interval * between measurements will be interval_us. However due to the channel survey module * having the lowest priority of all roles and modules, this may not be possible. In that * case fewer than expected channel survey reports may be given. * * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available * must be set. This is done using @ref sd_ble_cfg_set. * * @param[in] interval_us Requested average interval for the measurements and reports. See * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel * survey role will be scheduled at every available opportunity. * * @retval ::NRF_SUCCESS The module is successfully started. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the * allowed range. * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running. * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application. * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using * @ref sd_ble_cfg_set. */ SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us)); /**@brief Stop the Quality of Service (QoS) channel survey module. * * @retval ::NRF_SUCCESS The module is successfully stopped. * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running. */ SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void)); /** @} */ #ifdef __cplusplus } #endif #endif // BLE_GAP_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatt.h ================================================ /* * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common @{ @brief Common definitions and prototypes for the GATT interfaces. */ #ifndef BLE_GATT_H__ #define BLE_GATT_H__ #include #include "nrf_svc.h" #include "nrf_error.h" #include "ble_hci.h" #include "ble_ranges.h" #include "ble_types.h" #include "ble_err.h" #ifdef __cplusplus extern "C" { #endif /** @addtogroup BLE_GATT_DEFINES Defines * @{ */ /** @brief Default ATT MTU, in bytes. */ #define BLE_GATT_ATT_MTU_DEFAULT 23 /**@brief Invalid Attribute Handle. */ #define BLE_GATT_HANDLE_INVALID 0x0000 /**@brief First Attribute Handle. */ #define BLE_GATT_HANDLE_START 0x0001 /**@brief Last Attribute Handle. */ #define BLE_GATT_HANDLE_END 0xFFFF /** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources * @{ */ #define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ /** @} */ /** @defgroup BLE_GATT_WRITE_OPS GATT Write operations * @{ */ #define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ #define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ #define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ #define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ #define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ #define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ /** @} */ /** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags * @{ */ #define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ #define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ /** @} */ /** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations * @{ */ #define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ #define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ #define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ /** @} */ /** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes * @{ */ #define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ #define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ #define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ #define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ #define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ #define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ #define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ #define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ #define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ #define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ #define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ #define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ #define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ #define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ #define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ #define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ #define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ #define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ #define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ #define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ #define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ #define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ #define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ #define BLE_GATT_STATUS_ATTERR_CPS_WRITE_REQ_REJECTED 0x01FC /**< ATT Common Profile and Service Error: Write request rejected. */ #define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ #define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ #define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ /** @} */ /** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml * @{ */ #define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ #define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ #define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ #define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ #define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ #define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ #define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ #define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ #define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ #define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ #define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ #define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ #define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ #define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ /** @} */ /** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces * @{ */ #define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ #define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ /** @} */ /** @} */ /** @addtogroup BLE_GATT_STRUCTURES Structures * @{ */ /** * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. * * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. */ typedef struct { uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. @mscs @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} @endmscs */ } ble_gatt_conn_cfg_t; /**@brief GATT Characteristic Properties. */ typedef struct { /* Standard properties */ uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ uint8_t read :1; /**< Reading the value permitted. */ uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ uint8_t write :1; /**< Writing the value with Write Request permitted. */ uint8_t notify :1; /**< Notification of the value permitted. */ uint8_t indicate :1; /**< Indications of the value permitted. */ uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ } ble_gatt_char_props_t; /**@brief GATT Characteristic Extended Properties. */ typedef struct { /* Extended properties */ uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ } ble_gatt_char_ext_props_t; /** @} */ #ifdef __cplusplus } #endif #endif // BLE_GATT_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gattc.h ================================================ /* * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client @{ @brief Definitions and prototypes for the GATT Client interface. */ #ifndef BLE_GATTC_H__ #define BLE_GATTC_H__ #include #include "nrf.h" #include "nrf_svc.h" #include "nrf_error.h" #include "ble_ranges.h" #include "ble_types.h" #include "ble_err.h" #include "ble_gatt.h" #ifdef __cplusplus extern "C" { #endif /** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations * @{ */ /**@brief GATTC API SVC numbers. */ enum BLE_GATTC_SVCS { SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ SD_BLE_GATTC_READ, /**< Generic read. */ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ SD_BLE_GATTC_WRITE, /**< Generic write. */ SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ }; /** * @brief GATT Client Event IDs. */ enum BLE_GATTC_EVTS { BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ }; /** @} */ /** @addtogroup BLE_GATTC_DEFINES Defines * @{ */ /** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC * @{ */ #define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ /** @} */ /** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats * @{ */ #define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ #define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ /** @} */ /** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults * @{ */ #define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ /** @} */ /** @} */ /** @addtogroup BLE_GATTC_STRUCTURES Structures * @{ */ /** * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. */ typedef struct { uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ } ble_gattc_conn_cfg_t; /**@brief Operation Handle Range. */ typedef struct { uint16_t start_handle; /**< Start Handle. */ uint16_t end_handle; /**< End Handle. */ } ble_gattc_handle_range_t; /**@brief GATT service. */ typedef struct { ble_uuid_t uuid; /**< Service UUID. */ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ } ble_gattc_service_t; /**@brief GATT include. */ typedef struct { uint16_t handle; /**< Include Handle. */ ble_gattc_service_t included_srvc; /**< Handle of the included service. */ } ble_gattc_include_t; /**@brief GATT characteristic. */ typedef struct { ble_uuid_t uuid; /**< Characteristic UUID. */ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ uint8_t char_ext_props : 1; /**< Extended properties present. */ uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ uint16_t handle_value; /**< Handle of the Characteristic Value. */ } ble_gattc_char_t; /**@brief GATT descriptor. */ typedef struct { uint16_t handle; /**< Descriptor Handle. */ ble_uuid_t uuid; /**< Descriptor UUID. */ } ble_gattc_desc_t; /**@brief Write Parameters. */ typedef struct { uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ uint16_t handle; /**< Handle to the attribute to be written. */ uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ uint16_t len; /**< Length of data in bytes. */ uint8_t const *p_value; /**< Pointer to the value data. */ } ble_gattc_write_params_t; /**@brief Attribute Information for 16-bit Attribute UUID. */ typedef struct { uint16_t handle; /**< Attribute handle. */ ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ } ble_gattc_attr_info16_t; /**@brief Attribute Information for 128-bit Attribute UUID. */ typedef struct { uint16_t handle; /**< Attribute handle. */ ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ } ble_gattc_attr_info128_t; /**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ typedef struct { uint16_t count; /**< Service count. */ ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_prim_srvc_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ typedef struct { uint16_t count; /**< Include count. */ ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_rel_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ typedef struct { uint16_t count; /**< Characteristic count. */ ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ typedef struct { uint16_t count; /**< Descriptor count. */ ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_desc_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ typedef struct { uint16_t count; /**< Attribute count. */ uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ union { ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } info; /**< Attribute information union. */ } ble_gattc_evt_attr_info_disc_rsp_t; /**@brief GATT read by UUID handle value pair. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ } ble_gattc_handle_value_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ typedef struct { uint16_t count; /**< Handle-Value Pair Count. */ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_val_by_uuid_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ uint16_t offset; /**< Offset of the attribute data. */ uint16_t len; /**< Attribute data length. */ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ typedef struct { uint16_t len; /**< Concatenated Attribute values length. */ uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_vals_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ uint16_t offset; /**< Data offset. */ uint16_t len; /**< Data length. */ uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_write_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ typedef struct { uint16_t handle; /**< Handle to which the HVx operation applies. */ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ uint16_t len; /**< Attribute data length. */ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_hvx_t; /**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ typedef struct { uint16_t server_rx_mtu; /**< Server RX MTU size. */ } ble_gattc_evt_exchange_mtu_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ typedef struct { uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ } ble_gattc_evt_timeout_t; /**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ typedef struct { uint8_t count; /**< Number of write without response transmissions completed. */ } ble_gattc_evt_write_cmd_tx_complete_t; /**@brief GATTC event structure. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which event occurred. */ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ union { ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ } ble_gattc_evt_t; /** @} */ /** @addtogroup BLE_GATTC_FUNCTIONS Functions * @{ */ /**@brief Initiate or continue a GATT Primary Service Discovery procedure. * * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. * * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * * @events * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] start_handle Handle to start searching from. * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. * * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); /**@brief Initiate or continue a GATT Relationship Discovery procedure. * * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, * this must be called again with an updated handle range to continue the search. * * @events * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); /**@brief Initiate or continue a GATT Characteristic Discovery procedure. * * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, * this must be called again with an updated handle range to continue the discovery. * * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * * @events * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); /**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. * * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, * this must be called again with an updated handle range to continue the discovery. * * @events * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. * * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); /**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. * * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, * this must be called again with an updated handle range to continue the discovery. * * @events * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_uuid Pointer to a Characteristic value UUID to read. * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. * * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); /**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. * * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the * complete value. * * @events * @event{@ref BLE_GATTC_EVT_READ_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute to be read. * @param[in] offset Offset into the attribute value to be read. * * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); /**@brief Initiate a GATT Read Multiple Characteristic Values procedure. * * @details This function initiates a GATT Read Multiple Characteristic Values procedure. * * @events * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. * @param[in] handle_count The number of handles in p_handles. * * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); /**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. * * @details This function can perform all write procedures described in GATT. * * @note Only one write with response procedure can be ongoing per connection at a time. * If the application tries to write with response while another write with response procedure is ongoing, * the function call will return @ref NRF_ERROR_BUSY. * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. * * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. * * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: * - Store initial queue element count in a variable. * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. * * @events * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_write_params A pointer to a write parameters structure. * * @retval ::NRF_SUCCESS Successfully started the Write procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); /**@brief Send a Handle Value Confirmation to the GATT Server. * * @mscs * @mmsc{@ref BLE_GATTC_HVI_MSC} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute in the indication. * * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); /**@brief Discovers information about a range of attributes on a GATT server. * * @events * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} * @endevents * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range The range of handles to request information about. * * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); /**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. * * @details The SoftDevice sets ATT_MTU to the minimum of: * - The Client RX MTU value, and * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. * * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. * * @events * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} * @endevents * * @mscs * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] client_rx_mtu Client RX MTU size. * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration used for this connection. * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply * if an ATT_MTU exchange has already been performed in the other direction. * * @retval ::NRF_SUCCESS Successfully sent request to the server. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); /**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. * * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. * @note If the buffer contains different event, behavior is undefined. * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with * the next Handle-Value pair in each iteration. If the function returns other than * @ref NRF_SUCCESS, it will not be changed. * - To start iteration, initialize the structure to zero. * - To continue, pass the value from previous iteration. * * \code * ble_gattc_handle_value_t iter; * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) * { * app_handle = iter.handle; * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); * } * \endcode * * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. */ __STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); /** @} */ #ifndef SUPPRESS_INLINE_IMPLEMENTATION __STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) { uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) { p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; p_iter->p_value = p_next + sizeof(uint16_t); return NRF_SUCCESS; } else { return NRF_ERROR_NOT_FOUND; } } #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ #ifdef __cplusplus } #endif #endif /* BLE_GATTC_H__ */ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_gatts.h ================================================ /* * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server @{ @brief Definitions and prototypes for the GATTS interface. */ #ifndef BLE_GATTS_H__ #define BLE_GATTS_H__ #include #include "nrf_svc.h" #include "nrf_error.h" #include "ble_hci.h" #include "ble_ranges.h" #include "ble_types.h" #include "ble_err.h" #include "ble_gatt.h" #include "ble_gap.h" #ifdef __cplusplus extern "C" { #endif /** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations * @{ */ /** * @brief GATTS API SVC numbers. */ enum BLE_GATTS_SVCS { SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ }; /** * @brief GATT Server Event IDs. */ enum BLE_GATTS_EVTS { BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ }; /**@brief GATTS Configuration IDs. * * IDs that uniquely identify a GATTS configuration. */ enum BLE_GATTS_CFGS { BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ }; /** @} */ /** @addtogroup BLE_GATTS_DEFINES Defines * @{ */ /** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS * @{ */ #define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ #define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ /** @} */ /** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths * @{ */ #define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ #define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ /** @} */ /** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types * @{ */ #define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ #define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ #define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ /** @} */ /** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types * @{ */ #define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ #define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ #define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ #define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ #define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ #define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ #define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ #define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ /** @} */ /** @defgroup BLE_GATTS_OPS GATT Server Operations * @{ */ #define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ #define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ #define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ #define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ #define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ #define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ #define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ /** @} */ /** @defgroup BLE_GATTS_VLOCS GATT Value Locations * @{ */ #define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ #define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ #define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ /** @} */ /** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types * @{ */ #define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ #define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ #define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ /** @} */ /** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags * @{ */ #define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ #define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ /** @} */ /** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values * @{ */ #define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ /** @} */ /** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size * @{ */ #define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ #define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ /** @} */ /** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults * @{ */ #define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ /** @} */ /** @} */ /** @addtogroup BLE_GATTS_STRUCTURES Structures * @{ */ /** * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. */ typedef struct { uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ } ble_gatts_conn_cfg_t; /**@brief Attribute metadata. */ typedef struct { ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ uint8_t vlen :1; /**< Variable length attribute. */ uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ } ble_gatts_attr_md_t; /**@brief GATT Attribute. */ typedef struct { ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ uint16_t init_len; /**< Initial attribute value length in bytes. */ uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ } ble_gatts_attr_t; /**@brief GATT Attribute Value. */ typedef struct { uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ uint16_t offset; /**< Attribute value offset. */ uint8_t *p_value; /**< Pointer to where value is stored or will be stored. If value is stored in user memory, only the attribute length is updated when p_value == NULL. Set to NULL when reading to obtain the complete length of the attribute value */ } ble_gatts_value_t; /**@brief GATT Characteristic Presentation Format. */ typedef struct { uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ int8_t exponent; /**< Exponent for integer data types. */ uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ } ble_gatts_char_pf_t; /**@brief GATT Characteristic metadata. */ typedef struct { ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ } ble_gatts_char_md_t; /**@brief GATT Characteristic Definition Handles. */ typedef struct { uint16_t value_handle; /**< Handle to the characteristic value. */ uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ } ble_gatts_char_handles_t; /**@brief GATT HVx parameters. */ typedef struct { uint16_t handle; /**< Characteristic Value Handle. */ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ uint16_t offset; /**< Offset within the attribute value. */ uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */ uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ } ble_gatts_hvx_params_t; /**@brief GATT Authorization parameters. */ typedef struct { uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, as the data to be written needs to be stored and later provided by the application. */ uint16_t offset; /**< Offset of the attribute value being updated. */ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ } ble_gatts_authorize_params_t; /**@brief GATT Read or Write Authorize Reply parameters. */ typedef struct { uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ union { ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ } params; /**< Reply Parameters. */ } ble_gatts_rw_authorize_reply_params_t; /**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ typedef struct { uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ } ble_gatts_cfg_service_changed_t; /**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. * * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: * - The specified Attribute Table size is too small. * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. * - The specified Attribute Table size is not a multiple of 4. */ typedef struct { uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ } ble_gatts_cfg_attr_tab_size_t; /**@brief Config structure for GATTS configurations. */ typedef union { ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ } ble_gatts_cfg_t; /**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ ble_uuid_t uuid; /**< Attribute UUID. */ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the received data. */ uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gatts_evt_write_t; /**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ ble_uuid_t uuid; /**< Attribute UUID. */ uint16_t offset; /**< Offset for the read operation. */ } ble_gatts_evt_read_t; /**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ typedef struct { uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ union { ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ } request; /**< Request Parameters. */ } ble_gatts_evt_rw_authorize_request_t; /**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ typedef struct { uint8_t hint; /**< Hint (currently unused). */ } ble_gatts_evt_sys_attr_missing_t; /**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ } ble_gatts_evt_hvc_t; /**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ typedef struct { uint16_t client_rx_mtu; /**< Client RX MTU size. */ } ble_gatts_evt_exchange_mtu_request_t; /**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ typedef struct { uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ } ble_gatts_evt_timeout_t; /**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ typedef struct { uint8_t count; /**< Number of notification transmissions completed. */ } ble_gatts_evt_hvn_tx_complete_t; /**@brief GATTS event structure. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ union { ble_gatts_evt_write_t write; /**< Write Event Parameters. */ ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ } params; /**< Event Parameters. */ } ble_gatts_evt_t; /** @} */ /** @addtogroup BLE_GATTS_FUNCTIONS Functions * @{ */ /**@brief Add a service declaration to the Attribute Table. * * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to * add a secondary service declaration that is not referenced by another service later in the Attribute Table. * * @mscs * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} * @endmscs * * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. * @param[in] p_uuid Pointer to service UUID. * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. * * @retval ::NRF_SUCCESS Successfully added a service declaration. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. */ SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); /**@brief Add an include declaration to the Attribute Table. * * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). * * @note The included service must already be present in the Attribute Table prior to this call. * * @mscs * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} * @endmscs * * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] inc_srvc_handle Handle of the included service. * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. * * @retval ::NRF_SUCCESS Successfully added an include declaration. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. */ SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); /**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. * * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). * * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. * * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. * * @mscs * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} * @endmscs * * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_char_md Characteristic metadata. * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. * * @retval ::NRF_SUCCESS Successfully added a characteristic. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. */ SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); /**@brief Add a descriptor to the Attribute Table. * * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). * * @mscs * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} * @endmscs * * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_attr Pointer to the attribute structure. * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. * * @retval ::NRF_SUCCESS Successfully added a descriptor. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. */ SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); /**@brief Set the value of a given attribute. * * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. * * @mscs * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} * @endmscs * * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. * @param[in] handle Attribute handle. * @param[in,out] p_value Attribute value information. * * @retval ::NRF_SUCCESS Successfully set the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. */ SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); /**@brief Get the value of a given attribute. * * @note If the attribute value is longer than the size of the supplied buffer, * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset), * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value. * The application may use this information to allocate a suitable buffer size. * * @note When retrieving system attribute values with this function, the connection handle * may refer to an already disconnected connection. Refer to the documentation of * @ref sd_ble_gatts_sys_attr_get for further information. * * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. * @param[in] handle Attribute handle. * @param[in,out] p_value Attribute value information. * * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. */ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); /**@brief Notify or Indicate an attribute value. * * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that * the application can atomically perform a value update and a server initiated transaction with a single API call. * * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len). * * @note Only one indication procedure can be ongoing per connection at a time. * If the application tries to indicate an attribute value while another indication procedure is ongoing, * the function call will return @ref NRF_ERROR_BUSY. * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. * * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. * * @note The application can keep track of the available queue element count for notifications by following the procedure below: * - Store initial queue element count in a variable. * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. * * @events * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} * @endevents * * @mscs * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} * @mmsc{@ref BLE_GATTS_HVN_MSC} * @mmsc{@ref BLE_GATTS_HVI_MSC} * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data * contains a non-NULL pointer the attribute value will be updated with the contents * pointed by it before sending the notification or indication. If the attribute value * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to * contain the number of actual bytes written, else it will be set to 0. * * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: * - Invalid Connection State * - Notifications and/or indications not enabled in the CCCD * - An ATT_MTU exchange is ongoing * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); /**@brief Indicate the Service Changed attribute value. * * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will * be issued. * * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. * * @events * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} * @endevents * * @mscs * @mmsc{@ref BLE_GATTS_SC_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] start_handle Start of affected attribute handle range. * @param[in] end_handle End of affected attribute handle range. * * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: * - Invalid Connection State * - Notifications and/or indications not enabled in the CCCD * - An ATT_MTU exchange is ongoing * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. * @retval ::NRF_ERROR_BUSY Procedure already in progress. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); /**@brief Respond to a Read/Write authorization request. * * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. * * @mscs * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. * * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update * is set to 0. * * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, * handle supplied does not match requested handle, * or invalid data to be written provided by the application. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); /**@brief Update persistent system attribute information. * * @details Supply information about persistent system attributes to the stack, * previously obtained using @ref sd_ble_gatts_sys_attr_get. * This call is only allowed for active connections, and is usually * made immediately after a connection is established with an known bonded device, * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. * * p_sysattrs may point directly to the application's stored copy of the system attributes * obtained using @ref sd_ble_gatts_sys_attr_get. * If the pointer is NULL, the system attribute info is initialized, assuming that * the application does not have any previously saved system attribute data for this device. * * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. * * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or * reset the SoftDevice to return to a known state. * * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. * * @mscs * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. * @param[in] len Size of data pointed by p_sys_attr_data, in octets. * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS * * @retval ::NRF_SUCCESS Successfully set the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. */ SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); /**@brief Retrieve persistent system attribute information from the stack. * * @details This call is used to retrieve information about values to be stored persistently by the application * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes * may be written to at any time by the peer during a connection's lifetime. * * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. * * @mscs * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} * @endmscs * * @param[in] conn_handle Connection handle of the recently terminated connection. * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS * * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. */ SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); /**@brief Retrieve the first valid user attribute handle. * * @param[out] p_handle Pointer to an integer where the handle will be stored. * * @retval ::NRF_SUCCESS Successfully retrieved the handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. */ SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); /**@brief Retrieve the attribute UUID and/or metadata. * * @param[in] handle Attribute handle * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. * * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. */ SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); /**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. * * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. * * @details The SoftDevice sets ATT_MTU to the minimum of: * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and * - The Server RX MTU value. * * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. * * @mscs * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] server_rx_mtu Server RX MTU size. * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration * used for this connection. * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request * if an ATT_MTU exchange has already been performed in the other direction. * * @retval ::NRF_SUCCESS Successfully sent response to the client. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. */ SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); /** @} */ #ifdef __cplusplus } #endif #endif // BLE_GATTS_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_hci.h ================================================ /* * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_COMMON @{ */ #ifndef BLE_HCI_H__ #define BLE_HCI_H__ #ifdef __cplusplus extern "C" { #endif /** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes * @{ */ #define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ #define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ #define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ /*0x03 Hardware Failure 0x04 Page Timeout */ #define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ #define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ #define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ #define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ /*0x09 Connection Limit Exceeded 0x0A Synchronous Connection Limit To A Device Exceeded 0x0B ACL Connection Already Exists*/ #define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ /*0x0D Connection Rejected due to Limited Resources 0x0E Connection Rejected Due To Security Reasons 0x0F Connection Rejected due to Unacceptable BD_ADDR 0x10 Connection Accept Timeout Exceeded 0x11 Unsupported Feature or Parameter Value*/ #define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ #define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ #define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ #define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ #define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ /* 0x17 Repeated Attempts 0x18 Pairing Not Allowed 0x19 Unknown LMP PDU */ #define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ /* 0x1B SCO Offset Rejected 0x1C SCO Interval Rejected 0x1D SCO Air Mode Rejected*/ #define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ #define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ /*0x20 Unsupported LMP Parameter Value 0x21 Role Change Not Allowed */ #define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ #define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ #define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ /*0x25 Encryption Mode Not Acceptable 0x26 Link Key Can Not be Changed 0x27 Requested QoS Not Supported */ #define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ #define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ #define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ /* 0x2B Reserved 0x2C QoS Unacceptable Parameter 0x2D QoS Rejected 0x2E Channel Classification Not Supported 0x2F Insufficient Security */ #define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */ /* 0x31 Reserved 0x32 Role Switch Pending 0x33 Reserved 0x34 Reserved Slot Violation 0x35 Role Switch Failed 0x36 Extended Inquiry Response Too Large 0x37 Secure Simple Pairing Not Supported By Host. 0x38 Host Busy - Pairing 0x39 Connection Rejected due to No Suitable Channel Found*/ #define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ #define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ #define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ #define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ #define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ /** @} */ #ifdef __cplusplus } #endif #endif // BLE_HCI_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_l2cap.h ================================================ /* * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) @{ @brief Definitions and prototypes for the L2CAP interface. */ #ifndef BLE_L2CAP_H__ #define BLE_L2CAP_H__ #include #include "nrf_svc.h" #include "nrf_error.h" #include "ble_ranges.h" #include "ble_types.h" #include "ble_err.h" #ifdef __cplusplus extern "C" { #endif /**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology * @{ * @details * * L2CAP SDU * - A data unit that the application can send/receive to/from a peer. * * L2CAP PDU * - A data unit that is exchanged between local and remote L2CAP entities. * It consists of L2CAP protocol control information and payload fields. * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. * * L2CAP MTU * - The maximum length of an L2CAP SDU. * * L2CAP MPS * - The maximum length of an L2CAP PDU payload field. * * Credits * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. * @} */ /**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations * @{ */ /**@brief L2CAP API SVC numbers. */ enum BLE_L2CAP_SVCS { SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */ SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */ SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */ SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */ SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */ }; /**@brief L2CAP Event IDs. */ enum BLE_L2CAP_EVTS { BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event. \n See @ref ble_l2cap_evt_ch_setup_request_t. */ BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event. \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event. \n See @ref ble_l2cap_evt_ch_setup_t. */ BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event. \n No additional event structure applies. */ BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event. \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received. \n See @ref ble_l2cap_evt_ch_credit_t. */ BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received. \n See @ref ble_l2cap_evt_ch_rx_t. */ BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted. \n See @ref ble_l2cap_evt_ch_tx_t. */ }; /** @} */ /**@addtogroup BLE_L2CAP_DEFINES Defines * @{ */ /**@brief Maximum number of L2CAP channels per connection. */ #define BLE_L2CAP_CH_COUNT_MAX (64) /**@brief Minimum L2CAP MTU, in bytes. */ #define BLE_L2CAP_MTU_MIN (23) /**@brief Minimum L2CAP MPS, in bytes. */ #define BLE_L2CAP_MPS_MIN (23) /**@brief Invalid CID. */ #define BLE_L2CAP_CID_INVALID (0x0000) /**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ #define BLE_L2CAP_CREDITS_DEFAULT (1) /**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources * @{ */ #define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ #define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ /** @} */ /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes * @{ */ #define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ #define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ #define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ #define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ #define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ #define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ #define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ #define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ #define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ #define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ #define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ #define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ /** @} */ /** @} */ /**@addtogroup BLE_L2CAP_STRUCTURES Structures * @{ */ /** * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. * * @note These parameters are set per connection, so all L2CAP channels created on this connection * will have the same parameters. * * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. */ typedef struct { uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be able to receive on L2CAP channels on connections with this configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be able to transmit on L2CAP channels on connections with this configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per L2CAP channel. The minimum value is one. */ uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission per L2CAP channel. The minimum value is one. */ uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection with this configuration. The default value is zero, the maximum value is @ref BLE_L2CAP_CH_COUNT_MAX. @note if this parameter is set to zero, all other parameters in @ref ble_l2cap_conn_cfg_t are ignored. */ } ble_l2cap_conn_cfg_t; /**@brief L2CAP channel RX parameters. */ typedef struct { uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to receive on this L2CAP channel. - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be able to receive on this L2CAP channel. - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ ble_data_t sdu_buf; /**< SDU data buffer for reception. - If @ref ble_data_t::p_data is non-NULL, initial credits are issued to the peer. - If @ref ble_data_t::p_data is NULL, no initial credits are issued to the peer. */ } ble_l2cap_ch_rx_params_t; /**@brief L2CAP channel setup parameters. */ typedef struct { ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting setup of an L2CAP channel, ignored otherwise. */ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. Used when replying to a setup request of an L2CAP channel, ignored otherwise. */ } ble_l2cap_ch_setup_params_t; /**@brief L2CAP channel TX parameters. */ typedef struct { uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to transmit on this L2CAP channel. */ uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is able to receive on this L2CAP channel. */ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able to transmit on this L2CAP channel. This is effective tx_mps, selected by the SoftDevice as MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ uint16_t credits; /**< Initial credits given by the peer. */ } ble_l2cap_ch_tx_params_t; /**@brief L2CAP Channel Setup Request event. */ typedef struct { ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ } ble_l2cap_evt_ch_setup_request_t; /**@brief L2CAP Channel Setup Refused event. */ typedef struct { uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ } ble_l2cap_evt_ch_setup_refused_t; /**@brief L2CAP Channel Setup Completed event. */ typedef struct { ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ } ble_l2cap_evt_ch_setup_t; /**@brief L2CAP Channel SDU Data Buffer Released event. */ typedef struct { ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice returns SDU data buffers supplied by the application, which have not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or @ref BLE_L2CAP_EVT_CH_TX event. */ } ble_l2cap_evt_ch_sdu_buf_released_t; /**@brief L2CAP Channel Credit received event. */ typedef struct { uint16_t credits; /**< Additional credits given by the peer. */ } ble_l2cap_evt_ch_credit_t; /**@brief L2CAP Channel received SDU event. */ typedef struct { uint16_t sdu_len; /**< Total SDU length, in bytes. */ ble_data_t sdu_buf; /**< SDU data buffer. @note If there is not enough space in the buffer (sdu_buf.len < sdu_len) then the rest of the SDU will be silently discarded by the SoftDevice. */ } ble_l2cap_evt_ch_rx_t; /**@brief L2CAP Channel transmitted SDU event. */ typedef struct { ble_data_t sdu_buf; /**< SDU data buffer. */ } ble_l2cap_evt_ch_tx_t; /**@brief L2CAP event structure. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or @ref BLE_L2CAP_CID_INVALID if not present. */ union { ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ } params; /**< Event Parameters. */ } ble_l2cap_evt_t; /** @} */ /**@addtogroup BLE_L2CAP_FUNCTIONS Functions * @{ */ /**@brief Set up an L2CAP channel. * * @details This function is used to: * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. * - Reply to a setup request of an L2CAP channel (if called in response to a * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection * Response packet to a peer. * * @note A call to this function will require the application to keep the SDU data buffer alive * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. * * @events * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} * @endevents * * @mscs * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST * event when replying to a setup request of an L2CAP channel. * - As output: local_cid for this channel. * @param[in] p_params L2CAP channel parameters. * * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). * @retval ::NRF_ERROR_NOT_FOUND CID not found. * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, * see @ref ble_l2cap_conn_cfg_t::ch_count. */ SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); /**@brief Release an L2CAP channel. * * @details This sends a Disconnection Request packet to a peer. * * @events * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} * @endevents * * @mscs * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] local_cid Local Channel ID of the L2CAP channel. * * @retval ::NRF_SUCCESS Successfully queued request for transmission. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is * in progress for the L2CAP channel). * @retval ::NRF_ERROR_NOT_FOUND CID not found. */ SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); /**@brief Receive an SDU on an L2CAP channel. * * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. * * @note A call to this function will require the application to keep the memory pointed by * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. * * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers * for reception per L2CAP channel. * * @events * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} * @endevents * * @mscs * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] local_cid Local Channel ID of the L2CAP channel. * @param[in] p_sdu_buf Pointer to the SDU data buffer. * * @retval ::NRF_SUCCESS Buffer accepted. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is * in progress for an L2CAP channel). * @retval ::NRF_ERROR_NOT_FOUND CID not found. * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a * @ref BLE_L2CAP_EVT_CH_RX event and retry. */ SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); /**@brief Transmit an SDU on an L2CAP channel. * * @note A call to this function will require the application to keep the memory pointed by * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. * * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for * transmission per L2CAP channel. * * @note The application can keep track of the available credits for transmission by following * the procedure below: * - Store initial credits given by the peer in a variable. * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) * - Decrement the variable, which stores the currently available credits, by * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) * - Increment the variable, which stores the currently available credits, by additional * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. * * @events * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} * @endevents * * @mscs * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] local_cid Local Channel ID of the L2CAP channel. * @param[in] p_sdu_buf Pointer to the SDU data buffer. * * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is * in progress for the L2CAP channel). * @retval ::NRF_ERROR_NOT_FOUND CID not found. * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in * @ref BLE_L2CAP_EVT_CH_SETUP event. * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a * @ref BLE_L2CAP_EVT_CH_TX event and retry. */ SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); /**@brief Advanced SDU reception flow control. * * @details Adjust the way the SoftDevice issues credits to the peer. * This may issue additional credits to the peer using an LE Flow Control Credit packet. * * @mscs * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set * the value that will be used for newly created channels. * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every * time it starts using a new reception buffer. * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will * use if this function is not called. * - If set to zero, the SoftDevice will stop issuing credits for new reception * buffers the application provides or has provided. SDU reception that is * currently ongoing will be allowed to complete. * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be * written by the SoftDevice with the number of credits that is or will be * available to the peer. If the value written by the SoftDevice is 0 when * credits parameter was set to 0, the peer will not be able to send more * data until more credits are provided by calling this function again with * credits > 0. This parameter is ignored when local_cid is set to * @ref BLE_L2CAP_CID_INVALID. * * @note Application should take care when setting number of credits higher than default value. In * this case the application must make sure that the SoftDevice always has reception buffers * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic * on the connection handle may be stalled until the SoftDevice again has an available * reception buffer. This applies even if the application has used this call to set the * credits back to default, or zero. * * @retval ::NRF_SUCCESS Flow control parameters accepted. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is * in progress for an L2CAP channel). * @retval ::NRF_ERROR_NOT_FOUND CID not found. */ SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); /** @} */ #ifdef __cplusplus } #endif #endif // BLE_L2CAP_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_ranges.h ================================================ /* * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_COMMON @{ @defgroup ble_ranges Module specific SVC, event and option number subranges @{ @brief Definition of SVC, event and option number subranges for each API module. @note SVCs, event and option numbers are split into subranges for each API module. Each module receives its entire allocated range of SVC calls, whether implemented or not, but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, rather than the last SVC function call actually defined and implemented. Specific SVC, event and option values are defined in each module's ble_.h file, which defines names of each individual SVC code based on the range start value. */ #ifndef BLE_RANGES_H__ #define BLE_RANGES_H__ #ifdef __cplusplus extern "C" { #endif #define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ #define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ #define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ #define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */ #define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */ #define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */ #define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */ #define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */ #define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */ #define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ #define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ #define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ #define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ #define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ #define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ #define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ #define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ #define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ #define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ #define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ #define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ #define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ #define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ #define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ #define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ #define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ #define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ #define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ #define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ #define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ #define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ #define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ #define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ #define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ #define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ #define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ #define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ #define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ #define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ #define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ #define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ #define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ #define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ #define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ #define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ #define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ #define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ #define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ #define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ #ifdef __cplusplus } #endif #endif /* BLE_RANGES_H__ */ /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/ble_types.h ================================================ /* * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup BLE_COMMON @{ @defgroup ble_types Common types and macro definitions @{ @brief Common types and macro definitions for the BLE SoftDevice. */ #ifndef BLE_TYPES_H__ #define BLE_TYPES_H__ #include #ifdef __cplusplus extern "C" { #endif /** @addtogroup BLE_TYPES_DEFINES Defines * @{ */ /** @defgroup BLE_CONN_HANDLES BLE Connection Handles * @{ */ #define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ #define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ /** @} */ /** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs * @{ */ /* Generic UUIDs, applicable to all services */ #define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ #define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ #define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ #define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ #define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ #define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ #define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ #define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ #define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ #define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ #define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ /* GATT specific UUIDs */ #define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ #define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ /* GAP specific UUIDs */ #define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ #define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ /** @} */ /** @defgroup BLE_UUID_TYPES Types of UUID * @{ */ #define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ #define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ #define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ /** @} */ /** @defgroup BLE_APPEARANCES Bluetooth Appearance values * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml * @{ */ #define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ #define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ #define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ #define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ #define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ #define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ #define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ #define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ #define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ #define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ #define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ #define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ #define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ #define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ #define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ #define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ #define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ #define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ #define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ #define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ #define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ #define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ #define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ #define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ #define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ #define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ #define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ #define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ #define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ #define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ #define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ #define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ #define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ #define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ #define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ #define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ #define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ #define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ #define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ #define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ #define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ #define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ #define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ #define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ #define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ #define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ #define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ #define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ #define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ /** @} */ /** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ #define BLE_UUID_BLE_ASSIGN(instance, value) do {\ instance.type = BLE_UUID_TYPE_BLE; \ instance.uuid = value;} while(0) /** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ #define BLE_UUID_COPY_PTR(dst, src) do {\ (dst)->type = (src)->type; \ (dst)->uuid = (src)->uuid;} while(0) /** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ #define BLE_UUID_COPY_INST(dst, src) do {\ (dst).type = (src).type; \ (dst).uuid = (src).uuid;} while(0) /** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ #define BLE_UUID_EQ(p_uuid1, p_uuid2) \ (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) /** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ #define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) /** @} */ /** @addtogroup BLE_TYPES_STRUCTURES Structures * @{ */ /** @brief 128 bit UUID values. */ typedef struct { uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ } ble_uuid128_t; /** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ typedef struct { uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ } ble_uuid_t; /**@brief Data structure. */ typedef struct { uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ uint16_t len; /**< Length of the data buffer, in bytes. */ } ble_data_t; /** @} */ #ifdef __cplusplus } #endif #endif /* BLE_TYPES_H__ */ /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf52/nrf_mbr.h ================================================ /* * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @defgroup nrf_mbr_api Master Boot Record API @{ @brief APIs for updating SoftDevice and BootLoader */ #ifndef NRF_MBR_H__ #define NRF_MBR_H__ #include "nrf_svc.h" #include #ifdef __cplusplus extern "C" { #endif /** @addtogroup NRF_MBR_DEFINES Defines * @{ */ /**@brief MBR SVC Base number. */ #define MBR_SVC_BASE (0x18) /**@brief Page size in words. */ #define MBR_PAGE_SIZE_IN_WORDS (1024) /** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. This is the offset where the first byte of the SoftDevice hex file is written. */ #define MBR_SIZE (0x1000) /** @brief Location (in the flash memory) of the bootloader address. */ #define MBR_BOOTLOADER_ADDR (0xFF8) /** @brief Location (in UICR) of the bootloader address. */ #define MBR_UICR_BOOTLOADER_ADDR (&(NRF_UICR->NRFFW[0])) /** @brief Location (in the flash memory) of the address of the MBR parameter page. */ #define MBR_PARAM_PAGE_ADDR (0xFFC) /** @brief Location (in UICR) of the address of the MBR parameter page. */ #define MBR_UICR_PARAM_PAGE_ADDR (&(NRF_UICR->NRFFW[1])) /** @} */ /** @addtogroup NRF_MBR_ENUMS Enumerations * @{ */ /**@brief nRF Master Boot Record API SVC numbers. */ enum NRF_MBR_SVCS { SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ }; /**@brief Possible values for ::sd_mbr_command_t.command */ enum NRF_MBR_COMMANDS { SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/ SD_MBR_COMMAND_RESERVED, SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/ }; /** @} */ /** @addtogroup NRF_MBR_TYPES Types * @{ */ /**@brief This command copies part of a new SoftDevice * * The destination area is erased before copying. * If dst is in the middle of a flash page, that whole flash page will be erased. * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. * * The user of this function is responsible for setting the BPROT registers. * * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. */ typedef struct { uint32_t *src; /**< Pointer to the source of data to be copied.*/ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ } sd_mbr_command_copy_sd_t; /**@brief This command works like memcmp, but takes the length in words. * * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. */ typedef struct { uint32_t *ptr1; /**< Pointer to block of memory. */ uint32_t *ptr2; /**< Pointer to block of memory. */ uint32_t len; /**< Number of 32 bit words to compare.*/ } sd_mbr_command_compare_t; /**@brief This command copies a new BootLoader. * * The MBR assumes that either @ref MBR_BOOTLOADER_ADDR or @ref MBR_UICR_BOOTLOADER_ADDR is set to * the address where the bootloader will be copied. If both addresses are set, the MBR will prioritize * @ref MBR_BOOTLOADER_ADDR. * * The bootloader destination is erased by this function. * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. * * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, * see @ref sd_mbr_command. * * This command will use the flash protect peripheral (BPROT or ACL) to protect the flash that is * not intended to be written. * * On success, this function will not return. It will start the new bootloader from reset-vector as normal. * * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. * @retval ::NRF_ERROR_FORBIDDEN if the bootloader address is not set. * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. */ typedef struct { uint32_t *bl_src; /**< Pointer to the source of the bootloader to be be copied.*/ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ } sd_mbr_command_copy_bl_t; /**@brief Change the address the MBR starts after a reset * * Once this function has been called, this address is where the MBR will start to forward * interrupts to after a reset. * * To restore default forwarding, this function should be called with @ref address set to 0. If a * bootloader is present, interrupts will be forwarded to the bootloader. If not, interrupts will * be forwarded to the SoftDevice. * * The location of a bootloader can be specified in @ref MBR_BOOTLOADER_ADDR or * @ref MBR_UICR_BOOTLOADER_ADDR. If both addresses are set, the MBR will prioritize * @ref MBR_BOOTLOADER_ADDR. * * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, * see @ref sd_mbr_command. * * On success, this function will not return. It will reset the device. * * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. */ typedef struct { uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ } sd_mbr_command_vector_table_base_set_t; /**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR * * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not * change where the MBR starts after reset. * * @retval ::NRF_SUCCESS */ typedef struct { uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ } sd_mbr_command_irq_forward_address_set_t; /**@brief Input structure containing data used when calling ::sd_mbr_command * * Depending on what command value that is set, the corresponding params value type must also be * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params. */ typedef struct { uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */ union { sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ } params; /**< Command parameters. */ } sd_mbr_command_t; /** @} */ /** @addtogroup NRF_MBR_FUNCTIONS Functions * @{ */ /**@brief Issue Master Boot Record commands * * Commands used when updating a SoftDevice and bootloader. * * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash * page. The location of the flash page should be provided by the application in either * @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR. If both addresses are set, the MBR * will prioritize @ref MBR_PARAM_PAGE_ADDR. This page will be cleared by the MBR and is used to * store the command before reset. When an address is specified, the page it refers to must not be * used by the application. If no address is provided by the application, i.e. both * @ref MBR_PARAM_PAGE_ADDR and @ref MBR_UICR_PARAM_PAGE_ADDR is 0xFFFFFFFF, MBR commands which use * flash will be unavailable and return @ref NRF_ERROR_NO_MEM. * * @param[in] param Pointer to a struct describing the command. * * @note For a complete set of return values, see ::sd_mbr_command_copy_sd_t, * ::sd_mbr_command_copy_bl_t, ::sd_mbr_command_compare_t, * ::sd_mbr_command_vector_table_base_set_t, ::sd_mbr_command_irq_forward_address_set_t * * @retval ::NRF_ERROR_NO_MEM No MBR parameter page provided * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given. */ SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); /** @} */ #ifdef __cplusplus } #endif #endif // NRF_MBR_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error.h ================================================ /* * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @defgroup nrf_error SoftDevice Global Error Codes @{ @brief Global Error definitions */ /* Header guard */ #ifndef NRF_ERROR_H__ #define NRF_ERROR_H__ #ifdef __cplusplus extern "C" { #endif /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions * @{ */ #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base #define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base #define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base #define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base /** @} */ #define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command #define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing #define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled #define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error #define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation #define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found #define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported #define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter #define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data #define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy #define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. #define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation #ifdef __cplusplus } #endif #endif // NRF_ERROR_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_sdm.h ================================================ /* * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup nrf_sdm_api @{ @defgroup nrf_sdm_error SoftDevice Manager Error Codes @{ @brief Error definitions for the SDM API */ /* Header guard */ #ifndef NRF_ERROR_SDM_H__ #define NRF_ERROR_SDM_H__ #include "nrf_error.h" #ifdef __cplusplus extern "C" { #endif #define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). #define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). #ifdef __cplusplus } #endif #endif // NRF_ERROR_SDM_H__ /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_error_soc.h ================================================ /* * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @addtogroup nrf_soc_api @{ @defgroup nrf_soc_error SoC Library Error Codes @{ @brief Error definitions for the SoC library */ /* Header guard */ #ifndef NRF_ERROR_SOC_H__ #define NRF_ERROR_SOC_H__ #include "nrf_error.h" #ifdef __cplusplus extern "C" { #endif /* Mutex Errors */ #define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken /* NVIC errors */ #define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available #define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed #define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return /* Power errors */ #define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown #define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown #define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return /* Rand errors */ #define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values /* PPI errors */ #define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel #define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group #ifdef __cplusplus } #endif #endif // NRF_ERROR_SOC_H__ /** @} @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_nvic.h ================================================ /* * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** * @defgroup nrf_nvic_api SoftDevice NVIC API * @{ * * @note In order to use this module, the following code has to be added to a .c file: * \code * nrf_nvic_state_t nrf_nvic_state = {0}; * \endcode * * @note Definitions and declarations starting with __ (double underscore) in this header file are * not intended for direct use by the application. * * @brief APIs for the accessing NVIC when using a SoftDevice. * */ #ifndef NRF_NVIC_H__ #define NRF_NVIC_H__ #include #include "nrf.h" #include "nrf_svc.h" #include "nrf_error.h" #include "nrf_error_soc.h" #ifdef __cplusplus extern "C" { #endif /**@addtogroup NRF_NVIC_DEFINES Defines * @{ */ /**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions * @{ */ #define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ /**@brief Interrupt priority levels used by the SoftDevice. */ #define __NRF_NVIC_SD_IRQ_PRIOS ((uint8_t)( \ (1U << 0) /**< Priority level high .*/ \ | (1U << 1) /**< Priority level medium. */ \ | (1U << 4) /**< Priority level low. */ \ )) /**@brief Interrupt priority levels available to the application. */ #define __NRF_NVIC_APP_IRQ_PRIOS ((uint8_t)~__NRF_NVIC_SD_IRQ_PRIOS) /**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ (1U << POWER_CLOCK_IRQn) \ | (1U << RADIO_IRQn) \ | (1U << RTC0_IRQn) \ | (1U << TIMER0_IRQn) \ | (1U << RNG_IRQn) \ | (1U << ECB_IRQn) \ | (1U << CCM_AAR_IRQn) \ | (1U << TEMP_IRQn) \ | (1U << __NRF_NVIC_NVMC_IRQn) \ | (1U << (uint32_t)SWI5_IRQn) \ )) /**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) /**@brief Interrupts available for to application, with IRQn in the range 0-31. */ #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) /**@brief Interrupts available for to application, with IRQn in the range 32-63. */ #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) /**@} */ /**@} */ /**@addtogroup NRF_NVIC_VARIABLES Variables * @{ */ /**@brief Type representing the state struct for the SoftDevice NVIC module. */ typedef struct { uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ } nrf_nvic_state_t; /**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an * application source file. */ extern nrf_nvic_state_t nrf_nvic_state; /**@} */ /**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions * @{ */ /**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. * * @retval The value of PRIMASK prior to disabling the interrupts. */ __STATIC_INLINE int __sd_nvic_irq_disable(void); /**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. */ __STATIC_INLINE void __sd_nvic_irq_enable(void); /**@brief Checks if IRQn is available to application * @param[in] IRQn IRQ to check * * @retval 1 (true) if the IRQ to check is available to the application */ __STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); /**@brief Checks if priority is available to application * @param[in] priority priority to check * * @retval 1 (true) if the priority to check is available to the application */ __STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); /**@} */ /**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions * @{ */ /**@brief Enable External Interrupt. * @note Corresponds to NVIC_EnableIRQ in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. * * @retval ::NRF_SUCCESS The interrupt was enabled. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); /**@brief Disable External Interrupt. * @note Corresponds to NVIC_DisableIRQ in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. * * @retval ::NRF_SUCCESS The interrupt was disabled. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); /**@brief Get Pending Interrupt. * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. * * @retval ::NRF_SUCCESS The interrupt is available for the application. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); /**@brief Set Pending Interrupt. * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. * * @retval ::NRF_SUCCESS The interrupt is set pending. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); /**@brief Clear Pending Interrupt. * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. * * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); /**@brief Set Interrupt Priority. * @note Corresponds to NVIC_SetPriority in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * @pre Priority is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. * @param[in] priority A valid IRQ priority for use by the application. * * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); /**@brief Get Interrupt Priority. * @note Corresponds to NVIC_GetPriority in CMSIS. * * @pre IRQn is valid and not reserved by the stack. * * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. * @param[out] p_priority Return value from NVIC_GetPriority. * * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. */ __STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); /**@brief System Reset. * @note Corresponds to NVIC_SystemReset in CMSIS. * * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN */ __STATIC_INLINE uint32_t sd_nvic_SystemReset(void); /**@brief Enter critical region. * * @post Application interrupts will be disabled. * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each * execution context * @sa sd_nvic_critical_region_exit * * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. * * @retval ::NRF_SUCCESS */ __STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); /**@brief Exit critical region. * * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. * * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. * * @retval ::NRF_SUCCESS */ __STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); /**@} */ #ifndef SUPPRESS_INLINE_IMPLEMENTATION __STATIC_INLINE int __sd_nvic_irq_disable(void) { int pm = __get_PRIMASK(); __disable_irq(); return pm; } __STATIC_INLINE void __sd_nvic_irq_enable(void) { __enable_irq(); } __STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) { if (IRQn < 32) { return ((1UL<= (1 << __NVIC_PRIO_BITS)) || (((1 << priority) & __NRF_NVIC_APP_IRQ_PRIOS) == 0) ) { return 0; } return 1; } __STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) { if (!__sd_nvic_app_accessible_irq(IRQn)) { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) { return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; } if (nrf_nvic_state.__cr_flag) { nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); } else { NVIC_EnableIRQ(IRQn); } return NRF_SUCCESS; } __STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) { if (!__sd_nvic_app_accessible_irq(IRQn)) { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } if (nrf_nvic_state.__cr_flag) { nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); } else { NVIC_DisableIRQ(IRQn); } return NRF_SUCCESS; } __STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) { if (__sd_nvic_app_accessible_irq(IRQn)) { *p_pending_irq = NVIC_GetPendingIRQ(IRQn); return NRF_SUCCESS; } else { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } } __STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) { if (__sd_nvic_app_accessible_irq(IRQn)) { NVIC_SetPendingIRQ(IRQn); return NRF_SUCCESS; } else { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } } __STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) { if (__sd_nvic_app_accessible_irq(IRQn)) { NVIC_ClearPendingIRQ(IRQn); return NRF_SUCCESS; } else { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } } __STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) { if (!__sd_nvic_app_accessible_irq(IRQn)) { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } if (!__sd_nvic_is_app_accessible_priority(priority)) { return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; } NVIC_SetPriority(IRQn, (uint32_t)priority); return NRF_SUCCESS; } __STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) { if (__sd_nvic_app_accessible_irq(IRQn)) { *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); return NRF_SUCCESS; } else { return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; } } __STATIC_INLINE uint32_t sd_nvic_SystemReset(void) { NVIC_SystemReset(); return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; } __STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) { int was_masked = __sd_nvic_irq_disable(); if (!nrf_nvic_state.__cr_flag) { nrf_nvic_state.__cr_flag = 1; nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; *p_is_nested_critical_region = 0; } else { *p_is_nested_critical_region = 1; } if (!was_masked) { __sd_nvic_irq_enable(); } return NRF_SUCCESS; } __STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) { if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) { int was_masked = __sd_nvic_irq_disable(); NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; nrf_nvic_state.__cr_flag = 0; if (!was_masked) { __sd_nvic_irq_enable(); } } return NRF_SUCCESS; } #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ #ifdef __cplusplus } #endif #endif // NRF_NVIC_H__ /**@} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_sdm.h ================================================ /* * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** @defgroup nrf_sdm_api SoftDevice Manager API @{ @brief APIs for SoftDevice management. */ #ifndef NRF_SDM_H__ #define NRF_SDM_H__ #include #include "nrf.h" #include "nrf_svc.h" #include "nrf_error.h" #include "nrf_error_sdm.h" #include "nrf_soc.h" #ifdef __cplusplus extern "C" { #endif /** @addtogroup NRF_SDM_DEFINES Defines * @{ */ #ifdef NRFSOC_DOXYGEN /// Declared in nrf_mbr.h #define MBR_SIZE 0 #warning test #endif /** @brief The major version for the SoftDevice binary distributed with this header file. */ #define SD_MAJOR_VERSION (6) /** @brief The minor version for the SoftDevice binary distributed with this header file. */ #define SD_MINOR_VERSION (1) /** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ #define SD_BUGFIX_VERSION (1) /** @brief The SoftDevice variant of this firmware. */ #define SD_VARIANT_ID 140 /** @brief The full version number for the SoftDevice binary this header file was distributed * with, as a decimal number in the form Mmmmbbb, where: * - M is major version (one or more digits) * - mmm is minor version (three digits) * - bbb is bugfix version (three digits). */ #define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) /** @brief SoftDevice Manager SVC Base number. */ #define SDM_SVC_BASE 0x10 /** @brief SoftDevice unique string size in bytes. */ #define SD_UNIQUE_STR_SIZE 20 /** @brief Invalid info field. Returned when an info field does not exist. */ #define SDM_INFO_FIELD_INVALID (0) /** @brief Defines the SoftDevice Information Structure location (address) as an offset from the start of the SoftDevice (without MBR)*/ #define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) /** @brief Defines the absolute SoftDevice Information Structure location (address) when the * SoftDevice is installed just above the MBR (the usual case). */ #define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) /** @brief Defines the offset for the SoftDevice Information Structure size value relative to the * SoftDevice base address. The size value is of type uint8_t. */ #define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) /** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. * The size value is of type uint32_t. */ #define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) /** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value * is of type uint16_t. */ #define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) /** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID * is of type uint32_t. */ #define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) /** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in * the same format as @ref SD_VERSION, stored as an uint32_t. */ #define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) /** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. */ #define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) /** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is * installed just above the MBR (the usual case). */ #define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) /** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above * the MBR (the usual case). */ #define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) /** @brief Defines the amount of flash that is used by the SoftDevice. * Add @ref MBR_SIZE to find the first available flash address when the SoftDevice is installed * just above the MBR (the usual case). */ #define SD_FLASH_SIZE 0x25000 /** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual * case). */ #define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) /** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the * usual case). */ #define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) /** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR * (the usual case). */ #define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) /** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR * (the usual case). */ #define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID) /**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges * @{ */ #define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ #define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ /**@} */ /**@defgroup NRF_FAULT_IDS Fault ID types * @{ */ #define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ #define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000, in case of SoftDevice RAM access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the disallowed write access caused the memory access fault. */ /**@} */ /** @} */ /** @addtogroup NRF_SDM_ENUMS Enumerations * @{ */ /**@brief nRF SoftDevice Manager API SVC numbers. */ enum NRF_SD_SVCS { SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ SVC_SDM_LAST /**< Placeholder for last SDM SVC */ }; /** @} */ /** @addtogroup NRF_SDM_DEFINES Defines * @{ */ /**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy * @{ */ #define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ #define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ #define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ #define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ #define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ #define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ #define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ #define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ #define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ #define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ #define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ #define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ /** @} */ /**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources * @{ */ #define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ #define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ #define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ /** @} */ /** @} */ /** @addtogroup NRF_SDM_TYPES Types * @{ */ /**@brief Type representing LFCLK oscillator source. */ typedef struct { uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second units (nRF52: 1-32). @note To avoid excessive clock drift, 0.5 degrees Celsius is the maximum temperature change allowed in one calibration timer interval. The interval should be selected to ensure this. @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */ uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration intervals) the RC oscillator shall be calibrated if the temperature hasn't changed. 0: Always calibrate even if the temperature hasn't changed. 1: Only calibrate if the temperature has changed (legacy - nRF51 only). 2-33: Check the temperature and only calibrate if it has changed, however calibration will take place every rc_temp_ctiv intervals in any case. @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. @note For nRF52, the application must ensure calibration at least once every 8 seconds to ensure +/-500 ppm clock stability. The recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at least once every 8 seconds and for temperature changes of 0.5 degrees Celsius every 4 seconds. See the Product Specification for the nRF52 device being used for more information.*/ uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ } nrf_clock_lf_cfg_t; /**@brief Fault Handler type. * * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. * The protocol stack will be in an undefined state when this happens and the only way to recover will be to * perform a reset, using e.g. CMSIS NVIC_SystemReset(). * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). * * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. * * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. * @param[in] pc The program counter of the instruction that triggered the fault. * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. * * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. */ typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); /** @} */ /** @addtogroup NRF_SDM_FUNCTIONS Functions * @{ */ /**@brief Enables the SoftDevice and by extension the protocol stack. * * @note Some care must be taken if a low frequency clock source is already running when calling this function: * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new * clock source will be started. * * @note This function has no effect when returning with an error. * * @post If return code is ::NRF_SUCCESS * - SoC library and protocol stack APIs are made available. * - A portion of RAM will be unavailable (see relevant SDS documentation). * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). * - Interrupts will not arrive from protected peripherals or interrupts. * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). * - Chosen low frequency clock source will be running. * * @param p_clock_lf_cfg Low frequency clock source and accuracy. If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. * * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg. */ SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); /**@brief Disables the SoftDevice and by extension the protocol stack. * * Idempotent function to disable the SoftDevice. * * @post SoC library and protocol stack APIs are made unavailable. * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). * @post All peripherals used by the SoftDevice will be reset to default values. * @post All of RAM become available. * @post All interrupts are forwarded to the application. * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. * * @retval ::NRF_SUCCESS */ SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); /**@brief Check if the SoftDevice is enabled. * * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. * * @retval ::NRF_SUCCESS */ SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); /**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice * * This function is only intended to be called when a bootloader is enabled. * * @param[in] address The base address of the interrupt vector table for forwarded interrupts. * @retval ::NRF_SUCCESS */ SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); /** @} */ #ifdef __cplusplus } #endif #endif // NRF_SDM_H__ /** @} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_soc.h ================================================ /* * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ /** * @defgroup nrf_soc_api SoC Library API * @{ * * @brief APIs for the SoC library. * */ #ifndef NRF_SOC_H__ #define NRF_SOC_H__ #include #include "nrf.h" #include "nrf_svc.h" #include "nrf_error.h" #include "nrf_error_soc.h" #ifdef __cplusplus extern "C" { #endif /**@addtogroup NRF_SOC_DEFINES Defines * @{ */ /**@brief The number of the lowest SVC number reserved for the SoC library. */ #define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ #define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ /**@brief Guaranteed time for application to process radio inactive notification. */ #define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) /**@brief The minimum allowed timeslot extension time. */ #define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) /**@brief The maximum processing time to handle a timeslot extension. */ #define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17) /**@brief The latest time before the end of a timeslot the timeslot can be extended. */ #define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79) #define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ #define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ #define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ #define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ #define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. The default interrupt priority for this handler is set to 6 */ #define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ #define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. The default interrupt priority for this handler is set to 6 */ #define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ #define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ #define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ #define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ #define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ /**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is disabled. */ #define NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK ((uint32_t)(0)) /**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is enabled. */ #define NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK ((uint32_t)( \ (1U << 17) \ | (1U << 18) \ | (1U << 19) \ | (1U << 20) \ | (1U << 21) \ | (1U << 22) \ | (1U << 23) \ | (1U << 24) \ | (1U << 25) \ | (1U << 26) \ | (1U << 27) \ | (1U << 28) \ | (1U << 29) \ | (1U << 30) \ | (1U << 31) \ )) /**@brief Mask of PPI channels available to the application when the SoftDevice is disabled. */ #define NRF_SOC_APP_PPI_CHANNELS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK) /**@brief Mask of PPI channels available to the application when the SoftDevice is enabled. */ #define NRF_SOC_APP_PPI_CHANNELS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK) /**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is disabled. */ #define NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK ((uint32_t)(0)) /**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is enabled. */ #define NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK ((uint32_t)( \ (1U << 4) \ | (1U << 5) \ )) /**@brief Mask of PPI groups available to the application when the SoftDevice is disabled. */ #define NRF_SOC_APP_PPI_GROUPS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK) /**@brief Mask of PPI groups available to the application when the SoftDevice is enabled. */ #define NRF_SOC_APP_PPI_GROUPS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK) /**@} */ /**@addtogroup NRF_SOC_ENUMS Enumerations * @{ */ /**@brief The SVC numbers used by the SVC functions in the SoC library. */ enum NRF_SOC_SVCS { SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1, SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2, SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3, SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4, SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5, SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6, SD_PPI_GROUP_GET = SOC_SVC_BASE + 7, SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8, SD_FLASH_WRITE = SOC_SVC_BASE + 9, SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11, SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1, SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2, SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3, SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4, SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5, SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6, SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7, SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8, SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9, SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10, SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11, SD_POWER_POF_THRESHOLDVDDH_SET = SOC_SVC_BASE_NOT_AVAILABLE + 12, SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13, SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14, SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15, SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16, SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17, SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18, SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19, SD_POWER_DCDC0_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 20, SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21, SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22, SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23, SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24, SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25, SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26, SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27, SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28, SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29, SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30, SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31, SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32, SD_POWER_USBPWRRDY_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 33, SD_POWER_USBDETECTED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 34, SD_POWER_USBREMOVED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 35, SD_POWER_USBREGSTATUS_GET = SOC_SVC_BASE_NOT_AVAILABLE + 36, SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37 }; /**@brief Possible values of a ::nrf_mutex_t. */ enum NRF_MUTEX_VALUES { NRF_MUTEX_FREE, NRF_MUTEX_TAKEN }; /**@brief Power modes. */ enum NRF_POWER_MODES { NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ }; /**@brief Power failure thresholds */ enum NRF_POWER_THRESHOLDS { NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ }; /**@brief Power failure thresholds for high voltage */ enum NRF_POWER_THRESHOLDVDDHS { NRF_POWER_THRESHOLDVDDH_V27, /**< 2.7 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V28, /**< 2.8 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V29, /**< 2.9 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V30, /**< 3.0 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V31, /**< 3.1 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V32, /**< 3.2 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V33, /**< 3.3 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V34, /**< 3.4 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V35, /**< 3.5 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V36, /**< 3.6 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V37, /**< 3.7 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V38, /**< 3.8 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V39, /**< 3.9 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V40, /**< 4.0 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V41, /**< 4.1 Volts power failure threshold. */ NRF_POWER_THRESHOLDVDDH_V42 /**< 4.2 Volts power failure threshold. */ }; /**@brief DC/DC converter modes. */ enum NRF_POWER_DCDC_MODES { NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ }; /**@brief Radio notification distances. */ enum NRF_RADIO_NOTIFICATION_DISTANCES { NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ }; /**@brief Radio notification types. */ enum NRF_RADIO_NOTIFICATION_TYPES { NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ }; /**@brief The Radio signal callback types. */ enum NRF_RADIO_CALLBACK_SIGNAL_TYPE { NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ }; /**@brief The actions requested by the signal callback. * * This code gives the SOC instructions about what action to take when the signal callback has * returned. */ enum NRF_RADIO_SIGNAL_CALLBACK_ACTION { NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot. Maximum execution time for this action: @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. This action must be started at least @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before the end of the timeslot. */ NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ }; /**@brief Radio timeslot high frequency clock source configuration. */ enum NRF_RADIO_HFCLK_CFG { NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the external crystal for the whole duration of the timeslot. This should be the preferred option for events that use the radio or require high timing accuracy. @note The SoftDevice will automatically turn on and off the external crystal, at the beginning and end of the timeslot, respectively. The crystal may also intentionally be left running after the timeslot, in cases where it is needed by the SoftDevice shortly after the end of the timeslot. */ NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. The RC oscillator may be the clock source in part or for the whole duration of the timeslot. The RC oscillator's accuracy must therefore be taken into consideration. @note If the application will use the radio peripheral in timeslots with this configuration, it must make sure that the crystal is running and stable before starting the radio. */ }; /**@brief Radio timeslot priorities. */ enum NRF_RADIO_PRIORITY { NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ }; /**@brief Radio timeslot request type. */ enum NRF_RADIO_REQUEST_TYPE { NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ }; /**@brief SoC Events. */ enum NRF_SOC_EVTS { NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ NRF_EVT_POWER_USB_POWER_READY, /**< Event indicating that a USB 3.3 V supply is ready. */ NRF_EVT_POWER_USB_DETECTED, /**< Event indicating that voltage supply is detected on VBUS. */ NRF_EVT_POWER_USB_REMOVED, /**< Event indicating that voltage supply is removed from VBUS. */ NRF_EVT_NUMBER_OF_EVTS }; /**@} */ /**@addtogroup NRF_SOC_STRUCTURES Structures * @{ */ /**@brief Represents a mutex for use with the nrf_mutex functions. * @note Accessing the value directly is not safe, use the mutex functions! */ typedef volatile uint8_t nrf_mutex_t; /**@brief Parameters for a request for a timeslot as early as possible. */ typedef struct { uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ } nrf_radio_request_earliest_t; /**@brief Parameters for a normal radio timeslot request. */ typedef struct { uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ } nrf_radio_request_normal_t; /**@brief Radio timeslot request parameters. */ typedef struct { uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ union { nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ } params; /**< Parameter union. */ } nrf_radio_request_t; /**@brief Return parameters of the radio timeslot signal callback. */ typedef struct { uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ union { struct { nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ struct { uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ } params; /**< Parameter union. */ } nrf_radio_signal_callback_return_param_t; /**@brief The radio timeslot signal callback type. * * @note In case of invalid return parameters, the radio timeslot will automatically end * immediately after returning from the signal callback and the * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. * @note The returned struct pointer must remain valid after the signal callback * function returns. For instance, this means that it must not point to a stack variable. * * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. * * @return Pointer to structure containing action requested by the application. */ typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); /**@brief AES ECB parameter typedefs */ typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ /**@brief AES ECB data structure */ typedef struct { soc_ecb_key_t key; /**< Encryption key. */ soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ } nrf_ecb_hal_data_t; /**@brief AES ECB block. Used to provide multiple blocks in a single call to @ref sd_ecb_blocks_encrypt.*/ typedef struct { soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ } nrf_ecb_hal_data_block_t; /**@} */ /**@addtogroup NRF_SOC_FUNCTIONS Functions * @{ */ /**@brief Initialize a mutex. * * @param[in] p_mutex Pointer to the mutex to initialize. * * @retval ::NRF_SUCCESS */ SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); /**@brief Attempt to acquire a mutex. * * @param[in] p_mutex Pointer to the mutex to acquire. * * @retval ::NRF_SUCCESS The mutex was successfully acquired. * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. */ SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); /**@brief Release a mutex. * * @param[in] p_mutex Pointer to the mutex to release. * * @retval ::NRF_SUCCESS */ SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); /**@brief Query the capacity of the application random pool. * * @param[out] p_pool_capacity The capacity of the pool. * * @retval ::NRF_SUCCESS */ SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); /**@brief Get number of random bytes available to the application. * * @param[out] p_bytes_available The number of bytes currently available in the pool. * * @retval ::NRF_SUCCESS */ SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); /**@brief Get random bytes from the application pool. * * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. * @param[in] length Number of bytes to take from pool and place in p_buff. * * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. */ SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); /**@brief Gets the reset reason register. * * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); /**@brief Clears the bits of the reset reason register. * * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); /**@brief Sets the power mode when in CPU sleep. * * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait * * @retval ::NRF_SUCCESS The power mode was set. * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. */ SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); /**@brief Puts the chip in System OFF mode. * * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN */ SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); /**@brief Enables or disables the power-fail comparator. * * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. * The event can be retrieved with sd_evt_get(); * * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); /**@brief Enables or disables the USB power ready event. * * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_POWER_READY) when a USB 3.3 V supply is ready. * The event can be retrieved with sd_evt_get(); * * @param[in] usbpwrrdy_enable True if the power ready event should be enabled, false if it should be disabled. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_USBPWRRDY_ENABLE, uint32_t, sd_power_usbpwrrdy_enable(uint8_t usbpwrrdy_enable)); /**@brief Enables or disables the power USB-detected event. * * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_DETECTED) when a voltage supply is detected on VBUS. * The event can be retrieved with sd_evt_get(); * * @param[in] usbdetected_enable True if the power ready event should be enabled, false if it should be disabled. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_USBDETECTED_ENABLE, uint32_t, sd_power_usbdetected_enable(uint8_t usbdetected_enable)); /**@brief Enables or disables the power USB-removed event. * * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_REMOVED) when a voltage supply is removed from VBUS. * The event can be retrieved with sd_evt_get(); * * @param[in] usbremoved_enable True if the power ready event should be enabled, false if it should be disabled. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_USBREMOVED_ENABLE, uint32_t, sd_power_usbremoved_enable(uint8_t usbremoved_enable)); /**@brief Get USB supply status register content. * * @param[out] usbregstatus The content of USBREGSTATUS register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_USBREGSTATUS_GET, uint32_t, sd_power_usbregstatus_get(uint32_t * usbregstatus)); /**@brief Sets the power failure comparator threshold value. * * @note: Power failure comparator threshold setting. This setting applies both for normal voltage * mode (supply connected to both VDD and VDDH) and high voltage mode (supply connected to * VDDH only). * * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. * * @retval ::NRF_SUCCESS The power failure threshold was set. * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. */ SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); /**@brief Sets the power failure comparator threshold value for high voltage. * * @note: Power failure comparator threshold setting for high voltage mode (supply connected to * VDDH only). This setting does not apply for normal voltage mode (supply connected to both * VDD and VDDH). * * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDVDDHS. * * @retval ::NRF_SUCCESS The power failure threshold was set. * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. */ SVCALL(SD_POWER_POF_THRESHOLDVDDH_SET, uint32_t, sd_power_pof_thresholdvddh_set(uint8_t threshold)); /**@brief Writes the NRF_POWER->RAM[index].POWERSET register. * * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); /**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. * * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); /**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. * * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); /**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). * * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[in] gpregret_msk Bits to be set in the GPREGRET register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); /**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). * * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); /**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). * * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[out] p_gpregret Contents of the GPREGRET register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); /**@brief Enable or disable the DC/DC regulator for the regulator stage 1 (REG1). * * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. * * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. */ SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); /**@brief Enable or disable the DC/DC regulator for the regulator stage 0 (REG0). * * For more details on the REG0 stage, please see product specification. * * @param[in] dcdc_mode The mode of the DCDC0, see @ref NRF_POWER_DCDC_MODES. * * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INVALID_PARAM The dcdc_mode is invalid. */ SVCALL(SD_POWER_DCDC0_MODE_SET, uint32_t, sd_power_dcdc0_mode_set(uint8_t dcdc_mode)); /**@brief Request the high frequency crystal oscillator. * * Will start the high frequency crystal oscillator, the startup time of the crystal varies * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. * * @see sd_clock_hfclk_is_running * @see sd_clock_hfclk_release * * @retval ::NRF_SUCCESS */ SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); /**@brief Releases the high frequency crystal oscillator. * * Will stop the high frequency crystal oscillator, this happens immediately. * * @see sd_clock_hfclk_is_running * @see sd_clock_hfclk_request * * @retval ::NRF_SUCCESS */ SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); /**@brief Checks if the high frequency crystal oscillator is running. * * @see sd_clock_hfclk_request * @see sd_clock_hfclk_release * * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. * * @retval ::NRF_SUCCESS */ SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); /**@brief Waits for an application event. * * An application event is either an application interrupt or a pended interrupt when the interrupt * is disabled. * * When the application waits for an application event by calling this function, an interrupt that * is enabled will be taken immediately on pending since this function will wait in thread mode, * then the execution will return in the application's main thread. * * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets * pended, this function will return to the application's main thread. * * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ * in order to sleep using this function. This is only necessary for disabled interrupts, as * the interrupt handler will clear the pending flag automatically for enabled interrupts. * * @note If an application interrupt has happened since the last time sd_app_evt_wait was * called this function will return immediately and not go to sleep. This is to avoid race * conditions that can occur when a flag is updated in the interrupt handler and processed * in the main loop. * * @post An application interrupt has happened or a interrupt pending flag is set. * * @retval ::NRF_SUCCESS */ SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); /**@brief Get PPI channel enable register contents. * * @param[out] p_channel_enable The contents of the PPI CHEN register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); /**@brief Set PPI channel enable register. * * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); /**@brief Clear PPI channel enable register. * * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. * * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); /**@brief Assign endpoints to a PPI channel. * * @param[in] channel_num Number of the PPI channel to assign. * @param[in] evt_endpoint Event endpoint of the PPI channel. * @param[in] task_endpoint Task endpoint of the PPI channel. * * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); /**@brief Task to enable a channel group. * * @param[in] group_num Number of the channel group. * * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); /**@brief Task to disable a channel group. * * @param[in] group_num Number of the PPI group. * * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); /**@brief Assign PPI channels to a channel group. * * @param[in] group_num Number of the channel group. * @param[in] channel_msk Mask of the channels to assign to the group. * * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); /**@brief Gets the PPI channels of a channel group. * * @param[in] group_num Number of the channel group. * @param[out] p_channel_msk Mask of the channels assigned to the group. * * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. * @retval ::NRF_SUCCESS */ SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); /**@brief Configures the Radio Notification signal. * * @note * - The notification signal latency depends on the interrupt priority settings of SWI used * for notification signal. * - To ensure that the radio notification signal behaves in a consistent way, the radio * notifications must be configured when there is no protocol stack or other SoftDevice * activity in progress. It is recommended that the radio notification signal is * configured directly after the SoftDevice has been enabled. * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice * will interrupt the application to do Radio Event preparation. * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have * to shorten the connection events to have time for the Radio Notification signals. * * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is * recommended (but not required) to be used with * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. * * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. * * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all * running activities and retry. * @retval ::NRF_SUCCESS */ SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); /**@brief Encrypts a block according to the specified parameters. * * 128-bit AES encryption. * * @note: * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application * main or low interrupt level. * * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input * parameters and one output parameter). * * @retval ::NRF_SUCCESS */ SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); /**@brief Encrypts multiple data blocks provided as an array of data block structures. * * @details: Performs 128-bit AES encryption on multiple data blocks * * @note: * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application * main or low interrupt level. * * @param[in] block_count Count of blocks in the p_data_blocks array. * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of * @ref nrf_ecb_hal_data_block_t structures. * * @retval ::NRF_SUCCESS */ SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); /**@brief Gets any pending events generated by the SoC API. * * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. * * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. * * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. * @retval ::NRF_ERROR_NOT_FOUND No pending events. */ SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); /**@brief Get the temperature measured on the chip * * This function will block until the temperature measurement is done. * It takes around 50 us from call to return. * * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. * * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp */ SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); /**@brief Flash Write * * Commands to write a buffer to flash * * If the SoftDevice is enabled: * This call initiates the flash access command, and its completion will be communicated to the * application with exactly one of the following events: * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. * * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the * write has been completed * * @note * - This call takes control over the radio and the CPU during flash erase and write to make sure that * they will not interfere with the flash access. This means that all interrupts will be blocked * for a predictable time (depending on the NVMC specification in the device's Product Specification * and the command parameters). * - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS * or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. * - This call will make the SoftDevice trigger a hardfault when the page is written, if it is * protected. * * * @param[in] p_dst Pointer to start of flash location to be written. * @param[in] p_src Pointer to buffer with data to be written. * @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one * flash page. See the device's Product Specification for details. * * @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. * @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. * @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area. * @retval ::NRF_SUCCESS The command was accepted. */ SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); /**@brief Flash Erase page * * Commands to erase a flash page * If the SoftDevice is enabled: * This call initiates the flash access command, and its completion will be communicated to the * application with exactly one of the following events: * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. * * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the * erase has been completed * * @note * - This call takes control over the radio and the CPU during flash erase and write to make sure that * they will not interfere with the flash access. This means that all interrupts will be blocked * for a predictable time (depending on the NVMC specification in the device's Product Specification * and the command parameters). * - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is * protected. * * * @param[in] page_number Page number of the page to erase * * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. * @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. * @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area. * @retval ::NRF_SUCCESS The command was accepted. */ SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); /**@brief Opens a session for radio timeslot requests. * * @note Only one session can be open at a time. * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed * by the application. * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 * interrupt occurs. * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO * interrupt occurs. * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). * * @param[in] p_radio_signal_callback The signal callback. * * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. * @retval ::NRF_ERROR_BUSY If session cannot be opened. * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. * @retval ::NRF_SUCCESS Otherwise. */ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); /**@brief Closes a session for radio timeslot requests. * * @note Any current radio timeslot will be finished before the session is closed. * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED * event is received. * * @retval ::NRF_ERROR_FORBIDDEN If session not opened. * @retval ::NRF_ERROR_BUSY If session is currently being closed. * @retval ::NRF_SUCCESS Otherwise. */ SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); /**@brief Requests a radio timeslot. * * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by * p_request->distance_us and is given relative to the start of the previous timeslot. * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. * The application may then try to schedule the first radio timeslot again. * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the * specified radio timeslot start, but this does not affect the actual start time of the timeslot. * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is * guaranteed to be clocked from the external crystal. * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral * during the radio timeslot. * * @param[in] p_request Pointer to the request parameters. * * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. * @retval ::NRF_SUCCESS Otherwise. */ SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); /**@brief Write register protected by the SoftDevice * * This function writes to a register that is write-protected by the SoftDevice. Please refer to your * SoftDevice Specification for more details about which registers that are protected by SoftDevice. * This function can write to the following protected peripheral: * - ACL * * @note Protected registers may be read directly. * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in * the register has not changed. See the Product Specification for more details about register * properties. * * @param[in] p_register Pointer to register to be written. * @param[in] value Value to be written to the register. * * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register. * @retval ::NRF_SUCCESS Value successfully written to register. * */ SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value)); /**@} */ #ifdef __cplusplus } #endif #endif // NRF_SOC_H__ /**@} */ ================================================ FILE: hw/mcu/nordic/nrf5x/s140_nrf52_6.1.1_API/include/nrf_svc.h ================================================ /* * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA * 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, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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. */ #ifndef NRF_SVC__ #define NRF_SVC__ #include "stdint.h" #ifdef __cplusplus extern "C" { #endif #ifdef SVCALL_AS_NORMAL_FUNCTION #define SVCALL(number, return_type, signature) return_type signature #else #ifndef SVCALL #if defined (__CC_ARM) #define SVCALL(number, return_type, signature) return_type __svc(number) signature #elif defined (__GNUC__) #ifdef __cplusplus #define GCC_CAST_CPP (uint16_t) #else #define GCC_CAST_CPP #endif #define SVCALL(number, return_type, signature) \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ __attribute__((naked)) \ __attribute__((unused)) \ static return_type signature \ { \ __asm( \ "svc %0\n" \ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ ); \ } \ _Pragma("GCC diagnostic pop") #elif defined (__ICCARM__) #define PRAGMA(x) _Pragma(#x) #define SVCALL(number, return_type, signature) \ PRAGMA(swi_number = (number)) \ __swi return_type signature; #else #define SVCALL(number, return_type, signature) return_type signature #endif #endif // SVCALL #endif // SVCALL_AS_NORMAL_FUNCTION #ifdef __cplusplus } #endif #endif // NRF_SVC__ ================================================ FILE: hw/mcu/sony/cxd56/mkspk/.gitignore ================================================ /mkspk /mkspk.exe ================================================ FILE: hw/mcu/sony/cxd56/mkspk/Makefile ================================================ ############################################################################ # tools/mkspk/Makefile # # Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # 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. Neither the name NuttX nor the names of its contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "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 # COPYRIGHT OWNER OR CONTRIBUTORS 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. # ############################################################################ all: mkspk default: mkspk .PHONY: clean # Add CFLAGS=-g on the make command line to build debug versions CFLAGS = -O2 -Wall -I. # mkspk - Convert nuttx.hex image to nuttx.spk image mkspk: @gcc $(CFLAGS) -o mkspk mkspk.c clefia.c clean: @rm -f *.o *.a *.dSYM *~ .*.swp @rm -f mkspk mkspk.exe ================================================ FILE: hw/mcu/sony/cxd56/mkspk/clefia.c ================================================ /**************************************************************************** * tools/cxd56/clefia.c * * Copyright (C) 2007, 2008 Sony Corporation * * 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. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 * COPYRIGHT OWNER OR CONTRIBUTORS 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. *****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include "clefia.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define clefiamul4(_x) (clefiamul2(clefiamul2((_x)))) #define clefiamul6(_x) (clefiamul2((_x)) ^ clefiamul4((_x))) #define clefiamul8(_x) (clefiamul2(clefiamul4((_x)))) #define clefiamula(_x) (clefiamul2((_x)) ^ clefiamul8((_x))) /**************************************************************************** * Private Data ****************************************************************************/ /* S0 (8-bit S-box based on four 4-bit S-boxes) */ static const unsigned char clefia_s0[256] = { 0x57u, 0x49u, 0xd1u, 0xc6u, 0x2fu, 0x33u, 0x74u, 0xfbu, 0x95u, 0x6du, 0x82u, 0xeau, 0x0eu, 0xb0u, 0xa8u, 0x1cu, 0x28u, 0xd0u, 0x4bu, 0x92u, 0x5cu, 0xeeu, 0x85u, 0xb1u, 0xc4u, 0x0au, 0x76u, 0x3du, 0x63u, 0xf9u, 0x17u, 0xafu, 0xbfu, 0xa1u, 0x19u, 0x65u, 0xf7u, 0x7au, 0x32u, 0x20u, 0x06u, 0xceu, 0xe4u, 0x83u, 0x9du, 0x5bu, 0x4cu, 0xd8u, 0x42u, 0x5du, 0x2eu, 0xe8u, 0xd4u, 0x9bu, 0x0fu, 0x13u, 0x3cu, 0x89u, 0x67u, 0xc0u, 0x71u, 0xaau, 0xb6u, 0xf5u, 0xa4u, 0xbeu, 0xfdu, 0x8cu, 0x12u, 0x00u, 0x97u, 0xdau, 0x78u, 0xe1u, 0xcfu, 0x6bu, 0x39u, 0x43u, 0x55u, 0x26u, 0x30u, 0x98u, 0xccu, 0xddu, 0xebu, 0x54u, 0xb3u, 0x8fu, 0x4eu, 0x16u, 0xfau, 0x22u, 0xa5u, 0x77u, 0x09u, 0x61u, 0xd6u, 0x2au, 0x53u, 0x37u, 0x45u, 0xc1u, 0x6cu, 0xaeu, 0xefu, 0x70u, 0x08u, 0x99u, 0x8bu, 0x1du, 0xf2u, 0xb4u, 0xe9u, 0xc7u, 0x9fu, 0x4au, 0x31u, 0x25u, 0xfeu, 0x7cu, 0xd3u, 0xa2u, 0xbdu, 0x56u, 0x14u, 0x88u, 0x60u, 0x0bu, 0xcdu, 0xe2u, 0x34u, 0x50u, 0x9eu, 0xdcu, 0x11u, 0x05u, 0x2bu, 0xb7u, 0xa9u, 0x48u, 0xffu, 0x66u, 0x8au, 0x73u, 0x03u, 0x75u, 0x86u, 0xf1u, 0x6au, 0xa7u, 0x40u, 0xc2u, 0xb9u, 0x2cu, 0xdbu, 0x1fu, 0x58u, 0x94u, 0x3eu, 0xedu, 0xfcu, 0x1bu, 0xa0u, 0x04u, 0xb8u, 0x8du, 0xe6u, 0x59u, 0x62u, 0x93u, 0x35u, 0x7eu, 0xcau, 0x21u, 0xdfu, 0x47u, 0x15u, 0xf3u, 0xbau, 0x7fu, 0xa6u, 0x69u, 0xc8u, 0x4du, 0x87u, 0x3bu, 0x9cu, 0x01u, 0xe0u, 0xdeu, 0x24u, 0x52u, 0x7bu, 0x0cu, 0x68u, 0x1eu, 0x80u, 0xb2u, 0x5au, 0xe7u, 0xadu, 0xd5u, 0x23u, 0xf4u, 0x46u, 0x3fu, 0x91u, 0xc9u, 0x6eu, 0x84u, 0x72u, 0xbbu, 0x0du, 0x18u, 0xd9u, 0x96u, 0xf0u, 0x5fu, 0x41u, 0xacu, 0x27u, 0xc5u, 0xe3u, 0x3au, 0x81u, 0x6fu, 0x07u, 0xa3u, 0x79u, 0xf6u, 0x2du, 0x38u, 0x1au, 0x44u, 0x5eu, 0xb5u, 0xd2u, 0xecu, 0xcbu, 0x90u, 0x9au, 0x36u, 0xe5u, 0x29u, 0xc3u, 0x4fu, 0xabu, 0x64u, 0x51u, 0xf8u, 0x10u, 0xd7u, 0xbcu, 0x02u, 0x7du, 0x8eu }; /* S1 (8-bit S-box based on inverse function) */ static const unsigned char clefia_s1[256] = { 0x6cu, 0xdau, 0xc3u, 0xe9u, 0x4eu, 0x9du, 0x0au, 0x3du, 0xb8u, 0x36u, 0xb4u, 0x38u, 0x13u, 0x34u, 0x0cu, 0xd9u, 0xbfu, 0x74u, 0x94u, 0x8fu, 0xb7u, 0x9cu, 0xe5u, 0xdcu, 0x9eu, 0x07u, 0x49u, 0x4fu, 0x98u, 0x2cu, 0xb0u, 0x93u, 0x12u, 0xebu, 0xcdu, 0xb3u, 0x92u, 0xe7u, 0x41u, 0x60u, 0xe3u, 0x21u, 0x27u, 0x3bu, 0xe6u, 0x19u, 0xd2u, 0x0eu, 0x91u, 0x11u, 0xc7u, 0x3fu, 0x2au, 0x8eu, 0xa1u, 0xbcu, 0x2bu, 0xc8u, 0xc5u, 0x0fu, 0x5bu, 0xf3u, 0x87u, 0x8bu, 0xfbu, 0xf5u, 0xdeu, 0x20u, 0xc6u, 0xa7u, 0x84u, 0xceu, 0xd8u, 0x65u, 0x51u, 0xc9u, 0xa4u, 0xefu, 0x43u, 0x53u, 0x25u, 0x5du, 0x9bu, 0x31u, 0xe8u, 0x3eu, 0x0du, 0xd7u, 0x80u, 0xffu, 0x69u, 0x8au, 0xbau, 0x0bu, 0x73u, 0x5cu, 0x6eu, 0x54u, 0x15u, 0x62u, 0xf6u, 0x35u, 0x30u, 0x52u, 0xa3u, 0x16u, 0xd3u, 0x28u, 0x32u, 0xfau, 0xaau, 0x5eu, 0xcfu, 0xeau, 0xedu, 0x78u, 0x33u, 0x58u, 0x09u, 0x7bu, 0x63u, 0xc0u, 0xc1u, 0x46u, 0x1eu, 0xdfu, 0xa9u, 0x99u, 0x55u, 0x04u, 0xc4u, 0x86u, 0x39u, 0x77u, 0x82u, 0xecu, 0x40u, 0x18u, 0x90u, 0x97u, 0x59u, 0xddu, 0x83u, 0x1fu, 0x9au, 0x37u, 0x06u, 0x24u, 0x64u, 0x7cu, 0xa5u, 0x56u, 0x48u, 0x08u, 0x85u, 0xd0u, 0x61u, 0x26u, 0xcau, 0x6fu, 0x7eu, 0x6au, 0xb6u, 0x71u, 0xa0u, 0x70u, 0x05u, 0xd1u, 0x45u, 0x8cu, 0x23u, 0x1cu, 0xf0u, 0xeeu, 0x89u, 0xadu, 0x7au, 0x4bu, 0xc2u, 0x2fu, 0xdbu, 0x5au, 0x4du, 0x76u, 0x67u, 0x17u, 0x2du, 0xf4u, 0xcbu, 0xb1u, 0x4au, 0xa8u, 0xb5u, 0x22u, 0x47u, 0x3au, 0xd5u, 0x10u, 0x4cu, 0x72u, 0xccu, 0x00u, 0xf9u, 0xe0u, 0xfdu, 0xe2u, 0xfeu, 0xaeu, 0xf8u, 0x5fu, 0xabu, 0xf1u, 0x1bu, 0x42u, 0x81u, 0xd6u, 0xbeu, 0x44u, 0x29u, 0xa6u, 0x57u, 0xb9u, 0xafu, 0xf2u, 0xd4u, 0x75u, 0x66u, 0xbbu, 0x68u, 0x9fu, 0x50u, 0x02u, 0x01u, 0x3cu, 0x7fu, 0x8du, 0x1au, 0x88u, 0xbdu, 0xacu, 0xf7u, 0xe4u, 0x79u, 0x96u, 0xa2u, 0xfcu, 0x6du, 0xb2u, 0x6bu, 0x03u, 0xe1u, 0x2eu, 0x7du, 0x14u, 0x95u, 0x1du }; /**************************************************************************** * Private Functions ****************************************************************************/ static void bytecpy(unsigned char *dst, const unsigned char *src, int bytelen) { while (bytelen-- > 0) { *dst++ = *src++; } } static unsigned char clefiamul2(unsigned char x) { /* multiplication over GF(2^8) (p(x) = '11d') */ if (x & 0x80u) { x ^= 0x0eu; } return ((x << 1) | (x >> 7)); } static void clefiaf0xor(unsigned char *dst, const unsigned char *src, const unsigned char *rk) { unsigned char x[4]; unsigned char y[4]; unsigned char z[4]; /* F0 */ /* Key addition */ bytexor(x, src, rk, 4); /* Substitution layer */ z[0] = clefia_s0[x[0]]; z[1] = clefia_s1[x[1]]; z[2] = clefia_s0[x[2]]; z[3] = clefia_s1[x[3]]; /* Diffusion layer (M0) */ y[0] = z[0] ^ clefiamul2(z[1]) ^ clefiamul4(z[2]) ^ clefiamul6(z[3]); y[1] = clefiamul2(z[0]) ^ z[1] ^ clefiamul6(z[2]) ^ clefiamul4(z[3]); y[2] = clefiamul4(z[0]) ^ clefiamul6(z[1]) ^ z[2] ^ clefiamul2(z[3]); y[3] = clefiamul6(z[0]) ^ clefiamul4(z[1]) ^ clefiamul2(z[2]) ^ z[3]; /* Xoring after F0 */ bytecpy(dst + 0, src + 0, 4); bytexor(dst + 4, src + 4, y, 4); } static void clefiaf1xor(unsigned char *dst, const unsigned char *src, const unsigned char *rk) { unsigned char x[4]; unsigned char y[4]; unsigned char z[4]; /* F1 */ /* Key addition */ bytexor(x, src, rk, 4); /* Substitution layer */ z[0] = clefia_s1[x[0]]; z[1] = clefia_s0[x[1]]; z[2] = clefia_s1[x[2]]; z[3] = clefia_s0[x[3]]; /* Diffusion layer (M1) */ y[0] = z[0] ^ clefiamul8(z[1]) ^ clefiamul2(z[2]) ^ clefiamula(z[3]); y[1] = clefiamul8(z[0]) ^ z[1] ^ clefiamula(z[2]) ^ clefiamul2(z[3]); y[2] = clefiamul2(z[0]) ^ clefiamula(z[1]) ^ z[2] ^ clefiamul8(z[3]); y[3] = clefiamula(z[0]) ^ clefiamul2(z[1]) ^ clefiamul8(z[2]) ^ z[3]; /* Xoring after F1 */ bytecpy(dst + 0, src + 0, 4); bytexor(dst + 4, src + 4, y, 4); } static void clefiagfn4(unsigned char *y, const unsigned char *x, const unsigned char *rk, int r) { unsigned char fin[16]; unsigned char fout[16]; bytecpy(fin, x, 16); while (r-- > 0) { clefiaf0xor(fout + 0, fin + 0, rk + 0); clefiaf1xor(fout + 8, fin + 8, rk + 4); rk += 8; if (r) { /* swapping for encryption */ bytecpy(fin + 0, fout + 4, 12); bytecpy(fin + 12, fout + 0, 4); } } bytecpy(y, fout, 16); } #if 0 /* Not used */ static void clefiagfn8(unsigned char *y, const unsigned char *x, const unsigned char *rk, int r) { unsigned char fin[32]; unsigned char fout[32]; bytecpy(fin, x, 32); while (r-- > 0) { clefiaf0xor(fout + 0, fin + 0, rk + 0); clefiaf1xor(fout + 8, fin + 8, rk + 4); clefiaf0xor(fout + 16, fin + 16, rk + 8); clefiaf1xor(fout + 24, fin + 24, rk + 12); rk += 16; if (r) { /* swapping for encryption */ bytecpy(fin + 0, fout + 4, 28); bytecpy(fin + 28, fout + 0, 4); } } bytecpy(y, fout, 32); } #endif #if 0 /* Not used */ static void clefiagfn4inv(unsigned char *y, const unsigned char *x, const unsigned char *rk, int r) { unsigned char fin[16]; unsigned char fout[16]; rk += (r - 1) * 8; bytecpy(fin, x, 16); while (r-- > 0) { clefiaf0xor(fout + 0, fin + 0, rk + 0); clefiaf1xor(fout + 8, fin + 8, rk + 4); rk -= 8; if (r) { /* swapping for decryption */ bytecpy(fin + 0, fout + 12, 4); bytecpy(fin + 4, fout + 0, 12); } } bytecpy(y, fout, 16); } #endif static void clefiadoubleswap(unsigned char *lk) { unsigned char t[16]; t[0] = (lk[0] << 7) | (lk[1] >> 1); t[1] = (lk[1] << 7) | (lk[2] >> 1); t[2] = (lk[2] << 7) | (lk[3] >> 1); t[3] = (lk[3] << 7) | (lk[4] >> 1); t[4] = (lk[4] << 7) | (lk[5] >> 1); t[5] = (lk[5] << 7) | (lk[6] >> 1); t[6] = (lk[6] << 7) | (lk[7] >> 1); t[7] = (lk[7] << 7) | (lk[15] & 0x7fu); t[8] = (lk[8] >> 7) | (lk[0] & 0xfeu); t[9] = (lk[9] >> 7) | (lk[8] << 1); t[10] = (lk[10] >> 7) | (lk[9] << 1); t[11] = (lk[11] >> 7) | (lk[10] << 1); t[12] = (lk[12] >> 7) | (lk[11] << 1); t[13] = (lk[13] >> 7) | (lk[12] << 1); t[14] = (lk[14] >> 7) | (lk[13] << 1); t[15] = (lk[15] >> 7) | (lk[14] << 1); bytecpy(lk, t, 16); } static void clefiaconset(unsigned char *con, const unsigned char *iv, int lk) { unsigned char t[2]; unsigned char tmp; bytecpy(t, iv, 2); while (lk-- > 0) { con[0] = t[0] ^ 0xb7u; /* P_16 = 0xb7e1 (natural logarithm) */ con[1] = t[1] ^ 0xe1u; con[2] = ~((t[0] << 1) | (t[1] >> 7)); con[3] = ~((t[1] << 1) | (t[0] >> 7)); con[4] = ~t[0] ^ 0x24u; /* Q_16 = 0x243f (circle ratio) */ con[5] = ~t[1] ^ 0x3fu; con[6] = t[1]; con[7] = t[0]; con += 8; /* updating T */ if (t[1] & 0x01u) { t[0] ^= 0xa8u; t[1] ^= 0x30u; } tmp = t[0] << 7; t[0] = (t[0] >> 1) | (t[1] << 7); t[1] = (t[1] >> 1) | tmp; } } static void left_shift_one(uint8_t * in, uint8_t * out) { int i; int overflow; overflow = 0; for (i = 15; i >= 0; i--) { out[i] = in[i] << 1; out[i] |= overflow; overflow = (in[i] >> 7) & 1; } } static void gen_subkey(struct cipher *c) { uint8_t L[16]; memset(L, 0, 16); clefiaencrypt(L, L, c->rk, c->round); left_shift_one(L, c->k1); if (L[0] & 0x80) { c->k1[15] = c->k1[15] ^ 0x87; } left_shift_one(c->k1, c->k2); if (c->k1[0] & 0x80) { c->k2[15] = c->k2[15] ^ 0x87; } memset(L, 0, 16); } /**************************************************************************** * Public Functions ****************************************************************************/ struct cipher *cipher_init(uint8_t * key, uint8_t * iv) { struct cipher *c; c = (struct cipher *)malloc(sizeof(*c)); if (!c) { return NULL; } c->round = clefiakeyset(c->rk, key); gen_subkey(c); memset(c->vector, 0, 16); return c; } void cipher_deinit(struct cipher *c) { memset(c, 0, sizeof(*c)); free(c); } int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac) { uint8_t m[16]; uint8_t *p; if (size & 0xf) { return -1; } p = (uint8_t *) data; while (size) { bytexor(m, c->vector, p, 16); clefiaencrypt(c->vector, m, c->rk, c->round); size -= 16; p += 16; } bytexor(cmac, m, c->k1, 16); clefiaencrypt(cmac, cmac, c->rk, c->round); memset(m, 0, 16); return 0; } void bytexor(unsigned char *dst, const unsigned char *a, const unsigned char *b, int bytelen) { while (bytelen-- > 0) { *dst++ = *a++ ^ *b++; } } int clefiakeyset(unsigned char *rk, const unsigned char *skey) { const unsigned char iv[2] = { 0x42u, 0x8au /* cubic root of 2 */ }; unsigned char lk[16]; unsigned char con128[4 * 60]; int i; /* generating CONi^(128) (0 <= i < 60, lk = 30) */ clefiaconset(con128, iv, 30); /* GFN_{4,12} (generating L from K) */ clefiagfn4(lk, skey, con128, 12); bytecpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */ rk += 8; for (i = 0; i < 9; i++) { /* round key (RKi (0 <= i < 36)) */ bytexor(rk, lk, con128 + i * 16 + (4 * 24), 16); if (i % 2) { bytexor(rk, rk, skey, 16); /* Xoring K */ } clefiadoubleswap(lk); /* Updating L (DoubleSwap function) */ rk += 16; } bytecpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */ return 18; } void clefiaencrypt(unsigned char *ct, const unsigned char *pt, const unsigned char *rk, const int r) { unsigned char rin[16]; unsigned char rout[16]; bytecpy(rin, pt, 16); bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */ bytexor(rin + 12, rin + 12, rk + 4, 4); rk += 8; clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */ bytecpy(ct, rout, 16); bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */ bytexor(ct + 12, ct + 12, rk + r * 8 + 4, 4); } ================================================ FILE: hw/mcu/sony/cxd56/mkspk/clefia.h ================================================ /**************************************************************************** * tools/cxd56/clefia.h * * Copyright (C) 2007, 2008 Sony Corporation * * 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. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 * COPYRIGHT OWNER OR CONTRIBUTORS 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. *****************************************************************************/ #ifndef _TOOLS_CXD56_CLEFIA_H_ #define _TOOLS_CXD56_CLEFIA_H_ /**************************************************************************** * Public Types ****************************************************************************/ struct cipher { int mode; int dir; uint8_t rk[8 * 26 + 16]; uint8_t vector[16]; int round; uint8_t k1[16]; uint8_t k2[16]; }; /**************************************************************************** * Public Function Prototypes ****************************************************************************/ struct cipher *cipher_init(uint8_t * key, uint8_t * iv); void cipher_deinit(struct cipher *c); int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac); void bytexor(unsigned char *dst, const unsigned char *a, const unsigned char *b, int bytelen); int clefiakeyset(unsigned char *rk, const unsigned char *skey); void clefiaencrypt(unsigned char *ct, const unsigned char *pt, const unsigned char *rk, const int r); #endif ================================================ FILE: hw/mcu/sony/cxd56/mkspk/elf32.h ================================================ /**************************************************************************** * include/elf32.h * * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Reference: System V Application Binary Interface, Edition 4.1, March 18, * 1997, The Santa Cruz Operation, Inc. * * 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. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 * COPYRIGHT OWNER OR CONTRIBUTORS 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. * ****************************************************************************/ #ifndef __INCLUDE_ELF32_H #define __INCLUDE_ELF32_H /**************************************************************************** * Included Files ****************************************************************************/ #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define EI_NIDENT 16 /* Size of e_ident[] */ #define ELF32_ST_BIND(i) ((i) >> 4) #define ELF32_ST_TYPE(i) ((i) & 0xf) #define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf)) /* Definitions for Elf32_Rel*::r_info */ #define ELF32_R_SYM(i) ((i) >> 8) #define ELF32_R_TYPE(i) ((i) & 0xff) #define ELF32_R_INFO(s,t) (((s)<< 8) | ((t) & 0xff)) #define ELF_R_SYM(i) ELF32_R_SYM(i) /**************************************************************************** * Public Type Definitions ****************************************************************************/ /* Figure 4.2: 32-Bit Data Types */ typedef uint32_t Elf32_Addr; /* Unsigned program address */ typedef uint16_t Elf32_Half; /* Unsigned medium integer */ typedef uint32_t Elf32_Off; /* Unsigned file offset */ typedef int32_t Elf32_Sword; /* Signed large integer */ typedef uint32_t Elf32_Word; /* Unsigned large integer */ /* Figure 4-3: ELF Header */ typedef struct { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; /* Figure 4-8: Section Header */ typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; /* Figure 4-15: Symbol Table Entry */ typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym; /* Figure 4-19: Relocation Entries */ typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; /* Figure 5-1: Program Header */ typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; /* Figure 5-9: Dynamic Structure */ typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; typedef Elf32_Addr Elf_Addr; typedef Elf32_Ehdr Elf_Ehdr; typedef Elf32_Rel Elf_Rel; typedef Elf32_Rela Elf_Rela; typedef Elf32_Sym Elf_Sym; typedef Elf32_Shdr Elf_Shdr; typedef Elf32_Word Elf_Word; #endif /* __INCLUDE_ELF32_H */ ================================================ FILE: hw/mcu/sony/cxd56/mkspk/mkspk.c ================================================ /**************************************************************************** * tools/cxd56/mkspk.c * * Copyright (C) 2007, 2008 Sony Corporation * * 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. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 * COPYRIGHT OWNER OR CONTRIBUTORS 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. *****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "mkspk.h" /**************************************************************************** * Private Types ****************************************************************************/ struct args { int core; char *elffile; char *savename; char *outputfile; }; /**************************************************************************** * Private Data ****************************************************************************/ static uint8_t vmk[16] = "\x27\xc0\xaf\x1b\x5d\xcb\xc6\xc5\x58\x22\x1c\xdd\xaf\xf3\x20\x21"; static struct args g_options = { 0 }; /**************************************************************************** * Private Functions ****************************************************************************/ static struct args *parse_args(int argc, char **argv) { int opt; int show_help; struct args *args = &g_options; char *endp; show_help = 0; if (argc < 2) { show_help = 1; } memset(args, 0, sizeof(*args)); args->core = -1; while ((opt = getopt(argc, argv, "h:c:")) != -1) { switch (opt) { case 'c': args->core = strtol(optarg, &endp, 0); if (*endp) { fprintf(stderr, "Invalid core number \"%s\"\n", optarg); show_help = 1; } break; case 'h': default: show_help = 1; } } argc -= optind; argv += optind; args->elffile = argv[0]; args->savename = argv[1]; argc -= 2; argv += 2; if (argc > 0) { args->outputfile = strdup(argv[0]); } else { show_help = 1; } /* Sanity checks for options */ if (show_help == 1) { fprintf(stderr, "mkspk [-c ] []\n"); exit(EXIT_FAILURE); } if (args->core < 0) { fprintf(stderr, "Core number is not set. Please use -c option.\n"); exit(EXIT_FAILURE); } if (strlen(args->savename) > 63) { fprintf(stderr, "savename too long.\n"); exit(EXIT_FAILURE); } return args; } static struct elf_file *load_elf(const char *filename) { size_t fsize; int pos; char *buf; FILE *fp; struct elf_file *ef; Elf32_Shdr *sh; uint16_t i; int ret; fp = fopen(filename, "rb"); if (!fp) { return NULL; } ef = (struct elf_file *)malloc(sizeof(*ef)); if (!ef) { fclose(fp); return NULL; } pos = fseek(fp, 0, SEEK_END); fsize = (size_t) ftell(fp); fseek(fp, pos, SEEK_SET); buf = (char *)malloc(fsize); if (!buf) { free(ef); fclose(fp); return NULL; } ret = fread(buf, fsize, 1, fp); fclose(fp); if (ret != 1) { free(ef); free(buf); return NULL; } ef->data = buf; ef->ehdr = (Elf32_Ehdr *) buf; Elf32_Ehdr *h = (Elf32_Ehdr *) buf; if (!(h->e_ident[EI_MAG0] == 0x7f && h->e_ident[EI_MAG1] == 'E' && h->e_ident[EI_MAG2] == 'L' && h->e_ident[EI_MAG3] == 'F')) { free(ef); free(buf); return NULL; } ef->phdr = (Elf32_Phdr *) (buf + ef->ehdr->e_phoff); ef->shdr = (Elf32_Shdr *) (buf + ef->ehdr->e_shoff); ef->shstring = buf + ef->shdr[ef->ehdr->e_shstrndx].sh_offset; for (i = 0, sh = ef->shdr; i < ef->ehdr->e_shnum; i++, sh++) { if (sh->sh_type == SHT_SYMTAB) { ef->symtab = (Elf32_Sym *) (buf + sh->sh_offset); ef->nsyms = sh->sh_size / sh->sh_entsize; continue; } if (sh->sh_type == SHT_STRTAB) { if (!strcmp(".strtab", ef->shstring + sh->sh_name)) { ef->string = buf + sh->sh_offset; } } } return ef; } static void *create_image(struct elf_file *elf, int core, char *savename, int *image_size) { char *img; struct spk_header *header; struct spk_prog_info *pi; Elf32_Phdr *ph; Elf32_Sym *sym; char *name; int snlen; int nphs, psize, imgsize; int i; int j; uint32_t offset; uint32_t sp; snlen = alignup(strlen(savename) + 1, 16); nphs = 0; psize = 0; for (i = 0, ph = elf->phdr; i < elf->ehdr->e_phnum; i++, ph++) { if (ph->p_type != PT_LOAD || ph->p_filesz == 0) { continue; } nphs++; psize += alignup(ph->p_filesz, 16); } imgsize = sizeof(*header) + snlen + (nphs * 16) + psize; img = (char *)malloc(imgsize + 32); if (!img) { return NULL; } *image_size = imgsize; sym = elf->symtab; name = elf->string; sp = 0; for (j = 0; j < elf->nsyms; j++, sym++) { if (!strcmp("__stack", name + sym->st_name)) { sp = sym->st_value; } } memset(img, 0, imgsize); header = (struct spk_header *)img; header->magic[0] = 0xef; header->magic[1] = 'M'; header->magic[2] = 'O'; header->magic[3] = 'D'; header->cpu = core; header->entry = elf->ehdr->e_entry; header->stack = sp; header->core = core; header->binaries = nphs; header->phoffs = sizeof(*header) + snlen; header->mode = 0777; strncpy(img + sizeof(*header), savename, 63); ph = elf->phdr; pi = (struct spk_prog_info *)(img + header->phoffs); offset = ((char *)pi - img) + (nphs * sizeof(*pi)); for (i = 0; i < elf->ehdr->e_phnum; i++, ph++) { if (ph->p_type != PT_LOAD || ph->p_filesz == 0) continue; pi->load_address = ph->p_paddr; pi->offset = offset; pi->size = alignup(ph->p_filesz, 16); /* need 16 bytes align for * decryption */ pi->memsize = ph->p_memsz; memcpy(img + pi->offset, elf->data + ph->p_offset, ph->p_filesz); offset += alignup(ph->p_filesz, 16); pi++; } return img; } /**************************************************************************** * Public Functions ****************************************************************************/ int main(int argc, char **argv) { struct args *args; struct elf_file *elf; struct cipher *c; uint8_t *spkimage; int size = 0; FILE *fp; char footer[16]; args = parse_args(argc, argv); elf = load_elf(args->elffile); if (!elf) { fprintf(stderr, "Loading ELF %s failure.\n", args->elffile); exit(EXIT_FAILURE); } spkimage = create_image(elf, args->core, args->savename, &size); if(elf->data) { free(elf->data); } free(elf); c = cipher_init(vmk, NULL); cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size); cipher_deinit(c); size += 16; /* Extend CMAC size */ snprintf(footer, 16, "MKSPK_BN_HOOTER"); footer[15] = '\0'; fp = fopen(args->outputfile, "wb"); if (!fp) { fprintf(stderr, "Output file open error.\n"); free(spkimage); exit(EXIT_FAILURE); } fwrite(spkimage, size, 1, fp); fwrite(footer, 16, 1, fp); fclose(fp); printf("File %s is successfully created.\n", args->outputfile); free(args->outputfile); memset(spkimage, 0, size); free(spkimage); exit(EXIT_SUCCESS); } ================================================ FILE: hw/mcu/sony/cxd56/mkspk/mkspk.h ================================================ /**************************************************************************** * tools/cxd56/mkspk.h * * Copyright (C) 2007, 2008 Sony Corporation * * 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. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 * COPYRIGHT OWNER OR CONTRIBUTORS 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. *****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include "clefia.h" #include "elf32.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define EI_MAG0 0 /* File identification */ #define EI_MAG1 1 #define EI_MAG2 2 #define EI_MAG3 3 #define SHT_SYMTAB 2 #define SHT_STRTAB 3 #define PT_LOAD 1 #define alignup(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define swap(a, b) { (a) ^= (b); (b) ^= (a); (a) ^= (b); } /**************************************************************************** * Public Types ****************************************************************************/ struct spk_header { uint8_t magic[4]; uint8_t cpu; uint8_t reserved[11]; uint32_t entry; uint32_t stack; uint16_t core; uint16_t binaries; uint16_t phoffs; uint16_t mode; }; struct spk_prog_info { uint32_t load_address; uint32_t offset; uint32_t size; uint32_t memsize; }; struct elf_file { Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf32_Shdr *shdr; Elf32_Sym *symtab; int nsyms; char *shstring; char *string; char *data; }; ================================================ FILE: hw/mcu/sony/cxd56/tools/flash_writer.py ================================================ #!/usr/bin/env python3 # Copyright (C) 2018 Sony Semiconductor Solutions Corp. # # 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. Neither the name NuttX nor the names of its contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "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 # COPYRIGHT OWNER OR CONTRIBUTORS 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. # import time import sys import os import struct import glob import fnmatch import errno import telnetlib import argparse import shutil import subprocess import re import xmodem import_serial_module = True # When SDK release, please set SDK_RELEASE as True. SDK_RELEASE = False if SDK_RELEASE : PRINT_RAW_COMMAND = False REBOOT_AT_END = True else : PRINT_RAW_COMMAND = True REBOOT_AT_END = True try: import serial except: import_serial_module = False # supported environment various # CXD56_PORT # CXD56_TELNETSRV_PORT # CXD56_TELNETSRV_IP PROTOCOL_SERIAL = 0 PROTOCOL_TELNET = 1 MAX_DOT_COUNT = 70 # configure parameters and default value class ConfigArgs: PROTOCOL_TYPE = None SERIAL_PORT = "COM1" SERVER_PORT = 4569 SERVER_IP = "localhost" EOL = bytes([10]) WAIT_RESET = True AUTO_RESET = False DTR_RESET = False XMODEM_BAUD = 0 NO_SET_BOOTABLE = False PACKAGE_NAME = [] FILE_NAME = [] ERASE_NAME = [] PKGSYS_NAME = [] PKGAPP_NAME = [] PKGUPD_NAME = [] ROM_MSG = [b"Welcome to nash"] XMDM_MSG = "Waiting for XMODEM (CRC or 1K) transfer. Ctrl-X to cancel." class ConfigArgsLoader(): def __init__(self): self.parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) self.parser.add_argument("package_name", help="the name of the package to install", nargs='*') self.parser.add_argument("-f", "--file", dest="file_name", help="save file", action='append') self.parser.add_argument("-e", "--erase", dest="erase_name", help="erase file", action='append') self.parser.add_argument("-S", "--sys", dest="pkgsys_name", help="the name of the system package to install", action='append') self.parser.add_argument("-A", "--app", dest="pkgapp_name", help="the name of the application package to install", action='append') self.parser.add_argument("-U", "--upd", dest="pkgupd_name", help="the name of the updater package to install", action='append') self.parser.add_argument("-a", "--auto-reset", dest="auto_reset", action="store_true", default=None, help="try to auto reset develop board if possible") self.parser.add_argument("-d", "--dtr-reset", dest="dtr_reset", action="store_true", default=None, help="try to auto reset develop board if possible") self.parser.add_argument("-n", "--no-set-bootable", dest="no_set_bootable", action="store_true", default=None, help="not to set bootable") group = self.parser.add_argument_group() group.add_argument("-i", "--server-ip", dest="server_ip", help="the ip address connected to the telnet server") group.add_argument("-p", "--server-port", dest="server_port", type=int, help="the port connected to the telnet server") group = self.parser.add_argument_group() group.add_argument("-c", "--serial-port", dest="serial_port", help="the serial port") group.add_argument("-b", "--xmodem-baudrate", dest="xmodem_baud", help="Use the faster baudrate in xmodem") mutually_group = self.parser.add_mutually_exclusive_group() mutually_group.add_argument("-t", "--telnet-protocol", dest="telnet_protocol", action="store_true", default=None, help="use the telnet protocol for binary transmission") mutually_group.add_argument("-s", "--serial-protocol", dest="serial_protocol", action="store_true", default=None, help="use the serial port for binary transmission, default options") mutually_group2 = self.parser.add_mutually_exclusive_group() mutually_group2.add_argument("-F", "--force-wait-reset", dest="wait_reset", action="store_true", default=None, help="force wait for pressing RESET button") mutually_group2.add_argument("-N", "--no-wait-reset", dest="wait_reset", action="store_false", default=None, help="if possible, skip to wait for pressing RESET button") def update_config(self): args = self.parser.parse_args() ConfigArgs.PACKAGE_NAME = args.package_name ConfigArgs.FILE_NAME = args.file_name ConfigArgs.ERASE_NAME = args.erase_name ConfigArgs.PKGSYS_NAME = args.pkgsys_name ConfigArgs.PKGAPP_NAME = args.pkgapp_name ConfigArgs.PKGUPD_NAME = args.pkgupd_name # Get serial port or telnet server ip etc if args.serial_protocol == True: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL elif args.telnet_protocol == True: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET if ConfigArgs.PROTOCOL_TYPE == None: proto = os.environ.get("CXD56_PROTOCOL") if proto is not None: if 's' in proto: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL elif 't' in proto: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET if ConfigArgs.PROTOCOL_TYPE == None: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL if ConfigArgs.PROTOCOL_TYPE == PROTOCOL_SERIAL: if args.serial_port is not None: ConfigArgs.SERIAL_PORT = args.serial_port else: # Get serial port from the environment port = os.environ.get("CXD56_PORT") if port is not None: ConfigArgs.SERIAL_PORT = port else: print("CXD56_PORT is not set, Use " + ConfigArgs.SERIAL_PORT + ".") else: ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET if args.server_port is not None: ConfigArgs.SERVER_PORT = args.server_port else: port = os.environ.get("CXD56_TELNETSRV_PORT") if port is not None: ConfigArgs.SERVER_PORT = port else: print("CXD56_TELNETSRV_PORT is not set, Use " + str(ConfigArgs.SERVER_PORT) + ".") if args.server_ip is not None: ConfigArgs.SERVER_IP = args.server_ip else: ip = os.environ.get("CXD56_TELNETSRV_IP") if ip is not None: ConfigArgs.SERVER_IP = ip else: print("CXD56_TELNETSRV_IP is not set, Use " + ConfigArgs.SERVER_IP + ".") if args.xmodem_baud is not None: ConfigArgs.XMODEM_BAUD = args.xmodem_baud if args.auto_reset is not None: ConfigArgs.AUTO_RESET = args.auto_reset if args.dtr_reset is not None: ConfigArgs.DTR_RESET = args.dtr_reset if args.no_set_bootable is not None: ConfigArgs.NO_SET_BOOTABLE = args.no_set_bootable if args.wait_reset is not None: ConfigArgs.WAIT_RESET = args.wait_reset class TelnetDev: def __init__(self): srv_ipaddr = ConfigArgs.SERVER_IP srv_port = ConfigArgs.SERVER_PORT self.recvbuf = b''; try: self.telnet = telnetlib.Telnet(host=srv_ipaddr, port=srv_port, timeout=10) # There is a ack to be sent after connecting to the telnet server. self.telnet.write(b"\xff") except Exception as e: print("Cannot connect to the server %s:%d" % (srv_ipaddr, srv_port)) sys.exit(e.args[0]) def readline(self, size=None): res = b'' ch = b'' while ch != ConfigArgs.EOL: ch = self.getc_raw(1, timeout=0.1) if ch == b'': return res res += ch return res def getc_raw(self, size, timeout=1): res = b'' tm = time.monotonic() while size > 0: while self.recvbuf == b'': self.recvbuf = self.telnet.read_eager() if self.recvbuf == b'': if (time.monotonic() - tm) > timeout: return res time.sleep(0.1) res += self.recvbuf[0:1] self.recvbuf = self.recvbuf[1:] size -= 1 return res def write(self, buffer): self.telnet.write(buffer) def discard_inputs(self, timeout=1.0): while True: ch = self.getc_raw(1, timeout=timeout) if ch == b'': break def getc(self, size, timeout=1): c = self.getc_raw(size, timeout) return c def putc(self, buffer, timeout=1): self.telnet.write(buffer) self.show_progress(len(buffer)) def reboot(self): # no-op pass def set_file_size(self, filesize): self.bytes_transfered = 0 self.filesize = filesize self.count = 0 def show_progress(self, sendsize): if PRINT_RAW_COMMAND: if self.count < MAX_DOT_COUNT: self.bytes_transfered = self.bytes_transfered + sendsize cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize) if MAX_DOT_COUNT < cur_count: cur_count = MAX_DOT_COUNT for idx in range(cur_count - self.count): print('#',end='') sys.stdout.flush() self.count = cur_count if self.count == MAX_DOT_COUNT: print("\n") class SerialDev: def __init__(self): if import_serial_module is False: print("Cannot import serial module, maybe it's not install yet.") print("\n", end="") print("Please install python-setuptool by Cygwin installer.") print("After that use easy_intall command to install serial module") print(" $ cd tool/") print(" $ python3 -m easy_install pyserial-2.7.tar.gz") quit() else: port = ConfigArgs.SERIAL_PORT try: self.serial = serial.Serial(port, baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=0.1) except Exception as e: print("Cannot open port : " + port) sys.exit(e.args[0]) def readline(self, size=None): return self.serial.readline(size) def write(self, buffer): self.serial.write(buffer) self.serial.flush() def discard_inputs(self, timeout=1.0): time.sleep(timeout) self.serial.flushInput() def getc(self, size, timeout=1): self.serial.timeout = timeout c = self.serial.read(size) self.serial.timeout = 0.1 return c def putc(self, buffer, timeout=1): self.serial.timeout = timeout self.serial.write(buffer) self.serial.flush() self.serial.timeout = 0.1 self.show_progress(len(buffer)) # Note: windows platform dependent code def putc_win(self, buffer, timeout=1): self.serial.write(buffer) self.show_progress(len(buffer)) while True: if self.serial.out_waiting == 0: break def setBaudrate(self, baudrate): # self.serial.setBaudrate(baudrate) self.serial.baudrate = baudrate def reboot(self): # Target Reset by DTR self.serial.setDTR(False) self.serial.setDTR(True) self.serial.setDTR(False) def set_file_size(self, filesize): self.bytes_transfered = 0 self.filesize = filesize self.count = 0 def show_progress(self, sendsize): if PRINT_RAW_COMMAND: if self.count < MAX_DOT_COUNT: self.bytes_transfered = self.bytes_transfered + sendsize cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize) if MAX_DOT_COUNT < cur_count: cur_count = MAX_DOT_COUNT for idx in range(cur_count - self.count): print('#',end='') sys.stdout.flush() self.count = cur_count if self.count == MAX_DOT_COUNT: print("\n") class FlashWriter: def __init__(self, protocol_sel=PROTOCOL_SERIAL): if protocol_sel == PROTOCOL_TELNET: self.serial = TelnetDev() else: self.serial = SerialDev() def cancel_autoboot(self) : boot_msg = '' self.serial.reboot() # Target reboot before send 'r' while boot_msg == '' : rx = self.serial.readline().strip() self.serial.write(b"r") # Send "r" key to avoid auto boot for msg in ROM_MSG : if msg in rx : boot_msg = msg break while True : rx = self.serial.readline().decode(errors="replace").strip() if "updater" in rx : # Workaround : Sometime first character is dropped. # Send line feed as air shot before actual command. self.serial.write(b"\n") # Send line feed self.serial.discard_inputs()# Clear input buffer to sync return boot_msg.decode(errors="ignore") def recv(self): rx = self.serial.readline() if PRINT_RAW_COMMAND : serial_line = rx.decode(errors="replace") if serial_line.strip() != "" and not serial_line.startswith(XMDM_MSG): print(serial_line, end="") return rx def wait(self, string): while True: rx = self.recv() if string.encode() in rx: time.sleep(0.1) break def wait_for_prompt(self): prompt_pat = re.compile(b"updater") while True: rx = self.recv() if prompt_pat.search(rx): time.sleep(0.1) break def send(self, string): self.serial.write(str(string).encode() + b"\n") rx = self.serial.readline() if PRINT_RAW_COMMAND : print(rx.decode(errors="replace"), end="") def read_output(self, prompt_text) : output = [] while True : rx = self.serial.readline() if prompt_text.encode() in rx : time.sleep(0.1) break if rx != "" : output.append(rx.decode(errors="ignore").rstrip()) return output def install_files(self, files, command) : if ConfigArgs.XMODEM_BAUD: command += " -b " + ConfigArgs.XMODEM_BAUD if os.name == 'nt': modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') else: modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') for file in files: with open(file, "rb") as bin : self.send(command) print("Install " + file) self.wait(XMDM_MSG) print("|0%" + "-" * (int(MAX_DOT_COUNT / 2) - 6) + "50%" + "-" * (MAX_DOT_COUNT - int(MAX_DOT_COUNT / 2) - 5) + "100%|") if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) self.serial.discard_inputs() # Clear input buffer to sync self.serial.set_file_size(os.path.getsize(file)) modem.send(bin) if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(115200) self.wait_for_prompt() def save_files(self, files) : if ConfigArgs.XMODEM_BAUD: command = "save_file -b " + ConfigArgs.XMODEM_BAUD + " -x " else: command = "save_file -x " if os.name == 'nt': modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') else: modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') for file in files: with open(file, "rb") as bin : self.send(command + os.path.basename(file)) print("Save " + file) self.wait(XMDM_MSG) if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) self.serial.discard_inputs() # Clear input buffer to sync self.serial.set_file_size(os.path.getsize(file)) modem.send(bin) if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(115200) self.wait_for_prompt() self.send("chmod d+rw " + os.path.basename(file)) self.wait_for_prompt() def delete_files(self, files) : for file in files : self.delete_binary(file) def delete_binary(self, bin_name) : self.send("rm " + bin_name) self.wait_for_prompt() def main(): try: config_loader = ConfigArgsLoader() config_loader.update_config() except: return errno.EINVAL # Wait to reset the board writer = FlashWriter(ConfigArgs.PROTOCOL_TYPE) do_wait_reset = True if ConfigArgs.AUTO_RESET: if subprocess.call("cd " + sys.path[0] + "; ./reset_board.sh", shell=True) == 0: print("auto reset board success!!") do_wait_reset = False bootrom_msg = writer.cancel_autoboot() if ConfigArgs.DTR_RESET: do_wait_reset = False bootrom_msg = writer.cancel_autoboot() if ConfigArgs.WAIT_RESET == False and do_wait_reset == True: rx = writer.recv() time.sleep(1) for i in range(3): writer.send("") rx = writer.recv() if "updater".encode() in rx: # No need to wait for reset do_wait_reset = False break time.sleep(1) if do_wait_reset: # Wait to reset the board print('Please press RESET button on target board') sys.stdout.flush() bootrom_msg = writer.cancel_autoboot() # Remove files if ConfigArgs.ERASE_NAME : print(">>> Remove existing files ...") writer.delete_files(ConfigArgs.ERASE_NAME) # Install files if ConfigArgs.PACKAGE_NAME or ConfigArgs.PKGSYS_NAME or ConfigArgs.PKGAPP_NAME or ConfigArgs.PKGUPD_NAME: print(">>> Install files ...") if ConfigArgs.PACKAGE_NAME : writer.install_files(ConfigArgs.PACKAGE_NAME, "install") if ConfigArgs.PKGSYS_NAME : writer.install_files(ConfigArgs.PKGSYS_NAME, "install") if ConfigArgs.PKGAPP_NAME : writer.install_files(ConfigArgs.PKGAPP_NAME, "install") if ConfigArgs.PKGUPD_NAME : writer.install_files(ConfigArgs.PKGUPD_NAME, "install -k updater.key") # Save files if ConfigArgs.FILE_NAME : print(">>> Save files ...") writer.save_files(ConfigArgs.FILE_NAME) # Set auto boot if not ConfigArgs.NO_SET_BOOTABLE: print(">>> Save Configuration to FlashROM ...") writer.send("set bootable M0P") writer.wait_for_prompt() # Sync all cached data to flash writer.send("sync") writer.wait_for_prompt() if REBOOT_AT_END : print("Restarting the board ...") writer.send("reboot") return 0 if __name__ == "__main__": try: sys.exit(main()) except KeyboardInterrupt: print("Canceled by keyboard interrupt.") pass ================================================ FILE: hw/mcu/sony/cxd56/tools/xmodem.py ================================================ #!/usr/bin/env python3 ''' =============================== XMODEM file transfer protocol =============================== .. $Id$ This is a literal implementation of XMODEM.TXT_, XMODEM1K.TXT_ and XMODMCRC.TXT_, support for YMODEM and ZMODEM is pending. YMODEM should be fairly easy to implement as it is a hack on top of the XMODEM protocol using sequence bytes ``0x00`` for sending file names (and some meta data). .. _XMODEM.TXT: doc/XMODEM.TXT .. _XMODEM1K.TXT: doc/XMODEM1K.TXT .. _XMODMCRC.TXT: doc/XMODMCRC.TXT Data flow example including error recovery ========================================== Here is a sample of the data flow, sending a 3-block message. It includes the two most common line hits - a garbaged block, and an ``ACK`` reply getting garbaged. ``CRC`` or ``CSUM`` represents the checksum bytes. XMODEM 128 byte blocks ---------------------- :: SENDER RECEIVER <-- NAK SOH 01 FE Data[128] CSUM --> <-- ACK SOH 02 FD Data[128] CSUM --> <-- ACK SOH 03 FC Data[128] CSUM --> <-- ACK SOH 04 FB Data[128] CSUM --> <-- ACK SOH 05 FA Data[100] CPMEOF[28] CSUM --> <-- ACK EOT --> <-- ACK XMODEM-1k blocks, CRC mode -------------------------- :: SENDER RECEIVER <-- C STX 01 FE Data[1024] CRC CRC --> <-- ACK STX 02 FD Data[1024] CRC CRC --> <-- ACK STX 03 FC Data[1000] CPMEOF[24] CRC CRC --> <-- ACK EOT --> <-- ACK Mixed 1024 and 128 byte Blocks ------------------------------ :: SENDER RECEIVER <-- C STX 01 FE Data[1024] CRC CRC --> <-- ACK STX 02 FD Data[1024] CRC CRC --> <-- ACK SOH 03 FC Data[128] CRC CRC --> <-- ACK SOH 04 FB Data[100] CPMEOF[28] CRC CRC --> <-- ACK EOT --> <-- ACK YMODEM Batch Transmission Session (1 file) ------------------------------------------ :: SENDER RECEIVER <-- C (command:rb) SOH 00 FF foo.c NUL[123] CRC CRC --> <-- ACK <-- C SOH 01 FE Data[128] CRC CRC --> <-- ACK SOH 02 FC Data[128] CRC CRC --> <-- ACK SOH 03 FB Data[100] CPMEOF[28] CRC CRC --> <-- ACK EOT --> <-- NAK EOT --> <-- ACK <-- C SOH 00 FF NUL[128] CRC CRC --> <-- ACK ''' __author__ = 'Wijnand Modderman ' __copyright__ = ['Copyright (c) 2010 Wijnand Modderman', 'Copyright (c) 1981 Chuck Forsberg'] __license__ = 'MIT' __version__ = '0.3.2' import logging import time import sys from functools import partial import collections # Loggerr log = logging.getLogger('xmodem') # Protocol bytes SOH = bytes([0x01]) STX = bytes([0x02]) EOT = bytes([0x04]) ACK = bytes([0x06]) DLE = bytes([0x10]) NAK = bytes([0x15]) CAN = bytes([0x18]) CRC = bytes([0x43]) # C class XMODEM(object): ''' XMODEM Protocol handler, expects an object to read from and an object to write to. >>> def getc(size, timeout=1): ... return data or None ... >>> def putc(data, timeout=1): ... return size or None ... >>> modem = XMODEM(getc, putc) :param getc: Function to retrieve bytes from a stream :type getc: callable :param putc: Function to transmit bytes to a stream :type putc: callable :param mode: XMODEM protocol mode :type mode: string :param pad: Padding character to make the packets match the packet size :type pad: char ''' # crctab calculated by Mark G. Mendel, Network Systems Corporation crctable = [ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, ] def __init__(self, getc, putc, mode='xmodem', pad=b'\x1a'): self.getc = getc self.putc = putc self.mode = mode self.pad = pad def abort(self, count=2, timeout=60): ''' Send an abort sequence using CAN bytes. ''' for counter in range(0, count): self.putc(CAN, timeout) def send(self, stream, retry=32, timeout=360, quiet=0, callback=None): ''' Send a stream via the XMODEM protocol. >>> stream = file('/etc/issue', 'rb') >>> print modem.send(stream) True Returns ``True`` upon successful transmission or ``False`` in case of failure. :param stream: The stream object to send data from. :type stream: stream (file, etc.) :param retry: The maximum number of times to try to resend a failed packet before failing. :type retry: int :param timeout: The number of seconds to wait for a response before timing out. :type timeout: int :param quiet: If 0, it prints info to stderr. If 1, it does not print any info. :type quiet: int :param callback: Reference to a callback function that has the following signature. This is useful for getting status updates while a xmodem transfer is underway. Expected callback signature: def callback(total_packets, success_count, error_count) :type callback: callable ''' # initialize protocol try: packet_size = dict( xmodem = 128, xmodem1k = 1024, )[self.mode] except AttributeError: raise ValueError("An invalid mode was supplied") error_count = 0 crc_mode = 0 cancel = 0 while True: char = self.getc(1) if char: if char == NAK: crc_mode = 0 break elif char == CRC: crc_mode = 1 break elif char == CAN: if not quiet: print('received CAN', file=sys.stderr) if cancel: return False else: cancel = 1 else: log.error('send ERROR expected NAK/CRC, got %s' % \ (ord(char),)) error_count += 1 if error_count >= retry: self.abort(timeout=timeout) return False # send data error_count = 0 success_count = 0 total_packets = 0 sequence = 1 while True: data = stream.read(packet_size) if not data: log.info('sending EOT') # end of stream break total_packets += 1 data = data.ljust(packet_size, self.pad) if crc_mode: crc = self.calc_crc(data) else: crc = self.calc_checksum(data) # emit packet while True: if packet_size == 128: self.putc(SOH) else: # packet_size == 1024 self.putc(STX) self.putc(bytes([sequence])) self.putc(bytes([0xff - sequence])) self.putc(data) if crc_mode: self.putc(bytes([crc >> 8])) self.putc(bytes([crc & 0xff])) else: self.putc(bytes([crc])) char = self.getc(1, timeout) if char == ACK: success_count += 1 if isinstance(callback, collections.Callable): callback(total_packets, success_count, error_count) break if char == NAK: error_count += 1 if isinstance(callback, collections.Callable): callback(total_packets, success_count, error_count) if error_count >= retry: # excessive amounts of retransmissions requested, # abort transfer self.abort(timeout=timeout) log.warning('excessive NAKs, transfer aborted') return False # return to loop and resend continue else: log.error('Not ACK, Not NAK') error_count += 1 if isinstance(callback, collections.Callable): callback(total_packets, success_count, error_count) if error_count >= retry: # excessive amounts of retransmissions requested, # abort transfer self.abort(timeout=timeout) log.warning('excessive protocol errors, transfer aborted') return False # return to loop and resend continue # protocol error self.abort(timeout=timeout) log.error('protocol error') return False # keep track of sequence sequence = (sequence + 1) % 0x100 while True: # end of transmission self.putc(EOT) #An ACK should be returned char = self.getc(1, timeout) if char == ACK: break else: error_count += 1 if error_count >= retry: self.abort(timeout=timeout) log.warning('EOT was not ACKd, transfer aborted') return False return True def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1, quiet=0): ''' Receive a stream via the XMODEM protocol. >>> stream = file('/etc/issue', 'wb') >>> print modem.recv(stream) 2342 Returns the number of bytes received on success or ``None`` in case of failure. ''' # initiate protocol error_count = 0 char = 0 cancel = 0 while True: # first try CRC mode, if this fails, # fall back to checksum mode if error_count >= retry: self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): if not self.putc(CRC): time.sleep(delay) error_count += 1 else: crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 char = self.getc(1, timeout) if not char: error_count += 1 continue elif char == SOH: #crc_mode = 0 break elif char == STX: break elif char == CAN: if cancel: return None else: cancel = 1 else: error_count += 1 # read data error_count = 0 income_size = 0 packet_size = 128 sequence = 1 cancel = 0 while True: while True: if char == SOH: packet_size = 128 break elif char == STX: packet_size = 1024 break elif char == EOT: # We received an EOT, so send an ACK and return the received # data length self.putc(ACK) return income_size elif char == CAN: # cancel at two consecutive cancels if cancel: return None else: cancel = 1 else: if not quiet: print('recv ERROR expected SOH/EOT, got', ord(char), file=sys.stderr) error_count += 1 if error_count >= retry: self.abort() return None # read sequence error_count = 0 cancel = 0 seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: # sequence is ok, read packet # packet_size + checksum data = self.getc(packet_size + 1 + crc_mode, timeout) if crc_mode: csum = (ord(data[-2]) << 8) + ord(data[-1]) data = data[:-2] log.debug('CRC (%04x <> %04x)' % \ (csum, self.calc_crc(data))) valid = csum == self.calc_crc(data) else: csum = data[-1] data = data[:-1] log.debug('checksum (checksum(%02x <> %02x)' % \ (ord(csum), self.calc_checksum(data))) valid = ord(csum) == self.calc_checksum(data) # valid data, append chunk if valid: income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 char = self.getc(1, timeout) continue else: # consume data self.getc(packet_size + 1 + crc_mode) self.debug('expecting sequence %d, got %d/%d' % \ (sequence, seq1, seq2)) # something went wrong, request retransmission self.putc(NAK) def calc_checksum(self, data, checksum=0): ''' Calculate the checksum for a given block of data, can also be used to update a checksum. >>> csum = modem.calc_checksum('hello') >>> csum = modem.calc_checksum('world', csum) >>> hex(csum) '0x3c' ''' return (sum(map(ord, data)) + checksum) % 256 def calc_crc(self, data, crc=0): ''' Calculate the Cyclic Redundancy Check for a given block of data, can also be used to update a CRC. >>> crc = modem.calc_crc('hello') >>> crc = modem.calc_crc('world', crc) >>> hex(crc) '0xd5e3' ''' for char in data: crc = (crc << 8) ^ self.crctable[((crc >> 8) ^ int(char)) & 0xff] return crc & 0xffff XMODEM1k = partial(XMODEM, mode='xmodem1k') def run(): import optparse import subprocess parser = optparse.OptionParser(usage='%prog [] filename filename') parser.add_option('-m', '--mode', default='xmodem', help='XMODEM mode (xmodem, xmodem1k)') options, args = parser.parse_args() if len(args) != 3: parser.error('invalid arguments') return 1 elif args[0] not in ('send', 'recv'): parser.error('invalid mode') return 1 def _func(so, si): import select import subprocess print('si', si) print('so', so) def getc(size, timeout=3): w,t,f = select.select([so], [], [], timeout) if w: data = so.read(size) else: data = None print('getc(', repr(data), ')') return data def putc(data, timeout=3): w,t,f = select.select([], [si], [], timeout) if t: si.write(data) si.flush() size = len(data) else: size = None print('putc(', repr(data), repr(size), ')') return size return getc, putc def _pipe(*command): pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE) return pipe.stdout, pipe.stdin if args[0] == 'recv': import io getc, putc = _func(*_pipe('sz', '--xmodem', args[2])) stream = open(args[1], 'wb') xmodem = XMODEM(getc, putc, mode=options.mode) status = xmodem.recv(stream, retry=8) stream.close() elif args[0] == 'send': getc, putc = _func(*_pipe('rz', '--xmodem', args[2])) stream = open(args[1], 'rb') xmodem = XMODEM(getc, putc, mode=options.mode) status = xmodem.send(stream, retry=8) stream.close() if __name__ == '__main__': sys.exit(run()) ================================================ FILE: lib/SEGGER_RTT/Config/SEGGER_RTT_Conf.h ================================================ /********************************************************************* * SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 1995 - 2020 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * ********************************************************************** * * * SEGGER RTT * Real Time Transfer for embedded targets * * * ********************************************************************** * * * All rights reserved. * * * * SEGGER strongly recommends to not make any changes * * to or modify the source code of this software in order to stay * * compatible with the RTT protocol and J-Link. * * * * Redistribution and use in source and binary forms, with or * * without modification, are permitted provided that the following * * condition is met: * * * * o Redistributions of source code must retain the above copyright * * notice, this condition and the following disclaimer. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * CONTRIBUTORS "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 SEGGER Microcontroller 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. * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ File : SEGGER_RTT_Conf.h Purpose : Implementation of SEGGER real-time transfer (RTT) which allows real-time communication on targets which support debugger memory accesses while the CPU is running. Revision: $Rev: 24316 $ */ #ifndef SEGGER_RTT_CONF_H #define SEGGER_RTT_CONF_H #ifdef __IAR_SYSTEMS_ICC__ #include #endif /********************************************************************* * * Defines, configurable * ********************************************************************** */ // // Take in and set to correct values for Cortex-A systems with CPU cache // //#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system //#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached // // Most common case: // Up-channel 0: RTT // Up-channel 1: SystemView // #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS #define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) #endif // // Most common case: // Down-channel 0: RTT // Down-channel 1: SystemView // #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) #endif #ifndef BUFFER_SIZE_UP #define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) #endif #ifndef BUFFER_SIZE_DOWN #define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) #endif #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) #endif #ifndef SEGGER_RTT_MODE_DEFAULT #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) #endif /********************************************************************* * * RTT memcpy configuration * * memcpy() is good for large amounts of data, * but the overhead is big for small amounts, which are usually stored via RTT. * With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. * * SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. * This is may be required with memory access restrictions, * such as on Cortex-A devices with MMU. */ #ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop #endif // // Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets // //#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) // #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) //#endif // // Target is not allowed to perform other RTT operations while string still has not been stored completely. // Otherwise we would probably end up with a mixed string in the buffer. // If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. // // SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. // Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. // When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. // (Higher priority = lower priority number) // Default value for embOS: 128u // Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) // In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC // or define SEGGER_RTT_LOCK() to completely disable interrupts. // #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) #endif /********************************************************************* * * RTT lock configuration for SEGGER Embedded Studio, * Rowley CrossStudio and GCC */ #if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32)) #if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("mrs %0, primask \n\t" \ "movs r1, #1 \n\t" \ "msr primask, r1 \n\t" \ : "=r" (_SEGGER_RTT__LockState) \ : \ : "r1", "cc" \ ); #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ : \ : "r" (_SEGGER_RTT__LockState) \ : \ ); \ } #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #endif #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("mrs %0, basepri \n\t" \ "mov r1, %1 \n\t" \ "msr basepri, r1 \n\t" \ : "=r" (_SEGGER_RTT__LockState) \ : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ : "r1", "cc" \ ); #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ : \ : "r" (_SEGGER_RTT__LockState) \ : \ ); \ } #elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("mrs r1, CPSR \n\t" \ "mov %0, r1 \n\t" \ "orr r1, r1, #0xC0 \n\t" \ "msr CPSR_c, r1 \n\t" \ : "=r" (_SEGGER_RTT__LockState) \ : \ : "r1", "cc" \ ); #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ "mrs r1, CPSR \n\t" \ "bic r1, r1, #0xC0 \n\t" \ "and r0, r0, #0xC0 \n\t" \ "orr r1, r1, r0 \n\t" \ "msr CPSR_c, r1 \n\t" \ : \ : "r" (_SEGGER_RTT__LockState) \ : "r0", "r1", "cc" \ ); \ } #elif defined(__riscv) || defined(__riscv_xlen) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("csrr %0, mstatus \n\t" \ "csrci mstatus, 8 \n\t" \ "andi %0, %0, 8 \n\t" \ : "=r" (_SEGGER_RTT__LockState) \ : \ : \ ); #define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \ "or %0, %0, a1 \n\t" \ "csrs mstatus, %0 \n\t" \ : \ : "r" (_SEGGER_RTT__LockState) \ : "a1" \ ); \ } #else #define SEGGER_RTT_LOCK() #define SEGGER_RTT_UNLOCK() #endif #endif /********************************************************************* * * RTT lock configuration for IAR EWARM */ #ifdef __ICCARM__ #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \ (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = __get_PRIMASK(); \ __set_PRIMASK(1); #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ } #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \ (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \ (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \ (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #endif #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = __get_BASEPRI(); \ __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); #define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \ } #elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \ (defined (__ARM7R__) && (__CORE__ == __ARM7R__)) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("mrs r1, CPSR \n\t" \ "mov %0, r1 \n\t" \ "orr r1, r1, #0xC0 \n\t" \ "msr CPSR_c, r1 \n\t" \ : "=r" (_SEGGER_RTT__LockState) \ : \ : "r1", "cc" \ ); #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ "mrs r1, CPSR \n\t" \ "bic r1, r1, #0xC0 \n\t" \ "and r0, r0, #0xC0 \n\t" \ "orr r1, r1, r0 \n\t" \ "msr CPSR_c, r1 \n\t" \ : \ : "r" (_SEGGER_RTT__LockState) \ : "r0", "r1", "cc" \ ); \ } #endif #endif /********************************************************************* * * RTT lock configuration for IAR RX */ #ifdef __ICCRX__ #define SEGGER_RTT_LOCK() { \ unsigned long _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = __get_interrupt_state(); \ __disable_interrupt(); #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ } #endif /********************************************************************* * * RTT lock configuration for IAR RL78 */ #ifdef __ICCRL78__ #define SEGGER_RTT_LOCK() { \ __istate_t _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = __get_interrupt_state(); \ __disable_interrupt(); #define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \ } #endif /********************************************************************* * * RTT lock configuration for KEIL ARM */ #ifdef __CC_ARM #if (defined __TARGET_ARCH_6S_M) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \ _SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \ _SEGGER_RTT__PRIMASK = 1u; \ __schedule_barrier(); #define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \ __schedule_barrier(); \ } #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #endif #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ register unsigned char BASEPRI __asm( "basepri"); \ _SEGGER_RTT__LockState = BASEPRI; \ BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ __schedule_barrier(); #define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \ __schedule_barrier(); \ } #endif #endif /********************************************************************* * * RTT lock configuration for TI ARM */ #ifdef __TI_ARM__ #if defined (__TI_ARM_V6M0__) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = __get_PRIMASK(); \ __set_PRIMASK(1); #define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \ } #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #endif #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); #define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \ } #endif #endif /********************************************************************* * * RTT lock configuration for CCRX */ #ifdef __RX #include #define SEGGER_RTT_LOCK() { \ unsigned long _SEGGER_RTT__LockState; \ _SEGGER_RTT__LockState = get_psw() & 0x010000; \ clrpsw_i(); #define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \ } #endif /********************************************************************* * * RTT lock configuration for embOS Simulation on Windows * (Can also be used for generic RTT locking with embOS) */ #if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS) void OS_SIM_EnterCriticalSection(void); void OS_SIM_LeaveCriticalSection(void); #define SEGGER_RTT_LOCK() { \ OS_SIM_EnterCriticalSection(); #define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \ } #endif /********************************************************************* * * RTT lock configuration fallback */ #ifndef SEGGER_RTT_LOCK #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) #endif #ifndef SEGGER_RTT_UNLOCK #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) #endif #endif /*************************** End of file ****************************/ ================================================ FILE: lib/SEGGER_RTT/LICENSE.md ================================================ SEGGER Microcontroller GmbH The Embedded Experts (c) 1995 - 2021 SEGGER Microcontroller GmbH www.segger.com Support: support@segger.com SEGGER RTT Real Time Transfer for embedded targets All rights reserved. SEGGER strongly recommends to not make any changes to or modify the source code of this software in order to stay compatible with the RTT protocol and J-Link. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following condition is met: - Redistributions of source code must retain the above copyright notice, this condition and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 SEGGER Microcontroller 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. ================================================ FILE: lib/SEGGER_RTT/README.md ================================================ RTT === SEGGER RTT Sources https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer https://wiki.segger.com/RTT ## Included files * `RTT/` * `SEGGER_RTT.c` - Main module for RTT. * `SEGGER_RTT.h` - Main header for RTT. * `SEGGER_RTT_ASM_ARMv7M.S` - Assembly-optimized implementation of RTT functions for ARMv7M processors. * `SEGGER_RTT_Printf.c` - Simple implementation of printf (`SEGGER_RTT_Printf()`) to write formatted strings via RTT. * `Syscalls/` * `SEGGER_RTT_Syscalls_*.c` - Low-level syscalls to retarget `printf()` to RTT with different toolchains. * `Config/` * `SEGGER_RTT_Conf.h` - RTT configuration file. * `Examples/` * `Main_RTT_InputEchoApp.c` - Example application which echoes input on Channel 0. * `Main_RTT_MenuApp.c` - Example application to demonstrate RTT bi-directional functionality. * `Main_RTT_PrintfTest.c` - Example application to test RTT's simple printf implementation. * `Main_RTT_SpeedTestApp.c` - Example application to measure RTT performance. (Requires embOS) ================================================ FILE: lib/SEGGER_RTT/RTT/SEGGER_RTT.c ================================================ /********************************************************************* * SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 1995 - 2019 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * ********************************************************************** * * * SEGGER RTT * Real Time Transfer for embedded targets * * * ********************************************************************** * * * All rights reserved. * * * * SEGGER strongly recommends to not make any changes * * to or modify the source code of this software in order to stay * * compatible with the RTT protocol and J-Link. * * * * Redistribution and use in source and binary forms, with or * * without modification, are permitted provided that the following * * condition is met: * * * * o Redistributions of source code must retain the above copyright * * notice, this condition and the following disclaimer. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * CONTRIBUTORS "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 SEGGER Microcontroller 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. * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ File : SEGGER_RTT.c Purpose : Implementation of SEGGER real-time transfer (RTT) which allows real-time communication on targets which support debugger memory accesses while the CPU is running. Revision: $Rev: 29668 $ Additional information: Type "int" is assumed to be 32-bits in size H->T Host to target communication T->H Target to host communication RTT channel 0 is always present and reserved for Terminal usage. Name is fixed to "Terminal" Effective buffer size: SizeOfBuffer - 1 WrOff == RdOff: Buffer is empty WrOff == (RdOff - 1): Buffer is full WrOff > RdOff: Free space includes wrap-around WrOff < RdOff: Used space includes wrap-around (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): Buffer full and wrap-around after next byte ---------------------------------------------------------------------- */ #include "SEGGER_RTT.h" #include // for memcpy /********************************************************************* * * Configuration, default values * ********************************************************************** */ #if SEGGER_RTT_CPU_CACHE_LINE_SIZE #ifdef SEGGER_RTT_CB_ALIGN #error "Custom SEGGER_RTT_CB_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #ifdef SEGGER_RTT_BUFFER_ALIGN #error "Custom SEGGER_RTT_BUFFER_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #ifdef SEGGER_RTT_PUT_CB_SECTION #error "Custom SEGGER_RTT_PUT_CB_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #ifdef SEGGER_RTT_PUT_BUFFER_SECTION #error "Custom SEGGER_RTT_PUT_BUFFER_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #ifdef SEGGER_RTT_BUFFER_ALIGNMENT #error "Custom SEGGER_RTT_BUFFER_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #ifdef SEGGER_RTT_ALIGNMENT #error "Custom SEGGER_RTT_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #endif #ifndef BUFFER_SIZE_UP #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host #endif #ifndef BUFFER_SIZE_DOWN #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) #endif #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target #endif #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target #endif #ifndef SEGGER_RTT_BUFFER_SECTION #if defined(SEGGER_RTT_SECTION) #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION #endif #endif #ifndef SEGGER_RTT_ALIGNMENT #define SEGGER_RTT_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE #endif #ifndef SEGGER_RTT_BUFFER_ALIGNMENT #define SEGGER_RTT_BUFFER_ALIGNMENT SEGGER_RTT_CPU_CACHE_LINE_SIZE #endif #ifndef SEGGER_RTT_MODE_DEFAULT #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP #endif #ifndef SEGGER_RTT_LOCK #define SEGGER_RTT_LOCK() #endif #ifndef SEGGER_RTT_UNLOCK #define SEGGER_RTT_UNLOCK() #endif #ifndef STRLEN #define STRLEN(a) strlen((a)) #endif #ifndef STRCPY #define STRCPY(pDest, pSrc) strcpy((pDest), (pSrc)) #endif #ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 #endif #ifndef SEGGER_RTT_MEMCPY #ifdef MEMCPY #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) #else #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) #endif #endif #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif // // For some environments, NULL may not be defined until certain headers are included // #ifndef NULL #define NULL 0 #endif /********************************************************************* * * Defines, fixed * ********************************************************************** */ #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-align" #endif #if (defined __ICCARM__) || (defined __ICCRX__) #define RTT_PRAGMA(P) _Pragma(#P) #endif #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT #if ((defined __GNUC__) || (defined __clang__)) #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) #elif (defined __ICCARM__) || (defined __ICCRX__) #define PRAGMA(A) _Pragma(#A) #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ Var #elif (defined __CC_ARM) #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) #else #error "Alignment not supported for this compiler." #endif #else #define SEGGER_RTT_ALIGN(Var, Alignment) Var #endif #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) #if ((defined __GNUC__) || (defined __clang__)) #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var #elif (defined __ICCARM__) || (defined __ICCRX__) #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ Var #elif (defined __CC_ARM) #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var #else #error "Section placement not supported for this compiler." #endif #else #define SEGGER_RTT_PUT_SECTION(Var, Section) Var #endif #if SEGGER_RTT_ALIGNMENT #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) #else #define SEGGER_RTT_CB_ALIGN(Var) Var #endif #if SEGGER_RTT_BUFFER_ALIGNMENT #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) #else #define SEGGER_RTT_BUFFER_ALIGN(Var) Var #endif #if defined(SEGGER_RTT_SECTION) #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) #else #define SEGGER_RTT_PUT_CB_SECTION(Var) Var #endif #if defined(SEGGER_RTT_BUFFER_SECTION) #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) #else #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var #endif /********************************************************************* * * Static const data * ********************************************************************** */ static const unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /********************************************************************* * * Static data * ********************************************************************** */ // // RTT Control Block and allocate buffers for channel 0 // #if SEGGER_RTT_CPU_CACHE_LINE_SIZE #if ((defined __GNUC__) || (defined __clang__)) SEGGER_RTT_CB _SEGGER_RTT __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); #elif (defined __ICCARM__) #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE SEGGER_RTT_CB _SEGGER_RTT; #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)]; #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)]; #else #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned" #endif #else SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); #endif static unsigned char _ActiveTerminal; /********************************************************************* * * Static functions * ********************************************************************** */ /********************************************************************* * * _DoInit() * * Function description * Initializes the control block an buffers. * * Notes * (1) May only be called via INIT() to avoid overriding settings. * The only exception is SEGGER_RTT_Init(), to make an intentional override possible. */ #define INIT() \ do { \ volatile SEGGER_RTT_CB* pRTTCBInit; \ pRTTCBInit = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \ if (pRTTCBInit->acID[0] != 'S') { \ _DoInit(); \ } \ } while (0) static void _DoInit(void) { volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block static const char _aInitStr[] = "\0\0\0\0\0\0TTR REGGES"; // Init complete ID string to make sure that things also work if RTT is linked to a no-init memory area unsigned i; // // Initialize control block // p = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly memset((SEGGER_RTT_CB*)p, 0, sizeof(_SEGGER_RTT)); // Make sure that the RTT CB is always zero initialized. p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; // // Initialize up buffer 0 // p->aUp[0].sName = "Terminal"; p->aUp[0].pBuffer = _acUpBuffer; p->aUp[0].SizeOfBuffer = BUFFER_SIZE_UP; p->aUp[0].RdOff = 0u; p->aUp[0].WrOff = 0u; p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; // // Initialize down buffer 0 // p->aDown[0].sName = "Terminal"; p->aDown[0].pBuffer = _acDownBuffer; p->aDown[0].SizeOfBuffer = BUFFER_SIZE_DOWN; p->aDown[0].RdOff = 0u; p->aDown[0].WrOff = 0u; p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; // // Finish initialization of the control block. // Copy Id string backwards to make sure that "SEGGER RTT" is not found in initializer memory (usually flash), // as this would cause J-Link to "find" the control block at a wrong address. // RTT__DMB(); // Force order of memory accesses for cores that may perform out-of-order memory accesses for (i = 0; i < sizeof(_aInitStr) - 1; ++i) { p->acID[i] = _aInitStr[sizeof(_aInitStr) - 2 - i]; // Skip terminating \0 at the end of the array } RTT__DMB(); // Force order of memory accesses for cores that may perform out-of-order memory accesses } /********************************************************************* * * _WriteBlocking() * * Function description * Stores a specified number of characters in SEGGER RTT ring buffer * and updates the associated write pointer which is periodically * read by the host. * The caller is responsible for managing the write chunk sizes as * _WriteBlocking() will block until all data has been posted successfully. * * Parameters * pRing Ring buffer to post to. * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Return value * >= 0 - Number of bytes written into buffer. */ static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { unsigned NumBytesToWrite; unsigned NumBytesWritten; unsigned RdOff; unsigned WrOff; volatile char* pDst; // // Write data to buffer and handle wrap-around if necessary // NumBytesWritten = 0u; WrOff = pRing->WrOff; do { RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime if (RdOff > WrOff) { NumBytesToWrite = RdOff - WrOff - 1u; } else { NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); } NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytesWritten += NumBytesToWrite; NumBytes -= NumBytesToWrite; WrOff += NumBytesToWrite; while (NumBytesToWrite--) { *pDst++ = *pBuffer++; }; #else SEGGER_RTT_MEMCPY((void*)pDst, pBuffer, NumBytesToWrite); NumBytesWritten += NumBytesToWrite; pBuffer += NumBytesToWrite; NumBytes -= NumBytesToWrite; WrOff += NumBytesToWrite; #endif if (WrOff == pRing->SizeOfBuffer) { WrOff = 0u; } RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff; } while (NumBytes); return NumBytesWritten; } /********************************************************************* * * _WriteNoCheck() * * Function description * Stores a specified number of characters in SEGGER RTT ring buffer * and updates the associated write pointer which is periodically * read by the host. * It is callers responsibility to make sure data actually fits in buffer. * * Parameters * pRing Ring buffer to post to. * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Notes * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking */ static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { unsigned NumBytesAtOnce; unsigned WrOff; unsigned Rem; volatile char* pDst; WrOff = pRing->WrOff; Rem = pRing->SizeOfBuffer - WrOff; if (Rem > NumBytes) { // // All data fits before wrap around // pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP WrOff += NumBytes; while (NumBytes--) { *pDst++ = *pData++; }; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff; #else SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff + NumBytes; #endif } else { // // We reach the end of the buffer, so need to wrap around // #if SEGGER_RTT_MEMCPY_USE_BYTELOOP pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; NumBytesAtOnce = Rem; while (NumBytesAtOnce--) { *pDst++ = *pData++; }; pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; NumBytesAtOnce = NumBytes - Rem; while (NumBytesAtOnce--) { *pDst++ = *pData++; }; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = NumBytes - Rem; #else NumBytesAtOnce = Rem; pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytesAtOnce); NumBytesAtOnce = NumBytes - Rem; pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; SEGGER_RTT_MEMCPY((void*)pDst, pData + Rem, NumBytesAtOnce); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = NumBytesAtOnce; #endif } } /********************************************************************* * * _PostTerminalSwitch() * * Function description * Switch terminal to the given terminal ID. It is the caller's * responsibility to ensure the terminal ID is correct and there is * enough space in the buffer for this to complete successfully. * * Parameters * pRing Ring buffer to post to. * TerminalId Terminal ID to switch to. */ static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { unsigned char ac[2]; ac[0] = 0xFFu; ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit _WriteBlocking(pRing, (const char*)ac, 2u); } /********************************************************************* * * _GetAvailWriteSpace() * * Function description * Returns the number of bytes that can be written to the ring * buffer without blocking. * * Parameters * pRing Ring buffer to check. * * Return value * Number of bytes that are free in the buffer. */ static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { unsigned RdOff; unsigned WrOff; unsigned r; // // Avoid warnings regarding volatile access order. It's not a problem // in this case, but dampen compiler enthusiasm. // RdOff = pRing->RdOff; WrOff = pRing->WrOff; if (RdOff <= WrOff) { r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; } else { r = RdOff - WrOff - 1u; } return r; } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * SEGGER_RTT_ReadUpBufferNoLock() * * Function description * Reads characters from SEGGER real-time-terminal control block * which have been previously stored by the application. * Do not lock against interrupts and multiple access. * Used to do the same operation that J-Link does, to transfer * RTT data via other channels, such as TCP/IP or UART. * * Parameters * BufferIndex Index of Up-buffer to be used. * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. * BufferSize Size of the target application buffer. * * Return value * Number of bytes that have been read. * * Additional information * This function must not be called when J-Link might also do RTT. */ unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { unsigned NumBytesRem; unsigned NumBytesRead; unsigned RdOff; unsigned WrOff; unsigned char* pBuffer; SEGGER_RTT_BUFFER_UP* pRing; volatile char* pSrc; INIT(); pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly pBuffer = (unsigned char*)pData; RdOff = pRing->RdOff; WrOff = pRing->WrOff; NumBytesRead = 0u; // // Read from current read position to wrap-around of buffer, first // if (RdOff > WrOff) { NumBytesRem = pRing->SizeOfBuffer - RdOff; NumBytesRem = MIN(NumBytesRem, BufferSize); pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytesRead += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; while (NumBytesRem--) { *pBuffer++ = *pSrc++; }; #else SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); NumBytesRead += NumBytesRem; pBuffer += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; #endif // // Handle wrap-around of buffer // if (RdOff == pRing->SizeOfBuffer) { RdOff = 0u; } } // // Read remaining items of buffer // NumBytesRem = WrOff - RdOff; NumBytesRem = MIN(NumBytesRem, BufferSize); if (NumBytesRem > 0u) { pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytesRead += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; while (NumBytesRem--) { *pBuffer++ = *pSrc++; }; #else SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); NumBytesRead += NumBytesRem; pBuffer += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; #endif } // // Update read offset of buffer // if (NumBytesRead) { pRing->RdOff = RdOff; } // return NumBytesRead; } /********************************************************************* * * SEGGER_RTT_ReadNoLock() * * Function description * Reads characters from SEGGER real-time-terminal control block * which have been previously stored by the host. * Do not lock against interrupts and multiple access. * * Parameters * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. * BufferSize Size of the target application buffer. * * Return value * Number of bytes that have been read. */ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { unsigned NumBytesRem; unsigned NumBytesRead; unsigned RdOff; unsigned WrOff; unsigned char* pBuffer; SEGGER_RTT_BUFFER_DOWN* pRing; volatile char* pSrc; // INIT(); pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly pBuffer = (unsigned char*)pData; RdOff = pRing->RdOff; WrOff = pRing->WrOff; NumBytesRead = 0u; // // Read from current read position to wrap-around of buffer, first // if (RdOff > WrOff) { NumBytesRem = pRing->SizeOfBuffer - RdOff; NumBytesRem = MIN(NumBytesRem, BufferSize); pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytesRead += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; while (NumBytesRem--) { *pBuffer++ = *pSrc++; }; #else SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); NumBytesRead += NumBytesRem; pBuffer += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; #endif // // Handle wrap-around of buffer // if (RdOff == pRing->SizeOfBuffer) { RdOff = 0u; } } // // Read remaining items of buffer // NumBytesRem = WrOff - RdOff; NumBytesRem = MIN(NumBytesRem, BufferSize); if (NumBytesRem > 0u) { pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytesRead += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; while (NumBytesRem--) { *pBuffer++ = *pSrc++; }; #else SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem); NumBytesRead += NumBytesRem; pBuffer += NumBytesRem; BufferSize -= NumBytesRem; RdOff += NumBytesRem; #endif } if (NumBytesRead) { pRing->RdOff = RdOff; } // return NumBytesRead; } /********************************************************************* * * SEGGER_RTT_ReadUpBuffer * * Function description * Reads characters from SEGGER real-time-terminal control block * which have been previously stored by the application. * Used to do the same operation that J-Link does, to transfer * RTT data via other channels, such as TCP/IP or UART. * * Parameters * BufferIndex Index of Up-buffer to be used. * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to. * BufferSize Size of the target application buffer. * * Return value * Number of bytes that have been read. * * Additional information * This function must not be called when J-Link might also do RTT. * This function locks against all other RTT operations. I.e. during * the read operation, writing is also locked. * If only one consumer reads from the up buffer, * call sEGGER_RTT_ReadUpBufferNoLock() instead. */ unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { unsigned NumBytesRead; SEGGER_RTT_LOCK(); // // Call the non-locking read function // NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize); // // Finish up. // SEGGER_RTT_UNLOCK(); // return NumBytesRead; } /********************************************************************* * * SEGGER_RTT_Read * * Function description * Reads characters from SEGGER real-time-terminal control block * which have been previously stored by the host. * * Parameters * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. * BufferSize Size of the target application buffer. * * Return value * Number of bytes that have been read. */ unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { unsigned NumBytesRead; SEGGER_RTT_LOCK(); // // Call the non-locking read function // NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); // // Finish up. // SEGGER_RTT_UNLOCK(); // return NumBytesRead; } /********************************************************************* * * SEGGER_RTT_WriteWithOverwriteNoLock * * Function description * Stores a specified number of characters in SEGGER RTT * control block. * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application * and overwrites data if the data does not fit into the buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Notes * (1) If there is not enough space in the "Up"-buffer, data is overwritten. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link * connection reads RTT data. */ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { const char* pData; SEGGER_RTT_BUFFER_UP* pRing; unsigned Avail; volatile char* pDst; // // Get "to-host" ring buffer and copy some elements into local variables. // pData = (const char *)pBuffer; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // Check if we will overwrite data and need to adjust the RdOff. // if (pRing->WrOff == pRing->RdOff) { Avail = pRing->SizeOfBuffer - 1u; } else if ( pRing->WrOff < pRing->RdOff) { Avail = pRing->RdOff - pRing->WrOff - 1u; } else { Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; } if (NumBytes > Avail) { pRing->RdOff += (NumBytes - Avail); while (pRing->RdOff >= pRing->SizeOfBuffer) { pRing->RdOff -= pRing->SizeOfBuffer; } } // // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds // Avail = pRing->SizeOfBuffer - pRing->WrOff; do { if (Avail > NumBytes) { // // Last round // pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP Avail = NumBytes; while (NumBytes--) { *pDst++ = *pData++; }; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff += Avail; #else SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff += NumBytes; #endif break; } else { // // Wrap-around necessary, write until wrap-around and reset WrOff // pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; #if SEGGER_RTT_MEMCPY_USE_BYTELOOP NumBytes -= Avail; while (Avail--) { *pDst++ = *pData++; }; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = 0; #else SEGGER_RTT_MEMCPY((void*)pDst, pData, Avail); pData += Avail; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = 0; NumBytes -= Avail; #endif Avail = (pRing->SizeOfBuffer - 1); } } while (NumBytes); } /********************************************************************* * * SEGGER_RTT_WriteSkipNoLock * * Function description * Stores a specified number of characters in SEGGER RTT * control block which is then read by the host. * SEGGER_RTT_WriteSkipNoLock does not lock the application and * skips all data, if the data does not fit into the buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * MUST be > 0!!! * This is done for performance reasons, so no initial check has do be done. * * Return value * 1: Data has been copied * 0: No space, data has not been copied * * Notes * (1) If there is not enough space in the "Up"-buffer, all data is dropped. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. */ #if (RTT_USE_ASM == 0) unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { const char* pData; SEGGER_RTT_BUFFER_UP* pRing; unsigned Avail; unsigned RdOff; unsigned WrOff; unsigned Rem; volatile char* pDst; // // Cases: // 1) RdOff <= WrOff => Space until wrap-around is sufficient // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) // 3) RdOff < WrOff => No space in buf // 4) RdOff > WrOff => Space is sufficient // 5) RdOff > WrOff => No space in buf // // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough // pData = (const char *)pBuffer; pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly RdOff = pRing->RdOff; WrOff = pRing->WrOff; pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; if (RdOff <= WrOff) { // Case 1), 2) or 3) Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) if (Avail >= NumBytes) { // Case 1)? memcpy((void*)pDst, pData, NumBytes); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff + NumBytes; return 1; } Avail += RdOff; // Space incl. wrap-around if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer memcpy((void*)pDst, pData, Rem); // Copy 1st chunk NumBytes -= Rem; // // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks // Therefore, check if 2nd memcpy is necessary at all // if (NumBytes) { pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF; memcpy((void*)pDst, pData + Rem, NumBytes); } RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = NumBytes; return 1; } } else { // Potential case 4) Avail = RdOff - WrOff - 1u; if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) memcpy((void*)pDst, pData, NumBytes); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff + NumBytes; return 1; } } return 0; // No space in buffer } #endif /********************************************************************* * * SEGGER_RTT_WriteDownBufferNoLock * * Function description * Stores a specified number of characters in SEGGER RTT * control block inside a buffer. * SEGGER_RTT_WriteDownBufferNoLock does not lock the application. * Used to do the same operation that J-Link does, to transfer * RTT data from other channels, such as TCP/IP or UART. * * Parameters * BufferIndex Index of "Down"-buffer to be used. * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Return value * Number of bytes which have been stored in the "Down"-buffer. * * Notes * (1) Data is stored according to buffer flags. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. * * Additional information * This function must not be called when J-Link might also do RTT. */ unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { unsigned Status; unsigned Avail; const char* pData; SEGGER_RTT_BUFFER_UP* pRing; // // Get "to-target" ring buffer. // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link. // pData = (const char *)pBuffer; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // How we output depends upon the mode... // switch (pRing->Flags) { case SEGGER_RTT_MODE_NO_BLOCK_SKIP: // // If we are in skip mode and there is no space for the whole // of this output, don't bother. // Avail = _GetAvailWriteSpace(pRing); if (Avail < NumBytes) { Status = 0u; } else { Status = NumBytes; _WriteNoCheck(pRing, pData, NumBytes); } break; case SEGGER_RTT_MODE_NO_BLOCK_TRIM: // // If we are in trim mode, trim to what we can output without blocking. // Avail = _GetAvailWriteSpace(pRing); Status = Avail < NumBytes ? Avail : NumBytes; _WriteNoCheck(pRing, pData, Status); break; case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: // // If we are in blocking mode, output everything. // Status = _WriteBlocking(pRing, pData, NumBytes); break; default: Status = 0u; break; } // // Finish up. // return Status; } /********************************************************************* * * SEGGER_RTT_WriteNoLock * * Function description * Stores a specified number of characters in SEGGER RTT * control block which is then read by the host. * SEGGER_RTT_WriteNoLock does not lock the application. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) Data is stored according to buffer flags. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. */ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { unsigned Status; unsigned Avail; const char* pData; SEGGER_RTT_BUFFER_UP* pRing; // // Get "to-host" ring buffer. // pData = (const char *)pBuffer; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // How we output depends upon the mode... // switch (pRing->Flags) { case SEGGER_RTT_MODE_NO_BLOCK_SKIP: // // If we are in skip mode and there is no space for the whole // of this output, don't bother. // Avail = _GetAvailWriteSpace(pRing); if (Avail < NumBytes) { Status = 0u; } else { Status = NumBytes; _WriteNoCheck(pRing, pData, NumBytes); } break; case SEGGER_RTT_MODE_NO_BLOCK_TRIM: // // If we are in trim mode, trim to what we can output without blocking. // Avail = _GetAvailWriteSpace(pRing); Status = Avail < NumBytes ? Avail : NumBytes; _WriteNoCheck(pRing, pData, Status); break; case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: // // If we are in blocking mode, output everything. // Status = _WriteBlocking(pRing, pData, NumBytes); break; default: Status = 0u; break; } // // Finish up. // return Status; } /********************************************************************* * * SEGGER_RTT_WriteDownBuffer * * Function description * Stores a specified number of characters in SEGGER RTT control block in a buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Return value * Number of bytes which have been stored in the "Down"-buffer. * * Notes * (1) Data is stored according to buffer flags. * * Additional information * This function must not be called when J-Link might also do RTT. * This function locks against all other RTT operations. I.e. during * the write operation, writing from the application is also locked. * If only one consumer writes to the down buffer, * call SEGGER_RTT_WriteDownBufferNoLock() instead. */ unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { unsigned Status; INIT(); SEGGER_RTT_LOCK(); Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function SEGGER_RTT_UNLOCK(); return Status; } /********************************************************************* * * SEGGER_RTT_Write * * Function description * Stores a specified number of characters in SEGGER RTT * control block which is then read by the host. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) Data is stored according to buffer flags. */ unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { unsigned Status; INIT(); SEGGER_RTT_LOCK(); Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function SEGGER_RTT_UNLOCK(); return Status; } /********************************************************************* * * SEGGER_RTT_WriteString * * Function description * Stores string in SEGGER RTT control block. * This data is read by the host. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * s Pointer to string. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) Data is stored according to buffer flags. * (2) String passed to this function has to be \0 terminated * (3) \0 termination character is *not* stored in RTT buffer */ unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { unsigned Len; Len = STRLEN(s); return SEGGER_RTT_Write(BufferIndex, s, Len); } /********************************************************************* * * SEGGER_RTT_PutCharSkipNoLock * * Function description * Stores a single character/byte in SEGGER RTT buffer. * SEGGER_RTT_PutCharSkipNoLock does not lock the application and * skips the byte, if it does not fit into the buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * c Byte to be stored. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) If there is not enough space in the "Up"-buffer, the character is dropped. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. */ unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { SEGGER_RTT_BUFFER_UP* pRing; unsigned WrOff; unsigned Status; volatile char* pDst; // // Get "to-host" ring buffer. // pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // Get write position and handle wrap-around if necessary // WrOff = pRing->WrOff + 1; if (WrOff == pRing->SizeOfBuffer) { WrOff = 0; } // // Output byte if free space is available // if (WrOff != pRing->RdOff) { pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; *pDst = c; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff; Status = 1; } else { Status = 0; } // return Status; } /********************************************************************* * * SEGGER_RTT_PutCharSkip * * Function description * Stores a single character/byte in SEGGER RTT buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * c Byte to be stored. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) If there is not enough space in the "Up"-buffer, the character is dropped. */ unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { SEGGER_RTT_BUFFER_UP* pRing; unsigned WrOff; unsigned Status; volatile char* pDst; // // Prepare // INIT(); SEGGER_RTT_LOCK(); // // Get "to-host" ring buffer. // pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // Get write position and handle wrap-around if necessary // WrOff = pRing->WrOff + 1; if (WrOff == pRing->SizeOfBuffer) { WrOff = 0; } // // Output byte if free space is available // if (WrOff != pRing->RdOff) { pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; *pDst = c; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff; Status = 1; } else { Status = 0; } // // Finish up. // SEGGER_RTT_UNLOCK(); // return Status; } /********************************************************************* * * SEGGER_RTT_PutChar * * Function description * Stores a single character/byte in SEGGER RTT buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * c Byte to be stored. * * Return value * Number of bytes which have been stored in the "Up"-buffer. * * Notes * (1) Data is stored according to buffer flags. */ unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { SEGGER_RTT_BUFFER_UP* pRing; unsigned WrOff; unsigned Status; volatile char* pDst; // // Prepare // INIT(); SEGGER_RTT_LOCK(); // // Get "to-host" ring buffer. // pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // Get write position and handle wrap-around if necessary // WrOff = pRing->WrOff + 1; if (WrOff == pRing->SizeOfBuffer) { WrOff = 0; } // // Wait for free space if mode is set to blocking // if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { while (WrOff == pRing->RdOff) { ; } } // // Output byte if free space is available // if (WrOff != pRing->RdOff) { pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF; *pDst = c; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff; Status = 1; } else { Status = 0; } // // Finish up. // SEGGER_RTT_UNLOCK(); return Status; } /********************************************************************* * * SEGGER_RTT_GetKey * * Function description * Reads one character from the SEGGER RTT buffer. * Host has previously stored data there. * * Return value * < 0 - No character available (buffer empty). * >= 0 - Character which has been read. (Possible values: 0 - 255) * * Notes * (1) This function is only specified for accesses to RTT buffer 0. */ int SEGGER_RTT_GetKey(void) { char c; int r; r = (int)SEGGER_RTT_Read(0u, &c, 1u); if (r == 1) { r = (int)(unsigned char)c; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_WaitKey * * Function description * Waits until at least one character is avaible in the SEGGER RTT buffer. * Once a character is available, it is read and this function returns. * * Return value * >=0 - Character which has been read. * * Notes * (1) This function is only specified for accesses to RTT buffer 0 * (2) This function is blocking if no character is present in RTT buffer */ int SEGGER_RTT_WaitKey(void) { int r; do { r = SEGGER_RTT_GetKey(); } while (r < 0); return r; } /********************************************************************* * * SEGGER_RTT_HasKey * * Function description * Checks if at least one character for reading is available in the SEGGER RTT buffer. * * Return value * == 0 - No characters are available to read. * == 1 - At least one character is available. * * Notes * (1) This function is only specified for accesses to RTT buffer 0 */ int SEGGER_RTT_HasKey(void) { SEGGER_RTT_BUFFER_DOWN* pRing; unsigned RdOff; int r; INIT(); pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly RdOff = pRing->RdOff; if (RdOff != pRing->WrOff) { r = 1; } else { r = 0; } return r; } /********************************************************************* * * SEGGER_RTT_HasData * * Function description * Check if there is data from the host in the given buffer. * * Return value: * ==0: No data * !=0: Data in buffer * */ unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { SEGGER_RTT_BUFFER_DOWN* pRing; unsigned v; pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly v = pRing->WrOff; return v - pRing->RdOff; } /********************************************************************* * * SEGGER_RTT_HasDataUp * * Function description * Check if there is data remaining to be sent in the given buffer. * * Return value: * ==0: No data * !=0: Data in buffer * */ unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { SEGGER_RTT_BUFFER_UP* pRing; unsigned v; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly v = pRing->RdOff; return pRing->WrOff - v; } /********************************************************************* * * SEGGER_RTT_AllocDownBuffer * * Function description * Run-time configuration of the next down-buffer (H->T). * The next buffer, which is not used yet is configured. * This includes: Buffer address, size, name, flags, ... * * Parameters * sName Pointer to a constant name string. * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. Buffer Index * < 0 - Error */ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int BufferIndex; volatile SEGGER_RTT_CB* pRTTCB; INIT(); SEGGER_RTT_LOCK(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly BufferIndex = 0; do { if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) { break; } BufferIndex++; } while (BufferIndex < pRTTCB->MaxNumDownBuffers); if (BufferIndex < pRTTCB->MaxNumDownBuffers) { pRTTCB->aDown[BufferIndex].sName = sName; pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer; pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize; pRTTCB->aDown[BufferIndex].RdOff = 0u; pRTTCB->aDown[BufferIndex].WrOff = 0u; pRTTCB->aDown[BufferIndex].Flags = Flags; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses } else { BufferIndex = -1; } SEGGER_RTT_UNLOCK(); return BufferIndex; } /********************************************************************* * * SEGGER_RTT_AllocUpBuffer * * Function description * Run-time configuration of the next up-buffer (T->H). * The next buffer, which is not used yet is configured. * This includes: Buffer address, size, name, flags, ... * * Parameters * sName Pointer to a constant name string. * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. Buffer Index * < 0 - Error */ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int BufferIndex; volatile SEGGER_RTT_CB* pRTTCB; INIT(); SEGGER_RTT_LOCK(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly BufferIndex = 0; do { if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) { break; } BufferIndex++; } while (BufferIndex < pRTTCB->MaxNumUpBuffers); if (BufferIndex < pRTTCB->MaxNumUpBuffers) { pRTTCB->aUp[BufferIndex].sName = sName; pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer; pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize; pRTTCB->aUp[BufferIndex].RdOff = 0u; pRTTCB->aUp[BufferIndex].WrOff = 0u; pRTTCB->aUp[BufferIndex].Flags = Flags; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses } else { BufferIndex = -1; } SEGGER_RTT_UNLOCK(); return BufferIndex; } /********************************************************************* * * SEGGER_RTT_ConfigUpBuffer * * Function description * Run-time configuration of a specific up-buffer (T->H). * Buffer to be configured is specified by index. * This includes: Buffer address, size, name, flags, ... * * Parameters * BufferIndex Index of the buffer to configure. * sName Pointer to a constant name string. * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. * < 0 - Error * * Additional information * Buffer 0 is configured on compile-time. * May only be called once per buffer. * Buffer name and flags can be reconfigured using the appropriate functions. */ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); pUp = &pRTTCB->aUp[BufferIndex]; if (BufferIndex) { pUp->sName = sName; pUp->pBuffer = (char*)pBuffer; pUp->SizeOfBuffer = BufferSize; pUp->RdOff = 0u; pUp->WrOff = 0u; } pUp->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_ConfigDownBuffer * * Function description * Run-time configuration of a specific down-buffer (H->T). * Buffer to be configured is specified by index. * This includes: Buffer address, size, name, flags, ... * * Parameters * BufferIndex Index of the buffer to configure. * sName Pointer to a constant name string. * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. * < 0 Error * * Additional information * Buffer 0 is configured on compile-time. * May only be called once per buffer. * Buffer name and flags can be reconfigured using the appropriate functions. */ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); pDown = &pRTTCB->aDown[BufferIndex]; if (BufferIndex) { pDown->sName = sName; pDown->pBuffer = (char*)pBuffer; pDown->SizeOfBuffer = BufferSize; pDown->RdOff = 0u; pDown->WrOff = 0u; } pDown->Flags = Flags; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_SetNameUpBuffer * * Function description * Run-time configuration of a specific up-buffer name (T->H). * Buffer to be configured is specified by index. * * Parameters * BufferIndex Index of the buffer to renamed. * sName Pointer to a constant name string. * * Return value * >= 0 O.K. * < 0 Error */ int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); pUp = &pRTTCB->aUp[BufferIndex]; pUp->sName = sName; SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_SetNameDownBuffer * * Function description * Run-time configuration of a specific Down-buffer name (T->H). * Buffer to be configured is specified by index. * * Parameters * BufferIndex Index of the buffer to renamed. * sName Pointer to a constant name string. * * Return value * >= 0 O.K. * < 0 Error */ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); pDown = &pRTTCB->aDown[BufferIndex]; pDown->sName = sName; SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_SetFlagsUpBuffer * * Function description * Run-time configuration of specific up-buffer flags (T->H). * Buffer to be configured is specified by index. * * Parameters * BufferIndex Index of the buffer. * Flags Flags to set for the buffer. * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. * < 0 Error */ int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); pUp = &pRTTCB->aUp[BufferIndex]; pUp->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_SetFlagsDownBuffer * * Function description * Run-time configuration of specific Down-buffer flags (T->H). * Buffer to be configured is specified by index. * * Parameters * BufferIndex Index of the buffer to renamed. * Flags Flags to set for the buffer. * Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. * < 0 Error */ int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); pDown = &pRTTCB->aDown[BufferIndex]; pDown->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_Init * * Function description * Initializes the RTT Control Block. * Should be used in RAM targets, at start of the application. * */ void SEGGER_RTT_Init (void) { _DoInit(); } /********************************************************************* * * SEGGER_RTT_SetTerminal * * Function description * Sets the terminal to be used for output on channel 0. * * Parameters * TerminalId Index of the terminal. * * Return value * >= 0 O.K. * < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) * * Notes * (1) Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed */ int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { unsigned char ac[2]; SEGGER_RTT_BUFFER_UP* pRing; unsigned Avail; int r; INIT(); r = 0; ac[0] = 0xFFu; if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels ac[1] = _aTerminalId[TerminalId]; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { _ActiveTerminal = TerminalId; _WriteBlocking(pRing, (const char*)ac, 2u); } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes Avail = _GetAvailWriteSpace(pRing); if (Avail >= 2) { _ActiveTerminal = TerminalId; // Only change active terminal in case of success _WriteNoCheck(pRing, (const char*)ac, 2u); } else { r = -1; } } SEGGER_RTT_UNLOCK(); } else { r = -1; } return r; } /********************************************************************* * * SEGGER_RTT_TerminalOut * * Function description * Writes a string to the given terminal * without changing the terminal for channel 0. * * Parameters * TerminalId Index of the terminal. * s String to be printed on the terminal. * * Return value * >= 0 - Number of bytes written. * < 0 - Error. * */ int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { int Status; unsigned FragLen; unsigned Avail; SEGGER_RTT_BUFFER_UP* pRing; // INIT(); // // Validate terminal ID. // if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels // // Get "to-host" ring buffer. // pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly // // Need to be able to change terminal, write data, change back. // Compute the fixed and variable sizes. // FragLen = STRLEN(s); // // How we output depends upon the mode... // SEGGER_RTT_LOCK(); Avail = _GetAvailWriteSpace(pRing); switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { case SEGGER_RTT_MODE_NO_BLOCK_SKIP: // // If we are in skip mode and there is no space for the whole // of this output, don't bother switching terminals at all. // if (Avail < (FragLen + 4u)) { Status = 0; } else { _PostTerminalSwitch(pRing, TerminalId); Status = (int)_WriteBlocking(pRing, s, FragLen); _PostTerminalSwitch(pRing, _ActiveTerminal); } break; case SEGGER_RTT_MODE_NO_BLOCK_TRIM: // // If we are in trim mode and there is not enough space for everything, // trim the output but always include the terminal switch. If no room // for terminal switch, skip that totally. // if (Avail < 4u) { Status = -1; } else { _PostTerminalSwitch(pRing, TerminalId); Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); _PostTerminalSwitch(pRing, _ActiveTerminal); } break; case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: // // If we are in blocking mode, output everything. // _PostTerminalSwitch(pRing, TerminalId); Status = (int)_WriteBlocking(pRing, s, FragLen); _PostTerminalSwitch(pRing, _ActiveTerminal); break; default: Status = -1; break; } // // Finish up. // SEGGER_RTT_UNLOCK(); } else { Status = -1; } return Status; } /********************************************************************* * * SEGGER_RTT_GetAvailWriteSpace * * Function description * Returns the number of bytes available in the ring buffer. * * Parameters * BufferIndex Index of the up buffer. * * Return value * Number of bytes that are free in the selected up buffer. */ unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) { SEGGER_RTT_BUFFER_UP* pRing; pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly return _GetAvailWriteSpace(pRing); } /********************************************************************* * * SEGGER_RTT_GetBytesInBuffer() * * Function description * Returns the number of bytes currently used in the up buffer. * * Parameters * BufferIndex Index of the up buffer. * * Return value * Number of bytes that are used in the buffer. */ unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) { unsigned RdOff; unsigned WrOff; unsigned r; volatile SEGGER_RTT_CB* pRTTCB; // // Avoid warnings regarding volatile access order. It's not a problem // in this case, but dampen compiler enthusiasm. // pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly RdOff = pRTTCB->aUp[BufferIndex].RdOff; WrOff = pRTTCB->aUp[BufferIndex].WrOff; if (RdOff <= WrOff) { r = WrOff - RdOff; } else { r = pRTTCB->aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff); } return r; } /*************************** End of file ****************************/ ================================================ FILE: lib/SEGGER_RTT/RTT/SEGGER_RTT.h ================================================ /********************************************************************* * SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 1995 - 2019 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * ********************************************************************** * * * SEGGER RTT * Real Time Transfer for embedded targets * * * ********************************************************************** * * * All rights reserved. * * * * SEGGER strongly recommends to not make any changes * * to or modify the source code of this software in order to stay * * compatible with the RTT protocol and J-Link. * * * * Redistribution and use in source and binary forms, with or * * without modification, are permitted provided that the following * * condition is met: * * * * o Redistributions of source code must retain the above copyright * * notice, this condition and the following disclaimer. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * CONTRIBUTORS "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 SEGGER Microcontroller 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. * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ File : SEGGER_RTT.h Purpose : Implementation of SEGGER real-time transfer which allows real-time communication on targets which support debugger memory accesses while the CPU is running. Revision: $Rev: 25842 $ ---------------------------------------------------------------------- */ #ifndef SEGGER_RTT_H #define SEGGER_RTT_H #include "../Config/SEGGER_RTT_Conf.h" /********************************************************************* * * Defines, defaults * ********************************************************************** */ #ifndef RTT_USE_ASM // // Some cores support out-of-order memory accesses (reordering of memory accesses in the core) // For such cores, we need to define a memory barrier to guarantee the order of certain accesses to the RTT ring buffers. // Needed for: // Cortex-M7 (ARMv7-M) // Cortex-M23 (ARM-v8M) // Cortex-M33 (ARM-v8M) // Cortex-A/R (ARM-v7A/R) // // We do not explicitly check for "Embedded Studio" as the compiler in use determines what we support. // You can use an external toolchain like IAR inside ES. So there is no point in checking for "Embedded Studio" // #if (defined __CROSSWORKS_ARM) // Rowley Crossworks #define _CC_HAS_RTT_ASM_SUPPORT 1 #if (defined __ARM_ARCH_7M__) // Cortex-M3 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 #define _CORE_HAS_RTT_ASM_SUPPORT 0 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined(__ARM_ARCH_8_1M_MAIN__)) // Cortex-M85 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #else #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif #elif (defined __ARMCC_VERSION) // // ARM compiler // ARM compiler V6.0 and later is clang based. // Our ASM part is compatible to clang. // #if (__ARMCC_VERSION >= 6000000) #define _CC_HAS_RTT_ASM_SUPPORT 1 #else #define _CC_HAS_RTT_ASM_SUPPORT 0 #endif #if (defined __ARM_ARCH_6M__) // Cortex-M0 / M1 #define _CORE_HAS_RTT_ASM_SUPPORT 0 // No ASM support for this architecture #elif (defined __ARM_ARCH_7M__) // Cortex-M3 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 #define _CORE_HAS_RTT_ASM_SUPPORT 0 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #else #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif #elif ((defined __GNUC__) || (defined __clang__)) // // GCC / Clang // #define _CC_HAS_RTT_ASM_SUPPORT 1 // ARM 7/9: __ARM_ARCH_5__ / __ARM_ARCH_5E__ / __ARM_ARCH_5T__ / __ARM_ARCH_5T__ / __ARM_ARCH_5TE__ #if (defined __ARM_ARCH_7M__) // Cortex-M3 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 // Only Cortex-M7 needs a DMB but we cannot distinguish M4 and M7 here... #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 #define _CORE_HAS_RTT_ASM_SUPPORT 0 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); #else #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif #elif ((defined __IASMARM__) || (defined __ICCARM__)) // // IAR assembler/compiler // #define _CC_HAS_RTT_ASM_SUPPORT 1 #if (__VER__ < 6300000) #define VOLATILE #else #define VOLATILE volatile #endif #if (defined __ARM7M__) // Needed for old versions that do not know the define yet #if (__CORE__ == __ARM7M__) // Cortex-M3 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #endif #endif #if (defined __ARM7EM__) #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif #if (defined __ARM8M_BASELINE__) #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 #define _CORE_HAS_RTT_ASM_SUPPORT 0 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif #if (defined __ARM8M_MAINLINE__) #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif #if (defined __ARM8EM_MAINLINE__) #if (__CORE__ == __ARM8EM_MAINLINE__) // Cortex-??? #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif #if (defined __ARM7A__) #if (__CORE__ == __ARM7A__) // Cortex-A 32-bit ARMv7-A #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif #if (defined __ARM7R__) #if (__CORE__ == __ARM7R__) // Cortex-R 32-bit ARMv7-R #define _CORE_NEEDS_DMB 1 #define RTT__DMB() asm VOLATILE ("DMB"); #endif #endif // TBD: __ARM8A__ => Cortex-A 64-bit ARMv8-A // TBD: __ARM8R__ => Cortex-R 64-bit ARMv8-R #else // // Other compilers // #define _CC_HAS_RTT_ASM_SUPPORT 0 #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif // // If IDE and core support the ASM version, enable ASM version by default // #ifndef _CORE_HAS_RTT_ASM_SUPPORT #define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores #endif #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT) #define RTT_USE_ASM (1) #else #define RTT_USE_ASM (0) #endif #endif #ifndef _CORE_NEEDS_DMB #define _CORE_NEEDS_DMB 0 #endif #ifndef RTT__DMB #if _CORE_NEEDS_DMB #error "Don't know how to place inline assembly for DMB" #else #define RTT__DMB() #endif #endif #ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE #define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here #endif #ifndef SEGGER_RTT_UNCACHED_OFF #if SEGGER_RTT_CPU_CACHE_LINE_SIZE #error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #else #define SEGGER_RTT_UNCACHED_OFF (0) #endif #endif #if RTT_USE_ASM #if SEGGER_RTT_CPU_CACHE_LINE_SIZE #error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0" #endif #endif #ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file #include #include #include /********************************************************************* * * Defines, fixed * ********************************************************************** */ // // Determine how much we must pad the control block to make it a multiple of a cache line in size // Assuming: U8 = 1B // U16 = 2B // U32 = 4B // U8/U16/U32* = 4B // #if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE) #else #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes) #endif #define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24)) #define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE) /********************************************************************* * * Types * ********************************************************************** */ // // Description for a circular buffer (also called "ring buffer") // which is used as up-buffer (T->H) // typedef struct { const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" char* pBuffer; // Pointer to start of buffer unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. unsigned WrOff; // Position of next item to be written by either target. volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. } SEGGER_RTT_BUFFER_UP; // // Description for a circular buffer (also called "ring buffer") // which is used as down-buffer (H->T) // typedef struct { const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" char* pBuffer; // Pointer to start of buffer unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. unsigned RdOff; // Position of next item to be read by target (down-buffer). unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. } SEGGER_RTT_BUFFER_DOWN; // // RTT control block which describes the number of buffers available // as well as the configuration for each buffer // // typedef struct { char acID[16]; // Initialized to "SEGGER RTT" int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target #if SEGGER_RTT__CB_PADDING unsigned char aDummy[SEGGER_RTT__CB_PADDING]; #endif } SEGGER_RTT_CB; /********************************************************************* * * Global data * ********************************************************************** */ extern SEGGER_RTT_CB _SEGGER_RTT; /********************************************************************* * * RTT API functions * ********************************************************************** */ #ifdef __cplusplus extern "C" { #endif int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); int SEGGER_RTT_GetKey (void); unsigned SEGGER_RTT_HasData (unsigned BufferIndex); int SEGGER_RTT_HasKey (void); unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); void SEGGER_RTT_Init (void); unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); int SEGGER_RTT_WaitKey (void); unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex); unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex); // // Function macro for performance optimization // #define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) #if RTT_USE_ASM #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock #endif /********************************************************************* * * RTT transfer functions to send RTT data via other channels. * ********************************************************************** */ unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); #define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly /********************************************************************* * * RTT "Terminal" API functions * ********************************************************************** */ int SEGGER_RTT_SetTerminal (unsigned char TerminalId); int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s); /********************************************************************* * * RTT printf functions (require SEGGER_RTT_printf.c) * ********************************************************************** */ int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); #ifdef __cplusplus } #endif #endif // ifndef(SEGGER_RTT_ASM) /********************************************************************* * * Defines * ********************************************************************** */ // // Operating modes. Define behavior if buffer is full (not enough space for entire message) // #define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default) #define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits. #define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer. #define SEGGER_RTT_MODE_MASK (3) // // Control sequences, based on ANSI. // Can be used to control color, and clear the screen // #define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors #define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left #define RTT_CTRL_TEXT_BLACK "\x1B[2;30m" #define RTT_CTRL_TEXT_RED "\x1B[2;31m" #define RTT_CTRL_TEXT_GREEN "\x1B[2;32m" #define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m" #define RTT_CTRL_TEXT_BLUE "\x1B[2;34m" #define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m" #define RTT_CTRL_TEXT_CYAN "\x1B[2;36m" #define RTT_CTRL_TEXT_WHITE "\x1B[2;37m" #define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m" #define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m" #define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m" #define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m" #define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m" #define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m" #define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m" #define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m" #define RTT_CTRL_BG_BLACK "\x1B[24;40m" #define RTT_CTRL_BG_RED "\x1B[24;41m" #define RTT_CTRL_BG_GREEN "\x1B[24;42m" #define RTT_CTRL_BG_YELLOW "\x1B[24;43m" #define RTT_CTRL_BG_BLUE "\x1B[24;44m" #define RTT_CTRL_BG_MAGENTA "\x1B[24;45m" #define RTT_CTRL_BG_CYAN "\x1B[24;46m" #define RTT_CTRL_BG_WHITE "\x1B[24;47m" #define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m" #define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m" #define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m" #define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m" #define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m" #define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m" #define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m" #define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m" #endif /*************************** End of file ****************************/ ================================================ FILE: lib/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S ================================================ /********************************************************************* * (c) SEGGER Microcontroller GmbH * * The Embedded Experts * * www.segger.com * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : SEGGER_RTT_ASM_ARMv7M.S Purpose : Assembler implementation of RTT functions for ARMv7M Additional information: This module is written to be assembler-independent and works with GCC and clang (Embedded Studio) and IAR. */ #define SEGGER_RTT_ASM // Used to control processed input from header file #include "SEGGER_RTT.h" /********************************************************************* * * Defines, fixed * ********************************************************************** */ #define _CCIAR 0 #define _CCCLANG 1 #if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__) #define _CC_TYPE _CCCLANG #define _PUB_SYM .global #define _EXT_SYM .extern #define _END .end #define _WEAK .weak #define _THUMB_FUNC .thumb_func #define _THUMB_CODE .code 16 #define _WORD .word #define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax" #define _ALIGN(Exp) .align Exp #define _PLACE_LITS .ltorg #define _DATA_SECT_START #define _C_STARTUP _start #define _STACK_END __stack_end__ #define _RAMFUNC // // .text => Link to flash // .fast => Link to RAM // OtherSect => Usually link to RAM // Alignment is 2^x // #elif defined (__IASMARM__) #define _CC_TYPE _CCIAR #define _PUB_SYM PUBLIC #define _EXT_SYM EXTERN #define _END END #define _WEAK _WEAK #define _THUMB_FUNC #define _THUMB_CODE THUMB #define _WORD DCD #define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp) #define _ALIGN(Exp) alignrom Exp #define _PLACE_LITS #define _DATA_SECT_START DATA #define _C_STARTUP __iar_program_start #define _STACK_END sfe(CSTACK) #define _RAMFUNC SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR // // .text => Link to flash // .textrw => Link to RAM // OtherSect => Usually link to RAM // NOROOT => Allows linker to throw away the function, if not referenced // Alignment is 2^x // #endif #if (_CC_TYPE == _CCIAR) NAME SEGGER_RTT_ASM_ARMv7M #else .syntax unified #endif #if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) #define SHT_PROGBITS 0x1 /********************************************************************* * * Public / external symbols * ********************************************************************** */ _EXT_SYM __aeabi_memcpy _EXT_SYM __aeabi_memcpy4 _EXT_SYM _SEGGER_RTT _PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock /********************************************************************* * * SEGGER_RTT_WriteSkipNoLock * * Function description * Stores a specified number of characters in SEGGER RTT * control block which is then read by the host. * SEGGER_RTT_WriteSkipNoLock does not lock the application and * skips all data, if the data does not fit into the buffer. * * Parameters * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. * NumBytes Number of bytes to be stored in the SEGGER RTT control block. * MUST be > 0!!! * This is done for performance reasons, so no initial check has do be done. * * Return value * 1: Data has been copied * 0: No space, data has not been copied * * Notes * (1) If there is not enough space in the "Up"-buffer, all data is dropped. * (2) For performance reasons this function does not call Init() * and may only be called after RTT has been initialized. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. */ _SECTION(.text, CODE, 2) _ALIGN(2) _THUMB_FUNC SEGGER_RTT_ASM_WriteSkipNoLock: // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) { // // Cases: // 1) RdOff <= WrOff => Space until wrap-around is sufficient // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) // 3) RdOff < WrOff => No space in buf // 4) RdOff > WrOff => Space is sufficient // 5) RdOff > WrOff => No space in buf // // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough // // Register usage: // R0 Temporary needed as RdOff, register later on // R1 pData // R2 // R3 register. Hold free for subroutine calls // R4 // R5 pRing->pBuffer // R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN) // R7 WrOff // PUSH {R4-R7} ADD R3,R0,R0, LSL #+1 LDR.W R0,=_SEGGER_RTT // pRing = &_SEGGER_RTT.aUp[BufferIndex]; ADD R0,R0,R3, LSL #+3 ADD R6,R0,#+24 LDR R0,[R6, #+16] // RdOff = pRing->RdOff; LDR R7,[R6, #+12] // WrOff = pRing->WrOff; LDR R5,[R6, #+4] // pRing->pBuffer CMP R7,R0 BCC.N _CheckCase4 // if (RdOff <= WrOff) { => Case 1), 2) or 3) // // Handling for case 1, later on identical to case 4 // LDR R3,[R6, #+8] // Avail = pRing->SizeOfBuffer - WrOff - 1u; => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) SUBS R4,R3,R7 // (Used in case we jump into case 2 afterwards) SUBS R3,R4,#+1 // CMP R3,R2 BCC.N _CheckCase2 // if (Avail >= NumBytes) { => Case 1)? _Case4: ADDS R5,R7,R5 // pBuffer += WrOff ADDS R0,R2,R7 // v = WrOff + NumBytes // // 2x unrolling for the copy loop that is used most of the time // This is a special optimization for small SystemView packets and makes them even faster // _ALIGN(2) _LoopCopyStraight: // memcpy(pRing->pBuffer + WrOff, pData, NumBytes); LDRB R3,[R1], #+1 STRB R3,[R5], #+1 // *pDest++ = *pSrc++ SUBS R2,R2,#+1 BEQ _CSDone LDRB R3,[R1], #+1 STRB R3,[R5], #+1 // *pDest++ = *pSrc++ SUBS R2,R2,#+1 BNE _LoopCopyStraight _CSDone: #if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct #endif STR R0,[R6, #+12] // pRing->WrOff = WrOff + NumBytes; MOVS R0,#+1 POP {R4-R7} BX LR // Return 1 _CheckCase2: ADDS R0,R0,R3 // Avail += RdOff; => Space incl. wrap-around CMP R0,R2 BCC.N _Case3 // if (Avail >= NumBytes) { => Case 2? => If not, we have case 3) (does not fit) // // Handling for case 2 // ADDS R0,R7,R5 // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value SUBS R2,R2,R4 // NumBytes -= Rem; (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer) _LoopCopyBeforeWrapAround: // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk LDRB R3,[R1], #+1 STRB R3,[R0], #+1 // *pDest++ = *pSrc++ SUBS R4,R4,#+1 BNE _LoopCopyBeforeWrapAround // // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks // Therefore, check if 2nd memcpy is necessary at all // ADDS R4,R2,#+0 // Save (needed as counter in loop but must be written to after the loop). Also use this inst to update the flags to skip 2nd loop if possible BEQ.N _No2ChunkNeeded // if (NumBytes) { _LoopCopyAfterWrapAround: // memcpy(pRing->pBuffer, pData + Rem, NumBytes); LDRB R3,[R1], #+1 // pData already points to the next src byte due to copy loop increment before this loop STRB R3,[R5], #+1 // *pDest++ = *pSrc++ SUBS R2,R2,#+1 BNE _LoopCopyAfterWrapAround _No2ChunkNeeded: #if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the in the struct #endif STR R4,[R6, #+12] // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer MOVS R0,#+1 POP {R4-R7} BX LR // Return 1 _CheckCase4: SUBS R0,R0,R7 SUBS R0,R0,#+1 // Avail = RdOff - WrOff - 1u; CMP R0,R2 BCS.N _Case4 // if (Avail >= NumBytes) { => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit) _Case3: MOVS R0,#+0 POP {R4-R7} BX LR // Return 0 _PLACE_LITS #endif // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1) _END /*************************** End of file ****************************/ ================================================ FILE: lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c ================================================ /********************************************************************* * SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 1995 - 2019 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * ********************************************************************** * * * SEGGER RTT * Real Time Transfer for embedded targets * * * ********************************************************************** * * * All rights reserved. * * * * SEGGER strongly recommends to not make any changes * * to or modify the source code of this software in order to stay * * compatible with the RTT protocol and J-Link. * * * * Redistribution and use in source and binary forms, with or * * without modification, are permitted provided that the following * * condition is met: * * * * o Redistributions of source code must retain the above copyright * * notice, this condition and the following disclaimer. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * * CONTRIBUTORS "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 SEGGER Microcontroller 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. * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ File : SEGGER_RTT_printf.c Purpose : Replacement for printf to write formatted data via RTT Revision: $Rev: 17697 $ ---------------------------------------------------------------------- */ #include "SEGGER_RTT.h" #include "SEGGER_RTT_Conf.h" /********************************************************************* * * Defines, configurable * ********************************************************************** */ #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) #endif #include #include #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) #define FORMAT_FLAG_PAD_ZERO (1u << 1) #define FORMAT_FLAG_PRINT_SIGN (1u << 2) #define FORMAT_FLAG_ALTERNATE (1u << 3) /********************************************************************* * * Types * ********************************************************************** */ typedef struct { char* pBuffer; unsigned BufferSize; unsigned Cnt; int ReturnValue; unsigned RTTBufferIndex; } SEGGER_RTT_PRINTF_DESC; /********************************************************************* * * Function prototypes * ********************************************************************** */ /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _StoreChar */ static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { unsigned Cnt; Cnt = p->Cnt; if ((Cnt + 1u) <= p->BufferSize) { *(p->pBuffer + Cnt) = c; p->Cnt = Cnt + 1u; p->ReturnValue++; } // // Write part of string, when the buffer is full // if (p->Cnt == p->BufferSize) { if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { p->ReturnValue = -1; } else { p->Cnt = 0u; } } } /********************************************************************* * * _PrintUnsigned */ static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; unsigned Div; unsigned Digit; unsigned Number; unsigned Width; char c; Number = v; Digit = 1u; // // Get actual field width // Width = 1u; while (Number >= Base) { Number = (Number / Base); Width++; } if (NumDigits > Width) { Width = NumDigits; } // // Print leading chars if necessary // if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { if (FieldWidth != 0u) { if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { c = '0'; } else { c = ' '; } while ((FieldWidth != 0u) && (Width < FieldWidth)) { FieldWidth--; _StoreChar(pBufferDesc, c); if (pBufferDesc->ReturnValue < 0) { break; } } } } if (pBufferDesc->ReturnValue >= 0) { // // Compute Digit. // Loop until Digit has the value of the highest digit required. // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. // while (1) { if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) NumDigits--; } else { Div = v / Digit; if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done break; } } Digit *= Base; } // // Output digits // do { Div = v / Digit; v -= Div * Digit; _StoreChar(pBufferDesc, _aV2C[Div]); if (pBufferDesc->ReturnValue < 0) { break; } Digit /= Base; } while (Digit); // // Print trailing spaces if necessary // if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { if (FieldWidth != 0u) { while ((FieldWidth != 0u) && (Width < FieldWidth)) { FieldWidth--; _StoreChar(pBufferDesc, ' '); if (pBufferDesc->ReturnValue < 0) { break; } } } } } } /********************************************************************* * * _PrintInt */ static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { unsigned Width; int Number; Number = (v < 0) ? -v : v; // // Get actual field width // Width = 1u; while (Number >= (int)Base) { Number = (Number / (int)Base); Width++; } if (NumDigits > Width) { Width = NumDigits; } if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { FieldWidth--; } // // Print leading spaces if necessary // if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { if (FieldWidth != 0u) { while ((FieldWidth != 0u) && (Width < FieldWidth)) { FieldWidth--; _StoreChar(pBufferDesc, ' '); if (pBufferDesc->ReturnValue < 0) { break; } } } } // // Print sign if necessary // if (pBufferDesc->ReturnValue >= 0) { if (v < 0) { v = -v; _StoreChar(pBufferDesc, '-'); } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { _StoreChar(pBufferDesc, '+'); } else { } if (pBufferDesc->ReturnValue >= 0) { // // Print leading zeros if necessary // if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { if (FieldWidth != 0u) { while ((FieldWidth != 0u) && (Width < FieldWidth)) { FieldWidth--; _StoreChar(pBufferDesc, '0'); if (pBufferDesc->ReturnValue < 0) { break; } } } } if (pBufferDesc->ReturnValue >= 0) { // // Print number without sign // _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); } } } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * SEGGER_RTT_vprintf * * Function description * Stores a formatted string in SEGGER RTT control block. * This data is read by the host. * * Parameters * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") * sFormat Pointer to format string * pParamList Pointer to the list of arguments for the format string * * Return values * >= 0: Number of bytes which have been stored in the "Up"-buffer. * < 0: Error */ int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { char c; SEGGER_RTT_PRINTF_DESC BufferDesc; int v; unsigned NumDigits; unsigned FormatFlags; unsigned FieldWidth; char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; BufferDesc.pBuffer = acBuffer; BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; BufferDesc.Cnt = 0u; BufferDesc.RTTBufferIndex = BufferIndex; BufferDesc.ReturnValue = 0; do { c = *sFormat; sFormat++; if (c == 0u) { break; } if (c == '%') { // // Filter out flags // FormatFlags = 0u; v = 1; do { c = *sFormat; switch (c) { case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; default: v = 0; break; } } while (v); // // filter out field with // FieldWidth = 0u; do { c = *sFormat; if ((c < '0') || (c > '9')) { break; } sFormat++; FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); } while (1); // // Filter out precision (number of digits to display) // NumDigits = 0u; c = *sFormat; if (c == '.') { sFormat++; do { c = *sFormat; if ((c < '0') || (c > '9')) { break; } sFormat++; NumDigits = NumDigits * 10u + ((unsigned)c - '0'); } while (1); } // // Filter out length modifier // c = *sFormat; do { if ((c == 'l') || (c == 'h')) { sFormat++; c = *sFormat; } else { break; } } while (1); // // Handle specifiers // switch (c) { case 'c': { char c0; v = va_arg(*pParamList, int); c0 = (char)v; _StoreChar(&BufferDesc, c0); break; } case 'd': v = va_arg(*pParamList, int); _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'u': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'x': case 'X': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); break; case 's': { const char * s = va_arg(*pParamList, const char *); do { c = *s; s++; if (c == '\0') { break; } _StoreChar(&BufferDesc, c); } while (BufferDesc.ReturnValue >= 0); } break; case 'p': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); break; case '%': _StoreChar(&BufferDesc, '%'); break; default: break; } sFormat++; } else { _StoreChar(&BufferDesc, c); } } while (BufferDesc.ReturnValue >= 0); if (BufferDesc.ReturnValue > 0) { // // Write remaining data, if any // if (BufferDesc.Cnt != 0u) { SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); } BufferDesc.ReturnValue += (int)BufferDesc.Cnt; } return BufferDesc.ReturnValue; } /********************************************************************* * * SEGGER_RTT_printf * * Function description * Stores a formatted string in SEGGER RTT control block. * This data is read by the host. * * Parameters * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") * sFormat Pointer to format string, followed by the arguments for conversion * * Return values * >= 0: Number of bytes which have been stored in the "Up"-buffer. * < 0: Error * * Notes * (1) Conversion specifications have following syntax: * %[flags][FieldWidth][.Precision]ConversionSpecifier * (2) Supported flags: * -: Left justify within the field width * +: Always print sign extension for signed conversions * 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision * Supported conversion specifiers: * c: Print the argument as one char * d: Print the argument as a signed integer * u: Print the argument as an unsigned integer * x: Print the argument as an hexadecimal integer * s: Print the string pointed to by the argument * p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) */ int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { int r; va_list ParamList; va_start(ParamList, sFormat); r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); va_end(ParamList); return r; } /*************************** End of file ****************************/ ================================================ FILE: lib/embedded-cli/embedded_cli.h ================================================ /** * This header was automatically built using * embedded_cli.h and embedded_cli.c * @date 2022-11-03 * * MIT License * * Copyright (c) 2021 Sviatoslav Kokurin (funbiscuit) * * 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. */ #ifndef EMBEDDED_CLI_H #define EMBEDDED_CLI_H #ifdef __cplusplus extern "C" { #else #include #endif // cstdint is available only since C++11, so use C header #include // used for proper alignment of cli buffer #if UINTPTR_MAX == 0xFFFF #define CLI_UINT uint16_t #elif UINTPTR_MAX == 0xFFFFFFFF #define CLI_UINT uint32_t #elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu #define CLI_UINT uint64_t #else #error unsupported pointer size #endif #define CLI_UINT_SIZE (sizeof(CLI_UINT)) // convert size in bytes to size in terms of CLI_UINTs (rounded up // if bytes is not divisible by size of single CLI_UINT) #define BYTES_TO_CLI_UINTS(bytes) \ (((bytes) + CLI_UINT_SIZE - 1)/CLI_UINT_SIZE) typedef struct CliCommand CliCommand; typedef struct CliCommandBinding CliCommandBinding; typedef struct EmbeddedCli EmbeddedCli; typedef struct EmbeddedCliConfig EmbeddedCliConfig; struct CliCommand { /** * Name of the command. * In command "set led 1 1" "set" is name */ const char *name; /** * String of arguments of the command. * In command "set led 1 1" "led 1 1" is string of arguments * Is ended with double 0x00 char * Use tokenize functions to easily get individual tokens */ char *args; }; /** * Struct to describe binding of command to function and */ struct CliCommandBinding { /** * Name of command to bind. Should not be NULL. */ const char *name; /** * Help string that will be displayed when "help " is executed. * Can have multiple lines separated with "\r\n" * Can be NULL if no help is provided. */ const char *help; /** * Flag to perform tokenization before calling binding function. */ bool tokenizeArgs; /** * Pointer to any specific app context that is required for this binding. * It will be provided in binding callback. */ void *context; /** * Binding function for when command is received. * If null, default callback (onCommand) will be called. * @param cli - pointer to cli that is calling this binding * @param args - string of args (if tokenizeArgs is false) or tokens otherwise * @param context */ void (*binding)(EmbeddedCli *cli, char *args, void *context); }; struct EmbeddedCli { /** * Should write char to connection * @param cli - pointer to cli that executed this function * @param c - actual character to write */ void (*writeChar)(EmbeddedCli *cli, char c); /** * Called when command is received and command not found in list of * command bindings (or binding function is null). * @param cli - pointer to cli that executed this function * @param command - pointer to received command */ void (*onCommand)(EmbeddedCli *cli, CliCommand *command); /** * Can be used by for any application context */ void *appContext; /** * Pointer to actual implementation, do not use. */ void *_impl; }; /** * Configuration to create CLI */ struct EmbeddedCliConfig { /** * Size of buffer that is used to store characters until they're processed */ uint16_t rxBufferSize; /** * Size of buffer that is used to store current input that is not yet * sended as command (return not pressed yet) */ uint16_t cmdBufferSize; /** * Size of buffer that is used to store previously entered commands * Only unique commands are stored in buffer. If buffer is smaller than * entered command (including arguments), command is discarded from history */ uint16_t historyBufferSize; /** * Maximum amount of bindings that can be added via addBinding function. * Cli increases takes extra bindings for internal commands: * - help */ uint16_t maxBindingCount; /** * Buffer to use for cli and all internal structures. If NULL, memory will * be allocated dynamically. Otherwise this buffer is used and no * allocations are made */ CLI_UINT *cliBuffer; /** * Size of buffer for cli and internal structures (in bytes). */ uint16_t cliBufferSize; /** * Whether autocompletion should be enabled. * If false, autocompletion is disabled but you still can use 'tab' to * complete current command manually. */ bool enableAutoComplete; }; /** * Returns pointer to default configuration for cli creation. It is safe to * modify it and then send to embeddedCliNew(). * Returned structure is always the same so do not free and try to use it * immediately. * Default values: *
    *
  • rxBufferSize = 64
  • *
  • cmdBufferSize = 64
  • *
  • historyBufferSize = 128
  • *
  • cliBuffer = NULL (use dynamic allocation)
  • *
  • cliBufferSize = 0
  • *
  • maxBindingCount = 8
  • *
  • enableAutoComplete = true
  • *
* @return configuration for cli creation */ EmbeddedCliConfig *embeddedCliDefaultConfig(void); /** * Returns how many space in config buffer is required for cli creation * If you provide buffer with less space, embeddedCliNew will return NULL * This amount will always be divisible by CLI_UINT_SIZE so allocated buffer * and internal structures can be properly aligned * @param config * @return */ uint16_t embeddedCliRequiredSize(EmbeddedCliConfig *config); /** * Create new CLI. * Memory is allocated dynamically if cliBuffer in config is NULL. * After CLI is created, override function pointers to start using it * @param config - config for cli creation * @return pointer to created CLI */ EmbeddedCli *embeddedCliNew(EmbeddedCliConfig *config); /** * Same as calling embeddedCliNew with default config. * @return */ EmbeddedCli *embeddedCliNewDefault(void); /** * Receive character and put it to internal buffer * Actual processing is done inside embeddedCliProcess * You can call this function from something like interrupt service routine, * just make sure that you call it only from single place. Otherwise input * might get corrupted * @param cli * @param c - received char */ void embeddedCliReceiveChar(EmbeddedCli *cli, char c); /** * Process rx/tx buffers. Command callbacks are called from here * @param cli */ void embeddedCliProcess(EmbeddedCli *cli); /** * Add specified binding to list of bindings. If list is already full, binding * is not added and false is returned * @param cli * @param binding * @return true if binding was added, false otherwise */ bool embeddedCliAddBinding(EmbeddedCli *cli, CliCommandBinding binding); /** * Print specified string and account for currently entered but not submitted * command. * Current command is deleted, provided string is printed (with new line) after * that current command is printed again, so user can continue typing it. * @param cli * @param string */ void embeddedCliPrint(EmbeddedCli *cli, const char *string); /** * Free allocated for cli memory * @param cli */ void embeddedCliFree(EmbeddedCli *cli); /** * Perform tokenization of arguments string. Original string is modified and * should not be used directly (only inside other token functions). * Individual tokens are separated by single 0x00 char, double 0x00 is put at * the end of token list. After calling this function, you can use other * token functions to get individual tokens and token count. * * Important: Call this function only once. Otherwise information will be lost if * more than one token existed * @param args - string to tokenize (must have extra writable char after 0x00) * @return */ void embeddedCliTokenizeArgs(char *args); /** * Return specific token from tokenized string * @param tokenizedStr * @param pos (counted from 1) * @return token */ const char *embeddedCliGetToken(const char *tokenizedStr, uint16_t pos); /** * Same as embeddedCliGetToken but works on non-const buffer * @param tokenizedStr * @param pos (counted from 1) * @return token */ char *embeddedCliGetTokenVariable(char *tokenizedStr, uint16_t pos); /** * Find token in provided tokens string and return its position (counted from 1) * If no such token is found - 0 is returned. * @param tokenizedStr * @param token - token to find * @return position (increased by 1) or zero if no such token found */ uint16_t embeddedCliFindToken(const char *tokenizedStr, const char *token); /** * Return number of tokens in tokenized string * @param tokenizedStr * @return number of tokens */ uint16_t embeddedCliGetTokenCount(const char *tokenizedStr); #ifdef __cplusplus } #endif #endif //EMBEDDED_CLI_H #ifdef EMBEDDED_CLI_IMPL #ifndef EMBEDDED_CLI_IMPL_GUARD #define EMBEDDED_CLI_IMPL_GUARD #ifdef __cplusplus extern "C" { #endif #include #include #define CLI_TOKEN_NPOS 0xffff #define UNUSED(x) (void)x #define PREPARE_IMPL(t) \ EmbeddedCliImpl* impl = (EmbeddedCliImpl*)t->_impl #define IS_FLAG_SET(flags, flag) (((flags) & (flag)) != 0) #define SET_FLAG(flags, flag) ((flags) |= (flag)) #define UNSET_U8FLAG(flags, flag) ((flags) &= (uint8_t) ~(flag)) /** * Marks binding as candidate for autocompletion * This flag is updated each time getAutocompletedCommand is called */ #define BINDING_FLAG_AUTOCOMPLETE 1u /** * Indicates that rx buffer overflow happened. In such case last command * that wasn't finished (no \r or \n were received) will be discarded */ #define CLI_FLAG_OVERFLOW 0x01u /** * Indicates that initialization is completed. Initialization is completed in * first call to process and needed, for example, to print invitation message. */ #define CLI_FLAG_INIT_COMPLETE 0x02u /** * Indicates that CLI structure and internal structures were allocated with * malloc and should bre freed */ #define CLI_FLAG_ALLOCATED 0x04u /** * Indicates that CLI structure and internal structures were allocated with * malloc and should bre freed */ #define CLI_FLAG_ESCAPE_MODE 0x08u /** * Indicates that CLI in mode when it will print directly to output without * clear of current command and printing it back */ #define CLI_FLAG_DIRECT_PRINT 0x10u /** * Indicates that live autocompletion is enabled */ #define CLI_FLAG_AUTOCOMPLETE_ENABLED 0x20u typedef struct EmbeddedCliImpl EmbeddedCliImpl; typedef struct AutocompletedCommand AutocompletedCommand; typedef struct FifoBuf FifoBuf; typedef struct CliHistory CliHistory; struct FifoBuf { char *buf; /** * Position of first element in buffer. From this position elements are taken */ uint16_t front; /** * Position after last element. At this position new elements are inserted */ uint16_t back; /** * Size of buffer */ uint16_t size; }; struct CliHistory { /** * Items in buffer are separated by null-chars */ char *buf; /** * Total size of buffer */ uint16_t bufferSize; /** * Index of currently selected element. This allows to navigate history * After command is sent, current element is reset to 0 (no element) */ uint16_t current; /** * Number of items in buffer * Items are counted from top to bottom (and are 1 based). * So the most recent item is 1 and the oldest is itemCount. */ uint16_t itemsCount; }; struct EmbeddedCliImpl { /** * Invitation string. Is printed at the beginning of each line with user * input */ const char *invitation; CliHistory history; /** * Buffer for storing received chars. * Chars are stored in FIFO mode. */ FifoBuf rxBuffer; /** * Buffer for current command */ char *cmdBuffer; /** * Size of current command */ uint16_t cmdSize; /** * Total size of command buffer */ uint16_t cmdMaxSize; CliCommandBinding *bindings; /** * Flags for each binding. Sizes are the same as for bindings array */ uint8_t *bindingsFlags; uint16_t bindingsCount; uint16_t maxBindingsCount; /** * Total length of input line. This doesn't include invitation but * includes current command and its live autocompletion */ uint16_t inputLineLength; /** * Stores last character that was processed. */ char lastChar; /** * Flags are defined as CLI_FLAG_* */ uint8_t flags; }; struct AutocompletedCommand { /** * Name of autocompleted command (or first candidate for autocompletion if * there are multiple candidates). * NULL if autocomplete not possible. */ const char *firstCandidate; /** * Number of characters that can be completed safely. For example, if there * are two possible commands "get-led" and "get-adc", then for prefix "g" * autocompletedLen will be 4. If there are only one candidate, this number * is always equal to length of the command. */ uint16_t autocompletedLen; /** * Total number of candidates for autocompletion */ uint16_t candidateCount; }; static EmbeddedCliConfig defaultConfig; /** * Number of commands that cli adds. Commands: * - help */ static const uint16_t cliInternalBindingCount = 1; static const char *lineBreak = "\r\n"; /** * Navigate through command history back and forth. If navigateUp is true, * navigate to older commands, otherwise navigate to newer. * When history end is reached, nothing happens. * @param cli * @param navigateUp */ static void navigateHistory(EmbeddedCli *cli, bool navigateUp); /** * Process escaped character. After receiving ESC+[ sequence, all chars up to * ending character are sent to this function * @param cli * @param c */ static void onEscapedInput(EmbeddedCli *cli, char c); /** * Process input character. Character is valid displayable char and should be * added to current command string and displayed to client. * @param cli * @param c */ static void onCharInput(EmbeddedCli *cli, char c); /** * Process control character (like \r or \n) possibly altering state of current * command or executing onCommand callback. * @param cli * @param c */ static void onControlInput(EmbeddedCli *cli, char c); /** * Parse command in buffer and execute callback * @param cli */ static void parseCommand(EmbeddedCli *cli); /** * Setup bindings for internal commands, like help * @param cli */ static void initInternalBindings(EmbeddedCli *cli); /** * Show help for given tokens (or default help if no tokens) * @param cli * @param tokens * @param context - not used */ static void onHelp(EmbeddedCli *cli, char *tokens, void *context); /** * Show error about unknown command * @param cli * @param name */ static void onUnknownCommand(EmbeddedCli *cli, const char *name); /** * Return autocompleted command for given prefix. * Prefix is compared to all known command bindings and autocompleted result * is returned * @param cli * @param prefix * @return */ static AutocompletedCommand getAutocompletedCommand(EmbeddedCli *cli, const char *prefix); /** * Prints autocompletion result while keeping current command unchanged * Prints only if autocompletion is present and only one candidate exists. * @param cli */ static void printLiveAutocompletion(EmbeddedCli *cli); /** * Handles autocomplete request. If autocomplete possible - fills current * command with autocompleted command. When multiple commands satisfy entered * prefix, they are printed to output. * @param cli */ static void onAutocompleteRequest(EmbeddedCli *cli); /** * Removes all input from current line (replaces it with whitespaces) * And places cursor at the beginning of the line * @param cli */ static void clearCurrentLine(EmbeddedCli *cli); /** * Write given string to cli output * @param cli * @param str */ static void writeToOutput(EmbeddedCli *cli, const char *str); /** * Returns true if provided char is a supported control char: * \r, \n, \b or 0x7F (treated as \b) * @param c * @return */ static bool isControlChar(char c); /** * Returns true if provided char is a valid displayable character: * a-z, A-Z, 0-9, whitespace, punctuation, etc. * Currently only ASCII is supported * @param c * @return */ static bool isDisplayableChar(char c); /** * How many elements are currently available in buffer * @param buffer * @return number of elements */ static uint16_t fifoBufAvailable(FifoBuf *buffer); /** * Return first character from buffer and remove it from buffer * Buffer must be non-empty, otherwise 0 is returned * @param buffer * @return */ static char fifoBufPop(FifoBuf *buffer); /** * Push character into fifo buffer. If there is no space left, character is * discarded and false is returned * @param buffer * @param a - character to add * @return true if char was added to buffer, false otherwise */ static bool fifoBufPush(FifoBuf *buffer, char a); /** * Copy provided string to the history buffer. * If it is already inside history, it will be removed from it and added again. * So after addition, it will always be on top * If available size is not enough (and total size is enough) old elements will * be removed from history so this item can be put to it * @param history * @param str * @return true if string was put in history */ static bool historyPut(CliHistory *history, const char *str); /** * Get item from history. Items are counted from 1 so if item is 0 or greater * than itemCount, NULL is returned * @param history * @param item * @return true if string was put in history */ static const char *historyGet(CliHistory *history, uint16_t item); /** * Remove specific item from history * @param history * @param str - string to remove * @return */ static void historyRemove(CliHistory *history, const char *str); /** * Return position (index of first char) of specified token * @param tokenizedStr - tokenized string (separated by \0 with * \0\0 at the end) * @param pos - token position (counted from 1) * @return index of first char of specified token */ static uint16_t getTokenPosition(const char *tokenizedStr, uint16_t pos); EmbeddedCliConfig *embeddedCliDefaultConfig(void) { defaultConfig.rxBufferSize = 64; defaultConfig.cmdBufferSize = 64; defaultConfig.historyBufferSize = 128; defaultConfig.cliBuffer = NULL; defaultConfig.cliBufferSize = 0; defaultConfig.maxBindingCount = 8; defaultConfig.enableAutoComplete = true; return &defaultConfig; } uint16_t embeddedCliRequiredSize(EmbeddedCliConfig *config) { uint16_t bindingCount = (uint16_t) (config->maxBindingCount + cliInternalBindingCount); return (uint16_t) (CLI_UINT_SIZE * ( BYTES_TO_CLI_UINTS(sizeof(EmbeddedCli)) + BYTES_TO_CLI_UINTS(sizeof(EmbeddedCliImpl)) + BYTES_TO_CLI_UINTS(config->rxBufferSize * sizeof(char)) + BYTES_TO_CLI_UINTS(config->cmdBufferSize * sizeof(char)) + BYTES_TO_CLI_UINTS(config->historyBufferSize * sizeof(char)) + BYTES_TO_CLI_UINTS(bindingCount * sizeof(CliCommandBinding)) + BYTES_TO_CLI_UINTS(bindingCount * sizeof(uint8_t)))); } EmbeddedCli *embeddedCliNew(EmbeddedCliConfig *config) { EmbeddedCli *cli = NULL; uint16_t bindingCount = (uint16_t) (config->maxBindingCount + cliInternalBindingCount); size_t totalSize = embeddedCliRequiredSize(config); bool allocated = false; if (config->cliBuffer == NULL) { // config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment. if (config->cliBuffer == NULL) return NULL; allocated = true; } else if (config->cliBufferSize < totalSize) { return NULL; } CLI_UINT *buf = config->cliBuffer; memset(buf, 0, totalSize); cli = (EmbeddedCli *) buf; buf += BYTES_TO_CLI_UINTS(sizeof(EmbeddedCli)); cli->_impl = (EmbeddedCliImpl *) buf; buf += BYTES_TO_CLI_UINTS(sizeof(EmbeddedCliImpl)); PREPARE_IMPL(cli); impl->rxBuffer.buf = (char *) buf; buf += BYTES_TO_CLI_UINTS(config->rxBufferSize * sizeof(char)); impl->cmdBuffer = (char *) buf; buf += BYTES_TO_CLI_UINTS(config->cmdBufferSize * sizeof(char)); impl->bindings = (CliCommandBinding *) buf; buf += BYTES_TO_CLI_UINTS(bindingCount * sizeof(CliCommandBinding)); impl->bindingsFlags = (uint8_t *) buf; buf += BYTES_TO_CLI_UINTS(bindingCount); impl->history.buf = (char *) buf; impl->history.bufferSize = config->historyBufferSize; if (allocated) SET_FLAG(impl->flags, CLI_FLAG_ALLOCATED); if (config->enableAutoComplete) SET_FLAG(impl->flags, CLI_FLAG_AUTOCOMPLETE_ENABLED); impl->rxBuffer.size = config->rxBufferSize; impl->rxBuffer.front = 0; impl->rxBuffer.back = 0; impl->cmdMaxSize = config->cmdBufferSize; impl->bindingsCount = 0; impl->maxBindingsCount = (uint16_t) (config->maxBindingCount + cliInternalBindingCount); impl->lastChar = '\0'; impl->invitation = "> "; initInternalBindings(cli); return cli; } EmbeddedCli *embeddedCliNewDefault(void) { return embeddedCliNew(embeddedCliDefaultConfig()); } void embeddedCliReceiveChar(EmbeddedCli *cli, char c) { PREPARE_IMPL(cli); if (!fifoBufPush(&impl->rxBuffer, c)) { SET_FLAG(impl->flags, CLI_FLAG_OVERFLOW); } } void embeddedCliProcess(EmbeddedCli *cli) { if (cli->writeChar == NULL) return; PREPARE_IMPL(cli); if (!IS_FLAG_SET(impl->flags, CLI_FLAG_INIT_COMPLETE)) { SET_FLAG(impl->flags, CLI_FLAG_INIT_COMPLETE); writeToOutput(cli, impl->invitation); } while (fifoBufAvailable(&impl->rxBuffer)) { char c = fifoBufPop(&impl->rxBuffer); if (IS_FLAG_SET(impl->flags, CLI_FLAG_ESCAPE_MODE)) { onEscapedInput(cli, c); } else if (impl->lastChar == 0x1B && c == '[') { //enter escape mode SET_FLAG(impl->flags, CLI_FLAG_ESCAPE_MODE); } else if (isControlChar(c)) { onControlInput(cli, c); } else if (isDisplayableChar(c)) { onCharInput(cli, c); } printLiveAutocompletion(cli); impl->lastChar = c; } // discard unfinished command if overflow happened if (IS_FLAG_SET(impl->flags, CLI_FLAG_OVERFLOW)) { impl->cmdSize = 0; impl->cmdBuffer[impl->cmdSize] = '\0'; UNSET_U8FLAG(impl->flags, CLI_FLAG_OVERFLOW); } } bool embeddedCliAddBinding(EmbeddedCli *cli, CliCommandBinding binding) { PREPARE_IMPL(cli); if (impl->bindingsCount == impl->maxBindingsCount) return false; impl->bindings[impl->bindingsCount] = binding; ++impl->bindingsCount; return true; } void embeddedCliPrint(EmbeddedCli *cli, const char *string) { if (cli->writeChar == NULL) return; PREPARE_IMPL(cli); // remove chars for autocompletion and live command if (!IS_FLAG_SET(impl->flags, CLI_FLAG_DIRECT_PRINT)) clearCurrentLine(cli); // print provided string writeToOutput(cli, string); writeToOutput(cli, lineBreak); // print current command back to screen if (!IS_FLAG_SET(impl->flags, CLI_FLAG_DIRECT_PRINT)) { writeToOutput(cli, impl->invitation); writeToOutput(cli, impl->cmdBuffer); impl->inputLineLength = impl->cmdSize; printLiveAutocompletion(cli); } } void embeddedCliFree(EmbeddedCli *cli) { PREPARE_IMPL(cli); if (IS_FLAG_SET(impl->flags, CLI_FLAG_ALLOCATED)) { // allocation is done in single call to malloc, so need only single free // free(cli); } } void embeddedCliTokenizeArgs(char *args) { if (args == NULL) return; // for now only space, but can add more later const char *separators = " "; // indicates that arg is quoted so separators are copied as is bool quotesEnabled = false; // indicates that previous char was a slash, so next char is copied as is bool escapeActivated = false; int insertPos = 0; int i = 0; char currentChar; while ((currentChar = args[i]) != '\0') { ++i; if (escapeActivated) { escapeActivated = false; } else if (currentChar == '\\') { escapeActivated = true; continue; } else if (currentChar == '"') { quotesEnabled = !quotesEnabled; currentChar = '\0'; } else if (!quotesEnabled && strchr(separators, currentChar) != NULL) { currentChar = '\0'; } // null chars are only copied once and not copied to the beginning if (currentChar != '\0' || (insertPos > 0 && args[insertPos - 1] != '\0')) { args[insertPos] = currentChar; ++insertPos; } } // make args double null-terminated source buffer must be big enough to contain extra spaces args[insertPos] = '\0'; args[insertPos + 1] = '\0'; } const char *embeddedCliGetToken(const char *tokenizedStr, uint16_t pos) { uint16_t i = getTokenPosition(tokenizedStr, pos); if (i != CLI_TOKEN_NPOS) return &tokenizedStr[i]; else return NULL; } char *embeddedCliGetTokenVariable(char *tokenizedStr, uint16_t pos) { uint16_t i = getTokenPosition(tokenizedStr, pos); if (i != CLI_TOKEN_NPOS) return &tokenizedStr[i]; else return NULL; } uint16_t embeddedCliFindToken(const char *tokenizedStr, const char *token) { if (tokenizedStr == NULL || token == NULL) return 0; uint16_t size = embeddedCliGetTokenCount(tokenizedStr); for (uint16_t i = 1; i <= size; ++i) { if (strcmp(embeddedCliGetToken(tokenizedStr, i), token) == 0) return i; } return 0; } uint16_t embeddedCliGetTokenCount(const char *tokenizedStr) { if (tokenizedStr == NULL || tokenizedStr[0] == '\0') return 0; int i = 0; uint16_t tokenCount = 1; while (true) { if (tokenizedStr[i] == '\0') { if (tokenizedStr[i + 1] == '\0') break; ++tokenCount; } ++i; } return tokenCount; } static void navigateHistory(EmbeddedCli *cli, bool navigateUp) { PREPARE_IMPL(cli); if (impl->history.itemsCount == 0 || (navigateUp && impl->history.current == impl->history.itemsCount) || (!navigateUp && impl->history.current == 0)) return; clearCurrentLine(cli); writeToOutput(cli, impl->invitation); if (navigateUp) ++impl->history.current; else --impl->history.current; const char *item = historyGet(&impl->history, impl->history.current); // simple way to handle empty command the same way as others if (item == NULL) item = ""; uint16_t len = (uint16_t) strlen(item); memcpy(impl->cmdBuffer, item, len); impl->cmdBuffer[len] = '\0'; impl->cmdSize = len; writeToOutput(cli, impl->cmdBuffer); impl->inputLineLength = impl->cmdSize; printLiveAutocompletion(cli); } static void onEscapedInput(EmbeddedCli *cli, char c) { PREPARE_IMPL(cli); if (c >= 64 && c <= 126) { // handle escape sequence UNSET_U8FLAG(impl->flags, CLI_FLAG_ESCAPE_MODE); if (c == 'A' || c == 'B') { // treat \e[..A as cursor up and \e[..B as cursor down // there might be extra chars between [ and A/B, just ignore them navigateHistory(cli, c == 'A'); } } } static void onCharInput(EmbeddedCli *cli, char c) { PREPARE_IMPL(cli); // have to reserve two extra chars for command ending (used in tokenization) if (impl->cmdSize + 2 >= impl->cmdMaxSize) return; impl->cmdBuffer[impl->cmdSize] = c; ++impl->cmdSize; impl->cmdBuffer[impl->cmdSize] = '\0'; cli->writeChar(cli, c); } static void onControlInput(EmbeddedCli *cli, char c) { PREPARE_IMPL(cli); // process \r\n and \n\r as single \r\n command if ((impl->lastChar == '\r' && c == '\n') || (impl->lastChar == '\n' && c == '\r')) return; if (c == '\r' || c == '\n') { // try to autocomplete command and then process it onAutocompleteRequest(cli); writeToOutput(cli, lineBreak); if (impl->cmdSize > 0) parseCommand(cli); impl->cmdSize = 0; impl->cmdBuffer[impl->cmdSize] = '\0'; impl->inputLineLength = 0; impl->history.current = 0; writeToOutput(cli, impl->invitation); } else if ((c == '\b' || c == 0x7F) && impl->cmdSize > 0) { // remove char from screen cli->writeChar(cli, '\b'); cli->writeChar(cli, ' '); cli->writeChar(cli, '\b'); // and from buffer --impl->cmdSize; impl->cmdBuffer[impl->cmdSize] = '\0'; } else if (c == '\t') { onAutocompleteRequest(cli); } } static void parseCommand(EmbeddedCli *cli) { PREPARE_IMPL(cli); bool isEmpty = true; for (int i = 0; i < impl->cmdSize; ++i) { if (impl->cmdBuffer[i] != ' ') { isEmpty = false; break; } } // do not process empty commands if (isEmpty) return; // push command to history before buffer is modified historyPut(&impl->history, impl->cmdBuffer); char *cmdName = NULL; char *cmdArgs = NULL; bool nameFinished = false; // find command name and command args inside command buffer for (int i = 0; i < impl->cmdSize; ++i) { char c = impl->cmdBuffer[i]; if (c == ' ') { // all spaces between name and args are filled with zeros // so name is a correct null-terminated string if (cmdArgs == NULL) impl->cmdBuffer[i] = '\0'; if (cmdName != NULL) nameFinished = true; } else if (cmdName == NULL) { cmdName = &impl->cmdBuffer[i]; } else if (cmdArgs == NULL && nameFinished) { cmdArgs = &impl->cmdBuffer[i]; } } // we keep two last bytes in cmd buffer reserved so cmdSize is always by 2 // less than cmdMaxSize impl->cmdBuffer[impl->cmdSize + 1] = '\0'; if (cmdName == NULL) return; // try to find command in bindings for (int i = 0; i < impl->bindingsCount; ++i) { if (strcmp(cmdName, impl->bindings[i].name) == 0) { if (impl->bindings[i].binding == NULL) break; if (impl->bindings[i].tokenizeArgs) embeddedCliTokenizeArgs(cmdArgs); // currently, output is blank line, so we can just print directly SET_FLAG(impl->flags, CLI_FLAG_DIRECT_PRINT); impl->bindings[i].binding(cli, cmdArgs, impl->bindings[i].context); UNSET_U8FLAG(impl->flags, CLI_FLAG_DIRECT_PRINT); return; } } // command not found in bindings or binding was null // try to call default callback if (cli->onCommand != NULL) { CliCommand command; command.name = cmdName; command.args = cmdArgs; // currently, output is blank line, so we can just print directly SET_FLAG(impl->flags, CLI_FLAG_DIRECT_PRINT); cli->onCommand(cli, &command); UNSET_U8FLAG(impl->flags, CLI_FLAG_DIRECT_PRINT); } else { onUnknownCommand(cli, cmdName); } } static void initInternalBindings(EmbeddedCli *cli) { CliCommandBinding b = { "help", "Print list of commands", true, NULL, onHelp }; embeddedCliAddBinding(cli, b); } static void onHelp(EmbeddedCli *cli, char *tokens, void *context) { UNUSED(context); PREPARE_IMPL(cli); if (impl->bindingsCount == 0) { writeToOutput(cli, "Help is not available"); writeToOutput(cli, lineBreak); return; } uint16_t tokenCount = embeddedCliGetTokenCount(tokens); if (tokenCount == 0) { for (int i = 0; i < impl->bindingsCount; ++i) { writeToOutput(cli, " * "); writeToOutput(cli, impl->bindings[i].name); writeToOutput(cli, lineBreak); if (impl->bindings[i].help != NULL) { cli->writeChar(cli, '\t'); writeToOutput(cli, impl->bindings[i].help); writeToOutput(cli, lineBreak); } } } else if (tokenCount == 1) { // try find command const char *helpStr = NULL; const char *cmdName = embeddedCliGetToken(tokens, 1); bool found = false; for (int i = 0; i < impl->bindingsCount; ++i) { if (strcmp(impl->bindings[i].name, cmdName) == 0) { helpStr = impl->bindings[i].help; found = true; break; } } if (found && helpStr != NULL) { writeToOutput(cli, " * "); writeToOutput(cli, cmdName); writeToOutput(cli, lineBreak); cli->writeChar(cli, '\t'); writeToOutput(cli, helpStr); writeToOutput(cli, lineBreak); } else if (found) { writeToOutput(cli, "Help is not available"); writeToOutput(cli, lineBreak); } else { onUnknownCommand(cli, cmdName); } } else { writeToOutput(cli, "Command \"help\" receives one or zero arguments"); writeToOutput(cli, lineBreak); } } static void onUnknownCommand(EmbeddedCli *cli, const char *name) { writeToOutput(cli, "Unknown command: \""); writeToOutput(cli, name); writeToOutput(cli, "\". Write \"help\" for a list of available commands"); writeToOutput(cli, lineBreak); } static AutocompletedCommand getAutocompletedCommand(EmbeddedCli *cli, const char *prefix) { AutocompletedCommand cmd = {NULL, 0, 0}; size_t prefixLen = strlen(prefix); PREPARE_IMPL(cli); if (impl->bindingsCount == 0 || prefixLen == 0) return cmd; for (int i = 0; i < impl->bindingsCount; ++i) { const char *name = impl->bindings[i].name; size_t len = strlen(name); // unset autocomplete flag UNSET_U8FLAG(impl->bindingsFlags[i], BINDING_FLAG_AUTOCOMPLETE); if (len < prefixLen) continue; // check if this command is candidate for autocomplete bool isCandidate = true; for (size_t j = 0; j < prefixLen; ++j) { if (prefix[j] != name[j]) { isCandidate = false; break; } } if (!isCandidate) continue; impl->bindingsFlags[i] |= BINDING_FLAG_AUTOCOMPLETE; if (cmd.candidateCount == 0 || len < cmd.autocompletedLen) cmd.autocompletedLen = (uint16_t) len; ++cmd.candidateCount; if (cmd.candidateCount == 1) { cmd.firstCandidate = name; continue; } for (size_t j = impl->cmdSize; j < cmd.autocompletedLen; ++j) { if (cmd.firstCandidate[j] != name[j]) { cmd.autocompletedLen = (uint16_t) j; break; } } } return cmd; } static void printLiveAutocompletion(EmbeddedCli *cli) { PREPARE_IMPL(cli); if (!IS_FLAG_SET(impl->flags, CLI_FLAG_AUTOCOMPLETE_ENABLED)) return; AutocompletedCommand cmd = getAutocompletedCommand(cli, impl->cmdBuffer); if (cmd.candidateCount == 0) { cmd.autocompletedLen = impl->cmdSize; } // print live autocompletion (or nothing, if it doesn't exist) for (size_t i = impl->cmdSize; i < cmd.autocompletedLen; ++i) { cli->writeChar(cli, cmd.firstCandidate[i]); } // replace with spaces previous autocompletion for (size_t i = cmd.autocompletedLen; i < impl->inputLineLength; ++i) { cli->writeChar(cli, ' '); } impl->inputLineLength = cmd.autocompletedLen; cli->writeChar(cli, '\r'); // print current command again so cursor is moved to initial place writeToOutput(cli, impl->invitation); writeToOutput(cli, impl->cmdBuffer); } static void onAutocompleteRequest(EmbeddedCli *cli) { PREPARE_IMPL(cli); AutocompletedCommand cmd = getAutocompletedCommand(cli, impl->cmdBuffer); if (cmd.candidateCount == 0) return; if (cmd.candidateCount == 1 || cmd.autocompletedLen > impl->cmdSize) { // can copy from index cmdSize, but prefix is the same, so copy everything memcpy(impl->cmdBuffer, cmd.firstCandidate, cmd.autocompletedLen); if (cmd.candidateCount == 1) { impl->cmdBuffer[cmd.autocompletedLen] = ' '; ++cmd.autocompletedLen; } impl->cmdBuffer[cmd.autocompletedLen] = '\0'; writeToOutput(cli, &impl->cmdBuffer[impl->cmdSize]); impl->cmdSize = cmd.autocompletedLen; impl->inputLineLength = impl->cmdSize; return; } // with multiple candidates when we already completed to common prefix // we show all candidates and print input again // we need to completely clear current line since it begins with invitation clearCurrentLine(cli); for (int i = 0; i < impl->bindingsCount; ++i) { // autocomplete flag is set for all candidates by last call to // getAutocompletedCommand if (!(impl->bindingsFlags[i] & BINDING_FLAG_AUTOCOMPLETE)) continue; const char *name = impl->bindings[i].name; writeToOutput(cli, name); writeToOutput(cli, lineBreak); } writeToOutput(cli, impl->invitation); writeToOutput(cli, impl->cmdBuffer); impl->inputLineLength = impl->cmdSize; } static void clearCurrentLine(EmbeddedCli *cli) { PREPARE_IMPL(cli); size_t len = impl->inputLineLength + strlen(impl->invitation); cli->writeChar(cli, '\r'); for (size_t i = 0; i < len; ++i) { cli->writeChar(cli, ' '); } cli->writeChar(cli, '\r'); impl->inputLineLength = 0; } static void writeToOutput(EmbeddedCli *cli, const char *str) { size_t len = strlen(str); for (size_t i = 0; i < len; ++i) { cli->writeChar(cli, str[i]); } } static bool isControlChar(char c) { return c == '\r' || c == '\n' || c == '\b' || c == '\t' || c == 0x7F; } static bool isDisplayableChar(char c) { return (c >= 32 && c <= 126); } static uint16_t fifoBufAvailable(FifoBuf *buffer) { if (buffer->back >= buffer->front) return (uint16_t) (buffer->back - buffer->front); else return (uint16_t) (buffer->size - buffer->front + buffer->back); } static char fifoBufPop(FifoBuf *buffer) { char a = '\0'; if (buffer->front != buffer->back) { a = buffer->buf[buffer->front]; buffer->front = (uint16_t) (buffer->front + 1) % buffer->size; } return a; } static bool fifoBufPush(FifoBuf *buffer, char a) { uint16_t newBack = (uint16_t) (buffer->back + 1) % buffer->size; if (newBack != buffer->front) { buffer->buf[buffer->back] = a; buffer->back = newBack; return true; } return false; } static bool historyPut(CliHistory *history, const char *str) { size_t len = strlen(str); // each item is ended with \0 so, need to have that much space at least if (history->bufferSize < len + 1) return false; // remove str from history (if it's present) so we don't get duplicates historyRemove(history, str); size_t usedSize; // remove old items if new one can't fit into buffer while (history->itemsCount > 0) { const char *item = historyGet(history, history->itemsCount); size_t itemLen = strlen(item); usedSize = ((size_t) (item - history->buf)) + itemLen + 1; size_t freeSpace = history->bufferSize - usedSize; if (freeSpace >= len + 1) break; // space not enough, remove last element --history->itemsCount; } if (history->itemsCount > 0) { // when history not empty, shift elements so new item is first memmove(&history->buf[len + 1], history->buf, usedSize); } memcpy(history->buf, str, len + 1); ++history->itemsCount; return true; } static const char *historyGet(CliHistory *history, uint16_t item) { if (item == 0 || item > history->itemsCount) return NULL; // items are stored in the same way (separated by \0 and counted from 1), // so can use this call return embeddedCliGetToken(history->buf, item); } static void historyRemove(CliHistory *history, const char *str) { if (str == NULL || history->itemsCount == 0) return; char *item = NULL; uint16_t itemPosition; for (itemPosition = 1; itemPosition <= history->itemsCount; ++itemPosition) { // items are stored in the same way (separated by \0 and counted from 1), // so can use this call item = embeddedCliGetTokenVariable(history->buf, itemPosition); if (strcmp(item, str) == 0) { break; } item = NULL; } if (item == NULL) return; --history->itemsCount; if (itemPosition == (history->itemsCount + 1)) { // if this is a last element, nothing is remaining to move return; } size_t len = strlen(item); size_t remaining = (size_t) (history->bufferSize - (item + len + 1 - history->buf)); // move everything to the right of found item memmove(item, &item[len + 1], remaining); } static uint16_t getTokenPosition(const char *tokenizedStr, uint16_t pos) { if (tokenizedStr == NULL || pos == 0) return CLI_TOKEN_NPOS; uint16_t i = 0; uint16_t tokenCount = 1; while (true) { if (tokenCount == pos) break; if (tokenizedStr[i] == '\0') { ++tokenCount; if (tokenizedStr[i + 1] == '\0') break; } ++i; } if (tokenizedStr[i] != '\0') return i; else return CLI_TOKEN_NPOS; } #ifdef __cplusplus } #endif #endif // EMBEDDED_CLI_IMPL_GUARD #endif // EMBEDDED_CLI_IMPL ================================================ FILE: lib/fatfs/LICENSE.txt ================================================ FatFs License FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files. /*----------------------------------------------------------------------------/ / FatFs - Generic FAT Filesystem Module Rx.xx / /-----------------------------------------------------------------------------/ / / Copyright (C) 20xx, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided / that the following condition is met: / / 1. Redistributions of source code must retain the above copyright notice, / this condition and the following disclaimer. / / This software is provided by the copyright holder and contributors "AS IS" / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. /----------------------------------------------------------------------------*/ Therefore FatFs license is one of the BSD-style licenses, but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, do not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses include GNU GPL. When you redistribute the FatFs source code with changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. ================================================ FILE: lib/fatfs/source/00history.txt ================================================ ---------------------------------------------------------------------------- Revision history of FatFs module ---------------------------------------------------------------------------- R0.00 (February 26, 2006) Prototype. R0.01 (April 29, 2006) The first release. R0.02 (June 01, 2006) Added FAT12 support. Removed unbuffered mode. Fixed a problem on small (<32M) partition. R0.02a (June 10, 2006) Added a configuration option (_FS_MINIMUM). R0.03 (September 22, 2006) Added f_rename(). Changed option _FS_MINIMUM to _FS_MINIMIZE. R0.03a (December 11, 2006) Improved cluster scan algorithm to write files fast. Fixed f_mkdir() creates incorrect directory on FAT32. R0.04 (February 04, 2007) Added f_mkfs(). Supported multiple drive system. Changed some interfaces for multiple drive system. Changed f_mountdrv() to f_mount(). R0.04a (April 01, 2007) Supported multiple partitions on a physical drive. Added a capability of extending file size to f_lseek(). Added minimization level 3. Fixed an endian sensitive code in f_mkfs(). R0.04b (May 05, 2007) Added a configuration option _USE_NTFLAG. Added FSINFO support. Fixed DBCS name can result FR_INVALID_NAME. Fixed short seek (<= csize) collapses the file object. R0.05 (August 25, 2007) Changed arguments of f_read(), f_write() and f_mkfs(). Fixed f_mkfs() on FAT32 creates incorrect FSINFO. Fixed f_mkdir() on FAT32 creates incorrect directory. R0.05a (February 03, 2008) Added f_truncate() and f_utime(). Fixed off by one error at FAT sub-type determination. Fixed btr in f_read() can be mistruncated. Fixed cached sector is not flushed when create and close without write. R0.06 (April 01, 2008) Added fputc(), fputs(), fprintf() and fgets(). Improved performance of f_lseek() on moving to the same or following cluster. R0.07 (April 01, 2009) Merged Tiny-FatFs as a configuration option. (_FS_TINY) Added long file name feature. (_USE_LFN) Added multiple code page feature. (_CODE_PAGE) Added re-entrancy for multitask operation. (_FS_REENTRANT) Added auto cluster size selection to f_mkfs(). Added rewind option to f_readdir(). Changed result code of critical errors. Renamed string functions to avoid name collision. R0.07a (April 14, 2009) Septemberarated out OS dependent code on reentrant cfg. Added multiple sector size feature. R0.07c (June 21, 2009) Fixed f_unlink() can return FR_OK on error. Fixed wrong cache control in f_lseek(). Added relative path feature. Added f_chdir() and f_chdrive(). Added proper case conversion to extended character. R0.07e (November 03, 2009) Septemberarated out configuration options from ff.h to ffconf.h. Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. Fixed name matching error on the 13 character boundary. Added a configuration option, _LFN_UNICODE. Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. R0.08 (May 15, 2010) Added a memory configuration option. (_USE_LFN = 3) Added file lock feature. (_FS_SHARE) Added fast seek feature. (_USE_FASTSEEK) Changed some types on the API, XCHAR->TCHAR. Changed .fname in the FILINFO structure on Unicode cfg. String functions support UTF-8 encoding files on Unicode cfg. R0.08a (August 16, 2010) Added f_getcwd(). (_FS_RPATH = 2) Added sector erase feature. (_USE_ERASE) Moved file lock semaphore table from fs object to the bss. Fixed f_mkfs() creates wrong FAT32 volume. R0.08b (January 15, 2011) Fast seek feature is also applied to f_read() and f_write(). f_lseek() reports required table size on creating CLMP. Extended format syntax of f_printf(). Ignores duplicated directory separators in given path name. R0.09 (September 06, 2011) f_mkfs() supports multiple partition to complete the multiple partition feature. Added f_fdisk(). R0.09a (August 27, 2012) Changed f_open() and f_opendir() reject null object pointer to avoid crash. Changed option name _FS_SHARE to _FS_LOCK. Fixed assertion failure due to OS/2 EA on FAT12/16 volume. R0.09b (January 24, 2013) Added f_setlabel() and f_getlabel(). R0.10 (October 02, 2013) Added selection of character encoding on the file. (_STRF_ENCODE) Added f_closedir(). Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) Added forced mount feature with changes of f_mount(). Improved behavior of volume auto detection. Improved write throughput of f_puts() and f_printf(). Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). Fixed f_write() can be truncated when the file size is close to 4GB. Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error. R0.10a (January 15, 2014) Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) Added a configuration option of minimum sector size. (_MIN_SS) 2nd argument of f_rename() can have a drive number and it will be ignored. Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10) Fixed f_close() invalidates the file object without volume lock. Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10) Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07) R0.10b (May 19, 2014) Fixed a hard error in the disk I/O layer can collapse the directory entry. Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07) R0.10c (November 09, 2014) Added a configuration option for the platforms without RTC. (_FS_NORTC) Changed option name _USE_ERASE to _USE_TRIM. Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b) Fixed a potential problem of FAT access that can appear on disk error. Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08) R0.11 (February 09, 2015) Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND) Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c) Fixed _FS_NORTC option does not work properly. (appeared at R0.10c) R0.11a (September 05, 2015) Fixed wrong media change can lead a deadlock at thread-safe configuration. Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE) Removed some code pages actually not exist on the standard systems. (_CODE_PAGE) Fixed errors in the case conversion teble of code page 437 and 850 (ff.c). Fixed errors in the case conversion teble of Unicode (cc*.c). R0.12 (April 12, 2016) Added support for exFAT file system. (_FS_EXFAT) Added f_expand(). (_USE_EXPAND) Changed some members in FINFO structure and behavior of f_readdir(). Added an option _USE_CHMOD. Removed an option _WORD_ACCESS. Fixed errors in the case conversion table of Unicode (cc*.c). R0.12a (July 10, 2016) Added support for creating exFAT volume with some changes of f_mkfs(). Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed. f_forward() is available regardless of _FS_TINY. Fixed f_mkfs() creates wrong volume. (appeared at R0.12) Fixed wrong memory read in create_name(). (appeared at R0.12) Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD. R0.12b (September 04, 2016) Made f_rename() be able to rename objects with the same name but case. Fixed an error in the case conversion teble of code page 866. (ff.c) Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12) Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12) Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12) Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12) Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12) Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12) R0.12c (March 04, 2017) Improved write throughput at the fragmented file on the exFAT volume. Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN. Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12) Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c) R0.13 (May 21, 2017) Changed heading character of configuration keywords "_" to "FF_". Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead. Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0) Improved cluster allocation time on stretch a deep buried cluster chain. Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3. Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous. Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12) Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c) Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c) R0.13a (October 14, 2017) Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2) Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF). Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk(). Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09) Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c) Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12) R0.13b (April 07, 2018) Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3) Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2) Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c) Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b) R0.13c (October 14, 2018) Supported stdint.h for C99 and later. (integer.h was included in ff.h) Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12) Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12) Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b) R0.14 (October 14, 2019) Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1) Changed some API functions, f_mkfs() and f_fdisk(). Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters. Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters. Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12) Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12) R0.14a (December 5, 2020) Limited number of recursive calls in f_findnext(). Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted. Fixed some compiler warnings. R0.14b (April 17, 2021) Made FatFs uses standard library for copy, compare and search instead of built-in string functions. Added support for long long integer and floating point to f_printf(). (FF_STRF_LLI and FF_STRF_FP) Made path name parser ignore the terminating separator to allow "dir/". Improved the compatibility in Unix style path name feature. Fixed the file gets dead-locked when f_open() failed with some conditions. (appeared at R0.12a) Fixed f_mkfs() can create wrong exFAT volume due to a timing dependent error. (appeared at R0.12) Fixed code page 855 cannot be set by f_setcp(). Fixed some compiler warnings. R0.15 (November 6, 2022) Changed user provided synchronization functions in order to completely eliminate the platform dependency from FatFs code. FF_SYNC_t is removed from the configuration options. Fixed a potential error in f_mount when FF_FS_REENTRANT. Fixed file lock control FF_FS_LOCK is not mutal excluded when FF_FS_REENTRANT && FF_VOLUMES > 1 is true. Fixed f_mkfs() creates broken exFAT volume when the size of volume is >= 2^32 sectors. Fixed string functions cannot write the unicode characters not in BMP when FF_LFN_UNICODE == 2 (UTF-8). Fixed a compatibility issue in identification of GPT header. ================================================ FILE: lib/fatfs/source/00readme.txt ================================================ FatFs Module Source Files R0.15 FILES 00readme.txt This file. 00history.txt Revision history. ff.c FatFs module. ffconf.h Configuration file of FatFs module. ff.h Common include file for FatFs and application module. diskio.h Common include file for FatFs and disk I/O module. diskio.c An example of glue function to attach existing disk I/O module to FatFs. ffunicode.c Optional Unicode utility functions. ffsystem.c An example of optional O/S related functions. Low level disk I/O module is not included in this archive because the FatFs module is only a generic file system layer and it does not depend on any specific storage device. You need to provide a low level disk I/O module written to control the storage device that attached to the target system. ================================================ FILE: lib/fatfs/source/diskio.c ================================================ /*-----------------------------------------------------------------------*/ /* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */ /*-----------------------------------------------------------------------*/ /* If a working storage control module is available, it should be */ /* attached to the FatFs via a glue function rather than modifying it. */ /* This is an example of glue functions to attach various exsisting */ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ #include "ff.h" /* Obtains integer types */ #include "diskio.h" /* Declarations of disk functions */ /* Definitions of physical drive number for each drive */ #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ #define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat; int result; switch (pdrv) { case DEV_RAM : result = RAM_disk_status(); // translate the reslut code here return stat; case DEV_MMC : result = MMC_disk_status(); // translate the reslut code here return stat; case DEV_USB : result = USB_disk_status(); // translate the reslut code here return stat; } return STA_NOINIT; } /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat; int result; switch (pdrv) { case DEV_RAM : result = RAM_disk_initialize(); // translate the reslut code here return stat; case DEV_MMC : result = MMC_disk_initialize(); // translate the reslut code here return stat; case DEV_USB : result = USB_disk_initialize(); // translate the reslut code here return stat; } return STA_NOINIT; } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to read */ ) { DRESULT res; int result; switch (pdrv) { case DEV_RAM : // translate the arguments here result = RAM_disk_read(buff, sector, count); // translate the reslut code here return res; case DEV_MMC : // translate the arguments here result = MMC_disk_read(buff, sector, count); // translate the reslut code here return res; case DEV_USB : // translate the arguments here result = USB_disk_read(buff, sector, count); // translate the reslut code here return res; } return RES_PARERR; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ #if FF_FS_READONLY == 0 DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to write */ ) { DRESULT res; int result; switch (pdrv) { case DEV_RAM : // translate the arguments here result = RAM_disk_write(buff, sector, count); // translate the reslut code here return res; case DEV_MMC : // translate the arguments here result = MMC_disk_write(buff, sector, count); // translate the reslut code here return res; case DEV_USB : // translate the arguments here result = USB_disk_write(buff, sector, count); // translate the reslut code here return res; } return RES_PARERR; } #endif /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { DRESULT res; int result; switch (pdrv) { case DEV_RAM : // Process of the command for the RAM drive return res; case DEV_MMC : // Process of the command for the MMC/SD card return res; case DEV_USB : // Process of the command the USB drive return res; } return RES_PARERR; } ================================================ FILE: lib/fatfs/source/diskio.h ================================================ /*-----------------------------------------------------------------------/ / Low level disk interface modlue include file (C)ChaN, 2019 / /-----------------------------------------------------------------------*/ #ifndef _DISKIO_DEFINED #define _DISKIO_DEFINED #ifdef __cplusplus extern "C" { #endif /* Status of Disk Functions */ typedef BYTE DSTATUS; /* Results of Disk Functions */ typedef enum { RES_OK = 0, /* 0: Successful */ RES_ERROR, /* 1: R/W Error */ RES_WRPRT, /* 2: Write Protected */ RES_NOTRDY, /* 3: Not Ready */ RES_PARERR /* 4: Invalid Parameter */ } DRESULT; /*---------------------------------------*/ /* Prototypes for disk control functions */ DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); /* Disk Status Bits (DSTATUS) */ #define STA_NOINIT 0x01 /* Drive not initialized */ #define STA_NODISK 0x02 /* No medium in the drive */ #define STA_PROTECT 0x04 /* Write protected */ /* Command code for disk_ioctrl fucntion */ /* Generic command (Used by FatFs) */ #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ /* Generic command (Not used by FatFs) */ #define CTRL_POWER 5 /* Get/Set power status */ #define CTRL_LOCK 6 /* Lock/Unlock media removal */ #define CTRL_EJECT 7 /* Eject media */ #define CTRL_FORMAT 8 /* Create physical format on the media */ /* MMC/SDC specific ioctl command */ #define MMC_GET_TYPE 10 /* Get card type */ #define MMC_GET_CSD 11 /* Get CSD */ #define MMC_GET_CID 12 /* Get CID */ #define MMC_GET_OCR 13 /* Get OCR */ #define MMC_GET_SDSTAT 14 /* Get SD status */ #define ISDIO_READ 55 /* Read data form SD iSDIO register */ #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ /* ATA/CF specific ioctl command */ #define ATA_GET_REV 20 /* Get F/W revision */ #define ATA_GET_MODEL 21 /* Get model name */ #define ATA_GET_SN 22 /* Get serial number */ #ifdef __cplusplus } #endif #endif ================================================ FILE: lib/fatfs/source/ff.c ================================================ /*----------------------------------------------------------------------------/ / FatFs - Generic FAT Filesystem Module R0.15 w/patch1 / /-----------------------------------------------------------------------------/ / / Copyright (C) 2022, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided / that the following condition is met: / / 1. Redistributions of source code must retain the above copyright notice, / this condition and the following disclaimer. / / This software is provided by the copyright holder and contributors "AS IS" / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. / /----------------------------------------------------------------------------*/ #include #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ /*-------------------------------------------------------------------------- Module Private Definitions ---------------------------------------------------------------------------*/ #if FF_DEFINED != 80286 /* Revision ID */ #error Wrong include file (ff.h). #endif /* Limits and boundaries */ #define MAX_DIR 0x200000 /* Max size of FAT directory */ #define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ #define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ #define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ #define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ #define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ /* Character code support macros */ #define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') #define IsLower(c) ((c) >= 'a' && (c) <= 'z') #define IsDigit(c) ((c) >= '0' && (c) <= '9') #define IsSeparator(c) ((c) == '/' || (c) == '\\') #define IsTerminator(c) ((UINT)(c) < (FF_USE_LFN ? ' ' : '!')) #define IsSurrogate(c) ((c) >= 0xD800 && (c) <= 0xDFFF) #define IsSurrogateH(c) ((c) >= 0xD800 && (c) <= 0xDBFF) #define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) /* Additional file access control and file status flags for internal use */ #define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ #define FA_MODIFIED 0x40 /* File has been modified */ #define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ /* Additional file attribute bits for internal use */ #define AM_VOL 0x08 /* Volume label */ #define AM_LFN 0x0F /* LFN entry */ #define AM_MASK 0x3F /* Mask of defined bits in FAT */ #define AM_MASKX 0x37 /* Mask of defined bits in exFAT */ /* Name status flags in fn[11] */ #define NSFLAG 11 /* Index of the name status byte */ #define NS_LOSS 0x01 /* Out of 8.3 format */ #define NS_LFN 0x02 /* Force to create LFN entry */ #define NS_LAST 0x04 /* Last segment */ #define NS_BODY 0x08 /* Lower case flag (body) */ #define NS_EXT 0x10 /* Lower case flag (ext) */ #define NS_DOT 0x20 /* Dot entry */ #define NS_NOLFN 0x40 /* Do not find LFN */ #define NS_NONAME 0x80 /* Not followed */ /* exFAT directory entry types */ #define ET_BITMAP 0x81 /* Allocation bitmap */ #define ET_UPCASE 0x82 /* Up-case table */ #define ET_VLABEL 0x83 /* Volume label */ #define ET_FILEDIR 0x85 /* File and directory */ #define ET_STREAM 0xC0 /* Stream extension */ #define ET_FILENAME 0xC1 /* Name extension */ /* FatFs refers the FAT structure as simple byte array instead of structure member / because the C structure is not binary compatible between different platforms */ #define BS_JmpBoot 0 /* x86 jump instruction (3-byte) */ #define BS_OEMName 3 /* OEM name (8-byte) */ #define BPB_BytsPerSec 11 /* Sector size [byte] (WORD) */ #define BPB_SecPerClus 13 /* Cluster size [sector] (BYTE) */ #define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (WORD) */ #define BPB_NumFATs 16 /* Number of FATs (BYTE) */ #define BPB_RootEntCnt 17 /* Size of root directory area for FAT [entry] (WORD) */ #define BPB_TotSec16 19 /* Volume size (16-bit) [sector] (WORD) */ #define BPB_Media 21 /* Media descriptor byte (BYTE) */ #define BPB_FATSz16 22 /* FAT size (16-bit) [sector] (WORD) */ #define BPB_SecPerTrk 24 /* Number of sectors per track for int13h [sector] (WORD) */ #define BPB_NumHeads 26 /* Number of heads for int13h (WORD) */ #define BPB_HiddSec 28 /* Volume offset from top of the drive (DWORD) */ #define BPB_TotSec32 32 /* Volume size (32-bit) [sector] (DWORD) */ #define BS_DrvNum 36 /* Physical drive number for int13h (BYTE) */ #define BS_NTres 37 /* WindowsNT error flag (BYTE) */ #define BS_BootSig 38 /* Extended boot signature (BYTE) */ #define BS_VolID 39 /* Volume serial number (DWORD) */ #define BS_VolLab 43 /* Volume label string (8-byte) */ #define BS_FilSysType 54 /* Filesystem type string (8-byte) */ #define BS_BootCode 62 /* Boot code (448-byte) */ #define BS_55AA 510 /* Signature word (WORD) */ #define BPB_FATSz32 36 /* FAT32: FAT size [sector] (DWORD) */ #define BPB_ExtFlags32 40 /* FAT32: Extended flags (WORD) */ #define BPB_FSVer32 42 /* FAT32: Filesystem version (WORD) */ #define BPB_RootClus32 44 /* FAT32: Root directory cluster (DWORD) */ #define BPB_FSInfo32 48 /* FAT32: Offset of FSINFO sector (WORD) */ #define BPB_BkBootSec32 50 /* FAT32: Offset of backup boot sector (WORD) */ #define BS_DrvNum32 64 /* FAT32: Physical drive number for int13h (BYTE) */ #define BS_NTres32 65 /* FAT32: Error flag (BYTE) */ #define BS_BootSig32 66 /* FAT32: Extended boot signature (BYTE) */ #define BS_VolID32 67 /* FAT32: Volume serial number (DWORD) */ #define BS_VolLab32 71 /* FAT32: Volume label string (8-byte) */ #define BS_FilSysType32 82 /* FAT32: Filesystem type string (8-byte) */ #define BS_BootCode32 90 /* FAT32: Boot code (420-byte) */ #define BPB_ZeroedEx 11 /* exFAT: MBZ field (53-byte) */ #define BPB_VolOfsEx 64 /* exFAT: Volume offset from top of the drive [sector] (QWORD) */ #define BPB_TotSecEx 72 /* exFAT: Volume size [sector] (QWORD) */ #define BPB_FatOfsEx 80 /* exFAT: FAT offset from top of the volume [sector] (DWORD) */ #define BPB_FatSzEx 84 /* exFAT: FAT size [sector] (DWORD) */ #define BPB_DataOfsEx 88 /* exFAT: Data offset from top of the volume [sector] (DWORD) */ #define BPB_NumClusEx 92 /* exFAT: Number of clusters (DWORD) */ #define BPB_RootClusEx 96 /* exFAT: Root directory start cluster (DWORD) */ #define BPB_VolIDEx 100 /* exFAT: Volume serial number (DWORD) */ #define BPB_FSVerEx 104 /* exFAT: Filesystem version (WORD) */ #define BPB_VolFlagEx 106 /* exFAT: Volume flags (WORD) */ #define BPB_BytsPerSecEx 108 /* exFAT: Log2 of sector size in unit of byte (BYTE) */ #define BPB_SecPerClusEx 109 /* exFAT: Log2 of cluster size in unit of sector (BYTE) */ #define BPB_NumFATsEx 110 /* exFAT: Number of FATs (BYTE) */ #define BPB_DrvNumEx 111 /* exFAT: Physical drive number for int13h (BYTE) */ #define BPB_PercInUseEx 112 /* exFAT: Percent in use (BYTE) */ #define BPB_RsvdEx 113 /* exFAT: Reserved (7-byte) */ #define BS_BootCodeEx 120 /* exFAT: Boot code (390-byte) */ #define DIR_Name 0 /* Short file name (11-byte) */ #define DIR_Attr 11 /* Attribute (BYTE) */ #define DIR_NTres 12 /* Lower case flag (BYTE) */ #define DIR_CrtTime10 13 /* Created time sub-second (BYTE) */ #define DIR_CrtTime 14 /* Created time (DWORD) */ #define DIR_LstAccDate 18 /* Last accessed date (WORD) */ #define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (WORD) */ #define DIR_ModTime 22 /* Modified time (DWORD) */ #define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (WORD) */ #define DIR_FileSize 28 /* File size (DWORD) */ #define LDIR_Ord 0 /* LFN: LFN order and LLE flag (BYTE) */ #define LDIR_Attr 11 /* LFN: LFN attribute (BYTE) */ #define LDIR_Type 12 /* LFN: Entry type (BYTE) */ #define LDIR_Chksum 13 /* LFN: Checksum of the SFN (BYTE) */ #define LDIR_FstClusLO 26 /* LFN: MBZ field (WORD) */ #define XDIR_Type 0 /* exFAT: Type of exFAT directory entry (BYTE) */ #define XDIR_NumLabel 1 /* exFAT: Number of volume label characters (BYTE) */ #define XDIR_Label 2 /* exFAT: Volume label (11-WORD) */ #define XDIR_CaseSum 4 /* exFAT: Sum of case conversion table (DWORD) */ #define XDIR_NumSec 1 /* exFAT: Number of secondary entries (BYTE) */ #define XDIR_SetSum 2 /* exFAT: Sum of the set of directory entries (WORD) */ #define XDIR_Attr 4 /* exFAT: File attribute (WORD) */ #define XDIR_CrtTime 8 /* exFAT: Created time (DWORD) */ #define XDIR_ModTime 12 /* exFAT: Modified time (DWORD) */ #define XDIR_AccTime 16 /* exFAT: Last accessed time (DWORD) */ #define XDIR_CrtTime10 20 /* exFAT: Created time subsecond (BYTE) */ #define XDIR_ModTime10 21 /* exFAT: Modified time subsecond (BYTE) */ #define XDIR_CrtTZ 22 /* exFAT: Created timezone (BYTE) */ #define XDIR_ModTZ 23 /* exFAT: Modified timezone (BYTE) */ #define XDIR_AccTZ 24 /* exFAT: Last accessed timezone (BYTE) */ #define XDIR_GenFlags 33 /* exFAT: General secondary flags (BYTE) */ #define XDIR_NumName 35 /* exFAT: Number of file name characters (BYTE) */ #define XDIR_NameHash 36 /* exFAT: Hash of file name (WORD) */ #define XDIR_ValidFileSize 40 /* exFAT: Valid file size (QWORD) */ #define XDIR_FstClus 52 /* exFAT: First cluster of the file data (DWORD) */ #define XDIR_FileSize 56 /* exFAT: File/Directory size (QWORD) */ #define SZDIRE 32 /* Size of a directory entry */ #define DDEM 0xE5 /* Deleted directory entry mark set to DIR_Name[0] */ #define RDDEM 0x05 /* Replacement of the character collides with DDEM */ #define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ #define FSI_LeadSig 0 /* FAT32 FSI: Leading signature (DWORD) */ #define FSI_StrucSig 484 /* FAT32 FSI: Structure signature (DWORD) */ #define FSI_Free_Count 488 /* FAT32 FSI: Number of free clusters (DWORD) */ #define FSI_Nxt_Free 492 /* FAT32 FSI: Last allocated cluster (DWORD) */ #define MBR_Table 446 /* MBR: Offset of partition table in the MBR */ #define SZ_PTE 16 /* MBR: Size of a partition table entry */ #define PTE_Boot 0 /* MBR PTE: Boot indicator */ #define PTE_StHead 1 /* MBR PTE: Start head */ #define PTE_StSec 2 /* MBR PTE: Start sector */ #define PTE_StCyl 3 /* MBR PTE: Start cylinder */ #define PTE_System 4 /* MBR PTE: System ID */ #define PTE_EdHead 5 /* MBR PTE: End head */ #define PTE_EdSec 6 /* MBR PTE: End sector */ #define PTE_EdCyl 7 /* MBR PTE: End cylinder */ #define PTE_StLba 8 /* MBR PTE: Start in LBA */ #define PTE_SizLba 12 /* MBR PTE: Size in LBA */ #define GPTH_Sign 0 /* GPT HDR: Signature (8-byte) */ #define GPTH_Rev 8 /* GPT HDR: Revision (DWORD) */ #define GPTH_Size 12 /* GPT HDR: Header size (DWORD) */ #define GPTH_Bcc 16 /* GPT HDR: Header BCC (DWORD) */ #define GPTH_CurLba 24 /* GPT HDR: This header LBA (QWORD) */ #define GPTH_BakLba 32 /* GPT HDR: Another header LBA (QWORD) */ #define GPTH_FstLba 40 /* GPT HDR: First LBA for partition data (QWORD) */ #define GPTH_LstLba 48 /* GPT HDR: Last LBA for partition data (QWORD) */ #define GPTH_DskGuid 56 /* GPT HDR: Disk GUID (16-byte) */ #define GPTH_PtOfs 72 /* GPT HDR: Partition table LBA (QWORD) */ #define GPTH_PtNum 80 /* GPT HDR: Number of table entries (DWORD) */ #define GPTH_PteSize 84 /* GPT HDR: Size of table entry (DWORD) */ #define GPTH_PtBcc 88 /* GPT HDR: Partition table BCC (DWORD) */ #define SZ_GPTE 128 /* GPT PTE: Size of partition table entry */ #define GPTE_PtGuid 0 /* GPT PTE: Partition type GUID (16-byte) */ #define GPTE_UpGuid 16 /* GPT PTE: Partition unique GUID (16-byte) */ #define GPTE_FstLba 32 /* GPT PTE: First LBA of partition (QWORD) */ #define GPTE_LstLba 40 /* GPT PTE: Last LBA of partition (QWORD) */ #define GPTE_Flags 48 /* GPT PTE: Partition flags (QWORD) */ #define GPTE_Name 56 /* GPT PTE: Partition name */ /* Post process on fatal error in the file operations */ #define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } /* Re-entrancy related */ #if FF_FS_REENTRANT #if FF_USE_LFN == 1 #error Static LFN work area cannot be used in thread-safe configuration #endif #define LEAVE_FF(fs, res) { unlock_volume(fs, res); return res; } #else #define LEAVE_FF(fs, res) return res #endif /* Definitions of logical drive - physical location conversion */ #if FF_MULTI_PARTITION #define LD2PD(vol) VolToPart[vol].pd /* Get physical drive number */ #define LD2PT(vol) VolToPart[vol].pt /* Get partition number (0:auto search, 1..:forced partition number) */ #else #define LD2PD(vol) (BYTE)(vol) /* Each logical drive is associated with the same physical drive number */ #define LD2PT(vol) 0 /* Auto partition search */ #endif /* Definitions of sector size */ #if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096) #error Wrong sector size configuration #endif #if FF_MAX_SS == FF_MIN_SS #define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ #else #define SS(fs) ((fs)->ssize) /* Variable sector size */ #endif /* Timestamp */ #if FF_FS_NORTC == 1 #if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31 #error Invalid FF_FS_NORTC settings #endif #define GET_FATTIME() ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16) #else #define GET_FATTIME() get_fattime() #endif /* File lock controls */ #if FF_FS_LOCK #if FF_FS_READONLY #error FF_FS_LOCK must be 0 at read-only configuration #endif typedef struct { FATFS* fs; /* Object ID 1, volume (NULL:blank entry) */ DWORD clu; /* Object ID 2, containing directory (0:root) */ DWORD ofs; /* Object ID 3, offset in the directory */ UINT ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ } FILESEM; #endif /* SBCS up-case tables (\x80-\xFF) */ #define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT737 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT771 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF} #define TBL_CT775 {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \ 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT850 {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \ 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \ 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT852 {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \ 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} #define TBL_CT855 {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \ 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \ 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} #define TBL_CT857 {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \ 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT860 {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \ 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT861 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \ 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT862 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT863 {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \ 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \ 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT864 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT865 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT866 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #define TBL_CT869 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \ 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \ 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \ 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF} /* DBCS code range |----- 1st byte -----| |----------- 2nd byte -----------| */ /* <------> <------> <------> <------> <------> */ #define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00} #define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00} #define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE} #define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00} /* Macros for table definitions */ #define MERGE_2STR(a, b) a ## b #define MKCVTBL(hd, cp) MERGE_2STR(hd, cp) /*-------------------------------------------------------------------------- Module Private Work Area ---------------------------------------------------------------------------*/ /* Remark: Variables defined here without initial value shall be guaranteed / zero/null at start-up. If not, the linker option or start-up routine is / not compliance with C standard. */ /*--------------------------------*/ /* File/Volume controls */ /*--------------------------------*/ #if FF_VOLUMES < 1 || FF_VOLUMES > 10 #error Wrong FF_VOLUMES setting #endif static FATFS *FatFs[FF_VOLUMES]; /* Pointer to the filesystem objects (logical drives) */ static WORD Fsid; /* Filesystem mount ID */ #if FF_FS_RPATH != 0 static BYTE CurrVol; /* Current drive set by f_chdrive() */ #endif #if FF_FS_LOCK != 0 static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */ #if FF_FS_REENTRANT static BYTE SysLock; /* System lock flag (0:no mutex, 1:unlocked, 2:locked) */ #endif #endif #if FF_STR_VOLUME_ID #ifdef FF_VOLUME_STRS static const char *const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-defined volume ID */ #endif #endif #if FF_LBA64 #if FF_MIN_GPT > 0x100000000 #error Wrong FF_MIN_GPT setting #endif static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7}; #endif /*--------------------------------*/ /* LFN/Directory working buffer */ /*--------------------------------*/ #if FF_USE_LFN == 0 /* Non-LFN configuration */ #if FF_FS_EXFAT #error LFN must be enabled when enable exFAT #endif #define DEF_NAMBUF #define INIT_NAMBUF(fs) #define FREE_NAMBUF() #define LEAVE_MKFS(res) return res #else /* LFN configurations */ #if FF_MAX_LFN < 12 || FF_MAX_LFN > 255 #error Wrong setting of FF_MAX_LFN #endif #if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12 #error Wrong setting of FF_LFN_BUF or FF_SFN_BUF #endif #if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3 #error Wrong setting of FF_LFN_UNICODE #endif static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* FAT: Offset of LFN characters in the directory entry */ #define MAXDIRB(nc) ((nc + 44U) / 15 * SZDIRE) /* exFAT: Size of directory entry block scratchpad buffer needed for the name length */ #if FF_USE_LFN == 1 /* LFN enabled with static working buffer */ #if FF_FS_EXFAT static BYTE DirBuf[MAXDIRB(FF_MAX_LFN)]; /* Directory entry block scratchpad buffer */ #endif static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ #define DEF_NAMBUF #define INIT_NAMBUF(fs) #define FREE_NAMBUF() #define LEAVE_MKFS(res) return res #elif FF_USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */ #if FF_FS_EXFAT #define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)]; /* LFN working buffer and directory entry block scratchpad buffer */ #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } #define FREE_NAMBUF() #else #define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; /* LFN working buffer */ #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } #define FREE_NAMBUF() #endif #define LEAVE_MKFS(res) return res #elif FF_USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */ #if FF_FS_EXFAT #define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer and directory entry block scratchpad buffer */ #define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); } #define FREE_NAMBUF() ff_memfree(lfn) #else #define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer */ #define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; } #define FREE_NAMBUF() ff_memfree(lfn) #endif #define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } #define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */ #else #error Wrong setting of FF_USE_LFN #endif /* FF_USE_LFN == 1 */ #endif /* FF_USE_LFN == 0 */ /*--------------------------------*/ /* Code conversion tables */ /*--------------------------------*/ #if FF_CODE_PAGE == 0 /* Run-time code page configuration */ #define CODEPAGE CodePage static WORD CodePage; /* Current code page */ static const BYTE* ExCvt; /* Ptr to SBCS up-case table Ct???[] (null:not used) */ static const BYTE* DbcTbl; /* Ptr to DBCS code range table Dc???[] (null:not used) */ static const BYTE Ct437[] = TBL_CT437; static const BYTE Ct720[] = TBL_CT720; static const BYTE Ct737[] = TBL_CT737; static const BYTE Ct771[] = TBL_CT771; static const BYTE Ct775[] = TBL_CT775; static const BYTE Ct850[] = TBL_CT850; static const BYTE Ct852[] = TBL_CT852; static const BYTE Ct855[] = TBL_CT855; static const BYTE Ct857[] = TBL_CT857; static const BYTE Ct860[] = TBL_CT860; static const BYTE Ct861[] = TBL_CT861; static const BYTE Ct862[] = TBL_CT862; static const BYTE Ct863[] = TBL_CT863; static const BYTE Ct864[] = TBL_CT864; static const BYTE Ct865[] = TBL_CT865; static const BYTE Ct866[] = TBL_CT866; static const BYTE Ct869[] = TBL_CT869; static const BYTE Dc932[] = TBL_DC932; static const BYTE Dc936[] = TBL_DC936; static const BYTE Dc949[] = TBL_DC949; static const BYTE Dc950[] = TBL_DC950; #elif FF_CODE_PAGE < 900 /* Static code page configuration (SBCS) */ #define CODEPAGE FF_CODE_PAGE static const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE); #else /* Static code page configuration (DBCS) */ #define CODEPAGE FF_CODE_PAGE static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE); #endif /*-------------------------------------------------------------------------- Module Private Functions ---------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/ /* Load/Store multi-byte word in the FAT structure */ /*-----------------------------------------------------------------------*/ static WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ { WORD rv; rv = ptr[1]; rv = rv << 8 | ptr[0]; return rv; } static DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ { DWORD rv; rv = ptr[3]; rv = rv << 8 | ptr[2]; rv = rv << 8 | ptr[1]; rv = rv << 8 | ptr[0]; return rv; } #if FF_FS_EXFAT static QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ { QWORD rv; rv = ptr[7]; rv = rv << 8 | ptr[6]; rv = rv << 8 | ptr[5]; rv = rv << 8 | ptr[4]; rv = rv << 8 | ptr[3]; rv = rv << 8 | ptr[2]; rv = rv << 8 | ptr[1]; rv = rv << 8 | ptr[0]; return rv; } #endif #if !FF_FS_READONLY static void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; } static void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; } #if FF_FS_EXFAT static void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; } #endif #endif /* !FF_FS_READONLY */ /*-----------------------------------------------------------------------*/ /* String functions */ /*-----------------------------------------------------------------------*/ /* Test if the byte is DBC 1st byte */ static int dbc_1st (BYTE c) { #if FF_CODE_PAGE == 0 /* Variable code page */ if (DbcTbl && c >= DbcTbl[0]) { if (c <= DbcTbl[1]) return 1; /* 1st byte range 1 */ if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; /* 1st byte range 2 */ } #elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ if (c >= DbcTbl[0]) { if (c <= DbcTbl[1]) return 1; if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; } #else /* SBCS fixed code page */ if (c != 0) return 0; /* Always false */ #endif return 0; } /* Test if the byte is DBC 2nd byte */ static int dbc_2nd (BYTE c) { #if FF_CODE_PAGE == 0 /* Variable code page */ if (DbcTbl && c >= DbcTbl[4]) { if (c <= DbcTbl[5]) return 1; /* 2nd byte range 1 */ if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; /* 2nd byte range 2 */ if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; /* 2nd byte range 3 */ } #elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ if (c >= DbcTbl[4]) { if (c <= DbcTbl[5]) return 1; if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; } #else /* SBCS fixed code page */ if (c != 0) return 0; /* Always false */ #endif return 0; } #if FF_USE_LFN /* Get a Unicode code point from the TCHAR string in defined API encodeing */ static DWORD tchar2uni ( /* Returns a character in UTF-16 encoding (>=0x10000 on surrogate pair, 0xFFFFFFFF on decode error) */ const TCHAR** str /* Pointer to pointer to TCHAR string in configured encoding */ ) { DWORD uc; const TCHAR *p = *str; #if FF_LFN_UNICODE == 1 /* UTF-16 input */ WCHAR wc; uc = *p++; /* Get a unit */ if (IsSurrogate(uc)) { /* Surrogate? */ wc = *p++; /* Get low surrogate */ if (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF; /* Wrong surrogate? */ uc = uc << 16 | wc; } #elif FF_LFN_UNICODE == 2 /* UTF-8 input */ BYTE b; int nf; uc = (BYTE)*p++; /* Get an encoding unit */ if (uc & 0x80) { /* Multiple byte code? */ if ((uc & 0xE0) == 0xC0) { /* 2-byte sequence? */ uc &= 0x1F; nf = 1; } else if ((uc & 0xF0) == 0xE0) { /* 3-byte sequence? */ uc &= 0x0F; nf = 2; } else if ((uc & 0xF8) == 0xF0) { /* 4-byte sequence? */ uc &= 0x07; nf = 3; } else { /* Wrong sequence */ return 0xFFFFFFFF; } do { /* Get trailing bytes */ b = (BYTE)*p++; if ((b & 0xC0) != 0x80) return 0xFFFFFFFF; /* Wrong sequence? */ uc = uc << 6 | (b & 0x3F); } while (--nf != 0); if (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ } #elif FF_LFN_UNICODE == 3 /* UTF-32 input */ uc = (TCHAR)*p++; /* Get a unit */ if (uc >= 0x110000 || IsSurrogate(uc)) return 0xFFFFFFFF; /* Wrong code? */ if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ #else /* ANSI/OEM input */ BYTE b; WCHAR wc; wc = (BYTE)*p++; /* Get a byte */ if (dbc_1st((BYTE)wc)) { /* Is it a DBC 1st byte? */ b = (BYTE)*p++; /* Get 2nd byte */ if (!dbc_2nd(b)) return 0xFFFFFFFF; /* Invalid code? */ wc = (wc << 8) + b; /* Make a DBC */ } if (wc != 0) { wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM ==> Unicode */ if (wc == 0) return 0xFFFFFFFF; /* Invalid code? */ } uc = wc; #endif *str = p; /* Next read pointer */ return uc; } /* Store a Unicode char in defined API encoding */ static UINT put_utf ( /* Returns number of encoding units written (0:buffer overflow or wrong encoding) */ DWORD chr, /* UTF-16 encoded character (Surrogate pair if >=0x10000) */ TCHAR* buf, /* Output buffer */ UINT szb /* Size of the buffer */ ) { #if FF_LFN_UNICODE == 1 /* UTF-16 output */ WCHAR hs, wc; hs = (WCHAR)(chr >> 16); wc = (WCHAR)chr; if (hs == 0) { /* Single encoding unit? */ if (szb < 1 || IsSurrogate(wc)) return 0; /* Buffer overflow or wrong code? */ *buf = wc; return 1; } if (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0; /* Buffer overflow or wrong surrogate? */ *buf++ = hs; *buf++ = wc; return 2; #elif FF_LFN_UNICODE == 2 /* UTF-8 output */ DWORD hc; if (chr < 0x80) { /* Single byte code? */ if (szb < 1) return 0; /* Buffer overflow? */ *buf = (TCHAR)chr; return 1; } if (chr < 0x800) { /* 2-byte sequence? */ if (szb < 2) return 0; /* Buffer overflow? */ *buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F)); *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); return 2; } if (chr < 0x10000) { /* 3-byte sequence? */ if (szb < 3 || IsSurrogate(chr)) return 0; /* Buffer overflow or wrong code? */ *buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F)); *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); return 3; } /* 4-byte sequence */ if (szb < 4) return 0; /* Buffer overflow? */ hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ chr = (hc | chr) + 0x10000; *buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07)); *buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F)); *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); return 4; #elif FF_LFN_UNICODE == 3 /* UTF-32 output */ DWORD hc; if (szb < 1) return 0; /* Buffer overflow? */ if (chr >= 0x10000) { /* Out of BMP? */ hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ chr = (hc | chr) + 0x10000; } *buf++ = (TCHAR)chr; return 1; #else /* ANSI/OEM output */ WCHAR wc; wc = ff_uni2oem(chr, CODEPAGE); if (wc >= 0x100) { /* Is this a DBC? */ if (szb < 2) return 0; *buf++ = (char)(wc >> 8); /* Store DBC 1st byte */ *buf++ = (TCHAR)wc; /* Store DBC 2nd byte */ return 2; } if (wc == 0 || szb < 1) return 0; /* Invalid char or buffer overflow? */ *buf++ = (TCHAR)wc; /* Store the character */ return 1; #endif } #endif /* FF_USE_LFN */ #if FF_FS_REENTRANT /*-----------------------------------------------------------------------*/ /* Request/Release grant to access the volume */ /*-----------------------------------------------------------------------*/ static int lock_volume ( /* 1:Ok, 0:timeout */ FATFS* fs, /* Filesystem object to lock */ int syslock /* System lock required */ ) { int rv; #if FF_FS_LOCK rv = ff_mutex_take(fs->ldrv); /* Lock the volume */ if (rv && syslock) { /* System lock reqiered? */ rv = ff_mutex_take(FF_VOLUMES); /* Lock the system */ if (rv) { SysLock = 2; /* System lock succeeded */ } else { ff_mutex_give(fs->ldrv); /* Failed system lock */ } } #else rv = syslock ? ff_mutex_take(fs->ldrv) : ff_mutex_take(fs->ldrv); /* Lock the volume (this is to prevent compiler warning) */ #endif return rv; } static void unlock_volume ( FATFS* fs, /* Filesystem object */ FRESULT res /* Result code to be returned */ ) { if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { #if FF_FS_LOCK if (SysLock == 2) { /* Is the system locked? */ SysLock = 1; ff_mutex_give(FF_VOLUMES); } #endif ff_mutex_give(fs->ldrv); /* Unlock the volume */ } } #endif #if FF_FS_LOCK /*-----------------------------------------------------------------------*/ /* File shareing control functions */ /*-----------------------------------------------------------------------*/ static FRESULT chk_share ( /* Check if the file can be accessed */ DIR* dp, /* Directory object pointing the file to be checked */ int acc /* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */ ) { UINT i, be; /* Search open object table for the object */ be = 0; for (i = 0; i < FF_FS_LOCK; i++) { if (Files[i].fs) { /* Existing entry */ if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ Files[i].clu == dp->obj.sclust && Files[i].ofs == dp->dptr) break; } else { /* Blank entry */ be = 1; } } if (i == FF_FS_LOCK) { /* The object has not been opened */ return (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK; /* Is there a blank entry for new object? */ } /* The object was opened. Reject any open against writing file and all write mode open */ return (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; } static int enq_share (void) /* Check if an entry is available for a new object */ { UINT i; for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */ return (i == FF_FS_LOCK) ? 0 : 1; } static UINT inc_share ( /* Increment object open counter and returns its index (0:Internal error) */ DIR* dp, /* Directory object pointing the file to register or increment */ int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ ) { UINT i; for (i = 0; i < FF_FS_LOCK; i++) { /* Find the object */ if (Files[i].fs == dp->obj.fs && Files[i].clu == dp->obj.sclust && Files[i].ofs == dp->dptr) break; } if (i == FF_FS_LOCK) { /* Not opened. Register it as new. */ for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; /* Find a free entry */ if (i == FF_FS_LOCK) return 0; /* No free entry to register (int err) */ Files[i].fs = dp->obj.fs; Files[i].clu = dp->obj.sclust; Files[i].ofs = dp->dptr; Files[i].ctr = 0; } if (acc >= 1 && Files[i].ctr) return 0; /* Access violation (int err) */ Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ return i + 1; /* Index number origin from 1 */ } static FRESULT dec_share ( /* Decrement object open counter */ UINT i /* Semaphore index (1..) */ ) { UINT n; FRESULT res; if (--i < FF_FS_LOCK) { /* Index number origin from 0 */ n = Files[i].ctr; if (n == 0x100) n = 0; /* If write mode open, delete the object semaphore */ if (n > 0) n--; /* Decrement read mode open count */ Files[i].ctr = n; if (n == 0) { /* Delete the object semaphore if open count becomes zero */ Files[i].fs = 0; /* Free the entry << 1, there is a potential error in this process >>> */ } res = FR_OK; } else { res = FR_INT_ERR; /* Invalid index number */ } return res; } static void clear_share ( /* Clear all lock entries of the volume */ FATFS* fs ) { UINT i; for (i = 0; i < FF_FS_LOCK; i++) { if (Files[i].fs == fs) Files[i].fs = 0; } } #endif /* FF_FS_LOCK */ /*-----------------------------------------------------------------------*/ /* Move/Flush disk access window in the filesystem object */ /*-----------------------------------------------------------------------*/ #if !FF_FS_READONLY static FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERR */ FATFS* fs /* Filesystem object */ ) { FRESULT res = FR_OK; if (fs->wflag) { /* Is the disk access window dirty? */ if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */ fs->wflag = 0; /* Clear window dirty flag */ if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */ } } else { res = FR_DISK_ERR; } } return res; } #endif static FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERR */ FATFS* fs, /* Filesystem object */ LBA_t sect /* Sector LBA to make appearance in the fs->win[] */ ) { FRESULT res = FR_OK; if (sect != fs->winsect) { /* Window offset changed? */ #if !FF_FS_READONLY res = sync_window(fs); /* Flush the window */ #endif if (res == FR_OK) { /* Fill sector window with new data */ if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) { sect = (LBA_t)0 - 1; /* Invalidate window if read data is not valid */ res = FR_DISK_ERR; } fs->winsect = sect; } } return res; } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Synchronize filesystem and data on the storage */ /*-----------------------------------------------------------------------*/ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ FATFS* fs /* Filesystem object */ ) { FRESULT res; res = sync_window(fs); if (res == FR_OK) { if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ /* Create FSInfo structure */ memset(fs->win, 0, sizeof fs->win); st_word(fs->win + BS_55AA, 0xAA55); /* Boot signature */ st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */ st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */ st_dword(fs->win + FSI_Free_Count, fs->free_clst); /* Number of free clusters */ st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); /* Last allocated culuster */ fs->winsect = fs->volbase + 1; /* Write it into the FSInfo sector (Next to VBR) */ disk_write(fs->pdrv, fs->win, fs->winsect, 1); fs->fsi_flag = 0; } /* Make sure that no pending write process in the lower layer */ if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; } return res; } #endif /*-----------------------------------------------------------------------*/ /* Get physical sector number from cluster number */ /*-----------------------------------------------------------------------*/ static LBA_t clst2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ FATFS* fs, /* Filesystem object */ DWORD clst /* Cluster# to be converted */ ) { clst -= 2; /* Cluster number is origin from 2 */ if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ return fs->database + (LBA_t)fs->csize * clst; /* Start sector number of the cluster */ } /*-----------------------------------------------------------------------*/ /* FAT access - Read value of an FAT entry */ /*-----------------------------------------------------------------------*/ static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */ FFOBJID* obj, /* Corresponding object */ DWORD clst /* Cluster number to get the value */ ) { UINT wc, bc; DWORD val; FATFS *fs = obj->fs; if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */ val = 1; /* Internal error */ } else { val = 0xFFFFFFFF; /* Default value falls on disk error */ switch (fs->fs_type) { case FS_FAT12 : bc = (UINT)clst; bc += bc / 2; if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF); /* Adjust bit position */ break; case FS_FAT16 : if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ break; case FS_FAT32 : if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper 4 bits */ break; #if FF_FS_EXFAT case FS_EXFAT : if ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) { /* Object except root dir must have valid data length */ DWORD cofs = clst - obj->sclust; /* Offset from start cluster */ DWORD clen = (DWORD)((LBA_t)((obj->objsize - 1) / SS(fs)) / fs->csize); /* Number of clusters - 1 */ if (obj->stat == 2 && cofs <= clen) { /* Is it a contiguous chain? */ val = (cofs == clen) ? 0x7FFFFFFF : clst + 1; /* No data on the FAT, generate the value */ break; } if (obj->stat == 3 && cofs < obj->n_cont) { /* Is it in the 1st fragment? */ val = clst + 1; /* Generate the value */ break; } if (obj->stat != 2) { /* Get value from FAT if FAT chain is valid */ if (obj->n_frag != 0) { /* Is it on the growing edge? */ val = 0x7FFFFFFF; /* Generate EOC */ } else { if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; } break; } } val = 1; /* Internal error */ break; #endif default: val = 1; /* Internal error */ } } return val; } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT access - Change value of an FAT entry */ /*-----------------------------------------------------------------------*/ static FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ FATFS* fs, /* Corresponding filesystem object */ DWORD clst, /* FAT index number (cluster number) to be changed */ DWORD val /* New value to be set to the entry */ ) { UINT bc; BYTE *p; FRESULT res = FR_INT_ERR; if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ switch (fs->fs_type) { case FS_FAT12: bc = (UINT)clst; bc += bc / 2; /* bc: byte offset of the entry */ res = move_window(fs, fs->fatbase + (bc / SS(fs))); if (res != FR_OK) break; p = fs->win + bc++ % SS(fs); *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; /* Update 1st byte */ fs->wflag = 1; res = move_window(fs, fs->fatbase + (bc / SS(fs))); if (res != FR_OK) break; p = fs->win + bc % SS(fs); *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); /* Update 2nd byte */ fs->wflag = 1; break; case FS_FAT16: res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); if (res != FR_OK) break; st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ fs->wflag = 1; break; case FS_FAT32: #if FF_FS_EXFAT case FS_EXFAT: #endif res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); if (res != FR_OK) break; if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); } st_dword(fs->win + clst * 4 % SS(fs), val); fs->wflag = 1; break; } } return res; } #endif /* !FF_FS_READONLY */ #if FF_FS_EXFAT && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* exFAT: Accessing FAT and Allocation Bitmap */ /*-----------------------------------------------------------------------*/ /*--------------------------------------*/ /* Find a contiguous free cluster block */ /*--------------------------------------*/ static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */ FATFS* fs, /* Filesystem object */ DWORD clst, /* Cluster number to scan from */ DWORD ncl /* Number of contiguous clusters to find (1..) */ ) { BYTE bm, bv; UINT i; DWORD val, scl, ctr; clst -= 2; /* The first bit in the bitmap corresponds to cluster #2 */ if (clst >= fs->n_fatent - 2) clst = 0; scl = val = clst; ctr = 0; for (;;) { if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; i = val / 8 % SS(fs); bm = 1 << (val % 8); do { do { bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ val = 0; bm = 0; i = SS(fs); } if (bv == 0) { /* Is it a free cluster? */ if (++ctr == ncl) return scl + 2; /* Check if run length is sufficient for required */ } else { scl = val; ctr = 0; /* Encountered a cluster in-use, restart to scan */ } if (val == clst) return 0; /* All cluster scanned? */ } while (bm != 0); bm = 1; } while (++i < SS(fs)); } } /*----------------------------------------*/ /* Set/Clear a block of allocation bitmap */ /*----------------------------------------*/ static FRESULT change_bitmap ( FATFS* fs, /* Filesystem object */ DWORD clst, /* Cluster number to change from */ DWORD ncl, /* Number of clusters to be changed */ int bv /* bit value to be set (0 or 1) */ ) { BYTE bm; UINT i; LBA_t sect; clst -= 2; /* The first bit corresponds to cluster #2 */ sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ i = clst / 8 % SS(fs); /* Byte offset in the sector */ bm = 1 << (clst % 8); /* Bit mask in the byte */ for (;;) { if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; do { do { if (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR; /* Is the bit expected value? */ fs->win[i] ^= bm; /* Flip the bit */ fs->wflag = 1; if (--ncl == 0) return FR_OK; /* All bits processed? */ } while (bm <<= 1); /* Next bit */ bm = 1; } while (++i < SS(fs)); /* Next byte */ i = 0; } } /*---------------------------------------------*/ /* Fill the first fragment of the FAT chain */ /*---------------------------------------------*/ static FRESULT fill_first_frag ( FFOBJID* obj /* Pointer to the corresponding object */ ) { FRESULT res; DWORD cl, n; if (obj->stat == 3) { /* Has the object been changed 'fragmented' in this session? */ for (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) { /* Create cluster chain on the FAT */ res = put_fat(obj->fs, cl, cl + 1); if (res != FR_OK) return res; } obj->stat = 0; /* Change status 'FAT chain is valid' */ } return FR_OK; } /*---------------------------------------------*/ /* Fill the last fragment of the FAT chain */ /*---------------------------------------------*/ static FRESULT fill_last_frag ( FFOBJID* obj, /* Pointer to the corresponding object */ DWORD lcl, /* Last cluster of the fragment */ DWORD term /* Value to set the last FAT entry */ ) { FRESULT res; while (obj->n_frag > 0) { /* Create the chain of last fragment */ res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); if (res != FR_OK) return res; obj->n_frag--; } return FR_OK; } #endif /* FF_FS_EXFAT && !FF_FS_READONLY */ #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT handling - Remove a cluster chain */ /*-----------------------------------------------------------------------*/ static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ FFOBJID* obj, /* Corresponding object */ DWORD clst, /* Cluster to remove a chain from */ DWORD pclst /* Previous cluster of clst (0 if entire chain) */ ) { FRESULT res = FR_OK; DWORD nxt; FATFS *fs = obj->fs; #if FF_FS_EXFAT || FF_USE_TRIM DWORD scl = clst, ecl = clst; #endif #if FF_USE_TRIM LBA_t rt[2]; #endif if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ /* Mark the previous cluster 'EOC' on the FAT if it exists */ if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { res = put_fat(fs, pclst, 0xFFFFFFFF); if (res != FR_OK) return res; } /* Remove the chain */ do { nxt = get_fat(obj, clst); /* Get cluster status */ if (nxt == 0) break; /* Empty cluster? */ if (nxt == 1) return FR_INT_ERR; /* Internal error? */ if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error? */ if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ if (res != FR_OK) return res; } if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ fs->free_clst++; fs->fsi_flag |= 1; } #if FF_FS_EXFAT || FF_USE_TRIM if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ ecl = nxt; } else { /* End of contiguous cluster block */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ if (res != FR_OK) return res; } #endif #if FF_USE_TRIM rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */ rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */ disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be erased */ #endif scl = ecl = nxt; } #endif clst = nxt; /* Next cluster */ } while (clst < fs->n_fatent); /* Repeat while not the last link */ #if FF_FS_EXFAT /* Some post processes for chain status */ if (fs->fs_type == FS_EXFAT) { if (pclst == 0) { /* Has the entire chain been removed? */ obj->stat = 0; /* Change the chain status 'initial' */ } else { if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */ clst = obj->sclust; /* Follow the chain to check if it gets contiguous */ while (clst != pclst) { nxt = get_fat(obj, clst); if (nxt < 2) return FR_INT_ERR; if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; if (nxt != clst + 1) break; /* Not contiguous? */ clst++; } if (clst == pclst) { /* Has the chain got contiguous again? */ obj->stat = 2; /* Change the chain status 'contiguous' */ } } else { if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */ obj->stat = 2; /* Change the chain status 'contiguous' */ } } } } #endif return FR_OK; } /*-----------------------------------------------------------------------*/ /* FAT handling - Stretch a chain or Create a new chain */ /*-----------------------------------------------------------------------*/ static DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ FFOBJID* obj, /* Corresponding object */ DWORD clst /* Cluster# to stretch, 0:Create a new chain */ ) { DWORD cs, ncl, scl; FRESULT res; FATFS *fs = obj->fs; if (clst == 0) { /* Create a new chain */ scl = fs->last_clst; /* Suggested cluster to start to find */ if (scl == 0 || scl >= fs->n_fatent) scl = 1; } else { /* Stretch a chain */ cs = get_fat(obj, clst); /* Check the cluster status */ if (cs < 2) return 1; /* Test for insanity */ if (cs == 0xFFFFFFFF) return cs; /* Test for disk error */ if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ scl = clst; /* Cluster to start to find */ } if (fs->free_clst == 0) return 0; /* No free cluster */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ if (ncl == 0 || ncl == 0xFFFFFFFF) return ncl; /* No free cluster or hard error? */ res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ if (res == FR_INT_ERR) return 1; if (res == FR_DISK_ERR) return 0xFFFFFFFF; if (clst == 0) { /* Is it a new chain? */ obj->stat = 2; /* Set status 'contiguous' */ } else { /* It is a stretched chain */ if (obj->stat == 2 && ncl != scl + 1) { /* Is the chain got fragmented? */ obj->n_cont = scl - obj->sclust; /* Set size of the contiguous part */ obj->stat = 3; /* Change status 'just fragmented' */ } } if (obj->stat != 2) { /* Is the file non-contiguous? */ if (ncl == clst + 1) { /* Is the cluster next to previous one? */ obj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2; /* Increment size of last framgent */ } else { /* New fragment */ if (obj->n_frag == 0) obj->n_frag = 1; res = fill_last_frag(obj, clst, ncl); /* Fill last fragment on the FAT and link it to new one */ if (res == FR_OK) obj->n_frag = 1; } } } else #endif { /* On the FAT/FAT32 volume */ ncl = 0; if (scl == clst) { /* Stretching an existing chain? */ ncl = scl + 1; /* Test if next cluster is free */ if (ncl >= fs->n_fatent) ncl = 2; cs = get_fat(obj, ncl); /* Get next cluster status */ if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ if (cs != 0) { /* Not free? */ cs = fs->last_clst; /* Start at suggested cluster if it is valid */ if (cs >= 2 && cs < fs->n_fatent) scl = cs; ncl = 0; } } if (ncl == 0) { /* The new cluster cannot be contiguous and find another fragment */ ncl = scl; /* Start cluster */ for (;;) { ncl++; /* Next cluster */ if (ncl >= fs->n_fatent) { /* Check wrap-around */ ncl = 2; if (ncl > scl) return 0; /* No free cluster found? */ } cs = get_fat(obj, ncl); /* Get the cluster status */ if (cs == 0) break; /* Found a free cluster? */ if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ if (ncl == scl) return 0; /* No free cluster found? */ } } res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ if (res == FR_OK && clst != 0) { res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ } } if (res == FR_OK) { /* Update FSINFO if function succeeded. */ fs->last_clst = ncl; if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--; fs->fsi_flag |= 1; } else { ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; /* Failed. Generate error status */ } return ncl; /* Return new cluster number or error status */ } #endif /* !FF_FS_READONLY */ #if FF_USE_FASTSEEK /*-----------------------------------------------------------------------*/ /* FAT handling - Convert offset into cluster with link map table */ /*-----------------------------------------------------------------------*/ static DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ FIL* fp, /* Pointer to the file object */ FSIZE_t ofs /* File offset to be converted to cluster# */ ) { DWORD cl, ncl; DWORD *tbl; FATFS *fs = fp->obj.fs; tbl = fp->cltbl + 1; /* Top of CLMT */ cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */ for (;;) { ncl = *tbl++; /* Number of cluters in the fragment */ if (ncl == 0) return 0; /* End of table? (error) */ if (cl < ncl) break; /* In this fragment? */ cl -= ncl; tbl++; /* Next fragment */ } return cl + *tbl; /* Return the cluster number */ } #endif /* FF_USE_FASTSEEK */ /*-----------------------------------------------------------------------*/ /* Directory handling - Fill a cluster with zeros */ /*-----------------------------------------------------------------------*/ #if !FF_FS_READONLY static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ FATFS *fs, /* Filesystem object */ DWORD clst /* Directory table to clear */ ) { LBA_t sect; UINT n, szb; BYTE *ibuf; if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ sect = clst2sect(fs, clst); /* Top of the cluster */ fs->winsect = sect; /* Set window to top of the cluster */ memset(fs->win, 0, sizeof fs->win); /* Clear window buffer */ #if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ /* Allocate a temporary buffer */ for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; if (szb > SS(fs)) { /* Buffer allocated? */ memset(ibuf, 0, szb); szb /= SS(fs); /* Bytes -> Sectors */ for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ ff_memfree(ibuf); } else #endif { ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ } return (n == fs->csize) ? FR_OK : FR_DISK_ERR; } #endif /* !FF_FS_READONLY */ /*-----------------------------------------------------------------------*/ /* Directory handling - Set directory index */ /*-----------------------------------------------------------------------*/ static FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ DIR* dp, /* Pointer to directory object */ DWORD ofs /* Offset of directory table */ ) { DWORD csz, clst; FATFS *fs = dp->obj.fs; if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) { /* Check range of offset and alignment */ return FR_INT_ERR; } dp->dptr = ofs; /* Set current offset */ clst = dp->obj.sclust; /* Table start cluster (0:root) */ if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ clst = (DWORD)fs->dirbase; if (FF_FS_EXFAT) dp->obj.stat = 0; /* exFAT: Root dir has an FAT chain */ } if (clst == 0) { /* Static table (root-directory on the FAT volume) */ if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ dp->sect = fs->dirbase; } else { /* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */ csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ while (ofs >= csz) { /* Follow cluster chain */ clst = get_fat(&dp->obj, clst); /* Get next cluster */ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal error */ ofs -= csz; } dp->sect = clst2sect(fs, clst); } dp->clust = clst; /* Current cluster# */ if (dp->sect == 0) return FR_INT_ERR; dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ return FR_OK; } /*-----------------------------------------------------------------------*/ /* Directory handling - Move directory table index next */ /*-----------------------------------------------------------------------*/ static FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ DIR* dp, /* Pointer to the directory object */ int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ ) { DWORD ofs, clst; FATFS *fs = dp->obj.fs; ofs = dp->dptr + SZDIRE; /* Next entry */ if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0; /* Disable it if the offset reached the max value */ if (dp->sect == 0) return FR_NO_FILE; /* Report EOT if it has been disabled */ if (ofs % SS(fs) == 0) { /* Sector changed? */ dp->sect++; /* Next sector */ if (dp->clust == 0) { /* Static table */ if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ dp->sect = 0; return FR_NO_FILE; } } else { /* Dynamic table */ if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ clst = get_fat(&dp->obj, dp->clust); /* Get next cluster */ if (clst <= 1) return FR_INT_ERR; /* Internal error */ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ #if !FF_FS_READONLY if (!stretch) { /* If no stretch, report EOT */ dp->sect = 0; return FR_NO_FILE; } clst = create_chain(&dp->obj, dp->clust); /* Allocate a cluster */ if (clst == 0) return FR_DENIED; /* No free cluster */ if (clst == 1) return FR_INT_ERR; /* Internal error */ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ if (FF_FS_EXFAT) dp->obj.stat |= 4; /* exFAT: The directory has been stretched */ #else if (!stretch) dp->sect = 0; /* (this line is to suppress compiler warning) */ dp->sect = 0; return FR_NO_FILE; /* Report EOT */ #endif } dp->clust = clst; /* Initialize data for new cluster */ dp->sect = clst2sect(fs, clst); } } } dp->dptr = ofs; /* Current entry */ dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */ return FR_OK; } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Directory handling - Reserve a block of directory entries */ /*-----------------------------------------------------------------------*/ static FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ DIR* dp, /* Pointer to the directory object */ UINT n_ent /* Number of contiguous entries to allocate */ ) { FRESULT res; UINT n; FATFS *fs = dp->obj.fs; res = dir_sdi(dp, 0); if (res == FR_OK) { n = 0; do { res = move_window(fs, dp->sect); if (res != FR_OK) break; #if FF_FS_EXFAT if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) { /* Is the entry free? */ #else if (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) { /* Is the entry free? */ #endif if (++n == n_ent) break; /* Is a block of contiguous free entries found? */ } else { n = 0; /* Not a free entry, restart to search */ } res = dir_next(dp, 1); /* Next entry with table stretch enabled */ } while (res == FR_OK); } if (res == FR_NO_FILE) res = FR_DENIED; /* No directory entry to allocate */ return res; } #endif /* !FF_FS_READONLY */ /*-----------------------------------------------------------------------*/ /* FAT: Directory handling - Load/Store start cluster number */ /*-----------------------------------------------------------------------*/ static DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ FATFS* fs, /* Pointer to the fs object */ const BYTE* dir /* Pointer to the key entry */ ) { DWORD cl; cl = ld_word(dir + DIR_FstClusLO); if (fs->fs_type == FS_FAT32) { cl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16; } return cl; } #if !FF_FS_READONLY static void st_clust ( FATFS* fs, /* Pointer to the fs object */ BYTE* dir, /* Pointer to the key entry */ DWORD cl /* Value to be set */ ) { st_word(dir + DIR_FstClusLO, (WORD)cl); if (fs->fs_type == FS_FAT32) { st_word(dir + DIR_FstClusHI, (WORD)(cl >> 16)); } } #endif #if FF_USE_LFN /*--------------------------------------------------------*/ /* FAT-LFN: Compare a part of file name with an LFN entry */ /*--------------------------------------------------------*/ static int cmp_lfn ( /* 1:matched, 0:not matched */ const WCHAR* lfnbuf, /* Pointer to the LFN working buffer to be compared */ BYTE* dir /* Pointer to the directory entry containing the part of LFN */ ) { UINT i, s; WCHAR wc, uc; if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO */ i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ if (wc != 0) { if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ return 0; /* Not matched */ } wc = uc; } else { if (uc != 0xFFFF) return 0; /* Check filler */ } } if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0; /* Last segment matched but different length */ return 1; /* The part of LFN matched */ } #if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT /*-----------------------------------------------------*/ /* FAT-LFN: Pick a part of file name from an LFN entry */ /*-----------------------------------------------------*/ static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ WCHAR* lfnbuf, /* Pointer to the LFN working buffer */ BYTE* dir /* Pointer to the LFN entry */ ) { UINT i, s; WCHAR wc, uc; if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO is 0 */ i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Offset in the LFN buffer */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ if (wc != 0) { if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i++] = wc = uc; /* Store it */ } else { if (uc != 0xFFFF) return 0; /* Check filler */ } } if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */ if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i] = 0; } return 1; /* The part of LFN is valid */ } #endif #if !FF_FS_READONLY /*-----------------------------------------*/ /* FAT-LFN: Create an entry of LFN entries */ /*-----------------------------------------*/ static void put_lfn ( const WCHAR* lfn, /* Pointer to the LFN */ BYTE* dir, /* Pointer to the LFN entry to be created */ BYTE ord, /* LFN order (1-20) */ BYTE sum /* Checksum of the corresponding SFN */ ) { UINT i, s; WCHAR wc; dir[LDIR_Chksum] = sum; /* Set checksum */ dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ dir[LDIR_Type] = 0; st_word(dir + LDIR_FstClusLO, 0); i = (ord - 1) * 13; /* Get offset in the LFN working buffer */ s = wc = 0; do { if (wc != 0xFFFF) wc = lfn[i++]; /* Get an effective character */ st_word(dir + LfnOfs[s], wc); /* Put it */ if (wc == 0) wc = 0xFFFF; /* Padding characters for following items */ } while (++s < 13); if (wc == 0xFFFF || !lfn[i]) ord |= LLEF; /* Last LFN part is the start of LFN sequence */ dir[LDIR_Ord] = ord; /* Set the LFN order */ } #endif /* !FF_FS_READONLY */ #endif /* FF_USE_LFN */ #if FF_USE_LFN && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT-LFN: Create a Numbered SFN */ /*-----------------------------------------------------------------------*/ static void gen_numname ( BYTE* dst, /* Pointer to the buffer to store numbered SFN */ const BYTE* src, /* Pointer to SFN in directory form */ const WCHAR* lfn, /* Pointer to LFN */ UINT seq /* Sequence number */ ) { BYTE ns[8], c; UINT i, j; WCHAR wc; DWORD sreg; memcpy(dst, src, 11); /* Prepare the SFN to be modified */ if (seq > 5) { /* In case of many collisions, generate a hash number instead of sequential number */ sreg = seq; while (*lfn) { /* Create a CRC as hash value */ wc = *lfn++; for (i = 0; i < 16; i++) { sreg = (sreg << 1) + (wc & 1); wc >>= 1; if (sreg & 0x10000) sreg ^= 0x11021; } } seq = (UINT)sreg; } /* Make suffix (~ + hexadecimal) */ i = 7; do { c = (BYTE)((seq % 16) + '0'); seq /= 16; if (c > '9') c += 7; ns[i--] = c; } while (i && seq); ns[i] = '~'; /* Append the suffix to the SFN body */ for (j = 0; j < i && dst[j] != ' '; j++) { /* Find the offset to append */ if (dbc_1st(dst[j])) { /* To avoid DBC break up */ if (j == i - 1) break; j++; } } do { /* Append the suffix */ dst[j++] = (i < 8) ? ns[i++] : ' '; } while (j < 8); } #endif /* FF_USE_LFN && !FF_FS_READONLY */ #if FF_USE_LFN /*-----------------------------------------------------------------------*/ /* FAT-LFN: Calculate checksum of an SFN entry */ /*-----------------------------------------------------------------------*/ static BYTE sum_sfn ( const BYTE* dir /* Pointer to the SFN entry */ ) { BYTE sum = 0; UINT n = 11; do { sum = (sum >> 1) + (sum << 7) + *dir++; } while (--n); return sum; } #endif /* FF_USE_LFN */ #if FF_FS_EXFAT /*-----------------------------------------------------------------------*/ /* exFAT: Checksum */ /*-----------------------------------------------------------------------*/ static WORD xdir_sum ( /* Get checksum of the directoly entry block */ const BYTE* dir /* Directory entry block to be calculated */ ) { UINT i, szblk; WORD sum; szblk = (dir[XDIR_NumSec] + 1) * SZDIRE; /* Number of bytes of the entry block */ for (i = sum = 0; i < szblk; i++) { if (i == XDIR_SetSum) { /* Skip 2-byte sum field */ i++; } else { sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i]; } } return sum; } static WORD xname_sum ( /* Get check sum (to be used as hash) of the file name */ const WCHAR* name /* File name to be calculated */ ) { WCHAR chr; WORD sum = 0; while ((chr = *name++) != 0) { chr = (WCHAR)ff_wtoupper(chr); /* File name needs to be up-case converted */ sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF); sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8); } return sum; } #if !FF_FS_READONLY && FF_USE_MKFS static DWORD xsum32 ( /* Returns 32-bit checksum */ BYTE dat, /* Byte to be calculated (byte-by-byte processing) */ DWORD sum /* Previous sum value */ ) { sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat; return sum; } #endif /*------------------------------------*/ /* exFAT: Get a directory entry block */ /*------------------------------------*/ static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ DIR* dp /* Reading directory object pointing top of the entry block to load */ ) { FRESULT res; UINT i, sz_ent; BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory directory entry block 85+C0+C1s */ /* Load file directory entry */ res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */ memcpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; /* Load stream extension entry */ res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */ memcpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; /* Load file name entries */ i = 2 * SZDIRE; /* Name offset to load */ do { res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */ if (i < MAXDIRB(FF_MAX_LFN)) memcpy(dirb + i, dp->dir, SZDIRE); } while ((i += SZDIRE) < sz_ent); /* Sanity check (do it for only accessible object) */ if (i <= MAXDIRB(FF_MAX_LFN)) { if (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR; } return FR_OK; } /*------------------------------------------------------------------*/ /* exFAT: Initialize object allocation info with loaded entry block */ /*------------------------------------------------------------------*/ static void init_alloc_info ( FATFS* fs, /* Filesystem object */ FFOBJID* obj /* Object allocation information to be initialized */ ) { obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */ obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */ obj->n_frag = 0; /* No last fragment info */ } #if !FF_FS_READONLY || FF_FS_RPATH != 0 /*------------------------------------------------*/ /* exFAT: Load the object's directory entry block */ /*------------------------------------------------*/ static FRESULT load_obj_xdir ( DIR* dp, /* Blank directory object to be used to access containing directory */ const FFOBJID* obj /* Object with its containing directory information */ ) { FRESULT res; /* Open object containing directory */ dp->obj.fs = obj->fs; dp->obj.sclust = obj->c_scl; dp->obj.stat = (BYTE)obj->c_size; dp->obj.objsize = obj->c_size & 0xFFFFFF00; dp->obj.n_frag = 0; dp->blk_ofs = obj->c_ofs; res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */ if (res == FR_OK) { res = load_xdir(dp); /* Load the object's entry block */ } return res; } #endif #if !FF_FS_READONLY /*----------------------------------------*/ /* exFAT: Store the directory entry block */ /*----------------------------------------*/ static FRESULT store_xdir ( DIR* dp /* Pointer to the directory object */ ) { FRESULT res; UINT nent; BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the directory entry block 85+C0+C1s */ /* Create set sum */ st_word(dirb + XDIR_SetSum, xdir_sum(dirb)); nent = dirb[XDIR_NumSec] + 1; /* Store the directory entry block to the directory */ res = dir_sdi(dp, dp->blk_ofs); while (res == FR_OK) { res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) break; memcpy(dp->dir, dirb, SZDIRE); dp->obj.fs->wflag = 1; if (--nent == 0) break; dirb += SZDIRE; res = dir_next(dp, 0); } return (res == FR_OK || res == FR_DISK_ERR) ? res : FR_INT_ERR; } /*-------------------------------------------*/ /* exFAT: Create a new directory entry block */ /*-------------------------------------------*/ static void create_xdir ( BYTE* dirb, /* Pointer to the directory entry block buffer */ const WCHAR* lfn /* Pointer to the object name */ ) { UINT i; BYTE nc1, nlen; WCHAR wc; /* Create file-directory and stream-extension entry */ memset(dirb, 0, 2 * SZDIRE); dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR; dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM; /* Create file-name entries */ i = SZDIRE * 2; /* Top of file_name entries */ nlen = nc1 = 0; wc = 1; do { dirb[i++] = ET_FILENAME; dirb[i++] = 0; do { /* Fill name field */ if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ st_word(dirb + i, wc); /* Store it */ i += 2; } while (i % SZDIRE != 0); nc1++; } while (lfn[nlen]); /* Fill next entry if any char follows */ dirb[XDIR_NumName] = nlen; /* Set name length */ dirb[XDIR_NumSec] = 1 + nc1; /* Set secondary count (C0 + C1s) */ st_word(dirb + XDIR_NameHash, xname_sum(lfn)); /* Set name hash */ } #endif /* !FF_FS_READONLY */ #endif /* FF_FS_EXFAT */ #if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT /*-----------------------------------------------------------------------*/ /* Read an object from the directory */ /*-----------------------------------------------------------------------*/ #define DIR_READ_FILE(dp) dir_read(dp, 0) #define DIR_READ_LABEL(dp) dir_read(dp, 1) static FRESULT dir_read ( DIR* dp, /* Pointer to the directory object */ int vol /* Filtered by 0:file/directory or 1:volume label */ ) { FRESULT res = FR_NO_FILE; FATFS *fs = dp->obj.fs; BYTE attr, b; #if FF_USE_LFN BYTE ord = 0xFF, sum = 0xFF; #endif while (dp->sect) { res = move_window(fs, dp->sect); if (res != FR_OK) break; b = dp->dir[DIR_Name]; /* Test for the entry type */ if (b == 0) { res = FR_NO_FILE; break; /* Reached to end of the directory */ } #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (FF_USE_LABEL && vol) { if (b == ET_VLABEL) break; /* Volume label entry? */ } else { if (b == ET_FILEDIR) { /* Start of the file entry block? */ dp->blk_ofs = dp->dptr; /* Get location of the block */ res = load_xdir(dp); /* Load the entry block */ if (res == FR_OK) { dp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK; /* Get attribute */ } break; } } } else #endif { /* On the FAT/FAT32 volume */ dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ #if FF_USE_LFN /* LFN configuration */ if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ ord = 0xFF; } else { if (attr == AM_LFN) { /* An LFN entry is found */ if (b & LLEF) { /* Is it start of an LFN sequence? */ sum = dp->dir[LDIR_Chksum]; b &= (BYTE)~LLEF; ord = b; dp->blk_ofs = dp->dptr; } /* Check LFN validity and capture it */ ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } else { /* An SFN entry is found */ if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ } break; } } #else /* Non LFN configuration */ if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ break; } #endif } res = dir_next(dp, 0); /* Next entry */ if (res != FR_OK) break; } if (res != FR_OK) dp->sect = 0; /* Terminate the read operation on error or EOT */ return res; } #endif /* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */ /*-----------------------------------------------------------------------*/ /* Directory handling - Find an object in the directory */ /*-----------------------------------------------------------------------*/ static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ DIR* dp /* Pointer to the directory object with the file name */ ) { FRESULT res; FATFS *fs = dp->obj.fs; BYTE c; #if FF_USE_LFN BYTE a, ord, sum; #endif res = dir_sdi(dp, 0); /* Rewind directory object */ if (res != FR_OK) return res; #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ BYTE nc; UINT di, ni; WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */ #if FF_MAX_LFN < 255 if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ #endif if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */ for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare the name */ if ((di % SZDIRE) == 0) di += 2; if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break; } if (nc == 0 && !fs->lfnbuf[ni]) break; /* Name matched? */ } return res; } #endif /* On the FAT/FAT32 volume */ #if FF_USE_LFN ord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ #endif do { res = move_window(fs, dp->sect); if (res != FR_OK) break; c = dp->dir[DIR_Name]; if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ #if FF_USE_LFN /* LFN configuration */ dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ } else { if (a == AM_LFN) { /* An LFN entry is found */ if (!(dp->fn[NSFLAG] & NS_NOLFN)) { if (c & LLEF) { /* Is it start of LFN sequence? */ sum = dp->dir[LDIR_Chksum]; c &= (BYTE)~LLEF; ord = c; /* LFN start order */ dp->blk_ofs = dp->dptr; /* Start offset of LFN */ } /* Check validity of the LFN entry and compare it with given name */ ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } } else { /* An SFN entry is found */ if (ord == 0 && sum == sum_sfn(dp->dir)) break; /* LFN matched? */ if (!(dp->fn[NSFLAG] & NS_LOSS) && !memcmp(dp->dir, dp->fn, 11)) break; /* SFN matched? */ ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ } } #else /* Non LFN configuration */ dp->obj.attr = dp->dir[DIR_Attr] & AM_MASK; if (!(dp->dir[DIR_Attr] & AM_VOL) && !memcmp(dp->dir, dp->fn, 11)) break; /* Is it a valid entry? */ #endif res = dir_next(dp, 0); /* Next entry */ } while (res == FR_OK); return res; } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Register an object to the directory */ /*-----------------------------------------------------------------------*/ static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */ DIR* dp /* Target directory with object name to be created */ ) { FRESULT res; FATFS *fs = dp->obj.fs; #if FF_USE_LFN /* LFN configuration */ UINT n, len, n_ent; BYTE sn[12], sum; if (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME; /* Check name validity */ for (len = 0; fs->lfnbuf[len]; len++) ; /* Get lfn length */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ n_ent = (len + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ res = dir_alloc(dp, n_ent); /* Allocate directory entries */ if (res != FR_OK) return res; dp->blk_ofs = dp->dptr - SZDIRE * (n_ent - 1); /* Set the allocated entry block offset */ if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */ dp->obj.stat &= ~4; res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ if (res != FR_OK) return res; res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ if (res != FR_OK) return res; if (dp->obj.sclust != 0) { /* Is it a sub-directory? */ DIR dj; res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ if (res != FR_OK) return res; dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */ st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize); fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; /* Update the allocation status */ res = store_xdir(&dj); /* Store the object status */ if (res != FR_OK) return res; } } create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */ return FR_OK; } #endif /* On the FAT/FAT32 volume */ memcpy(sn, dp->fn, 12); if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ dp->fn[NSFLAG] = NS_NOLFN; /* Find only SFN */ for (n = 1; n < 100; n++) { gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */ res = dir_find(dp); /* Check if the name collides with existing SFN */ if (res != FR_OK) break; } if (n == 100) return FR_DENIED; /* Abort if too many collisions */ if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ dp->fn[NSFLAG] = sn[NSFLAG]; } /* Create an SFN with/without LFNs. */ n_ent = (sn[NSFLAG] & NS_LFN) ? (len + 12) / 13 + 1 : 1; /* Number of entries to allocate */ res = dir_alloc(dp, n_ent); /* Allocate entries */ if (res == FR_OK && --n_ent) { /* Set LFN entry if needed */ res = dir_sdi(dp, dp->dptr - n_ent * SZDIRE); if (res == FR_OK) { sum = sum_sfn(dp->fn); /* Checksum value of the SFN tied to the LFN */ do { /* Store LFN entries in bottom first */ res = move_window(fs, dp->sect); if (res != FR_OK) break; put_lfn(fs->lfnbuf, dp->dir, (BYTE)n_ent, sum); fs->wflag = 1; res = dir_next(dp, 0); /* Next entry */ } while (res == FR_OK && --n_ent); } } #else /* Non LFN configuration */ res = dir_alloc(dp, 1); /* Allocate an entry for SFN */ #endif /* Set SFN entry */ if (res == FR_OK) { res = move_window(fs, dp->sect); if (res == FR_OK) { memset(dp->dir, 0, SZDIRE); /* Clean the entry */ memcpy(dp->dir + DIR_Name, dp->fn, 11); /* Put SFN */ #if FF_USE_LFN dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */ #endif fs->wflag = 1; } } return res; } #endif /* !FF_FS_READONLY */ #if !FF_FS_READONLY && FF_FS_MINIMIZE == 0 /*-----------------------------------------------------------------------*/ /* Remove an object from the directory */ /*-----------------------------------------------------------------------*/ static FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ DIR* dp /* Directory object pointing the entry to be removed */ ) { FRESULT res; FATFS *fs = dp->obj.fs; #if FF_USE_LFN /* LFN configuration */ DWORD last = dp->dptr; res = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs); /* Goto top of the entry block if LFN is exist */ if (res == FR_OK) { do { res = move_window(fs, dp->sect); if (res != FR_OK) break; if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ dp->dir[XDIR_Type] &= 0x7F; /* Clear the entry InUse flag. */ } else { /* On the FAT/FAT32 volume */ dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'. */ } fs->wflag = 1; if (dp->dptr >= last) break; /* If reached last entry then all entries of the object has been deleted. */ res = dir_next(dp, 0); /* Next entry */ } while (res == FR_OK); if (res == FR_NO_FILE) res = FR_INT_ERR; } #else /* Non LFN configuration */ res = move_window(fs, dp->sect); if (res == FR_OK) { dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'.*/ fs->wflag = 1; } #endif return res; } #endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */ #if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 /*-----------------------------------------------------------------------*/ /* Get file information from directory entry */ /*-----------------------------------------------------------------------*/ static void get_fileinfo ( DIR* dp, /* Pointer to the directory object */ FILINFO* fno /* Pointer to the file information to be filled */ ) { UINT si, di; #if FF_USE_LFN BYTE lcf; WCHAR wc, hs; FATFS *fs = dp->obj.fs; UINT nw; #else TCHAR c; #endif fno->fname[0] = 0; /* Invaidate file info */ if (dp->sect == 0) return; /* Exit if read pointer has reached end of directory */ #if FF_USE_LFN /* LFN configuration */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* exFAT volume */ UINT nc = 0; si = SZDIRE * 2; di = 0; /* 1st C1 entry in the entry block */ hs = 0; while (nc < fs->dirbuf[XDIR_NumName]) { if (si >= MAXDIRB(FF_MAX_LFN)) { /* Truncated directory block? */ di = 0; break; } if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ wc = ld_word(fs->dirbuf + si); si += 2; nc++; /* Get a character */ if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ hs = wc; continue; /* Get low surrogate */ } nw = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ if (nw == 0) { /* Buffer overflow or wrong char? */ di = 0; break; } di += nw; hs = 0; } if (hs != 0) di = 0; /* Broken surrogate pair? */ if (di == 0) fno->fname[di++] = '\?'; /* Inaccessible object name? */ fno->fname[di] = 0; /* Terminate the name */ fno->altname[0] = 0; /* exFAT does not support SFN */ fno->fattrib = fs->dirbuf[XDIR_Attr] & AM_MASKX; /* Attribute */ fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ fno->ftime = ld_word(fs->dirbuf + XDIR_ModTime + 0); /* Time */ fno->fdate = ld_word(fs->dirbuf + XDIR_ModTime + 2); /* Date */ return; } else #endif { /* FAT/FAT32 volume */ if (dp->blk_ofs != 0xFFFFFFFF) { /* Get LFN if available */ si = di = 0; hs = 0; while (fs->lfnbuf[si] != 0) { wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */ if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ hs = wc; continue; /* Get low surrogate */ } nw = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ if (nw == 0) { /* Buffer overflow or wrong char? */ di = 0; break; } di += nw; hs = 0; } if (hs != 0) di = 0; /* Broken surrogate pair? */ fno->fname[di] = 0; /* Terminate the LFN (null string means LFN is invalid) */ } } si = di = 0; while (si < 11) { /* Get SFN from SFN entry */ wc = dp->dir[si++]; /* Get a char */ if (wc == ' ') continue; /* Skip padding spaces */ if (wc == RDDEM) wc = DDEM; /* Restore replaced DDEM character */ if (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.'; /* Insert a . if extension is exist */ #if FF_LFN_UNICODE >= 1 /* Unicode output */ if (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) { /* Make a DBC if needed */ wc = wc << 8 | dp->dir[si++]; } wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM -> Unicode */ if (wc == 0) { /* Wrong char in the current code page? */ di = 0; break; } nw = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di); /* Store it in API encoding */ if (nw == 0) { /* Buffer overflow? */ di = 0; break; } di += nw; #else /* ANSI/OEM output */ fno->altname[di++] = (TCHAR)wc; /* Store it without any conversion */ #endif } fno->altname[di] = 0; /* Terminate the SFN (null string means SFN is invalid) */ if (fno->fname[0] == 0) { /* If LFN is invalid, altname[] needs to be copied to fname[] */ if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccessible */ fno->fname[di++] = '\?'; } else { for (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ wc = (WCHAR)fno->altname[si]; if (wc == '.') lcf = NS_EXT; if (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20; fno->fname[di] = (TCHAR)wc; } } fno->fname[di] = 0; /* Terminate the LFN */ if (!dp->dir[DIR_NTres]) fno->altname[0] = 0; /* Altname is not needed if neither LFN nor case info is exist. */ } #else /* Non-LFN configuration */ si = di = 0; while (si < 11) { /* Copy name body and extension */ c = (TCHAR)dp->dir[si++]; if (c == ' ') continue; /* Skip padding spaces */ if (c == RDDEM) c = DDEM; /* Restore replaced DDEM character */ if (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */ fno->fname[di++] = c; } fno->fname[di] = 0; /* Terminate the SFN */ #endif fno->fattrib = dp->dir[DIR_Attr] & AM_MASK; /* Attribute */ fno->fsize = ld_dword(dp->dir + DIR_FileSize); /* Size */ fno->ftime = ld_word(dp->dir + DIR_ModTime + 0); /* Time */ fno->fdate = ld_word(dp->dir + DIR_ModTime + 2); /* Date */ } #endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ #if FF_USE_FIND && FF_FS_MINIMIZE <= 1 /*-----------------------------------------------------------------------*/ /* Pattern matching */ /*-----------------------------------------------------------------------*/ #define FIND_RECURS 4 /* Maximum number of wildcard terms in the pattern to limit recursion */ static DWORD get_achar ( /* Get a character and advance ptr */ const TCHAR** ptr /* Pointer to pointer to the ANSI/OEM or Unicode string */ ) { DWORD chr; #if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode input */ chr = tchar2uni(ptr); if (chr == 0xFFFFFFFF) chr = 0; /* Wrong UTF encoding is recognized as end of the string */ chr = ff_wtoupper(chr); #else /* ANSI/OEM input */ chr = (BYTE)*(*ptr)++; /* Get a byte */ if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ #if FF_CODE_PAGE == 0 if (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ #elif FF_CODE_PAGE < 900 if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ #endif #if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900 if (dbc_1st((BYTE)chr)) { /* Get DBC 2nd byte if needed */ chr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0; } #endif #endif return chr; } static int pattern_match ( /* 0:mismatched, 1:matched */ const TCHAR* pat, /* Matching pattern */ const TCHAR* nam, /* String to be tested */ UINT skip, /* Number of pre-skip chars (number of ?s, b8:infinite (* specified)) */ UINT recur /* Recursion count */ ) { const TCHAR *pptr; const TCHAR *nptr; DWORD pchr, nchr; UINT sk; while ((skip & 0xFF) != 0) { /* Pre-skip name chars */ if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */ skip--; } if (*pat == 0 && skip) return 1; /* Matched? (short circuit) */ do { pptr = pat; nptr = nam; /* Top of pattern and name to match */ for (;;) { if (*pptr == '\?' || *pptr == '*') { /* Wildcard term? */ if (recur == 0) return 0; /* Too many wildcard terms? */ sk = 0; do { /* Analyze the wildcard term */ if (*pptr++ == '\?') { sk++; } else { sk |= 0x100; } } while (*pptr == '\?' || *pptr == '*'); if (pattern_match(pptr, nptr, sk, recur - 1)) return 1; /* Test new branch (recursive call) */ nchr = *nptr; break; /* Branch mismatched */ } pchr = get_achar(&pptr); /* Get a pattern char */ nchr = get_achar(&nptr); /* Get a name char */ if (pchr != nchr) break; /* Branch mismatched? */ if (pchr == 0) return 1; /* Branch matched? (matched at end of both strings) */ } get_achar(&nam); /* nam++ */ } while (skip && nchr); /* Retry until end of name if infinite search is specified */ return 0; } #endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */ /*-----------------------------------------------------------------------*/ /* Pick a top segment and create the object name in directory form */ /*-----------------------------------------------------------------------*/ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ DIR* dp, /* Pointer to the directory object */ const TCHAR** path /* Pointer to pointer to the segment in the path string */ ) { #if FF_USE_LFN /* LFN configuration */ BYTE b, cf; WCHAR wc; WCHAR *lfn; const TCHAR* p; DWORD uc; UINT i, ni, si, di; /* Create LFN into LFN working buffer */ p = *path; lfn = dp->obj.fs->lfnbuf; di = 0; for (;;) { uc = tchar2uni(&p); /* Get a character */ if (uc == 0xFFFFFFFF) return FR_INVALID_NAME; /* Invalid code or UTF decode error */ if (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16); /* Store high surrogate if needed */ wc = (WCHAR)uc; if (wc < ' ' || IsSeparator(wc)) break; /* Break if end of the path or a separator is found */ if (wc < 0x80 && strchr("*:<>|\"\?\x7F", (int)wc)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ lfn[di++] = wc; /* Store the Unicode character */ } if (wc < ' ') { /* Stopped at end of the path? */ cf = NS_LAST; /* Last segment */ } else { /* Stopped at a separator */ while (IsSeparator(*p)) p++; /* Skip duplicated separators if exist */ cf = 0; /* Next segment may follow */ if (IsTerminator(*p)) cf = NS_LAST; /* Ignore terminating separator */ } *path = p; /* Return pointer to the next segment */ #if FF_FS_RPATH != 0 if ((di == 1 && lfn[di - 1] == '.') || (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { /* Is this segment a dot name? */ lfn[di] = 0; for (i = 0; i < 11; i++) { /* Create dot name for SFN entry */ dp->fn[i] = (i < di) ? '.' : ' '; } dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ return FR_OK; } #endif while (di) { /* Snip off trailing spaces and dots if exist */ wc = lfn[di - 1]; if (wc != ' ' && wc != '.') break; di--; } lfn[di] = 0; /* LFN is created into the working buffer */ if (di == 0) return FR_INVALID_NAME; /* Reject null name */ /* Create SFN in directory form */ for (si = 0; lfn[si] == ' '; si++) ; /* Remove leading spaces */ if (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN; /* Is there any leading space or dot? */ while (di > 0 && lfn[di - 1] != '.') di--; /* Find last dot (di<=si: no extension) */ memset(dp->fn, ' ', 11); i = b = 0; ni = 8; for (;;) { wc = lfn[si++]; /* Get an LFN character */ if (wc == 0) break; /* Break on end of the LFN */ if (wc == ' ' || (wc == '.' && si != di)) { /* Remove embedded spaces and dots */ cf |= NS_LOSS | NS_LFN; continue; } if (i >= ni || si == di) { /* End of field? */ if (ni == 11) { /* Name extension overflow? */ cf |= NS_LOSS | NS_LFN; break; } if (si != di) cf |= NS_LOSS | NS_LFN; /* Name body overflow? */ if (si > di) break; /* No name extension? */ si = di; i = 8; ni = 11; b <<= 2; /* Enter name extension */ continue; } if (wc >= 0x80) { /* Is this an extended character? */ cf |= NS_LFN; /* LFN entry needs to be created */ #if FF_CODE_PAGE == 0 if (ExCvt) { /* In SBCS cfg */ wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ } else { /* In DBCS cfg */ wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Up-convert ==> ANSI/OEM code */ } #elif FF_CODE_PAGE < 900 /* In SBCS cfg */ wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ #else /* In DBCS cfg */ wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Up-convert ==> ANSI/OEM code */ #endif } if (wc >= 0x100) { /* Is this a DBC? */ if (i >= ni - 1) { /* Field overflow? */ cf |= NS_LOSS | NS_LFN; i = ni; continue; /* Next field */ } dp->fn[i++] = (BYTE)(wc >> 8); /* Put 1st byte */ } else { /* SBC */ if (wc == 0 || strchr("+,;=[]", (int)wc)) { /* Replace illegal characters for SFN */ wc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ } else { if (IsUpper(wc)) { /* ASCII upper case? */ b |= 2; } if (IsLower(wc)) { /* ASCII lower case? */ b |= 1; wc -= 0x20; } } } dp->fn[i++] = (BYTE)wc; } if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ if (ni == 8) b <<= 2; /* Shift capital flags if no extension */ if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN; /* LFN entry needs to be created if composite capitals */ if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ if (b & 0x01) cf |= NS_EXT; /* NT flag (Extension has small capital letters only) */ if (b & 0x04) cf |= NS_BODY; /* NT flag (Body has small capital letters only) */ } dp->fn[NSFLAG] = cf; /* SFN is created into dp->fn[] */ return FR_OK; #else /* FF_USE_LFN : Non-LFN configuration */ BYTE c, d; BYTE *sfn; UINT ni, si, i; const char *p; /* Create file name in directory form */ p = *path; sfn = dp->fn; memset(sfn, ' ', 11); si = i = 0; ni = 8; #if FF_FS_RPATH != 0 if (p[si] == '.') { /* Is this a dot entry? */ for (;;) { c = (BYTE)p[si++]; if (c != '.' || si >= 3) break; sfn[i++] = c; } if (!IsSeparator(c) && c > ' ') return FR_INVALID_NAME; *path = p + si; /* Return pointer to the next segment */ sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of the path */ return FR_OK; } #endif for (;;) { c = (BYTE)p[si++]; /* Get a byte */ if (c <= ' ') break; /* Break if end of the path name */ if (IsSeparator(c)) { /* Break if a separator is found */ while (IsSeparator(p[si])) si++; /* Skip duplicated separator if exist */ break; } if (c == '.' || i >= ni) { /* End of body or field overflow? */ if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Field overflow or invalid dot? */ i = 8; ni = 11; /* Enter file extension field */ continue; } #if FF_CODE_PAGE == 0 if (ExCvt && c >= 0x80) { /* Is SBC extended character? */ c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ } #elif FF_CODE_PAGE < 900 if (c >= 0x80) { /* Is SBC extended character? */ c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ } #endif if (dbc_1st(c)) { /* Check if it is a DBC 1st byte */ d = (BYTE)p[si++]; /* Get 2nd byte */ if (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */ sfn[i++] = c; sfn[i++] = d; } else { /* SBC */ if (strchr("*+,:;<=>[]|\"\?\x7F", (int)c)) return FR_INVALID_NAME; /* Reject illegal chrs for SFN */ if (IsLower(c)) c -= 0x20; /* To upper */ sfn[i++] = c; } } *path = &p[si]; /* Return pointer to the next segment */ if (i == 0) return FR_INVALID_NAME; /* Reject nul string */ if (sfn[0] == DDEM) sfn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ sfn[NSFLAG] = (c <= ' ' || p[si] <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ return FR_OK; #endif /* FF_USE_LFN */ } /*-----------------------------------------------------------------------*/ /* Follow a file path */ /*-----------------------------------------------------------------------*/ static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ DIR* dp, /* Directory object to return last directory and found object */ const TCHAR* path /* Full-path string to find a file or directory */ ) { FRESULT res; BYTE ns; FATFS *fs = dp->obj.fs; #if FF_FS_RPATH != 0 if (!IsSeparator(*path) && (FF_STR_VOLUME_ID != 2 || !IsTerminator(*path))) { /* Without heading separator */ dp->obj.sclust = fs->cdir; /* Start at the current directory */ } else #endif { /* With heading separator */ while (IsSeparator(*path)) path++; /* Strip separators */ dp->obj.sclust = 0; /* Start from the root directory */ } #if FF_FS_EXFAT dp->obj.n_frag = 0; /* Invalidate last fragment counter of the object */ #if FF_FS_RPATH != 0 if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */ DIR dj; dp->obj.c_scl = fs->cdc_scl; dp->obj.c_size = fs->cdc_size; dp->obj.c_ofs = fs->cdc_ofs; res = load_obj_xdir(&dj, &dp->obj); if (res != FR_OK) return res; dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize); dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; } #endif #endif if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ dp->fn[NSFLAG] = NS_NONAME; res = dir_sdi(dp, 0); } else { /* Follow path */ for (;;) { res = create_name(dp, &path); /* Get a segment name of the path */ if (res != FR_OK) break; res = dir_find(dp); /* Find an object with the segment name */ ns = dp->fn[NSFLAG]; if (res != FR_OK) { /* Failed to find the object */ if (res == FR_NO_FILE) { /* Object is not found */ if (FF_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, stay there */ if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ dp->fn[NSFLAG] = NS_NONAME; res = FR_OK; } else { /* Could not find the object */ if (!(ns & NS_LAST)) res = FR_NO_PATH; /* Adjust error code if not last segment */ } } break; } if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ /* Get into the sub-directory */ if (!(dp->obj.attr & AM_DIR)) { /* It is not a sub-directory and cannot follow */ res = FR_NO_PATH; break; } #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */ dp->obj.c_scl = dp->obj.sclust; dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; dp->obj.c_ofs = dp->blk_ofs; init_alloc_info(fs, &dp->obj); /* Open next directory */ } else #endif { dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */ } } } return res; } /*-----------------------------------------------------------------------*/ /* Get logical drive number from path name */ /*-----------------------------------------------------------------------*/ static int get_ldnumber ( /* Returns logical drive number (-1:invalid drive number or null pointer) */ const TCHAR** path /* Pointer to pointer to the path name */ ) { const TCHAR *tp; const TCHAR *tt; TCHAR tc; int i; int vol = -1; #if FF_STR_VOLUME_ID /* Find string volume ID */ const char *sp; char c; #endif tt = tp = *path; if (!tp) return vol; /* Invalid path name? */ do { /* Find a colon in the path */ tc = *tt++; } while (!IsTerminator(tc) && tc != ':'); if (tc == ':') { /* DOS/Windows style volume ID? */ i = FF_VOLUMES; if (IsDigit(*tp) && tp + 2 == tt) { /* Is there a numeric volume ID + colon? */ i = (int)*tp - '0'; /* Get the LD number */ } #if FF_STR_VOLUME_ID == 1 /* Arbitrary string is enabled */ else { i = 0; do { sp = VolumeStr[i]; tp = *path; /* This string volume ID and path name */ do { /* Compare the volume ID with path name */ c = *sp++; tc = *tp++; if (IsLower(c)) c -= 0x20; if (IsLower(tc)) tc -= 0x20; } while (c && (TCHAR)c == tc); } while ((c || tp != tt) && ++i < FF_VOLUMES); /* Repeat for each id until pattern match */ } #endif if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ vol = i; /* Drive number */ *path = tt; /* Snip the drive prefix off */ } return vol; } #if FF_STR_VOLUME_ID == 2 /* Unix style volume ID is enabled */ if (*tp == '/') { /* Is there a volume ID? */ while (*(tp + 1) == '/') tp++; /* Skip duplicated separator */ i = 0; do { tt = tp; sp = VolumeStr[i]; /* Path name and this string volume ID */ do { /* Compare the volume ID with path name */ c = *sp++; tc = *(++tt); if (IsLower(c)) c -= 0x20; if (IsLower(tc)) tc -= 0x20; } while (c && (TCHAR)c == tc); } while ((c || (tc != '/' && !IsTerminator(tc))) && ++i < FF_VOLUMES); /* Repeat for each ID until pattern match */ if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ vol = i; /* Drive number */ *path = tt; /* Snip the drive prefix off */ } return vol; } #endif /* No drive prefix is found */ #if FF_FS_RPATH != 0 vol = CurrVol; /* Default drive is current drive */ #else vol = 0; /* Default drive is 0 */ #endif return vol; /* Return the default drive */ } /*-----------------------------------------------------------------------*/ /* GPT support functions */ /*-----------------------------------------------------------------------*/ #if FF_LBA64 /* Calculate CRC32 in byte-by-byte */ static DWORD crc32 ( /* Returns next CRC value */ DWORD crc, /* Current CRC value */ BYTE d /* A byte to be processed */ ) { BYTE b; for (b = 1; b; b <<= 1) { crc ^= (d & b) ? 1 : 0; crc = (crc & 1) ? crc >> 1 ^ 0xEDB88320 : crc >> 1; } return crc; } /* Check validity of GPT header */ static int test_gpt_header ( /* 0:Invalid, 1:Valid */ const BYTE* gpth /* Pointer to the GPT header */ ) { UINT i; DWORD bcc, hlen; if (memcmp(gpth + GPTH_Sign, "EFI PART" "\0\0\1", 12)) return 0; /* Check signature and version (1.0) */ hlen = ld_dword(gpth + GPTH_Size); /* Check header size */ if (hlen < 92 || hlen > FF_MIN_SS) return 0; for (i = 0, bcc = 0xFFFFFFFF; i < hlen; i++) { /* Check header BCC */ bcc = crc32(bcc, i - GPTH_Bcc < 4 ? 0 : gpth[i]); } if (~bcc != ld_dword(gpth + GPTH_Bcc)) return 0; if (ld_dword(gpth + GPTH_PteSize) != SZ_GPTE) return 0; /* Table entry size (must be SZ_GPTE bytes) */ if (ld_dword(gpth + GPTH_PtNum) > 128) return 0; /* Table size (must be 128 entries or less) */ return 1; } #if !FF_FS_READONLY && FF_USE_MKFS /* Generate random value */ static DWORD make_rand ( DWORD seed, /* Seed value */ BYTE *buff, /* Output buffer */ UINT n /* Data length */ ) { UINT r; if (seed == 0) seed = 1; do { for (r = 0; r < 8; r++) seed = seed & 1 ? seed >> 1 ^ 0xA3000000 : seed >> 1; /* Shift 8 bits the 32-bit LFSR */ *buff++ = (BYTE)seed; } while (--n); return seed; } #endif #endif /*-----------------------------------------------------------------------*/ /* Load a sector and check if it is an FAT VBR */ /*-----------------------------------------------------------------------*/ /* Check what the sector is */ static UINT check_fs ( /* 0:FAT/FAT32 VBR, 1:exFAT VBR, 2:Not FAT and valid BS, 3:Not FAT and invalid BS, 4:Disk error */ FATFS* fs, /* Filesystem object */ LBA_t sect /* Sector to load and check if it is an FAT-VBR or not */ ) { WORD w, sign; BYTE b; fs->wflag = 0; fs->winsect = (LBA_t)0 - 1; /* Invaidate window */ if (move_window(fs, sect) != FR_OK) return 4; /* Load the boot sector */ sign = ld_word(fs->win + BS_55AA); #if FF_FS_EXFAT if (sign == 0xAA55 && !memcmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* It is an exFAT VBR */ #endif b = fs->win[BS_JmpBoot]; if (b == 0xEB || b == 0xE9 || b == 0xE8) { /* Valid JumpBoot code? (short jump, near jump or near call) */ if (sign == 0xAA55 && !memcmp(fs->win + BS_FilSysType32, "FAT32 ", 8)) { return 0; /* It is an FAT32 VBR */ } /* FAT volumes formatted with early MS-DOS lack BS_55AA and BS_FilSysType, so FAT VBR needs to be identified without them. */ w = ld_word(fs->win + BPB_BytsPerSec); b = fs->win[BPB_SecPerClus]; if ((w & (w - 1)) == 0 && w >= FF_MIN_SS && w <= FF_MAX_SS /* Properness of sector size (512-4096 and 2^n) */ && b != 0 && (b & (b - 1)) == 0 /* Properness of cluster size (2^n) */ && ld_word(fs->win + BPB_RsvdSecCnt) != 0 /* Properness of reserved sectors (MNBZ) */ && (UINT)fs->win[BPB_NumFATs] - 1 <= 1 /* Properness of FATs (1 or 2) */ && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root dir entries (MNBZ) */ && (ld_word(fs->win + BPB_TotSec16) >= 128 || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Properness of volume sectors (>=128) */ && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size (MNBZ) */ return 0; /* It can be presumed an FAT VBR */ } } return sign == 0xAA55 ? 2 : 3; /* Not an FAT VBR (valid or invalid BS) */ } /* Find an FAT volume */ /* (It supports only generic partitioning rules, MBR, GPT and SFD) */ static UINT find_volume ( /* Returns BS status found in the hosting drive */ FATFS* fs, /* Filesystem object */ UINT part /* Partition to fined = 0:find as SFD and partitions, >0:forced partition number */ ) { UINT fmt, i; DWORD mbr_pt[4]; fmt = check_fs(fs, 0); /* Load sector 0 and check if it is an FAT VBR as SFD format */ if (fmt != 2 && (fmt >= 3 || part == 0)) return fmt; /* Returns if it is an FAT VBR as auto scan, not a BS or disk error */ /* Sector 0 is not an FAT VBR or forced partition number wants a partition */ #if FF_LBA64 if (fs->win[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */ DWORD n_ent, v_ent, ofs; QWORD pt_lba; if (move_window(fs, 1) != FR_OK) return 4; /* Load GPT header sector (next to MBR) */ if (!test_gpt_header(fs->win)) return 3; /* Check if GPT header is valid */ n_ent = ld_dword(fs->win + GPTH_PtNum); /* Number of entries */ pt_lba = ld_qword(fs->win + GPTH_PtOfs); /* Table location */ for (v_ent = i = 0; i < n_ent; i++) { /* Find FAT partition */ if (move_window(fs, pt_lba + i * SZ_GPTE / SS(fs)) != FR_OK) return 4; /* PT sector */ ofs = i * SZ_GPTE % SS(fs); /* Offset in the sector */ if (!memcmp(fs->win + ofs + GPTE_PtGuid, GUID_MS_Basic, 16)) { /* MS basic data partition? */ v_ent++; fmt = check_fs(fs, ld_qword(fs->win + ofs + GPTE_FstLba)); /* Load VBR and check status */ if (part == 0 && fmt <= 1) return fmt; /* Auto search (valid FAT volume found first) */ if (part != 0 && v_ent == part) return fmt; /* Forced partition order (regardless of it is valid or not) */ } } return 3; /* Not found */ } #endif if (FF_MULTI_PARTITION && part > 4) return 3; /* MBR has 4 partitions max */ for (i = 0; i < 4; i++) { /* Load partition offset in the MBR */ mbr_pt[i] = ld_dword(fs->win + MBR_Table + i * SZ_PTE + PTE_StLba); } i = part ? part - 1 : 0; /* Table index to find first */ do { /* Find an FAT volume */ fmt = mbr_pt[i] ? check_fs(fs, mbr_pt[i]) : 3; /* Check if the partition is FAT */ } while (part == 0 && fmt >= 2 && ++i < 4); return fmt; } /*-----------------------------------------------------------------------*/ /* Determine logical drive number and mount the volume if needed */ /*-----------------------------------------------------------------------*/ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ FATFS** rfs, /* Pointer to pointer to the found filesystem object */ BYTE mode /* Desiered access mode to check write protection */ ) { int vol; FATFS *fs; DSTATUS stat; LBA_t bsect; DWORD tsect, sysect, fasize, nclst, szbfat; WORD nrsv; UINT fmt; /* Get logical drive number */ *rfs = 0; vol = get_ldnumber(path); if (vol < 0) return FR_INVALID_DRIVE; /* Check if the filesystem object is valid or not */ fs = FatFs[vol]; /* Get pointer to the filesystem object */ if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */ #if FF_FS_REENTRANT if (!lock_volume(fs, 1)) return FR_TIMEOUT; /* Lock the volume, and system if needed */ #endif *rfs = fs; /* Return pointer to the filesystem object */ mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ if (fs->fs_type != 0) { /* If the volume has been mounted */ stat = disk_status(fs->pdrv); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ return FR_WRITE_PROTECTED; } return FR_OK; /* The filesystem object is already valid */ } } /* The filesystem object is not valid. */ /* Following code attempts to mount the volume. (find an FAT volume, analyze the BPB and initialize the filesystem object) */ fs->fs_type = 0; /* Invalidate the filesystem object */ stat = disk_initialize(fs->pdrv); /* Initialize the volume hosting physical drive */ if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ } if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ return FR_WRITE_PROTECTED; } #if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */ if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR; if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; #endif /* Find an FAT volume on the hosting drive */ fmt = find_volume(fs, LD2PT(vol)); if (fmt == 4) return FR_DISK_ERR; /* An error occurred in the disk I/O layer */ if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ bsect = fs->winsect; /* Volume offset in the hosting physical drive */ /* An FAT volume is found (bsect). Following code initializes the filesystem object */ #if FF_FS_EXFAT if (fmt == 1) { QWORD maxlba; DWORD so, cv, bcl, i; for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ return FR_NO_FILESYSTEM; } maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA of the volume + 1 */ if (!FF_LBA64 && maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be accessed in 32-bit LBA) */ fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */ fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */ if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */ fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */ if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768 sectors) */ nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */ if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */ fs->n_fatent = nclst + 2; /* Boundaries and Limits */ fs->volbase = bsect; fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size required) */ fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); /* Get bitmap location and check if it is contiguous (implementation assumption) */ so = i = 0; for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */ if (i == 0) { if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */ if (move_window(fs, clst2sect(fs, (DWORD)fs->dirbase) + so) != FR_OK) return FR_DISK_ERR; so++; } if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */ i = (i + SZDIRE) % SS(fs); /* Next entry */ } bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; /* (Wrong cluster#) */ fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */ for (;;) { /* Check if bitmap is contiguous */ if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); if (cv == 0xFFFFFFFF) break; /* Last link? */ if (cv != ++bcl) return FR_NO_FILESYSTEM; /* Fragmented bitmap? */ } #if !FF_FS_READONLY fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ #endif fmt = FS_EXFAT; /* FAT sub-type */ } else #endif /* FF_FS_EXFAT */ { if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */ fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32); fs->fsize = fasize; fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ fasize *= fs->n_fats; /* Number of sectors for FAT area */ fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ /* Determine the FAT sub type */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ fmt = 0; if (nclst <= MAX_FAT32) fmt = FS_FAT32; if (nclst <= MAX_FAT16) fmt = FS_FAT16; if (nclst <= MAX_FAT12) fmt = FS_FAT12; if (fmt == 0) return FR_NO_FILESYSTEM; /* Boundaries and Limits */ fs->n_fatent = nclst + 2; /* Number of FAT entries */ fs->volbase = bsect; /* Volume start sector */ fs->fatbase = bsect + nrsv; /* FAT start sector */ fs->database = bsect + sysect; /* Data start sector */ if (fmt == FS_FAT32) { if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ } else { if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); } if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ #if !FF_FS_READONLY /* Get FSInfo if available */ fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ fs->fsi_flag = 0x80; #if (FF_FS_NOFSINFO & 3) != 3 if (fmt == FS_FAT32 /* Allow to update FSInfo only if BPB_FSInfo32 == 1 */ && ld_word(fs->win + BPB_FSInfo32) == 1 && move_window(fs, bsect + 1) == FR_OK) { fs->fsi_flag = 0; if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */ && ld_dword(fs->win + FSI_LeadSig) == 0x41615252 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272) { #if (FF_FS_NOFSINFO & 1) == 0 fs->free_clst = ld_dword(fs->win + FSI_Free_Count); #endif #if (FF_FS_NOFSINFO & 2) == 0 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free); #endif } } #endif /* (FF_FS_NOFSINFO & 3) != 3 */ #endif /* !FF_FS_READONLY */ } fs->fs_type = (BYTE)fmt;/* FAT sub-type (the filesystem object gets valid) */ fs->id = ++Fsid; /* Volume mount ID */ #if FF_USE_LFN == 1 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ #if FF_FS_EXFAT fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ #endif #endif #if FF_FS_RPATH != 0 fs->cdir = 0; /* Initialize current directory */ #endif #if FF_FS_LOCK /* Clear file lock semaphores */ clear_share(fs); #endif return FR_OK; } /*-----------------------------------------------------------------------*/ /* Check if the file/directory object is valid or not */ /*-----------------------------------------------------------------------*/ static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ FFOBJID* obj, /* Pointer to the FFOBJID, the 1st member in the FIL/DIR structure, to check validity */ FATFS** rfs /* Pointer to pointer to the owner filesystem object to return */ ) { FRESULT res = FR_INVALID_OBJECT; if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */ #if FF_FS_REENTRANT if (lock_volume(obj->fs, 0)) { /* Take a grant to access the volume */ if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting phsical drive is kept initialized */ res = FR_OK; } else { unlock_volume(obj->fs, FR_OK); /* Invalidated volume, abort to access */ } } else { /* Could not take */ res = FR_TIMEOUT; } #else if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the hosting phsical drive is kept initialized */ res = FR_OK; } #endif } *rfs = (res == FR_OK) ? obj->fs : 0; /* Return corresponding filesystem object if it is valid */ return res; } /*--------------------------------------------------------------------------- Public Functions (FatFs API) ----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/ /* Mount/Unmount a Logical Drive */ /*-----------------------------------------------------------------------*/ FRESULT f_mount ( FATFS* fs, /* Pointer to the filesystem object to be registered (NULL:unmount)*/ const TCHAR* path, /* Logical drive number to be mounted/unmounted */ BYTE opt /* Mount option: 0=Do not mount (delayed mount), 1=Mount immediately */ ) { FATFS *cfs; int vol; FRESULT res; const TCHAR *rp = path; /* Get volume ID (logical drive number) */ vol = get_ldnumber(&rp); if (vol < 0) return FR_INVALID_DRIVE; cfs = FatFs[vol]; /* Pointer to the filesystem object of the volume */ if (cfs) { /* Unregister current filesystem object if regsitered */ FatFs[vol] = 0; #if FF_FS_LOCK clear_share(cfs); #endif #if FF_FS_REENTRANT /* Discard mutex of the current volume */ ff_mutex_delete(vol); #endif cfs->fs_type = 0; /* Invalidate the filesystem object to be unregistered */ } if (fs) { /* Register new filesystem object */ fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */ #if FF_FS_REENTRANT /* Create a volume mutex */ fs->ldrv = (BYTE)vol; /* Owner volume ID */ if (!ff_mutex_create(vol)) return FR_INT_ERR; #if FF_FS_LOCK if (SysLock == 0) { /* Create a system mutex if needed */ if (!ff_mutex_create(FF_VOLUMES)) { ff_mutex_delete(vol); return FR_INT_ERR; } SysLock = 1; /* System mutex is ready */ } #endif #endif fs->fs_type = 0; /* Invalidate the new filesystem object */ FatFs[vol] = fs; /* Register new fs object */ } if (opt == 0) return FR_OK; /* Do not mount now, it will be mounted in subsequent file functions */ res = mount_volume(&path, &fs, 0); /* Force mounted the volume */ LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Open or Create a File */ /*-----------------------------------------------------------------------*/ FRESULT f_open ( FIL* fp, /* Pointer to the blank file object */ const TCHAR* path, /* Pointer to the file name */ BYTE mode /* Access mode and open mode flags */ ) { FRESULT res; DIR dj; FATFS *fs; #if !FF_FS_READONLY DWORD cl, bcs, clst, tm; LBA_t sc; FSIZE_t ofs; #endif DEF_NAMBUF if (!fp) return FR_INVALID_OBJECT; /* Get logical drive number */ mode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND; res = mount_volume(&path, &fs, mode); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ #if !FF_FS_READONLY /* Read/Write configuration */ if (res == FR_OK) { if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */ res = FR_INVALID_NAME; } #if FF_FS_LOCK else { res = chk_share(&dj, (mode & ~FA_READ) ? 1 : 0); /* Check if the file can be used */ } #endif } /* Create or Open a file */ if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { if (res != FR_OK) { /* No file, create new */ if (res == FR_NO_FILE) { /* There is no file to open, create a new entry */ #if FF_FS_LOCK res = enq_share() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; #else res = dir_register(&dj); #endif } mode |= FA_CREATE_ALWAYS; /* File is created */ } else { /* Any object with the same name is already existing */ if (dj.obj.attr & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ res = FR_DENIED; } else { if (mode & FA_CREATE_NEW) res = FR_EXIST; /* Cannot create as new file */ } } if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate the file if overwrite mode */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Get current allocation info */ fp->obj.fs = fs; init_alloc_info(fs, &fp->obj); /* Set directory entry block initial state */ memset(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */ memset(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */ fs->dirbuf[XDIR_Attr] = AM_ARC; st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME()); fs->dirbuf[XDIR_GenFlags] = 1; res = store_xdir(&dj); if (res == FR_OK && fp->obj.sclust != 0) { /* Remove the cluster chain if exist */ res = remove_chain(&fp->obj, fp->obj.sclust, 0); fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */ } } else #endif { /* Set directory entry initial state */ tm = GET_FATTIME(); /* Set created time */ st_dword(dj.dir + DIR_CrtTime, tm); st_dword(dj.dir + DIR_ModTime, tm); cl = ld_clust(fs, dj.dir); /* Get current cluster chain */ dj.dir[DIR_Attr] = AM_ARC; /* Reset attribute */ st_clust(fs, dj.dir, 0); /* Reset file allocation info */ st_dword(dj.dir + DIR_FileSize, 0); fs->wflag = 1; if (cl != 0) { /* Remove the cluster chain if exist */ sc = fs->winsect; res = remove_chain(&dj.obj, cl, 0); if (res == FR_OK) { res = move_window(fs, sc); fs->last_clst = cl - 1; /* Reuse the cluster hole */ } } } } } else { /* Open an existing file */ if (res == FR_OK) { /* Is the object exsiting? */ if (dj.obj.attr & AM_DIR) { /* File open against a directory */ res = FR_NO_FILE; } else { if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */ res = FR_DENIED; } } } } if (res == FR_OK) { if (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED; /* Set file change flag if created or overwritten */ fp->dir_sect = fs->winsect; /* Pointer to the directory entry */ fp->dir_ptr = dj.dir; #if FF_FS_LOCK fp->obj.lockid = inc_share(&dj, (mode & ~FA_READ) ? 1 : 0); /* Lock the file for this session */ if (fp->obj.lockid == 0) res = FR_INT_ERR; #endif } #else /* R/O configuration */ if (res == FR_OK) { if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it origin directory itself? */ res = FR_INVALID_NAME; } else { if (dj.obj.attr & AM_DIR) { /* Is it a directory? */ res = FR_NO_FILE; } } } #endif if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fp->obj.c_scl = dj.obj.sclust; /* Get containing directory info */ fp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; fp->obj.c_ofs = dj.blk_ofs; init_alloc_info(fs, &fp->obj); } else #endif { fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */ fp->obj.objsize = ld_dword(dj.dir + DIR_FileSize); } #if FF_USE_FASTSEEK fp->cltbl = 0; /* Disable fast seek mode */ #endif fp->obj.fs = fs; /* Validate the file object */ fp->obj.id = fs->id; fp->flag = mode; /* Set file access mode */ fp->err = 0; /* Clear error flag */ fp->sect = 0; /* Invalidate current data sector */ fp->fptr = 0; /* Set file pointer top of the file */ #if !FF_FS_READONLY #if !FF_FS_TINY memset(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ #endif if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ fp->fptr = fp->obj.objsize; /* Offset to seek */ bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */ clst = fp->obj.sclust; /* Follow the cluster chain */ for (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) { clst = get_fat(&fp->obj, clst); if (clst <= 1) res = FR_INT_ERR; if (clst == 0xFFFFFFFF) res = FR_DISK_ERR; } fp->clust = clst; if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */ sc = clst2sect(fs, clst); if (sc == 0) { res = FR_INT_ERR; } else { fp->sect = sc + (DWORD)(ofs / SS(fs)); #if !FF_FS_TINY if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR; #endif } } #if FF_FS_LOCK if (res != FR_OK) dec_share(fp->obj.lockid); /* Decrement file open counter if seek failed */ #endif } #endif } FREE_NAMBUF(); } if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */ LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Read File */ /*-----------------------------------------------------------------------*/ FRESULT f_read ( FIL* fp, /* Open file to be read */ void* buff, /* Data buffer to store the read data */ UINT btr, /* Number of bytes to read */ UINT* br /* Number of bytes read */ ) { FRESULT res; FATFS *fs; DWORD clst; LBA_t sect; FSIZE_t remain; UINT rcnt, cc, csect; BYTE *rbuff = (BYTE*)buff; *br = 0; /* Clear read byte counter */ res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ remain = fp->obj.objsize - fp->fptr; if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ for ( ; btr > 0; btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { /* Repeat until btr bytes read */ if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ if (csect == 0) { /* On the cluster boundary? */ if (fp->fptr == 0) { /* On the top of the file? */ clst = fp->obj.sclust; /* Follow cluster chain from the origin */ } else { /* Middle or end of the file */ #if FF_USE_FASTSEEK if (fp->cltbl) { clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ } else #endif { clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */ } } if (clst < 2) ABORT(fs, FR_INT_ERR); if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); fp->clust = clst; /* Update current cluster */ } sect = clst2sect(fs, fp->clust); /* Get current sector */ if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btr / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Read maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); #if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ #if FF_FS_TINY if (fs->wflag && fs->winsect - sect < cc) { memcpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs)); } #else if ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) { memcpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs)); } #endif #endif rcnt = SS(fs) * cc; /* Number of bytes transferred */ continue; } #if !FF_FS_TINY if (fp->sect != sect) { /* Load data sector if not in cache */ #if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ } #endif fp->sect = sect; } rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */ #if FF_FS_TINY if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ memcpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ #else memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ #endif } LEAVE_FF(fs, FR_OK); } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Write File */ /*-----------------------------------------------------------------------*/ FRESULT f_write ( FIL* fp, /* Open file to be written */ const void* buff, /* Data to be written */ UINT btw, /* Number of bytes to write */ UINT* bw /* Number of bytes written */ ) { FRESULT res; FATFS *fs; DWORD clst; LBA_t sect; UINT wcnt, cc, csect; const BYTE *wbuff = (const BYTE*)buff; *bw = 0; /* Clear write byte counter */ res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr); } for ( ; btw > 0; btw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) { /* Repeat until all data written */ if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */ if (csect == 0) { /* On the cluster boundary? */ if (fp->fptr == 0) { /* On the top of the file? */ clst = fp->obj.sclust; /* Follow from the origin */ if (clst == 0) { /* If no cluster is allocated, */ clst = create_chain(&fp->obj, 0); /* create a new cluster chain */ } } else { /* On the middle or end of the file */ #if FF_USE_FASTSEEK if (fp->cltbl) { clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ } else #endif { clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */ } } if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ if (clst == 1) ABORT(fs, FR_INT_ERR); if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); fp->clust = clst; /* Update current cluster */ if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */ } #if FF_FS_TINY if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ #else if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif sect = clst2sect(fs, fp->clust); /* Get current sector */ if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btw / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Write maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); #if FF_FS_MINIMIZE <= 2 #if FF_FS_TINY if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ memcpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs)); fs->wflag = 0; } #else if (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ memcpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs)); fp->flag &= (BYTE)~FA_DIRTY; } #endif #endif wcnt = SS(fs) * cc; /* Number of bytes transferred */ continue; } #if FF_FS_TINY if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */ if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); fs->winsect = sect; } #else if (fp->sect != sect && /* Fill sector cache with file data */ fp->fptr < fp->obj.objsize && disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) { ABORT(fs, FR_DISK_ERR); } #endif fp->sect = sect; } wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ if (wcnt > btw) wcnt = btw; /* Clip it by btw if needed */ #if FF_FS_TINY if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ memcpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ fs->wflag = 1; #else memcpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ fp->flag |= FA_DIRTY; #endif } fp->flag |= FA_MODIFIED; /* Set file change flag */ LEAVE_FF(fs, FR_OK); } /*-----------------------------------------------------------------------*/ /* Synchronize the File */ /*-----------------------------------------------------------------------*/ FRESULT f_sync ( FIL* fp /* Open file to be synced */ ) { FRESULT res; FATFS *fs; DWORD tm; BYTE *dir; res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */ #if !FF_FS_TINY if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif /* Update the directory entry */ tm = GET_FATTIME(); /* Modified time */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { res = fill_first_frag(&fp->obj); /* Fill first fragment on the FAT if needed */ if (res == FR_OK) { res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ } if (res == FR_OK) { DIR dj; DEF_NAMBUF INIT_NAMBUF(fs); res = load_obj_xdir(&dj, &fp->obj); /* Load directory entry block */ if (res == FR_OK) { fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */ st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); /* Update start cluster */ st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); /* Update file size */ st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); /* (FatFs does not support Valid File Size feature) */ st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */ fs->dirbuf[XDIR_ModTime10] = 0; st_dword(fs->dirbuf + XDIR_AccTime, 0); res = store_xdir(&dj); /* Restore it to the directory */ if (res == FR_OK) { res = sync_fs(fs); fp->flag &= (BYTE)~FA_MODIFIED; } } FREE_NAMBUF(); } } else #endif { res = move_window(fs, fp->dir_sect); if (res == FR_OK) { dir = fp->dir_ptr; dir[DIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */ st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize); /* Update file size */ st_dword(dir + DIR_ModTime, tm); /* Update modified time */ st_word(dir + DIR_LstAccDate, 0); fs->wflag = 1; res = sync_fs(fs); /* Restore it to the directory */ fp->flag &= (BYTE)~FA_MODIFIED; } } } } LEAVE_FF(fs, res); } #endif /* !FF_FS_READONLY */ /*-----------------------------------------------------------------------*/ /* Close File */ /*-----------------------------------------------------------------------*/ FRESULT f_close ( FIL* fp /* Open file to be closed */ ) { FRESULT res; FATFS *fs; #if !FF_FS_READONLY res = f_sync(fp); /* Flush cached data */ if (res == FR_OK) #endif { res = validate(&fp->obj, &fs); /* Lock volume */ if (res == FR_OK) { #if FF_FS_LOCK res = dec_share(fp->obj.lockid); /* Decrement file open counter */ if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */ #else fp->obj.fs = 0; /* Invalidate file object */ #endif #if FF_FS_REENTRANT unlock_volume(fs, FR_OK); /* Unlock volume */ #endif } } return res; } #if FF_FS_RPATH >= 1 /*-----------------------------------------------------------------------*/ /* Change Current Directory or Current Drive, Get Current Directory */ /*-----------------------------------------------------------------------*/ FRESULT f_chdrive ( const TCHAR* path /* Drive number to set */ ) { int vol; /* Get logical drive number */ vol = get_ldnumber(&path); if (vol < 0) return FR_INVALID_DRIVE; CurrVol = (BYTE)vol; /* Set it as current volume */ return FR_OK; } FRESULT f_chdir ( const TCHAR* path /* Pointer to the directory path */ ) { #if FF_STR_VOLUME_ID == 2 UINT i; #endif FRESULT res; DIR dj; FATFS *fs; DEF_NAMBUF /* Get logical drive */ res = mount_volume(&path, &fs, 0); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the path */ if (res == FR_OK) { /* Follow completed */ if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it the start directory itself? */ fs->cdir = dj.obj.sclust; #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->cdc_scl = dj.obj.c_scl; fs->cdc_size = dj.obj.c_size; fs->cdc_ofs = dj.obj.c_ofs; } #endif } else { if (dj.obj.attr & AM_DIR) { /* It is a sub-directory */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */ fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */ fs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; fs->cdc_ofs = dj.blk_ofs; } else #endif { fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */ } } else { res = FR_NO_PATH; /* Reached but a file */ } } } FREE_NAMBUF(); if (res == FR_NO_FILE) res = FR_NO_PATH; #if FF_STR_VOLUME_ID == 2 /* Also current drive is changed if in Unix style volume ID */ if (res == FR_OK) { for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */ CurrVol = (BYTE)i; } #endif } LEAVE_FF(fs, res); } #if FF_FS_RPATH >= 2 FRESULT f_getcwd ( TCHAR* buff, /* Pointer to the directory path */ UINT len /* Size of buff in unit of TCHAR */ ) { FRESULT res; DIR dj; FATFS *fs; UINT i, n; DWORD ccl; TCHAR *tp = buff; #if FF_VOLUMES >= 2 UINT vl; #if FF_STR_VOLUME_ID const char *vp; #endif #endif FILINFO fno; DEF_NAMBUF /* Get logical drive */ buff[0] = 0; /* Set null string to get current volume */ res = mount_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); /* Follow parent directories and create the path */ i = len; /* Bottom of buffer (directory stack base) */ if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path) */ dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */ while ((ccl = dj.obj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ res = dir_sdi(&dj, 1 * SZDIRE); /* Get parent directory */ if (res != FR_OK) break; res = move_window(fs, dj.sect); if (res != FR_OK) break; dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */ res = dir_sdi(&dj, 0); if (res != FR_OK) break; do { /* Find the entry links to the child directory */ res = DIR_READ_FILE(&dj); if (res != FR_OK) break; if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ res = dir_next(&dj, 0); } while (res == FR_OK); if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ if (res != FR_OK) break; get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ for (n = 0; fno.fname[n]; n++) ; /* Name length */ if (i < n + 1) { /* Insufficient space to store the path name? */ res = FR_NOT_ENOUGH_CORE; break; } while (n) buff[--i] = fno.fname[--n]; /* Stack the name */ buff[--i] = '/'; } } if (res == FR_OK) { if (i == len) buff[--i] = '/'; /* Is it the root-directory? */ #if FF_VOLUMES >= 2 /* Put drive prefix */ vl = 0; #if FF_STR_VOLUME_ID >= 1 /* String volume ID */ for (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ; if (i >= n + 2) { if (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/'; for (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ; if (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':'; vl++; } #else /* Numeric volume ID */ if (i >= 3) { *tp++ = (TCHAR)'0' + CurrVol; *tp++ = (TCHAR)':'; vl = 2; } #endif if (vl == 0) res = FR_NOT_ENOUGH_CORE; #endif /* Add current directory path */ if (res == FR_OK) { do { /* Copy stacked path string */ *tp++ = buff[i++]; } while (i < len); } } FREE_NAMBUF(); } *tp = 0; LEAVE_FF(fs, res); } #endif /* FF_FS_RPATH >= 2 */ #endif /* FF_FS_RPATH >= 1 */ #if FF_FS_MINIMIZE <= 2 /*-----------------------------------------------------------------------*/ /* Seek File Read/Write Pointer */ /*-----------------------------------------------------------------------*/ FRESULT f_lseek ( FIL* fp, /* Pointer to the file object */ FSIZE_t ofs /* File pointer from top of file */ ) { FRESULT res; FATFS *fs; DWORD clst, bcs; LBA_t nsect; FSIZE_t ifptr; #if FF_USE_FASTSEEK DWORD cl, pcl, ncl, tcl, tlen, ulen; DWORD *tbl; LBA_t dsc; #endif res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) res = (FRESULT)fp->err; #if FF_FS_EXFAT && !FF_FS_READONLY if (res == FR_OK && fs->fs_type == FS_EXFAT) { res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ } #endif if (res != FR_OK) LEAVE_FF(fs, res); #if FF_USE_FASTSEEK if (fp->cltbl) { /* Fast seek */ if (ofs == CREATE_LINKMAP) { /* Create CLMT */ tbl = fp->cltbl; tlen = *tbl++; ulen = 2; /* Given table size and required table size */ cl = fp->obj.sclust; /* Origin of the chain */ if (cl != 0) { do { /* Get a fragment */ tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ do { pcl = cl; ncl++; cl = get_fat(&fp->obj, cl); if (cl <= 1) ABORT(fs, FR_INT_ERR); if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); } while (cl == pcl + 1); if (ulen <= tlen) { /* Store the length and top of the fragment */ *tbl++ = ncl; *tbl++ = tcl; } } while (cl < fs->n_fatent); /* Repeat until end of chain */ } *fp->cltbl = ulen; /* Number of items used */ if (ulen <= tlen) { *tbl = 0; /* Terminate table */ } else { res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ } } else { /* Fast seek */ if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; /* Clip offset at the file size */ fp->fptr = ofs; /* Set file pointer */ if (ofs > 0) { fp->clust = clmt_clust(fp, ofs - 1); dsc = clst2sect(fs, fp->clust); if (dsc == 0) ABORT(fs, FR_INT_ERR); dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1); if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */ #if !FF_FS_TINY #if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ #endif fp->sect = dsc; } } } } else #endif /* Normal Seek */ { #if FF_FS_EXFAT if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FATxx */ #endif if (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ ofs = fp->obj.objsize; } ifptr = fp->fptr; fp->fptr = nsect = 0; if (ofs > 0) { bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */ if (ifptr > 0 && (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1); /* start from the current cluster */ ofs -= fp->fptr; clst = fp->clust; } else { /* When seek to back cluster, */ clst = fp->obj.sclust; /* start from the first cluster */ #if !FF_FS_READONLY if (clst == 0) { /* If no cluster chain, create a new chain */ clst = create_chain(&fp->obj, 0); if (clst == 1) ABORT(fs, FR_INT_ERR); if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); fp->obj.sclust = clst; } #endif fp->clust = clst; } if (clst != 0) { while (ofs > bcs) { /* Cluster following loop */ ofs -= bcs; fp->fptr += bcs; #if !FF_FS_READONLY if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ if (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ fp->obj.objsize = fp->fptr; fp->flag |= FA_MODIFIED; } clst = create_chain(&fp->obj, clst); /* Follow chain with forceed stretch */ if (clst == 0) { /* Clip file size in case of disk full */ ofs = 0; break; } } else #endif { clst = get_fat(&fp->obj, clst); /* Follow cluster chain if not in write mode */ } if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR); fp->clust = clst; } fp->fptr += ofs; if (ofs % SS(fs)) { nsect = clst2sect(fs, clst); /* Current sector */ if (nsect == 0) ABORT(fs, FR_INT_ERR); nsect += (DWORD)(ofs / SS(fs)); } } } if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ fp->obj.objsize = fp->fptr; fp->flag |= FA_MODIFIED; } if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */ #if !FF_FS_TINY #if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ #endif fp->sect = nsect; } } LEAVE_FF(fs, res); } #if FF_FS_MINIMIZE <= 1 /*-----------------------------------------------------------------------*/ /* Create a Directory Object */ /*-----------------------------------------------------------------------*/ FRESULT f_opendir ( DIR* dp, /* Pointer to directory object to create */ const TCHAR* path /* Pointer to the directory path */ ) { FRESULT res; FATFS *fs; DEF_NAMBUF if (!dp) return FR_INVALID_OBJECT; /* Get logical drive */ res = mount_volume(&path, &fs, 0); if (res == FR_OK) { dp->obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(dp, path); /* Follow the path to the directory */ if (res == FR_OK) { /* Follow completed */ if (!(dp->fn[NSFLAG] & NS_NONAME)) { /* It is not the origin directory itself */ if (dp->obj.attr & AM_DIR) { /* This object is a sub-directory */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { dp->obj.c_scl = dp->obj.sclust; /* Get containing directory inforamation */ dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; dp->obj.c_ofs = dp->blk_ofs; init_alloc_info(fs, &dp->obj); /* Get object allocation info */ } else #endif { dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */ } } else { /* This object is a file */ res = FR_NO_PATH; } } if (res == FR_OK) { dp->obj.id = fs->id; res = dir_sdi(dp, 0); /* Rewind directory */ #if FF_FS_LOCK if (res == FR_OK) { if (dp->obj.sclust != 0) { dp->obj.lockid = inc_share(dp, 0); /* Lock the sub directory */ if (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES; } else { dp->obj.lockid = 0; /* Root directory need not to be locked */ } } #endif } } FREE_NAMBUF(); if (res == FR_NO_FILE) res = FR_NO_PATH; } if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function failed */ LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Close Directory */ /*-----------------------------------------------------------------------*/ FRESULT f_closedir ( DIR *dp /* Pointer to the directory object to be closed */ ) { FRESULT res; FATFS *fs; res = validate(&dp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { #if FF_FS_LOCK if (dp->obj.lockid) res = dec_share(dp->obj.lockid); /* Decrement sub-directory open counter */ if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */ #else dp->obj.fs = 0; /* Invalidate directory object */ #endif #if FF_FS_REENTRANT unlock_volume(fs, FR_OK); /* Unlock volume */ #endif } return res; } /*-----------------------------------------------------------------------*/ /* Read Directory Entries in Sequence */ /*-----------------------------------------------------------------------*/ FRESULT f_readdir ( DIR* dp, /* Pointer to the open directory object */ FILINFO* fno /* Pointer to file information to return */ ) { FRESULT res; FATFS *fs; DEF_NAMBUF res = validate(&dp->obj, &fs); /* Check validity of the directory object */ if (res == FR_OK) { if (!fno) { res = dir_sdi(dp, 0); /* Rewind the directory object */ } else { INIT_NAMBUF(fs); res = DIR_READ_FILE(dp); /* Read an item */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ if (res == FR_OK) { /* A valid entry is found */ get_fileinfo(dp, fno); /* Get the object information */ res = dir_next(dp, 0); /* Increment index for next */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */ } FREE_NAMBUF(); } } LEAVE_FF(fs, res); } #if FF_USE_FIND /*-----------------------------------------------------------------------*/ /* Find Next File */ /*-----------------------------------------------------------------------*/ FRESULT f_findnext ( DIR* dp, /* Pointer to the open directory object */ FILINFO* fno /* Pointer to the file information structure */ ) { FRESULT res; for (;;) { res = f_readdir(dp, fno); /* Get a directory item */ if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */ if (pattern_match(dp->pat, fno->fname, 0, FIND_RECURS)) break; /* Test for the file name */ #if FF_USE_LFN && FF_USE_FIND == 2 if (pattern_match(dp->pat, fno->altname, 0, FIND_RECURS)) break; /* Test for alternative name if exist */ #endif } return res; } /*-----------------------------------------------------------------------*/ /* Find First File */ /*-----------------------------------------------------------------------*/ FRESULT f_findfirst ( DIR* dp, /* Pointer to the blank directory object */ FILINFO* fno, /* Pointer to the file information structure */ const TCHAR* path, /* Pointer to the directory to open */ const TCHAR* pattern /* Pointer to the matching pattern */ ) { FRESULT res; dp->pat = pattern; /* Save pointer to pattern string */ res = f_opendir(dp, path); /* Open the target directory */ if (res == FR_OK) { res = f_findnext(dp, fno); /* Find the first item */ } return res; } #endif /* FF_USE_FIND */ #if FF_FS_MINIMIZE == 0 /*-----------------------------------------------------------------------*/ /* Get File Status */ /*-----------------------------------------------------------------------*/ FRESULT f_stat ( const TCHAR* path, /* Pointer to the file path */ FILINFO* fno /* Pointer to file information to return */ ) { FRESULT res; DIR dj; DEF_NAMBUF /* Get logical drive */ res = mount_volume(&path, &dj.obj.fs, 0); if (res == FR_OK) { INIT_NAMBUF(dj.obj.fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK) { /* Follow completed */ if (dj.fn[NSFLAG] & NS_NONAME) { /* It is origin directory */ res = FR_INVALID_NAME; } else { /* Found an object */ if (fno) get_fileinfo(&dj, fno); } } FREE_NAMBUF(); } LEAVE_FF(dj.obj.fs, res); } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Get Number of Free Clusters */ /*-----------------------------------------------------------------------*/ FRESULT f_getfree ( const TCHAR* path, /* Logical drive number */ DWORD* nclst, /* Pointer to a variable to return number of free clusters */ FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */ ) { FRESULT res; FATFS *fs; DWORD nfree, clst, stat; LBA_t sect; UINT i; FFOBJID obj; /* Get logical drive */ res = mount_volume(&path, &fs, 0); if (res == FR_OK) { *fatfs = fs; /* Return ptr to the fs object */ /* If free_clst is valid, return it without full FAT scan */ if (fs->free_clst <= fs->n_fatent - 2) { *nclst = fs->free_clst; } else { /* Scan FAT to obtain number of free clusters */ nfree = 0; if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ clst = 2; obj.fs = fs; do { stat = get_fat(&obj, clst); if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } if (stat == 1) { res = FR_INT_ERR; break; } if (stat == 0) nfree++; } while (++clst < fs->n_fatent); } else { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */ BYTE bm; UINT b; clst = fs->n_fatent - 2; /* Number of clusters */ sect = fs->bitbase; /* Bitmap sector */ i = 0; /* Offset in the sector */ do { /* Counts numbuer of bits with zero in the bitmap */ if (i == 0) { /* New sector? */ res = move_window(fs, sect++); if (res != FR_OK) break; } for (b = 8, bm = ~fs->win[i]; b && clst; b--, clst--) { nfree += bm & 1; bm >>= 1; } i = (i + 1) % SS(fs); } while (clst); } else #endif { /* FAT16/32: Scan WORD/DWORD FAT entries */ clst = fs->n_fatent; /* Number of entries */ sect = fs->fatbase; /* Top of the FAT */ i = 0; /* Offset in the sector */ do { /* Counts numbuer of entries with zero in the FAT */ if (i == 0) { /* New sector? */ res = move_window(fs, sect++); if (res != FR_OK) break; } if (fs->fs_type == FS_FAT16) { if (ld_word(fs->win + i) == 0) nfree++; i += 2; } else { if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; i += 4; } i %= SS(fs); } while (--clst); } } if (res == FR_OK) { /* Update parameters if succeeded */ *nclst = nfree; /* Return the free clusters */ fs->free_clst = nfree; /* Now free_clst is valid */ fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ } } } LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Truncate File */ /*-----------------------------------------------------------------------*/ FRESULT f_truncate ( FIL* fp /* Pointer to the file object */ ) { FRESULT res; FATFS *fs; DWORD ncl; res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ if (fp->fptr < fp->obj.objsize) { /* Process when fptr is not on the eof */ if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ res = remove_chain(&fp->obj, fp->obj.sclust, 0); fp->obj.sclust = 0; } else { /* When truncate a part of the file, remove remaining clusters */ ncl = get_fat(&fp->obj, fp->clust); res = FR_OK; if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; if (ncl == 1) res = FR_INT_ERR; if (res == FR_OK && ncl < fs->n_fatent) { res = remove_chain(&fp->obj, ncl, fp->clust); } } fp->obj.objsize = fp->fptr; /* Set file size to current read/write point */ fp->flag |= FA_MODIFIED; #if !FF_FS_TINY if (res == FR_OK && (fp->flag & FA_DIRTY)) { if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) { res = FR_DISK_ERR; } else { fp->flag &= (BYTE)~FA_DIRTY; } } #endif if (res != FR_OK) ABORT(fs, res); } LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Delete a File/Directory */ /*-----------------------------------------------------------------------*/ FRESULT f_unlink ( const TCHAR* path /* Pointer to the file or directory path */ ) { FRESULT res; FATFS *fs; DIR dj, sdj; DWORD dclst = 0; #if FF_FS_EXFAT FFOBJID obj; #endif DEF_NAMBUF /* Get logical drive */ res = mount_volume(&path, &fs, FA_WRITE); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) { res = FR_INVALID_NAME; /* Cannot remove dot entry */ } #if FF_FS_LOCK if (res == FR_OK) res = chk_share(&dj, 2); /* Check if it is an open object */ #endif if (res == FR_OK) { /* The object is accessible */ if (dj.fn[NSFLAG] & NS_NONAME) { res = FR_INVALID_NAME; /* Cannot remove the origin directory */ } else { if (dj.obj.attr & AM_RDO) { res = FR_DENIED; /* Cannot remove R/O object */ } } if (res == FR_OK) { #if FF_FS_EXFAT obj.fs = fs; if (fs->fs_type == FS_EXFAT) { init_alloc_info(fs, &obj); dclst = obj.sclust; } else #endif { dclst = ld_clust(fs, dj.dir); } if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory? */ #if FF_FS_RPATH != 0 if (dclst == fs->cdir) { /* Is it the current directory? */ res = FR_DENIED; } else #endif { sdj.obj.fs = fs; /* Open the sub-directory */ sdj.obj.sclust = dclst; #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { sdj.obj.objsize = obj.objsize; sdj.obj.stat = obj.stat; } #endif res = dir_sdi(&sdj, 0); if (res == FR_OK) { res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */ if (res == FR_OK) res = FR_DENIED; /* Not empty? */ if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ } } } } if (res == FR_OK) { res = dir_remove(&dj); /* Remove the directory entry */ if (res == FR_OK && dclst != 0) { /* Remove the cluster chain if exist */ #if FF_FS_EXFAT res = remove_chain(&obj, dclst, 0); #else res = remove_chain(&dj.obj, dclst, 0); #endif } if (res == FR_OK) res = sync_fs(fs); } } FREE_NAMBUF(); } LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Create a Directory */ /*-----------------------------------------------------------------------*/ FRESULT f_mkdir ( const TCHAR* path /* Pointer to the directory path */ ) { FRESULT res; FATFS *fs; DIR dj; FFOBJID sobj; DWORD dcl, pcl, tm; DEF_NAMBUF res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK) res = FR_EXIST; /* Name collision? */ if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */ res = FR_INVALID_NAME; } if (res == FR_NO_FILE) { /* It is clear to create a new directory */ sobj.fs = fs; /* New object id to create a new chain */ dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ res = FR_OK; if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */ if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */ if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */ tm = GET_FATTIME(); if (res == FR_OK) { res = dir_clear(fs, dcl); /* Clean up the new table */ if (res == FR_OK) { if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */ memset(fs->win + DIR_Name, ' ', 11); /* Create "." entry */ fs->win[DIR_Name] = '.'; fs->win[DIR_Attr] = AM_DIR; st_dword(fs->win + DIR_ModTime, tm); st_clust(fs, fs->win, dcl); memcpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */ fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; st_clust(fs, fs->win + SZDIRE, pcl); fs->wflag = 1; } res = dir_register(&dj); /* Register the object to the parent directoy */ } } if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */ st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */ st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */ st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* Directory size needs to be valid */ st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs)); fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */ fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */ res = store_xdir(&dj); } else #endif { st_dword(dj.dir + DIR_ModTime, tm); /* Created time */ st_clust(fs, dj.dir, dcl); /* Table start cluster */ dj.dir[DIR_Attr] = AM_DIR; /* Attribute */ fs->wflag = 1; } if (res == FR_OK) { res = sync_fs(fs); } } else { remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */ } } FREE_NAMBUF(); } LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Rename a File/Directory */ /*-----------------------------------------------------------------------*/ FRESULT f_rename ( const TCHAR* path_old, /* Pointer to the object name to be renamed */ const TCHAR* path_new /* Pointer to the new name */ ) { FRESULT res; FATFS *fs; DIR djo, djn; BYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir; LBA_t sect; DEF_NAMBUF get_ldnumber(&path_new); /* Snip the drive number of new name off */ res = mount_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */ if (res == FR_OK) { djo.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&djo, path_old); /* Check old object */ if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check validity of name */ #if FF_FS_LOCK if (res == FR_OK) { res = chk_share(&djo, 2); } #endif if (res == FR_OK) { /* Object to be renamed is found */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */ BYTE nf, nn; WORD nh; memcpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */ memcpy(&djn, &djo, sizeof djo); res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ if (res == FR_OK) { /* Is new name already in use by any other object? */ res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; } if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName]; nh = ld_word(fs->dirbuf + XDIR_NameHash); memcpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */ fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn; st_word(fs->dirbuf + XDIR_NameHash, nh); if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ /* Start of critical section where an interruption can cause a cross-link */ res = store_xdir(&djn); } } } else #endif { /* At FAT/FAT32 volume */ memcpy(buf, djo.dir, SZDIRE); /* Save directory entry of the object */ memcpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ if (res == FR_OK) { /* Is new name already in use by any other object? */ res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; } if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { dir = djn.dir; /* Copy directory entry of the object except name */ memcpy(dir + 13, buf + 13, SZDIRE - 13); dir[DIR_Attr] = buf[DIR_Attr]; if (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ fs->wflag = 1; if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) { /* Update .. entry in the sub-directory if needed */ sect = clst2sect(fs, ld_clust(fs, dir)); if (sect == 0) { res = FR_INT_ERR; } else { /* Start of critical section where an interruption can cause a cross-link */ res = move_window(fs, sect); dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */ if (res == FR_OK && dir[1] == '.') { st_clust(fs, dir, djn.obj.sclust); fs->wflag = 1; } } } } } } if (res == FR_OK) { res = dir_remove(&djo); /* Remove old entry */ if (res == FR_OK) { res = sync_fs(fs); } } /* End of the critical section */ } FREE_NAMBUF(); } LEAVE_FF(fs, res); } #endif /* !FF_FS_READONLY */ #endif /* FF_FS_MINIMIZE == 0 */ #endif /* FF_FS_MINIMIZE <= 1 */ #endif /* FF_FS_MINIMIZE <= 2 */ #if FF_USE_CHMOD && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Change Attribute */ /*-----------------------------------------------------------------------*/ FRESULT f_chmod ( const TCHAR* path, /* Pointer to the file path */ BYTE attr, /* Attribute bits */ BYTE mask /* Attribute mask to change */ ) { FRESULT res; FATFS *fs; DIR dj; DEF_NAMBUF res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ if (res == FR_OK) { mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute change */ res = store_xdir(&dj); } else #endif { dj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ fs->wflag = 1; } if (res == FR_OK) { res = sync_fs(fs); } } FREE_NAMBUF(); } LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ /* Change Timestamp */ /*-----------------------------------------------------------------------*/ FRESULT f_utime ( const TCHAR* path, /* Pointer to the file/directory name */ const FILINFO* fno /* Pointer to the timestamp to be set */ ) { FRESULT res; FATFS *fs; DIR dj; DEF_NAMBUF res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); res = store_xdir(&dj); } else #endif { st_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); fs->wflag = 1; } if (res == FR_OK) { res = sync_fs(fs); } } FREE_NAMBUF(); } LEAVE_FF(fs, res); } #endif /* FF_USE_CHMOD && !FF_FS_READONLY */ #if FF_USE_LABEL /*-----------------------------------------------------------------------*/ /* Get Volume Label */ /*-----------------------------------------------------------------------*/ FRESULT f_getlabel ( const TCHAR* path, /* Logical drive number */ TCHAR* label, /* Buffer to store the volume label */ DWORD* vsn /* Variable to store the volume serial number */ ) { FRESULT res; FATFS *fs; DIR dj; UINT si, di; WCHAR wc; /* Get logical drive */ res = mount_volume(&path, &fs, 0); /* Get volume label */ if (res == FR_OK && label) { dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { res = DIR_READ_LABEL(&dj); /* Find a volume label entry */ if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { WCHAR hs; UINT nw; for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */ wc = ld_word(dj.dir + XDIR_Label + si * 2); if (hs == 0 && IsSurrogate(wc)) { /* Is the code a surrogate? */ hs = wc; continue; } nw = put_utf((DWORD)hs << 16 | wc, &label[di], 4); /* Store it in API encoding */ if (nw == 0) { /* Encode error? */ di = 0; break; } di += nw; hs = 0; } if (hs != 0) di = 0; /* Broken surrogate pair? */ label[di] = 0; } else #endif { si = di = 0; /* Extract volume label from AM_VOL entry */ while (si < 11) { wc = dj.dir[si++]; #if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode output */ if (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++]; /* Is it a DBC? */ wc = ff_oem2uni(wc, CODEPAGE); /* Convert it into Unicode */ if (wc == 0) { /* Invalid char in current code page? */ di = 0; break; } di += put_utf(wc, &label[di], 4); /* Store it in Unicode */ #else /* ANSI/OEM output */ label[di++] = (TCHAR)wc; #endif } do { /* Truncate trailing spaces */ label[di] = 0; if (di == 0) break; } while (label[--di] == ' '); } } } if (res == FR_NO_FILE) { /* No label entry and return nul string */ label[0] = 0; res = FR_OK; } } /* Get volume serial number */ if (res == FR_OK && vsn) { res = move_window(fs, fs->volbase); if (res == FR_OK) { switch (fs->fs_type) { case FS_EXFAT: di = BPB_VolIDEx; break; case FS_FAT32: di = BS_VolID32; break; default: di = BS_VolID; } *vsn = ld_dword(fs->win + di); } } LEAVE_FF(fs, res); } #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Set Volume Label */ /*-----------------------------------------------------------------------*/ FRESULT f_setlabel ( const TCHAR* label /* Volume label to set with heading logical drive number */ ) { FRESULT res; FATFS *fs; DIR dj; BYTE dirvn[22]; UINT di; WCHAR wc; static const char badchr[18] = "+.,;=[]" "/*:<>|\\\"\?\x7F"; /* [0..16] for FAT, [7..16] for exFAT */ #if FF_USE_LFN DWORD dc; #endif /* Get logical drive */ res = mount_volume(&label, &fs, FA_WRITE); if (res != FR_OK) LEAVE_FF(fs, res); #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ memset(dirvn, 0, 22); di = 0; while ((UINT)*label >= ' ') { /* Create volume label */ dc = tchar2uni(&label); /* Get a Unicode character */ if (dc >= 0x10000) { if (dc == 0xFFFFFFFF || di >= 10) { /* Wrong surrogate or buffer overflow */ dc = 0; } else { st_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++; } } if (dc == 0 || strchr(&badchr[7], (int)dc) || di >= 11) { /* Check validity of the volume label */ LEAVE_FF(fs, FR_INVALID_NAME); } st_word(dirvn + di * 2, (WCHAR)dc); di++; } } else #endif { /* On the FAT/FAT32 volume */ memset(dirvn, ' ', 11); di = 0; while ((UINT)*label >= ' ') { /* Create volume label */ #if FF_USE_LFN dc = tchar2uni(&label); wc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0; #else /* ANSI/OEM input */ wc = (BYTE)*label++; if (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0; if (IsLower(wc)) wc -= 0x20; /* To upper ASCII characters */ #if FF_CODE_PAGE == 0 if (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ #elif FF_CODE_PAGE < 900 if (wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ #endif #endif if (wc == 0 || strchr(&badchr[0], (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) { /* Reject invalid characters for volume label */ LEAVE_FF(fs, FR_INVALID_NAME); } if (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8); dirvn[di++] = (BYTE)wc; } if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ while (di && dirvn[di - 1] == ' ') di--; /* Snip trailing spaces */ } /* Set volume label */ dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { res = DIR_READ_LABEL(&dj); /* Get volume label entry */ if (res == FR_OK) { if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ memcpy(dj.dir + XDIR_Label, dirvn, 22); } else { if (di != 0) { memcpy(dj.dir, dirvn, 11); /* Change the volume label */ } else { dj.dir[DIR_Name] = DDEM; /* Remove the volume label */ } } fs->wflag = 1; res = sync_fs(fs); } else { /* No volume label entry or an error */ if (res == FR_NO_FILE) { res = FR_OK; if (di != 0) { /* Create a volume label entry */ res = dir_alloc(&dj, 1); /* Allocate an entry */ if (res == FR_OK) { memset(dj.dir, 0, SZDIRE); /* Clean the entry */ if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */ dj.dir[XDIR_NumLabel] = (BYTE)di; memcpy(dj.dir + XDIR_Label, dirvn, 22); } else { dj.dir[DIR_Attr] = AM_VOL; /* Create volume label entry */ memcpy(dj.dir, dirvn, 11); } fs->wflag = 1; res = sync_fs(fs); } } } } } LEAVE_FF(fs, res); } #endif /* !FF_FS_READONLY */ #endif /* FF_USE_LABEL */ #if FF_USE_EXPAND && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Allocate a Contiguous Blocks to the File */ /*-----------------------------------------------------------------------*/ FRESULT f_expand ( FIL* fp, /* Pointer to the file object */ FSIZE_t fsz, /* File size to be expanded to */ BYTE opt /* Operation mode 0:Find and prepare or 1:Find and allocate */ ) { FRESULT res; FATFS *fs; DWORD n, clst, stcl, scl, ncl, tcl, lclst; res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); #if FF_FS_EXFAT if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size limit */ #endif n = (DWORD)fs->csize * SS(fs); /* Cluster size */ tcl = (DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0); /* Number of clusters required */ stcl = fs->last_clst; lclst = 0; if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2; #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */ if (scl == 0) res = FR_DENIED; /* No contiguous cluster block was found */ if (scl == 0xFFFFFFFF) res = FR_DISK_ERR; if (res == FR_OK) { /* A contiguous free area is found */ if (opt) { /* Allocate it now */ res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */ lclst = scl + tcl - 1; } else { /* Set it as suggested point for next allocation */ lclst = scl - 1; } } } else #endif { scl = clst = stcl; ncl = 0; for (;;) { /* Find a contiguous cluster block */ n = get_fat(&fp->obj, clst); if (++clst >= fs->n_fatent) clst = 2; if (n == 1) { res = FR_INT_ERR; break; } if (n == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } if (n == 0) { /* Is it a free cluster? */ if (++ncl == tcl) break; /* Break if a contiguous cluster block is found */ } else { scl = clst; ncl = 0; /* Not a free cluster */ } if (clst == stcl) { /* No contiguous cluster? */ res = FR_DENIED; break; } } if (res == FR_OK) { /* A contiguous free area is found */ if (opt) { /* Allocate it now */ for (clst = scl, n = tcl; n; clst++, n--) { /* Create a cluster chain on the FAT */ res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1); if (res != FR_OK) break; lclst = clst; } } else { /* Set it as suggested point for next allocation */ lclst = scl - 1; } } } if (res == FR_OK) { fs->last_clst = lclst; /* Set suggested start cluster to start next */ if (opt) { /* Is it allocated now? */ fp->obj.sclust = scl; /* Update object allocation information */ fp->obj.objsize = fsz; if (FF_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ fp->flag |= FA_MODIFIED; if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */ fs->free_clst -= tcl; fs->fsi_flag |= 1; } } } LEAVE_FF(fs, res); } #endif /* FF_USE_EXPAND && !FF_FS_READONLY */ #if FF_USE_FORWARD /*-----------------------------------------------------------------------*/ /* Forward Data to the Stream Directly */ /*-----------------------------------------------------------------------*/ FRESULT f_forward ( FIL* fp, /* Pointer to the file object */ UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ UINT btf, /* Number of bytes to forward */ UINT* bf /* Pointer to number of bytes forwarded */ ) { FRESULT res; FATFS *fs; DWORD clst; LBA_t sect; FSIZE_t remain; UINT rcnt, csect; BYTE *dbuf; *bf = 0; /* Clear transfer byte counter */ res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ remain = fp->obj.objsize - fp->fptr; if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ for ( ; btf > 0 && (*func)(0, 0); fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { /* Repeat until all data transferred or stream goes busy */ csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ if (csect == 0) { /* On the cluster boundary? */ clst = (fp->fptr == 0) ? /* On the top of the file? */ fp->obj.sclust : get_fat(&fp->obj, fp->clust); if (clst <= 1) ABORT(fs, FR_INT_ERR); if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); fp->clust = clst; /* Update current cluster */ } } sect = clst2sect(fs, fp->clust); /* Get current data sector */ if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; #if FF_FS_TINY if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data */ dbuf = fs->win; #else if (fp->sect != sect) { /* Fill sector cache with file data */ #if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); } dbuf = fp->buf; #endif fp->sect = sect; rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ if (rcnt > btf) rcnt = btf; /* Clip it by btr if needed */ rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */ if (rcnt == 0) ABORT(fs, FR_INT_ERR); } LEAVE_FF(fs, FR_OK); } #endif /* FF_USE_FORWARD */ #if !FF_FS_READONLY && FF_USE_MKFS /*-----------------------------------------------------------------------*/ /* Create FAT/exFAT volume (with sub-functions) */ /*-----------------------------------------------------------------------*/ #define N_SEC_TRACK 63 /* Sectors per track for determination of drive CHS */ #define GPT_ALIGN 0x100000 /* Alignment of partitions in GPT [byte] (>=128KB) */ #define GPT_ITEMS 128 /* Number of GPT table size (>=128, sector aligned) */ /* Create partitions on the physical drive in format of MBR or GPT */ static FRESULT create_partition ( BYTE drv, /* Physical drive number */ const LBA_t plst[], /* Partition list */ BYTE sys, /* System ID for each partition (for only MBR) */ BYTE *buf /* Working buffer for a sector */ ) { UINT i, cy; LBA_t sz_drv; DWORD sz_drv32, nxt_alloc32, sz_part32; BYTE *pte; BYTE hd, n_hd, sc, n_sc; /* Get physical drive size */ if (disk_ioctl(drv, GET_SECTOR_COUNT, &sz_drv) != RES_OK) return FR_DISK_ERR; #if FF_LBA64 if (sz_drv >= FF_MIN_GPT) { /* Create partitions in GPT format */ WORD ss; UINT sz_ptbl, pi, si, ofs; DWORD bcc, rnd, align; QWORD nxt_alloc, sz_part, sz_pool, top_bpt; static const BYTE gpt_mbr[16] = {0x00, 0x00, 0x02, 0x00, 0xEE, 0xFE, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; #if FF_MAX_SS != FF_MIN_SS if (disk_ioctl(drv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; /* Get sector size */ if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; #else ss = FF_MAX_SS; #endif rnd = (DWORD)sz_drv + GET_FATTIME(); /* Random seed */ align = GPT_ALIGN / ss; /* Partition alignment for GPT [sector] */ sz_ptbl = GPT_ITEMS * SZ_GPTE / ss; /* Size of partition table [sector] */ top_bpt = sz_drv - sz_ptbl - 1; /* Backup partition table start sector */ nxt_alloc = 2 + sz_ptbl; /* First allocatable sector */ sz_pool = top_bpt - nxt_alloc; /* Size of allocatable area */ bcc = 0xFFFFFFFF; sz_part = 1; pi = si = 0; /* partition table index, size table index */ do { if (pi * SZ_GPTE % ss == 0) memset(buf, 0, ss); /* Clean the buffer if needed */ if (sz_part != 0) { /* Is the size table not termintated? */ nxt_alloc = (nxt_alloc + align - 1) & ((QWORD)0 - align); /* Align partition start */ sz_part = plst[si++]; /* Get a partition size */ if (sz_part <= 100) { /* Is the size in percentage? */ sz_part = sz_pool * sz_part / 100; sz_part = (sz_part + align - 1) & ((QWORD)0 - align); /* Align partition end (only if in percentage) */ } if (nxt_alloc + sz_part > top_bpt) { /* Clip the size at end of the pool */ sz_part = (nxt_alloc < top_bpt) ? top_bpt - nxt_alloc : 0; } } if (sz_part != 0) { /* Add a partition? */ ofs = pi * SZ_GPTE % ss; memcpy(buf + ofs + GPTE_PtGuid, GUID_MS_Basic, 16); /* Set partition GUID (Microsoft Basic Data) */ rnd = make_rand(rnd, buf + ofs + GPTE_UpGuid, 16); /* Set unique partition GUID */ st_qword(buf + ofs + GPTE_FstLba, nxt_alloc); /* Set partition start sector */ st_qword(buf + ofs + GPTE_LstLba, nxt_alloc + sz_part - 1); /* Set partition end sector */ nxt_alloc += sz_part; /* Next allocatable sector */ } if ((pi + 1) * SZ_GPTE % ss == 0) { /* Write the buffer if it is filled up */ for (i = 0; i < ss; bcc = crc32(bcc, buf[i++])) ; /* Calculate table check sum */ if (disk_write(drv, buf, 2 + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Write to primary table */ if (disk_write(drv, buf, top_bpt + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Write to secondary table */ } } while (++pi < GPT_ITEMS); /* Create primary GPT header */ memset(buf, 0, ss); memcpy(buf + GPTH_Sign, "EFI PART" "\0\0\1\0" "\x5C\0\0", 16); /* Signature, version (1.0) and size (92) */ st_dword(buf + GPTH_PtBcc, ~bcc); /* Table check sum */ st_qword(buf + GPTH_CurLba, 1); /* LBA of this header */ st_qword(buf + GPTH_BakLba, sz_drv - 1); /* LBA of secondary header */ st_qword(buf + GPTH_FstLba, 2 + sz_ptbl); /* LBA of first allocatable sector */ st_qword(buf + GPTH_LstLba, top_bpt - 1); /* LBA of last allocatable sector */ st_dword(buf + GPTH_PteSize, SZ_GPTE); /* Size of a table entry */ st_dword(buf + GPTH_PtNum, GPT_ITEMS); /* Number of table entries */ st_dword(buf + GPTH_PtOfs, 2); /* LBA of this table */ rnd = make_rand(rnd, buf + GPTH_DskGuid, 16); /* Disk GUID */ for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */ st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */ if (disk_write(drv, buf, 1, 1) != RES_OK) return FR_DISK_ERR; /* Create secondary GPT header */ st_qword(buf + GPTH_CurLba, sz_drv - 1); /* LBA of this header */ st_qword(buf + GPTH_BakLba, 1); /* LBA of primary header */ st_qword(buf + GPTH_PtOfs, top_bpt); /* LBA of this table */ st_dword(buf + GPTH_Bcc, 0); for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */ st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */ if (disk_write(drv, buf, sz_drv - 1, 1) != RES_OK) return FR_DISK_ERR; /* Create protective MBR */ memset(buf, 0, ss); memcpy(buf + MBR_Table, gpt_mbr, 16); /* Create a GPT partition */ st_word(buf + BS_55AA, 0xAA55); if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; } else #endif { /* Create partitions in MBR format */ sz_drv32 = (DWORD)sz_drv; n_sc = N_SEC_TRACK; /* Determine drive CHS without any consideration of the drive geometry */ for (n_hd = 8; n_hd != 0 && sz_drv32 / n_hd / n_sc > 1024; n_hd *= 2) ; if (n_hd == 0) n_hd = 255; /* Number of heads needs to be <256 */ memset(buf, 0, FF_MAX_SS); /* Clear MBR */ pte = buf + MBR_Table; /* Partition table in the MBR */ for (i = 0, nxt_alloc32 = n_sc; i < 4 && nxt_alloc32 != 0 && nxt_alloc32 < sz_drv32; i++, nxt_alloc32 += sz_part32) { sz_part32 = (DWORD)plst[i]; /* Get partition size */ if (sz_part32 <= 100) sz_part32 = (sz_part32 == 100) ? sz_drv32 : sz_drv32 / 100 * sz_part32; /* Size in percentage? */ if (nxt_alloc32 + sz_part32 > sz_drv32 || nxt_alloc32 + sz_part32 < nxt_alloc32) sz_part32 = sz_drv32 - nxt_alloc32; /* Clip at drive size */ if (sz_part32 == 0) break; /* End of table or no sector to allocate? */ st_dword(pte + PTE_StLba, nxt_alloc32); /* Start LBA */ st_dword(pte + PTE_SizLba, sz_part32); /* Number of sectors */ pte[PTE_System] = sys; /* System type */ cy = (UINT)(nxt_alloc32 / n_sc / n_hd); /* Start cylinder */ hd = (BYTE)(nxt_alloc32 / n_sc % n_hd); /* Start head */ sc = (BYTE)(nxt_alloc32 % n_sc + 1); /* Start sector */ pte[PTE_StHead] = hd; pte[PTE_StSec] = (BYTE)((cy >> 2 & 0xC0) | sc); pte[PTE_StCyl] = (BYTE)cy; cy = (UINT)((nxt_alloc32 + sz_part32 - 1) / n_sc / n_hd); /* End cylinder */ hd = (BYTE)((nxt_alloc32 + sz_part32 - 1) / n_sc % n_hd); /* End head */ sc = (BYTE)((nxt_alloc32 + sz_part32 - 1) % n_sc + 1); /* End sector */ pte[PTE_EdHead] = hd; pte[PTE_EdSec] = (BYTE)((cy >> 2 & 0xC0) | sc); pte[PTE_EdCyl] = (BYTE)cy; pte += SZ_PTE; /* Next entry */ } st_word(buf + BS_55AA, 0xAA55); /* MBR signature */ if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the MBR */ } return FR_OK; } FRESULT f_mkfs ( const TCHAR* path, /* Logical drive number */ const MKFS_PARM* opt, /* Format options */ void* work, /* Pointer to working buffer (null: use len bytes of heap memory) */ UINT len /* Size of working buffer [byte] */ ) { static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ static const MKFS_PARM defopt = {FM_ANY, 0, 0, 0, 0}; /* Default parameter */ BYTE fsopt, fsty, sys, pdrv, ipart; BYTE *buf; BYTE *pte; WORD ss; /* Sector size */ DWORD sz_buf, sz_blk, n_clst, pau, nsect, n, vsn; LBA_t sz_vol, b_vol, b_fat, b_data; /* Size of volume, Base LBA of volume, fat, data */ LBA_t sect, lba[2]; DWORD sz_rsv, sz_fat, sz_dir, sz_au; /* Size of reserved, fat, dir, data, cluster */ UINT n_fat, n_root, i; /* Index, Number of FATs and Number of roor dir entries */ int vol; DSTATUS ds; FRESULT res; /* Check mounted drive and clear work area */ vol = get_ldnumber(&path); /* Get target logical drive */ if (vol < 0) return FR_INVALID_DRIVE; if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear the fs object if mounted */ pdrv = LD2PD(vol); /* Hosting physical drive */ ipart = LD2PT(vol); /* Hosting partition (0:create as new, 1..:existing partition) */ /* Initialize the hosting physical drive */ ds = disk_initialize(pdrv); if (ds & STA_NOINIT) return FR_NOT_READY; if (ds & STA_PROTECT) return FR_WRITE_PROTECTED; /* Get physical drive parameters (sz_drv, sz_blk and ss) */ if (!opt) opt = &defopt; /* Use default parameter if it is not given */ sz_blk = opt->align; if (sz_blk == 0) disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk); /* Block size from the paramter or lower layer */ if (sz_blk == 0 || sz_blk > 0x8000 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Use default if the block size is invalid */ #if FF_MAX_SS != FF_MIN_SS if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; #else ss = FF_MAX_SS; #endif /* Options for FAT sub-type and FAT parameters */ fsopt = opt->fmt & (FM_ANY | FM_SFD); n_fat = (opt->n_fat >= 1 && opt->n_fat <= 2) ? opt->n_fat : 1; n_root = (opt->n_root >= 1 && opt->n_root <= 32768 && (opt->n_root % (ss / SZDIRE)) == 0) ? opt->n_root : 512; sz_au = (opt->au_size <= 0x1000000 && (opt->au_size & (opt->au_size - 1)) == 0) ? opt->au_size : 0; sz_au /= ss; /* Byte --> Sector */ /* Get working buffer */ sz_buf = len / ss; /* Size of working buffer [sector] */ if (sz_buf == 0) return FR_NOT_ENOUGH_CORE; buf = (BYTE*)work; /* Working buffer */ #if FF_USE_LFN == 3 if (!buf) buf = ff_memalloc(sz_buf * ss); /* Use heap memory for working buffer */ #endif if (!buf) return FR_NOT_ENOUGH_CORE; /* Determine where the volume to be located (b_vol, sz_vol) */ b_vol = sz_vol = 0; if (FF_MULTI_PARTITION && ipart != 0) { /* Is the volume associated with any specific partition? */ /* Get partition location from the existing partition table */ if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */ if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */ #if FF_LBA64 if (buf[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */ DWORD n_ent, ofs; QWORD pt_lba; /* Get the partition location from GPT */ if (disk_read(pdrv, buf, 1, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load GPT header sector (next to MBR) */ if (!test_gpt_header(buf)) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if GPT header is valid */ n_ent = ld_dword(buf + GPTH_PtNum); /* Number of entries */ pt_lba = ld_qword(buf + GPTH_PtOfs); /* Table start sector */ ofs = i = 0; while (n_ent) { /* Find MS Basic partition with order of ipart */ if (ofs == 0 && disk_read(pdrv, buf, pt_lba++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Get PT sector */ if (!memcmp(buf + ofs + GPTE_PtGuid, GUID_MS_Basic, 16) && ++i == ipart) { /* MS basic data partition? */ b_vol = ld_qword(buf + ofs + GPTE_FstLba); sz_vol = ld_qword(buf + ofs + GPTE_LstLba) - b_vol + 1; break; } n_ent--; ofs = (ofs + SZ_GPTE) % ss; /* Next entry */ } if (n_ent == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* Partition not found */ fsopt |= 0x80; /* Partitioning is in GPT */ } else #endif { /* Get the partition location from MBR partition table */ pte = buf + (MBR_Table + (ipart - 1) * SZ_PTE); if (ipart > 4 || pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* No partition? */ b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */ sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */ } } else { /* The volume is associated with a physical drive */ if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); if (!(fsopt & FM_SFD)) { /* To be partitioned? */ /* Create a single-partition on the drive in this function */ #if FF_LBA64 if (sz_vol >= FF_MIN_GPT) { /* Which partition type to create, MBR or GPT? */ fsopt |= 0x80; /* Partitioning is in GPT */ b_vol = GPT_ALIGN / ss; sz_vol -= b_vol + GPT_ITEMS * SZ_GPTE / ss + 1; /* Estimated partition offset and size */ } else #endif { /* Partitioning is in MBR */ if (sz_vol > N_SEC_TRACK) { b_vol = N_SEC_TRACK; sz_vol -= b_vol; /* Estimated partition offset and size */ } } } } if (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >=128s */ /* Now start to create an FAT volume at b_vol and sz_vol */ do { /* Pre-determine the FAT type */ if (FF_FS_EXFAT && (fsopt & FM_EXFAT)) { /* exFAT possible? */ if ((fsopt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || sz_au > 128) { /* exFAT only, vol >= 64MS or sz_au > 128S ? */ fsty = FS_EXFAT; break; } } #if FF_LBA64 if (sz_vol >= 0x100000000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too large volume for FAT/FAT32 */ #endif if (sz_au > 128) sz_au = 128; /* Invalid AU for FAT/FAT32? */ if (fsopt & FM_FAT32) { /* FAT32 possible? */ if (!(fsopt & FM_FAT)) { /* no-FAT? */ fsty = FS_FAT32; break; } } if (!(fsopt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER); /* no-FAT? */ fsty = FS_FAT16; } while (0); vsn = (DWORD)sz_vol + GET_FATTIME(); /* VSN generated from current time and partitiion size */ #if FF_FS_EXFAT if (fsty == FS_EXFAT) { /* Create an exFAT volume */ DWORD szb_bit, szb_case, sum, nbit, clu, clen[3]; WCHAR ch, si; UINT j, st; if (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume for exFAT? */ #if FF_USE_TRIM lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */ disk_ioctl(pdrv, CTRL_TRIM, lba); #endif /* Determine FAT location, data location and number of clusters */ if (sz_au == 0) { /* AU auto-selection */ sz_au = 8; if (sz_vol >= 0x80000) sz_au = 64; /* >= 512Ks */ if (sz_vol >= 0x4000000) sz_au = 256; /* >= 64Ms */ } b_fat = b_vol + 32; /* FAT start at offset 32 */ sz_fat = (DWORD)((sz_vol / sz_au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ b_data = (b_fat + sz_fat + sz_blk - 1) & ~((LBA_t)sz_blk - 1); /* Align data area to the erase block boundary */ if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ n_clst = (DWORD)((sz_vol - (b_data - b_vol)) / sz_au); /* Number of clusters */ if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ clen[0] = (szb_bit + sz_au * ss - 1) / (sz_au * ss); /* Number of allocation bitmap clusters */ /* Create a compressed up-case table */ sect = b_data + sz_au * clen[0]; /* Table start sector */ sum = 0; /* Table checksum to be stored in the 82 entry */ st = 0; si = 0; i = 0; j = 0; szb_case = 0; do { switch (st) { case 0: ch = (WCHAR)ff_wtoupper(si); /* Get an up-case char */ if (ch != si) { si++; break; /* Store the up-case char if exist */ } for (j = 1; (WCHAR)(si + j) && (WCHAR)(si + j) == ff_wtoupper((WCHAR)(si + j)); j++) ; /* Get run length of no-case block */ if (j >= 128) { ch = 0xFFFF; st = 2; break; /* Compress the no-case block if run is >= 128 chars */ } st = 1; /* Do not compress short run */ /* FALLTHROUGH */ case 1: ch = si++; /* Fill the short run */ if (--j == 0) st = 0; break; default: ch = (WCHAR)j; si += (WCHAR)j; /* Number of chars to skip */ st = 0; } sum = xsum32(buf[i + 0] = (BYTE)ch, sum); /* Put it into the write buffer */ sum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum); i += 2; szb_case += 2; if (si == 0 || i == sz_buf * ss) { /* Write buffered data when buffer full or end of process */ n = (i + ss - 1) / ss; if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; i = 0; } } while (si); clen[1] = (szb_case + sz_au * ss - 1) / (sz_au * ss); /* Number of up-case table clusters */ clen[2] = 1; /* Number of root dir clusters */ /* Initialize the allocation bitmap */ sect = b_data; nsect = (szb_bit + ss - 1) / ss; /* Start of bitmap and number of bitmap sectors */ nbit = clen[0] + clen[1] + clen[2]; /* Number of clusters in-use by system (bitmap, up-case and root-dir) */ do { memset(buf, 0, sz_buf * ss); /* Initialize bitmap buffer */ for (i = 0; nbit != 0 && i / 8 < sz_buf * ss; buf[i / 8] |= 1 << (i % 8), i++, nbit--) ; /* Mark used clusters */ n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); /* Initialize the FAT */ sect = b_fat; nsect = sz_fat; /* Start of FAT and number of FAT sectors */ j = nbit = clu = 0; do { memset(buf, 0, sz_buf * ss); i = 0; /* Clear work area and reset write offset */ if (clu == 0) { /* Initialize FAT [0] and FAT[1] */ st_dword(buf + i, 0xFFFFFFF8); i += 4; clu++; st_dword(buf + i, 0xFFFFFFFF); i += 4; clu++; } do { /* Create chains of bitmap, up-case and root dir */ while (nbit != 0 && i < sz_buf * ss) { /* Create a chain */ st_dword(buf + i, (nbit > 1) ? clu + 1 : 0xFFFFFFFF); i += 4; clu++; nbit--; } if (nbit == 0 && j < 3) nbit = clen[j++]; /* Get next chain length */ } while (nbit != 0 && i < sz_buf * ss); n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); /* Initialize the root directory */ memset(buf, 0, sz_buf * ss); buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry (no label) */ buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */ st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */ st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ st_dword(buf + SZDIRE * 2 + 20, 2 + clen[0]); /* cluster */ st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ sect = b_data + sz_au * (clen[0] + clen[1]); nsect = sz_au; /* Start of the root directory and number of sectors */ do { /* Fill root directory sectors */ n = (nsect > sz_buf) ? sz_buf : nsect; if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); memset(buf, 0, ss); /* Rest of entries are filled with zero */ sect += n; nsect -= n; } while (nsect); /* Create two set of the exFAT VBR blocks */ sect = b_vol; for (n = 0; n < 2; n++) { /* Main record (+0) */ memset(buf, 0, ss); memcpy(buf + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11); /* Boot jump code (x86), OEM name */ st_qword(buf + BPB_VolOfsEx, b_vol); /* Volume offset in the physical drive [sector] */ st_qword(buf + BPB_TotSecEx, sz_vol); /* Volume size [sector] */ st_dword(buf + BPB_FatOfsEx, (DWORD)(b_fat - b_vol)); /* FAT offset [sector] */ st_dword(buf + BPB_FatSzEx, sz_fat); /* FAT size [sector] */ st_dword(buf + BPB_DataOfsEx, (DWORD)(b_data - b_vol)); /* Data offset [sector] */ st_dword(buf + BPB_NumClusEx, n_clst); /* Number of clusters */ st_dword(buf + BPB_RootClusEx, 2 + clen[0] + clen[1]); /* Root dir cluster # */ st_dword(buf + BPB_VolIDEx, vsn); /* VSN */ st_word(buf + BPB_FSVerEx, 0x100); /* Filesystem version (1.00) */ for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ; /* Log2 of sector size [byte] */ for (buf[BPB_SecPerClusEx] = 0, i = sz_au; i >>= 1; buf[BPB_SecPerClusEx]++) ; /* Log2 of cluster size [sector] */ buf[BPB_NumFATsEx] = 1; /* Number of FATs */ buf[BPB_DrvNumEx] = 0x80; /* Drive number (for int13) */ st_word(buf + BS_BootCodeEx, 0xFEEB); /* Boot code (x86) */ st_word(buf + BS_55AA, 0xAA55); /* Signature (placed here regardless of sector size) */ for (i = sum = 0; i < ss; i++) { /* VBR checksum */ if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum); } if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Extended bootstrap record (+1..+8) */ memset(buf, 0, ss); st_word(buf + ss - 2, 0xAA55); /* Signature (placed at end of sector) */ for (j = 1; j < 9; j++) { for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } /* OEM/Reserved record (+9..+10) */ memset(buf, 0, ss); for ( ; j < 11; j++) { for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } /* Sum record (+11) */ for (i = 0; i < ss; i += 4) st_dword(buf + i, sum); /* Fill with checksum value */ if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } } else #endif /* FF_FS_EXFAT */ { /* Create an FAT/FAT32 volume */ do { pau = sz_au; /* Pre-determine number of clusters and FAT sub-type */ if (fsty == FS_FAT32) { /* FAT32 volume */ if (pau == 0) { /* AU auto-selection */ n = (DWORD)sz_vol / 0x20000; /* Volume size in unit of 128KS */ for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */ } n_clst = (DWORD)sz_vol / pau; /* Number of clusters */ sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */ sz_rsv = 32; /* Number of reserved sectors */ sz_dir = 0; /* No static directory */ if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); } else { /* FAT volume */ if (pau == 0) { /* au auto-selection */ n = (DWORD)sz_vol / 0x1000; /* Volume size in unit of 4KS */ for (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ; /* Get from table */ } n_clst = (DWORD)sz_vol / pau; if (n_clst > MAX_FAT12) { n = n_clst * 2 + 4; /* FAT size [byte] */ } else { fsty = FS_FAT12; n = (n_clst * 3 + 1) / 2 + 3; /* FAT size [byte] */ } sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */ sz_rsv = 1; /* Number of reserved sectors */ sz_dir = (DWORD)n_root * SZDIRE / ss; /* Root dir size [sector] */ } b_fat = b_vol + sz_rsv; /* FAT base */ b_data = b_fat + sz_fat * n_fat + sz_dir; /* Data base */ /* Align data area to erase block boundary (for flash memory media) */ n = (DWORD)(((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data); /* Sectors to next nearest from current data base */ if (fsty == FS_FAT32) { /* FAT32: Move FAT */ sz_rsv += n; b_fat += n; } else { /* FAT: Expand FAT */ if (n % n_fat) { /* Adjust fractional error if needed */ n--; sz_rsv++; b_fat++; } sz_fat += n / n_fat; } /* Determine number of clusters and final check of validity of the FAT sub-type */ if (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ n_clst = ((DWORD)sz_vol - sz_rsv - sz_fat * n_fat - sz_dir) / pau; if (fsty == FS_FAT32) { if (n_clst <= MAX_FAT16) { /* Too few clusters for FAT32? */ if (sz_au == 0 && (sz_au = pau / 2) != 0) continue; /* Adjust cluster size and retry */ LEAVE_MKFS(FR_MKFS_ABORTED); } } if (fsty == FS_FAT16) { if (n_clst > MAX_FAT16) { /* Too many clusters for FAT16 */ if (sz_au == 0 && (pau * 2) <= 64) { sz_au = pau * 2; continue; /* Adjust cluster size and retry */ } if ((fsopt & FM_FAT32)) { fsty = FS_FAT32; continue; /* Switch type to FAT32 and retry */ } if (sz_au == 0 && (sz_au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ LEAVE_MKFS(FR_MKFS_ABORTED); } if (n_clst <= MAX_FAT12) { /* Too few clusters for FAT16 */ if (sz_au == 0 && (sz_au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ LEAVE_MKFS(FR_MKFS_ABORTED); } } if (fsty == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters for FAT12 */ /* Ok, it is the valid cluster configuration */ break; } while (1); #if FF_USE_TRIM lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */ disk_ioctl(pdrv, CTRL_TRIM, lba); #endif /* Create FAT VBR */ memset(buf, 0, ss); memcpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11); /* Boot jump code (x86), OEM name */ st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */ buf[BPB_NumFATs] = (BYTE)n_fat; /* Number of FATs */ st_word(buf + BPB_RootEntCnt, (WORD)((fsty == FS_FAT32) ? 0 : n_root)); /* Number of root directory entries */ if (sz_vol < 0x10000) { st_word(buf + BPB_TotSec16, (WORD)sz_vol); /* Volume size in 16-bit LBA */ } else { st_dword(buf + BPB_TotSec32, (DWORD)sz_vol); /* Volume size in 32-bit LBA */ } buf[BPB_Media] = 0xF8; /* Media descriptor byte */ st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */ st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */ st_dword(buf + BPB_HiddSec, (DWORD)b_vol); /* Volume offset in the physical drive [sector] */ if (fsty == FS_FAT32) { st_dword(buf + BS_VolID32, vsn); /* VSN */ st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */ st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */ st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */ st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ buf[BS_BootSig32] = 0x29; /* Extended boot signature */ memcpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ } else { st_dword(buf + BS_VolID, vsn); /* VSN */ st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ buf[BS_BootSig] = 0x29; /* Extended boot signature */ memcpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ } st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ /* Create FSINFO record if needed */ if (fsty == FS_FAT32) { disk_write(pdrv, buf, b_vol + 6, 1); /* Write backup VBR (VBR + 6) */ memset(buf, 0, ss); st_dword(buf + FSI_LeadSig, 0x41615252); st_dword(buf + FSI_StrucSig, 0x61417272); st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */ st_word(buf + BS_55AA, 0xAA55); disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */ disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */ } /* Initialize FAT area */ memset(buf, 0, sz_buf * ss); sect = b_fat; /* FAT start sector */ for (i = 0; i < n_fat; i++) { /* Initialize FATs each */ if (fsty == FS_FAT32) { st_dword(buf + 0, 0xFFFFFFF8); /* FAT[0] */ st_dword(buf + 4, 0xFFFFFFFF); /* FAT[1] */ st_dword(buf + 8, 0x0FFFFFFF); /* FAT[2] (root directory) */ } else { st_dword(buf + 0, (fsty == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8); /* FAT[0] and FAT[1] */ } nsect = sz_fat; /* Number of FAT sectors */ do { /* Fill FAT sectors */ n = (nsect > sz_buf) ? sz_buf : nsect; if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); memset(buf, 0, ss); /* Rest of FAT all are cleared */ sect += n; nsect -= n; } while (nsect); } /* Initialize root directory (fill with zero) */ nsect = (fsty == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */ do { n = (nsect > sz_buf) ? sz_buf : nsect; if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); } /* A FAT volume has been created here */ /* Determine system ID in the MBR partition table */ if (FF_FS_EXFAT && fsty == FS_EXFAT) { sys = 0x07; /* exFAT */ } else if (fsty == FS_FAT32) { sys = 0x0C; /* FAT32X */ } else if (sz_vol >= 0x10000) { sys = 0x06; /* FAT12/16 (large) */ } else if (fsty == FS_FAT16) { sys = 0x04; /* FAT16 */ } else { sys = 0x01; /* FAT12 */ } /* Update partition information */ if (FF_MULTI_PARTITION && ipart != 0) { /* Volume is in the existing partition */ if (!FF_LBA64 || !(fsopt & 0x80)) { /* Is the partition in MBR? */ /* Update system ID in the partition table */ if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */ buf[MBR_Table + (ipart - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */ if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */ } } else { /* Volume as a new single partition */ if (!(fsopt & FM_SFD)) { /* Create partition table if not in SFD format */ lba[0] = sz_vol; lba[1] = 0; res = create_partition(pdrv, lba, sys, buf); if (res != FR_OK) LEAVE_MKFS(res); } } if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); LEAVE_MKFS(FR_OK); } #if FF_MULTI_PARTITION /*-----------------------------------------------------------------------*/ /* Create Partition Table on the Physical Drive */ /*-----------------------------------------------------------------------*/ FRESULT f_fdisk ( BYTE pdrv, /* Physical drive number */ const LBA_t ptbl[], /* Pointer to the size table for each partitions */ void* work /* Pointer to the working buffer (null: use heap memory) */ ) { BYTE *buf = (BYTE*)work; DSTATUS stat; FRESULT res; /* Initialize the physical drive */ stat = disk_initialize(pdrv); if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; #if FF_USE_LFN == 3 if (!buf) buf = ff_memalloc(FF_MAX_SS); /* Use heap memory for working buffer */ #endif if (!buf) return FR_NOT_ENOUGH_CORE; res = create_partition(pdrv, ptbl, 0x07, buf); /* Create partitions (system ID is temporary setting and determined by f_mkfs) */ LEAVE_MKFS(res); } #endif /* FF_MULTI_PARTITION */ #endif /* !FF_FS_READONLY && FF_USE_MKFS */ #if FF_USE_STRFUNC #if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3) #error Wrong FF_STRF_ENCODE setting #endif /*-----------------------------------------------------------------------*/ /* Get a String from the File */ /*-----------------------------------------------------------------------*/ TCHAR* f_gets ( TCHAR* buff, /* Pointer to the buffer to store read string */ int len, /* Size of string buffer (items) */ FIL* fp /* Pointer to the file object */ ) { int nc = 0; TCHAR *p = buff; BYTE s[4]; UINT rc; DWORD dc; #if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2 WCHAR wc; #endif #if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3 UINT ct; #endif #if FF_USE_LFN && FF_LFN_UNICODE /* With code conversion (Unicode API) */ /* Make a room for the character and terminator */ if (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2; if (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4; if (FF_LFN_UNICODE == 3) len -= 1; while (nc < len) { #if FF_STRF_ENCODE == 0 /* Read a character in ANSI/OEM */ f_read(fp, s, 1, &rc); /* Get a code unit */ if (rc != 1) break; /* EOF? */ wc = s[0]; if (dbc_1st((BYTE)wc)) { /* DBC 1st byte? */ f_read(fp, s, 1, &rc); /* Get 2nd byte */ if (rc != 1 || !dbc_2nd(s[0])) continue; /* Wrong code? */ wc = wc << 8 | s[0]; } dc = ff_oem2uni(wc, CODEPAGE); /* Convert ANSI/OEM into Unicode */ if (dc == 0) continue; /* Conversion error? */ #elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 /* Read a character in UTF-16LE/BE */ f_read(fp, s, 2, &rc); /* Get a code unit */ if (rc != 2) break; /* EOF? */ dc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; if (IsSurrogateL(dc)) continue; /* Broken surrogate pair? */ if (IsSurrogateH(dc)) { /* High surrogate? */ f_read(fp, s, 2, &rc); /* Get low surrogate */ if (rc != 2) break; /* EOF? */ wc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; if (!IsSurrogateL(wc)) continue; /* Broken surrogate pair? */ dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF); /* Merge surrogate pair */ } #else /* Read a character in UTF-8 */ f_read(fp, s, 1, &rc); /* Get a code unit */ if (rc != 1) break; /* EOF? */ dc = s[0]; if (dc >= 0x80) { /* Multi-byte sequence? */ ct = 0; if ((dc & 0xE0) == 0xC0) { /* 2-byte sequence? */ dc &= 0x1F; ct = 1; } if ((dc & 0xF0) == 0xE0) { /* 3-byte sequence? */ dc &= 0x0F; ct = 2; } if ((dc & 0xF8) == 0xF0) { /* 4-byte sequence? */ dc &= 0x07; ct = 3; } if (ct == 0) continue; f_read(fp, s, ct, &rc); /* Get trailing bytes */ if (rc != ct) break; rc = 0; do { /* Merge the byte sequence */ if ((s[rc] & 0xC0) != 0x80) break; dc = dc << 6 | (s[rc] & 0x3F); } while (++rc < ct); if (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue; /* Wrong encoding? */ } #endif /* A code point is avaialble in dc to be output */ if (FF_USE_STRFUNC == 2 && dc == '\r') continue; /* Strip \r off if needed */ #if FF_LFN_UNICODE == 1 || FF_LFN_UNICODE == 3 /* Output it in UTF-16/32 encoding */ if (FF_LFN_UNICODE == 1 && dc >= 0x10000) { /* Out of BMP at UTF-16? */ *p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++; /* Make and output high surrogate */ dc = 0xDC00 | (dc & 0x3FF); /* Make low surrogate */ } *p++ = (TCHAR)dc; nc++; if (dc == '\n') break; /* End of line? */ #elif FF_LFN_UNICODE == 2 /* Output it in UTF-8 encoding */ if (dc < 0x80) { /* Single byte? */ *p++ = (TCHAR)dc; nc++; if (dc == '\n') break; /* End of line? */ } else if (dc < 0x800) { /* 2-byte sequence? */ *p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F)); *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); nc += 2; } else if (dc < 0x10000) { /* 3-byte sequence? */ *p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F)); *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); nc += 3; } else { /* 4-byte sequence */ *p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07)); *p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F)); *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); nc += 4; } #endif } #else /* Byte-by-byte read without any conversion (ANSI/OEM API) */ len -= 1; /* Make a room for the terminator */ while (nc < len) { f_read(fp, s, 1, &rc); /* Get a byte */ if (rc != 1) break; /* EOF? */ dc = s[0]; if (FF_USE_STRFUNC == 2 && dc == '\r') continue; *p++ = (TCHAR)dc; nc++; if (dc == '\n') break; } #endif *p = 0; /* Terminate the string */ return nc ? buff : 0; /* When no data read due to EOF or error, return with error. */ } #if !FF_FS_READONLY #include #define SZ_PUTC_BUF 64 #define SZ_NUM_BUF 32 /*-----------------------------------------------------------------------*/ /* Put a Character to the File (with sub-functions) */ /*-----------------------------------------------------------------------*/ /* Output buffer and work area */ typedef struct { FIL *fp; /* Ptr to the writing file */ int idx, nchr; /* Write index of buf[] (-1:error), number of encoding units written */ #if FF_USE_LFN && FF_LFN_UNICODE == 1 WCHAR hs; #elif FF_USE_LFN && FF_LFN_UNICODE == 2 BYTE bs[4]; UINT wi, ct; #endif BYTE buf[SZ_PUTC_BUF]; /* Write buffer */ } putbuff; /* Buffered file write with code conversion */ static void putc_bfd (putbuff* pb, TCHAR c) { UINT n; int i, nc; #if FF_USE_LFN && FF_LFN_UNICODE WCHAR hs, wc; #if FF_LFN_UNICODE == 2 DWORD dc; const TCHAR* tp; #endif #endif if (FF_USE_STRFUNC == 2 && c == '\n') { /* LF -> CRLF conversion */ putc_bfd(pb, '\r'); } i = pb->idx; /* Write index of pb->buf[] */ if (i < 0) return; /* In write error? */ nc = pb->nchr; /* Write unit counter */ #if FF_USE_LFN && FF_LFN_UNICODE #if FF_LFN_UNICODE == 1 /* UTF-16 input */ if (IsSurrogateH(c)) { /* Is this a high-surrogate? */ pb->hs = c; return; /* Save it for next */ } hs = pb->hs; pb->hs = 0; if (hs != 0) { /* Is there a leading high-surrogate? */ if (!IsSurrogateL(c)) hs = 0; /* Discard high-surrogate if not a surrogate pair */ } else { if (IsSurrogateL(c)) return; /* Discard stray low-surrogate */ } wc = c; #elif FF_LFN_UNICODE == 2 /* UTF-8 input */ for (;;) { if (pb->ct == 0) { /* Out of multi-byte sequence? */ pb->bs[pb->wi = 0] = (BYTE)c; /* Save 1st byte */ if ((BYTE)c < 0x80) break; /* Single byte code? */ if (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1; /* 2-byte sequence? */ if (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2; /* 3-byte sequence? */ if (((BYTE)c & 0xF8) == 0xF0) pb->ct = 3; /* 4-byte sequence? */ return; /* Wrong leading byte (discard it) */ } else { /* In the multi-byte sequence */ if (((BYTE)c & 0xC0) != 0x80) { /* Broken sequence? */ pb->ct = 0; continue; /* Discard the sequense */ } pb->bs[++pb->wi] = (BYTE)c; /* Save the trailing byte */ if (--pb->ct == 0) break; /* End of the sequence? */ return; } } tp = (const TCHAR*)pb->bs; dc = tchar2uni(&tp); /* UTF-8 ==> UTF-16 */ if (dc == 0xFFFFFFFF) return; /* Wrong code? */ hs = (WCHAR)(dc >> 16); wc = (WCHAR)dc; #elif FF_LFN_UNICODE == 3 /* UTF-32 input */ if (IsSurrogate(c) || c >= 0x110000) return; /* Discard invalid code */ if (c >= 0x10000) { /* Out of BMP? */ hs = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); /* Make high surrogate */ wc = 0xDC00 | (c & 0x3FF); /* Make low surrogate */ } else { hs = 0; wc = (WCHAR)c; } #endif /* A code point in UTF-16 is available in hs and wc */ #if FF_STRF_ENCODE == 1 /* Write a code point in UTF-16LE */ if (hs != 0) { /* Surrogate pair? */ st_word(&pb->buf[i], hs); i += 2; nc++; } st_word(&pb->buf[i], wc); i += 2; #elif FF_STRF_ENCODE == 2 /* Write a code point in UTF-16BE */ if (hs != 0) { /* Surrogate pair? */ pb->buf[i++] = (BYTE)(hs >> 8); pb->buf[i++] = (BYTE)hs; nc++; } pb->buf[i++] = (BYTE)(wc >> 8); pb->buf[i++] = (BYTE)wc; #elif FF_STRF_ENCODE == 3 /* Write a code point in UTF-8 */ if (hs != 0) { /* 4-byte sequence? */ nc += 3; hs = (hs & 0x3FF) + 0x40; pb->buf[i++] = (BYTE)(0xF0 | hs >> 8); pb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F)); pb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F)); pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); } else { if (wc < 0x80) { /* Single byte? */ pb->buf[i++] = (BYTE)wc; } else { if (wc < 0x800) { /* 2-byte sequence? */ nc += 1; pb->buf[i++] = (BYTE)(0xC0 | wc >> 6); } else { /* 3-byte sequence */ nc += 2; pb->buf[i++] = (BYTE)(0xE0 | wc >> 12); pb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F)); } pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); } } #else /* Write a code point in ANSI/OEM */ if (hs != 0) return; wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ if (wc == 0) return; if (wc >= 0x100) { pb->buf[i++] = (BYTE)(wc >> 8); nc++; } pb->buf[i++] = (BYTE)wc; #endif #else /* ANSI/OEM input (without re-encoding) */ pb->buf[i++] = (BYTE)c; #endif if (i >= (int)(sizeof pb->buf) - 4) { /* Write buffered characters to the file */ f_write(pb->fp, pb->buf, (UINT)i, &n); i = (n == (UINT)i) ? 0 : -1; } pb->idx = i; pb->nchr = nc + 1; } /* Flush remaining characters in the buffer */ static int putc_flush (putbuff* pb) { UINT nw; if ( pb->idx >= 0 /* Flush buffered characters to the file */ && f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK && (UINT)pb->idx == nw) return pb->nchr; return -1; } /* Initialize write buffer */ static void putc_init (putbuff* pb, FIL* fp) { memset(pb, 0, sizeof (putbuff)); pb->fp = fp; } int f_putc ( TCHAR c, /* A character to be output */ FIL* fp /* Pointer to the file object */ ) { putbuff pb; putc_init(&pb, fp); putc_bfd(&pb, c); /* Put the character */ return putc_flush(&pb); } /*-----------------------------------------------------------------------*/ /* Put a String to the File */ /*-----------------------------------------------------------------------*/ int f_puts ( const TCHAR* str, /* Pointer to the string to be output */ FIL* fp /* Pointer to the file object */ ) { putbuff pb; putc_init(&pb, fp); while (*str) putc_bfd(&pb, *str++); /* Put the string */ return putc_flush(&pb); } /*-----------------------------------------------------------------------*/ /* Put a Formatted String to the File (with sub-functions) */ /*-----------------------------------------------------------------------*/ #if FF_PRINT_FLOAT && FF_INTDEF == 2 #include static int ilog10 (double n) /* Calculate log10(n) in integer output */ { int rv = 0; while (n >= 10) { /* Decimate digit in right shift */ if (n >= 100000) { n /= 100000; rv += 5; } else { n /= 10; rv++; } } while (n < 1) { /* Decimate digit in left shift */ if (n < 0.00001) { n *= 100000; rv -= 5; } else { n *= 10; rv--; } } return rv; } static double i10x (int n) /* Calculate 10^n in integer input */ { double rv = 1; while (n > 0) { /* Left shift */ if (n >= 5) { rv *= 100000; n -= 5; } else { rv *= 10; n--; } } while (n < 0) { /* Right shift */ if (n <= -5) { rv /= 100000; n += 5; } else { rv /= 10; n++; } } return rv; } static void ftoa ( char* buf, /* Buffer to output the floating point string */ double val, /* Value to output */ int prec, /* Number of fractional digits */ TCHAR fmt /* Notation */ ) { int d; int e = 0, m = 0; char sign = 0; double w; const char *er = 0; const char ds = FF_PRINT_FLOAT == 2 ? ',' : '.'; if (isnan(val)) { /* Not a number? */ er = "NaN"; } else { if (prec < 0) prec = 6; /* Default precision? (6 fractional digits) */ if (val < 0) { /* Negative? */ val = 0 - val; sign = '-'; } else { sign = '+'; } if (isinf(val)) { /* Infinite? */ er = "INF"; } else { if (fmt == 'f') { /* Decimal notation? */ val += i10x(0 - prec) / 2; /* Round (nearest) */ m = ilog10(val); if (m < 0) m = 0; if (m + prec + 3 >= SZ_NUM_BUF) er = "OV"; /* Buffer overflow? */ } else { /* E notation */ if (val != 0) { /* Not a true zero? */ val += i10x(ilog10(val) - prec) / 2; /* Round (nearest) */ e = ilog10(val); if (e > 99 || prec + 7 >= SZ_NUM_BUF) { /* Buffer overflow or E > +99? */ er = "OV"; } else { if (e < -99) e = -99; val /= i10x(e); /* Normalize */ } } } } if (!er) { /* Not error condition */ if (sign == '-') *buf++ = sign; /* Add a - if negative value */ do { /* Put decimal number */ if (m == -1) *buf++ = ds; /* Insert a decimal separator when get into fractional part */ w = i10x(m); /* Snip the highest digit d */ d = (int)(val / w); val -= d * w; *buf++ = (char)('0' + d); /* Put the digit */ } while (--m >= -prec); /* Output all digits specified by prec */ if (fmt != 'f') { /* Put exponent if needed */ *buf++ = (char)fmt; if (e < 0) { e = 0 - e; *buf++ = '-'; } else { *buf++ = '+'; } *buf++ = (char)('0' + e / 10); *buf++ = (char)('0' + e % 10); } } } if (er) { /* Error condition */ if (sign) *buf++ = sign; /* Add sign if needed */ do { /* Put error symbol */ *buf++ = *er++; } while (*er); } *buf = 0; /* Term */ } #endif /* FF_PRINT_FLOAT && FF_INTDEF == 2 */ int f_printf ( FIL* fp, /* Pointer to the file object */ const TCHAR* fmt, /* Pointer to the format string */ ... /* Optional arguments... */ ) { va_list arp; putbuff pb; UINT i, j, w, f, r; int prec; #if FF_PRINT_LLI && FF_INTDEF == 2 QWORD v; #else DWORD v; #endif TCHAR *tp; TCHAR tc, pad; TCHAR nul = 0; char d, str[SZ_NUM_BUF]; putc_init(&pb, fp); va_start(arp, fmt); for (;;) { tc = *fmt++; if (tc == 0) break; /* End of format string */ if (tc != '%') { /* Not an escape character (pass-through) */ putc_bfd(&pb, tc); continue; } f = w = 0; pad = ' '; prec = -1; /* Initialize parms */ tc = *fmt++; if (tc == '0') { /* Flag: '0' padded */ pad = '0'; tc = *fmt++; } else if (tc == '-') { /* Flag: Left aligned */ f = 2; tc = *fmt++; } if (tc == '*') { /* Minimum width from an argument */ w = va_arg(arp, int); tc = *fmt++; } else { while (IsDigit(tc)) { /* Minimum width */ w = w * 10 + tc - '0'; tc = *fmt++; } } if (tc == '.') { /* Precision */ tc = *fmt++; if (tc == '*') { /* Precision from an argument */ prec = va_arg(arp, int); tc = *fmt++; } else { prec = 0; while (IsDigit(tc)) { /* Precision */ prec = prec * 10 + tc - '0'; tc = *fmt++; } } } if (tc == 'l') { /* Size: long int */ f |= 4; tc = *fmt++; #if FF_PRINT_LLI && FF_INTDEF == 2 if (tc == 'l') { /* Size: long long int */ f |= 8; tc = *fmt++; } #endif } if (tc == 0) break; /* End of format string */ switch (tc) { /* Atgument type is... */ case 'b': /* Unsigned binary */ r = 2; break; case 'o': /* Unsigned octal */ r = 8; break; case 'd': /* Signed decimal */ case 'u': /* Unsigned decimal */ r = 10; break; case 'x': /* Unsigned hexadecimal (lower case) */ case 'X': /* Unsigned hexadecimal (upper case) */ r = 16; break; case 'c': /* Character */ putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue; case 's': /* String */ tp = va_arg(arp, TCHAR*); /* Get a pointer argument */ if (!tp) tp = &nul; /* Null ptr generates a null string */ for (j = 0; tp[j]; j++) ; /* j = tcslen(tp) */ if (prec >= 0 && j > (UINT)prec) j = prec; /* Limited length of string body */ for ( ; !(f & 2) && j < w; j++) putc_bfd(&pb, pad); /* Left pads */ while (*tp && prec--) putc_bfd(&pb, *tp++); /* Body */ while (j++ < w) putc_bfd(&pb, ' '); /* Right pads */ continue; #if FF_PRINT_FLOAT && FF_INTDEF == 2 case 'f': /* Floating point (decimal) */ case 'e': /* Floating point (e) */ case 'E': /* Floating point (E) */ ftoa(str, va_arg(arp, double), prec, tc); /* Make a floating point string */ for (j = strlen(str); !(f & 2) && j < w; j++) putc_bfd(&pb, pad); /* Left pads */ for (i = 0; str[i]; putc_bfd(&pb, str[i++])) ; /* Body */ while (j++ < w) putc_bfd(&pb, ' '); /* Right pads */ continue; #endif default: /* Unknown type (pass-through) */ putc_bfd(&pb, tc); continue; } /* Get an integer argument and put it in numeral */ #if FF_PRINT_LLI && FF_INTDEF == 2 if (f & 8) { /* long long argument? */ v = (QWORD)va_arg(arp, long long); } else if (f & 4) { /* long argument? */ v = (tc == 'd') ? (QWORD)(long long)va_arg(arp, long) : (QWORD)va_arg(arp, unsigned long); } else { /* int/short/char argument */ v = (tc == 'd') ? (QWORD)(long long)va_arg(arp, int) : (QWORD)va_arg(arp, unsigned int); } if (tc == 'd' && (v & 0x8000000000000000)) { /* Negative value? */ v = 0 - v; f |= 1; } #else if (f & 4) { /* long argument? */ v = (DWORD)va_arg(arp, long); } else { /* int/short/char argument */ v = (tc == 'd') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int); } if (tc == 'd' && (v & 0x80000000)) { /* Negative value? */ v = 0 - v; f |= 1; } #endif i = 0; do { /* Make an integer number string */ d = (char)(v % r); v /= r; if (d > 9) d += (tc == 'x') ? 0x27 : 0x07; str[i++] = d + '0'; } while (v && i < SZ_NUM_BUF); if (f & 1) str[i++] = '-'; /* Sign */ /* Write it */ for (j = i; !(f & 2) && j < w; j++) { /* Left pads */ putc_bfd(&pb, pad); } do { /* Body */ putc_bfd(&pb, (TCHAR)str[--i]); } while (i); while (j++ < w) { /* Right pads */ putc_bfd(&pb, ' '); } } va_end(arp); return putc_flush(&pb); } #endif /* !FF_FS_READONLY */ #endif /* FF_USE_STRFUNC */ #if FF_CODE_PAGE == 0 /*-----------------------------------------------------------------------*/ /* Set Active Codepage for the Path Name */ /*-----------------------------------------------------------------------*/ FRESULT f_setcp ( WORD cp /* Value to be set as active code page */ ) { static const WORD validcp[22] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 932, 936, 949, 950, 0}; static const BYTE *const tables[22] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct855, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0}; UINT i; for (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ; /* Find the code page */ if (validcp[i] != cp) return FR_INVALID_PARAMETER; /* Not found? */ CodePage = cp; if (cp >= 900) { /* DBCS */ ExCvt = 0; DbcTbl = tables[i]; } else { /* SBCS */ ExCvt = tables[i]; DbcTbl = 0; } return FR_OK; } #endif /* FF_CODE_PAGE == 0 */ ================================================ FILE: lib/fatfs/source/ff.h ================================================ /*----------------------------------------------------------------------------/ / FatFs - Generic FAT Filesystem module R0.15 / /-----------------------------------------------------------------------------/ / / Copyright (C) 2022, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided / that the following condition is met: / 1. Redistributions of source code must retain the above copyright notice, / this condition and the following disclaimer. / / This software is provided by the copyright holder and contributors "AS IS" / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. / /----------------------------------------------------------------------------*/ #ifndef FF_DEFINED #define FF_DEFINED 80286 /* Revision ID */ #ifdef __cplusplus extern "C" { #endif #include "ffconf.h" /* FatFs configuration options */ #if FF_DEFINED != FFCONF_DEF #error Wrong configuration file (ffconf.h). #endif /* Integer types used for FatFs API */ #if defined(_WIN32) /* Windows VC++ (for development only) */ #define FF_INTDEF 2 #include typedef unsigned __int64 QWORD; #include #define isnan(v) _isnan(v) #define isinf(v) (!_finite(v)) #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ #define FF_INTDEF 2 #include typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ typedef unsigned char BYTE; /* char must be 8-bit */ typedef uint16_t WORD; /* 16-bit unsigned integer */ typedef uint32_t DWORD; /* 32-bit unsigned integer */ typedef uint64_t QWORD; /* 64-bit unsigned integer */ typedef WORD WCHAR; /* UTF-16 character type */ #else /* Earlier than C99 */ #define FF_INTDEF 1 typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ typedef unsigned char BYTE; /* char must be 8-bit */ typedef unsigned short WORD; /* 16-bit unsigned integer */ typedef unsigned long DWORD; /* 32-bit unsigned integer */ typedef WORD WCHAR; /* UTF-16 character type */ #endif /* Type of file size and LBA variables */ #if FF_FS_EXFAT #if FF_INTDEF != 2 #error exFAT feature wants C99 or later #endif typedef QWORD FSIZE_t; #if FF_LBA64 typedef QWORD LBA_t; #else typedef DWORD LBA_t; #endif #else #if FF_LBA64 #error exFAT needs to be enabled when enable 64-bit LBA #endif typedef DWORD FSIZE_t; typedef DWORD LBA_t; #endif /* Type of path name strings on FatFs API (TCHAR) */ #if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */ typedef WCHAR TCHAR; #define _T(x) L ## x #define _TEXT(x) L ## x #elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */ typedef char TCHAR; #define _T(x) u8 ## x #define _TEXT(x) u8 ## x #elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */ typedef DWORD TCHAR; #define _T(x) U ## x #define _TEXT(x) U ## x #elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3) #error Wrong FF_LFN_UNICODE setting #else /* ANSI/OEM code in SBCS/DBCS */ typedef char TCHAR; #define _T(x) x #define _TEXT(x) x #endif /* Definitions of volume management */ #if FF_MULTI_PARTITION /* Multiple partition configuration */ typedef struct { BYTE pd; /* Physical drive number */ BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ } PARTITION; extern PARTITION VolToPart[]; /* Volume - Partition mapping table */ #endif #if FF_STR_VOLUME_ID #ifndef FF_VOLUME_STRS extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */ #endif #endif /* Filesystem object structure (FATFS) */ typedef struct { BYTE fs_type; /* Filesystem type (0:not mounted) */ BYTE pdrv; /* Volume hosting physical drive */ BYTE ldrv; /* Logical drive number (used only when FF_FS_REENTRANT) */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] status (b0:dirty) */ BYTE fsi_flag; /* FSINFO status (b7:disabled, b0:dirty) */ WORD id; /* Volume mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD csize; /* Cluster size [sectors] */ #if FF_MAX_SS != FF_MIN_SS WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ #endif #if FF_USE_LFN WCHAR* lfnbuf; /* LFN working buffer */ #endif #if FF_FS_EXFAT BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ #endif #if !FF_FS_READONLY DWORD last_clst; /* Last allocated cluster */ DWORD free_clst; /* Number of free clusters */ #endif #if FF_FS_RPATH DWORD cdir; /* Current directory start cluster (0:root) */ #if FF_FS_EXFAT DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ #endif #endif DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ DWORD fsize; /* Number of sectors per FAT */ LBA_t volbase; /* Volume base sector */ LBA_t fatbase; /* FAT base sector */ LBA_t dirbase; /* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */ LBA_t database; /* Data base sector */ #if FF_FS_EXFAT LBA_t bitbase; /* Allocation bitmap base sector */ #endif LBA_t winsect; /* Current sector appearing in the win[] */ BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFS; /* Object ID and allocation information (FFOBJID) */ typedef struct { FATFS* fs; /* Pointer to the hosting volume of this object */ WORD id; /* Hosting volume's mount ID */ BYTE attr; /* Object attribute */ BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ FSIZE_t objsize; /* Object size (valid when sclust != 0) */ #if FF_FS_EXFAT DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */ DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */ DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */ #endif #if FF_FS_LOCK UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ #endif } FFOBJID; /* File object structure (FIL) */ typedef struct { FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ BYTE flag; /* File status flags */ BYTE err; /* Abort flag (error code) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */ #if !FF_FS_READONLY LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ #endif #if FF_USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ #endif #if !FF_FS_TINY BYTE buf[FF_MAX_SS]; /* File private data read/write window */ #endif } FIL; /* Directory object structure (DIR) */ typedef struct { FFOBJID obj; /* Object identifier */ DWORD dptr; /* Current read/write offset */ DWORD clust; /* Current cluster */ LBA_t sect; /* Current sector (0:Read operation has terminated) */ BYTE* dir; /* Pointer to the directory item in the win[] */ BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ #if FF_USE_LFN DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ #endif #if FF_USE_FIND const TCHAR* pat; /* Pointer to the name matching pattern */ #endif } DIR; /* File information structure (FILINFO) */ typedef struct { FSIZE_t fsize; /* File size */ WORD fdate; /* Modified date */ WORD ftime; /* Modified time */ BYTE fattrib; /* File attribute */ #if FF_USE_LFN TCHAR altname[FF_SFN_BUF + 1];/* Alternative file name */ TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */ #else TCHAR fname[12 + 1]; /* File name */ #endif } FILINFO; /* Format parameter structure (MKFS_PARM) */ typedef struct { BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */ BYTE n_fat; /* Number of FATs */ UINT align; /* Data area alignment (sector) */ UINT n_root; /* Number of root directory entries */ DWORD au_size; /* Cluster size (byte) */ } MKFS_PARM; /* File function return code (FRESULT) */ typedef enum { FR_OK = 0, /* (0) Succeeded */ FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ FR_INT_ERR, /* (2) Assertion failed */ FR_NOT_READY, /* (3) The physical drive cannot work */ FR_NO_FILE, /* (4) Could not find the file */ FR_NO_PATH, /* (5) Could not find the path */ FR_INVALID_NAME, /* (6) The path name format is invalid */ FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ FR_EXIST, /* (8) Access denied due to prohibited access */ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ FR_NOT_ENABLED, /* (12) The volume has no work area */ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ } FRESULT; /*--------------------------------------------------------------*/ /* FatFs Module Application Interface */ /*--------------------------------------------------------------*/ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ FRESULT f_close (FIL* fp); /* Close an open file object */ FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ FRESULT f_truncate (FIL* fp); /* Truncate the file */ FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ FRESULT f_closedir (DIR* dp); /* Close an open directory */ FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ FRESULT f_chdir (const TCHAR* path); /* Change current directory */ FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */ FRESULT f_setcp (WORD cp); /* Set current code page */ int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ /* Some API fucntions are implemented as macro */ #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) #define f_error(fp) ((fp)->err) #define f_tell(fp) ((fp)->fptr) #define f_size(fp) ((fp)->obj.objsize) #define f_rewind(fp) f_lseek((fp), 0) #define f_rewinddir(dp) f_readdir((dp), 0) #define f_rmdir(path) f_unlink(path) #define f_unmount(path) f_mount(0, path, 0) /*--------------------------------------------------------------*/ /* Additional Functions */ /*--------------------------------------------------------------*/ /* RTC function (provided by user) */ #if !FF_FS_READONLY && !FF_FS_NORTC DWORD get_fattime (void); /* Get current time */ #endif /* LFN support functions (defined in ffunicode.c) */ #if FF_USE_LFN >= 1 WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */ DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */ #endif /* O/S dependent functions (samples available in ffsystem.c) */ #if FF_USE_LFN == 3 /* Dynamic memory allocation */ void* ff_memalloc (UINT msize); /* Allocate memory block */ void ff_memfree (void* mblock); /* Free memory block */ #endif #if FF_FS_REENTRANT /* Sync functions */ int ff_mutex_create (int vol); /* Create a sync object */ void ff_mutex_delete (int vol); /* Delete a sync object */ int ff_mutex_take (int vol); /* Lock sync object */ void ff_mutex_give (int vol); /* Unlock sync object */ #endif /*--------------------------------------------------------------*/ /* Flags and Offset Address */ /*--------------------------------------------------------------*/ /* File access mode and open method flags (3rd argument of f_open) */ #define FA_READ 0x01 #define FA_WRITE 0x02 #define FA_OPEN_EXISTING 0x00 #define FA_CREATE_NEW 0x04 #define FA_CREATE_ALWAYS 0x08 #define FA_OPEN_ALWAYS 0x10 #define FA_OPEN_APPEND 0x30 /* Fast seek controls (2nd argument of f_lseek) */ #define CREATE_LINKMAP ((FSIZE_t)0 - 1) /* Format options (2nd argument of f_mkfs) */ #define FM_FAT 0x01 #define FM_FAT32 0x02 #define FM_EXFAT 0x04 #define FM_ANY 0x07 #define FM_SFD 0x08 /* Filesystem type (FATFS.fs_type) */ #define FS_FAT12 1 #define FS_FAT16 2 #define FS_FAT32 3 #define FS_EXFAT 4 /* File attribute bits for directory entry (FILINFO.fattrib) */ #define AM_RDO 0x01 /* Read only */ #define AM_HID 0x02 /* Hidden */ #define AM_SYS 0x04 /* System */ #define AM_DIR 0x10 /* Directory */ #define AM_ARC 0x20 /* Archive */ #ifdef __cplusplus } #endif #endif /* FF_DEFINED */ ================================================ FILE: lib/fatfs/source/ffconf.h ================================================ /*---------------------------------------------------------------------------/ / Configurations of FatFs Module /---------------------------------------------------------------------------*/ #define FFCONF_DEF 80286 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations /---------------------------------------------------------------------------*/ #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 0 /* 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 0 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ #define FF_USE_FASTSEEK 0 /* 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 1 #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 2 /* 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 4 /* Number of volumes (logical drives) to be used. (1-10) */ #define FF_STR_VOLUME_ID 0 #define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" /* 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 ---*/ ================================================ FILE: lib/fatfs/source/ffsystem.c ================================================ /*------------------------------------------------------------------------*/ /* A Sample Code of User Provided OS Dependent Functions for FatFs */ /*------------------------------------------------------------------------*/ #include "ff.h" #if FF_USE_LFN == 3 /* Use dynamic memory allocation */ /*------------------------------------------------------------------------*/ /* Allocate/Free a Memory Block */ /*------------------------------------------------------------------------*/ #include /* with POSIX API */ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ UINT msize /* Number of bytes to allocate */ ) { return malloc((size_t)msize); /* Allocate a new memory block */ } void ff_memfree ( void* mblock /* Pointer to the memory block to free (no effect if null) */ ) { free(mblock); /* Free the memory block */ } #endif #if FF_FS_REENTRANT /* Mutal exclusion */ /*------------------------------------------------------------------------*/ /* Definitions of Mutex */ /*------------------------------------------------------------------------*/ #define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */ #if OS_TYPE == 0 /* Win32 */ #include static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */ #elif OS_TYPE == 1 /* uITRON */ #include "itron.h" #include "kernel.h" static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */ #elif OS_TYPE == 2 /* uc/OS-II */ #include "includes.h" static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */ #elif OS_TYPE == 3 /* FreeRTOS */ #include "FreeRTOS.h" #include "semphr.h" static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */ #elif OS_TYPE == 4 /* CMSIS-RTOS */ #include "cmsis_os.h" static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */ #endif /*------------------------------------------------------------------------*/ /* Create a Mutex */ /*------------------------------------------------------------------------*/ /* This function is called in f_mount function to create a new mutex / or semaphore for the volume. When a 0 is returned, the f_mount function / fails with FR_INT_ERR. */ int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ ) { #if OS_TYPE == 0 /* Win32 */ Mutex[vol] = CreateMutex(NULL, FALSE, NULL); return (int)(Mutex[vol] != INVALID_HANDLE_VALUE); #elif OS_TYPE == 1 /* uITRON */ T_CMTX cmtx = {TA_TPRI,1}; Mutex[vol] = acre_mtx(&cmtx); return (int)(Mutex[vol] > 0); #elif OS_TYPE == 2 /* uC/OS-II */ OS_ERR err; Mutex[vol] = OSMutexCreate(0, &err); return (int)(err == OS_NO_ERR); #elif OS_TYPE == 3 /* FreeRTOS */ Mutex[vol] = xSemaphoreCreateMutex(); return (int)(Mutex[vol] != NULL); #elif OS_TYPE == 4 /* CMSIS-RTOS */ osMutexDef(cmsis_os_mutex); Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex)); return (int)(Mutex[vol] != NULL); #endif } /*------------------------------------------------------------------------*/ /* Delete a Mutex */ /*------------------------------------------------------------------------*/ /* This function is called in f_mount function to delete a mutex or / semaphore of the volume created with ff_mutex_create function. */ void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ ) { #if OS_TYPE == 0 /* Win32 */ CloseHandle(Mutex[vol]); #elif OS_TYPE == 1 /* uITRON */ del_mtx(Mutex[vol]); #elif OS_TYPE == 2 /* uC/OS-II */ OS_ERR err; OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err); #elif OS_TYPE == 3 /* FreeRTOS */ vSemaphoreDelete(Mutex[vol]); #elif OS_TYPE == 4 /* CMSIS-RTOS */ osMutexDelete(Mutex[vol]); #endif } /*------------------------------------------------------------------------*/ /* Request a Grant to Access the Volume */ /*------------------------------------------------------------------------*/ /* This function is called on enter file functions to lock the volume. / When a 0 is returned, the file function fails with FR_TIMEOUT. */ int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ ) { #if OS_TYPE == 0 /* Win32 */ return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0); #elif OS_TYPE == 1 /* uITRON */ return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK); #elif OS_TYPE == 2 /* uC/OS-II */ OS_ERR err; OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err)); return (int)(err == OS_NO_ERR); #elif OS_TYPE == 3 /* FreeRTOS */ return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE); #elif OS_TYPE == 4 /* CMSIS-RTOS */ return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK); #endif } /*------------------------------------------------------------------------*/ /* Release a Grant to Access the Volume */ /*------------------------------------------------------------------------*/ /* This function is called on leave file functions to unlock the volume. */ void ff_mutex_give ( int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ ) { #if OS_TYPE == 0 /* Win32 */ ReleaseMutex(Mutex[vol]); #elif OS_TYPE == 1 /* uITRON */ unl_mtx(Mutex[vol]); #elif OS_TYPE == 2 /* uC/OS-II */ OSMutexPost(Mutex[vol]); #elif OS_TYPE == 3 /* FreeRTOS */ xSemaphoreGive(Mutex[vol]); #elif OS_TYPE == 4 /* CMSIS-RTOS */ osMutexRelease(Mutex[vol]); #endif } #endif /* FF_FS_REENTRANT */ ================================================ FILE: lib/fatfs/source/ffunicode.c ================================================ /*------------------------------------------------------------------------*/ /* Unicode Handling Functions for FatFs R0.13 and Later */ /*------------------------------------------------------------------------*/ /* This module will occupy a huge memory in the .rodata section when the */ /* FatFs is configured for LFN with DBCS. If the system has a Unicode */ /* library for the code conversion, this module should be modified to use */ /* it to avoid silly memory consumption. */ /*------------------------------------------------------------------------*/ /* / Copyright (C) 2022, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided / that the following condition is met: / / 1. Redistributions of source code must retain the above copyright notice, / this condition and the following disclaimer. / / This software is provided by the copyright holder and contributors "AS IS" / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. */ #include "ff.h" #if FF_USE_LFN != 0 /* This module will be blanked if in non-LFN configuration */ #define MERGE2(a, b) a ## b #define CVTBL(tbl, cp) MERGE2(tbl, cp) /*------------------------------------------------------------------------*/ /* Code Conversion Tables */ /*------------------------------------------------------------------------*/ #if FF_CODE_PAGE == 932 || FF_CODE_PAGE == 0 /* Japanese */ static const WCHAR uni2oem932[] = { /* Unicode --> Shift_JIS pairs */ 0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D, 0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180, 0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2, 0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6, 0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA, 0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE, 0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2, 0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6, 0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2, 0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6, 0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA, 0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE, 0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2, 0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6, 0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442, 0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447, 0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B, 0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F, 0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453, 0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457, 0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B, 0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F, 0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472, 0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477, 0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B, 0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480, 0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484, 0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488, 0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C, 0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490, 0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C, 0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168, 0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163, 0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6, 0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0, 0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757, 0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B, 0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41, 0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45, 0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49, 0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB, 0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD, 0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9, 0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187, 0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8, 0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7, 0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6, 0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF, 0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2, 0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB, 0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740, 0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744, 0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748, 0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C, 0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750, 0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F, 0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1, 0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4, 0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5, 0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7, 0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6, 0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8, 0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9, 0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1, 0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5, 0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B, 0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A, 0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4, 0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141, 0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159, 0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173, 0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177, 0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7, 0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780, 0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1, 0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5, 0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9, 0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD, 0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1, 0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5, 0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9, 0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD, 0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1, 0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5, 0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9, 0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD, 0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1, 0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5, 0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9, 0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD, 0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1, 0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5, 0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9, 0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED, 0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1, 0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154, 0x309E, 0x8155, 0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342, 0x30A4, 0x8343, 0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346, 0x30A8, 0x8347, 0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A, 0x30AC, 0x834B, 0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E, 0x30B0, 0x834F, 0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352, 0x30B4, 0x8353, 0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356, 0x30B8, 0x8357, 0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A, 0x30BC, 0x835B, 0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E, 0x30C0, 0x835F, 0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362, 0x30C4, 0x8363, 0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366, 0x30C8, 0x8367, 0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A, 0x30CC, 0x836B, 0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E, 0x30D0, 0x836F, 0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372, 0x30D4, 0x8373, 0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376, 0x30D8, 0x8377, 0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A, 0x30DC, 0x837B, 0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E, 0x30E0, 0x8380, 0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383, 0x30E4, 0x8384, 0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387, 0x30E8, 0x8388, 0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B, 0x30EC, 0x838C, 0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F, 0x30F0, 0x8390, 0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393, 0x30F4, 0x8394, 0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145, 0x30FC, 0x815B, 0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A, 0x3232, 0x878B, 0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786, 0x32A6, 0x8787, 0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765, 0x330D, 0x8769, 0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761, 0x3323, 0x876B, 0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C, 0x3336, 0x8766, 0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D, 0x334D, 0x8762, 0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E, 0x337C, 0x878F, 0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772, 0x338F, 0x8773, 0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771, 0x33A1, 0x8775, 0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA, 0x4E01, 0x929A, 0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4, 0x4E09, 0x8E4F, 0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573, 0x4E0E, 0x975E, 0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E, 0x4E15, 0x98A1, 0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75, 0x4E19, 0x95B8, 0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0, 0x4E28, 0xFA68, 0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3, 0x4E32, 0x8BF8, 0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F, 0x4E3B, 0x8EE5, 0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7, 0x4E43, 0x9454, 0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1, 0x4E4E, 0x8CC1, 0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8, 0x4E57, 0x8FE6, 0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3, 0x4E5E, 0x8CEE, 0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790, 0x4E73, 0x93FB, 0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA, 0x4E85, 0x98AB, 0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188, 0x4E8A, 0x98AD, 0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0, 0x4E91, 0x895D, 0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4, 0x4E98, 0x986A, 0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F, 0x4E9E, 0x98B1, 0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653, 0x4EA2, 0x98B4, 0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692, 0x4EA8, 0x8B9C, 0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0, 0x4EAE, 0x97BA, 0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7, 0x4EBA, 0x906C, 0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC, 0x4EC4, 0x98BA, 0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1, 0x4ECB, 0x89EE, 0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7, 0x4ED4, 0x8E65, 0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD, 0x4ED8, 0x9574, 0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE, 0x4EDF, 0x98C0, 0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF, 0x4EE5, 0x88C8, 0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2, 0x4EF2, 0x9287, 0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443, 0x4EFC, 0xFA6A, 0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C, 0x4F09, 0x98C2, 0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA, 0x4F0F, 0x959A, 0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF, 0x4F1C, 0x98E5, 0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4, 0x4F34, 0x94BA, 0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D, 0x4F3A, 0x8E66, 0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF, 0x4F46, 0x9241, 0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1, 0x4F4F, 0x8F5A, 0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC, 0x4F55, 0x89BD, 0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D, 0x4F5A, 0x98C3, 0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6, 0x4F5E, 0x9B43, 0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF, 0x4F73, 0x89C0, 0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD, 0x4F7C, 0x8CF1, 0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2, 0x4F88, 0x98CA, 0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98, 0x4F8F, 0x98CB, 0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72, 0x4F96, 0x98D3, 0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F, 0x4F9D, 0x88CB, 0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44, 0x4FAD, 0x9699, 0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E, 0x4FB6, 0x97B5, 0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3, 0x4FC4, 0x89E2, 0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73, 0x4FCE, 0x98D7, 0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5, 0x4FD7, 0x91AD, 0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9, 0x4FDD, 0x95DB, 0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693, 0x4FE4, 0x98DD, 0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB, 0x4FF3, 0x946F, 0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE, 0x4FFA, 0x89B4, 0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4, 0x5006, 0x98ED, 0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B, 0x500F, 0xE0C5, 0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1, 0x5016, 0x8CF4, 0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77, 0x501F, 0x8ED8, 0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED, 0x5024, 0x926C, 0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0, 0x5029, 0x98E8, 0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9, 0x502D, 0x9860, 0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74, 0x5042, 0xFA7A, 0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF, 0x5048, 0x98F3, 0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2, 0x5055, 0x98F1, 0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2, 0x5065, 0x8C92, 0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3, 0x5074, 0x91A4, 0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7, 0x507D, 0x8B55, 0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654, 0x5091, 0x8C86, 0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5, 0x509A, 0x98F9, 0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC, 0x50B3, 0x9942, 0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D, 0x50BE, 0x8C58, 0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940, 0x50CA, 0x9941, 0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1, 0x50D5, 0x966C, 0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB, 0x50DE, 0x9945, 0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D, 0x50ED, 0x9947, 0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B, 0x50F9, 0x994A, 0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D, 0x5102, 0x994E, 0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2, 0x5114, 0x9951, 0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4, 0x511A, 0x9952, 0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744, 0x5132, 0x96D7, 0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957, 0x513C, 0x9956, 0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2, 0x5143, 0x8CB3, 0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B, 0x5147, 0x8BA2, 0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E, 0x514B, 0x8D8E, 0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365, 0x5150, 0x8E99, 0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D, 0x515C, 0x8A95, 0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC, 0x5168, 0x9153, 0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA, 0x516C, 0x8CF6, 0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4, 0x5175, 0x95BA, 0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354, 0x517C, 0x8C93, 0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0, 0x5186, 0x897E, 0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965, 0x518D, 0x8DC4, 0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968, 0x5192, 0x9660, 0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B, 0x5197, 0x8FE7, 0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5, 0x51A2, 0x996E, 0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D, 0x51A8, 0x9579, 0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971, 0x51AC, 0x937E, 0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974, 0x51B3, 0x9972, 0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8, 0x51B7, 0x97E2, 0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6, 0x51C5, 0x9978, 0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C, 0x51CC, 0x97BD, 0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A, 0x51DC, 0xEAA3, 0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D, 0x51E6, 0x8F88, 0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2, 0x51EC, 0xFA83, 0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D, 0x51F5, 0x9981, 0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A, 0x51FA, 0x8F6F, 0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381, 0x5203, 0x906E, 0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8, 0x5208, 0x8AA0, 0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986, 0x5211, 0x8C59, 0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1, 0x521D, 0x8F89, 0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987, 0x5229, 0x9798, 0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E, 0x5233, 0x998A, 0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94, 0x5239, 0x998B, 0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4, 0x5244, 0x998D, 0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E, 0x524C, 0x998F, 0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991, 0x5256, 0x9655, 0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95, 0x5264, 0x8DDC, 0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992, 0x526F, 0x959B, 0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84, 0x5273, 0x9995, 0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997, 0x527F, 0x9996, 0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C, 0x5289, 0x97AB, 0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A, 0x5294, 0x9999, 0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7, 0x52A0, 0x89C1, 0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95, 0x52AA, 0x9377, 0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1, 0x52AF, 0xFB77, 0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3, 0x52B9, 0x8CF8, 0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87, 0x52C1, 0x99A4, 0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745, 0x52C9, 0x95D7, 0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE, 0x52D7, 0x99A6, 0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88, 0x52DD, 0x8F9F, 0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB, 0x52E2, 0x90A8, 0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9, 0x52E7, 0x8AA9, 0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD, 0x52F8, 0x99AE, 0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9, 0x52FF, 0x96DC, 0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5, 0x5305, 0x95EF, 0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1, 0x530D, 0x99B3, 0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6, 0x5316, 0x89BB, 0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7, 0x531D, 0x9178, 0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8, 0x5324, 0xFA8B, 0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA, 0x5333, 0x99BB, 0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6, 0x533B, 0x88E3, 0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C, 0x5343, 0x90E7, 0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1, 0x5348, 0x8CDF, 0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2, 0x5351, 0x94DA, 0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6, 0x5357, 0x93EC, 0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D, 0x535E, 0x99C4, 0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5, 0x536E, 0x99C6, 0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB, 0x5372, 0xFA8C, 0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791, 0x5377, 0x99C9, 0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8, 0x5382, 0x99CA, 0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB, 0x5398, 0x97D0, 0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC, 0x53A5, 0x99CE, 0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958, 0x53AD, 0x897D, 0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E, 0x53B3, 0x8CB5, 0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51, 0x53C3, 0x99D2, 0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79, 0x53CB, 0x9746, 0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB, 0x53D4, 0x8F66, 0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96, 0x53DB, 0x94BE, 0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962, 0x53E2, 0x9170, 0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5, 0x53E8, 0x99D9, 0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9, 0x53EC, 0x8FA2, 0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2, 0x53F0, 0x91E4, 0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945, 0x53F6, 0x8A90, 0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB, 0x5401, 0x99DC, 0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87, 0x5409, 0x8B67, 0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF, 0x540D, 0x96BC, 0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366, 0x5411, 0x8CFC, 0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1, 0x5420, 0x9669, 0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC, 0x542C, 0x99DF, 0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3, 0x5438, 0x8B7A, 0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1, 0x543D, 0x99DD, 0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843, 0x5446, 0x95F0, 0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90, 0x544E, 0x99E6, 0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC, 0x546A, 0x8EF4, 0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1, 0x5475, 0x99E8, 0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF, 0x547C, 0x8CC4, 0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2, 0x5486, 0x99F4, 0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861, 0x548E, 0x99E9, 0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE, 0x549C, 0xFA91, 0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8, 0x54A8, 0x99FC, 0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9, 0x54AF, 0x9A5D, 0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7, 0x54BC, 0x9A44, 0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3, 0x54C1, 0x9569, 0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5, 0x54C8, 0x99FB, 0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5, 0x54E2, 0x9A4E, 0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3, 0x54E9, 0x9689, 0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E, 0x54FA, 0x9A4D, 0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953, 0x5506, 0x8DB4, 0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382, 0x5514, 0x9A49, 0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742, 0x5531, 0x8FA5, 0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F, 0x553E, 0x91C1, 0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55, 0x5546, 0x8FA4, 0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B, 0x5556, 0x9A56, 0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A, 0x5563, 0x9A51, 0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61, 0x5580, 0x9A5C, 0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95, 0x5587, 0x9A68, 0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D, 0x5598, 0x9A62, 0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC, 0x559D, 0x8A85, 0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96, 0x55A8, 0x9A69, 0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69, 0x55AC, 0x8BAA, 0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963, 0x55C4, 0x9A6D, 0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70, 0x55DA, 0x9A6A, 0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B, 0x55E4, 0x9A6F, 0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75, 0x55FE, 0x9A74, 0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71, 0x5616, 0x9A73, 0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76, 0x5629, 0x89DC, 0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D, 0x5634, 0x9A7B, 0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C, 0x564C, 0x9158, 0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A, 0x5664, 0x9A81, 0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80, 0x566C, 0x9A83, 0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6, 0x5680, 0x9A86, 0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87, 0x568F, 0x9A8A, 0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458, 0x56A5, 0x9A8B, 0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D, 0x56BC, 0x9A90, 0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F, 0x56C3, 0x9A92, 0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96, 0x56D3, 0x9A97, 0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA, 0x56DB, 0x8E6C, 0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263, 0x56EE, 0x9A99, 0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D, 0x56F9, 0x9A9A, 0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C, 0x5700, 0x9A9B, 0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F, 0x5709, 0x9A9E, 0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97, 0x5712, 0x8980, 0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3, 0x571C, 0x9AA6, 0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3, 0x5728, 0x8DDD, 0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8, 0x5738, 0x9AA9, 0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2, 0x5747, 0x8BCF, 0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD, 0x5750, 0x8DBF, 0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1, 0x5764, 0x8DA3, 0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE, 0x576A, 0x92D8, 0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0, 0x5789, 0x9AB3, 0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5, 0x57A2, 0x8D43, 0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8, 0x57AC, 0xFA98, 0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF, 0x57C3, 0x9ABA, 0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99, 0x57CB, 0x9684, 0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE, 0x57D4, 0x9ABC, 0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6, 0x57E0, 0x9575, 0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7, 0x57F9, 0x947C, 0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678, 0x5802, 0x93B0, 0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF, 0x580B, 0x9AC2, 0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4, 0x5821, 0x9AC6, 0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F, 0x5830, 0x8981, 0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367, 0x583A, 0x8DE4, 0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB, 0x584A, 0x89F2, 0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB, 0x5854, 0x9383, 0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7, 0x585A, 0x92CB, 0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996, 0x586B, 0x9355, 0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F, 0x5879, 0x9ACD, 0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE, 0x5893, 0x95E6, 0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D, 0x589F, 0x9AD0, 0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6, 0x58B2, 0xFA9E, 0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF, 0x58BA, 0x9AD2, 0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7, 0x58C5, 0x9AD7, 0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB, 0x58D1, 0x9AD9, 0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA, 0x58D8, 0x9ADC, 0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3, 0x58DF, 0x9AE0, 0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D, 0x58EC, 0x9070, 0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA, 0x58F1, 0x88EB, 0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3, 0x58FA, 0x9AE2, 0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6, 0x5902, 0x9AE7, 0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F, 0x590F, 0x89C4, 0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F, 0x5918, 0x99C7, 0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA, 0x591C, 0x96E9, 0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5, 0x5929, 0x9356, 0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED, 0x592D, 0x9AEE, 0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF, 0x5937, 0x88CE, 0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982, 0x5947, 0x8AEF, 0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5, 0x594F, 0x9174, 0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0, 0x5954, 0x967A, 0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7, 0x595A, 0x9AF6, 0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9, 0x5962, 0x9AF8, 0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA, 0x5968, 0x8FA7, 0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB, 0x596E, 0x95B1, 0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40, 0x597D, 0x8D44, 0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC, 0x5984, 0x96CF, 0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57, 0x5996, 0x9764, 0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42, 0x59A3, 0x9B45, 0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657, 0x59AC, 0x9369, 0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5, 0x59BB, 0x8DC8, 0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F, 0x59CB, 0x8E6E, 0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9, 0x59D4, 0x88CF, 0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49, 0x59E5, 0x8957, 0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3, 0x59EB, 0x9550, 0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70, 0x5A01, 0x88D0, 0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F, 0x5A18, 0x96BA, 0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E, 0x5A20, 0x9050, 0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2, 0x5A35, 0x9B56, 0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53, 0x5A41, 0x984B, 0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5, 0x5A62, 0x9B58, 0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54, 0x5A7F, 0x96B9, 0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551, 0x5ABC, 0x9B5B, 0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5, 0x5AC2, 0x9B5E, 0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99, 0x5AD0, 0x9B6B, 0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284, 0x5AE3, 0x9B60, 0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65, 0x5AFB, 0x9B66, 0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67, 0x5B16, 0x9B69, 0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA, 0x5B30, 0x8964, 0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E, 0x5B40, 0x9B71, 0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71, 0x5B51, 0x9B72, 0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6, 0x5B57, 0x8E9A, 0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75, 0x5B5C, 0x8E79, 0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47, 0x5B64, 0x8CC7, 0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77, 0x5B6B, 0x91B7, 0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79, 0x5B75, 0x9B7A, 0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E, 0x5B83, 0x9B80, 0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7, 0x5B89, 0x88C0, 0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3, 0x5B8F, 0x8D47, 0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF, 0x5B99, 0x9288, 0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58, 0x5B9D, 0x95F3, 0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9, 0x5BA4, 0x8EBA, 0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B, 0x5BB0, 0x8DC9, 0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA, 0x5BB6, 0x89C6, 0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68, 0x5BC0, 0xFAA7, 0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1, 0x5BC5, 0x93D0, 0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85, 0x5BCC, 0x9578, 0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5, 0x5BD4, 0x9B86, 0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051, 0x5BDE, 0x9B8B, 0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A, 0x5BE4, 0x9B88, 0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A, 0x5BE8, 0x9ECB, 0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA, 0x5BEE, 0x97BE, 0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E, 0x5BF6, 0x9B8F, 0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE, 0x5BFF, 0x8EF5, 0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB, 0x5C05, 0x9B91, 0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93, 0x5C09, 0x88D1, 0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94, 0x5C0E, 0x93B1, 0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95, 0x5C16, 0x90EB, 0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96, 0x5C22, 0x9B97, 0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4, 0x5C31, 0x8F41, 0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA, 0x5C3B, 0x904B, 0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6, 0x5C3F, 0x9441, 0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F, 0x5C46, 0x9B9C, 0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE, 0x5C4D, 0x8E72, 0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F, 0x5C51, 0x8BFB, 0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE, 0x5C60, 0x936A, 0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A, 0x5C6C, 0x9BA2, 0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52, 0x5C76, 0x9BA5, 0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2, 0x5C91, 0x9BA8, 0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC, 0x5CA8, 0x915A, 0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6, 0x5CB1, 0x91D0, 0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF, 0x5CB8, 0x8ADD, 0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE, 0x5CBE, 0x9BB1, 0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3, 0x5CE0, 0x93BB, 0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4, 0x5CEA, 0x9BB9, 0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4, 0x5CF5, 0xFAAE, 0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73, 0x5CFD, 0x9BB5, 0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8, 0x5D11, 0x9BC0, 0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52, 0x5D17, 0x9BBC, 0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3, 0x5D1B, 0x9BBF, 0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF, 0x5D29, 0x95F6, 0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6, 0x5D4E, 0x9BC8, 0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0, 0x5D5C, 0x9BBD, 0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3, 0x5D6F, 0x8DB5, 0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF, 0x5D84, 0x9BCE, 0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8, 0x5D90, 0x9BD5, 0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2, 0x5DAE, 0x9BD3, 0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5, 0x5DBA, 0x97E4, 0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8, 0x5DCC, 0x8ADE, 0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB, 0x5DD3, 0x9BDA, 0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC, 0x5DDE, 0x8F42, 0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48, 0x5DE6, 0x8DB6, 0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE, 0x5DEE, 0x8DB7, 0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4, 0x5DF4, 0x9462, 0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA, 0x5DFD, 0x9246, 0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A, 0x5E06, 0x94BF, 0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4, 0x5E16, 0x929F, 0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5, 0x5E1D, 0x92E9, 0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8, 0x5E2F, 0x91D1, 0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6, 0x5E37, 0x9BE7, 0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA, 0x5E43, 0x9BE9, 0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1, 0x5E4C, 0x9679, 0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B, 0x5E57, 0x9BEC, 0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF, 0x5E63, 0x95BC, 0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD, 0x5E74, 0x944E, 0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B, 0x5E79, 0x8AB2, 0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763, 0x5E7D, 0x9748, 0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1, 0x5E83, 0x8D4C, 0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0, 0x5E8F, 0x8F98, 0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358, 0x5E9A, 0x8D4D, 0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378, 0x5EA7, 0x8DC0, 0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1, 0x5EB6, 0x8F8E, 0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8, 0x5EC2, 0x9BF9, 0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5, 0x5ECA, 0x984C, 0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66, 0x5ED6, 0x9C40, 0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42, 0x5EDF, 0x955F, 0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45, 0x5EE3, 0x9C41, 0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49, 0x5EF0, 0x9C4C, 0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D, 0x5EF6, 0x8984, 0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A, 0x5EFB, 0x89F4, 0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9, 0x5F01, 0x95D9, 0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51, 0x5F0A, 0x95BE, 0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF, 0x5F0F, 0x8EAE, 0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C, 0x5F14, 0x92A2, 0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4, 0x5F18, 0x8D4F, 0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7, 0x5F25, 0x96ED, 0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57, 0x5F2D, 0x9C58, 0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8, 0x5F35, 0x92A3, 0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A, 0x5F3E, 0x9265, 0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B, 0x5F4A, 0x8BAE, 0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F, 0x5F53, 0x9396, 0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62, 0x5F5C, 0x9C53, 0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60, 0x5F66, 0x9546, 0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556, 0x5F6B, 0x92A4, 0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2, 0x5F71, 0x8965, 0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0, 0x5F7C, 0x94DE, 0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA, 0x5F82, 0x9C68, 0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2, 0x5F87, 0x9C6D, 0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5, 0x5F8C, 0x8CE3, 0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B, 0x5F93, 0x8F5D, 0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F, 0x5F9E, 0x9C6E, 0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72, 0x5FA9, 0x959C, 0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7, 0x5FB3, 0x93BF, 0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F, 0x5FBC, 0x9C74, 0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B, 0x5FCC, 0x8AF5, 0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75, 0x5FD8, 0x9659, 0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A, 0x5FDE, 0xFABB, 0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5, 0x5FF0, 0x9CAB, 0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78, 0x5FFB, 0x9C76, 0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83, 0x600F, 0x9C89, 0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86, 0x6016, 0x957C, 0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5, 0x601D, 0x8E76, 0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D, 0x6026, 0x9C88, 0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82, 0x602A, 0x89F6, 0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84, 0x603A, 0x9C8A, 0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94, 0x6046, 0x9C91, 0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92, 0x6050, 0x8BB0, 0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99, 0x605A, 0x9C8B, 0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E, 0x6062, 0x89F8, 0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270, 0x6068, 0x8DA6, 0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98, 0x606C, 0x9C97, 0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86, 0x6075, 0x8C62, 0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D, 0x6084, 0x9C9F, 0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE, 0x608B, 0x9CA5, 0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3, 0x6094, 0x89F7, 0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E, 0x609B, 0x9CA0, 0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3, 0x60A6, 0x8978, 0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB, 0x60B2, 0x94DF, 0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE, 0x60B6, 0x96E3, 0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC, 0x60C5, 0x8FEE, 0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866, 0x60D3, 0x9CA9, 0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B, 0x60DC, 0x90C9, 0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8, 0x60E1, 0x9CA6, 0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53, 0x60F0, 0x91C4, 0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A, 0x60F4, 0x9CB6, 0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4, 0x60FA, 0x9CB7, 0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44, 0x6103, 0x9CB8, 0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9, 0x610D, 0x9CBC, 0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3, 0x6115, 0x9CB1, 0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4, 0x6120, 0xFAC1, 0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0, 0x612C, 0x9CC5, 0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4, 0x613C, 0x9CC4, 0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3, 0x6142, 0x9CC8, 0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C, 0x614A, 0x9CC2, 0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0, 0x614E, 0x9054, 0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC, 0x6159, 0x9CCD, 0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4, 0x6162, 0x969D, 0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64, 0x6168, 0x8A53, 0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1, 0x6170, 0x88D4, 0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0, 0x6175, 0x9CD7, 0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C, 0x6182, 0x974A, 0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E, 0x6190, 0x97F7, 0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9, 0x6198, 0xFAC6, 0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE, 0x61A7, 0x93B2, 0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB, 0x61AE, 0x9CE1, 0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9, 0x61BE, 0x8AB6, 0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7, 0x61C8, 0x9CE6, 0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA, 0x61CC, 0x9CE2, 0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE, 0x61E6, 0x9CED, 0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF, 0x61F7, 0x9CE5, 0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4, 0x61FD, 0x9CF3, 0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6, 0x6208, 0x9CF7, 0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA, 0x620D, 0x9CF9, 0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4, 0x6212, 0x89FA, 0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD, 0x621A, 0x90CA, 0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40, 0x621F, 0x8C81, 0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42, 0x622E, 0x9D43, 0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45, 0x6233, 0x9D46, 0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF, 0x623F, 0x965B, 0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE, 0x6248, 0xE7BB, 0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB, 0x624E, 0x9D48, 0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF, 0x625B, 0x9D4B, 0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A, 0x6268, 0x9D4D, 0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D, 0x6279, 0x94E1, 0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3, 0x6280, 0x8B5A, 0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4, 0x6289, 0x9D50, 0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52, 0x6293, 0x9D53, 0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54, 0x6297, 0x8D52, 0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2, 0x629E, 0x91F0, 0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB, 0x62B1, 0x95F8, 0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A, 0x62BC, 0x899F, 0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253, 0x62C6, 0x9D5D, 0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66, 0x62CA, 0x9D62, 0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B, 0x62D0, 0x89FB, 0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1, 0x62D4, 0x9D55, 0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9, 0x62DB, 0x8FB5, 0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92, 0x62E1, 0x8A67, 0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68, 0x62EF, 0x9D6D, 0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E, 0x62F6, 0x8E41, 0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C, 0x6301, 0x8E9D, 0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C, 0x6309, 0x88C2, 0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93, 0x631F, 0x8BB2, 0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1, 0x632F, 0x9055, 0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70, 0x633F, 0x917D, 0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71, 0x634F, 0x9D73, 0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB, 0x635C, 0x917B, 0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80, 0x636B, 0x9D7E, 0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78, 0x6377, 0x8FB7, 0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76, 0x6383, 0x917C, 0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6, 0x638E, 0x9D75, 0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74, 0x6398, 0x8C40, 0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9, 0x63A1, 0x8DCC, 0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA, 0x63A7, 0x8D54, 0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B, 0x63AB, 0x9D77, 0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD, 0x63B5, 0x9D7D, 0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83, 0x63C3, 0x91B5, 0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86, 0x63CF, 0x9560, 0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B, 0x63DA, 0x9767, 0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85, 0x63E9, 0x9D82, 0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9, 0x63F6, 0x9D88, 0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9, 0x640F, 0x9D93, 0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91, 0x641C, 0x9D72, 0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0, 0x642D, 0x938B, 0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67, 0x643E, 0x8DEF, 0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345, 0x6460, 0xFACA, 0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95, 0x6476, 0x9D96, 0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82, 0x6488, 0x9D9D, 0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99, 0x649A, 0x9451, 0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350, 0x64A5, 0x9D9B, 0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464, 0x64AE, 0x8E42, 0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68, 0x64BB, 0x9DA3, 0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5, 0x64C5, 0x9DA1, 0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC, 0x64D2, 0x9DA0, 0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F, 0x64E0, 0x9DA9, 0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC, 0x64E6, 0x8E43, 0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD, 0x64F1, 0x9DA6, 0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF, 0x64FA, 0x9DB2, 0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3, 0x6505, 0x9DB7, 0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90, 0x6523, 0x9DB9, 0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA, 0x652C, 0x9DAE, 0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC, 0x6536, 0x9DBE, 0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC, 0x653B, 0x8D55, 0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC, 0x6548, 0x9DC1, 0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571, 0x6551, 0x8B7E, 0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473, 0x6558, 0x9DC5, 0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6, 0x6562, 0x8AB8, 0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68, 0x6570, 0x9094, 0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347, 0x6577, 0x957E, 0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB, 0x6587, 0x95B6, 0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B, 0x658E, 0x8DD6, 0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C, 0x6599, 0x97BF, 0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE, 0x65A1, 0x88B4, 0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580, 0x65AB, 0x9DCF, 0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A, 0x65B0, 0x9056, 0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997, 0x65BD, 0x8E7B, 0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4, 0x65C5, 0x97B7, 0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5, 0x65CF, 0x91B0, 0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8, 0x65DB, 0x9DD7, 0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9, 0x65E5, 0x93FA, 0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C, 0x65E9, 0x9181, 0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB, 0x65FA, 0x89A0, 0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56, 0x6603, 0x9DDE, 0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1, 0x660A, 0x9DDD, 0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8, 0x6613, 0x88D5, 0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4, 0x661E, 0xFAD3, 0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4, 0x6625, 0x8F74, 0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA, 0x662E, 0xFAD2, 0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3, 0x6635, 0x9DE1, 0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B, 0x663F, 0x9E45, 0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57, 0x6644, 0x9DE6, 0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5, 0x6652, 0x8E4E, 0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA, 0x665E, 0x9DE9, 0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB, 0x6665, 0xFAD5, 0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED, 0x6669, 0x94D3, 0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0, 0x6673, 0xFAD9, 0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271, 0x6681, 0x8BC5, 0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9, 0x6688, 0x9DF2, 0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B, 0x6696, 0x9267, 0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA, 0x669D, 0x9DF7, 0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF, 0x66AB, 0x8E62, 0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C, 0x66B8, 0x9E41, 0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB, 0x66BF, 0xFADD, 0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC, 0x66C9, 0x9DFA, 0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43, 0x66DC, 0x976A, 0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46, 0x66E9, 0x9E47, 0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967, 0x66F4, 0x8D58, 0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91, 0x66F9, 0x9182, 0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6, 0x66FD, 0x915D, 0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5, 0x6703, 0x98F0, 0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC, 0x670D, 0x959E, 0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1, 0x6715, 0x92BD, 0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D, 0x671D, 0x92A9, 0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E, 0x6727, 0x9E4F, 0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696, 0x672C, 0x967B, 0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9, 0x6734, 0x9670, 0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55, 0x673A, 0x8AF7, 0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54, 0x6746, 0x9E57, 0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7, 0x6750, 0x8DDE, 0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1, 0x6759, 0x9E5A, 0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9, 0x6760, 0x9E59, 0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B, 0x6764, 0x9E5C, 0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61, 0x676D, 0x8D59, 0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C, 0x6772, 0x9DDC, 0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466, 0x677C, 0x9E60, 0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66, 0x6787, 0x94F8, 0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62, 0x6790, 0x90CD, 0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687, 0x679C, 0x89CA, 0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65, 0x67A2, 0x9095, 0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD, 0x67B3, 0x9E6B, 0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67, 0x67B8, 0x9E6D, 0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4, 0x67C1, 0x91C6, 0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541, 0x67CE, 0x9E74, 0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9, 0x67D3, 0x90F5, 0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D, 0x67DD, 0x9E70, 0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E, 0x67E7, 0x9E76, 0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72, 0x67EF, 0x9E68, 0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4, 0x67F5, 0x8DF2, 0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60, 0x6801, 0xFAE5, 0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968, 0x6813, 0x90F0, 0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78, 0x6821, 0x8D5A, 0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94, 0x682B, 0x9E81, 0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A, 0x6839, 0x8DAA, 0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B, 0x6841, 0x8C85, 0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6, 0x6846, 0x9E79, 0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E, 0x6850, 0x8BCB, 0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA, 0x6854, 0x8B6A, 0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691, 0x685F, 0x8E56, 0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F, 0x6876, 0x89B1, 0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85, 0x6881, 0x97C0, 0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94, 0x688F, 0x9E87, 0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B, 0x689B, 0x9E8B, 0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91, 0x68A2, 0x8FBD, 0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C, 0x68AD, 0x9E88, 0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB, 0x68B3, 0x9E80, 0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E, 0x68BA, 0x9E92, 0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0, 0x68C8, 0xFA64, 0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB, 0x68CD, 0x9E9E, 0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F, 0x68D5, 0x9EA1, 0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249, 0x68DF, 0x938F, 0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6, 0x68E7, 0x9EA0, 0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1, 0x68F9, 0x9EA8, 0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96, 0x6904, 0x9EA4, 0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8, 0x690C, 0x9E9D, 0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93, 0x6912, 0x9EA3, 0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91, 0x691C, 0x8C9F, 0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE, 0x6925, 0x9EA7, 0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC, 0x6930, 0x9EBD, 0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9, 0x693D, 0x9EBB, 0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596, 0x6954, 0x9EB6, 0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E, 0x695C, 0x9EB3, 0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED, 0x6961, 0x9EBE, 0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2, 0x696B, 0x9EB5, 0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C, 0x6973, 0x9480, 0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2, 0x6978, 0x9EB4, 0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79, 0x697E, 0x9EB7, 0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5, 0x698E, 0x897C, 0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5, 0x6998, 0xFAEB, 0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3, 0x69A7, 0x9ED0, 0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3, 0x69B4, 0x9ED6, 0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6, 0x69C1, 0x9EC7, 0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC, 0x69CB, 0x8D5C, 0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA, 0x69D0, 0x9EC5, 0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A, 0x69DD, 0x9ECD, 0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF, 0x69E8, 0x9ED8, 0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE, 0x69F9, 0x9EDD, 0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB, 0x6A02, 0x9ED9, 0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3, 0x6A0C, 0x9EEC, 0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4, 0x6A17, 0x9294, 0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2, 0x6A1F, 0x8FBE, 0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9, 0x6A29, 0x8CA0, 0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1, 0x6A30, 0xFAED, 0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5, 0x6A39, 0x8EF7, 0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB, 0x6A46, 0xFAEF, 0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4, 0x6A58, 0x8B6B, 0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9, 0x6A62, 0x9EF1, 0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED, 0x6A73, 0xFAF0, 0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80, 0x6A80, 0x9268, 0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7, 0x6A90, 0x9EF7, 0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9, 0x6AA2, 0x9EFB, 0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47, 0x6AAE, 0x9E8D, 0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42, 0x6AC1, 0x9EE8, 0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49, 0x6AD3, 0x9845, 0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48, 0x6ADF, 0x9F4A, 0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5, 0x6AEA, 0x9F4D, 0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793, 0x6B05, 0x9F4F, 0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53, 0x6B1D, 0x8954, 0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F, 0x6B23, 0x8BD3, 0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57, 0x6B38, 0x9F56, 0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4, 0x6B3E, 0x8ABC, 0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D, 0x6B4C, 0x89CC, 0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD, 0x6B54, 0x9F60, 0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62, 0x6B61, 0x9F63, 0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F, 0x6B66, 0x9590, 0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95, 0x6B73, 0x8DCE, 0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65, 0x6B7B, 0x8E80, 0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69, 0x6B84, 0x9F68, 0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA, 0x6B8B, 0x8E63, 0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042, 0x6B98, 0x9F6B, 0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F, 0x6BAB, 0x9F70, 0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72, 0x6BB3, 0x9F74, 0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75, 0x6BBA, 0x8E45, 0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361, 0x6BC0, 0x9ACA, 0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78, 0x6BCD, 0x95EA, 0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79, 0x6BD4, 0x94E4, 0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1, 0x6BDF, 0x9F7A, 0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E, 0x6BF3, 0x9F7D, 0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF, 0x6C13, 0x9F82, 0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84, 0x6C23, 0x9F86, 0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558, 0x6C38, 0x8969, 0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3, 0x6C41, 0x8F60, 0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC, 0x6C55, 0x9F88, 0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6, 0x6C5D, 0x93F0, 0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272, 0x6C62, 0x9F89, 0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8, 0x6C70, 0x91BF, 0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88, 0x6C7D, 0x8B44, 0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B, 0x6C83, 0x9780, 0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7, 0x6C8D, 0x9F8C, 0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42, 0x6C96, 0x89AB, 0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F, 0x6CA1, 0x9676, 0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C, 0x6CB1, 0x9F9D, 0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB, 0x6CBA, 0x9F9F, 0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98, 0x6CBE, 0x9F9E, 0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95, 0x6CC5, 0x9F9A, 0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5, 0x6CD3, 0x9F97, 0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2, 0x6CDA, 0xFAF9, 0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641, 0x6CE2, 0x9467, 0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D, 0x6CEA, 0x9FA3, 0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96, 0x6CF3, 0x896A, 0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE, 0x6D12, 0x9FAD, 0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C, 0x6D1E, 0x93B4, 0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B, 0x6D2A, 0x8D5E, 0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC, 0x6D35, 0x9FAB, 0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88, 0x6D3D, 0x9FA8, 0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2, 0x6D45, 0x90F3, 0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C, 0x6D63, 0x9FAF, 0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F, 0x6D6A, 0x9851, 0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC, 0x6D74, 0x9781, 0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3, 0x6D85, 0x9FB8, 0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F, 0x6D8E, 0x9FB5, 0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40, 0x6D99, 0x97DC, 0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41, 0x6DAF, 0x8A55, 0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF, 0x6DBC, 0x97C1, 0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0, 0x6DC7, 0x9FBD, 0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42, 0x6DD1, 0x8F69, 0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391, 0x6DD9, 0x9FC8, 0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9, 0x6DE6, 0x9FBE, 0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA, 0x6DEC, 0x9FC1, 0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44, 0x6DF3, 0x8F7E, 0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43, 0x6DF9, 0x9FB9, 0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45, 0x6E05, 0x90B4, 0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2, 0x6E0A, 0x9FBB, 0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA, 0x6E19, 0x9FD0, 0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF, 0x6E1F, 0x9FD9, 0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4, 0x6E24, 0x9FDD, 0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48, 0x6E29, 0x89B7, 0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD, 0x6E2E, 0x9FCF, 0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46, 0x6E3A, 0x9FDB, 0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA, 0x6E4A, 0x96A9, 0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE, 0x6E58, 0x8FC3, 0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2, 0x6E67, 0x974E, 0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392, 0x6E72, 0x9FD1, 0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC, 0x6E80, 0x969E, 0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED, 0x6E90, 0x8CB9, 0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD, 0x6E9D, 0x8D61, 0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE, 0x6EAA, 0x9FE2, 0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E, 0x6EB7, 0x9FE5, 0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A, 0x6EC2, 0x9FEF, 0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4, 0x6ECB, 0x8EA0, 0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6, 0x6ED4, 0x9FEB, 0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8, 0x6EEC, 0x9FF4, 0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348, 0x6EF7, 0xE042, 0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE, 0x6F01, 0x8B99, 0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97, 0x6F0F, 0x9852, 0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989, 0x6F15, 0x9186, 0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8, 0x6F2B, 0x969F, 0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB, 0x6F38, 0x9151, 0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1, 0x6F45, 0x8AC1, 0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049, 0x6F5C, 0x90F6, 0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052, 0x6F6D, 0xE04B, 0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7, 0x6F74, 0xE06B, 0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D, 0x6F80, 0xE047, 0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F, 0x6F86, 0xE043, 0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050, 0x6F97, 0x8AC0, 0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056, 0x6FAA, 0xE059, 0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C, 0x6FB9, 0xE057, 0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051, 0x6FC3, 0x945A, 0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B, 0x6FD8, 0xE05E, 0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A, 0x6FE1, 0x9447, 0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C, 0x6FEE, 0xE060, 0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A, 0x6FF5, 0xFB4D, 0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068, 0x7001, 0xE066, 0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062, 0x700B, 0xE063, 0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D, 0x7018, 0xE06D, 0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C, 0x701E, 0x93D2, 0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB, 0x7028, 0xFB50, 0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071, 0x703E, 0xE070, 0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5, 0x7063, 0xE073, 0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44, 0x7078, 0x8B84, 0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51, 0x7089, 0x9846, 0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075, 0x7099, 0xE074, 0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259, 0x70AE, 0xE07B, 0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079, 0x70B9, 0x935F, 0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3, 0x70CB, 0xE07D, 0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E, 0x70DF, 0xE07C, 0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082, 0x7104, 0xFB54, 0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B, 0x7119, 0xE084, 0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3, 0x7126, 0x8FC5, 0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56, 0x7147, 0xFB57, 0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7, 0x7155, 0xE086, 0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55, 0x7162, 0xE089, 0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088, 0x7167, 0x8FC6, 0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF, 0x717D, 0x90F8, 0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46, 0x718F, 0xE08D, 0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4, 0x719F, 0x8F6E, 0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D, 0x71B9, 0xE094, 0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452, 0x71C8, 0x9395, 0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3, 0x71D2, 0xE096, 0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093, 0x71DF, 0x9A7A, 0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57, 0x71E7, 0xE09C, 0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7, 0x71F5, 0xE09D, 0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E, 0x71FE, 0xFB5A, 0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1, 0x7210, 0xE0A2, 0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC, 0x722C, 0xE0A6, 0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8, 0x7235, 0x8EDD, 0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9, 0x723C, 0xE0AA, 0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB, 0x7240, 0xE0AC, 0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5, 0x724B, 0xE0AE, 0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF, 0x7259, 0x89E5, 0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4, 0x7261, 0x89B2, 0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8, 0x7272, 0x90B5, 0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1, 0x727E, 0xE0B1, 0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2, 0x7287, 0xE0B4, 0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D, 0x72A2, 0xE0B7, 0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6, 0x72B1, 0xFB5B, 0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9, 0x72BE, 0xFB5C, 0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD, 0x72C6, 0xE0BC, 0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF, 0x72D7, 0x8BE7, 0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1, 0x72E1, 0xE0C2, 0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6, 0x72ED, 0x8BB7, 0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3, 0x72FC, 0x9854, 0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9, 0x7317, 0xE0C6, 0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA, 0x731F, 0x97C2, 0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD, 0x732A, 0x9296, 0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC, 0x7334, 0xE0CB, 0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF, 0x733F, 0x898E, 0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0, 0x734F, 0xE0D1, 0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5, 0x736A, 0xE0D4, 0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8, 0x7377, 0xFB5F, 0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9, 0x7384, 0x8CBA, 0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4, 0x7396, 0x8BE8, 0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC, 0x73BB, 0xE0DE, 0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF, 0x73C8, 0xE0DB, 0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF, 0x73CE, 0xE0DD, 0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2, 0x73E0, 0x8EEC, 0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D, 0x73ED, 0x94C7, 0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66, 0x73F8, 0xE0E7, 0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4, 0x7406, 0x979D, 0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4, 0x7425, 0xE0E6, 0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68, 0x742E, 0xFB6A, 0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5, 0x7435, 0x94FA, 0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB, 0x7441, 0xE0EE, 0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8, 0x745B, 0x896C, 0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC, 0x7460, 0x97DA, 0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2, 0x7469, 0xE0F0, 0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1, 0x7473, 0x8DBA, 0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E, 0x7489, 0xFB6C, 0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D, 0x74A2, 0xE0E3, 0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3, 0x74CA, 0xE0F9, 0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A, 0x74E0, 0xE140, 0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2, 0x74E7, 0xE142, 0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146, 0x74F1, 0xE147, 0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149, 0x74F8, 0xE148, 0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A, 0x7505, 0xE14C, 0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E, 0x7511, 0x8D99, 0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3, 0x751A, 0x9072, 0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6, 0x7523, 0x8E59, 0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770, 0x752B, 0x95E1, 0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363, 0x7531, 0x9752, 0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A, 0x7538, 0x99B2, 0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155, 0x7544, 0xE156, 0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158, 0x754B, 0x9DC0, 0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8, 0x7551, 0x94A8, 0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C, 0x755B, 0xE15A, 0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9, 0x7562, 0x954C, 0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C, 0x7567, 0xE15F, 0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160, 0x756D, 0xE161, 0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4, 0x7574, 0xE166, 0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162, 0x757F, 0x8B45, 0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165, 0x7589, 0xE168, 0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161, 0x758F, 0x9160, 0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B, 0x759D, 0xE16C, 0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975, 0x75B1, 0xE176, 0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172, 0x75B8, 0xE174, 0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173, 0x75BE, 0x8EBE, 0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561, 0x75C7, 0x8FC7, 0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179, 0x75D4, 0x8EA4, 0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A, 0x75DB, 0x92C9, 0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B, 0x75E9, 0x9189, 0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185, 0x75F4, 0x9273, 0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D, 0x75FF, 0xE17E, 0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186, 0x760D, 0xE187, 0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C, 0x7622, 0xE18D, 0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190, 0x7634, 0xE18F, 0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194, 0x7647, 0xE192, 0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC, 0x7656, 0x95C8, 0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197, 0x7662, 0xE198, 0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A, 0x766A, 0xE19B, 0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F, 0x7676, 0xE1A0, 0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F, 0x767C, 0xE1A2, 0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3, 0x7682, 0xFB70, 0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46, 0x7687, 0x8D63, 0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7, 0x7690, 0x8E48, 0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA, 0x769A, 0xE1AB, 0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72, 0x76A6, 0xFB74, 0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD, 0x76B7, 0xEA89, 0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0, 0x76BF, 0x8E4D, 0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E, 0x76C8, 0x896D, 0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4, 0x76D6, 0xE1B3, 0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58, 0x76DE, 0xE1B5, 0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4, 0x76E4, 0x94D5, 0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9, 0x76EE, 0x96DA, 0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A, 0x76FB, 0xE1BB, 0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE, 0x7707, 0xE1BD, 0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5, 0x770C, 0x8CA7, 0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E, 0x7720, 0x96B0, 0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3, 0x7729, 0xE1BF, 0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD, 0x773C, 0x8AE1, 0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7, 0x775A, 0xE1C8, 0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2, 0x7765, 0xE1CC, 0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA, 0x7779, 0xE1CF, 0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1, 0x778E, 0xE1D0, 0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3, 0x77A5, 0x95CB, 0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5, 0x77B3, 0x93B5, 0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB, 0x77BC, 0xE1D9, 0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC, 0x77CD, 0xE1DD, 0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5, 0x77DC, 0xE1E0, 0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D, 0x77E7, 0x948A, 0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2, 0x77EF, 0x8BB8, 0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB, 0x780C, 0xE1E4, 0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3, 0x7820, 0xE1E7, 0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4, 0x7827, 0x8B6D, 0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376, 0x783F, 0x8D7B, 0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9, 0x7864, 0xFB7A, 0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5, 0x7872, 0x94A1, 0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED, 0x7881, 0x8CE9, 0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF, 0x788D, 0x8A56, 0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F, 0x7895, 0x8DEA, 0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0, 0x78A7, 0x95C9, 0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3, 0x78B5, 0xE1F1, 0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8, 0x78C1, 0x8EA5, 0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB, 0x78CB, 0xE1F6, 0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7, 0x78DA, 0xE241, 0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC, 0x78EF, 0x88E9, 0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA, 0x7907, 0xE244, 0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245, 0x7919, 0xE247, 0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249, 0x792C, 0xE248, 0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7, 0x793E, 0x8ED0, 0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F, 0x7948, 0x8B46, 0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250, 0x7955, 0xE24F, 0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E, 0x795D, 0x8F6A, 0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B, 0x7962, 0x9449, 0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5, 0x7977, 0x9398, 0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268, 0x7981, 0x8BD6, 0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253, 0x798D, 0x89D0, 0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81, 0x799B, 0xFB83, 0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255, 0x79AA, 0xE257, 0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259, 0x79B9, 0xE25A, 0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1, 0x79BF, 0x93C3, 0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C, 0x79CB, 0x8F48, 0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D, 0x79D8, 0x94E9, 0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261, 0x79E4, 0x9489, 0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281, 0x79EC, 0xE25F, 0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48, 0x7A08, 0xE262, 0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5, 0x7A14, 0x96AB, 0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265, 0x7A1A, 0x9274, 0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266, 0x7A2E, 0x8EED, 0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C, 0x7A3B, 0xE26A, 0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B, 0x7A3F, 0x8D65, 0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D, 0x7A46, 0x9673, 0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E, 0x7A4F, 0x89B8, 0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270, 0x7A62, 0xE271, 0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E, 0x7A70, 0xE274, 0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275, 0x7A7A, 0x8BF3, 0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB, 0x7A83, 0x90DE, 0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282, 0x7A93, 0x918B, 0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278, 0x7A98, 0xE27A, 0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45, 0x7AAE, 0x8B87, 0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280, 0x7ABA, 0x894D, 0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282, 0x7AC5, 0xE281, 0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286, 0x7ACB, 0x97A7, 0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84, 0x7AD2, 0x9AF2, 0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B, 0x7ADA, 0xE28C, 0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED, 0x7AE0, 0x8FCD, 0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76, 0x7AE5, 0x93B6, 0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247, 0x7AEB, 0xFB87, 0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292, 0x7AF6, 0x8BA3, 0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1, 0x7AFF, 0x8AC6, 0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296, 0x7B08, 0x8B88, 0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294, 0x7B11, 0x8FCE, 0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A, 0x7B1E, 0xE29A, 0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584, 0x7B28, 0xE29C, 0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B, 0x7B36, 0xE29D, 0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D, 0x7B48, 0x94A4, 0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3, 0x7B4D, 0xE2A1, 0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D, 0x7B52, 0x939B, 0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6, 0x7B65, 0xE2A6, 0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC, 0x7B70, 0xE2A9, 0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5, 0x7B7A, 0xE29F, 0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3, 0x7B8D, 0xE2B0, 0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493, 0x7B95, 0x96A5, 0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7, 0x7B9A, 0xE2B2, 0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88, 0x7B9F, 0xE2AF, 0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB, 0x7BB1, 0x94A0, 0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF, 0x7BC1, 0xE2B9, 0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1, 0x7BC9, 0x927A, 0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB, 0x7BDD, 0xE2BE, 0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3, 0x7BE6, 0xE2C2, 0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8, 0x7BF6, 0xE2CC, 0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6, 0x7C0D, 0xE2CB, 0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7, 0x7C14, 0xE2C1, 0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8, 0x7C23, 0xE2CD, 0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2, 0x7C37, 0xE2D1, 0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA, 0x7C3F, 0x95EB, 0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4, 0x7C4D, 0x90D0, 0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6, 0x7C56, 0xE2DD, 0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4, 0x7C64, 0xE2DC, 0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4, 0x7C75, 0xE2E0, 0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48, 0x7C83, 0xE2E1, 0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE, 0x7C90, 0xE2E2, 0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165, 0x7C98, 0x9453, 0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7, 0x7CA2, 0xE2E5, 0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF, 0x7CA8, 0xE2E8, 0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, 0x7CB1, 0xE2EB, 0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, 0x7CBD, 0xE2EE, 0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, 0x7CC5, 0xE2F0, 0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3, 0x7CD6, 0x939C, 0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3, 0x7CDF, 0x918C, 0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6, 0x7CEF, 0xE2F7, 0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA, 0x7CF8, 0x8E85, 0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A, 0x7D00, 0x8B49, 0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67, 0x7D06, 0xE2FC, 0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B, 0x7D10, 0x9552, 0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1, 0x7D18, 0x8D68, 0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4, 0x7D1C, 0xE341, 0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5, 0x7D2B, 0x8E87, 0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD, 0x7D30, 0x8DD7, 0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349, 0x7D39, 0x8FD0, 0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49, 0x7D43, 0x8CBC, 0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A, 0x7D48, 0xFB8A, 0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D, 0x7D4F, 0xE351, 0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355, 0x7D5C, 0xFB8B, 0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA, 0x7D63, 0xE352, 0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350, 0x7D71, 0x939D, 0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47, 0x7D76, 0x90E2, 0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354, 0x7D8F, 0xE356, 0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1, 0x7D9B, 0xE358, 0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D, 0x7DA2, 0xE361, 0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8, 0x7DAD, 0x88DB, 0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366, 0x7DB1, 0x8D6A, 0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C, 0x7DB7, 0xFB8C, 0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D, 0x7DBD, 0xE35E, 0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D, 0x7DCA, 0x8BD9, 0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE, 0x7DD2, 0x8F8F, 0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367, 0x7DDA, 0x90FC, 0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A, 0x7DE0, 0x92F7, 0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2, 0x7DE9, 0x8AC9, 0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C, 0x7DF4, 0x97FB, 0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA, 0x7E05, 0xE36E, 0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376, 0x7E12, 0xE372, 0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374, 0x7E21, 0xE371, 0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63, 0x7E2B, 0x9644, 0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380, 0x7E35, 0xE37B, 0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381, 0x7E3B, 0xE37A, 0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9, 0x7E43, 0xE37D, 0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71, 0x7E4D, 0x8F4A, 0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155, 0x7E56, 0xE384, 0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383, 0x7E5E, 0xE385, 0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A, 0x7E6A, 0xE389, 0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388, 0x7E7B, 0xE38C, 0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391, 0x7E82, 0x8E5B, 0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393, 0x7E8A, 0xFA5C, 0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A, 0x7E90, 0xE396, 0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398, 0x7E96, 0xE399, 0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA, 0x7F38, 0xE39D, 0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90, 0x7F4C, 0xE3A0, 0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3, 0x7F51, 0xE3A4, 0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7, 0x7F5F, 0xE3A8, 0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA, 0x7F69, 0xE3AB, 0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275, 0x7F70, 0x94B1, 0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB, 0x7F78, 0xE3AD, 0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0, 0x7F85, 0x9785, 0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1, 0x7F8A, 0x9772, 0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4, 0x7F9A, 0xE3B7, 0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91, 0x7FA3, 0xE3B8, 0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60, 0x7FAE, 0xE3BC, 0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD, 0x7FB8, 0xE3BE, 0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5, 0x7FC5, 0xE3C0, 0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782, 0x7FD2, 0x8F4B, 0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089, 0x7FE1, 0xE3C5, 0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3, 0x7FF0, 0x8ACB, 0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C, 0x7FFC, 0x9783, 0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C, 0x8004, 0xE3CC, 0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD, 0x800C, 0x8EA7, 0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B, 0x8017, 0x96D5, 0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1, 0x8021, 0xE3D2, 0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB, 0x803B, 0xE3D5, 0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7, 0x804A, 0xE3D6, 0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9, 0x805A, 0xE3DA, 0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F, 0x8062, 0xE3DC, 0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0, 0x8072, 0xE3DF, 0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1, 0x8077, 0x9045, 0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857, 0x807F, 0xE3E4, 0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6, 0x8087, 0x94A3, 0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7, 0x8093, 0xE3E9, 0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA, 0x809B, 0xE3E8, 0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88, 0x80A5, 0x94EC, 0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED, 0x80AD, 0xE3EB, 0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7, 0x80B4, 0x8DE6, 0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2, 0x80C6, 0x925F, 0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4, 0x80D9, 0xE3F0, 0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1, 0x80DE, 0x9645, 0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF, 0x80EF, 0xE3F6, 0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9, 0x80FC, 0xE445, 0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA, 0x8106, 0x90C6, 0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5, 0x810A, 0x90D2, 0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA, 0x8129, 0xE3F9, 0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D, 0x8139, 0x92AF, 0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC, 0x814E, 0x9074, 0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443, 0x8154, 0x8D6F, 0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448, 0x8166, 0xE449, 0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98, 0x8171, 0xE446, 0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0, 0x817A, 0x9142, 0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F, 0x8183, 0xE44B, 0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70, 0x8193, 0xE455, 0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C, 0x819D, 0x9547, 0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452, 0x81A8, 0x9663, 0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156, 0x81B5, 0xE458, 0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B, 0x81BE, 0xE459, 0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D, 0x81C6, 0x89B0, 0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460, 0x81D1, 0xE461, 0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462, 0x81DA, 0xE465, 0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062, 0x81E5, 0x89E7, 0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9, 0x81ED, 0x8F4C, 0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469, 0x81FB, 0xE46A, 0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C, 0x8202, 0xE46D, 0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB, 0x8209, 0x9DA8, 0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471, 0x820E, 0x8EC9, 0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473, 0x8217, 0x95DC, 0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77, 0x821E, 0x9591, 0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71, 0x822B, 0xE475, 0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477, 0x8235, 0x91C7, 0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476, 0x8239, 0x9144, 0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A, 0x8259, 0xE479, 0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D, 0x8262, 0xE480, 0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481, 0x826A, 0xE482, 0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7, 0x8271, 0xE485, 0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486, 0x8278, 0xE487, 0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489, 0x8292, 0xE48A, 0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C, 0x82A5, 0x8A48, 0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E, 0x82AD, 0x946D, 0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646, 0x82B8, 0x8C7C, 0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8, 0x82C5, 0x8AA1, 0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8, 0x82D4, 0x91DB, 0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5, 0x82DC, 0xE49C, 0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F, 0x82E3, 0xE490, 0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297, 0x82EB, 0x93CF, 0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493, 0x82F9, 0xE499, 0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93, 0x8302, 0x96CE, 0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D, 0x8306, 0xE49B, 0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1, 0x8317, 0xE4AA, 0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2, 0x8328, 0x88EF, 0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3, 0x8332, 0xE4A2, 0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283, 0x8338, 0x91F9, 0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7, 0x8349, 0x9190, 0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6, 0x8352, 0x8D72, 0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8, 0x8375, 0xE4B9, 0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6, 0x837F, 0xFB95, 0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB, 0x838A, 0xE4B5, 0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1, 0x839A, 0xE4AD, 0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA, 0x83A2, 0xE4B0, 0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C, 0x83B1, 0x9789, 0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5, 0x83C5, 0x909B, 0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB, 0x83CE, 0xE4C0, 0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3, 0x83DC, 0x8DD8, 0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC, 0x83EB, 0xE4BF, 0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548, 0x83F2, 0xE4C9, 0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6, 0x83FB, 0xE4D0, 0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8, 0x8407, 0xE4C7, 0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA, 0x840E, 0x88DE, 0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB, 0x8429, 0x948B, 0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E, 0x8435, 0xE4E0, 0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E, 0x8446, 0xE4DC, 0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8, 0x8457, 0x9298, 0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2, 0x8463, 0x939F, 0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7, 0x846C, 0x9192, 0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE, 0x8471, 0x944B, 0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF, 0x847A, 0x9598, 0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3, 0x8490, 0x8F4E, 0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566, 0x849F, 0xE4E5, 0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97, 0x84B4, 0xFB99, 0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8, 0x84BC, 0x9193, 0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E, 0x84C6, 0xE4EC, 0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57, 0x84CD, 0xE4E7, 0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED, 0x84D9, 0xE4E6, 0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648, 0x84EE, 0x9840, 0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0, 0x8500, 0x8EC1, 0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0, 0x8514, 0xE4F7, 0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3, 0x851A, 0x8955, 0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3, 0x852C, 0xE4F4, 0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1, 0x8540, 0xE4F9, 0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC, 0x8549, 0x8FD4, 0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC, 0x8553, 0xFB9A, 0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB, 0x8559, 0xFB9B, 0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E, 0x8569, 0x93A0, 0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A, 0x8577, 0xE550, 0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496, 0x8587, 0xE54E, 0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552, 0x8591, 0xE547, 0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3, 0x859B, 0xE54C, 0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145, 0x85A8, 0xE549, 0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F, 0x85AC, 0x96F2, 0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E, 0x85B9, 0xE556, 0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553, 0x85CD, 0x9795, 0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558, 0x85DC, 0xE55B, 0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A, 0x85E9, 0x94CB, 0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C, 0x85FA, 0xE561, 0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541, 0x8606, 0xE562, 0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F, 0x8613, 0xE55E, 0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564, 0x8622, 0xE563, 0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565, 0x863F, 0xE566, 0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73, 0x8654, 0xE569, 0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8, 0x865E, 0x8BF1, 0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E, 0x8671, 0xE56C, 0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1, 0x868B, 0xE571, 0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C, 0x86A3, 0xE56E, 0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570, 0x86AB, 0xE57A, 0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573, 0x86C4, 0xE575, 0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578, 0x86CB, 0x9260, 0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B, 0x86D9, 0x8A5E, 0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580, 0x86E4, 0x94B8, 0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567, 0x86EE, 0x94D8, 0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C, 0x86FB, 0xE588, 0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649, 0x8703, 0xE587, 0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A, 0x870A, 0xE58D, 0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583, 0x8718, 0x9277, 0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592, 0x8729, 0xE593, 0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591, 0x873F, 0xE58F, 0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598, 0x874E, 0xE599, 0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B, 0x8759, 0xE59E, 0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0, 0x8766, 0x89DA, 0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D, 0x8774, 0xE59A, 0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488, 0x8782, 0xE5A5, 0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3, 0x87AB, 0xE5AC, 0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786, 0x87BB, 0xE5B1, 0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD, 0x87C6, 0xE5B0, 0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA, 0x87D2, 0xE5BB, 0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3, 0x87F6, 0xE5B8, 0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61, 0x87FE, 0xE5B7, 0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6, 0x880E, 0xE5BA, 0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE, 0x8816, 0xE5BD, 0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579, 0x8827, 0xE5C4, 0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3, 0x883B, 0xE5C5, 0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6, 0x8846, 0x8F4F, 0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8, 0x8853, 0x8F70, 0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971, 0x885D, 0x8FD5, 0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB, 0x8863, 0x88DF, 0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A, 0x8872, 0xE5D3, 0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1, 0x887E, 0xE5CE, 0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4, 0x8888, 0x8C55, 0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6, 0x8896, 0x91B3, 0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, 0x88A2, 0xE5D9, 0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, 0x88B0, 0xE5DC, 0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2, 0x88B7, 0x88BF, 0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4, 0x88C3, 0xE5DF, 0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0, 0x88D4, 0xE5E1, 0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3, 0x88DC, 0x95E2, 0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1, 0x88E8, 0xE5E9, 0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8, 0x88F5, 0xFBA2, 0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7, 0x88FD, 0x90BB, 0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB, 0x8907, 0x95A1, 0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C, 0x8912, 0x964A, 0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA, 0x891E, 0xE5F0, 0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3, 0x8936, 0xE5F7, 0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4, 0x8943, 0xE5EF, 0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5, 0x8956, 0x89A6, 0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB, 0x8964, 0xE641, 0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642, 0x896F, 0xE644, 0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646, 0x897E, 0xE647, 0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648, 0x8986, 0x95A2, 0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A, 0x898B, 0x8CA9, 0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B, 0x8997, 0x9460, 0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D, 0x89A6, 0xE64F, 0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065, 0x89AC, 0xE650, 0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF, 0x89BA, 0xE653, 0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656, 0x89D2, 0x8A70, 0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659, 0x89E3, 0x89F0, 0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B, 0x89F8, 0xE65C, 0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D, 0x8A08, 0x8C76, 0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2, 0x8A10, 0xE65F, 0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E, 0x8A17, 0x91F5, 0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662, 0x8A1F, 0x8FD7, 0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B, 0x8A2D, 0x90DD, 0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169, 0x8A36, 0xE664, 0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290, 0x8A3C, 0x8FD8, 0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669, 0x8A50, 0x8DBC, 0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9, 0x8A55, 0x955D, 0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972, 0x8A62, 0xE66D, 0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D, 0x8A6B, 0x986C, 0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146, 0x8A70, 0x8B6C, 0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA, 0x8A79, 0xFBA5, 0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670, 0x8A85, 0xE66E, 0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F, 0x8A8D, 0x9446, 0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261, 0x8A98, 0x9755, 0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD, 0x8AA1, 0xE672, 0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674, 0x8AA6, 0xE675, 0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0, 0x8AAD, 0x93C7, 0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE, 0x8ABC, 0x8B62, 0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A, 0x8AC4, 0xE678, 0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0, 0x8ACD, 0xE679, 0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F, 0x8ADA, 0xE67B, 0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686, 0x8ADF, 0xFBA8, 0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684, 0x8AE4, 0xE680, 0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C, 0x8AED, 0x9740, 0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D, 0x8AF6, 0xFBAA, 0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF, 0x8AFE, 0x91F8, 0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0, 0x8B04, 0x93A3, 0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4, 0x8B10, 0xE68D, 0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E, 0x8B19, 0x8CAA, 0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3, 0x8B20, 0xE68F, 0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695, 0x8B2B, 0xE693, 0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE, 0x8B3E, 0xE694, 0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697, 0x8B4E, 0xE699, 0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B, 0x8B58, 0x8EAF, 0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588, 0x8B5F, 0xE69F, 0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0, 0x8B6F, 0xE6A1, 0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7, 0x8B74, 0xE6A2, 0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC, 0x8B80, 0xE6A4, 0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5, 0x8B8E, 0xE6A6, 0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8, 0x8B96, 0xE6A9, 0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A, 0x8C3A, 0xE6AC, 0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4, 0x8C48, 0xE6AF, 0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1, 0x8C50, 0xE6B2, 0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB, 0x8C62, 0xE6B4, 0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5, 0x8C78, 0xE6B6, 0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF, 0x8C82, 0xE6B8, 0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB, 0x8C8C, 0x9665, 0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE, 0x8C98, 0xE6C0, 0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589, 0x8CA1, 0x8DE0, 0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD, 0x8CA9, 0x94CC, 0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3, 0x8CAD, 0xE6C2, 0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1, 0x8CB2, 0xE6C5, 0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8, 0x8CB7, 0x9483, 0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C, 0x8CBD, 0xE6C4, 0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA, 0x8CC2, 0x9847, 0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91, 0x8CC8, 0xE6C9, 0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147, 0x8CD1, 0x93F6, 0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E, 0x8CDC, 0x8E92, 0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB, 0x8CE3, 0xE6CC, 0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF, 0x8CED, 0x9371, 0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF, 0x8CFB, 0xE6D0, 0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1, 0x8D05, 0xE6D2, 0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3, 0x8D0B, 0x8AE4, 0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7, 0x8D12, 0xFBAF, 0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC, 0x8D64, 0x90D4, 0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71, 0x8D6D, 0xE6DE, 0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0, 0x8D74, 0x958B, 0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1, 0x8D85, 0x92B4, 0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF, 0x8DA8, 0x9096, 0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4, 0x8DC2, 0xE6E3, 0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6, 0x8DD6, 0xE6E8, 0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97, 0x8DDF, 0xE6EE, 0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7, 0x8DEA, 0xE6EC, 0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5, 0x8DF5, 0x9148, 0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1, 0x8E09, 0xE6F2, 0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6, 0x8E1D, 0xE6F4, 0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748, 0x8E30, 0xE6FA, 0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8, 0x8E44, 0x92FB, 0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741, 0x8E4A, 0xE6FC, 0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A, 0x8E59, 0xE745, 0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749, 0x8E64, 0xE746, 0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B, 0x8E7C, 0xE74D, 0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750, 0x8E87, 0xE74F, 0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4, 0x8E91, 0xE755, 0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757, 0x8EA1, 0xE759, 0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A, 0x8EAF, 0x8BEB, 0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E, 0x8EC5, 0xE75F, 0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4, 0x8ECB, 0xE761, 0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2, 0x8ED2, 0x8CAC, 0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D, 0x8EE3, 0xE763, 0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765, 0x8EFC, 0xE764, 0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72, 0x8F05, 0xE769, 0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771, 0x8F12, 0xE76B, 0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A, 0x8F19, 0xE76C, 0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50, 0x8F1F, 0xE76F, 0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6, 0x8F2F, 0x8F53, 0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775, 0x8F3B, 0xE774, 0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777, 0x8F44, 0x8A8D, 0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A, 0x8F4C, 0xE779, 0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D, 0x8F5C, 0xE77E, 0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780, 0x8F63, 0xE781, 0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783, 0x8F9E, 0x8EAB, 0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F, 0x8FA8, 0x999E, 0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787, 0x8FB0, 0x9243, 0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788, 0x8FBA, 0x95D3, 0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248, 0x8FC2, 0x8949, 0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D, 0x8FD1, 0x8BDF, 0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B, 0x8FE5, 0xE78A, 0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C, 0x8FEB, 0x9497, 0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71, 0x8FF4, 0xE78F, 0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791, 0x8FFA, 0xE792, 0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197, 0x9003, 0x93A6, 0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799, 0x900D, 0xE796, 0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280, 0x9011, 0xE793, 0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794, 0x9016, 0xE798, 0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA, 0x901D, 0x90C0, 0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2, 0x9021, 0xE795, 0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A, 0x902E, 0x91DF, 0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C, 0x9036, 0xE79B, 0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E, 0x903E, 0xE7A5, 0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278, 0x9047, 0x8BF6, 0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E, 0x904D, 0x95D5, 0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0, 0x9051, 0xE7A1, 0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242, 0x9055, 0x88E1, 0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1, 0x905C, 0x91BB, 0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B, 0x9063, 0x8CAD, 0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9, 0x9069, 0x934B, 0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA, 0x9072, 0xE7AD, 0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A, 0x9078, 0x9149, 0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF, 0x907F, 0x94F0, 0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE, 0x9083, 0xE284, 0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3, 0x908A, 0xE7B2, 0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF, 0x90A6, 0x964D, 0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6, 0x90B1, 0xE7B7, 0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8, 0x90CA, 0x8D78, 0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6, 0x90E1, 0x8C53, 0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594, 0x90ED, 0x8A73, 0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373, 0x9102, 0xE7BD, 0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF, 0x9127, 0xFBB9, 0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0, 0x9149, 0x93D1, 0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE, 0x914D, 0x947A, 0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C, 0x9156, 0xE7C3, 0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5, 0x9165, 0xE7C6, 0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56, 0x9172, 0xE7C9, 0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93, 0x9178, 0x8E5F, 0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB, 0x918B, 0xE7CA, 0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1, 0x9197, 0x94AE, 0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD, 0x91AA, 0xE7D0, 0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2, 0x91B5, 0xE7D1, 0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4, 0x91C1, 0xE7D5, 0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF, 0x91C9, 0xE7D6, 0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64, 0x91CE, 0x96EC, 0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0, 0x91D6, 0xE7D9, 0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA, 0x91DB, 0xE7DC, 0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC, 0x91DF, 0xE7DA, 0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF, 0x91E5, 0xFBC0, 0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD, 0x91EE, 0xFBBE, 0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD, 0x91FF, 0xE7E1, 0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD, 0x920E, 0x8A62, 0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2, 0x9215, 0xE7E4, 0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3, 0x9234, 0x97E9, 0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4, 0x923C, 0xFBC6, 0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353, 0x9245, 0xE7E8, 0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE, 0x924E, 0xFBC7, 0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7, 0x9259, 0xFBC8, 0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6, 0x9262, 0x94AB, 0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB, 0x9271, 0x8D7A, 0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667, 0x9280, 0x8BE2, 0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F, 0x9291, 0x914C, 0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1, 0x9298, 0x96C1, 0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0, 0x92A7, 0xFBCC, 0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6, 0x92CF, 0xE7F5, 0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6, 0x92D5, 0xFBD4, 0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5, 0x92E4, 0x8F9B, 0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD, 0x92ED, 0x8973, 0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98, 0x92F9, 0xFA65, 0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C, 0x92FF, 0xFBDC, 0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9, 0x9310, 0x908D, 0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842, 0x931D, 0xFBDD, 0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8, 0x9322, 0xE841, 0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1, 0x9328, 0x9564, 0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC, 0x932F, 0x8DF6, 0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844, 0x933B, 0xE846, 0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7, 0x934D, 0x9374, 0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0, 0x935B, 0x9262, 0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C, 0x936E, 0xE84A, 0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849, 0x937E, 0x8FDF, 0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD, 0x9397, 0x9199, 0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A, 0x93AC, 0xE84D, 0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C, 0x93B9, 0xE850, 0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859, 0x93D0, 0xE858, 0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852, 0x93D8, 0xE855, 0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE, 0x93E4, 0xE85A, 0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4, 0x9403, 0xE85E, 0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D, 0x9414, 0xE85C, 0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B, 0x9421, 0xE864, 0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863, 0x9436, 0xE861, 0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866, 0x9444, 0xE868, 0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3, 0x9452, 0xE867, 0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869, 0x945E, 0xE86C, 0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D, 0x9470, 0xE86F, 0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874, 0x947D, 0xE872, 0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876, 0x9577, 0x92B7, 0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D, 0x9587, 0xE879, 0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A, 0x958F, 0x895B, 0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4, 0x9594, 0xE87B, 0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E, 0x95A0, 0xE880, 0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D, 0x95A5, 0x94B4, 0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883, 0x95B2, 0x897B, 0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884, 0x95BE, 0xE887, 0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888, 0x95CC, 0xE88C, 0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D, 0x95D6, 0xE88F, 0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891, 0x95E2, 0xE893, 0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894, 0x9628, 0xE895, 0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897, 0x9632, 0x9668, 0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9, 0x9642, 0xE898, 0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899, 0x964D, 0x8D7E, 0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3, 0x965C, 0xE89D, 0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0, 0x9662, 0x8940, 0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7, 0x9666, 0xE8A1, 0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941, 0x9672, 0xE8A2, 0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9, 0x9677, 0xE89C, 0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A, 0x9685, 0x8BF7, 0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0, 0x968B, 0xE440, 0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F, 0x9694, 0x8A75, 0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5, 0x9699, 0x8C84, 0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB, 0x96A0, 0x8942, 0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC, 0x96AA, 0xE8A8, 0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA, 0x96B2, 0xE8AB, 0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA, 0x96B8, 0xE8AF, 0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9, 0x96C0, 0x909D, 0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB, 0x96C6, 0x8F57, 0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2, 0x96CC, 0x8E93, 0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47, 0x96D5, 0xE8B8, 0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097, 0x96DC, 0xE8B6, 0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A, 0x96EA, 0x90E1, 0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F, 0x96F6, 0x97EB, 0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364, 0x9700, 0x8EF9, 0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B, 0x9708, 0xE8BC, 0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE, 0x970F, 0xE8C0, 0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1, 0x9719, 0xE8C2, 0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3, 0x9727, 0x96B6, 0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849, 0x9733, 0xFBED, 0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE, 0x973D, 0xE8C7, 0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF, 0x9744, 0xE8C9, 0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD, 0x974D, 0xFBF0, 0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2, 0x9755, 0xFBF3, 0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE, 0x975E, 0x94F1, 0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA, 0x9764, 0xE8D0, 0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76, 0x976B, 0xE8D4, 0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43, 0x9779, 0xE8D6, 0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9, 0x9784, 0x8A93, 0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC, 0x978D, 0x88C6, 0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2, 0x979C, 0xE8DF, 0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1, 0x97A8, 0xE8E0, 0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3, 0x97B4, 0xE8E4, 0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7, 0x97CB, 0xE8E8, 0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA, 0x97EE, 0x9442, 0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF, 0x97F6, 0xE8EE, 0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5, 0x9802, 0x92B8, 0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87, 0x9808, 0x907B, 0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761, 0x9811, 0x8AE6, 0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C, 0x9818, 0x97CC, 0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3, 0x982C, 0x966A, 0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5, 0x9838, 0xE8F2, 0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6, 0x9846, 0xE8F7, 0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A, 0x984E, 0x8A7B, 0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0, 0x9857, 0xFBF4, 0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE, 0x9865, 0xFBF5, 0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB, 0x9870, 0xE8FC, 0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941, 0x98A8, 0x9597, 0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945, 0x98B6, 0xE946, 0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949, 0x98DB, 0x94F2, 0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51, 0x98E9, 0xE94A, 0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A, 0x98EF, 0x94D1, 0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94, 0x98FD, 0x964F, 0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD, 0x9909, 0xE94D, 0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60, 0x9912, 0xE94E, 0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950, 0x991D, 0xE952, 0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951, 0x9924, 0xE954, 0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956, 0x992E, 0xE957, 0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A, 0x9945, 0xE95C, 0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961, 0x9950, 0xE95D, 0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962, 0x9957, 0x8BC0, 0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964, 0x9999, 0x8D81, 0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D, 0x99AC, 0x946E, 0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279, 0x99B4, 0x93E9, 0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA, 0x99C5, 0x8977, 0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293, 0x99D1, 0xE96D, 0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C, 0x99DB, 0xE96A, 0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977, 0x99ED, 0xE96E, 0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971, 0x99F8, 0xE973, 0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974, 0x9A05, 0xE976, 0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B, 0x9A13, 0x8CB1, 0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979, 0x9A30, 0x93AB, 0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D, 0x9A42, 0xE97C, 0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982, 0x9A4E, 0xFBFB, 0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1, 0x9A5B, 0xE983, 0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988, 0x9A65, 0xE987, 0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A, 0x9AA8, 0x8D9C, 0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B, 0x9ABC, 0xE98E, 0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990, 0x9AD1, 0xE991, 0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82, 0x9AD9, 0xFBFC, 0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995, 0x9AE2, 0xE996, 0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF, 0x9AEB, 0xE99A, 0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999, 0x9AF1, 0xE99D, 0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F, 0x9B06, 0xE9A0, 0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3, 0x9B22, 0xE9A4, 0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7, 0x9B28, 0xE9A8, 0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB, 0x9B2F, 0xE9AC, 0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6, 0x9B3C, 0x8B53, 0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF, 0x9B44, 0xE9AE, 0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2, 0x9B4F, 0xE9B0, 0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4, 0x9B5A, 0x8B9B, 0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5, 0x9B75, 0xFC41, 0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43, 0x9B91, 0xE9B8, 0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9, 0x9B97, 0xE9BA, 0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD, 0x9BAA, 0x968E, 0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E, 0x9BB1, 0xFC44, 0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45, 0x9BC0, 0xE9BF, 0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0, 0x9BCF, 0xE9C3, 0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9, 0x9BD6, 0x8E49, 0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7, 0x9BE3, 0xE9C6, 0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE, 0x9BF1, 0xE9CD, 0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46, 0x9C04, 0xE9D8, 0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1, 0x9C0A, 0xE9D7, 0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B, 0x9C12, 0xE9D6, 0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF, 0x9C1B, 0xE9DA, 0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB, 0x9C2D, 0x9568, 0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE, 0x9C32, 0xE9E0, 0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956, 0x9C3E, 0xE9E2, 0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C, 0x9C52, 0x9690, 0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4, 0x9C67, 0xE9E5, 0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9, 0x9CE7, 0xE9E8, 0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9, 0x9CF0, 0xE9EA, 0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE, 0x9D03, 0xE9EE, 0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC, 0x9D09, 0xE9EB, 0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6, 0x9D1B, 0x8995, 0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1, 0x9D28, 0x8A9B, 0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7, 0x9D3B, 0x8D83, 0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8, 0x9D44, 0xE9F5, 0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44, 0x9D51, 0xEA43, 0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40, 0x9D5E, 0xEA41, 0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42, 0x9D6B, 0xFC48, 0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47, 0x9D72, 0xEA46, 0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47, 0x9D8F, 0x8C7B, 0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E, 0x9DAB, 0xEA49, 0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF, 0x9DB8, 0xEA53, 0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51, 0x9DC2, 0xEA57, 0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56, 0x9DD3, 0xEA59, 0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C, 0x9DEF, 0xEA5D, 0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9, 0x9DFA, 0x8DEB, 0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F, 0x9E1B, 0xEA60, 0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2, 0x9E79, 0xEA63, 0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65, 0x9E88, 0xEA66, 0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B, 0x9E92, 0xEA69, 0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED, 0x9E9D, 0xEA6C, 0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E, 0x9EA9, 0xEA6E, 0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F, 0x9EB9, 0x8D8D, 0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5, 0x9EBE, 0x9F80, 0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73, 0x9ECD, 0x8B6F, 0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76, 0x9ED1, 0xFC4B, 0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2, 0x9ED9, 0x96D9, 0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A, 0x9EDE, 0xEA79, 0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D, 0x9EEF, 0xEA7E, 0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82, 0x9EF9, 0xEA83, 0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86, 0x9F07, 0xEA87, 0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB, 0x9F15, 0xEA8A, 0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C, 0x9F3B, 0x9540, 0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256, 0x9F4E, 0xE6D8, 0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90, 0x9F5F, 0xEA92, 0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE, 0x9F63, 0xEA91, 0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98, 0x9F6C, 0xEA97, 0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99, 0x9F8D, 0x97B4, 0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273, 0x9FA0, 0xEA9E, 0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90, 0xFA0F, 0xFA9B, 0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8, 0xFA13, 0xFAE8, 0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E, 0xFA17, 0xFB75, 0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80, 0xFA1B, 0xFB82, 0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92, 0xFA1F, 0xFB9D, 0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9, 0xFA23, 0xFBB1, 0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7, 0xFA27, 0xFBD3, 0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6, 0xFA2B, 0xFBF7, 0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149, 0xFF02, 0xFA57, 0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193, 0xFF06, 0x8195, 0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A, 0xFF0A, 0x8196, 0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C, 0xFF0E, 0x8144, 0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250, 0xFF12, 0x8251, 0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254, 0xFF16, 0x8255, 0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258, 0xFF1A, 0x8146, 0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181, 0xFF1E, 0x8184, 0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260, 0xFF22, 0x8261, 0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264, 0xFF26, 0x8265, 0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268, 0xFF2A, 0x8269, 0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C, 0xFF2E, 0x826D, 0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270, 0xFF32, 0x8271, 0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274, 0xFF36, 0x8275, 0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278, 0xFF3A, 0x8279, 0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E, 0xFF3E, 0x814F, 0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281, 0xFF42, 0x8282, 0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285, 0xFF46, 0x8286, 0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289, 0xFF4A, 0x828A, 0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D, 0xFF4E, 0x828E, 0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291, 0xFF52, 0x8292, 0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295, 0xFF56, 0x8296, 0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299, 0xFF5A, 0x829A, 0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170, 0xFF5E, 0x8160, 0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3, 0xFF64, 0x00A4, 0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7, 0xFF68, 0x00A8, 0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB, 0xFF6C, 0x00AC, 0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF, 0xFF70, 0x00B0, 0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3, 0xFF74, 0x00B4, 0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7, 0xFF78, 0x00B8, 0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB, 0xFF7C, 0x00BC, 0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF, 0xFF80, 0x00C0, 0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3, 0xFF84, 0x00C4, 0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7, 0xFF88, 0x00C8, 0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB, 0xFF8C, 0x00CC, 0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF, 0xFF90, 0x00D0, 0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3, 0xFF94, 0x00D4, 0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7, 0xFF98, 0x00D8, 0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB, 0xFF9C, 0x00DC, 0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF, 0xFFE0, 0x8191, 0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, 0xFFE4, 0xFA55, 0xFFE5, 0x818F, 0, 0 }; static const WCHAR oem2uni932[] = { /* Shift_JIS --> Unicode pairs */ 0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64, 0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68, 0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C, 0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70, 0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74, 0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78, 0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C, 0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80, 0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84, 0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88, 0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C, 0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90, 0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94, 0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98, 0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C, 0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000, 0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E, 0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F, 0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4, 0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3, 0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D, 0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005, 0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015, 0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E, 0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025, 0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D, 0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015, 0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D, 0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B, 0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F, 0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D, 0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D, 0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266, 0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642, 0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033, 0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0, 0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06, 0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606, 0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE, 0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0, 0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC, 0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190, 0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208, 0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282, 0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227, 0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4, 0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5, 0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261, 0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A, 0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B, 0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F, 0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021, 0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11, 0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15, 0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19, 0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24, 0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28, 0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C, 0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30, 0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34, 0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38, 0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42, 0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46, 0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A, 0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E, 0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52, 0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56, 0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A, 0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044, 0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048, 0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C, 0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050, 0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054, 0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058, 0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C, 0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060, 0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064, 0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068, 0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C, 0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070, 0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074, 0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078, 0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C, 0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080, 0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084, 0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088, 0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C, 0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090, 0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1, 0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5, 0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9, 0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD, 0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1, 0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5, 0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9, 0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD, 0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1, 0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5, 0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9, 0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD, 0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1, 0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5, 0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9, 0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD, 0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1, 0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5, 0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9, 0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED, 0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1, 0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x30F4, 0x8395, 0x30F5, 0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392, 0x83A1, 0x0393, 0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396, 0x83A5, 0x0397, 0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A, 0x83A9, 0x039B, 0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E, 0x83AD, 0x039F, 0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3, 0x83B1, 0x03A4, 0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7, 0x83B5, 0x03A8, 0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2, 0x83C1, 0x03B3, 0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6, 0x83C5, 0x03B7, 0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA, 0x83C9, 0x03BB, 0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE, 0x83CD, 0x03BF, 0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3, 0x83D1, 0x03C4, 0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7, 0x83D5, 0x03C8, 0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411, 0x8442, 0x0412, 0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415, 0x8446, 0x0401, 0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418, 0x844A, 0x0419, 0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C, 0x844E, 0x041D, 0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420, 0x8452, 0x0421, 0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424, 0x8456, 0x0425, 0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428, 0x845A, 0x0429, 0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C, 0x845E, 0x042D, 0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430, 0x8471, 0x0431, 0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434, 0x8475, 0x0435, 0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437, 0x8479, 0x0438, 0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B, 0x847D, 0x043C, 0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F, 0x8482, 0x0440, 0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443, 0x8486, 0x0444, 0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447, 0x848A, 0x0448, 0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B, 0x848E, 0x044C, 0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F, 0x849F, 0x2500, 0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510, 0x84A3, 0x2518, 0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C, 0x84A7, 0x2524, 0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501, 0x84AB, 0x2503, 0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B, 0x84AF, 0x2517, 0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B, 0x84B3, 0x253B, 0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F, 0x84B7, 0x2528, 0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D, 0x84BB, 0x2530, 0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542, 0x8740, 0x2460, 0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463, 0x8744, 0x2464, 0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467, 0x8748, 0x2468, 0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B, 0x874C, 0x246C, 0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F, 0x8750, 0x2470, 0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473, 0x8754, 0x2160, 0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163, 0x8758, 0x2164, 0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167, 0x875C, 0x2168, 0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314, 0x8761, 0x3322, 0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327, 0x8765, 0x3303, 0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357, 0x8769, 0x330D, 0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B, 0x876D, 0x334A, 0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D, 0x8771, 0x339E, 0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4, 0x8775, 0x33A1, 0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F, 0x8782, 0x2116, 0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4, 0x8786, 0x32A5, 0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8, 0x878A, 0x3231, 0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E, 0x878E, 0x337D, 0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211, 0x8798, 0x221F, 0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516, 0x88A1, 0x5A03, 0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B, 0x88A5, 0x6328, 0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475, 0x88A9, 0x831C, 0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1, 0x88AD, 0x6E25, 0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6, 0x88B1, 0x9BF5, 0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1, 0x88B5, 0x6271, 0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B, 0x88B9, 0x98F4, 0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E, 0x88BD, 0x6216, 0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89, 0x88C1, 0x5EB5, 0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848, 0x88C5, 0x95C7, 0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5, 0x88C9, 0x4F0A, 0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049, 0x88CD, 0x56F2, 0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01, 0x88D1, 0x5C09, 0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170, 0x88D5, 0x6613, 0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F, 0x88D9, 0x7570, 0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF, 0x88DD, 0x80C3, 0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02, 0x88E1, 0x9055, 0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95, 0x88E5, 0x4EA5, 0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1, 0x88E9, 0x78EF, 0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2, 0x88ED, 0x9038, 0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B, 0x88F1, 0x9C2F, 0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD, 0x88F5, 0x54E1, 0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15, 0x88F9, 0x98F2, 0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D, 0x8940, 0x9662, 0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB, 0x8944, 0x540B, 0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF, 0x8948, 0x7FBD, 0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F, 0x894C, 0x9D5C, 0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893, 0x8950, 0x81FC, 0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504, 0x8954, 0x6B1D, 0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5, 0x8958, 0x53A9, 0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F, 0x895C, 0x5642, 0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2, 0x8960, 0x834F, 0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6, 0x8964, 0x5B30, 0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3, 0x8968, 0x6804, 0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29, 0x896C, 0x745B, 0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834, 0x8970, 0x82F1, 0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED, 0x8974, 0x6DB2, 0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5, 0x8978, 0x60A6, 0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2, 0x897C, 0x698E, 0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712, 0x8981, 0x5830, 0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6, 0x8985, 0x6028, 0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF, 0x8989, 0x6F14, 0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159, 0x898D, 0x71D5, 0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276, 0x8991, 0x82D1, 0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B, 0x8995, 0x9D1B, 0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A, 0x8999, 0x7525, 0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965, 0x899D, 0x5F80, 0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA, 0x89A1, 0x6A2A, 0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B, 0x89A5, 0x7FC1, 0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E, 0x89A9, 0x9EC4, 0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B, 0x89AD, 0x5104, 0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6, 0x89B1, 0x6876, 0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA, 0x89B5, 0x5378, 0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F, 0x89B9, 0x97F3, 0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE, 0x89BD, 0x4F55, 0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73, 0x89C1, 0x52A0, 0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F, 0x89C5, 0x5AC1, 0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1, 0x89C9, 0x6687, 0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C, 0x89CD, 0x6CB3, 0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D, 0x89D1, 0x79BE, 0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1, 0x89D5, 0x82DB, 0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF, 0x89D9, 0x83D3, 0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629, 0x89DD, 0x8CA8, 0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E, 0x89E1, 0x868A, 0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211, 0x89E5, 0x7259, 0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD, 0x89E9, 0x86FE, 0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913, 0x89ED, 0x99D5, 0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3, 0x89F1, 0x56DE, 0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB, 0x89F5, 0x5FEB, 0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062, 0x89F9, 0x61D0, 0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539, 0x8A40, 0x9B41, 0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77, 0x8A44, 0x7070, 0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75, 0x8A48, 0x82A5, 0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E, 0x8A4C, 0x8C9D, 0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916, 0x8A50, 0x54B3, 0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168, 0x8A54, 0x6982, 0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB, 0x8A58, 0x8857, 0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8, 0x8A5C, 0x6D6C, 0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3, 0x8A60, 0x67FF, 0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283, 0x8A64, 0x5687, 0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1, 0x8A68, 0x64B9, 0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB, 0x8A6C, 0x7372, 0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A, 0x8A70, 0x89D2, 0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED, 0x8A74, 0x95A3, 0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66, 0x8A78, 0x5CB3, 0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E, 0x8A7C, 0x639B, 0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F, 0x8A81, 0x68B6, 0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272, 0x8A85, 0x559D, 0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B, 0x8A89, 0x6E07, 0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910, 0x8A8D, 0x8F44, 0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6, 0x8A91, 0x691B, 0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A, 0x8A95, 0x515C, 0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC, 0x8A99, 0x938C, 0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822, 0x8A9D, 0x8305, 0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208, 0x8AA1, 0x82C5, 0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83, 0x8AA5, 0x51A0, 0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8, 0x8AA9, 0x52E7, 0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A, 0x8AAD, 0x59E6, 0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB, 0x8AB1, 0x5E72, 0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F, 0x8AB5, 0x6163, 0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562, 0x8AB9, 0x67D1, 0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E, 0x8ABD, 0x6B53, 0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97, 0x8AC1, 0x6F45, 0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3, 0x8AC5, 0x770B, 0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21, 0x8AC9, 0x7DE9, 0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D, 0x8ACD, 0x8266, 0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC, 0x8AD1, 0x8CAB, 0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593, 0x8AD5, 0x9591, 0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3, 0x8AD9, 0x9928, 0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B, 0x8ADD, 0x5CB8, 0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C, 0x8AE1, 0x773C, 0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B, 0x8AE5, 0x96C1, 0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858, 0x8AE9, 0x4F01, 0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C, 0x8AED, 0x5668, 0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09, 0x8AF1, 0x5BC4, 0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E, 0x8AF5, 0x5FCC, 0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7, 0x8AF9, 0x65E2, 0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4, 0x8B40, 0x6A5F, 0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17, 0x8B44, 0x6C7D, 0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63, 0x8B48, 0x7A00, 0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F, 0x8B4C, 0x8A18, 0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC, 0x8B50, 0x8F1D, 0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C, 0x8B54, 0x4E80, 0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993, 0x8B58, 0x5B9C, 0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC, 0x8B5C, 0x6B3A, 0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947, 0x8B60, 0x7FA9, 0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70, 0x8B64, 0x63AC, 0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409, 0x8B68, 0x5403, 0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58, 0x8B6C, 0x8A70, 0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD, 0x8B70, 0x5374, 0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650, 0x8B74, 0x9006, 0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7, 0x8B78, 0x4F11, 0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE, 0x8B7C, 0x5F13, 0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D, 0x8B81, 0x6C42, 0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078, 0x8B85, 0x7403, 0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08, 0x8B89, 0x7D1A, 0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7, 0x8B8D, 0x725B, 0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8, 0x8B91, 0x62D2, 0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20, 0x8B95, 0x865A, 0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8, 0x8B99, 0x6F01, 0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8, 0x8B9D, 0x4EAB, 0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0, 0x8BA1, 0x50D1, 0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171, 0x8BA5, 0x51F6, 0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F, 0x8BA9, 0x53EB, 0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1, 0x8BAD, 0x5F37, 0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050, 0x8BB1, 0x606D, 0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B, 0x8BB5, 0x6CC1, 0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF, 0x8BB9, 0x80F8, 0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E, 0x8BBD, 0x90F7, 0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957, 0x8BC1, 0x9A5A, 0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D, 0x8BC5, 0x6681, 0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2, 0x8BC9, 0x6975, 0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81, 0x8BCD, 0x50C5, 0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE, 0x8BD1, 0x9326, 0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D, 0x8BD5, 0x7434, 0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B, 0x8BD9, 0x7DCA, 0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F, 0x8BDD, 0x895F, 0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1, 0x8BE1, 0x541F, 0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036, 0x8BE5, 0x53E5, 0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396, 0x8BE9, 0x77E9, 0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6, 0x8BED, 0x99C8, 0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A, 0x8BF1, 0x865E, 0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076, 0x8BF5, 0x5BD3, 0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32, 0x8BF9, 0x6ADB, 0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48, 0x8C40, 0x6398, 0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774, 0x8C44, 0x8F61, 0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688, 0x8C48, 0x7C82, 0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851, 0x8C4C, 0x936C, 0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB, 0x8C50, 0x8A13, 0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1, 0x8C54, 0x5366, 0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2, 0x8C58, 0x50BE, 0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553, 0x8C5C, 0x572D, 0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951, 0x8C60, 0x5F62, 0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176, 0x8C64, 0x6167, 0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A, 0x8C68, 0x656C, 0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13, 0x8C6C, 0x7566, 0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C, 0x8C70, 0x7D99, 0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E, 0x8C74, 0x834A, 0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63, 0x8C78, 0x8B66, 0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F, 0x8C7C, 0x82B8, 0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287, 0x8C81, 0x621F, 0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699, 0x8C85, 0x6841, 0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A, 0x8C89, 0x6F54, 0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840, 0x8C8D, 0x8A23, 0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039, 0x8C91, 0x5026, 0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238, 0x8C95, 0x5263, 0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805, 0x8C99, 0x5ACC, 0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8, 0x8C9D, 0x62F3, 0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29, 0x8CA1, 0x727D, 0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814, 0x8CA5, 0x786F, 0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9, 0x8CA9, 0x898B, 0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2, 0x8CAD, 0x9063, 0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855, 0x8CB1, 0x9A13, 0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F, 0x8CB5, 0x53B3, 0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B, 0x8CB9, 0x6E90, 0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43, 0x8CBD, 0x8237, 0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650, 0x8CC1, 0x4E4E, 0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C, 0x8CC5, 0x56FA, 0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1, 0x8CC9, 0x5EAB, 0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545, 0x8CCD, 0x67AF, 0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA, 0x8CD1, 0x88B4, 0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0, 0x8CD5, 0x864E, 0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237, 0x8CD9, 0x96C7, 0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94, 0x8CDD, 0x4E92, 0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449, 0x8CE1, 0x543E, 0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1, 0x8CE5, 0x609F, 0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A, 0x8CE9, 0x7881, 0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77, 0x8CED, 0x9190, 0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4, 0x8CF1, 0x4F7C, 0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016, 0x8CF5, 0x5149, 0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9, 0x8CF9, 0x52FE, 0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411, 0x8D40, 0x540E, 0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2, 0x8D44, 0x597D, 0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F, 0x8D48, 0x5DE5, 0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78, 0x8D4C, 0x5E83, 0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18, 0x8D50, 0x6052, 0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8, 0x8D54, 0x63A7, 0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643, 0x8D58, 0x66F4, 0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897, 0x8D5C, 0x69CB, 0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69, 0x8D60, 0x6E2F, 0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687, 0x8D64, 0x786C, 0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05, 0x8D68, 0x7D18, 0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015, 0x8D6C, 0x8003, 0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154, 0x8D70, 0x818F, 0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C, 0x8D74, 0x8861, 0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC, 0x8D78, 0x90CA, 0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F, 0x8D7C, 0x92FC, 0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805, 0x8D81, 0x9999, 0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B, 0x8D85, 0x52AB, 0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5, 0x8D89, 0x62F7, 0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F, 0x8D8D, 0x9EB9, 0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A, 0x8D91, 0x56FD, 0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60, 0x8D95, 0x9ED2, 0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170, 0x8D99, 0x7511, 0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8, 0x8D9D, 0x72DB, 0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803, 0x8DA1, 0x4ECA, 0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE, 0x8DA5, 0x5A5A, 0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F, 0x8DA9, 0x6606, 0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7, 0x8DAD, 0x75D5, 0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42, 0x8DB1, 0x4E9B, 0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506, 0x8DB5, 0x5D6F, 0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB, 0x8DB9, 0x6C99, 0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50, 0x8DBD, 0x9396, 0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7, 0x8DC1, 0x632B, 0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D, 0x8DC5, 0x6700, 0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB, 0x8DC9, 0x5BB0, 0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1, 0x8DCD, 0x683D, 0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D, 0x8DD1, 0x91C7, 0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826, 0x8DD5, 0x796D, 0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC, 0x8DD9, 0x88C1, 0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264, 0x8DDD, 0x5728, 0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1, 0x8DE1, 0x51B4, 0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A, 0x8DE5, 0x698A, 0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E, 0x8DE9, 0x57FC, 0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C, 0x8DED, 0x524A, 0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628, 0x8DF1, 0x6714, 0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56, 0x8DF5, 0x7D22, 0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD, 0x8DF9, 0x7B39, 0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237, 0x8E40, 0x5BDF, 0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6, 0x8E44, 0x672D, 0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1, 0x8E48, 0x7690, 0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306, 0x8E4C, 0x9BAB, 0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09, 0x8E50, 0x5098, 0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8, 0x8E54, 0x6492, 0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6, 0x8E58, 0x73CA, 0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82, 0x8E5C, 0x8695, 0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178, 0x8E60, 0x9910, 0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B, 0x8E64, 0x4ED5, 0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F, 0x8E68, 0x523A, 0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3, 0x8E6C, 0x56DB, 0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9, 0x8E70, 0x59FF, 0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02, 0x8E74, 0x5E2B, 0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307, 0x8E78, 0x652F, 0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD, 0x8E7C, 0x65E8, 0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B, 0x8E81, 0x6C0F, 0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1, 0x8E85, 0x7CF8, 0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2, 0x8E89, 0x8102, 0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E, 0x8E8D, 0x8A69, 0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE, 0x8E91, 0x8CC7, 0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC, 0x8E95, 0x6B6F, 0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D, 0x8E99, 0x5150, 0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148, 0x8E9D, 0x6301, 0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB, 0x8EA1, 0x6CBB, 0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4, 0x8EA5, 0x78C1, 0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033, 0x8EA9, 0x81EA, 0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50, 0x8EAD, 0x9E7F, 0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B, 0x8EB1, 0x7AFA, 0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB, 0x8EB5, 0x4E03, 0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931, 0x8EB9, 0x5AC9, 0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F, 0x8EBD, 0x6F06, 0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F, 0x8EC1, 0x8500, 0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4, 0x8EC5, 0x829D, 0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E, 0x8EC9, 0x820E, 0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368, 0x8ECD, 0x8D66, 0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E, 0x8ED1, 0x7D17, 0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA, 0x8ED5, 0x906E, 0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F, 0x8ED9, 0x52FA, 0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C, 0x8EDD, 0x7235, 0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B, 0x8EE1, 0x82E5, 0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9, 0x8EE5, 0x4E3B, 0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B, 0x8EE9, 0x6731, 0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0, 0x8EED, 0x7A2E, 0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152, 0x8EF1, 0x9996, 0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A, 0x8EF5, 0x5BFF, 0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC, 0x8EF9, 0x9700, 0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468, 0x8F40, 0x5B97, 0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE, 0x8F44, 0x6101, 0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0, 0x8F48, 0x79CB, 0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2, 0x8F4C, 0x81ED, 0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846, 0x8F50, 0x8972, 0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F, 0x8F54, 0x9031, 0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6, 0x8F58, 0x919C, 0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145, 0x8F5C, 0x5341, 0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4, 0x8F60, 0x6C41, 0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26, 0x8F64, 0x91CD, 0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919, 0x8F68, 0x5BBF, 0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E, 0x8F6C, 0x7C9B, 0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA, 0x8F70, 0x8853, 0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB, 0x8F74, 0x6625, 0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C, 0x8F78, 0x99FF, 0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC, 0x8F7C, 0x696F, 0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96, 0x8F81, 0x6F64, 0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1, 0x8F85, 0x9075, 0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6, 0x8F89, 0x521D, 0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9, 0x8F8D, 0x6E1A, 0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72, 0x8F91, 0x66F8, 0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8, 0x8F95, 0x52A9, 0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F, 0x8F99, 0x5F90, 0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664, 0x8F9D, 0x50B7, 0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320, 0x8FA1, 0x5347, 0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546, 0x8FA5, 0x5531, 0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE, 0x8FA9, 0x5A3C, 0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F, 0x8FAD, 0x5C11, 0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A, 0x8FB1, 0x5EE0, 0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284, 0x8FB5, 0x62DB, 0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607, 0x8FB9, 0x660C, 0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E, 0x8FBD, 0x68A2, 0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC, 0x8FC1, 0x6D88, 0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C, 0x8FC5, 0x7126, 0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701, 0x8FC9, 0x785D, 0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0, 0x8FCD, 0x7AE0, 0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39, 0x8FD1, 0x8096, 0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549, 0x8FD5, 0x885D, 0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C, 0x8FD9, 0x8A54, 0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE, 0x8FDD, 0x91A4, 0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418, 0x8FE1, 0x969C, 0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08, 0x8FE5, 0x4E1E, 0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270, 0x8FE9, 0x57CE, 0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22, 0x8FED, 0x5E38, 0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761, 0x8FF1, 0x6756, 0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573, 0x8FF5, 0x7A63, 0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8, 0x8FF9, 0x9320, 0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE, 0x9040, 0x62ED, 0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED, 0x9044, 0x7E54, 0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6, 0x9048, 0x98DF, 0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B, 0x904C, 0x4F38, 0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507, 0x9050, 0x5A20, 0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3, 0x9054, 0x614E, 0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B, 0x9058, 0x68EE, 0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1, 0x905C, 0x7533, 0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E, 0x9060, 0x79E6, 0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF, 0x9064, 0x85AA, 0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB, 0x9068, 0x8F9B, 0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707, 0x906C, 0x4EBA, 0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875, 0x9070, 0x58EC, 0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D, 0x9074, 0x814E, 0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663, 0x9078, 0x976D, 0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808, 0x907C, 0x9162, 0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017, 0x9081, 0x5439, 0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8, 0x9085, 0x6C34, 0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B, 0x9089, 0x7FE0, 0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154, 0x908D, 0x9310, 0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E, 0x9091, 0x9AC4, 0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570, 0x9095, 0x67A2, 0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E, 0x9099, 0x6749, 0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817, 0x909D, 0x96C0, 0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A, 0x90A1, 0x5BF8, 0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D, 0x90A5, 0x662F, 0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2, 0x90A9, 0x59D3, 0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210, 0x90AD, 0x653F, 0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674, 0x90B1, 0x68F2, 0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05, 0x90B5, 0x7272, 0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE, 0x90B9, 0x8056, 0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F, 0x90BD, 0x8AA0, 0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D, 0x90C1, 0x9192, 0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589, 0x90C5, 0x7A0E, 0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D, 0x90C9, 0x60DC, 0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614, 0x90CD, 0x6790, 0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D, 0x90D1, 0x7E3E, 0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64, 0x90D5, 0x8DE1, 0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207, 0x90D9, 0x62D9, 0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298, 0x90DD, 0x8A2D, 0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC, 0x90E1, 0x96EA, 0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749, 0x90E5, 0x4ED9, 0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360, 0x90E9, 0x5BA3, 0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD, 0x90ED, 0x6226, 0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813, 0x90F1, 0x6834, 0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17, 0x90F5, 0x67D3, 0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D, 0x90F9, 0x65CB, 0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA, 0x9140, 0x7E4A, 0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B, 0x9144, 0x8239, 0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE, 0x9148, 0x8DF5, 0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD, 0x914C, 0x9291, 0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D, 0x9150, 0x5584, 0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168, 0x9154, 0x7985, 0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE, 0x9158, 0x564C, 0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA, 0x915C, 0x66FE, 0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9, 0x9160, 0x758F, 0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956, 0x9164, 0x79DF, 0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44, 0x9168, 0x8607, 0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061, 0x916C, 0x9F20, 0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC, 0x9170, 0x53E2, 0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE, 0x9174, 0x594F, 0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64, 0x9178, 0x531D, 0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C, 0x917C, 0x6383, 0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD, 0x9181, 0x65E9, 0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD, 0x9185, 0x69FD, 0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89, 0x9189, 0x75E9, 0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF, 0x918D, 0x7DCF, 0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349, 0x9191, 0x8358, 0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB, 0x9195, 0x88C5, 0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D, 0x9199, 0x9397, 0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF, 0x919D, 0x5897, 0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535, 0x91A1, 0x8D08, 0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074, 0x91A5, 0x5247, 0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349, 0x91A9, 0x675F, 0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F, 0x91AD, 0x4FD7, 0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF, 0x91B1, 0x7D9A, 0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176, 0x91B5, 0x63C3, 0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A, 0x91B9, 0x640D, 0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6, 0x91BD, 0x591A, 0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51, 0x91C1, 0x553E, 0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0, 0x91C5, 0x6253, 0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955, 0x91C9, 0x9640, 0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53, 0x91CD, 0x5806, 0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1, 0x91D1, 0x5E2F, 0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B, 0x91D5, 0x6234, 0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE, 0x91D9, 0x80CE, 0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B, 0x91DD, 0x8CB8, 0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A, 0x91E1, 0x9EDB, 0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0, 0x91E5, 0x5927, 0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C, 0x91E9, 0x9DF9, 0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353, 0x91ED, 0x5544, 0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E, 0x91F1, 0x62D3, 0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422, 0x91F5, 0x8A17, 0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE, 0x91F9, 0x8338, 0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA, 0x9240, 0x53E9, 0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0, 0x9244, 0x596A, 0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA, 0x9248, 0x8FBF, 0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8, 0x924C, 0x9C48, 0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39, 0x9250, 0x5358, 0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5, 0x9254, 0x63A2, 0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1, 0x9258, 0x6E5B, 0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF, 0x925C, 0x7BAA, 0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6, 0x9260, 0x86CB, 0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3, 0x9264, 0x58C7, 0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696, 0x9268, 0x6A80, 0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7, 0x926C, 0x5024, 0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B, 0x9270, 0x6065, 0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4, 0x9274, 0x7A1A, 0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718, 0x9278, 0x9045, 0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C, 0x927C, 0x7AF9, 0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010, 0x9281, 0x79E9, 0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1, 0x9285, 0x7740, 0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99, 0x9289, 0x5FE0, 0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1, 0x928D, 0x6CE8, 0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B, 0x9291, 0x914E, 0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17, 0x9295, 0x7026, 0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457, 0x9299, 0x8CAF, 0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB, 0x929D, 0x558B, 0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33, 0x92A1, 0x5E81, 0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B, 0x92A5, 0x5FB4, 0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2, 0x92A9, 0x671D, 0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A, 0x92AD, 0x773A, 0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178, 0x92B1, 0x8776, 0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85, 0x92B5, 0x8DF3, 0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802, 0x92B9, 0x9CE5, 0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4, 0x92BD, 0x6715, 0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3, 0x92C1, 0x93AE, 0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C, 0x92C5, 0x690E, 0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A, 0x92C9, 0x75DB, 0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802, 0x92CD, 0x63B4, 0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C, 0x92D1, 0x67D8, 0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4, 0x92D5, 0x9354, 0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A, 0x92D9, 0x58F7, 0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A, 0x92DD, 0x540A, 0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD, 0x92E1, 0x4F4E, 0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243, 0x92E5, 0x8C9E, 0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A, 0x92E9, 0x5E1D, 0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7, 0x92ED, 0x5F1F, 0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A, 0x92F1, 0x63D0, 0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887, 0x92F5, 0x798E, 0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247, 0x92F9, 0x8A02, 0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013, 0x9340, 0x90B8, 0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E, 0x9344, 0x6CE5, 0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575, 0x9348, 0x6EF4, 0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069, 0x934C, 0x93D1, 0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9, 0x9350, 0x64A4, 0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244, 0x9354, 0x5178, 0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55, 0x9358, 0x5E97, 0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C, 0x935C, 0x8CBC, 0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9, 0x9360, 0x4F1D, 0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530, 0x9364, 0x96FB, 0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835, 0x9368, 0x5857, 0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92, 0x936C, 0x6597, 0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B, 0x9370, 0x83DF, 0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD, 0x9374, 0x934D, 0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA, 0x9378, 0x5EA6, 0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012, 0x937C, 0x5012, 0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD, 0x9381, 0x5200, 0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858, 0x9385, 0x5957, 0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B, 0x9389, 0x60BC, 0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771, 0x938D, 0x6843, 0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7, 0x9391, 0x6DD8, 0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F, 0x9395, 0x71C8, 0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977, 0x9399, 0x7B49, 0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6, 0x939D, 0x7D71, 0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569, 0x93A1, 0x85E4, 0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46, 0x93A5, 0x8E0F, 0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419, 0x93A9, 0x9676, 0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8, 0x93AD, 0x50CD, 0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802, 0x93B1, 0x5C0E, 0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E, 0x93B5, 0x77B3, 0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404, 0x93B9, 0x9053, 0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07, 0x93BD, 0x533F, 0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C, 0x93C1, 0x7279, 0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4, 0x93C5, 0x6BD2, 0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803, 0x93C9, 0x6A61, 0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934, 0x93CD, 0x5C4A, 0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5, 0x93D1, 0x9149, 0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F, 0x93D5, 0x60C7, 0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A, 0x93D9, 0x9041, 0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7, 0x93DD, 0x920D, 0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185, 0x93E1, 0x4E4D, 0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E, 0x93E5, 0x7058, 0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962, 0x93E9, 0x99B4, 0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357, 0x93ED, 0x6960, 0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D, 0x93F1, 0x4E8C, 0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9, 0x93F5, 0x5302, 0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679, 0x93F9, 0x5EFF, 0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165, 0x9440, 0x5982, 0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB, 0x9444, 0x598A, 0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1, 0x9448, 0x79B0, 0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471, 0x944C, 0x732B, 0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5, 0x9450, 0x637B, 0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98, 0x9454, 0x4E43, 0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC, 0x9458, 0x56A2, 0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D, 0x945C, 0x80FD, 0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2, 0x9460, 0x8997, 0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A, 0x9464, 0x64AD, 0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2, 0x9468, 0x6D3E, 0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46, 0x946C, 0x7F75, 0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3, 0x9470, 0x5EC3, 0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557, 0x9474, 0x676F, 0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC, 0x9478, 0x80BA, 0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D, 0x947C, 0x57F9, 0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973, 0x9481, 0x7164, 0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2, 0x9485, 0x8CE0, 0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F, 0x9489, 0x79E4, 0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F, 0x948D, 0x5265, 0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF, 0x9491, 0x6CCA, 0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95, 0x9495, 0x8236, 0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD, 0x9499, 0x6F20, 0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB, 0x949D, 0x99C1, 0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1, 0x94A1, 0x7872, 0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48, 0x94A5, 0x6AE8, 0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551, 0x94A9, 0x7560, 0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C, 0x94AD, 0x767A, 0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10, 0x94B1, 0x7F70, 0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5, 0x94B5, 0x9CE9, 0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4, 0x94B9, 0x96BC, 0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A, 0x94BD, 0x53CD, 0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C, 0x94C1, 0x6591, 0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E, 0x94C5, 0x7248, 0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554, 0x94C9, 0x7E41, 0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9, 0x94CD, 0x7BC4, 0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812, 0x94D1, 0x98EF, 0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A, 0x94D5, 0x76E4, 0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE, 0x94D9, 0x532A, 0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983, 0x94DD, 0x5E87, 0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249, 0x94E1, 0x6279, 0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4, 0x94E5, 0x6CCC, 0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891, 0x94E9, 0x79D8, 0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5, 0x94ED, 0x88AB, 0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F, 0x94F1, 0x975E, 0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38, 0x94F5, 0x5099, 0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787, 0x94F9, 0x6BD8, 0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E, 0x9540, 0x9F3B, 0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339, 0x9544, 0x758B, 0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D, 0x9548, 0x83F1, 0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5, 0x954C, 0x7562, 0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867, 0x9550, 0x59EB, 0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E, 0x9554, 0x8B2C, 0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19, 0x9558, 0x6C37, 0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968, 0x955C, 0x8868, 0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF, 0x9560, 0x63CF, 0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7, 0x9564, 0x9328, 0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED, 0x9568, 0x9C2D, 0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C, 0x956C, 0x6D5C, 0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3, 0x9570, 0x983B, 0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D, 0x9574, 0x4ED8, 0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66, 0x9578, 0x5BCC, 0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C, 0x957C, 0x6016, 0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7, 0x9581, 0x666E, 0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26, 0x9585, 0x8150, 0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C, 0x9589, 0x8CA0, 0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C, 0x958D, 0x9644, 0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66, 0x9591, 0x821E, 0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8, 0x9595, 0x5C01, 0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A, 0x9599, 0x8557, 0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9, 0x959D, 0x5E45, 0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179, 0x95A1, 0x8907, 0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17, 0x95A5, 0x6255, 0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269, 0x95A9, 0x9B92, 0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674, 0x95AD, 0x58B3, 0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A, 0x95B1, 0x596E, 0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B, 0x95B5, 0x96F0, 0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19, 0x95B9, 0x4F75, 0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63, 0x95BD, 0x5E73, 0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26, 0x95C1, 0x853D, 0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73, 0x95C5, 0x9801, 0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656, 0x95C9, 0x78A7, 0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511, 0x95CD, 0x7B86, 0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247, 0x95D1, 0x7BC7, 0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4, 0x95D5, 0x904D, 0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29, 0x95D9, 0x5F01, 0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217, 0x95DD, 0x92EA, 0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69, 0x95E1, 0x752B, 0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42, 0x95E5, 0x52DF, 0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A, 0x95E9, 0x66AE, 0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9, 0x95ED, 0x5023, 0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446, 0x95F1, 0x5831, 0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0, 0x95F5, 0x5CEF, 0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1, 0x95F9, 0x6367, 0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B, 0x9640, 0x6CD5, 0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832, 0x9644, 0x7E2B, 0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C, 0x9648, 0x84EC, 0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A, 0x964C, 0x8C4A, 0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD, 0x9650, 0x9CF3, 0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1, 0x9654, 0x508D, 0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8, 0x9658, 0x5E3D, 0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F, 0x965C, 0x66B4, 0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2, 0x9660, 0x5192, 0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8, 0x9664, 0x8B00, 0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E, 0x9668, 0x9632, 0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317, 0x966C, 0x50D5, 0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2, 0x9670, 0x6734, 0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46, 0x9674, 0x91E6, 0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86, 0x9678, 0x5800, 0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C, 0x967C, 0x7FFB, 0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469, 0x9681, 0x78E8, 0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB, 0x9685, 0x59B9, 0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE, 0x9689, 0x54E9, 0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C, 0x968D, 0x6795, 0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52, 0x9691, 0x685D, 0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8, 0x9695, 0x62B9, 0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4, 0x9699, 0x4FAD, 0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07, 0x969D, 0x6162, 0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513, 0x96A1, 0x5473, 0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3, 0x96A5, 0x7B95, 0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C, 0x96A9, 0x6E4A, 0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108, 0x96AD, 0x5999, 0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720, 0x96B1, 0x52D9, 0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F, 0x96B5, 0x77DB, 0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B, 0x96B9, 0x5A7F, 0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D, 0x96BD, 0x547D, 0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7, 0x96C1, 0x9298, 0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D, 0x96C5, 0x6EC5, 0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF, 0x96C9, 0x7DEC, 0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478, 0x96CD, 0x6A21, 0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F, 0x96D1, 0x6BDB, 0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2, 0x96D5, 0x8017, 0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728, 0x96D9, 0x9ED9, 0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF, 0x96DD, 0x9905, 0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E, 0x96E1, 0x8CB0, 0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B, 0x96E5, 0x9580, 0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6, 0x96E9, 0x591C, 0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE, 0x96ED, 0x5F25, 0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79, 0x96F1, 0x7D04, 0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D, 0x96F5, 0x9756, 0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453, 0x96F9, 0x6109, 0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652, 0x9740, 0x8AED, 0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51, 0x9744, 0x512A, 0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5, 0x9748, 0x5E7D, 0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6, 0x974C, 0x6709, 0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C, 0x9750, 0x7336, 0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950, 0x9754, 0x88D5, 0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091, 0x9758, 0x90F5, 0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915, 0x975C, 0x4E88, 0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89, 0x9760, 0x8F3F, 0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C, 0x9764, 0x5996, 0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA, 0x9768, 0x63FA, 0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A, 0x976C, 0x69D8, 0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194, 0x9770, 0x7528, 0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000, 0x9774, 0x8449, 0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21, 0x9778, 0x8E0A, 0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A, 0x977C, 0x617E, 0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83, 0x9781, 0x6D74, 0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0, 0x9785, 0x7F85, 0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765, 0x9789, 0x83B1, 0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B, 0x978D, 0x7D61, 0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71, 0x9791, 0x5375, 0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB, 0x9795, 0x85CD, 0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229, 0x9799, 0x540F, 0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8, 0x979D, 0x7406, 0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF, 0x97A1, 0x88E1, 0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678, 0x97A5, 0x5F8B, 0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E, 0x97A9, 0x63A0, 0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41, 0x97AD, 0x6E9C, 0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B, 0x97B1, 0x7C92, 0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D, 0x97B5, 0x4FB6, 0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C, 0x97B9, 0x4E86, 0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21, 0x97BD, 0x51CC, 0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881, 0x97C1, 0x6DBC, 0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD, 0x97C5, 0x7A1C, 0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2, 0x97C9, 0x907C, 0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818, 0x97CD, 0x529B, 0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398, 0x97D1, 0x6797, 0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433, 0x97D5, 0x81E8, 0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57, 0x97D9, 0x9E9F, 0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99, 0x97DD, 0x7D2F, 0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36, 0x97E1, 0x4F8B, 0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA, 0x97E5, 0x601C, 0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3, 0x97E9, 0x9234, 0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A, 0x97ED, 0x9E97, 0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74, 0x97F1, 0x5217, 0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2, 0x97F5, 0x5EC9, 0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23, 0x97F9, 0x7149, 0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F, 0x9840, 0x84EE, 0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442, 0x9844, 0x9B6F, 0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2, 0x9848, 0x8DEF, 0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41, 0x984C, 0x5ECA, 0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C, 0x9850, 0x6994, 0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262, 0x9854, 0x72FC, 0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E, 0x9858, 0x874B, 0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93, 0x985C, 0x7984, 0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6, 0x9860, 0x502D, 0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A, 0x9864, 0x8CC4, 0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0, 0x9868, 0x9DF2, 0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10, 0x986C, 0x8A6B, 0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900, 0x9870, 0x6E7E, 0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C, 0x98A0, 0x4E10, 0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31, 0x98A4, 0x4E36, 0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42, 0x98A8, 0x4E56, 0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85, 0x98AC, 0x8C6B, 0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D, 0x98B0, 0x4E8E, 0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0, 0x98B4, 0x4EA2, 0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6, 0x98B8, 0x4ECE, 0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6, 0x98BC, 0x4EC2, 0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED, 0x98C0, 0x4EDF, 0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A, 0x98C4, 0x4F30, 0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57, 0x98C8, 0x4F47, 0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F, 0x98CC, 0x4F98, 0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70, 0x98D0, 0x4F91, 0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96, 0x98D4, 0x5118, 0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE, 0x98D8, 0x4FD8, 0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA, 0x98DC, 0x4FD0, 0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A, 0x98E0, 0x5028, 0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025, 0x98E4, 0x5005, 0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021, 0x98E8, 0x5029, 0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF, 0x98EC, 0x5011, 0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047, 0x98F0, 0x6703, 0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048, 0x98F4, 0x505A, 0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078, 0x98F8, 0x5080, 0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4, 0x98FC, 0x50B2, 0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3, 0x9943, 0x50C2, 0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5, 0x9947, 0x50ED, 0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9, 0x994B, 0x50F5, 0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102, 0x994F, 0x5116, 0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A, 0x9953, 0x5121, 0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C, 0x9957, 0x513B, 0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152, 0x995B, 0x514C, 0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8, 0x995F, 0x5169, 0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180, 0x9963, 0x5182, 0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189, 0x9967, 0x518F, 0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195, 0x996B, 0x5196, 0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2, 0x996F, 0x51A9, 0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3, 0x9973, 0x51B1, 0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5, 0x9977, 0x51BD, 0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB, 0x997B, 0x51E0, 0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED, 0x9980, 0x51F0, 0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204, 0x9984, 0x520B, 0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227, 0x9988, 0x522A, 0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239, 0x998C, 0x524F, 0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C, 0x9990, 0x525E, 0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274, 0x9994, 0x5269, 0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D, 0x9998, 0x528D, 0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271, 0x999C, 0x5288, 0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7, 0x99A0, 0x52AC, 0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5, 0x99A4, 0x52C1, 0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE, 0x99A8, 0x52E3, 0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0, 0x99AC, 0x52F3, 0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9, 0x99B0, 0x5306, 0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D, 0x99B4, 0x5310, 0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A, 0x99B8, 0x5323, 0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333, 0x99BC, 0x5338, 0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345, 0x99C0, 0x4E17, 0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6, 0x99C4, 0x535E, 0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918, 0x99C8, 0x537B, 0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396, 0x99CC, 0x53A0, 0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE, 0x99D0, 0x53B0, 0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12, 0x99D4, 0x96D9, 0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE, 0x99D8, 0x53EE, 0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA, 0x99DC, 0x5401, 0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C, 0x99E0, 0x542D, 0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436, 0x99E4, 0x5429, 0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F, 0x99E8, 0x5475, 0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471, 0x99EC, 0x5477, 0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B, 0x99F0, 0x5480, 0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490, 0x99F4, 0x5486, 0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8, 0x99F8, 0x54A5, 0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8, 0x99FC, 0x54A8, 0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4, 0x9A43, 0x54BE, 0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5, 0x9A47, 0x54E6, 0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD, 0x9A4B, 0x54EE, 0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2, 0x9A4F, 0x5539, 0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C, 0x9A53, 0x552E, 0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556, 0x9A57, 0x5557, 0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D, 0x9A5B, 0x5599, 0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A, 0x9A5F, 0x559F, 0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598, 0x9A63, 0x559E, 0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583, 0x9A67, 0x55A9, 0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA, 0x9A6B, 0x55C5, 0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC, 0x9A6F, 0x55E4, 0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7, 0x9A73, 0x5616, 0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B, 0x9A77, 0x55F9, 0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF, 0x9A7B, 0x5634, 0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638, 0x9A80, 0x566B, 0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C, 0x9A84, 0x566A, 0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A, 0x9A88, 0x56A0, 0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5, 0x9A8C, 0x56AE, 0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2, 0x9A90, 0x56BC, 0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0, 0x9A94, 0x56C8, 0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3, 0x9A98, 0x56D7, 0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700, 0x9A9C, 0x56FF, 0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708, 0x9AA0, 0x570B, 0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718, 0x9AA4, 0x5716, 0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726, 0x9AA8, 0x5737, 0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B, 0x9AAC, 0x5740, 0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0, 0x9AB0, 0x5788, 0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789, 0x9AB4, 0x5793, 0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4, 0x9AB8, 0x57AA, 0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6, 0x9ABC, 0x57D4, 0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A, 0x9AC0, 0x57D6, 0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819, 0x9AC4, 0x581D, 0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862, 0x9AC8, 0x584B, 0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852, 0x9ACC, 0x583D, 0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9, 0x9AD0, 0x589F, 0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE, 0x9AD4, 0x58BB, 0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5, 0x9AD8, 0x58D3, 0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9, 0x9ADC, 0x58D8, 0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4, 0x9AE0, 0x58DF, 0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9, 0x9AE4, 0x58FB, 0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902, 0x9AE8, 0x590A, 0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6, 0x9AEC, 0x5925, 0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932, 0x9AF0, 0x5938, 0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955, 0x9AF4, 0x5950, 0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958, 0x9AF8, 0x5962, 0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C, 0x9AFC, 0x5969, 0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D, 0x9B43, 0x4F5E, 0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2, 0x9B47, 0x59C6, 0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D, 0x9B4B, 0x59D9, 0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F, 0x9B4F, 0x5A11, 0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A, 0x9B53, 0x5A40, 0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35, 0x9B57, 0x5A36, 0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A, 0x9B5B, 0x5ABC, 0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2, 0x9B5F, 0x5ABD, 0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6, 0x9B63, 0x5AE9, 0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB, 0x9B67, 0x5B0C, 0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32, 0x9B6B, 0x5AD0, 0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E, 0x9B6F, 0x5B43, 0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51, 0x9B73, 0x5B55, 0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65, 0x9B77, 0x5B69, 0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75, 0x9B7B, 0x5B78, 0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80, 0x9B80, 0x5B83, 0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3, 0x9B84, 0x5BC7, 0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0, 0x9B88, 0x5BE4, 0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE, 0x9B8C, 0x5BE5, 0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6, 0x9B90, 0x5BF3, 0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08, 0x9B94, 0x5C0D, 0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22, 0x9B98, 0x5C28, 0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41, 0x9B9C, 0x5C46, 0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50, 0x9BA0, 0x5C4F, 0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E, 0x9BA4, 0x4E62, 0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C, 0x9BA8, 0x5C91, 0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB, 0x9BAC, 0x5CBB, 0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7, 0x9BB0, 0x5CC5, 0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9, 0x9BB4, 0x5CE9, 0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED, 0x9BB8, 0x5D8C, 0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15, 0x9BBC, 0x5D17, 0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B, 0x9BC0, 0x5D11, 0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A, 0x9BC4, 0x5D19, 0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52, 0x9BC8, 0x5D4E, 0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73, 0x9BCC, 0x5D76, 0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82, 0x9BD0, 0x5DA2, 0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE, 0x9BD4, 0x5DBD, 0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC, 0x9BD8, 0x5DC9, 0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2, 0x9BDC, 0x5DD6, 0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2, 0x9BE0, 0x5DF5, 0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19, 0x9BE4, 0x5E11, 0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37, 0x9BE8, 0x5E44, 0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E, 0x9BEC, 0x5E57, 0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62, 0x9BF0, 0x5E64, 0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76, 0x9BF4, 0x5E7A, 0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0, 0x9BF8, 0x5EC1, 0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0, 0x9BFC, 0x5ECF, 0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD, 0x9C43, 0x5EDA, 0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1, 0x9C47, 0x5EE8, 0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1, 0x9C4B, 0x5EF3, 0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8, 0x9C4F, 0x5EFE, 0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D, 0x9C53, 0x5F5C, 0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16, 0x9C57, 0x5F29, 0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41, 0x9C5B, 0x5F48, 0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F, 0x9C5F, 0x5F51, 0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59, 0x9C63, 0x5F61, 0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77, 0x9C67, 0x5F83, 0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A, 0x9C6B, 0x5F88, 0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E, 0x9C6F, 0x5F99, 0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8, 0x9C73, 0x5FAD, 0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB, 0x9C77, 0x5FE4, 0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD, 0x9C7B, 0x60B3, 0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060, 0x9C80, 0x6019, 0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E, 0x9C84, 0x6031, 0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B, 0x9C88, 0x6026, 0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A, 0x9C8C, 0x6041, 0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F, 0x9C90, 0x604A, 0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063, 0x9C94, 0x6043, 0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C, 0x9C98, 0x606B, 0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D, 0x9C9C, 0x60E7, 0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084, 0x9CA0, 0x609B, 0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092, 0x9CA4, 0x60A7, 0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8, 0x9CA8, 0x60E0, 0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0, 0x9CAC, 0x60BD, 0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8, 0x9CB0, 0x614D, 0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6, 0x9CB4, 0x60F7, 0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA, 0x9CB8, 0x6103, 0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1, 0x9CBC, 0x610D, 0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E, 0x9CC0, 0x6128, 0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F, 0x9CC4, 0x613C, 0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D, 0x9CC8, 0x6142, 0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177, 0x9CCC, 0x6158, 0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B, 0x9CD0, 0x6174, 0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171, 0x9CD4, 0x615F, 0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175, 0x9CD8, 0x6199, 0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC, 0x9CDC, 0x6194, 0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191, 0x9CE0, 0x61AB, 0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA, 0x9CE4, 0x61C9, 0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3, 0x9CE8, 0x61C6, 0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79, 0x9CEC, 0x61CD, 0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6, 0x9CF0, 0x61FA, 0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD, 0x9CF4, 0x61FC, 0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208, 0x9CF8, 0x6209, 0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214, 0x9CFC, 0x621B, 0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A, 0x9D43, 0x622E, 0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233, 0x9D47, 0x6241, 0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263, 0x9D4B, 0x625B, 0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C, 0x9D4F, 0x6282, 0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292, 0x9D53, 0x6293, 0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283, 0x9D57, 0x6294, 0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB, 0x9D5B, 0x62CF, 0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4, 0x9D5F, 0x62C8, 0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA, 0x9D63, 0x62C2, 0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9, 0x9D67, 0x630C, 0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327, 0x9D6B, 0x6302, 0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5, 0x9D6F, 0x6350, 0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C, 0x9D73, 0x634F, 0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380, 0x9D77, 0x63AB, 0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F, 0x9D7B, 0x6389, 0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B, 0x9D80, 0x6369, 0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0, 0x9D84, 0x63C6, 0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2, 0x9D88, 0x63F6, 0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434, 0x9D8C, 0x6406, 0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436, 0x9D90, 0x651D, 0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F, 0x9D94, 0x6467, 0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E, 0x9D98, 0x652A, 0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5, 0x9D9C, 0x64A9, 0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA, 0x9DA0, 0x64D2, 0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB, 0x9DA4, 0x64D8, 0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7, 0x9DA8, 0x8209, 0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC, 0x9DAC, 0x64E3, 0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6, 0x9DB0, 0x64F4, 0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500, 0x9DB4, 0x64FD, 0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505, 0x9DB8, 0x6524, 0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534, 0x9DBC, 0x6535, 0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538, 0x9DC0, 0x754B, 0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555, 0x9DC4, 0x654D, 0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D, 0x9DC8, 0x6572, 0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583, 0x9DCC, 0x8B8A, 0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB, 0x9DD0, 0x65B7, 0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1, 0x9DD4, 0x65C4, 0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB, 0x9DD8, 0x65D9, 0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1, 0x9DDC, 0x6772, 0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB, 0x9DE0, 0x6773, 0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634, 0x9DE4, 0x661C, 0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649, 0x9DE8, 0x6641, 0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664, 0x9DEC, 0x6667, 0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662, 0x9DF0, 0x6670, 0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E, 0x9DF4, 0x6689, 0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D, 0x9DF8, 0x66C1, 0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE, 0x9DFC, 0x66BC, 0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6, 0x9E43, 0x66DA, 0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6, 0x9E47, 0x66E9, 0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7, 0x9E4B, 0x670F, 0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726, 0x9E4F, 0x6727, 0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F, 0x9E53, 0x6736, 0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737, 0x9E57, 0x6746, 0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759, 0x9E5B, 0x6763, 0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770, 0x9E5F, 0x67A9, 0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C, 0x9E63, 0x678B, 0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785, 0x9E67, 0x67B7, 0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC, 0x9E6B, 0x67B3, 0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4, 0x9E6F, 0x67DE, 0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE, 0x9E73, 0x67B9, 0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7, 0x9E77, 0x6A9C, 0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829, 0x9E7B, 0x6840, 0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E, 0x9E80, 0x68B3, 0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863, 0x9E84, 0x6877, 0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F, 0x9E88, 0x68AD, 0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B, 0x9E8C, 0x6883, 0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874, 0x9E90, 0x68B5, 0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F, 0x9E94, 0x688D, 0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA, 0x9E98, 0x6908, 0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926, 0x9E9C, 0x68E1, 0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4, 0x9EA0, 0x68E7, 0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912, 0x9EA4, 0x6904, 0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925, 0x9EA8, 0x68F9, 0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928, 0x9EAC, 0x692A, 0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921, 0x9EB0, 0x68C6, 0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C, 0x9EB4, 0x6978, 0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E, 0x9EB8, 0x696E, 0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D, 0x9EBC, 0x6959, 0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E, 0x9EC0, 0x695D, 0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2, 0x9EC4, 0x69AE, 0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1, 0x9EC8, 0x69D3, 0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8, 0x9ECC, 0x69CA, 0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3, 0x9ED0, 0x69A7, 0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0, 0x9ED4, 0x699C, 0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE, 0x9ED8, 0x69E8, 0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF, 0x9EDC, 0x6B0A, 0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7, 0x9EE0, 0x6A05, 0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED, 0x9EE4, 0x6A14, 0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12, 0x9EE8, 0x6AC1, 0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44, 0x9EEC, 0x6A0C, 0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78, 0x9EF0, 0x6A47, 0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66, 0x9EF4, 0x6A48, 0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90, 0x9EF8, 0x6A8D, 0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2, 0x9EFC, 0x6AA3, 0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB, 0x9F43, 0x6AC3, 0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3, 0x9F47, 0x6AAC, 0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF, 0x9F4B, 0x6AAA, 0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB, 0x9F4F, 0x6B05, 0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12, 0x9F53, 0x6B16, 0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38, 0x9F57, 0x6B37, 0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE, 0x9F5B, 0x6B47, 0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50, 0x9F5F, 0x6B59, 0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F, 0x9F63, 0x6B61, 0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F, 0x9F67, 0x6B80, 0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D, 0x9F6B, 0x6B98, 0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4, 0x9F6F, 0x6BAA, 0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2, 0x9F73, 0x6BB1, 0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC, 0x9F77, 0x6BC6, 0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF, 0x9F7B, 0x6BEC, 0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF, 0x9F80, 0x9EBE, 0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14, 0x9F84, 0x6C1B, 0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E, 0x9F88, 0x6C55, 0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82, 0x9F8C, 0x6C8D, 0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B, 0x9F90, 0x6C7E, 0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92, 0x9F94, 0x6C90, 0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3, 0x9F98, 0x6CBD, 0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD, 0x9F9C, 0x6CAE, 0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA, 0x9FA0, 0x6CDB, 0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA, 0x9FA4, 0x6D1F, 0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B, 0x9FA8, 0x6D3D, 0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35, 0x9FAC, 0x6D33, 0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63, 0x9FB0, 0x6D93, 0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79, 0x9FB4, 0x6D59, 0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4, 0x9FB8, 0x6D85, 0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A, 0x9FBC, 0x6DB5, 0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8, 0x9FC0, 0x6DC6, 0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC, 0x9FC4, 0x6DE8, 0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA, 0x9FC8, 0x6DD9, 0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA, 0x9FCC, 0x6DEE, 0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E, 0x9FD0, 0x6E19, 0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E, 0x9FD4, 0x6E23, 0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76, 0x9FD8, 0x6E4D, 0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A, 0x9FDC, 0x6E4E, 0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D, 0x9FE0, 0x6E38, 0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98, 0x9FE4, 0x6EC9, 0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD, 0x9FE8, 0x6EAF, 0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4, 0x9FEC, 0x6ED5, 0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2, 0x9FF0, 0x6E9F, 0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C, 0x9FF4, 0x6EEC, 0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F, 0x9FF8, 0x6EF2, 0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32, 0x9FFC, 0x6ECC, 0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7, 0xE043, 0x6F86, 0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81, 0xE047, 0x6F80, 0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3, 0xE04B, 0x6F6D, 0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58, 0xE04F, 0x6F8E, 0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66, 0xE053, 0x6FB3, 0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4, 0xE057, 0x6FB9, 0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF, 0xE05B, 0x6FD5, 0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8, 0xE05F, 0x6FF1, 0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009, 0xE063, 0x700B, 0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001, 0xE067, 0x700F, 0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A, 0xE06B, 0x6F74, 0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F, 0xE06F, 0x7030, 0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051, 0xE073, 0x7063, 0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF, 0xE077, 0x70F1, 0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3, 0xE07B, 0x70AE, 0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD, 0xE080, 0x70D9, 0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C, 0xE084, 0x7119, 0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188, 0xE088, 0x7166, 0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156, 0xE08C, 0x716C, 0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184, 0xE090, 0x7195, 0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7, 0xE094, 0x71B9, 0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9, 0xE098, 0x71D4, 0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC, 0xE09C, 0x71E7, 0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9, 0xE0A0, 0x71FF, 0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B, 0xE0A4, 0x7228, 0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230, 0xE0A8, 0x7232, 0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F, 0xE0AC, 0x7240, 0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258, 0xE0B0, 0x7274, 0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281, 0xE0B4, 0x7287, 0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2, 0xE0B8, 0x72A7, 0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3, 0xE0BC, 0x72C6, 0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2, 0xE0C0, 0x72E2, 0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9, 0xE0C4, 0x72F7, 0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A, 0xE0C8, 0x731C, 0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334, 0xE0CC, 0x732F, 0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E, 0xE0D0, 0x734E, 0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357, 0xE0D4, 0x736A, 0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378, 0xE0D8, 0x7375, 0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8, 0xE0DC, 0x73B3, 0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0, 0xE0E0, 0x73E5, 0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2, 0xE0E4, 0x7405, 0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8, 0xE0E8, 0x7432, 0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F, 0xE0EC, 0x745F, 0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C, 0xE0F0, 0x7469, 0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A, 0xE0F4, 0x7476, 0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E, 0xE0F8, 0x74A7, 0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4, 0xE0FC, 0x73F1, 0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7, 0xE143, 0x74E9, 0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0, 0xE147, 0x74F1, 0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504, 0xE14B, 0x7503, 0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E, 0xE14F, 0x750D, 0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E, 0xE153, 0x7526, 0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544, 0xE157, 0x754D, 0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B, 0xE15B, 0x7546, 0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564, 0xE15F, 0x7567, 0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578, 0xE163, 0x7576, 0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574, 0xE167, 0x758A, 0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594, 0xE16B, 0x759A, 0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3, 0xE16F, 0x75C2, 0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5, 0xE173, 0x75BD, 0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1, 0xE177, 0x75CD, 0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9, 0xE17B, 0x75E3, 0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF, 0xE180, 0x75FC, 0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA, 0xE184, 0x75F2, 0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D, 0xE188, 0x7609, 0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620, 0xE18C, 0x7621, 0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634, 0xE190, 0x7630, 0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648, 0xE194, 0x7646, 0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661, 0xE198, 0x7662, 0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A, 0xE19C, 0x7667, 0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672, 0xE1A0, 0x7676, 0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680, 0xE1A4, 0x7683, 0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E, 0xE1A8, 0x7696, 0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A, 0xE1AC, 0x76B0, 0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9, 0xE1B0, 0x76BA, 0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6, 0xE1B4, 0x76D2, 0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5, 0xE1B8, 0x76E7, 0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB, 0xE1BC, 0x7708, 0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729, 0xE1C0, 0x7724, 0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726, 0xE1C4, 0x771B, 0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747, 0xE1C8, 0x775A, 0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B, 0xE1CC, 0x7765, 0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779, 0xE1D0, 0x778E, 0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0, 0xE1D4, 0x779E, 0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9, 0xE1D8, 0x77BF, 0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB, 0xE1DC, 0x77C7, 0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA, 0xE1E0, 0x77DC, 0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC, 0xE1E4, 0x780C, 0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820, 0xE1E8, 0x792A, 0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874, 0xE1EC, 0x7886, 0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C, 0xE1F0, 0x78A3, 0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF, 0xE1F4, 0x78D1, 0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4, 0xE1F8, 0x78BE, 0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA, 0xE1FC, 0x78EC, 0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD, 0xE243, 0x78F4, 0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911, 0xE247, 0x7919, 0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940, 0xE24B, 0x7960, 0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A, 0xE24F, 0x7955, 0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F, 0xE253, 0x798A, 0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B, 0xE257, 0x79AA, 0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9, 0xE25B, 0x79BA, 0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7, 0xE25F, 0x79EC, 0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08, 0xE263, 0x7A0D, 0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20, 0xE267, 0x7A1F, 0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B, 0xE26B, 0x7A3E, 0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57, 0xE26F, 0x7A49, 0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69, 0xE273, 0x9F9D, 0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D, 0xE277, 0x7A88, 0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98, 0xE27B, 0x7A96, 0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0, 0xE280, 0x7AB6, 0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF, 0xE284, 0x9083, 0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD, 0xE288, 0x7ACF, 0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9, 0xE28C, 0x7ADA, 0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2, 0xE290, 0x7AE6, 0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02, 0xE294, 0x7B0F, 0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33, 0xE298, 0x7B18, 0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35, 0xE29C, 0x7B28, 0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A, 0xE2A0, 0x7B04, 0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C, 0xE2A4, 0x7B45, 0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74, 0xE2A8, 0x7B67, 0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C, 0xE2AC, 0x7B6E, 0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F, 0xE2B0, 0x7B8D, 0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B, 0xE2B4, 0x7B92, 0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99, 0xE2B8, 0x7BCB, 0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF, 0xE2BC, 0x7BB4, 0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9, 0xE2C0, 0x7C11, 0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5, 0xE2C4, 0x7C60, 0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13, 0xE2C8, 0x7BF3, 0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D, 0xE2CC, 0x7BF6, 0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A, 0xE2D0, 0x7C1F, 0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D, 0xE2D4, 0x7C4C, 0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F, 0xE2D8, 0x7C40, 0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F, 0xE2DC, 0x7C64, 0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C, 0xE2E0, 0x7C75, 0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4, 0xE2E4, 0x7CAD, 0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1, 0xE2E8, 0x7CA8, 0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1, 0xE2EC, 0x7CAE, 0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0, 0xE2F0, 0x7CC5, 0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2, 0xE2F4, 0x7CDC, 0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF, 0xE2F8, 0x7CF2, 0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA, 0xE2FC, 0x7D06, 0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15, 0xE343, 0x7D0A, 0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E, 0xE347, 0x7D32, 0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46, 0xE34B, 0x7D73, 0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72, 0xE34F, 0x7D68, 0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63, 0xE353, 0x7D93, 0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F, 0xE357, 0x7D7D, 0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE, 0xE35B, 0x7DA3, 0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD, 0xE35F, 0x7DAB, 0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF, 0xE363, 0x7DDC, 0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0, 0xE367, 0x7DD8, 0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE, 0xE36B, 0x7DFB, 0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05, 0xE36F, 0x7E0A, 0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12, 0xE373, 0x7E31, 0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B, 0xE377, 0x7E22, 0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B, 0xE37B, 0x7E35, 0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37, 0xE380, 0x7E32, 0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D, 0xE384, 0x7E56, 0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A, 0xE388, 0x7E79, 0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C, 0xE38C, 0x7E7B, 0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D, 0xE390, 0x8FAE, 0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89, 0xE394, 0x7E8C, 0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93, 0xE398, 0x7E94, 0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B, 0xE39C, 0x7E9C, 0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45, 0xE3A0, 0x7F4C, 0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50, 0xE3A4, 0x7F51, 0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58, 0xE3A8, 0x7F5F, 0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69, 0xE3AC, 0x7F67, 0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86, 0xE3B0, 0x7F83, 0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C, 0xE3B4, 0x7F94, 0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A, 0xE3B8, 0x7FA3, 0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9, 0xE3BC, 0x7FAE, 0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71, 0xE3C0, 0x7FC5, 0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5, 0xE3C4, 0x7FD4, 0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9, 0xE3C8, 0x7FF3, 0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006, 0xE3CC, 0x8004, 0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018, 0xE3D0, 0x8019, 0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028, 0xE3D4, 0x803F, 0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046, 0xE3D8, 0x8052, 0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F, 0xE3DC, 0x8062, 0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072, 0xE3E0, 0x8070, 0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D, 0xE3E4, 0x807F, 0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085, 0xE3E8, 0x809B, 0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD, 0xE3EC, 0x5190, 0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5, 0xE3F0, 0x80D9, 0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA, 0xE3F4, 0x80D6, 0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1, 0xE3F8, 0x811B, 0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F, 0xE3FC, 0x814B, 0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E, 0xE443, 0x8153, 0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171, 0xE447, 0x816E, 0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174, 0xE44B, 0x8183, 0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180, 0xE44F, 0x8182, 0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4, 0xE453, 0x81A3, 0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9, 0xE457, 0x81B0, 0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8, 0xE45B, 0x81BD, 0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA, 0xE45F, 0x81C9, 0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9, 0xE463, 0x81D8, 0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF, 0xE467, 0x81E0, 0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB, 0xE46B, 0x81FE, 0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205, 0xE46F, 0x8207, 0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210, 0xE473, 0x8216, 0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238, 0xE477, 0x8233, 0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258, 0xE47B, 0x825D, 0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264, 0xE480, 0x8262, 0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B, 0xE484, 0x822E, 0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278, 0xE488, 0x827E, 0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB, 0xE48C, 0x829F, 0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1, 0xE490, 0x82E3, 0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4, 0xE494, 0x82F3, 0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303, 0xE498, 0x82FB, 0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306, 0xE49C, 0x82DC, 0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335, 0xE4A0, 0x8334, 0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331, 0xE4A4, 0x8340, 0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345, 0xE4A8, 0x832F, 0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318, 0xE4AC, 0x8385, 0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F, 0xE4B0, 0x83A2, 0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E, 0xE4B4, 0x8387, 0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5, 0xE4B8, 0x8373, 0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389, 0xE4BC, 0x83A8, 0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB, 0xE4C0, 0x83CE, 0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8, 0xE4C4, 0x840B, 0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407, 0xE4C8, 0x83E0, 0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422, 0xE4CC, 0x8420, 0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506, 0xE4D0, 0x83FB, 0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C, 0xE4D4, 0x855A, 0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B, 0xE4D8, 0x84AD, 0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469, 0xE4DC, 0x8446, 0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479, 0xE4E0, 0x8435, 0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9, 0xE4E4, 0x84BF, 0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD, 0xE4E8, 0x84BB, 0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1, 0xE4EC, 0x84C6, 0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521, 0xE4F0, 0x84FF, 0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518, 0xE4F4, 0x852C, 0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514, 0xE4F8, 0x84FC, 0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558, 0xE4FC, 0x8548, 0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B, 0xE543, 0x8555, 0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588, 0xE547, 0x8591, 0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D, 0xE54B, 0x8594, 0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587, 0xE54F, 0x859C, 0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590, 0xE553, 0x85C9, 0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9, 0xE557, 0x85D0, 0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5, 0xE55B, 0x85DC, 0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613, 0xE55F, 0x860B, 0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606, 0xE563, 0x8622, 0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F, 0xE567, 0x864D, 0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F, 0xE56B, 0x8667, 0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3, 0xE56F, 0x86A9, 0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C, 0xE573, 0x86B6, 0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6, 0xE577, 0x86B0, 0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB, 0xE57B, 0x86D4, 0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC, 0xE580, 0x86DF, 0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712, 0xE584, 0x8706, 0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703, 0xE588, 0x86FB, 0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D, 0xE58C, 0x86F9, 0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F, 0xE590, 0x8737, 0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729, 0xE594, 0x871A, 0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778, 0xE598, 0x874C, 0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757, 0xE59C, 0x8768, 0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753, 0xE5A0, 0x8763, 0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2, 0xE5A4, 0x879F, 0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB, 0xE5A8, 0x87BD, 0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6, 0xE5AC, 0x87AB, 0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7, 0xE5B0, 0x87C6, 0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2, 0xE5B4, 0x87E0, 0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE, 0xE5B8, 0x87F6, 0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2, 0xE5BC, 0x8811, 0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822, 0xE5C0, 0x8821, 0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839, 0xE5C4, 0x8827, 0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842, 0xE5C8, 0x8852, 0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862, 0xE5CC, 0x886B, 0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E, 0xE5D0, 0x8875, 0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872, 0xE5D4, 0x8882, 0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE, 0xE5D8, 0x8899, 0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4, 0xE5DC, 0x88B0, 0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3, 0xE5E0, 0x88C4, 0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9, 0xE5E4, 0x88DD, 0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC, 0xE5E8, 0x88F4, 0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904, 0xE5EC, 0x890C, 0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943, 0xE5F0, 0x891E, 0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B, 0xE5F4, 0x8941, 0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936, 0xE5F8, 0x8938, 0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960, 0xE5FC, 0x895E, 0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D, 0xE643, 0x896A, 0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977, 0xE647, 0x897E, 0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A, 0xE64B, 0x8993, 0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9, 0xE64F, 0x89A6, 0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2, 0xE653, 0x89BA, 0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0, 0xE657, 0x89DA, 0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7, 0xE65B, 0x89F4, 0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16, 0xE65F, 0x8A10, 0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D, 0xE663, 0x8A25, 0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B, 0xE667, 0x8A52, 0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C, 0xE66B, 0x8A6D, 0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85, 0xE66F, 0x8A82, 0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1, 0xE673, 0x8A91, 0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A, 0xE677, 0x8AA3, 0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2, 0xE67B, 0x8ADA, 0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7, 0xE680, 0x8AE4, 0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0, 0xE684, 0x8AE2, 0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB, 0xE688, 0x8B0C, 0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1, 0xE68C, 0x8B16, 0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20, 0xE690, 0x8B33, 0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B, 0xE694, 0x8B3E, 0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C, 0xE698, 0x8B4F, 0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56, 0xE69C, 0x8B5B, 0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F, 0xE6A0, 0x8B6C, 0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D, 0xE6A4, 0x8B80, 0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92, 0xE6A8, 0x8B93, 0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A, 0xE6AC, 0x8C3A, 0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48, 0xE6B0, 0x8C4C, 0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55, 0xE6B4, 0x8C62, 0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A, 0xE6B8, 0x8C82, 0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A, 0xE6BC, 0x8C8D, 0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C, 0xE6C0, 0x8C98, 0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA, 0xE6C4, 0x8CBD, 0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE, 0xE6C8, 0x8CB6, 0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4, 0xE6CC, 0x8CE3, 0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA, 0xE6D0, 0x8CFB, 0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A, 0xE6D4, 0x8D07, 0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10, 0xE6D8, 0x9F4E, 0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14, 0xE6DC, 0x8D16, 0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71, 0xE6E0, 0x8D73, 0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2, 0xE6E4, 0x8DBE, 0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA, 0xE6E8, 0x8DD6, 0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB, 0xE6EC, 0x8DEA, 0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3, 0xE6F0, 0x8DFC, 0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF, 0xE6F4, 0x8E1D, 0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F, 0xE6F8, 0x8E42, 0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34, 0xE6FC, 0x8E4A, 0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C, 0xE743, 0x8E50, 0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64, 0xE747, 0x8E60, 0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55, 0xE74B, 0x8E76, 0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81, 0xE74F, 0x8E87, 0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B, 0xE753, 0x8E8A, 0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94, 0xE757, 0x8E99, 0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC, 0xE75B, 0x8EB0, 0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE, 0xE75F, 0x8EC5, 0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB, 0xE763, 0x8EE3, 0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB, 0xE767, 0x8EFE, 0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15, 0xE76B, 0x8F12, 0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C, 0xE76F, 0x8F1F, 0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26, 0xE773, 0x8F33, 0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45, 0xE777, 0x8F42, 0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49, 0xE77B, 0x8F46, 0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C, 0xE780, 0x8F62, 0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C, 0xE784, 0x8F9F, 0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF, 0xE788, 0x8FB7, 0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2, 0xE78C, 0x8FEA, 0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4, 0xE790, 0x9005, 0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011, 0xE794, 0x9015, 0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E, 0xE798, 0x9016, 0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036, 0xE79C, 0x9035, 0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F, 0xE7A0, 0x9050, 0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E, 0xE7A4, 0x9049, 0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058, 0xE7A8, 0x905E, 0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076, 0xE7AC, 0x96A8, 0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D, 0xE7B0, 0x9081, 0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089, 0xE7B4, 0x908F, 0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1, 0xE7B8, 0x90B5, 0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248, 0xE7BC, 0x90DB, 0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119, 0xE7C0, 0x9132, 0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156, 0xE7C4, 0x9158, 0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169, 0xE7C8, 0x9173, 0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189, 0xE7CC, 0x9182, 0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF, 0xE7D0, 0x91AA, 0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA, 0xE7D4, 0x91C0, 0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB, 0xE7D8, 0x91D0, 0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1, 0xE7DC, 0x91DB, 0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6, 0xE7E0, 0x921E, 0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C, 0xE7E4, 0x9215, 0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257, 0xE7E8, 0x9245, 0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248, 0xE7EC, 0x9295, 0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250, 0xE7F0, 0x929C, 0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B, 0xE7F4, 0x925A, 0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7, 0xE7F8, 0x92E9, 0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344, 0xE7FC, 0x932E, 0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A, 0xE843, 0x9323, 0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B, 0xE847, 0x935C, 0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E, 0xE84B, 0x9356, 0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD, 0xE84F, 0x9394, 0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7, 0xE853, 0x93E8, 0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3, 0xE857, 0x93DD, 0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4, 0xE85B, 0x941A, 0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403, 0xE85F, 0x9407, 0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B, 0xE863, 0x9435, 0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441, 0xE867, 0x9452, 0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460, 0xE86B, 0x9462, 0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229, 0xE86F, 0x9470, 0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D, 0xE873, 0x945A, 0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481, 0xE877, 0x947F, 0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A, 0xE87B, 0x9594, 0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599, 0xE880, 0x95A0, 0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD, 0xE884, 0x95BC, 0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE, 0xE888, 0x95CA, 0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD, 0xE88C, 0x95CC, 0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6, 0xE890, 0x95DC, 0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2, 0xE894, 0x9621, 0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F, 0xE898, 0x9642, 0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B, 0xE89C, 0x9677, 0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D, 0xE8A0, 0x965F, 0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C, 0xE8A4, 0x968D, 0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697, 0xE8A8, 0x96AA, 0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2, 0xE8AC, 0x96B0, 0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8, 0xE8B0, 0x96B9, 0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9, 0xE8B4, 0x96CD, 0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D, 0xE8B8, 0x96D5, 0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706, 0xE8BC, 0x9708, 0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711, 0xE8C0, 0x970F, 0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724, 0xE8C4, 0x972A, 0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D, 0xE8C8, 0x973E, 0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748, 0xE8CC, 0x9742, 0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760, 0xE8D0, 0x9764, 0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2, 0xE8D4, 0x976B, 0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785, 0xE8D8, 0x977C, 0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786, 0xE8DC, 0x978B, 0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C, 0xE8E0, 0x97A8, 0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3, 0xE8E4, 0x97B4, 0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8, 0xE8E8, 0x97CB, 0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F, 0xE8EC, 0x97F2, 0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5, 0xE8F0, 0x980F, 0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824, 0xE8F4, 0x9821, 0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846, 0xE8F8, 0x984F, 0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F, 0xE8FC, 0x9870, 0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873, 0xE943, 0x98AA, 0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6, 0xE947, 0x98C4, 0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9, 0xE94B, 0x98EB, 0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912, 0xE94F, 0x9914, 0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D, 0xE953, 0x991E, 0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C, 0xE957, 0x992E, 0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942, 0xE95B, 0x9949, 0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B, 0xE95F, 0x9951, 0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955, 0xE963, 0x9997, 0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD, 0xE967, 0x99AE, 0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB, 0xE96B, 0x99DD, 0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED, 0xE96F, 0x99EE, 0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB, 0xE973, 0x99F8, 0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05, 0xE977, 0x99E2, 0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37, 0xE97B, 0x9A45, 0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43, 0xE980, 0x9A3E, 0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B, 0xE984, 0x9A57, 0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65, 0xE988, 0x9A64, 0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A, 0xE98C, 0x9AAD, 0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0, 0xE990, 0x9ACF, 0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4, 0xE994, 0x9ADE, 0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3, 0xE998, 0x9AE6, 0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE, 0xE99C, 0x9AF4, 0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB, 0xE9A0, 0x9B06, 0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F, 0xE9A4, 0x9B22, 0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27, 0xE9A8, 0x9B28, 0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E, 0xE9AC, 0x9B2F, 0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43, 0xE9B0, 0x9B4F, 0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51, 0xE9B4, 0x9B58, 0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83, 0xE9B8, 0x9B91, 0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F, 0xE9BC, 0x9BA0, 0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0, 0xE9C0, 0x9BCA, 0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF, 0xE9C4, 0x9BD1, 0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2, 0xE9C8, 0x9BE4, 0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A, 0xE9CC, 0x9BF2, 0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15, 0xE9D0, 0x9C14, 0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C, 0xE9D4, 0x9C06, 0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A, 0xE9D8, 0x9C04, 0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25, 0xE9DC, 0x9C24, 0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47, 0xE9E0, 0x9C32, 0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A, 0xE9E4, 0x9C60, 0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78, 0xE9E8, 0x9CE7, 0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09, 0xE9EC, 0x9D08, 0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06, 0xE9F0, 0x9D2A, 0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23, 0xE9F4, 0x9D1F, 0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12, 0xE9F8, 0x9D41, 0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46, 0xE9FC, 0x9D48, 0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64, 0xEA43, 0x9D51, 0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72, 0xEA47, 0x9D89, 0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F, 0xEA4B, 0x9D7A, 0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9, 0xEA4F, 0x9DB2, 0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB, 0xEA53, 0x9DB8, 0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF, 0xEA57, 0x9DC2, 0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8, 0xEA5B, 0x9DE6, 0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD, 0xEA5F, 0x9E1A, 0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75, 0xEA63, 0x9E79, 0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88, 0xEA67, 0x9E8B, 0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95, 0xEA6B, 0x9E91, 0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9, 0xEA6F, 0x9EB8, 0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761, 0xEA73, 0x9ECC, 0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0, 0xEA77, 0x9ED4, 0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD, 0xEA7B, 0x9EE0, 0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF, 0xEA80, 0x9EF4, 0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9, 0xEA84, 0x9EFB, 0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07, 0xEA88, 0x9F08, 0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21, 0xEA8C, 0x9F2C, 0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52, 0xEA90, 0x9F54, 0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60, 0xEA94, 0x9F61, 0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C, 0xEA98, 0x9F6A, 0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76, 0xEA9C, 0x9F95, 0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F, 0xEAA0, 0x69C7, 0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC, 0xEAA4, 0x7199, 0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172, 0xFA43, 0x2173, 0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176, 0xFA47, 0x2177, 0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4, 0xFA56, 0xFF07, 0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C, 0xFA5E, 0x9348, 0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9, 0xFA62, 0x70BB, 0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9, 0xFA66, 0x66FB, 0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1, 0xFA6A, 0x4EFC, 0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39, 0xFA6E, 0x4F56, 0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A, 0xFA72, 0x4F94, 0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022, 0xFA76, 0x4FFF, 0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070, 0xFA7A, 0x5042, 0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8, 0xFA7E, 0x514A, 0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE, 0xFA83, 0x51EC, 0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6, 0xFA87, 0x52C0, 0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307, 0xFA8B, 0x5324, 0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2, 0xFA8F, 0x53DD, 0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A, 0xFA93, 0x54A9, 0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759, 0xFA97, 0x5765, 0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7, 0xFA9B, 0xFA0F, 0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2, 0xFA9F, 0x590B, 0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D, 0xFAA3, 0x5963, 0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56, 0xFAA7, 0x5BC0, 0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC, 0xFAAB, 0x5C1E, 0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5, 0xFAAF, 0x5D27, 0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42, 0xFAB3, 0x5D6D, 0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0, 0xFAB7, 0x5F21, 0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7, 0xFABB, 0x5FDE, 0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A, 0xFABF, 0x60DE, 0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2, 0xFAC3, 0x6111, 0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198, 0xFAC7, 0x6213, 0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460, 0xFACB, 0x649D, 0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600, 0xFACF, 0x6615, 0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E, 0xFAD3, 0x661E, 0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657, 0xFAD7, 0x6659, 0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699, 0xFADB, 0x66A0, 0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA, 0xFADF, 0x670E, 0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB, 0xFAE3, 0x6852, 0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844, 0xFAE7, 0x68CF, 0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14, 0xFAEB, 0x6998, 0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B, 0xFAEF, 0x6A46, 0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2, 0xFAF3, 0x6AE4, 0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C, 0xFAF7, 0x6C86, 0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04, 0xFAFB, 0x6D87, 0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC, 0xFB42, 0x6DCF, 0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC, 0xFB46, 0x6E39, 0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C, 0xFB4A, 0x6EBF, 0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5, 0xFB4E, 0x7005, 0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085, 0xFB52, 0x70AB, 0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C, 0xFB56, 0x7146, 0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1, 0xFB5A, 0x71FE, 0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324, 0xFB5E, 0xFA16, 0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9, 0xFB62, 0x73D6, 0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407, 0xFB66, 0x73F5, 0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429, 0xFB6A, 0x742E, 0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F, 0xFB6E, 0x7501, 0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C, 0xFB72, 0x769E, 0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17, 0xFB76, 0x7746, 0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E, 0xFB7A, 0x7864, 0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18, 0xFB7E, 0xFA19, 0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B, 0xFB83, 0x799B, 0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C, 0xFB87, 0x7AEB, 0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48, 0xFB8B, 0x7D5C, 0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6, 0xFB8F, 0x7E52, 0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E, 0xFB93, 0x8301, 0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7, 0xFB97, 0x83F6, 0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553, 0xFB9B, 0x8559, 0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0, 0xFB9F, 0xFA20, 0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5, 0xFBA3, 0x8A12, 0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7, 0xFBA7, 0x8ABE, 0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6, 0xFBAB, 0x8B53, 0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4, 0xFBAF, 0x8D12, 0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF, 0xFBB3, 0xFA24, 0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE, 0xFBB7, 0xFA26, 0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA, 0xFBBB, 0x91D7, 0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE, 0xFBBF, 0x91E4, 0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210, 0xFBC3, 0x920A, 0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C, 0xFBC7, 0x924E, 0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239, 0xFBCB, 0x9267, 0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278, 0xFBCF, 0x92E7, 0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0, 0xFBD3, 0xFA27, 0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3, 0xFBD7, 0x9325, 0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28, 0xFBDB, 0x931E, 0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302, 0xFBDF, 0x9370, 0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6, 0xFBE3, 0x93DE, 0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445, 0xFBE7, 0x9448, 0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29, 0xFBEB, 0x969D, 0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B, 0xFBEF, 0x9743, 0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751, 0xFBF3, 0x9755, 0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A, 0xFBF7, 0xFA2B, 0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E, 0xFBFB, 0x9A4E, 0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75, 0xFC42, 0x9B72, 0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB, 0xFC46, 0x9C00, 0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D, 0xFC4A, 0x9E19, 0xFC4B, 0x9ED1, 0, 0 }; #endif #if FF_CODE_PAGE == 936 || FF_CODE_PAGE == 0 /* Simplified Chinese */ static const WCHAR uni2oem936[] = { /* Unicode --> GBK pairs */ 0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3, 0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4, 0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA, 0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE, 0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9, 0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9, 0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1, 0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3, 0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8, 0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5, 0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1, 0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5, 0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9, 0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD, 0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1, 0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5, 0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1, 0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5, 0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9, 0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD, 0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1, 0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5, 0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7, 0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4, 0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9, 0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD, 0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1, 0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5, 0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9, 0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD, 0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1, 0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4, 0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9, 0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD, 0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1, 0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5, 0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9, 0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED, 0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1, 0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA, 0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD, 0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846, 0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847, 0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1, 0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5, 0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9, 0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1, 0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5, 0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9, 0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA, 0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B, 0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6, 0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE, 0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE, 0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8, 0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF, 0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6, 0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4, 0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852, 0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1, 0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9, 0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD, 0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1, 0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7, 0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB, 0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF, 0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3, 0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7, 0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3, 0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7, 0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB, 0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF, 0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3, 0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6, 0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA, 0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE, 0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2, 0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6, 0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA, 0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE, 0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2, 0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6, 0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA, 0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE, 0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2, 0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6, 0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA, 0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE, 0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2, 0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6, 0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA, 0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE, 0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856, 0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A, 0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E, 0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862, 0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866, 0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A, 0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E, 0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872, 0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876, 0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A, 0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E, 0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883, 0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887, 0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6, 0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B, 0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0, 0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E, 0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE, 0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1, 0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9, 0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5, 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF, 0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895, 0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943, 0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947, 0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3, 0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7, 0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB, 0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF, 0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3, 0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7, 0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB, 0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF, 0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3, 0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7, 0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB, 0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF, 0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3, 0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7, 0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB, 0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF, 0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3, 0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7, 0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB, 0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF, 0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3, 0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967, 0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4, 0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8, 0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC, 0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0, 0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4, 0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8, 0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC, 0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0, 0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4, 0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8, 0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC, 0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0, 0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4, 0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8, 0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC, 0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0, 0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4, 0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8, 0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC, 0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0, 0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4, 0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963, 0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7, 0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB, 0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF, 0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3, 0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7, 0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB, 0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF, 0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3, 0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7, 0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6, 0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA, 0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE, 0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B, 0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F, 0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953, 0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140, 0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143, 0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF, 0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB, 0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145, 0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0, 0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5, 0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9, 0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA, 0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B, 0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6, 0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D, 0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE, 0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC, 0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA, 0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9, 0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156, 0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158, 0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159, 0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5, 0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9, 0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4, 0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D, 0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2, 0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F, 0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9, 0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165, 0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169, 0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B, 0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E, 0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172, 0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC, 0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179, 0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB, 0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E, 0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA, 0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5, 0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181, 0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7, 0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186, 0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA, 0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0, 0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188, 0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1, 0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7, 0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D, 0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB, 0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193, 0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC, 0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD, 0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1, 0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3, 0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198, 0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB, 0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199, 0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0, 0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D, 0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E, 0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7, 0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2, 0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9, 0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE, 0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8, 0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA, 0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC, 0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0, 0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1, 0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF, 0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5, 0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9, 0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1, 0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1, 0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3, 0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7, 0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1, 0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2, 0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3, 0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6, 0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5, 0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9, 0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD, 0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB, 0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3, 0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD, 0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6, 0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8, 0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD, 0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA, 0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA, 0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB, 0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD, 0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0, 0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2, 0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5, 0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7, 0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB, 0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB, 0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED, 0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF, 0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1, 0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3, 0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6, 0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9, 0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB, 0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE, 0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC, 0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD, 0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA, 0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245, 0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248, 0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C, 0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250, 0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253, 0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254, 0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1, 0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE, 0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B, 0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F, 0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5, 0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1, 0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263, 0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1, 0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3, 0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE, 0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A, 0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D, 0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3, 0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2, 0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276, 0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A, 0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E, 0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281, 0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9, 0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286, 0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0, 0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A, 0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C, 0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB, 0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF, 0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0, 0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294, 0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298, 0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE, 0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3, 0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1, 0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4, 0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6, 0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB, 0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB, 0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE, 0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6, 0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4, 0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8, 0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB, 0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF, 0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2, 0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6, 0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC, 0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC, 0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7, 0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0, 0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3, 0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6, 0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9, 0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD, 0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1, 0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5, 0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9, 0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED, 0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF, 0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0, 0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3, 0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1, 0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA, 0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1, 0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341, 0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345, 0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349, 0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D, 0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351, 0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354, 0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2, 0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5, 0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E, 0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362, 0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6, 0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368, 0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7, 0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D, 0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F, 0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373, 0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376, 0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A, 0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3, 0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381, 0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384, 0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5, 0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B, 0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F, 0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393, 0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396, 0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A, 0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E, 0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2, 0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6, 0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA, 0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE, 0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2, 0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3, 0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7, 0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5, 0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7, 0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA, 0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0, 0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3, 0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1, 0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4, 0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7, 0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA, 0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2, 0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC, 0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4, 0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD, 0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE, 0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7, 0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2, 0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4, 0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6, 0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0, 0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2, 0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD, 0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF, 0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3, 0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3, 0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7, 0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9, 0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5, 0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1, 0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED, 0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE, 0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1, 0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC, 0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5, 0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7, 0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9, 0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD, 0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442, 0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444, 0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446, 0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449, 0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D, 0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F, 0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451, 0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7, 0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6, 0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454, 0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6, 0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6, 0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF, 0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8, 0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE, 0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE, 0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5, 0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460, 0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463, 0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466, 0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468, 0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE, 0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C, 0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6, 0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC, 0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470, 0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1, 0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473, 0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7, 0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478, 0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A, 0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA, 0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481, 0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE, 0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486, 0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489, 0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4, 0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E, 0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE, 0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494, 0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498, 0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B, 0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3, 0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0, 0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3, 0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7, 0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA, 0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD, 0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1, 0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC, 0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD, 0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5, 0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC, 0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7, 0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2, 0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC, 0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0, 0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0, 0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6, 0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9, 0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB, 0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE, 0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5, 0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3, 0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6, 0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA, 0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD, 0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0, 0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4, 0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8, 0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB, 0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF, 0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7, 0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4, 0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6, 0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2, 0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB, 0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE, 0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541, 0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF, 0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE, 0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547, 0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549, 0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0, 0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB, 0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1, 0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555, 0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559, 0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8, 0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2, 0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F, 0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561, 0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB, 0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA, 0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4, 0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4, 0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9, 0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5, 0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC, 0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4, 0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D, 0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4, 0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570, 0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571, 0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1, 0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576, 0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7, 0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA, 0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C, 0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D, 0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582, 0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585, 0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1, 0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A, 0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1, 0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3, 0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F, 0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB, 0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596, 0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC, 0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D, 0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0, 0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE, 0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5, 0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0, 0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7, 0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA, 0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1, 0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD, 0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0, 0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2, 0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED, 0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB, 0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3, 0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7, 0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6, 0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5, 0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6, 0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9, 0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA, 0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5, 0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3, 0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8, 0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9, 0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0, 0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC, 0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2, 0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1, 0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5, 0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1, 0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5, 0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8, 0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA, 0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1, 0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE, 0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4, 0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6, 0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5, 0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC, 0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF, 0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8, 0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA, 0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8, 0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF, 0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2, 0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6, 0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA, 0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE, 0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB, 0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC, 0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6, 0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8, 0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4, 0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC, 0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4, 0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7, 0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB, 0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB, 0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640, 0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7, 0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4, 0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642, 0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644, 0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646, 0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649, 0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B, 0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3, 0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF, 0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E, 0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5, 0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5, 0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650, 0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1, 0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8, 0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655, 0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6, 0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4, 0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8, 0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC, 0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F, 0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8, 0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664, 0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666, 0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4, 0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B, 0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F, 0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670, 0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673, 0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677, 0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A, 0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF, 0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E, 0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4, 0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB, 0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684, 0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687, 0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A, 0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9, 0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E, 0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC, 0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1, 0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695, 0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698, 0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2, 0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E, 0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1, 0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4, 0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2, 0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE, 0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6, 0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC, 0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4, 0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0, 0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1, 0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9, 0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4, 0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0, 0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7, 0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9, 0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC, 0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE, 0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0, 0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3, 0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7, 0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA, 0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE, 0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1, 0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3, 0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5, 0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7, 0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA, 0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC, 0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF, 0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1, 0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA, 0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2, 0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8, 0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA, 0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC, 0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2, 0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA, 0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0, 0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7, 0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4, 0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7, 0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5, 0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB, 0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740, 0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742, 0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2, 0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747, 0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B, 0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E, 0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF, 0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753, 0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755, 0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758, 0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A, 0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0, 0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB, 0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761, 0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764, 0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767, 0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B, 0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F, 0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD, 0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774, 0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777, 0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778, 0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B, 0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE, 0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782, 0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB, 0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785, 0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788, 0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1, 0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F, 0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791, 0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795, 0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3, 0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B, 0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF, 0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1, 0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4, 0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8, 0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC, 0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0, 0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3, 0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7, 0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB, 0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE, 0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2, 0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5, 0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8, 0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC, 0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0, 0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2, 0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7, 0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB, 0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE, 0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4, 0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8, 0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5, 0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4, 0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8, 0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA, 0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC, 0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE, 0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC, 0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC, 0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5, 0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2, 0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5, 0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB, 0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840, 0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844, 0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848, 0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B, 0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E, 0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851, 0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9, 0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC, 0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855, 0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858, 0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1, 0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8, 0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0, 0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862, 0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB, 0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2, 0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866, 0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A, 0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1, 0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB, 0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D, 0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9, 0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA, 0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872, 0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875, 0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9, 0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A, 0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C, 0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9, 0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4, 0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884, 0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886, 0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD, 0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C, 0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890, 0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893, 0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8, 0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1, 0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897, 0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5, 0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE, 0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E, 0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1, 0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5, 0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1, 0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB, 0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF, 0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7, 0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8, 0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5, 0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6, 0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9, 0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB, 0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE, 0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2, 0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5, 0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8, 0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB, 0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9, 0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF, 0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3, 0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1, 0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7, 0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9, 0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC, 0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF, 0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2, 0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6, 0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7, 0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA, 0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0, 0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1, 0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4, 0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7, 0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB, 0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940, 0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944, 0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947, 0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B, 0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D, 0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950, 0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953, 0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956, 0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB, 0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D, 0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960, 0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964, 0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966, 0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A, 0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E, 0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972, 0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3, 0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977, 0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979, 0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C, 0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981, 0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA, 0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987, 0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE, 0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6, 0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F, 0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993, 0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995, 0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999, 0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D, 0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1, 0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5, 0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8, 0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB, 0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE, 0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2, 0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6, 0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9, 0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC, 0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0, 0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4, 0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8, 0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB, 0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF, 0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3, 0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3, 0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8, 0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8, 0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC, 0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA, 0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2, 0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5, 0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8, 0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB, 0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2, 0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0, 0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1, 0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4, 0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6, 0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB, 0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB, 0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA, 0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD, 0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1, 0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41, 0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC, 0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46, 0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47, 0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC, 0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B, 0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1, 0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9, 0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51, 0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD, 0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56, 0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A, 0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E, 0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62, 0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC, 0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65, 0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68, 0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7, 0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1, 0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1, 0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F, 0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA, 0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD, 0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76, 0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4, 0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D, 0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E, 0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD, 0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD, 0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7, 0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88, 0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B, 0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA, 0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91, 0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7, 0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2, 0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A, 0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6, 0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D, 0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6, 0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0, 0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4, 0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6, 0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9, 0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC, 0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0, 0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4, 0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7, 0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA, 0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC, 0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC, 0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD, 0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0, 0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3, 0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6, 0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9, 0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC, 0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE, 0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0, 0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3, 0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7, 0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4, 0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2, 0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF, 0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2, 0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5, 0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5, 0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB, 0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE, 0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2, 0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5, 0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9, 0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC, 0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE, 0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44, 0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7, 0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A, 0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E, 0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4, 0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4, 0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55, 0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58, 0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C, 0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60, 0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64, 0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD, 0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B, 0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4, 0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71, 0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75, 0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79, 0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1, 0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81, 0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7, 0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86, 0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89, 0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5, 0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9, 0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92, 0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95, 0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98, 0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8, 0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE, 0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0, 0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3, 0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5, 0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF, 0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA, 0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD, 0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0, 0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4, 0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8, 0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC, 0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0, 0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4, 0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7, 0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB, 0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF, 0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4, 0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5, 0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9, 0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD, 0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1, 0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5, 0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9, 0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5, 0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF, 0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2, 0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6, 0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9, 0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD, 0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42, 0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46, 0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48, 0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49, 0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA, 0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A, 0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF, 0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7, 0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF, 0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51, 0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53, 0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55, 0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6, 0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B, 0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D, 0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E, 0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F, 0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61, 0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64, 0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66, 0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8, 0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5, 0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD, 0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2, 0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC, 0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D, 0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70, 0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2, 0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72, 0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6, 0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5, 0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC, 0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A, 0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D, 0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE, 0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83, 0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87, 0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF, 0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B, 0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D, 0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90, 0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC, 0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96, 0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A, 0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2, 0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D, 0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F, 0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB, 0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0, 0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7, 0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9, 0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2, 0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0, 0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE, 0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC, 0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3, 0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6, 0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9, 0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC, 0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF, 0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF, 0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2, 0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3, 0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3, 0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC, 0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA, 0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7, 0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA, 0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD, 0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4, 0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2, 0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0, 0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7, 0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8, 0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC, 0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0, 0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8, 0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6, 0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1, 0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB, 0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE, 0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0, 0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2, 0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB, 0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0, 0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6, 0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3, 0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC, 0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40, 0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41, 0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44, 0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46, 0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48, 0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B, 0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D, 0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50, 0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54, 0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57, 0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC, 0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E, 0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61, 0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65, 0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68, 0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD, 0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8, 0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E, 0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71, 0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75, 0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79, 0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C, 0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0, 0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7, 0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85, 0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9, 0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C, 0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2, 0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92, 0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6, 0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98, 0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3, 0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C, 0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4, 0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2, 0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5, 0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9, 0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA, 0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF, 0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3, 0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3, 0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7, 0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB, 0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF, 0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2, 0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4, 0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8, 0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC, 0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF, 0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1, 0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4, 0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7, 0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB, 0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF, 0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6, 0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6, 0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA, 0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE, 0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2, 0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6, 0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9, 0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC, 0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41, 0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45, 0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49, 0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D, 0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51, 0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55, 0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58, 0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C, 0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60, 0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63, 0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67, 0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A, 0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E, 0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72, 0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76, 0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD, 0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2, 0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3, 0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C, 0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE, 0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1, 0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82, 0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85, 0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED, 0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0, 0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB, 0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D, 0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90, 0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91, 0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB, 0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3, 0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94, 0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98, 0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8, 0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E, 0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF, 0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3, 0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7, 0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9, 0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA, 0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD, 0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF, 0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3, 0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6, 0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA, 0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC, 0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0, 0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5, 0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1, 0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8, 0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC, 0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0, 0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9, 0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2, 0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB, 0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7, 0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9, 0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC, 0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2, 0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0, 0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1, 0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2, 0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD, 0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3, 0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6, 0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8, 0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB, 0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE, 0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2, 0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC, 0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4, 0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7, 0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB, 0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40, 0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8, 0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46, 0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA, 0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE, 0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E, 0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51, 0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55, 0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59, 0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE, 0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F, 0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63, 0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3, 0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8, 0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3, 0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC, 0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C, 0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7, 0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71, 0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73, 0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75, 0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77, 0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A, 0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C, 0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2, 0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2, 0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83, 0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85, 0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89, 0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF, 0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E, 0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91, 0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95, 0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99, 0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D, 0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9, 0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8, 0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2, 0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5, 0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE, 0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5, 0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB, 0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD, 0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF, 0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2, 0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4, 0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6, 0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE, 0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9, 0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2, 0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB, 0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD, 0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0, 0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1, 0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4, 0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7, 0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB, 0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD, 0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2, 0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3, 0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6, 0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9, 0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB, 0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF, 0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4, 0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2, 0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4, 0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF, 0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2, 0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8, 0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB, 0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED, 0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0, 0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC, 0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5, 0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6, 0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9, 0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC, 0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9, 0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB, 0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB, 0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7, 0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5, 0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD, 0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0, 0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049, 0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A, 0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C, 0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1, 0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6, 0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051, 0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054, 0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057, 0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B, 0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D, 0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE, 0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061, 0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065, 0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067, 0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3, 0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C, 0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3, 0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071, 0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6, 0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076, 0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1, 0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077, 0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079, 0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1, 0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD, 0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D, 0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081, 0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083, 0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086, 0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088, 0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8, 0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3, 0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4, 0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092, 0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094, 0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3, 0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099, 0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A, 0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF, 0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E, 0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1, 0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3, 0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7, 0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0, 0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA, 0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF, 0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2, 0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5, 0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1, 0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9, 0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB, 0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB, 0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF, 0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC, 0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1, 0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC, 0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA, 0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8, 0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA, 0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9, 0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF, 0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9, 0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4, 0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7, 0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE, 0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE, 0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0, 0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4, 0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4, 0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7, 0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB, 0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF, 0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3, 0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7, 0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA, 0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE, 0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB, 0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7, 0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146, 0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149, 0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D, 0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150, 0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD, 0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157, 0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159, 0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D, 0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160, 0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163, 0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166, 0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A, 0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E, 0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172, 0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176, 0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7, 0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C, 0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180, 0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184, 0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187, 0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B, 0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F, 0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190, 0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193, 0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197, 0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B, 0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E, 0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6, 0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE, 0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8, 0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3, 0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD, 0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1, 0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2, 0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6, 0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA, 0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE, 0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3, 0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5, 0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9, 0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD, 0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0, 0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4, 0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8, 0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB, 0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0, 0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC, 0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6, 0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4, 0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2, 0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD, 0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6, 0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB, 0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9, 0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8, 0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE, 0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2, 0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4, 0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7, 0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5, 0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA, 0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD, 0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE, 0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA, 0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7, 0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243, 0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246, 0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249, 0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D, 0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4, 0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1, 0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7, 0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252, 0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6, 0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257, 0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2, 0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B, 0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E, 0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1, 0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264, 0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3, 0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6, 0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7, 0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B, 0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0, 0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D, 0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270, 0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272, 0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275, 0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278, 0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B, 0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C, 0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7, 0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0, 0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4, 0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0, 0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC, 0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF, 0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5, 0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286, 0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3, 0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9, 0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A, 0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7, 0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D, 0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9, 0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291, 0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0, 0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2, 0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297, 0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298, 0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6, 0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E, 0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA, 0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF, 0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2, 0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8, 0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6, 0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2, 0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB, 0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD, 0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1, 0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6, 0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6, 0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6, 0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6, 0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD, 0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3, 0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF, 0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2, 0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6, 0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC, 0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB, 0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD, 0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF, 0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD, 0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4, 0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7, 0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0, 0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC, 0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0, 0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2, 0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5, 0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1, 0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5, 0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4, 0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB, 0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF, 0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD, 0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3, 0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB, 0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7, 0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7, 0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9, 0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4, 0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2, 0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341, 0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1, 0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346, 0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF, 0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5, 0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE, 0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350, 0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE, 0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355, 0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358, 0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE, 0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D, 0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9, 0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE, 0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365, 0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368, 0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7, 0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B, 0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F, 0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371, 0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373, 0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375, 0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379, 0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3, 0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C, 0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9, 0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2, 0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385, 0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389, 0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C, 0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF, 0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392, 0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394, 0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA, 0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF, 0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A, 0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0, 0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0, 0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3, 0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB, 0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA, 0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE, 0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0, 0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3, 0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7, 0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB, 0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1, 0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0, 0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC, 0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5, 0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8, 0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC, 0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6, 0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE, 0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3, 0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2, 0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA, 0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD, 0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0, 0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9, 0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4, 0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7, 0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5, 0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB, 0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE, 0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0, 0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4, 0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6, 0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC, 0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC, 0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE, 0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3, 0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA, 0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1, 0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B, 0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F, 0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453, 0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457, 0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B, 0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F, 0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462, 0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466, 0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469, 0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D, 0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC, 0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474, 0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477, 0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B, 0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480, 0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483, 0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487, 0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD, 0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C, 0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5, 0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F, 0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5, 0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494, 0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497, 0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499, 0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C, 0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E, 0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD, 0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3, 0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8, 0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2, 0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8, 0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD, 0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF, 0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3, 0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4, 0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7, 0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB, 0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF, 0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3, 0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6, 0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8, 0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA, 0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD, 0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF, 0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1, 0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3, 0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5, 0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7, 0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9, 0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB, 0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF, 0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2, 0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4, 0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7, 0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7, 0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB, 0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB, 0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC, 0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD, 0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4, 0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8, 0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8, 0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9, 0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD, 0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8, 0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540, 0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1, 0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA, 0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549, 0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA, 0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5, 0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB, 0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7, 0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555, 0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556, 0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559, 0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C, 0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E, 0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561, 0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563, 0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566, 0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568, 0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6, 0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D, 0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4, 0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572, 0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575, 0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579, 0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B, 0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9, 0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD, 0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED, 0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584, 0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586, 0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE, 0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B, 0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5, 0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590, 0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7, 0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7, 0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0, 0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD, 0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D, 0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0, 0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3, 0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6, 0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF, 0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC, 0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF, 0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3, 0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7, 0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9, 0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA, 0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0, 0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3, 0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6, 0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5, 0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD, 0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1, 0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5, 0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9, 0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD, 0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1, 0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4, 0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5, 0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9, 0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8, 0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF, 0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3, 0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA, 0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7, 0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9, 0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8, 0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD, 0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642, 0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3, 0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645, 0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648, 0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A, 0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D, 0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F, 0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652, 0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC, 0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4, 0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658, 0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A, 0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C, 0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA, 0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662, 0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3, 0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB, 0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668, 0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE, 0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B, 0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8, 0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671, 0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD, 0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674, 0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677, 0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2, 0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B, 0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD, 0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E, 0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682, 0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9, 0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686, 0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689, 0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B, 0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E, 0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691, 0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694, 0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6, 0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8, 0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0, 0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B, 0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9, 0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E, 0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0, 0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC, 0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3, 0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7, 0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA, 0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC, 0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0, 0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4, 0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2, 0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6, 0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6, 0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5, 0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC, 0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD, 0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0, 0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3, 0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4, 0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6, 0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA, 0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD, 0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF, 0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2, 0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0, 0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD, 0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5, 0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC, 0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA, 0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD, 0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0, 0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4, 0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA, 0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA, 0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0, 0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0, 0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1, 0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF, 0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0, 0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2, 0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0, 0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4, 0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8, 0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9, 0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD, 0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742, 0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5, 0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB, 0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744, 0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747, 0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B, 0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0, 0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750, 0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754, 0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757, 0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0, 0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C, 0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760, 0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763, 0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766, 0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769, 0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D, 0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2, 0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE, 0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775, 0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778, 0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A, 0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C, 0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781, 0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785, 0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9, 0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B, 0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E, 0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790, 0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4, 0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796, 0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF, 0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C, 0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F, 0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2, 0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6, 0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD, 0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB, 0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE, 0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7, 0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3, 0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6, 0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9, 0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD, 0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5, 0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7, 0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4, 0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8, 0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC, 0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE, 0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1, 0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5, 0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8, 0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB, 0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE, 0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1, 0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4, 0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB, 0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA, 0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE, 0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2, 0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6, 0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9, 0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE, 0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3, 0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841, 0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8, 0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847, 0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA, 0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C, 0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850, 0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851, 0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854, 0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5, 0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC, 0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859, 0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C, 0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860, 0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862, 0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865, 0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867, 0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B, 0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F, 0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871, 0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873, 0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876, 0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879, 0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C, 0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880, 0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883, 0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887, 0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3, 0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6, 0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F, 0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892, 0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896, 0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899, 0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B, 0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F, 0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3, 0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6, 0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE, 0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD, 0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1, 0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4, 0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7, 0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB, 0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE, 0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2, 0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6, 0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA, 0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC, 0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0, 0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2, 0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6, 0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1, 0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC, 0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE, 0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1, 0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5, 0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0, 0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB, 0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE, 0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1, 0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5, 0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8, 0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC, 0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE, 0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942, 0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945, 0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948, 0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C, 0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950, 0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953, 0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957, 0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A, 0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D, 0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960, 0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963, 0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967, 0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5, 0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C, 0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970, 0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973, 0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977, 0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A, 0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E, 0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982, 0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984, 0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988, 0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C, 0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990, 0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994, 0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998, 0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C, 0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0, 0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4, 0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8, 0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC, 0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0, 0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4, 0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8, 0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC, 0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0, 0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4, 0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8, 0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC, 0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0, 0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4, 0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8, 0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC, 0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0, 0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4, 0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8, 0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC, 0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0, 0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4, 0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6, 0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7, 0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA, 0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE, 0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB, 0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46, 0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB, 0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE, 0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E, 0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7, 0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52, 0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55, 0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59, 0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D, 0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60, 0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64, 0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9, 0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4, 0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1, 0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D, 0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71, 0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75, 0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78, 0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A, 0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3, 0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9, 0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2, 0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81, 0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6, 0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3, 0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9, 0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C, 0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F, 0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93, 0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC, 0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A, 0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E, 0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F, 0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2, 0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6, 0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1, 0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA, 0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE, 0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0, 0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE, 0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1, 0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4, 0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7, 0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA, 0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE, 0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4, 0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4, 0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7, 0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9, 0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC, 0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF, 0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3, 0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB, 0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8, 0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB, 0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC, 0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA, 0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0, 0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0, 0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2, 0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4, 0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4, 0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA, 0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5, 0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9, 0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC, 0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF, 0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3, 0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0, 0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2, 0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8, 0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB, 0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD, 0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41, 0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF, 0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42, 0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45, 0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4, 0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A, 0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3, 0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB, 0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51, 0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA, 0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA, 0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC, 0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58, 0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B, 0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D, 0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F, 0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62, 0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65, 0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67, 0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9, 0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6, 0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA, 0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5, 0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E, 0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70, 0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4, 0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73, 0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75, 0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4, 0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A, 0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D, 0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7, 0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81, 0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2, 0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8, 0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86, 0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1, 0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA, 0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B, 0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4, 0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8, 0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE, 0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90, 0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93, 0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96, 0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9, 0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7, 0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E, 0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE, 0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4, 0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5, 0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8, 0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9, 0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC, 0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE, 0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0, 0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3, 0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9, 0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6, 0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC, 0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7, 0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3, 0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0, 0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC, 0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3, 0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7, 0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3, 0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6, 0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB, 0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1, 0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD, 0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0, 0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2, 0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5, 0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF, 0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB, 0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD, 0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1, 0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2, 0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3, 0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7, 0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5, 0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9, 0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3, 0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2, 0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC, 0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA, 0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1, 0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4, 0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8, 0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA, 0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD, 0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE, 0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41, 0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44, 0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7, 0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49, 0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1, 0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D, 0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6, 0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53, 0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4, 0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57, 0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A, 0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C, 0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E, 0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62, 0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65, 0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8, 0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2, 0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B, 0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9, 0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE, 0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72, 0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74, 0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75, 0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78, 0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A, 0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6, 0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80, 0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC, 0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86, 0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A, 0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C, 0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90, 0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF, 0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96, 0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE, 0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A, 0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D, 0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0, 0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4, 0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8, 0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE, 0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE, 0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2, 0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6, 0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5, 0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC, 0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3, 0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0, 0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4, 0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6, 0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA, 0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD, 0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0, 0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7, 0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5, 0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA, 0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB, 0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1, 0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC, 0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7, 0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2, 0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8, 0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8, 0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB, 0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE, 0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0, 0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1, 0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6, 0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD, 0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE, 0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0, 0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9, 0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD, 0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42, 0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45, 0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48, 0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C, 0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF, 0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1, 0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55, 0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59, 0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C, 0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D, 0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61, 0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65, 0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68, 0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B, 0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4, 0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F, 0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71, 0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1, 0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77, 0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA, 0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E, 0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB, 0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85, 0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87, 0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B, 0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F, 0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92, 0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA, 0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA, 0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA, 0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E, 0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1, 0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB, 0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6, 0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD, 0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB, 0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF, 0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2, 0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4, 0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC, 0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9, 0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD, 0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1, 0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4, 0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7, 0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB, 0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE, 0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2, 0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6, 0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4, 0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB, 0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF, 0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5, 0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5, 0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8, 0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC, 0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4, 0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2, 0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6, 0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8, 0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB, 0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40, 0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44, 0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7, 0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A, 0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E, 0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52, 0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56, 0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A, 0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E, 0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62, 0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66, 0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69, 0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D, 0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB, 0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73, 0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77, 0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A, 0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E, 0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83, 0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87, 0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A, 0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D, 0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91, 0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95, 0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99, 0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D, 0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0, 0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3, 0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7, 0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB, 0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1, 0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2, 0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6, 0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA, 0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB, 0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD, 0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE, 0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2, 0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6, 0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6, 0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9, 0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6, 0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7, 0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4, 0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0, 0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5, 0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7, 0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB, 0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF, 0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3, 0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA, 0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5, 0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8, 0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9, 0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA, 0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3, 0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE, 0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8, 0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4, 0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8, 0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC, 0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE, 0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42, 0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45, 0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3, 0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48, 0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49, 0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C, 0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50, 0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52, 0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55, 0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59, 0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D, 0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8, 0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63, 0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66, 0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB, 0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9, 0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C, 0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70, 0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9, 0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77, 0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B, 0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C, 0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB, 0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84, 0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88, 0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C, 0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F, 0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3, 0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5, 0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98, 0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C, 0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0, 0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7, 0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6, 0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3, 0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA, 0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3, 0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2, 0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3, 0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5, 0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8, 0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC, 0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF, 0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC, 0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6, 0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9, 0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC, 0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE, 0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2, 0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4, 0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8, 0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB, 0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE, 0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2, 0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4, 0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7, 0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB, 0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF, 0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2, 0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6, 0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7, 0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD, 0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040, 0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044, 0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048, 0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B, 0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E, 0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051, 0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6, 0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058, 0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C, 0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F, 0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063, 0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067, 0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC, 0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E, 0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072, 0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076, 0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A, 0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E, 0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082, 0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086, 0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A, 0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6, 0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F, 0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091, 0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8, 0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094, 0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096, 0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099, 0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D, 0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F, 0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1, 0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA, 0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB, 0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA, 0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC, 0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE, 0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3, 0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2, 0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0, 0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC, 0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA, 0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE, 0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5, 0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0, 0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3, 0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF, 0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8, 0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB, 0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE, 0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2, 0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6, 0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9, 0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD, 0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1, 0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3, 0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5, 0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4, 0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8, 0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC, 0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1, 0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0, 0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3, 0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2, 0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4, 0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB, 0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD, 0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC, 0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43, 0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47, 0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49, 0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8, 0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8, 0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C, 0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE, 0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F, 0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52, 0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55, 0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5, 0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4, 0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F, 0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE, 0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63, 0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6, 0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9, 0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68, 0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED, 0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7, 0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E, 0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71, 0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72, 0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB, 0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78, 0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C, 0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81, 0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84, 0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1, 0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A, 0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D, 0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91, 0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94, 0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98, 0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C, 0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E, 0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40, 0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44, 0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48, 0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5, 0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F, 0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52, 0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54, 0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0, 0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59, 0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1, 0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60, 0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63, 0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3, 0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69, 0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C, 0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2, 0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1, 0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72, 0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4, 0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77, 0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6, 0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D, 0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA, 0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82, 0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83, 0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87, 0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A, 0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3, 0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90, 0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93, 0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95, 0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98, 0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5, 0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F, 0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42, 0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46, 0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A, 0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED, 0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0, 0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51, 0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53, 0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57, 0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2, 0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D, 0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1, 0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9, 0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7, 0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD, 0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69, 0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3, 0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D, 0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70, 0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73, 0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77, 0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B, 0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80, 0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84, 0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87, 0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7, 0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0, 0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C, 0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90, 0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94, 0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97, 0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A, 0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE, 0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0, 0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA, 0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44, 0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47, 0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A, 0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC, 0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F, 0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53, 0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57, 0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1, 0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D, 0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61, 0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62, 0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66, 0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A, 0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E, 0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7, 0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75, 0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79, 0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D, 0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82, 0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86, 0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6, 0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D, 0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91, 0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC, 0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0, 0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF, 0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A, 0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD, 0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0, 0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF, 0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44, 0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48, 0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B, 0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E, 0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52, 0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55, 0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57, 0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A, 0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5, 0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E, 0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61, 0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64, 0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66, 0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67, 0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7, 0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69, 0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE, 0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE, 0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F, 0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72, 0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75, 0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0, 0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79, 0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C, 0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE, 0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81, 0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85, 0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8, 0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC, 0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E, 0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4, 0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94, 0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96, 0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A, 0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D, 0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE, 0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42, 0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45, 0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA, 0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC, 0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE, 0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C, 0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D, 0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E, 0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52, 0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF, 0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3, 0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54, 0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56, 0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2, 0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8, 0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B, 0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC, 0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E, 0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7, 0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9, 0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65, 0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6, 0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1, 0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED, 0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE, 0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F, 0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71, 0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74, 0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77, 0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A, 0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B, 0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D, 0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA, 0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84, 0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87, 0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A, 0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B, 0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E, 0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3, 0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD, 0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1, 0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94, 0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97, 0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98, 0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B, 0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB, 0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F, 0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041, 0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045, 0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047, 0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B, 0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1, 0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051, 0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE, 0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057, 0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A, 0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E, 0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061, 0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064, 0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068, 0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B, 0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9, 0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED, 0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4, 0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073, 0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8, 0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078, 0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE, 0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D, 0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082, 0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086, 0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089, 0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D, 0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4, 0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4, 0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095, 0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099, 0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D, 0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB, 0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8, 0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6, 0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB, 0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0, 0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7, 0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148, 0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B, 0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E, 0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151, 0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155, 0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF, 0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4, 0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C, 0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E, 0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC, 0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163, 0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166, 0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167, 0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169, 0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D, 0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171, 0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2, 0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177, 0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3, 0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6, 0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D, 0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181, 0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184, 0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4, 0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7, 0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A, 0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C, 0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F, 0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192, 0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196, 0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198, 0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C, 0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD, 0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241, 0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1, 0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0, 0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247, 0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249, 0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D, 0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251, 0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254, 0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA, 0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258, 0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A, 0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E, 0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9, 0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7, 0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265, 0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269, 0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D, 0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB, 0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271, 0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9, 0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275, 0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278, 0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A, 0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E, 0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281, 0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284, 0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288, 0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C, 0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F, 0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293, 0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297, 0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A, 0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C, 0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8, 0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340, 0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342, 0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB, 0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346, 0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6, 0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B, 0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF, 0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0, 0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351, 0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354, 0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356, 0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8, 0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9, 0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2, 0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D, 0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360, 0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE, 0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363, 0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365, 0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368, 0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B, 0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2, 0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9, 0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F, 0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372, 0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375, 0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA, 0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8, 0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC, 0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E, 0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382, 0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386, 0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A, 0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2, 0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7, 0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391, 0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395, 0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398, 0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B, 0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F, 0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442, 0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444, 0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9, 0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448, 0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B, 0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5, 0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E, 0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450, 0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452, 0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455, 0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459, 0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA, 0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C, 0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F, 0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB, 0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465, 0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468, 0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA, 0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D, 0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470, 0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472, 0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475, 0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479, 0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D, 0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482, 0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485, 0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488, 0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1, 0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E, 0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7, 0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494, 0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497, 0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A, 0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E, 0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541, 0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545, 0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548, 0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C, 0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6, 0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553, 0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556, 0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A, 0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E, 0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562, 0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565, 0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE, 0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7, 0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B, 0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC, 0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570, 0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574, 0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578, 0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6, 0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1, 0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1, 0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2, 0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581, 0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583, 0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586, 0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589, 0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D, 0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7, 0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592, 0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594, 0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596, 0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9, 0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D, 0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0, 0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643, 0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA, 0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A, 0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E, 0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652, 0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655, 0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659, 0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D, 0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660, 0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE, 0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC, 0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665, 0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1, 0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A, 0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C, 0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB, 0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671, 0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674, 0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678, 0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B, 0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8, 0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E, 0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681, 0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683, 0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687, 0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A, 0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C, 0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC, 0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9, 0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694, 0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0, 0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699, 0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C, 0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9, 0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD, 0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743, 0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746, 0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A, 0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E, 0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752, 0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755, 0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757, 0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758, 0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B, 0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2, 0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762, 0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766, 0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769, 0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D, 0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770, 0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774, 0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778, 0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C, 0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781, 0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785, 0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788, 0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF, 0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5, 0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E, 0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F, 0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9, 0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793, 0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796, 0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF, 0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1, 0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C, 0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E, 0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0, 0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC, 0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844, 0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846, 0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A, 0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D, 0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851, 0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855, 0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858, 0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C, 0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860, 0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863, 0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867, 0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA, 0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D, 0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA, 0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872, 0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5, 0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877, 0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A, 0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D, 0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882, 0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3, 0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887, 0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A, 0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA, 0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9, 0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890, 0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892, 0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894, 0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897, 0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7, 0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C, 0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB, 0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE, 0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0, 0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942, 0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945, 0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3, 0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6, 0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D, 0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950, 0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952, 0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954, 0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2, 0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF, 0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9, 0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A, 0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1, 0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960, 0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964, 0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF, 0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2, 0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C, 0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E, 0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9, 0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973, 0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976, 0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A, 0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D, 0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981, 0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983, 0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986, 0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988, 0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE, 0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5, 0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC, 0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E, 0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991, 0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994, 0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997, 0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B, 0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E, 0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD, 0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43, 0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46, 0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49, 0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C, 0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5, 0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51, 0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54, 0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7, 0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8, 0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA, 0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F, 0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63, 0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66, 0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA, 0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C, 0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70, 0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73, 0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75, 0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78, 0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD, 0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80, 0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84, 0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87, 0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3, 0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2, 0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90, 0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94, 0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98, 0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B, 0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F, 0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0, 0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43, 0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47, 0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A, 0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E, 0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52, 0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56, 0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A, 0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E, 0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62, 0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66, 0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A, 0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E, 0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70, 0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74, 0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75, 0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79, 0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D, 0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81, 0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85, 0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3, 0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A, 0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C, 0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1, 0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2, 0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91, 0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0, 0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8, 0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3, 0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C, 0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F, 0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB, 0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42, 0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45, 0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD, 0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48, 0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C, 0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7, 0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50, 0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53, 0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55, 0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59, 0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C, 0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60, 0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63, 0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67, 0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A, 0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D, 0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71, 0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75, 0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9, 0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C, 0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81, 0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85, 0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89, 0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D, 0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7, 0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93, 0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96, 0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99, 0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C, 0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0, 0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43, 0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47, 0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B, 0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F, 0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53, 0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57, 0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B, 0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F, 0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63, 0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67, 0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B, 0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F, 0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73, 0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5, 0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A, 0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E, 0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82, 0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86, 0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A, 0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E, 0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92, 0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96, 0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A, 0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E, 0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41, 0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45, 0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49, 0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB, 0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50, 0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC, 0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57, 0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B, 0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F, 0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63, 0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67, 0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B, 0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F, 0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73, 0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77, 0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B, 0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80, 0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84, 0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88, 0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C, 0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90, 0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94, 0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98, 0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C, 0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0, 0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43, 0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47, 0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B, 0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F, 0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53, 0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57, 0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B, 0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F, 0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63, 0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67, 0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B, 0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F, 0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73, 0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77, 0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B, 0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80, 0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83, 0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86, 0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A, 0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D, 0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91, 0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95, 0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99, 0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D, 0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040, 0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044, 0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048, 0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C, 0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050, 0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054, 0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058, 0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C, 0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060, 0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB, 0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067, 0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B, 0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F, 0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073, 0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077, 0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B, 0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E, 0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC, 0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC, 0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD, 0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080, 0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9, 0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA, 0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4, 0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3, 0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6, 0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8, 0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED, 0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF, 0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE, 0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084, 0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4, 0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA, 0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE, 0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0, 0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7, 0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2, 0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5, 0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7, 0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8, 0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA, 0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC, 0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2, 0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088, 0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0, 0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4, 0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0, 0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF, 0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A, 0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB, 0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF, 0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1, 0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9, 0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8, 0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE, 0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1, 0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090, 0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF, 0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095, 0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099, 0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D, 0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F, 0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140, 0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3, 0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145, 0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5, 0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A, 0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF, 0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3, 0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0, 0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153, 0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156, 0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0, 0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C, 0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160, 0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2, 0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0, 0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169, 0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C, 0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7, 0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF, 0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173, 0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176, 0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179, 0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D, 0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB, 0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183, 0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185, 0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187, 0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189, 0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C, 0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4, 0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1, 0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195, 0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197, 0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A, 0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E, 0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F, 0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5, 0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243, 0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7, 0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248, 0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B, 0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F, 0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251, 0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253, 0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8, 0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257, 0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258, 0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7, 0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9, 0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C, 0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F, 0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC, 0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE, 0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5, 0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267, 0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A, 0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE, 0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D, 0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F, 0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4, 0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6, 0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4, 0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277, 0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8, 0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D, 0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB, 0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284, 0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288, 0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C, 0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF, 0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292, 0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295, 0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299, 0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D, 0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340, 0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342, 0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1, 0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345, 0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347, 0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B, 0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4, 0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7, 0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350, 0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB, 0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352, 0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE, 0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9, 0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD, 0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359, 0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE, 0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6, 0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF, 0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8, 0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361, 0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5, 0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366, 0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6, 0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF, 0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB, 0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D, 0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F, 0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD, 0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370, 0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC, 0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA, 0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7, 0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375, 0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC, 0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0, 0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9, 0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB, 0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF, 0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1, 0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5, 0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2, 0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A, 0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E, 0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392, 0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395, 0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5, 0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1, 0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C, 0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2, 0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442, 0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3, 0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0, 0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449, 0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B, 0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C, 0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB, 0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452, 0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455, 0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458, 0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A, 0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9, 0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E, 0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461, 0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9, 0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA, 0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6, 0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468, 0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2, 0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E, 0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470, 0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474, 0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477, 0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478, 0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C, 0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2, 0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA, 0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485, 0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489, 0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C, 0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF, 0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492, 0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB, 0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC, 0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD, 0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B, 0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F, 0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542, 0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546, 0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A, 0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E, 0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551, 0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4, 0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555, 0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559, 0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B, 0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F, 0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7, 0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9, 0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF, 0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566, 0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568, 0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6, 0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D, 0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571, 0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8, 0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE, 0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576, 0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD, 0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579, 0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A, 0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0, 0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B, 0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8, 0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582, 0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585, 0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587, 0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A, 0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D, 0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591, 0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD, 0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597, 0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A, 0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E, 0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640, 0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE, 0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB, 0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646, 0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5, 0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC, 0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA, 0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F, 0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7, 0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA, 0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2, 0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657, 0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658, 0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A, 0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C, 0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB, 0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE, 0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7, 0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F, 0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661, 0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662, 0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0, 0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667, 0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A, 0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3, 0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1, 0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB, 0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D, 0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F, 0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA, 0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671, 0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0, 0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675, 0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678, 0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A, 0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D, 0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680, 0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683, 0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF, 0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2, 0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686, 0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5, 0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A, 0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C, 0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1, 0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690, 0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694, 0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698, 0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A, 0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B, 0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D, 0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8, 0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB, 0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740, 0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743, 0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3, 0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747, 0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B, 0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4, 0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E, 0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4, 0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1, 0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753, 0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD, 0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5, 0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7, 0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756, 0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A, 0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C, 0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D, 0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761, 0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE, 0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766, 0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF, 0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC, 0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F, 0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772, 0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8, 0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776, 0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A, 0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD, 0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E, 0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB, 0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2, 0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA, 0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783, 0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785, 0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788, 0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5, 0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D, 0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790, 0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5, 0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795, 0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797, 0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798, 0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B, 0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0, 0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840, 0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6, 0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845, 0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847, 0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A, 0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D, 0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9, 0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852, 0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE, 0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854, 0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858, 0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B, 0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D, 0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861, 0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3, 0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864, 0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868, 0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B, 0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F, 0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872, 0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874, 0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878, 0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1, 0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880, 0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884, 0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887, 0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B, 0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8, 0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E, 0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891, 0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894, 0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897, 0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898, 0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B, 0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3, 0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD, 0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941, 0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9, 0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948, 0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949, 0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5, 0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E, 0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952, 0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954, 0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957, 0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A, 0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E, 0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962, 0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966, 0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1, 0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B, 0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0, 0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F, 0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971, 0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974, 0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE, 0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979, 0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B, 0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD, 0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982, 0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985, 0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987, 0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB, 0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C, 0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F, 0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992, 0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996, 0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A, 0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D, 0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0, 0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43, 0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47, 0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A, 0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D, 0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50, 0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5, 0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56, 0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58, 0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C, 0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60, 0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62, 0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66, 0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A, 0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE, 0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B, 0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F, 0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72, 0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF, 0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77, 0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B, 0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1, 0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82, 0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9, 0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89, 0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C, 0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F, 0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93, 0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD, 0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99, 0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA, 0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9, 0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40, 0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42, 0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45, 0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49, 0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C, 0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50, 0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54, 0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56, 0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A, 0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D, 0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD, 0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4, 0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64, 0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68, 0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A, 0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E, 0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71, 0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75, 0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78, 0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C, 0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E, 0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81, 0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85, 0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88, 0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C, 0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F, 0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92, 0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96, 0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A, 0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E, 0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41, 0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44, 0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47, 0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A, 0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E, 0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52, 0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55, 0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1, 0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C, 0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60, 0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64, 0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68, 0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A, 0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E, 0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72, 0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76, 0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79, 0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C, 0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81, 0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85, 0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89, 0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2, 0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C, 0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F, 0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9, 0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD, 0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD, 0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C, 0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0, 0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1, 0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43, 0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47, 0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3, 0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA, 0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC, 0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D, 0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3, 0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51, 0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55, 0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57, 0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B, 0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D, 0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61, 0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63, 0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD, 0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66, 0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67, 0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0, 0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5, 0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F, 0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72, 0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9, 0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6, 0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3, 0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78, 0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B, 0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D, 0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2, 0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83, 0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86, 0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89, 0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9, 0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD, 0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E, 0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90, 0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA, 0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4, 0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98, 0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB, 0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B, 0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1, 0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0, 0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3, 0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0, 0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC, 0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46, 0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49, 0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2, 0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F, 0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52, 0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55, 0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4, 0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A, 0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E, 0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F, 0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB, 0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65, 0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68, 0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A, 0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E, 0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71, 0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72, 0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76, 0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3, 0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C, 0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB, 0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83, 0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE, 0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB, 0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88, 0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B, 0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D, 0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91, 0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94, 0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97, 0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B, 0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E, 0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41, 0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44, 0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45, 0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48, 0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A, 0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD, 0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50, 0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53, 0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1, 0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1, 0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C, 0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE, 0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61, 0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65, 0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68, 0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B, 0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E, 0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3, 0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5, 0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78, 0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C, 0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80, 0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8, 0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87, 0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A, 0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9, 0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91, 0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95, 0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6, 0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A, 0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D, 0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0, 0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042, 0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046, 0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A, 0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3, 0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051, 0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054, 0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057, 0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A, 0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C, 0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060, 0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062, 0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066, 0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069, 0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B, 0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F, 0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9, 0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072, 0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074, 0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2, 0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4, 0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B, 0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E, 0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0, 0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7, 0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084, 0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087, 0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089, 0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB, 0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4, 0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093, 0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096, 0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8, 0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C, 0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0, 0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141, 0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144, 0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148, 0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B, 0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E, 0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1, 0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9, 0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155, 0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE, 0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6, 0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D, 0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F, 0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163, 0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD, 0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166, 0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169, 0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D, 0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F, 0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171, 0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173, 0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5, 0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3, 0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C, 0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB, 0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184, 0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD, 0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189, 0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2, 0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E, 0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191, 0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194, 0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA, 0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A, 0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D, 0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE, 0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242, 0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246, 0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249, 0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C, 0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250, 0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254, 0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258, 0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C, 0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260, 0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5, 0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266, 0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0, 0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D, 0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271, 0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275, 0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279, 0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D, 0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281, 0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283, 0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2, 0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289, 0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D, 0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291, 0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295, 0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299, 0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D, 0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340, 0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344, 0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348, 0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C, 0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350, 0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354, 0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358, 0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C, 0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB, 0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3, 0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9, 0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC, 0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7, 0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB, 0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD, 0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC, 0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C, 0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5, 0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371, 0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374, 0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377, 0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A, 0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E, 0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383, 0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386, 0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A, 0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D, 0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391, 0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395, 0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399, 0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D, 0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440, 0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444, 0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448, 0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C, 0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450, 0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454, 0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458, 0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C, 0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4, 0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463, 0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467, 0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A, 0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E, 0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472, 0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476, 0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A, 0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E, 0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483, 0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487, 0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B, 0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F, 0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493, 0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497, 0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A, 0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E, 0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541, 0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545, 0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC, 0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B, 0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F, 0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552, 0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556, 0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A, 0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E, 0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562, 0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566, 0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A, 0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E, 0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572, 0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576, 0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A, 0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E, 0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583, 0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587, 0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B, 0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F, 0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593, 0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597, 0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B, 0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F, 0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642, 0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646, 0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A, 0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E, 0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652, 0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656, 0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A, 0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E, 0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662, 0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665, 0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669, 0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D, 0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671, 0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675, 0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679, 0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D, 0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5, 0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685, 0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689, 0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D, 0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691, 0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695, 0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699, 0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D, 0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740, 0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744, 0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748, 0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C, 0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750, 0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754, 0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758, 0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C, 0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF, 0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763, 0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766, 0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A, 0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E, 0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772, 0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776, 0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A, 0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E, 0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783, 0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787, 0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B, 0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F, 0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793, 0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797, 0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9, 0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6, 0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8, 0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9, 0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2, 0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8, 0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB, 0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8, 0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC, 0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6, 0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF, 0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0, 0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1, 0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4, 0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF, 0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE, 0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF, 0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA, 0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E, 0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD, 0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5, 0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0, 0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5, 0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE, 0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5, 0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB, 0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA, 0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1, 0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB, 0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE, 0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8, 0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0, 0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB, 0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB, 0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8, 0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA, 0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC, 0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF, 0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842, 0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846, 0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849, 0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9, 0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E, 0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851, 0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855, 0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858, 0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0, 0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F, 0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF, 0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865, 0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0, 0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B, 0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F, 0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872, 0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2, 0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877, 0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5, 0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D, 0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6, 0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883, 0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887, 0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A, 0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D, 0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891, 0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895, 0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899, 0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D, 0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940, 0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944, 0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948, 0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C, 0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950, 0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954, 0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958, 0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C, 0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960, 0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964, 0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968, 0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C, 0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970, 0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974, 0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978, 0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C, 0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981, 0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985, 0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989, 0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D, 0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991, 0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995, 0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999, 0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D, 0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40, 0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44, 0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48, 0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C, 0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA, 0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6, 0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB, 0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0, 0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC, 0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA, 0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC, 0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8, 0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6, 0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8, 0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1, 0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE, 0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA, 0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51, 0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5, 0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC, 0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE, 0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE, 0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2, 0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57, 0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59, 0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C, 0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF, 0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F, 0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63, 0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66, 0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68, 0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD, 0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E, 0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71, 0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74, 0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78, 0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C, 0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80, 0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83, 0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87, 0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B, 0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E, 0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F, 0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3, 0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA, 0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96, 0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC, 0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B, 0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9, 0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E, 0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5, 0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7, 0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8, 0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46, 0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48, 0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2, 0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C, 0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F, 0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51, 0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5, 0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53, 0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57, 0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A, 0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB, 0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F, 0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62, 0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65, 0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69, 0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1, 0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF, 0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70, 0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9, 0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA, 0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76, 0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79, 0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD, 0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E, 0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5, 0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83, 0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8, 0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86, 0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7, 0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C, 0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F, 0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93, 0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97, 0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4, 0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D, 0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F, 0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7, 0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA, 0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45, 0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48, 0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A, 0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D, 0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50, 0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54, 0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56, 0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59, 0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D, 0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3, 0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63, 0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67, 0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B, 0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D, 0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3, 0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73, 0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9, 0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A, 0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E, 0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83, 0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87, 0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6, 0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E, 0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92, 0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96, 0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A, 0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E, 0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41, 0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45, 0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49, 0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D, 0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51, 0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55, 0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59, 0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D, 0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61, 0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65, 0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69, 0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D, 0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71, 0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75, 0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79, 0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D, 0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82, 0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86, 0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A, 0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E, 0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92, 0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96, 0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A, 0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E, 0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41, 0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45, 0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49, 0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D, 0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51, 0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55, 0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59, 0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D, 0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5, 0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61, 0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6, 0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0, 0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3, 0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7, 0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9, 0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB, 0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE, 0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5, 0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2, 0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64, 0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD, 0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5, 0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7, 0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68, 0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B, 0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D, 0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70, 0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72, 0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1, 0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78, 0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF, 0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8, 0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E, 0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81, 0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD, 0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86, 0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87, 0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89, 0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC, 0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6, 0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8, 0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF, 0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5, 0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91, 0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94, 0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95, 0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98, 0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA, 0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6, 0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7, 0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D, 0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD, 0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1, 0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8, 0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1, 0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA, 0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE, 0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48, 0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE, 0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D, 0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4, 0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52, 0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2, 0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC, 0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58, 0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B, 0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E, 0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9, 0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61, 0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63, 0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66, 0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD, 0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B, 0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E, 0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA, 0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74, 0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76, 0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A, 0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D, 0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2, 0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82, 0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85, 0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88, 0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B, 0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D, 0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F, 0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91, 0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF, 0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE, 0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0, 0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA, 0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B, 0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD, 0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE, 0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5, 0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040, 0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042, 0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC, 0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9, 0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048, 0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B, 0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E, 0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F, 0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB, 0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA, 0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056, 0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058, 0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B, 0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E, 0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061, 0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1, 0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5, 0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069, 0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D, 0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071, 0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075, 0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079, 0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C, 0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4, 0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3, 0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086, 0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A, 0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E, 0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090, 0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094, 0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097, 0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B, 0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F, 0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA, 0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA, 0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC, 0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6, 0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147, 0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3, 0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA, 0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1, 0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E, 0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2, 0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA, 0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8, 0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8, 0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154, 0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7, 0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159, 0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C, 0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E, 0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F, 0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1, 0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164, 0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1, 0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A, 0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0, 0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170, 0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2, 0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4, 0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178, 0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A, 0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8, 0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182, 0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186, 0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A, 0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD, 0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0, 0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E, 0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192, 0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196, 0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199, 0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D, 0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240, 0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244, 0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248, 0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C, 0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250, 0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254, 0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258, 0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C, 0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260, 0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264, 0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268, 0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C, 0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270, 0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274, 0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278, 0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C, 0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281, 0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285, 0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289, 0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D, 0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291, 0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295, 0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299, 0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D, 0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340, 0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344, 0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348, 0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C, 0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350, 0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354, 0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358, 0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C, 0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360, 0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364, 0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368, 0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C, 0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F, 0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373, 0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377, 0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B, 0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380, 0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384, 0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6, 0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B, 0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F, 0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393, 0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397, 0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B, 0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F, 0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442, 0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7, 0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449, 0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D, 0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451, 0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455, 0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459, 0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D, 0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460, 0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464, 0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468, 0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C, 0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470, 0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474, 0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478, 0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C, 0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481, 0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485, 0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489, 0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D, 0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491, 0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495, 0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499, 0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D, 0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540, 0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544, 0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548, 0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C, 0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550, 0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554, 0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558, 0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C, 0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560, 0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564, 0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568, 0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C, 0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570, 0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9, 0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577, 0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B, 0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580, 0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584, 0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588, 0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C, 0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590, 0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594, 0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598, 0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C, 0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA, 0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642, 0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646, 0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A, 0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E, 0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652, 0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656, 0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A, 0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E, 0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662, 0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665, 0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669, 0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D, 0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671, 0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675, 0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679, 0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D, 0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682, 0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686, 0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A, 0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E, 0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692, 0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696, 0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A, 0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB, 0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740, 0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744, 0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9, 0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B, 0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F, 0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753, 0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757, 0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B, 0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F, 0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763, 0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767, 0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B, 0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F, 0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773, 0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777, 0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B, 0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780, 0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784, 0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788, 0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C, 0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790, 0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794, 0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798, 0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C, 0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0, 0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843, 0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847, 0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B, 0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD, 0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852, 0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856, 0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A, 0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E, 0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862, 0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866, 0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A, 0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E, 0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872, 0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876, 0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A, 0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D, 0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882, 0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886, 0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A, 0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E, 0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892, 0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5, 0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8, 0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5, 0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0, 0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896, 0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0, 0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE, 0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6, 0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5, 0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6, 0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5, 0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB, 0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD, 0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1, 0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8, 0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC, 0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD, 0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8, 0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC, 0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF, 0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1, 0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C, 0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6, 0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9, 0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D, 0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE, 0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3, 0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9, 0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8, 0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC, 0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4, 0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE, 0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF, 0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2, 0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4, 0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6, 0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA, 0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA, 0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE, 0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0, 0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5, 0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1, 0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC, 0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6, 0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8, 0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1, 0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC, 0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE, 0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2, 0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7, 0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5, 0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7, 0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA, 0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947, 0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF, 0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3, 0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6, 0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA, 0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949, 0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF, 0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2, 0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F, 0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953, 0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956, 0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A, 0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E, 0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962, 0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966, 0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A, 0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E, 0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972, 0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976, 0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A, 0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E, 0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983, 0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987, 0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B, 0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F, 0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993, 0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997, 0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B, 0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F, 0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42, 0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46, 0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A, 0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E, 0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52, 0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56, 0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A, 0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1, 0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA, 0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0, 0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA, 0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB, 0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC, 0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2, 0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF, 0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1, 0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6, 0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6, 0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8, 0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB, 0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62, 0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3, 0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67, 0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6, 0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE, 0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0, 0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7, 0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73, 0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74, 0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9, 0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD, 0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77, 0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78, 0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B, 0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D, 0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82, 0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85, 0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA, 0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89, 0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3, 0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C, 0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF, 0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5, 0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93, 0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97, 0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B, 0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1, 0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0, 0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41, 0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43, 0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46, 0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47, 0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A, 0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E, 0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52, 0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55, 0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59, 0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C, 0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5, 0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61, 0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1, 0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64, 0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF, 0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67, 0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2, 0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3, 0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D, 0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71, 0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75, 0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78, 0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C, 0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9, 0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82, 0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85, 0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3, 0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89, 0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED, 0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E, 0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA, 0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91, 0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE, 0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96, 0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8, 0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C, 0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC, 0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41, 0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45, 0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF, 0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B, 0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6, 0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51, 0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53, 0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2, 0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A, 0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E, 0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62, 0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66, 0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0, 0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8, 0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E, 0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7, 0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6, 0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74, 0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77, 0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B, 0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80, 0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0, 0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85, 0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88, 0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C, 0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F, 0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93, 0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95, 0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3, 0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A, 0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D, 0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40, 0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43, 0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46, 0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A, 0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C, 0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8, 0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51, 0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55, 0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59, 0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D, 0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61, 0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65, 0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69, 0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D, 0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71, 0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75, 0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79, 0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D, 0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4, 0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8, 0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83, 0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87, 0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8, 0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C, 0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90, 0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94, 0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98, 0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C, 0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0, 0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43, 0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47, 0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B, 0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F, 0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53, 0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57, 0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B, 0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F, 0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63, 0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67, 0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B, 0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F, 0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73, 0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77, 0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B, 0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80, 0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84, 0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88, 0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C, 0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90, 0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94, 0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98, 0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C, 0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0, 0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43, 0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5, 0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3, 0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB, 0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC, 0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC, 0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5, 0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47, 0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48, 0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1, 0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6, 0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8, 0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB, 0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD, 0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E, 0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52, 0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56, 0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A, 0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E, 0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62, 0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66, 0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A, 0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E, 0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7, 0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA, 0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75, 0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE, 0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9, 0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C, 0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81, 0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83, 0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87, 0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B, 0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F, 0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93, 0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97, 0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B, 0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F, 0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042, 0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045, 0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048, 0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C, 0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050, 0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054, 0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058, 0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C, 0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060, 0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1, 0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067, 0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B, 0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F, 0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073, 0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077, 0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B, 0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080, 0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084, 0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088, 0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A, 0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E, 0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092, 0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096, 0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098, 0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF, 0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB, 0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7, 0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4, 0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8, 0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D, 0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E, 0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD, 0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8, 0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141, 0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8, 0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7, 0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142, 0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146, 0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A, 0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D, 0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150, 0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154, 0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158, 0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C, 0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160, 0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164, 0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168, 0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C, 0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170, 0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174, 0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178, 0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C, 0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181, 0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185, 0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189, 0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D, 0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191, 0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195, 0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199, 0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D, 0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240, 0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244, 0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248, 0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C, 0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250, 0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254, 0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258, 0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C, 0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260, 0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264, 0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268, 0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C, 0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270, 0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274, 0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278, 0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C, 0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281, 0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285, 0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289, 0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D, 0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291, 0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295, 0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299, 0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D, 0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340, 0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344, 0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348, 0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C, 0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350, 0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4, 0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352, 0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB, 0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3, 0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD, 0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE, 0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6, 0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA, 0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356, 0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC, 0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE, 0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7, 0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9, 0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5, 0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A, 0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C, 0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360, 0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362, 0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE, 0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF, 0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369, 0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4, 0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D, 0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371, 0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373, 0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376, 0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379, 0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C, 0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381, 0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383, 0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6, 0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A, 0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C, 0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F, 0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393, 0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396, 0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399, 0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D, 0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0, 0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442, 0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446, 0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449, 0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C, 0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450, 0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454, 0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457, 0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A, 0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E, 0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462, 0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA, 0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468, 0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C, 0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E, 0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA, 0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471, 0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472, 0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475, 0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477, 0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A, 0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E, 0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483, 0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487, 0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B, 0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F, 0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493, 0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497, 0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B, 0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F, 0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542, 0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546, 0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A, 0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E, 0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552, 0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556, 0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A, 0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E, 0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562, 0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566, 0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A, 0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E, 0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572, 0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576, 0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A, 0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E, 0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583, 0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587, 0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B, 0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F, 0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593, 0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597, 0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B, 0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F, 0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642, 0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646, 0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A, 0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E, 0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652, 0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656, 0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A, 0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E, 0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662, 0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666, 0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A, 0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E, 0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672, 0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676, 0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A, 0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E, 0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683, 0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687, 0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B, 0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F, 0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693, 0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697, 0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B, 0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F, 0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742, 0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746, 0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A, 0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E, 0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752, 0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756, 0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A, 0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E, 0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762, 0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766, 0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A, 0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E, 0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772, 0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776, 0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A, 0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E, 0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782, 0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0, 0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2, 0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787, 0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7, 0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA, 0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B, 0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD, 0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF, 0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3, 0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6, 0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790, 0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC, 0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF, 0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3, 0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5, 0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794, 0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798, 0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB, 0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD, 0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3, 0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C, 0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE, 0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D, 0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB, 0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF, 0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843, 0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847, 0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B, 0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F, 0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853, 0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857, 0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B, 0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F, 0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863, 0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867, 0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B, 0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F, 0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873, 0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877, 0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B, 0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880, 0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884, 0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888, 0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C, 0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890, 0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894, 0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898, 0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C, 0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0, 0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943, 0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947, 0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B, 0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F, 0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953, 0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957, 0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B, 0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F, 0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963, 0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967, 0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B, 0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F, 0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973, 0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977, 0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B, 0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980, 0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984, 0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988, 0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C, 0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990, 0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994, 0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998, 0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C, 0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0, 0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43, 0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47, 0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B, 0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F, 0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53, 0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57, 0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B, 0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F, 0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63, 0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67, 0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B, 0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F, 0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73, 0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77, 0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B, 0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80, 0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84, 0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88, 0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C, 0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90, 0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94, 0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98, 0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C, 0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0, 0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43, 0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47, 0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B, 0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F, 0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53, 0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57, 0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B, 0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0, 0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB, 0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3, 0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E, 0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6, 0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8, 0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC, 0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD, 0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF, 0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1, 0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5, 0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7, 0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66, 0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69, 0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB, 0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE, 0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F, 0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0, 0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4, 0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71, 0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73, 0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76, 0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A, 0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA, 0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4, 0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84, 0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86, 0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89, 0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8, 0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F, 0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93, 0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96, 0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99, 0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3, 0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0, 0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43, 0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47, 0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A, 0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D, 0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2, 0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52, 0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55, 0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58, 0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8, 0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C, 0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F, 0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62, 0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63, 0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1, 0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67, 0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5, 0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C, 0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F, 0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73, 0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76, 0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC, 0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B, 0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80, 0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84, 0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6, 0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88, 0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B, 0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D, 0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91, 0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7, 0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97, 0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B, 0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E, 0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40, 0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44, 0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46, 0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD, 0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B, 0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E, 0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52, 0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56, 0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58, 0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C, 0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60, 0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64, 0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68, 0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C, 0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70, 0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74, 0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78, 0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C, 0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81, 0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85, 0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87, 0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6, 0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA, 0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89, 0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D, 0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91, 0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8, 0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96, 0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98, 0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C, 0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0, 0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43, 0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47, 0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B, 0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F, 0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5, 0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1, 0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF, 0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5, 0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB, 0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B, 0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F, 0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973, 0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977, 0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B, 0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980, 0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984, 0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988, 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7, 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC, 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, 0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA, 0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4, 0, 0 }; static const WCHAR oem2uni936[] = { /* GBK --> Unicode pairs */ 0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05, 0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17, 0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23, 0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F, 0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37, 0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42, 0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51, 0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B, 0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65, 0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B, 0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F, 0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76, 0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A, 0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F, 0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83, 0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A, 0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99, 0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3, 0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1, 0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8, 0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE, 0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0, 0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC, 0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7, 0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF, 0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9, 0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00, 0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05, 0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B, 0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14, 0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D, 0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29, 0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31, 0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39, 0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40, 0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45, 0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A, 0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54, 0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66, 0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D, 0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75, 0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A, 0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82, 0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A, 0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92, 0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98, 0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E, 0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4, 0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1, 0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6, 0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA, 0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE, 0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6, 0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB, 0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3, 0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9, 0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4, 0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC, 0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5, 0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB, 0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000, 0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004, 0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008, 0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E, 0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015, 0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D, 0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023, 0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F, 0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033, 0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037, 0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D, 0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042, 0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049, 0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050, 0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054, 0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059, 0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F, 0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063, 0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068, 0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D, 0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071, 0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075, 0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C, 0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083, 0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089, 0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E, 0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092, 0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096, 0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A, 0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E, 0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2, 0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB, 0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0, 0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5, 0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9, 0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF, 0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3, 0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7, 0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB, 0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0, 0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4, 0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9, 0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE, 0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2, 0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8, 0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF, 0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4, 0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9, 0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE, 0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102, 0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108, 0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D, 0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111, 0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116, 0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A, 0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E, 0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123, 0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127, 0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B, 0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F, 0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133, 0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137, 0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B, 0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142, 0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E, 0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153, 0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B, 0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160, 0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166, 0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F, 0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F, 0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187, 0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F, 0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194, 0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E, 0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6, 0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA, 0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8, 0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF, 0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5, 0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE, 0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4, 0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8, 0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE, 0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5, 0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9, 0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1, 0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE, 0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B, 0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213, 0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E, 0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223, 0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A, 0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232, 0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E, 0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247, 0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E, 0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255, 0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A, 0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260, 0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266, 0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D, 0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273, 0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277, 0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B, 0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283, 0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287, 0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C, 0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291, 0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296, 0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A, 0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6, 0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0, 0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7, 0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB, 0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1, 0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6, 0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD, 0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3, 0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9, 0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD, 0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2, 0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7, 0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB, 0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF, 0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4, 0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8, 0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301, 0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307, 0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C, 0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313, 0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C, 0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324, 0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329, 0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F, 0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333, 0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337, 0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340, 0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B, 0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354, 0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D, 0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C, 0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379, 0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E, 0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387, 0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F, 0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393, 0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399, 0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0, 0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA, 0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF, 0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3, 0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8, 0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD, 0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4, 0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE, 0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3, 0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD, 0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7, 0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF, 0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407, 0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419, 0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424, 0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433, 0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D, 0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444, 0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C, 0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451, 0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F, 0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465, 0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B, 0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F, 0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A, 0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483, 0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489, 0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493, 0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E, 0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2, 0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2, 0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9, 0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3, 0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6, 0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1, 0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB, 0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1, 0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7, 0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE, 0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504, 0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B, 0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512, 0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517, 0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C, 0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521, 0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529, 0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534, 0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539, 0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540, 0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548, 0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E, 0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553, 0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559, 0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E, 0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563, 0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F, 0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573, 0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D, 0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C, 0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592, 0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597, 0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0, 0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4, 0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9, 0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD, 0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2, 0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA, 0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1, 0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7, 0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE, 0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7, 0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB, 0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7, 0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0, 0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8, 0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC, 0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604, 0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A, 0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611, 0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615, 0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A, 0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621, 0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628, 0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E, 0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635, 0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C, 0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641, 0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645, 0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649, 0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650, 0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655, 0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D, 0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661, 0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667, 0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670, 0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675, 0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A, 0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680, 0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684, 0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A, 0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690, 0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695, 0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699, 0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D, 0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1, 0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6, 0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA, 0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE, 0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3, 0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8, 0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD, 0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1, 0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5, 0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9, 0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE, 0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2, 0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8, 0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5, 0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9, 0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF, 0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7, 0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700, 0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707, 0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E, 0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712, 0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716, 0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A, 0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720, 0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725, 0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731, 0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736, 0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D, 0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744, 0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749, 0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754, 0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759, 0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767, 0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771, 0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778, 0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E, 0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787, 0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D, 0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791, 0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797, 0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C, 0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5, 0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF, 0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5, 0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA, 0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE, 0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4, 0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8, 0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD, 0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6, 0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE, 0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5, 0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9, 0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE, 0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3, 0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB, 0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801, 0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808, 0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E, 0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813, 0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818, 0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D, 0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825, 0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829, 0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E, 0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833, 0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838, 0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C, 0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840, 0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845, 0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849, 0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F, 0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855, 0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A, 0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F, 0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863, 0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868, 0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E, 0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872, 0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876, 0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A, 0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F, 0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887, 0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C, 0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890, 0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896, 0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C, 0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2, 0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6, 0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC, 0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0, 0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4, 0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8, 0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD, 0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2, 0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7, 0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB, 0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF, 0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4, 0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9, 0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD, 0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1, 0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6, 0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA, 0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2, 0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8, 0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD, 0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901, 0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908, 0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C, 0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912, 0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B, 0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921, 0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928, 0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933, 0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D, 0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943, 0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C, 0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953, 0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D, 0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963, 0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968, 0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C, 0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970, 0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977, 0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E, 0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989, 0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F, 0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995, 0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C, 0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1, 0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC, 0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3, 0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7, 0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD, 0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2, 0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7, 0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD, 0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6, 0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF, 0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4, 0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA, 0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF, 0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3, 0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7, 0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD, 0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A, 0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F, 0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15, 0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A, 0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21, 0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27, 0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C, 0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30, 0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38, 0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D, 0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42, 0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47, 0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D, 0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51, 0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56, 0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B, 0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F, 0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64, 0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69, 0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E, 0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72, 0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B, 0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80, 0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84, 0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88, 0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C, 0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90, 0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95, 0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99, 0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F, 0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3, 0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7, 0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC, 0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0, 0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7, 0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC, 0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3, 0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7, 0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD, 0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1, 0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9, 0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE, 0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5, 0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC, 0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0, 0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5, 0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9, 0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD, 0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01, 0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05, 0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A, 0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E, 0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12, 0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18, 0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C, 0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20, 0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24, 0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28, 0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C, 0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30, 0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36, 0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B, 0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F, 0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44, 0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48, 0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C, 0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52, 0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61, 0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D, 0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74, 0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79, 0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F, 0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D, 0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92, 0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7, 0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD, 0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2, 0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC, 0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8, 0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD, 0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4, 0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8, 0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC, 0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6, 0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB, 0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1, 0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5, 0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE, 0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05, 0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C, 0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12, 0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B, 0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21, 0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29, 0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E, 0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33, 0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43, 0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C, 0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54, 0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A, 0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F, 0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68, 0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C, 0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73, 0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77, 0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D, 0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84, 0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89, 0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F, 0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D, 0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1, 0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7, 0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF, 0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6, 0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC, 0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3, 0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8, 0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD, 0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1, 0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6, 0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB, 0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF, 0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7, 0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE, 0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3, 0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7, 0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC, 0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00, 0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08, 0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C, 0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11, 0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17, 0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C, 0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21, 0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28, 0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F, 0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33, 0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38, 0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C, 0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42, 0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46, 0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E, 0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52, 0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56, 0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C, 0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61, 0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65, 0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A, 0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71, 0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76, 0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A, 0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E, 0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83, 0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87, 0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B, 0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F, 0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93, 0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97, 0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C, 0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1, 0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5, 0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9, 0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD, 0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1, 0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5, 0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA, 0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE, 0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2, 0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7, 0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB, 0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0, 0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4, 0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8, 0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF, 0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA, 0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5, 0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA, 0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00, 0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A, 0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12, 0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F, 0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23, 0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29, 0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F, 0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34, 0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A, 0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41, 0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48, 0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D, 0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51, 0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57, 0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C, 0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63, 0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67, 0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B, 0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F, 0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77, 0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82, 0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89, 0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92, 0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1, 0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8, 0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC, 0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1, 0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB, 0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0, 0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4, 0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8, 0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE, 0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5, 0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA, 0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF, 0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3, 0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7, 0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED, 0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1, 0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8, 0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD, 0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09, 0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10, 0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19, 0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E, 0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24, 0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E, 0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34, 0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38, 0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F, 0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44, 0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48, 0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C, 0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51, 0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B, 0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60, 0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68, 0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72, 0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78, 0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F, 0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E, 0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94, 0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D, 0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2, 0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6, 0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC, 0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2, 0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8, 0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE, 0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2, 0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB, 0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5, 0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE, 0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5, 0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC, 0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3, 0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9, 0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008, 0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010, 0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018, 0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022, 0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D, 0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032, 0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037, 0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D, 0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045, 0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049, 0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F, 0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056, 0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C, 0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061, 0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071, 0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077, 0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082, 0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088, 0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F, 0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095, 0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C, 0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4, 0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA, 0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5, 0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA, 0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0, 0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4, 0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC, 0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0, 0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6, 0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE, 0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4, 0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2, 0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB, 0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF, 0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105, 0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C, 0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113, 0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118, 0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D, 0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125, 0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C, 0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130, 0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134, 0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138, 0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C, 0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141, 0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145, 0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B, 0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152, 0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157, 0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B, 0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160, 0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165, 0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B, 0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F, 0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174, 0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A, 0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E, 0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182, 0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186, 0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A, 0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190, 0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195, 0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199, 0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E, 0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2, 0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6, 0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE, 0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2, 0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6, 0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB, 0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0, 0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5, 0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC, 0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0, 0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7, 0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB, 0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF, 0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3, 0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8, 0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC, 0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0, 0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4, 0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9, 0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD, 0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202, 0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207, 0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219, 0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220, 0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228, 0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F, 0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235, 0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A, 0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244, 0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F, 0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257, 0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D, 0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261, 0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268, 0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275, 0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B, 0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283, 0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288, 0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E, 0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299, 0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3, 0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA, 0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0, 0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6, 0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE, 0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB, 0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD, 0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4, 0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2, 0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA, 0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304, 0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B, 0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310, 0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315, 0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C, 0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C, 0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331, 0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336, 0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C, 0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341, 0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A, 0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354, 0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359, 0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D, 0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366, 0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C, 0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373, 0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379, 0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F, 0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385, 0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391, 0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397, 0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C, 0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1, 0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF, 0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6, 0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF, 0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3, 0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA, 0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3, 0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8, 0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC, 0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4, 0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8, 0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF, 0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5, 0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB, 0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404, 0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409, 0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411, 0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417, 0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D, 0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424, 0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429, 0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430, 0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435, 0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439, 0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440, 0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B, 0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F, 0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455, 0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A, 0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F, 0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463, 0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468, 0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E, 0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472, 0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476, 0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D, 0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481, 0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489, 0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D, 0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493, 0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A, 0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F, 0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3, 0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8, 0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1, 0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6, 0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE, 0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4, 0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9, 0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF, 0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5, 0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB, 0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0, 0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7, 0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB, 0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF, 0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3, 0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7, 0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB, 0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF, 0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504, 0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508, 0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D, 0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511, 0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516, 0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B, 0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F, 0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523, 0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528, 0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D, 0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533, 0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D, 0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543, 0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A, 0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550, 0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557, 0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F, 0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565, 0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A, 0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571, 0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578, 0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C, 0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580, 0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584, 0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589, 0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F, 0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596, 0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E, 0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6, 0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE, 0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4, 0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8, 0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF, 0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8, 0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0, 0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5, 0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB, 0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF, 0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA, 0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4, 0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB, 0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF, 0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607, 0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D, 0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616, 0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B, 0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622, 0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629, 0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E, 0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637, 0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B, 0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642, 0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647, 0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D, 0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658, 0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D, 0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663, 0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A, 0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671, 0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678, 0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D, 0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683, 0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689, 0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E, 0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693, 0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699, 0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E, 0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2, 0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6, 0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC, 0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1, 0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6, 0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB, 0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0, 0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4, 0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8, 0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC, 0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0, 0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4, 0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8, 0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0, 0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4, 0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA, 0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE, 0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6, 0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD, 0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704, 0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C, 0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712, 0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719, 0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720, 0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724, 0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E, 0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736, 0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B, 0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741, 0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A, 0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754, 0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759, 0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762, 0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767, 0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771, 0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779, 0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780, 0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786, 0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D, 0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792, 0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799, 0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1, 0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC, 0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4, 0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC, 0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0, 0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7, 0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB, 0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5, 0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF, 0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6, 0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB, 0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5, 0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9, 0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE, 0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804, 0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812, 0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819, 0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E, 0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823, 0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827, 0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D, 0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831, 0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A, 0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B, 0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856, 0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A, 0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E, 0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D, 0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871, 0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878, 0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C, 0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880, 0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888, 0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C, 0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891, 0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896, 0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B, 0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F, 0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4, 0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB, 0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2, 0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8, 0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC, 0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1, 0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6, 0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC, 0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1, 0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7, 0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD, 0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2, 0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7, 0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB, 0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2, 0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7, 0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE, 0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903, 0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908, 0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F, 0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915, 0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919, 0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D, 0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923, 0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928, 0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C, 0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932, 0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937, 0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C, 0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943, 0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947, 0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B, 0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F, 0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953, 0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959, 0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961, 0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967, 0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C, 0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972, 0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976, 0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E, 0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985, 0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E, 0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992, 0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999, 0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F, 0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3, 0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9, 0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF, 0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5, 0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA, 0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF, 0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4, 0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8, 0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF, 0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5, 0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9, 0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE, 0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4, 0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8, 0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC, 0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1, 0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6, 0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA, 0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00, 0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04, 0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08, 0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D, 0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11, 0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15, 0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B, 0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20, 0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25, 0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B, 0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30, 0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36, 0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A, 0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40, 0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45, 0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A, 0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E, 0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53, 0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57, 0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E, 0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63, 0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68, 0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C, 0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70, 0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75, 0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A, 0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F, 0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85, 0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89, 0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D, 0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94, 0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99, 0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D, 0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2, 0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6, 0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD, 0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1, 0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5, 0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9, 0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD, 0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1, 0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5, 0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9, 0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD, 0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1, 0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5, 0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9, 0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD, 0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1, 0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5, 0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9, 0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED, 0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1, 0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5, 0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9, 0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD, 0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01, 0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05, 0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09, 0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D, 0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11, 0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15, 0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19, 0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D, 0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26, 0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B, 0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F, 0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34, 0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B, 0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40, 0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45, 0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D, 0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51, 0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55, 0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A, 0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E, 0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68, 0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D, 0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71, 0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75, 0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A, 0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80, 0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E, 0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94, 0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99, 0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F, 0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4, 0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8, 0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD, 0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1, 0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9, 0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD, 0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4, 0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9, 0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0, 0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC, 0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0, 0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5, 0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9, 0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0, 0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6, 0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB, 0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00, 0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04, 0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B, 0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17, 0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20, 0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C, 0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36, 0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B, 0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43, 0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B, 0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F, 0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56, 0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62, 0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67, 0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E, 0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75, 0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B, 0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84, 0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D, 0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95, 0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A, 0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0, 0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF, 0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6, 0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1, 0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7, 0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE, 0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8, 0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD, 0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7, 0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2, 0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00, 0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06, 0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D, 0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13, 0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18, 0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20, 0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24, 0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C, 0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34, 0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A, 0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44, 0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55, 0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B, 0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62, 0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68, 0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70, 0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75, 0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B, 0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80, 0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86, 0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D, 0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96, 0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A, 0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC, 0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3, 0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9, 0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD, 0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3, 0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD, 0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2, 0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7, 0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF, 0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7, 0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED, 0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4, 0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA, 0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00, 0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04, 0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09, 0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13, 0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B, 0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22, 0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A, 0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31, 0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37, 0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D, 0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41, 0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47, 0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B, 0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51, 0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59, 0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E, 0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63, 0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67, 0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C, 0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71, 0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75, 0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79, 0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D, 0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84, 0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B, 0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91, 0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95, 0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A, 0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0, 0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6, 0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC, 0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3, 0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC, 0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3, 0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8, 0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD, 0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6, 0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC, 0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA, 0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE, 0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2, 0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7, 0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC, 0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00, 0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05, 0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B, 0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10, 0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17, 0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B, 0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F, 0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25, 0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C, 0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34, 0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39, 0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D, 0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42, 0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48, 0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E, 0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52, 0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56, 0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B, 0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61, 0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67, 0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B, 0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71, 0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77, 0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E, 0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82, 0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87, 0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90, 0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94, 0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98, 0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D, 0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2, 0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6, 0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB, 0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF, 0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4, 0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA, 0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE, 0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4, 0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8, 0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD, 0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3, 0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7, 0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB, 0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2, 0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6, 0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA, 0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0, 0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4, 0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8, 0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC, 0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000, 0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004, 0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008, 0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C, 0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010, 0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015, 0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019, 0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F, 0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024, 0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028, 0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C, 0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030, 0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034, 0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A, 0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E, 0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042, 0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046, 0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A, 0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050, 0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054, 0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058, 0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C, 0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061, 0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065, 0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069, 0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072, 0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079, 0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081, 0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086, 0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C, 0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091, 0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A, 0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0, 0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4, 0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8, 0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2, 0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA, 0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5, 0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB, 0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF, 0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3, 0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7, 0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE, 0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3, 0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0, 0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4, 0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA, 0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF, 0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103, 0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107, 0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D, 0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112, 0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C, 0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120, 0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124, 0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129, 0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D, 0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134, 0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139, 0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D, 0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141, 0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146, 0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B, 0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151, 0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155, 0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159, 0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F, 0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163, 0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B, 0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170, 0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176, 0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C, 0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181, 0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186, 0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B, 0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190, 0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195, 0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B, 0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1, 0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5, 0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA, 0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF, 0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4, 0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA, 0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE, 0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2, 0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7, 0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB, 0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0, 0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6, 0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA, 0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE, 0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3, 0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9, 0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED, 0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2, 0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6, 0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB, 0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF, 0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203, 0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208, 0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C, 0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210, 0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214, 0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218, 0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C, 0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221, 0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225, 0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B, 0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232, 0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C, 0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242, 0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246, 0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E, 0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253, 0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258, 0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260, 0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268, 0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D, 0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274, 0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B, 0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283, 0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288, 0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290, 0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295, 0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299, 0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D, 0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2, 0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6, 0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA, 0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2, 0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB, 0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF, 0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7, 0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC, 0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4, 0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA, 0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8, 0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E, 0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011, 0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236, 0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F, 0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237, 0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220, 0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E, 0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D, 0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F, 0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235, 0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0, 0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04, 0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030, 0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605, 0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7, 0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3, 0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190, 0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170, 0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174, 0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178, 0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A, 0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E, 0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492, 0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496, 0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A, 0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476, 0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A, 0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E, 0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482, 0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486, 0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462, 0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466, 0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220, 0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224, 0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228, 0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162, 0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166, 0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A, 0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, 0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, 0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041, 0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045, 0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049, 0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D, 0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051, 0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055, 0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059, 0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D, 0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061, 0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065, 0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069, 0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D, 0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071, 0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075, 0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079, 0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D, 0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081, 0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085, 0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089, 0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D, 0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091, 0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2, 0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6, 0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA, 0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE, 0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2, 0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6, 0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA, 0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE, 0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2, 0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6, 0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA, 0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE, 0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2, 0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6, 0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA, 0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE, 0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2, 0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6, 0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA, 0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE, 0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2, 0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6, 0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394, 0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398, 0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C, 0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0, 0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5, 0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9, 0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4, 0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8, 0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC, 0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0, 0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5, 0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9, 0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A, 0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E, 0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44, 0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38, 0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410, 0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414, 0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417, 0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B, 0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F, 0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423, 0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427, 0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B, 0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F, 0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433, 0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436, 0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A, 0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E, 0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442, 0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446, 0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A, 0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E, 0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9, 0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035, 0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197, 0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F, 0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267, 0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552, 0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556, 0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A, 0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E, 0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562, 0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566, 0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A, 0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E, 0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572, 0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583, 0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587, 0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B, 0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F, 0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC, 0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4, 0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012, 0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1, 0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9, 0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED, 0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3, 0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA, 0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8, 0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA, 0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261, 0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108, 0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C, 0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110, 0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114, 0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118, 0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C, 0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120, 0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124, 0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128, 0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023, 0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027, 0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E, 0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E, 0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1, 0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2, 0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010, 0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD, 0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E, 0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C, 0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50, 0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55, 0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A, 0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E, 0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62, 0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66, 0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B, 0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502, 0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506, 0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A, 0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E, 0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512, 0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516, 0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A, 0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E, 0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522, 0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526, 0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A, 0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E, 0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532, 0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536, 0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A, 0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E, 0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542, 0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546, 0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A, 0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF, 0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5, 0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB, 0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD, 0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302, 0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307, 0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C, 0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311, 0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319, 0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323, 0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328, 0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332, 0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A, 0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340, 0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344, 0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348, 0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C, 0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353, 0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358, 0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C, 0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361, 0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365, 0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369, 0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370, 0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374, 0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378, 0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C, 0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381, 0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386, 0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D, 0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393, 0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398, 0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D, 0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3, 0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7, 0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD, 0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6, 0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD, 0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3, 0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7, 0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2, 0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6, 0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB, 0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1, 0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6, 0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC, 0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1, 0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6, 0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA, 0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE, 0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402, 0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B, 0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411, 0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415, 0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419, 0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F, 0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424, 0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D, 0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437, 0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B, 0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440, 0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445, 0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449, 0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D, 0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451, 0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456, 0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461, 0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465, 0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469, 0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E, 0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473, 0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479, 0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D, 0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485, 0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A, 0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491, 0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495, 0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499, 0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F, 0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3, 0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA, 0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE, 0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2, 0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6, 0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB, 0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF, 0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3, 0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7, 0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB, 0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF, 0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4, 0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8, 0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD, 0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7, 0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB, 0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1, 0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8, 0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC, 0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501, 0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506, 0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A, 0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510, 0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516, 0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E, 0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523, 0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A, 0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539, 0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541, 0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546, 0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D, 0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553, 0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558, 0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560, 0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564, 0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B, 0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F, 0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575, 0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B, 0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580, 0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585, 0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A, 0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590, 0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B, 0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6, 0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA, 0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA, 0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1, 0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE, 0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3, 0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC, 0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1, 0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED, 0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3, 0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8, 0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE, 0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607, 0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D, 0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612, 0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A, 0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621, 0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C, 0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632, 0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A, 0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642, 0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647, 0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B, 0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651, 0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657, 0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B, 0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661, 0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666, 0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A, 0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670, 0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674, 0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679, 0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680, 0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689, 0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F, 0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695, 0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B, 0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F, 0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3, 0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8, 0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC, 0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3, 0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8, 0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC, 0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1, 0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3, 0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0, 0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE, 0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698, 0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA, 0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA, 0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE, 0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1, 0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA, 0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252, 0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B, 0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB, 0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D, 0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D, 0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70, 0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591, 0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C, 0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E, 0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A, 0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E, 0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1, 0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551, 0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE, 0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4, 0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC, 0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA, 0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0, 0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4, 0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9, 0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED, 0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6, 0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD, 0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703, 0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C, 0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711, 0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715, 0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B, 0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721, 0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727, 0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E, 0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733, 0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D, 0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744, 0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749, 0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D, 0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753, 0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757, 0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584, 0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971, 0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4, 0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F, 0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317, 0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1, 0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB, 0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF, 0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7, 0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8, 0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119, 0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6, 0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6, 0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED, 0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F, 0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B, 0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C, 0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E, 0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D, 0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868, 0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A, 0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8, 0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0, 0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C, 0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F, 0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769, 0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F, 0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773, 0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777, 0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C, 0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786, 0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A, 0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793, 0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797, 0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B, 0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1, 0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8, 0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF, 0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6, 0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA, 0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1, 0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5, 0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9, 0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE, 0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2, 0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6, 0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD, 0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1, 0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB, 0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5, 0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F, 0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B, 0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24, 0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C, 0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D, 0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8, 0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1, 0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C, 0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC, 0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695, 0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F, 0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7, 0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD, 0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56, 0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42, 0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C, 0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D, 0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7, 0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400, 0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17, 0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610, 0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6, 0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0, 0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5, 0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB, 0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805, 0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A, 0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810, 0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B, 0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822, 0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B, 0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832, 0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D, 0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843, 0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849, 0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F, 0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858, 0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C, 0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861, 0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865, 0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869, 0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872, 0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876, 0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B, 0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880, 0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A, 0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F, 0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545, 0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284, 0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E, 0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66, 0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B, 0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0, 0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89, 0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491, 0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210, 0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9, 0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E, 0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4, 0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF, 0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F, 0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5, 0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2, 0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD, 0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20, 0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8, 0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D, 0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87, 0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664, 0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886, 0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F, 0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895, 0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E, 0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6, 0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB, 0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF, 0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8, 0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD, 0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3, 0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8, 0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF, 0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6, 0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB, 0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF, 0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3, 0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7, 0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED, 0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1, 0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8, 0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD, 0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902, 0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907, 0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B, 0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7, 0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3, 0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20, 0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE, 0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF, 0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376, 0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F, 0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF, 0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5, 0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E, 0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64, 0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A, 0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE, 0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B, 0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1, 0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC, 0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC, 0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8, 0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA, 0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE, 0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927, 0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234, 0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37, 0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D, 0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911, 0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916, 0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A, 0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F, 0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923, 0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928, 0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C, 0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930, 0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935, 0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939, 0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943, 0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A, 0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E, 0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952, 0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959, 0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966, 0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C, 0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972, 0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976, 0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D, 0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983, 0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989, 0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E, 0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020, 0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355, 0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6, 0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1, 0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53, 0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863, 0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012, 0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230, 0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7, 0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C, 0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA, 0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E, 0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B, 0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1, 0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482, 0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012, 0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7, 0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B, 0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538, 0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0, 0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5, 0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A, 0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239, 0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D, 0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995, 0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999, 0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E, 0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2, 0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6, 0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB, 0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF, 0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4, 0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8, 0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4, 0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA, 0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0, 0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7, 0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC, 0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1, 0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA, 0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2, 0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6, 0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC, 0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04, 0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09, 0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10, 0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15, 0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B, 0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE, 0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D, 0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C, 0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8, 0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB, 0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597, 0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8, 0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A, 0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779, 0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A, 0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF, 0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD, 0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F, 0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72, 0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D, 0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6, 0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2, 0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241, 0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8, 0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9, 0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C, 0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069, 0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14, 0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D, 0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24, 0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28, 0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C, 0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30, 0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35, 0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E, 0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43, 0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48, 0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C, 0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50, 0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55, 0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A, 0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E, 0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62, 0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66, 0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A, 0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E, 0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73, 0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D, 0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87, 0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C, 0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93, 0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B, 0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30, 0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10, 0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0, 0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB, 0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41, 0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4, 0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D, 0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9, 0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8, 0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E, 0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE, 0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420, 0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39, 0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B, 0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A, 0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD, 0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30, 0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0, 0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD, 0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD, 0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426, 0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75, 0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45, 0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8, 0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7, 0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE, 0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2, 0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7, 0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB, 0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0, 0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4, 0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8, 0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD, 0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1, 0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5, 0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB, 0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2, 0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9, 0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE, 0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3, 0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7, 0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE, 0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05, 0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D, 0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13, 0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A, 0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21, 0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29, 0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F, 0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A, 0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7, 0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150, 0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B, 0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C, 0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC, 0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A, 0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5, 0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6, 0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746, 0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76, 0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63, 0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38, 0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F, 0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8, 0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E, 0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5, 0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D, 0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769, 0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601, 0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404, 0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015, 0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F, 0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35, 0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B, 0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41, 0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46, 0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E, 0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59, 0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61, 0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66, 0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A, 0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F, 0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76, 0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D, 0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83, 0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88, 0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C, 0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92, 0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99, 0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F, 0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5, 0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2, 0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7, 0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC, 0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0, 0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2, 0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B, 0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B, 0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13, 0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21, 0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F, 0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784, 0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7, 0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD, 0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4, 0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1, 0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7, 0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1, 0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0, 0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98, 0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986, 0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F, 0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470, 0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52, 0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C, 0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC, 0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A, 0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED, 0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7, 0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9, 0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE, 0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4, 0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8, 0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF, 0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4, 0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB, 0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0, 0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5, 0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA, 0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00, 0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04, 0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09, 0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10, 0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14, 0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19, 0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D, 0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22, 0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28, 0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D, 0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31, 0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35, 0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A, 0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E, 0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77, 0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87, 0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9, 0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD, 0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC, 0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D, 0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F, 0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E, 0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D, 0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475, 0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838, 0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408, 0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3, 0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64, 0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5, 0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC, 0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052, 0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679, 0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18, 0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334, 0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E, 0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A, 0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774, 0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43, 0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47, 0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B, 0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50, 0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54, 0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58, 0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C, 0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60, 0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64, 0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68, 0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C, 0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70, 0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76, 0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A, 0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81, 0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85, 0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A, 0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E, 0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94, 0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B, 0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6, 0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB, 0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0, 0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7, 0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27, 0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92, 0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7, 0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B, 0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0, 0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F, 0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8, 0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524, 0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3, 0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C, 0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27, 0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C, 0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E, 0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD, 0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1, 0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0, 0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A, 0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2, 0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A, 0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41, 0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7, 0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27, 0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA, 0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF, 0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2, 0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9, 0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0, 0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4, 0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD, 0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3, 0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7, 0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC, 0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1, 0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5, 0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA, 0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF, 0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03, 0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07, 0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C, 0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10, 0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14, 0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18, 0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C, 0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21, 0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26, 0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C, 0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31, 0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35, 0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9, 0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC, 0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781, 0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6, 0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72, 0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324, 0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF, 0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E, 0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E, 0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0, 0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993, 0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7, 0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0, 0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532, 0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7, 0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C, 0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A, 0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9, 0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327, 0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877, 0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED, 0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB, 0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1, 0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37, 0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B, 0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F, 0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43, 0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47, 0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B, 0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F, 0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53, 0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57, 0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B, 0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F, 0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63, 0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67, 0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B, 0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70, 0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74, 0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79, 0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D, 0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81, 0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85, 0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89, 0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D, 0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91, 0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95, 0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065, 0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10, 0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5, 0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F, 0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956, 0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D, 0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126, 0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47, 0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405, 0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A, 0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34, 0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175, 0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96, 0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8, 0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB, 0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377, 0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3, 0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9, 0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB, 0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE, 0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA, 0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526, 0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773, 0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC, 0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B, 0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F, 0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3, 0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8, 0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC, 0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1, 0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5, 0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9, 0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD, 0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1, 0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5, 0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9, 0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD, 0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1, 0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5, 0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9, 0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD, 0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1, 0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5, 0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9, 0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED, 0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1, 0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5, 0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9, 0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346, 0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676, 0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE, 0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66, 0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883, 0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9, 0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0, 0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76, 0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45, 0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9, 0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205, 0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0, 0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45, 0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480, 0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A, 0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177, 0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1, 0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267, 0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026, 0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485, 0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014, 0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0, 0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7, 0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB, 0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF, 0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03, 0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07, 0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B, 0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F, 0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13, 0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17, 0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B, 0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F, 0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23, 0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27, 0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B, 0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F, 0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33, 0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37, 0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C, 0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40, 0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45, 0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A, 0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E, 0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52, 0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56, 0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A, 0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA, 0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F, 0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF, 0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF, 0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8, 0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7, 0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297, 0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7, 0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB, 0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897, 0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF, 0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2, 0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6, 0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A, 0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0, 0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF, 0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177, 0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE, 0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757, 0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD, 0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2, 0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7, 0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF, 0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41, 0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60, 0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64, 0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68, 0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C, 0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70, 0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74, 0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78, 0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C, 0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80, 0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85, 0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89, 0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D, 0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91, 0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95, 0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99, 0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E, 0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC, 0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9, 0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37, 0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D, 0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41, 0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48, 0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C, 0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52, 0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83, 0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0, 0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614, 0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721, 0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1, 0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A, 0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611, 0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD, 0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2, 0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC, 0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A, 0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001, 0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9, 0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7, 0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F, 0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B, 0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E, 0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281, 0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB, 0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC, 0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354, 0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389, 0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229, 0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56, 0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D, 0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64, 0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B, 0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70, 0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77, 0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C, 0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82, 0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86, 0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B, 0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91, 0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96, 0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B, 0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3, 0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9, 0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD, 0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4, 0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA, 0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2, 0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7, 0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD, 0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2, 0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9, 0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD, 0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2, 0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6, 0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9, 0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570, 0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18, 0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B, 0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9, 0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24, 0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE, 0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA, 0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD, 0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563, 0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2, 0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433, 0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34, 0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB, 0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2, 0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3, 0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075, 0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6, 0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4, 0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218, 0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D, 0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C, 0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8, 0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED, 0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5, 0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9, 0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF, 0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009, 0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011, 0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D, 0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023, 0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D, 0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032, 0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C, 0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044, 0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049, 0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051, 0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057, 0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D, 0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061, 0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065, 0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B, 0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F, 0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074, 0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078, 0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C, 0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2, 0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402, 0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6, 0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089, 0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81, 0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF, 0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984, 0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74, 0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5, 0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651, 0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4, 0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A, 0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0, 0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26, 0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA, 0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B, 0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8, 0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC, 0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801, 0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B, 0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6, 0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792, 0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513, 0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E, 0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088, 0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F, 0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094, 0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E, 0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8, 0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5, 0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB, 0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9, 0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0, 0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4, 0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0, 0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE, 0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB, 0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101, 0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107, 0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115, 0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C, 0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121, 0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125, 0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129, 0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E, 0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135, 0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B, 0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29, 0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13, 0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305, 0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6, 0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D, 0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB, 0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709, 0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92, 0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627, 0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8, 0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499, 0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B, 0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A, 0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C, 0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5, 0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42, 0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195, 0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05, 0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784, 0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99, 0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11, 0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF, 0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23, 0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C, 0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142, 0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147, 0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F, 0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158, 0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E, 0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163, 0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A, 0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172, 0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177, 0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184, 0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189, 0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E, 0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194, 0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199, 0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0, 0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5, 0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC, 0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0, 0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5, 0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9, 0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF, 0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8, 0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE, 0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2, 0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21, 0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54, 0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8, 0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE, 0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0, 0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6, 0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55, 0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE, 0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF, 0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3, 0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43, 0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357, 0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320, 0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6, 0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9, 0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A, 0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60, 0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA, 0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE, 0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18, 0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F, 0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A, 0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0, 0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4, 0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8, 0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC, 0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0, 0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5, 0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB, 0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1, 0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7, 0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD, 0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208, 0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E, 0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215, 0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219, 0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224, 0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229, 0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C, 0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241, 0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246, 0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D, 0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252, 0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256, 0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C, 0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261, 0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265, 0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7, 0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE, 0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C, 0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012, 0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F, 0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA, 0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4, 0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4, 0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15, 0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392, 0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E, 0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0, 0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB, 0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A, 0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228, 0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1, 0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4, 0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69, 0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830, 0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D, 0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7, 0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367, 0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739, 0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435, 0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C, 0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276, 0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C, 0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285, 0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C, 0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295, 0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E, 0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7, 0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA, 0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0, 0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6, 0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9, 0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7, 0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC, 0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2, 0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8, 0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE, 0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B, 0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313, 0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D, 0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321, 0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325, 0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E, 0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B, 0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2, 0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB, 0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F, 0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02, 0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5, 0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1, 0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9, 0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6, 0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC, 0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44, 0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251, 0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461, 0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734, 0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31, 0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A, 0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03, 0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F, 0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67, 0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50, 0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91, 0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01, 0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668, 0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D, 0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E, 0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344, 0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B, 0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353, 0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358, 0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370, 0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374, 0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A, 0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381, 0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387, 0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C, 0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391, 0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397, 0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F, 0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4, 0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC, 0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5, 0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2, 0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8, 0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE, 0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3, 0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA, 0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3, 0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8, 0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070, 0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E, 0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E, 0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4, 0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C, 0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811, 0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA, 0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899, 0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47, 0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865, 0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7, 0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED, 0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304, 0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6, 0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434, 0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD, 0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B, 0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05, 0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5, 0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C, 0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1, 0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B, 0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6, 0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71, 0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3, 0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7, 0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE, 0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405, 0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A, 0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414, 0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419, 0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F, 0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423, 0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C, 0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430, 0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435, 0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A, 0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440, 0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444, 0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449, 0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D, 0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452, 0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456, 0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F, 0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465, 0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A, 0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472, 0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B, 0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B, 0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7, 0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168, 0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238, 0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638, 0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E, 0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136, 0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4, 0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9, 0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9, 0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA, 0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4, 0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254, 0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338, 0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194, 0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197, 0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339, 0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982, 0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165, 0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A, 0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6, 0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12, 0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E, 0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D, 0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481, 0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486, 0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490, 0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494, 0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A, 0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F, 0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4, 0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8, 0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC, 0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1, 0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7, 0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0, 0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6, 0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC, 0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4, 0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9, 0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE, 0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7, 0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB, 0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1, 0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5, 0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9, 0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE, 0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E, 0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27, 0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2, 0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE, 0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740, 0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB, 0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652, 0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71, 0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA, 0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3, 0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E, 0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F, 0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3, 0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7, 0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11, 0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962, 0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D, 0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151, 0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837, 0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB, 0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E, 0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A, 0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0, 0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347, 0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505, 0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509, 0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E, 0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514, 0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519, 0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E, 0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524, 0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528, 0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E, 0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532, 0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536, 0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541, 0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546, 0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D, 0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551, 0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555, 0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B, 0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560, 0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565, 0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A, 0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E, 0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573, 0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578, 0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580, 0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269, 0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931, 0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7, 0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3, 0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF, 0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2, 0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76, 0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB, 0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED, 0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F, 0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5, 0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F, 0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6, 0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996, 0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E, 0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C, 0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292, 0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1, 0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70, 0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9, 0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20, 0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811, 0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885, 0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582, 0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589, 0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D, 0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592, 0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596, 0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A, 0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0, 0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5, 0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB, 0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2, 0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6, 0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC, 0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0, 0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5, 0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA, 0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE, 0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6, 0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA, 0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF, 0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3, 0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8, 0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED, 0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1, 0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5, 0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055, 0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870, 0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4, 0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01, 0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E, 0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4, 0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF, 0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1, 0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086, 0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A, 0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E, 0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001, 0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C, 0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF, 0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F, 0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF, 0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178, 0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B, 0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E, 0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7, 0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B, 0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29, 0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240, 0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979, 0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC, 0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601, 0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606, 0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A, 0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E, 0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613, 0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618, 0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C, 0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620, 0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624, 0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A, 0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E, 0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632, 0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636, 0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B, 0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640, 0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644, 0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648, 0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C, 0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656, 0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B, 0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660, 0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665, 0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669, 0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B, 0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC, 0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A, 0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A, 0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B, 0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D, 0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892, 0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD, 0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802, 0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6, 0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F, 0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4, 0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003, 0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957, 0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC, 0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22, 0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44, 0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F, 0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49, 0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530, 0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146, 0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A, 0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16, 0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D, 0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673, 0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677, 0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685, 0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689, 0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691, 0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697, 0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B, 0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1, 0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB, 0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3, 0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB, 0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF, 0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5, 0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2, 0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7, 0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0, 0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5, 0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA, 0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5, 0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB, 0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701, 0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B, 0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710, 0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40, 0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD, 0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850, 0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC, 0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345, 0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077, 0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8, 0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92, 0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F, 0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2, 0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715, 0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F, 0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131, 0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C, 0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E, 0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C, 0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A, 0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E, 0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7, 0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A, 0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49, 0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B, 0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80, 0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984, 0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D, 0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726, 0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B, 0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730, 0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736, 0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C, 0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742, 0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746, 0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F, 0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754, 0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A, 0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E, 0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766, 0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A, 0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F, 0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775, 0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A, 0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784, 0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A, 0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790, 0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795, 0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A, 0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E, 0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3, 0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371, 0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4, 0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D, 0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4, 0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC, 0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F, 0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D, 0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170, 0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A, 0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B, 0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1, 0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717, 0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1, 0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB, 0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61, 0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C, 0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB, 0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348, 0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E, 0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269, 0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF, 0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F, 0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B, 0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5, 0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA, 0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2, 0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8, 0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE, 0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3, 0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8, 0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE, 0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5, 0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9, 0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE, 0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3, 0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8, 0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED, 0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2, 0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6, 0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB, 0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800, 0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805, 0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809, 0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E, 0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812, 0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819, 0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E, 0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00, 0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D, 0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF, 0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84, 0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3, 0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB, 0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E, 0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96, 0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED, 0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413, 0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9, 0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24, 0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E, 0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669, 0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A, 0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677, 0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2, 0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944, 0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965, 0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB, 0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF, 0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D, 0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3, 0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6, 0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826, 0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A, 0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E, 0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833, 0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837, 0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D, 0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842, 0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848, 0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E, 0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852, 0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858, 0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D, 0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866, 0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F, 0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875, 0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A, 0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883, 0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A, 0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890, 0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895, 0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A, 0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F, 0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5, 0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9, 0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821, 0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548, 0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E, 0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A, 0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10, 0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9, 0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22, 0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C, 0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB, 0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F, 0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174, 0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2, 0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F, 0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6, 0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4, 0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E, 0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0, 0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C, 0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B, 0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157, 0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C, 0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA, 0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3, 0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC, 0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2, 0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6, 0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB, 0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0, 0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8, 0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD, 0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3, 0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB, 0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0, 0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9, 0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED, 0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5, 0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB, 0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901, 0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906, 0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B, 0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F, 0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916, 0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D, 0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922, 0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927, 0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D, 0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932, 0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009, 0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774, 0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA, 0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA, 0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F, 0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD, 0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B, 0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440, 0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C, 0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5, 0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109, 0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9, 0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712, 0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C, 0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944, 0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14, 0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C, 0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66, 0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C, 0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7, 0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1, 0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27, 0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837, 0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996, 0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A, 0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E, 0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943, 0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948, 0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C, 0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950, 0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954, 0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958, 0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C, 0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962, 0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967, 0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B, 0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F, 0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973, 0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977, 0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C, 0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982, 0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988, 0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C, 0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990, 0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994, 0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998, 0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C, 0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0, 0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065, 0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC, 0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000, 0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237, 0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875, 0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3, 0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00, 0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1, 0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890, 0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA, 0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C, 0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681, 0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3, 0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613, 0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79, 0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB, 0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5, 0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2, 0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1, 0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE, 0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7, 0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F, 0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E, 0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2, 0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6, 0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA, 0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE, 0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2, 0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6, 0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA, 0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE, 0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD, 0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7, 0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD, 0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2, 0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9, 0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE, 0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4, 0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8, 0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC, 0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01, 0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05, 0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A, 0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E, 0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12, 0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16, 0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A, 0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370, 0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70, 0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424, 0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE, 0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896, 0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5, 0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8, 0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F, 0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F, 0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18, 0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531, 0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9, 0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB, 0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1, 0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4, 0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E, 0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE, 0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D, 0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31, 0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9, 0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389, 0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401, 0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1, 0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2, 0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20, 0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24, 0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28, 0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C, 0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30, 0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34, 0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38, 0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C, 0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41, 0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45, 0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A, 0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E, 0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52, 0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56, 0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A, 0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E, 0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62, 0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66, 0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A, 0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E, 0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72, 0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76, 0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B, 0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F, 0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5, 0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33, 0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3, 0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95, 0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F, 0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1, 0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0, 0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5, 0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6, 0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7, 0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0, 0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5, 0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742, 0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0, 0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1, 0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43, 0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF, 0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9, 0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A, 0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5, 0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD, 0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E, 0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3, 0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81, 0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85, 0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B, 0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F, 0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94, 0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98, 0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C, 0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0, 0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4, 0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8, 0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC, 0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0, 0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4, 0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8, 0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC, 0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0, 0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4, 0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8, 0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC, 0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0, 0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4, 0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8, 0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC, 0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0, 0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1, 0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8, 0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8, 0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84, 0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1, 0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF, 0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55, 0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218, 0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F, 0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20, 0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08, 0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0, 0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D, 0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167, 0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC, 0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0, 0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517, 0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F, 0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB, 0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795, 0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F, 0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323, 0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89, 0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63, 0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6, 0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA, 0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE, 0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2, 0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6, 0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA, 0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE, 0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02, 0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06, 0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B, 0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F, 0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13, 0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17, 0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B, 0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F, 0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23, 0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28, 0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C, 0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30, 0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34, 0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38, 0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C, 0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40, 0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44, 0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1, 0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F, 0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2, 0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7, 0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96, 0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740, 0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA, 0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A, 0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E, 0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A, 0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099, 0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92, 0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F, 0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF, 0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F, 0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC, 0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A, 0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C, 0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB, 0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB, 0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E, 0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B, 0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0, 0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46, 0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A, 0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E, 0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52, 0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56, 0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A, 0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E, 0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62, 0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67, 0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B, 0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70, 0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74, 0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78, 0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C, 0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80, 0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84, 0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88, 0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C, 0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90, 0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94, 0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98, 0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C, 0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC, 0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0, 0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F, 0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293, 0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816, 0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6, 0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986, 0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E, 0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760, 0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349, 0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422, 0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740, 0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8, 0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4, 0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D, 0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D, 0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A, 0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5, 0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD, 0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF, 0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4, 0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189, 0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075, 0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE, 0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7, 0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B, 0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F, 0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44, 0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B, 0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50, 0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54, 0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59, 0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E, 0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64, 0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68, 0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E, 0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72, 0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77, 0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E, 0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83, 0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88, 0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F, 0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93, 0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99, 0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D, 0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1, 0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5, 0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9, 0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD, 0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10, 0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98, 0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669, 0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315, 0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E, 0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997, 0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36, 0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69, 0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C, 0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D, 0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765, 0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326, 0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366, 0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E, 0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240, 0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C, 0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281, 0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54, 0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2, 0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE, 0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64, 0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09, 0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538, 0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF, 0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3, 0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7, 0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB, 0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF, 0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3, 0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7, 0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB, 0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF, 0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3, 0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7, 0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB, 0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF, 0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3, 0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7, 0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB, 0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF, 0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3, 0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7, 0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB, 0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF, 0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03, 0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07, 0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B, 0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57, 0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74, 0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F, 0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C, 0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8, 0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3, 0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8, 0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C, 0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE, 0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028, 0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048, 0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5, 0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6, 0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6, 0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD, 0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE, 0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E, 0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181, 0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07, 0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155, 0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E, 0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2, 0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8, 0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC, 0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11, 0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15, 0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19, 0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20, 0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F, 0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A, 0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71, 0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A, 0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E, 0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83, 0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89, 0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F, 0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95, 0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99, 0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D, 0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2, 0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7, 0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB, 0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF, 0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7, 0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0, 0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7, 0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD, 0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4, 0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5, 0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA, 0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2, 0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE, 0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6, 0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF, 0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9, 0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6, 0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00, 0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C, 0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14, 0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B, 0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20, 0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A, 0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32, 0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369, 0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621, 0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C, 0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F, 0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674, 0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0, 0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099, 0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3, 0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8, 0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1, 0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7, 0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0, 0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6, 0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00, 0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04, 0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B, 0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11, 0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16, 0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A, 0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21, 0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27, 0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30, 0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36, 0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C, 0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45, 0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E, 0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54, 0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58, 0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D, 0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61, 0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65, 0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B, 0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0, 0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0, 0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6, 0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB, 0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104, 0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131, 0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146, 0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC, 0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0, 0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE, 0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC, 0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A, 0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1, 0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1, 0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733, 0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C, 0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785, 0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B, 0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773, 0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2, 0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793, 0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA, 0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4, 0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD, 0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78, 0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D, 0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83, 0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89, 0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D, 0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93, 0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98, 0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D, 0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2, 0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6, 0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA, 0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1, 0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6, 0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB, 0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF, 0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3, 0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7, 0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB, 0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0, 0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4, 0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8, 0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC, 0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0, 0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4, 0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED, 0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844, 0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881, 0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8, 0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D, 0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8, 0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297, 0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE, 0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3, 0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB, 0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4, 0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4, 0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309, 0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307, 0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8, 0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311, 0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315, 0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351, 0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392, 0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B, 0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347, 0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317, 0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333, 0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6, 0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA, 0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE, 0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2, 0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6, 0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA, 0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE, 0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02, 0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06, 0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A, 0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E, 0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12, 0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16, 0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A, 0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E, 0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22, 0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26, 0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A, 0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E, 0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32, 0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36, 0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A, 0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E, 0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42, 0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B, 0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D, 0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3, 0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393, 0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6, 0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B, 0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA, 0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5, 0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B, 0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C, 0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4, 0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8, 0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0, 0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C, 0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473, 0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489, 0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469, 0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431, 0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0, 0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA, 0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1, 0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5, 0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538, 0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A, 0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48, 0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C, 0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50, 0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54, 0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58, 0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C, 0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60, 0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64, 0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C, 0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1, 0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6, 0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD, 0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3, 0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8, 0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF, 0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9, 0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD, 0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7, 0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3, 0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1, 0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6, 0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE, 0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C, 0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018, 0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC, 0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564, 0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543, 0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8, 0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE, 0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7, 0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC, 0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629, 0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08, 0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955, 0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22, 0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C, 0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA, 0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322, 0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343, 0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A, 0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC, 0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC, 0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF, 0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452, 0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441, 0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C, 0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484, 0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C, 0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027, 0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B, 0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032, 0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039, 0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040, 0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048, 0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C, 0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056, 0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D, 0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061, 0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069, 0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F, 0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073, 0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079, 0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E, 0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086, 0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C, 0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090, 0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098, 0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F, 0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7, 0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD, 0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD, 0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7, 0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0, 0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2, 0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B, 0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F, 0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8, 0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406, 0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454, 0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457, 0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482, 0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464, 0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476, 0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD, 0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7, 0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472, 0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF, 0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC, 0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD, 0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7, 0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3, 0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511, 0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F, 0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541, 0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C, 0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8, 0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD, 0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6, 0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE, 0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4, 0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC, 0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2, 0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7, 0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC, 0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103, 0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108, 0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C, 0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110, 0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114, 0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118, 0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D, 0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124, 0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128, 0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C, 0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132, 0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136, 0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B, 0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F, 0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144, 0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576, 0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C, 0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1, 0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F, 0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B, 0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594, 0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9, 0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC, 0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4, 0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3, 0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5, 0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608, 0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623, 0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D, 0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C, 0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C, 0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664, 0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C, 0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4, 0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5, 0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704, 0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F, 0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31, 0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147, 0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154, 0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159, 0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160, 0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B, 0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B, 0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182, 0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188, 0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193, 0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197, 0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D, 0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1, 0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7, 0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC, 0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3, 0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9, 0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE, 0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2, 0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6, 0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2, 0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6, 0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA, 0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF, 0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3, 0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44, 0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61, 0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90, 0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99, 0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5, 0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB, 0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7, 0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB, 0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27, 0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E, 0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E, 0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B, 0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B, 0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82, 0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7, 0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82, 0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95, 0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD, 0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61, 0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7, 0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE, 0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF, 0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7, 0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA, 0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9, 0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED, 0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1, 0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5, 0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9, 0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD, 0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201, 0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205, 0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209, 0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D, 0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211, 0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215, 0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219, 0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D, 0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221, 0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225, 0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229, 0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D, 0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231, 0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235, 0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239, 0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D, 0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241, 0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245, 0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321, 0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315, 0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C, 0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D, 0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F, 0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7, 0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967, 0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B, 0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D, 0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A, 0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993, 0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91, 0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0, 0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3, 0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB, 0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4, 0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003, 0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4, 0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA, 0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035, 0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D, 0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F, 0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B, 0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247, 0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B, 0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F, 0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253, 0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257, 0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B, 0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F, 0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263, 0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267, 0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B, 0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F, 0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273, 0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278, 0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C, 0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280, 0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284, 0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288, 0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C, 0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291, 0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295, 0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299, 0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D, 0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1, 0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5, 0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D, 0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D, 0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B, 0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD, 0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4, 0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123, 0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B, 0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194, 0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5, 0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB, 0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6, 0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604, 0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B, 0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612, 0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619, 0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215, 0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A, 0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94, 0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74, 0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0, 0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8, 0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0, 0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE, 0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE, 0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB, 0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0, 0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4, 0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8, 0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC, 0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0, 0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4, 0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9, 0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD, 0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1, 0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5, 0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9, 0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD, 0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1, 0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5, 0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9, 0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED, 0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1, 0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5, 0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9, 0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD, 0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301, 0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305, 0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309, 0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43, 0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19, 0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E, 0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52, 0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F, 0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93, 0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C, 0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5, 0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0, 0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9, 0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE, 0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B, 0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53, 0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44, 0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0, 0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7, 0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7, 0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2, 0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47, 0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F, 0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A, 0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D, 0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C, 0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B, 0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F, 0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313, 0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317, 0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B, 0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F, 0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323, 0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327, 0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B, 0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F, 0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333, 0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337, 0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B, 0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340, 0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344, 0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348, 0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C, 0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350, 0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354, 0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358, 0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C, 0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360, 0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364, 0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368, 0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7, 0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1, 0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF, 0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039, 0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80, 0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5, 0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434, 0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0, 0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3, 0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4, 0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8, 0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026, 0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021, 0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F, 0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050, 0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B, 0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082, 0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50, 0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B, 0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71, 0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A, 0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C, 0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983, 0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3, 0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F, 0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373, 0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377, 0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B, 0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F, 0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383, 0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387, 0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B, 0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390, 0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394, 0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398, 0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C, 0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0, 0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4, 0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8, 0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC, 0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0, 0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4, 0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8, 0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC, 0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0, 0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4, 0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8, 0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD, 0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E, 0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF, 0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06, 0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8, 0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32, 0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13, 0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55, 0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC, 0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A, 0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2, 0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3, 0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8, 0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16, 0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15, 0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73, 0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75, 0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F, 0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85, 0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92, 0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B, 0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0, 0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7, 0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5, 0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF, 0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3, 0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8, 0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC, 0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0, 0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4, 0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8, 0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC, 0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0, 0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4, 0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8, 0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC, 0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400, 0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404, 0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408, 0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C, 0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410, 0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414, 0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418, 0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C, 0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420, 0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424, 0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428, 0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C, 0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0, 0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2, 0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0, 0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0, 0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE, 0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D, 0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE, 0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07, 0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F, 0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19, 0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21, 0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25, 0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B, 0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30, 0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35, 0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E, 0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE, 0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2, 0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0, 0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9, 0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7, 0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F, 0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425, 0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C, 0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432, 0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436, 0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A, 0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F, 0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443, 0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447, 0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B, 0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F, 0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453, 0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457, 0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B, 0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F, 0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463, 0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467, 0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C, 0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470, 0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474, 0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478, 0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C, 0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480, 0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484, 0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7, 0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA, 0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520, 0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C, 0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477, 0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E, 0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B, 0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490, 0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA, 0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753, 0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5, 0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798, 0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E, 0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C, 0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A, 0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9, 0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD, 0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2, 0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832, 0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E, 0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883, 0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841, 0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A, 0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F, 0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B, 0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F, 0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533, 0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B, 0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E, 0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578, 0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C, 0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581, 0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585, 0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589, 0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D, 0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591, 0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595, 0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599, 0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D, 0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1, 0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5, 0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9, 0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD, 0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1, 0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5, 0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9, 0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD, 0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1, 0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5, 0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9, 0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0, 0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3, 0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960, 0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B, 0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934, 0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE, 0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979, 0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB, 0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1, 0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0, 0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED, 0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2, 0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50, 0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79, 0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C, 0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97, 0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81, 0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92, 0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B, 0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D, 0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75, 0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79, 0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81, 0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B, 0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF, 0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3, 0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7, 0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB, 0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF, 0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3, 0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7, 0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613, 0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620, 0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626, 0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B, 0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630, 0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A, 0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A, 0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652, 0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658, 0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D, 0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665, 0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E, 0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673, 0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B, 0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F, 0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683, 0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A, 0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98, 0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217, 0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221, 0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7, 0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F, 0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE, 0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619, 0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600, 0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634, 0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006, 0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F, 0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677, 0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D, 0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6, 0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36, 0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45, 0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47, 0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7, 0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE, 0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E, 0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F, 0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B, 0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308, 0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E, 0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695, 0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D, 0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1, 0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5, 0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA, 0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE, 0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4, 0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA, 0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3, 0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0, 0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6, 0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA, 0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE, 0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3, 0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7, 0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE, 0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4, 0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB, 0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702, 0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B, 0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712, 0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718, 0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D, 0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8, 0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD, 0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07, 0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18, 0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29, 0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535, 0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252, 0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216, 0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC, 0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB, 0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7, 0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB, 0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD, 0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB, 0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D, 0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715, 0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E, 0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148, 0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159, 0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169, 0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167, 0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182, 0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA, 0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB, 0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724, 0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728, 0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E, 0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734, 0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A, 0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F, 0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743, 0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747, 0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B, 0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F, 0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755, 0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C, 0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764, 0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A, 0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E, 0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772, 0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779, 0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E, 0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782, 0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787, 0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C, 0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793, 0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799, 0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D, 0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37, 0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59, 0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5, 0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40, 0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51, 0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4, 0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2, 0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096, 0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7, 0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA, 0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F, 0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168, 0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178, 0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5, 0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4, 0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228, 0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9, 0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248, 0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946, 0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953, 0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960, 0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985, 0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3, 0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F, 0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5, 0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9, 0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0, 0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6, 0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA, 0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE, 0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2, 0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6, 0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA, 0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE, 0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2, 0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6, 0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA, 0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE, 0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2, 0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8, 0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1, 0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8, 0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC, 0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800, 0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804, 0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808, 0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C, 0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D, 0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059, 0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D, 0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB, 0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F, 0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6, 0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817, 0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D, 0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A, 0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825, 0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E, 0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826, 0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A, 0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887, 0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2, 0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9, 0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905, 0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E, 0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB, 0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D, 0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A, 0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726, 0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751, 0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768, 0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812, 0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816, 0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A, 0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E, 0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822, 0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826, 0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A, 0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E, 0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832, 0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836, 0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A, 0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E, 0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842, 0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846, 0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A, 0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E, 0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852, 0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856, 0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A, 0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E, 0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862, 0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866, 0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A, 0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E, 0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D, 0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791, 0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5, 0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E, 0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572, 0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61, 0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74, 0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E, 0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485, 0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A, 0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490, 0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A, 0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4, 0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC, 0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4, 0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9, 0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF, 0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA, 0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE, 0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5, 0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8, 0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0, 0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7, 0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870, 0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874, 0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895, 0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9, 0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD, 0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1, 0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5, 0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9, 0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD, 0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1, 0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5, 0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9, 0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD, 0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6, 0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD, 0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3, 0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9, 0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED, 0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1, 0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5, 0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9, 0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD, 0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901, 0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905, 0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB, 0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4, 0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC, 0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502, 0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A, 0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512, 0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516, 0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E, 0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B, 0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532, 0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538, 0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542, 0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546, 0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F, 0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556, 0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B, 0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561, 0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566, 0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A, 0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571, 0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7, 0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED, 0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47, 0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14, 0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B, 0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911, 0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915, 0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919, 0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D, 0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921, 0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925, 0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929, 0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D, 0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932, 0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936, 0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A, 0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E, 0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942, 0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946, 0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A, 0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E, 0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952, 0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958, 0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C, 0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960, 0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966, 0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B, 0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989, 0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF, 0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E, 0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE, 0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22, 0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B, 0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36, 0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A, 0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44, 0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49, 0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51, 0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B, 0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66, 0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A, 0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D, 0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596, 0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3, 0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4, 0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2, 0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8, 0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7, 0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF, 0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C, 0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618, 0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E, 0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D, 0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1, 0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6, 0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB, 0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF, 0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3, 0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7, 0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB, 0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF, 0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3, 0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7, 0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB, 0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF, 0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3, 0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7, 0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB, 0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF, 0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3, 0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7, 0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB, 0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF, 0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3, 0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7, 0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C, 0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D, 0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643, 0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E, 0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B, 0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78, 0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88, 0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC, 0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864, 0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F, 0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7, 0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE, 0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A, 0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0, 0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B, 0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936, 0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B, 0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC, 0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C, 0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026, 0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031, 0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046, 0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071, 0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883, 0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD, 0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01, 0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05, 0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09, 0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D, 0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11, 0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15, 0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19, 0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D, 0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21, 0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25, 0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29, 0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D, 0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31, 0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35, 0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39, 0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D, 0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41, 0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45, 0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49, 0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D, 0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51, 0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55, 0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59, 0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F, 0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E, 0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5, 0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C, 0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C, 0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B, 0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3, 0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6, 0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0, 0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9, 0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1, 0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0, 0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF, 0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707, 0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D, 0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E, 0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E, 0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729, 0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722, 0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760, 0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B, 0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764, 0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF, 0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B, 0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F, 0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63, 0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67, 0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B, 0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D, 0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99, 0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB, 0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF, 0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5, 0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE, 0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6, 0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA, 0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0, 0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6, 0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB, 0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0, 0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5, 0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA, 0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1, 0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5, 0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA, 0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF, 0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04, 0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788, 0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783, 0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5, 0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD, 0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB, 0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816, 0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B, 0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36, 0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210, 0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03, 0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B, 0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A, 0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20, 0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E, 0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45, 0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60, 0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72, 0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7, 0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8, 0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2, 0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1, 0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5, 0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE, 0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B, 0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B, 0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10, 0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15, 0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19, 0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D, 0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22, 0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27, 0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B, 0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30, 0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35, 0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39, 0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F, 0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B, 0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52, 0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57, 0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B, 0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F, 0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63, 0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67, 0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B, 0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F, 0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73, 0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77, 0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B, 0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38, 0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201, 0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844, 0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D, 0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238, 0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E, 0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F, 0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E, 0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF, 0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7, 0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C, 0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C, 0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC, 0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC, 0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7, 0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF, 0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1, 0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3, 0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE, 0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4, 0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91, 0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47, 0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E, 0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D, 0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81, 0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85, 0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89, 0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D, 0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91, 0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95, 0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99, 0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D, 0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1, 0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5, 0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9, 0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD, 0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1, 0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5, 0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9, 0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD, 0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1, 0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5, 0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9, 0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD, 0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1, 0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5, 0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9, 0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161, 0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D, 0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179, 0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D, 0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA, 0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5, 0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E, 0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59, 0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC, 0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7, 0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF, 0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7, 0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB, 0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14, 0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E, 0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40, 0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31, 0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51, 0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76, 0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85, 0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C, 0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A, 0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B, 0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC, 0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF, 0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3, 0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7, 0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB, 0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF, 0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3, 0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7, 0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB, 0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF, 0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03, 0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07, 0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B, 0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F, 0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13, 0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17, 0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B, 0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F, 0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23, 0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27, 0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B, 0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F, 0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33, 0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37, 0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B, 0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E, 0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3, 0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708, 0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D, 0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83, 0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88, 0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE, 0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC, 0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF, 0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8, 0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F, 0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82, 0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88, 0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90, 0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95, 0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F, 0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3, 0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8, 0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE, 0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3, 0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7, 0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD, 0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7, 0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D, 0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41, 0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45, 0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49, 0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D, 0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51, 0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55, 0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59, 0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D, 0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61, 0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65, 0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69, 0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D, 0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71, 0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75, 0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79, 0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E, 0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89, 0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93, 0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99, 0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF, 0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0, 0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9, 0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB, 0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD, 0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3, 0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8, 0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF, 0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791, 0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB, 0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1, 0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6, 0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0, 0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC, 0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47, 0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51, 0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955, 0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6, 0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED, 0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13, 0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE, 0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88, 0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D, 0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD, 0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9, 0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF, 0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39, 0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44, 0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6, 0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA, 0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE, 0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2, 0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6, 0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA, 0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE, 0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02, 0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06, 0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A, 0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E, 0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12, 0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16, 0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A, 0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E, 0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22, 0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26, 0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A, 0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E, 0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32, 0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36, 0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A, 0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E, 0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42, 0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46, 0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A, 0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E, 0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52, 0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56, 0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A, 0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E, 0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62, 0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66, 0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A, 0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E, 0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72, 0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76, 0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A, 0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E, 0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82, 0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86, 0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A, 0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E, 0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92, 0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96, 0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A, 0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E, 0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2, 0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6, 0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA, 0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE, 0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2, 0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6, 0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA, 0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE, 0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2, 0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6, 0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA, 0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE, 0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2, 0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6, 0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA, 0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE, 0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2, 0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6, 0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA, 0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE, 0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2, 0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6, 0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA, 0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE, 0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02, 0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06, 0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A, 0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E, 0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12, 0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16, 0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A, 0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E, 0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30, 0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40, 0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53, 0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D, 0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62, 0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72, 0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77, 0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B, 0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81, 0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86, 0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D, 0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91, 0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97, 0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B, 0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1, 0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5, 0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA, 0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE, 0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2, 0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7, 0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF, 0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3, 0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8, 0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0, 0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6, 0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE, 0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6, 0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED, 0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2, 0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6, 0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD, 0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02, 0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06, 0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A, 0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12, 0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18, 0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D, 0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23, 0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27, 0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B, 0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31, 0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35, 0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C, 0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42, 0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47, 0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B, 0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F, 0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55, 0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59, 0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D, 0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61, 0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65, 0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69, 0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D, 0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71, 0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75, 0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79, 0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D, 0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D, 0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91, 0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95, 0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C, 0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2, 0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C, 0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1, 0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F, 0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18, 0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23, 0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29, 0, 0 }; #endif #if FF_CODE_PAGE == 949 || FF_CODE_PAGE == 0 /* Korean */ static const WCHAR uni2oem949[] = { /* Unicode --> Korean pairs */ 0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7, 0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6, 0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5, 0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6, 0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA, 0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF, 0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1, 0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD, 0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5, 0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8, 0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0, 0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB, 0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0, 0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD, 0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3, 0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7, 0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB, 0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF, 0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3, 0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7, 0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3, 0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7, 0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB, 0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF, 0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3, 0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7, 0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2, 0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6, 0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB, 0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF, 0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3, 0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7, 0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB, 0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF, 0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2, 0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6, 0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB, 0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF, 0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3, 0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7, 0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB, 0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF, 0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA, 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6, 0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8, 0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC, 0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9, 0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5, 0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7, 0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD, 0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2, 0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6, 0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1, 0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5, 0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9, 0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6, 0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8, 0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1, 0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4, 0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3, 0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4, 0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD, 0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3, 0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD, 0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5, 0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED, 0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7, 0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7, 0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB, 0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF, 0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3, 0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8, 0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC, 0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0, 0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4, 0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF, 0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3, 0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7, 0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB, 0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF, 0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3, 0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD, 0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1, 0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5, 0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9, 0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD, 0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1, 0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5, 0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2, 0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7, 0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1, 0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5, 0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3, 0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9, 0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC, 0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD, 0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0, 0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2, 0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4, 0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6, 0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8, 0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA, 0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0, 0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0, 0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4, 0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0, 0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB, 0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3, 0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5, 0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF, 0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD, 0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA, 0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0, 0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC, 0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE, 0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC, 0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5, 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD, 0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1, 0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5, 0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9, 0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD, 0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1, 0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5, 0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9, 0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD, 0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1, 0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5, 0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9, 0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD, 0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1, 0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5, 0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9, 0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD, 0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1, 0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5, 0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9, 0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED, 0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1, 0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2, 0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6, 0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA, 0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE, 0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2, 0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6, 0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA, 0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE, 0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2, 0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6, 0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA, 0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE, 0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2, 0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6, 0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA, 0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE, 0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2, 0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6, 0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA, 0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE, 0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2, 0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6, 0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4, 0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8, 0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC, 0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0, 0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4, 0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8, 0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC, 0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0, 0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4, 0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8, 0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC, 0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0, 0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4, 0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8, 0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC, 0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0, 0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4, 0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8, 0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC, 0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0, 0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4, 0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8, 0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC, 0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2, 0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6, 0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA, 0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE, 0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2, 0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6, 0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA, 0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1, 0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5, 0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9, 0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD, 0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1, 0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5, 0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9, 0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE, 0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC, 0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC, 0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7, 0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6, 0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2, 0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC, 0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0, 0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4, 0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA, 0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6, 0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2, 0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1, 0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5, 0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE, 0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2, 0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3, 0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF, 0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5, 0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF, 0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9, 0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2, 0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB, 0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0, 0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA, 0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1, 0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9, 0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9, 0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA, 0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC, 0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB, 0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0, 0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6, 0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6, 0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1, 0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB, 0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5, 0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2, 0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF, 0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2, 0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE, 0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4, 0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0, 0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5, 0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1, 0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1, 0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4, 0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7, 0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC, 0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9, 0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5, 0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD, 0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0, 0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6, 0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD, 0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA, 0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5, 0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5, 0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB, 0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4, 0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF, 0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC, 0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF, 0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1, 0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8, 0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA, 0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7, 0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2, 0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6, 0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9, 0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE, 0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF, 0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8, 0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA, 0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0, 0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2, 0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2, 0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9, 0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8, 0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2, 0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1, 0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3, 0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3, 0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC, 0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA, 0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE, 0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE, 0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2, 0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC, 0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0, 0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC, 0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7, 0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF, 0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2, 0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0, 0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB, 0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5, 0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE, 0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7, 0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD, 0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC, 0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0, 0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB, 0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE, 0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1, 0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE, 0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9, 0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9, 0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1, 0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4, 0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2, 0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6, 0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8, 0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1, 0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2, 0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7, 0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4, 0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE, 0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1, 0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9, 0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4, 0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF, 0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6, 0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1, 0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF, 0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF, 0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF, 0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB, 0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED, 0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8, 0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0, 0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1, 0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2, 0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4, 0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2, 0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE, 0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6, 0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3, 0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA, 0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3, 0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE, 0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5, 0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF, 0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9, 0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1, 0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2, 0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC, 0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA, 0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA, 0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0, 0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF, 0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8, 0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9, 0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6, 0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6, 0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2, 0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA, 0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3, 0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA, 0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0, 0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7, 0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4, 0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0, 0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8, 0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9, 0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF, 0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF, 0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF, 0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4, 0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6, 0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD, 0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8, 0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE, 0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF, 0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0, 0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9, 0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5, 0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0, 0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3, 0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7, 0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF, 0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2, 0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0, 0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2, 0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8, 0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC, 0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED, 0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE, 0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB, 0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3, 0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3, 0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2, 0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA, 0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2, 0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5, 0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB, 0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5, 0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4, 0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD, 0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC, 0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE, 0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4, 0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE, 0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC, 0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1, 0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5, 0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8, 0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8, 0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC, 0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7, 0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF, 0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4, 0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8, 0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9, 0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5, 0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4, 0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE, 0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9, 0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1, 0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF, 0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6, 0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4, 0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8, 0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE, 0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8, 0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC, 0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC, 0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3, 0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE, 0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6, 0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF, 0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5, 0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF, 0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED, 0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC, 0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5, 0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF, 0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1, 0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9, 0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5, 0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB, 0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2, 0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9, 0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB, 0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC, 0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6, 0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB, 0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0, 0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4, 0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2, 0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE, 0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3, 0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6, 0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5, 0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD, 0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA, 0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA, 0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5, 0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5, 0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7, 0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB, 0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0, 0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0, 0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1, 0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6, 0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF, 0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0, 0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA, 0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1, 0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7, 0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5, 0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0, 0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9, 0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF, 0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3, 0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3, 0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE, 0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1, 0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9, 0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC, 0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6, 0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB, 0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA, 0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE, 0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9, 0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB, 0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9, 0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2, 0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8, 0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE, 0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB, 0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA, 0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8, 0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6, 0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5, 0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7, 0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1, 0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0, 0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1, 0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD, 0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF, 0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4, 0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE, 0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF, 0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD, 0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9, 0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0, 0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3, 0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5, 0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7, 0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3, 0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD, 0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC, 0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7, 0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8, 0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB, 0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1, 0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5, 0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8, 0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF, 0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1, 0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1, 0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6, 0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0, 0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9, 0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2, 0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED, 0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA, 0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3, 0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3, 0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC, 0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3, 0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0, 0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3, 0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7, 0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5, 0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9, 0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE, 0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3, 0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7, 0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6, 0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4, 0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3, 0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB, 0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2, 0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8, 0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA, 0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4, 0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8, 0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB, 0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB, 0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC, 0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4, 0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4, 0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8, 0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3, 0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6, 0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA, 0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5, 0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB, 0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC, 0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1, 0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8, 0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6, 0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7, 0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0, 0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC, 0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC, 0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0, 0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2, 0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA, 0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB, 0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9, 0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4, 0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9, 0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF, 0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7, 0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9, 0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3, 0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3, 0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1, 0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB, 0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4, 0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA, 0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8, 0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA, 0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6, 0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7, 0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE, 0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5, 0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8, 0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2, 0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA, 0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6, 0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0, 0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD, 0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA, 0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC, 0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6, 0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5, 0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4, 0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9, 0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD, 0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2, 0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2, 0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7, 0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA, 0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC, 0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7, 0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5, 0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6, 0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0, 0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9, 0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2, 0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED, 0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2, 0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA, 0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA, 0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4, 0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB, 0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA, 0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0, 0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0, 0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4, 0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1, 0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC, 0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8, 0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7, 0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9, 0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF, 0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD, 0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB, 0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4, 0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6, 0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA, 0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7, 0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5, 0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5, 0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6, 0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA, 0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6, 0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC, 0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB, 0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7, 0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2, 0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1, 0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4, 0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5, 0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD, 0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5, 0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6, 0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4, 0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE, 0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB, 0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2, 0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD, 0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC, 0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2, 0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3, 0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6, 0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF, 0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3, 0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE, 0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA, 0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1, 0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8, 0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE, 0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD, 0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2, 0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9, 0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9, 0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC, 0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE, 0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2, 0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4, 0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA, 0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6, 0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8, 0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5, 0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7, 0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5, 0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1, 0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8, 0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF, 0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4, 0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3, 0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE, 0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4, 0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9, 0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8, 0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5, 0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0, 0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC, 0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7, 0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA, 0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9, 0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4, 0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5, 0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE, 0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2, 0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE, 0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED, 0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2, 0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7, 0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE, 0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2, 0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE, 0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8, 0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1, 0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6, 0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9, 0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB, 0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC, 0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC, 0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE, 0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2, 0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD, 0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8, 0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0, 0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1, 0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD, 0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE, 0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0, 0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9, 0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA, 0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8, 0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB, 0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE, 0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1, 0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD, 0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD, 0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB, 0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6, 0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE, 0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA, 0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6, 0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9, 0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0, 0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD, 0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7, 0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5, 0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB, 0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF, 0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9, 0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC, 0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD, 0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1, 0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3, 0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE, 0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7, 0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7, 0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2, 0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0, 0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC, 0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2, 0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4, 0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE, 0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB, 0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD, 0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9, 0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC, 0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7, 0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3, 0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9, 0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6, 0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA, 0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1, 0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7, 0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF, 0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5, 0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3, 0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4, 0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC, 0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC, 0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2, 0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE, 0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6, 0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8, 0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2, 0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB, 0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1, 0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4, 0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD, 0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6, 0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8, 0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD, 0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD, 0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4, 0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9, 0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE, 0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA, 0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE, 0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB, 0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5, 0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD, 0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7, 0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA, 0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9, 0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3, 0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0, 0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE, 0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6, 0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB, 0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC, 0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5, 0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1, 0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC, 0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0, 0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE, 0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3, 0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7, 0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9, 0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8, 0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7, 0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2, 0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD, 0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7, 0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7, 0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3, 0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3, 0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB, 0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3, 0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA, 0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3, 0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0, 0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5, 0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0, 0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3, 0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4, 0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA, 0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9, 0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED, 0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA, 0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3, 0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2, 0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC, 0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4, 0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC, 0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD, 0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB, 0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC, 0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD, 0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6, 0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB, 0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1, 0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0, 0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE, 0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4, 0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF, 0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2, 0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD, 0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE, 0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB, 0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD, 0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1, 0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2, 0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0, 0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9, 0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3, 0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8, 0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2, 0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7, 0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0, 0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB, 0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE, 0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA, 0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE, 0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF, 0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4, 0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4, 0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7, 0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5, 0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9, 0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4, 0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC, 0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5, 0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF, 0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE, 0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2, 0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5, 0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8, 0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA, 0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6, 0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2, 0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA, 0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2, 0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6, 0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC, 0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0, 0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1, 0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6, 0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB, 0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6, 0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC, 0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5, 0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB, 0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD, 0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC, 0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3, 0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF, 0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1, 0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD, 0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7, 0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF, 0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7, 0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD, 0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2, 0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE, 0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9, 0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA, 0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5, 0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD, 0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3, 0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB, 0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9, 0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3, 0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED, 0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8, 0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5, 0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8, 0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5, 0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4, 0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8, 0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3, 0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5, 0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE, 0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4, 0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6, 0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8, 0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE, 0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB, 0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC, 0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE, 0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6, 0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9, 0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA, 0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC, 0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA, 0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3, 0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA, 0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB, 0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA, 0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4, 0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1, 0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC, 0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE, 0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2, 0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF, 0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2, 0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4, 0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7, 0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2, 0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE, 0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA, 0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE, 0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF, 0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5, 0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA, 0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD, 0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB, 0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8, 0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9, 0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9, 0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD, 0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9, 0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF, 0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF, 0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7, 0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE, 0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9, 0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF, 0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4, 0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB, 0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6, 0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0, 0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7, 0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3, 0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC, 0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF, 0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5, 0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7, 0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF, 0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7, 0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1, 0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF, 0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5, 0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6, 0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5, 0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8, 0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8, 0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE, 0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA, 0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5, 0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5, 0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3, 0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0, 0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6, 0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA, 0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD, 0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0, 0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0, 0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3, 0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4, 0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8, 0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9, 0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5, 0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF, 0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2, 0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA, 0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE, 0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE, 0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8, 0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8, 0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8, 0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7, 0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7, 0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8, 0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7, 0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5, 0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE, 0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4, 0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD, 0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0, 0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9, 0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2, 0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC, 0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB, 0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF, 0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6, 0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8, 0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2, 0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE, 0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0, 0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD, 0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7, 0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6, 0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB, 0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1, 0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC, 0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3, 0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6, 0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD, 0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB, 0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3, 0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE, 0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC, 0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6, 0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED, 0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB, 0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6, 0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0, 0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF, 0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF, 0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE, 0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC, 0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9, 0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6, 0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4, 0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3, 0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3, 0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE, 0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4, 0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB, 0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6, 0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD, 0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0, 0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE, 0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8, 0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2, 0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9, 0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA, 0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE, 0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB, 0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF, 0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2, 0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC, 0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4, 0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA, 0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6, 0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC, 0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4, 0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD, 0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0, 0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF, 0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8, 0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD, 0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5, 0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8, 0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4, 0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA, 0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6, 0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE, 0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1, 0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB, 0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD, 0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA, 0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9, 0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0, 0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2, 0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD, 0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9, 0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1, 0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1, 0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0, 0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD, 0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF, 0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB, 0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3, 0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5, 0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3, 0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5, 0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5, 0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE, 0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE, 0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED, 0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0, 0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4, 0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9, 0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD, 0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7, 0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2, 0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8, 0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA, 0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE, 0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC, 0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5, 0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB, 0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD, 0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4, 0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE, 0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5, 0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5, 0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE, 0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9, 0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB, 0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1, 0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8, 0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2, 0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE, 0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC, 0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4, 0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE, 0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA, 0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC, 0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7, 0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB, 0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2, 0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1, 0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8, 0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE, 0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8, 0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF, 0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9, 0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC, 0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5, 0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA, 0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3, 0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE, 0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6, 0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3, 0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE, 0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4, 0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8, 0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3, 0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5, 0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9, 0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC, 0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD, 0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC, 0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0, 0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8, 0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD, 0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1, 0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED, 0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9, 0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8, 0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9, 0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3, 0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5, 0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF, 0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0, 0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6, 0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8, 0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB, 0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3, 0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8, 0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5, 0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC, 0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4, 0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4, 0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3, 0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE, 0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF, 0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC, 0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB, 0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB, 0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1, 0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9, 0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5, 0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5, 0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5, 0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE, 0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2, 0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4, 0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC, 0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3, 0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8, 0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6, 0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA, 0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE, 0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9, 0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0, 0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA, 0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE, 0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD, 0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD, 0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE, 0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE, 0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8, 0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA, 0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6, 0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7, 0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7, 0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9, 0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1, 0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD, 0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF, 0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8, 0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1, 0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1, 0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4, 0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5, 0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4, 0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6, 0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE, 0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6, 0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA, 0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0, 0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6, 0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD, 0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD, 0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4, 0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE, 0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7, 0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0, 0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD, 0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8, 0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1, 0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3, 0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC, 0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2, 0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3, 0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD, 0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD, 0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8, 0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4, 0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC, 0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED, 0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC, 0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9, 0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE, 0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2, 0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9, 0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7, 0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA, 0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5, 0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7, 0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8, 0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7, 0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2, 0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6, 0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1, 0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8, 0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8, 0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4, 0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3, 0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0, 0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5, 0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB, 0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5, 0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1, 0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD, 0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE, 0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2, 0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0, 0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE, 0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3, 0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4, 0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC, 0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6, 0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6, 0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE, 0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA, 0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3, 0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6, 0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5, 0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5, 0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9, 0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2, 0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1, 0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF, 0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD, 0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2, 0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1, 0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC, 0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE, 0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4, 0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3, 0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD, 0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7, 0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7, 0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4, 0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4, 0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA, 0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5, 0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9, 0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA, 0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF, 0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2, 0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED, 0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7, 0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8, 0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6, 0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2, 0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9, 0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3, 0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3, 0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD, 0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB, 0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6, 0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7, 0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5, 0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9, 0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF, 0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA, 0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE, 0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5, 0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9, 0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC, 0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2, 0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF, 0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD, 0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8, 0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9, 0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE, 0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0, 0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0, 0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9, 0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4, 0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2, 0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA, 0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5, 0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB, 0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7, 0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6, 0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1, 0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4, 0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8, 0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0, 0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC, 0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD, 0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE, 0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE, 0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED, 0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD, 0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB, 0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8, 0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB, 0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3, 0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA, 0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD, 0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5, 0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1, 0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6, 0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB, 0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF, 0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142, 0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4, 0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145, 0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149, 0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB, 0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF, 0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2, 0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C, 0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F, 0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152, 0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156, 0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9, 0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159, 0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163, 0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165, 0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168, 0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B, 0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F, 0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0, 0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175, 0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179, 0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182, 0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185, 0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188, 0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C, 0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190, 0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194, 0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198, 0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A, 0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8, 0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E, 0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2, 0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD, 0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4, 0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3, 0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8, 0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB, 0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE, 0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2, 0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9, 0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5, 0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9, 0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA, 0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0, 0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF, 0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3, 0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4, 0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6, 0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9, 0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC, 0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF, 0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2, 0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6, 0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC, 0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC, 0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0, 0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2, 0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0, 0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6, 0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4, 0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7, 0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB, 0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF, 0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1, 0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4, 0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6, 0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA, 0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3, 0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE, 0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244, 0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247, 0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A, 0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D, 0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251, 0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254, 0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256, 0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A, 0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262, 0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265, 0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268, 0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C, 0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1, 0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270, 0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274, 0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277, 0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A, 0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283, 0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287, 0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7, 0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D, 0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291, 0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293, 0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB, 0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296, 0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF, 0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2, 0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C, 0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0, 0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2, 0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5, 0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8, 0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC, 0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0, 0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2, 0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6, 0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9, 0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD, 0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1, 0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5, 0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC, 0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC, 0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0, 0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2, 0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5, 0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8, 0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC, 0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3, 0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1, 0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5, 0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8, 0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB, 0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE, 0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2, 0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6, 0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA, 0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE, 0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342, 0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA, 0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346, 0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A, 0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF, 0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E, 0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352, 0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355, 0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359, 0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363, 0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367, 0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B, 0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F, 0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373, 0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375, 0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5, 0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379, 0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383, 0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA, 0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386, 0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389, 0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A, 0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D, 0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F, 0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393, 0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6, 0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396, 0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399, 0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B, 0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E, 0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1, 0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5, 0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2, 0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8, 0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC, 0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE, 0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2, 0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5, 0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9, 0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD, 0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1, 0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5, 0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9, 0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD, 0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1, 0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5, 0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9, 0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD, 0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1, 0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2, 0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5, 0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8, 0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC, 0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF, 0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF, 0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3, 0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5, 0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8, 0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC, 0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442, 0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6, 0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447, 0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B, 0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E, 0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451, 0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454, 0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458, 0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB, 0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464, 0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467, 0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A, 0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E, 0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472, 0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476, 0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A, 0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484, 0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488, 0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A, 0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C, 0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F, 0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493, 0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6, 0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9, 0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499, 0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B, 0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F, 0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2, 0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6, 0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA, 0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC, 0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0, 0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2, 0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6, 0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA, 0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE, 0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2, 0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5, 0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9, 0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC, 0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF, 0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2, 0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6, 0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8, 0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB, 0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF, 0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2, 0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6, 0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA, 0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE, 0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2, 0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6, 0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA, 0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC, 0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541, 0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544, 0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD, 0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0, 0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A, 0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E, 0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551, 0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555, 0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558, 0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562, 0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566, 0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568, 0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C, 0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E, 0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571, 0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574, 0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578, 0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A, 0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583, 0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587, 0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A, 0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D, 0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590, 0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594, 0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596, 0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A, 0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E, 0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1, 0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5, 0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9, 0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD, 0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1, 0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5, 0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9, 0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB, 0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD, 0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF, 0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA, 0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD, 0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6, 0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9, 0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD, 0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1, 0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5, 0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9, 0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD, 0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1, 0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5, 0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7, 0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA, 0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED, 0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1, 0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8, 0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5, 0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9, 0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA, 0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE, 0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD, 0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643, 0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4, 0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8, 0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA, 0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648, 0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B, 0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E, 0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652, 0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1, 0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655, 0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659, 0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661, 0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664, 0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667, 0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B, 0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E, 0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671, 0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675, 0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679, 0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683, 0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687, 0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B, 0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F, 0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693, 0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697, 0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC, 0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B, 0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0, 0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0, 0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3, 0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3, 0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6, 0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8, 0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB, 0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE, 0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2, 0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD, 0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5, 0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9, 0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB, 0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE, 0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1, 0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5, 0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7, 0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9, 0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC, 0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF, 0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2, 0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6, 0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA, 0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE, 0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2, 0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6, 0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8, 0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB, 0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED, 0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1, 0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2, 0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5, 0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5, 0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA, 0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD, 0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742, 0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746, 0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A, 0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D, 0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751, 0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755, 0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759, 0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763, 0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767, 0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B, 0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F, 0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773, 0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776, 0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779, 0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782, 0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786, 0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1, 0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B, 0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F, 0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791, 0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794, 0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797, 0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B, 0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7, 0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0, 0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4, 0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6, 0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC, 0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB, 0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF, 0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0, 0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3, 0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7, 0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA, 0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE, 0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2, 0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6, 0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA, 0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD, 0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1, 0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4, 0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8, 0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC, 0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0, 0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4, 0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8, 0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC, 0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF, 0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2, 0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5, 0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9, 0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB, 0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841, 0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845, 0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847, 0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B, 0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E, 0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852, 0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854, 0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857, 0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861, 0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863, 0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866, 0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867, 0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B, 0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8, 0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E, 0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871, 0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874, 0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877, 0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A, 0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884, 0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888, 0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C, 0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890, 0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892, 0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895, 0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897, 0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B, 0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6, 0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F, 0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2, 0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3, 0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD, 0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1, 0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2, 0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5, 0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9, 0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA, 0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE, 0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1, 0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4, 0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8, 0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1, 0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB, 0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF, 0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2, 0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6, 0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA, 0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE, 0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2, 0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6, 0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA, 0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE, 0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2, 0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6, 0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA, 0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE, 0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2, 0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6, 0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7, 0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9, 0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC, 0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE, 0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1, 0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3, 0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946, 0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948, 0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B, 0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E, 0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952, 0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB, 0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955, 0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959, 0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962, 0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965, 0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968, 0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C, 0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970, 0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972, 0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976, 0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979, 0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982, 0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986, 0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A, 0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E, 0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992, 0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996, 0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998, 0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8, 0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C, 0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F, 0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE, 0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0, 0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5, 0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8, 0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB, 0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE, 0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2, 0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6, 0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA, 0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE, 0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1, 0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5, 0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9, 0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD, 0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1, 0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4, 0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8, 0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB, 0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE, 0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1, 0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5, 0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC, 0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA, 0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE, 0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1, 0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5, 0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9, 0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD, 0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43, 0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47, 0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B, 0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D, 0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50, 0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53, 0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57, 0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4, 0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61, 0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65, 0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68, 0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C, 0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70, 0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74, 0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78, 0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81, 0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85, 0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88, 0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C, 0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90, 0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94, 0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98, 0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B, 0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F, 0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2, 0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5, 0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8, 0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC, 0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE, 0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1, 0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5, 0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8, 0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB, 0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE, 0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2, 0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5, 0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8, 0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC, 0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE, 0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8, 0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2, 0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6, 0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED, 0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA, 0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE, 0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1, 0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5, 0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9, 0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED, 0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1, 0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5, 0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9, 0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB, 0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3, 0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42, 0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46, 0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7, 0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48, 0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C, 0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E, 0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51, 0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54, 0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58, 0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3, 0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61, 0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6, 0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66, 0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69, 0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C, 0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70, 0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD, 0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73, 0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77, 0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81, 0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85, 0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89, 0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D, 0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91, 0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95, 0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99, 0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D, 0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1, 0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5, 0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9, 0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD, 0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1, 0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5, 0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7, 0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA, 0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5, 0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF, 0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8, 0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2, 0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB, 0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7, 0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA, 0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD, 0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1, 0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2, 0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4, 0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8, 0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB, 0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF, 0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3, 0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7, 0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB, 0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE, 0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2, 0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6, 0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA, 0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE, 0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44, 0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48, 0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C, 0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50, 0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52, 0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55, 0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58, 0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62, 0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66, 0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69, 0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D, 0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70, 0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74, 0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77, 0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81, 0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85, 0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89, 0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D, 0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90, 0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94, 0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98, 0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C, 0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0, 0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4, 0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8, 0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB, 0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE, 0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2, 0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6, 0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA, 0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE, 0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2, 0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6, 0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA, 0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE, 0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2, 0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6, 0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA, 0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE, 0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0, 0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3, 0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6, 0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5, 0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC, 0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF, 0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3, 0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7, 0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB, 0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41, 0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45, 0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49, 0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D, 0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51, 0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54, 0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58, 0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62, 0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66, 0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A, 0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E, 0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72, 0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75, 0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78, 0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81, 0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85, 0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87, 0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A, 0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E, 0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92, 0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96, 0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A, 0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E, 0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2, 0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6, 0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA, 0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC, 0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2, 0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1, 0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5, 0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6, 0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA, 0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE, 0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1, 0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4, 0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7, 0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB, 0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD, 0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1, 0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5, 0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8, 0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB, 0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE, 0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2, 0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1, 0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6, 0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA, 0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC, 0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF, 0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2, 0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6, 0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9, 0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8, 0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE, 0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC, 0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41, 0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44, 0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48, 0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7, 0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B, 0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F, 0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51, 0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54, 0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58, 0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62, 0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD, 0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68, 0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C, 0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70, 0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74, 0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78, 0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82, 0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86, 0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A, 0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E, 0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90, 0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93, 0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96, 0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A, 0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5, 0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D, 0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8, 0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2, 0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5, 0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8, 0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC, 0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF, 0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0, 0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4, 0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6, 0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9, 0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC, 0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0, 0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7, 0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3, 0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7, 0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA, 0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD, 0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1, 0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5, 0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD, 0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB, 0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF, 0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1, 0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4, 0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7, 0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB, 0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4, 0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF, 0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3, 0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6, 0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9, 0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD, 0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43, 0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47, 0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A, 0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E, 0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52, 0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56, 0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A, 0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64, 0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68, 0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B, 0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F, 0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72, 0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75, 0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78, 0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82, 0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF, 0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86, 0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A, 0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D, 0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90, 0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93, 0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97, 0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5, 0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C, 0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0, 0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2, 0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5, 0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8, 0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC, 0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED, 0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0, 0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4, 0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7, 0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB, 0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF, 0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3, 0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7, 0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA, 0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE, 0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1, 0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5, 0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9, 0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD, 0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1, 0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5, 0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9, 0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB, 0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE, 0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1, 0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5, 0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7, 0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA, 0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE, 0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042, 0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045, 0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048, 0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C, 0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1, 0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050, 0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054, 0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056, 0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059, 0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062, 0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066, 0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9, 0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069, 0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B, 0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F, 0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073, 0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077, 0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081, 0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085, 0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089, 0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D, 0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F, 0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092, 0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095, 0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099, 0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4, 0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D, 0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1, 0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3, 0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA, 0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5, 0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9, 0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0, 0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC, 0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4, 0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0, 0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3, 0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6, 0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA, 0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB, 0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC, 0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0, 0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2, 0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6, 0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9, 0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD, 0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1, 0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4, 0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8, 0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC, 0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0, 0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4, 0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8, 0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC, 0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0, 0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4, 0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6, 0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9, 0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB, 0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141, 0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA, 0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144, 0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD, 0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149, 0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C, 0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F, 0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153, 0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4, 0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156, 0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A, 0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162, 0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165, 0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168, 0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C, 0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB, 0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE, 0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174, 0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177, 0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181, 0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185, 0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189, 0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D, 0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191, 0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195, 0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2, 0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199, 0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B, 0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F, 0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8, 0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3, 0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7, 0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA, 0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD, 0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1, 0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5, 0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9, 0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB, 0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF, 0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3, 0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7, 0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB, 0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF, 0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3, 0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7, 0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB, 0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE, 0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1, 0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4, 0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8, 0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4, 0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED, 0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1, 0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4, 0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7, 0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA, 0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE, 0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA, 0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246, 0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A, 0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B, 0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF, 0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E, 0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252, 0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5, 0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256, 0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8, 0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261, 0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264, 0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267, 0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B, 0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD, 0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271, 0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275, 0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278, 0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282, 0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286, 0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A, 0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E, 0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292, 0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296, 0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299, 0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C, 0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F, 0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3, 0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7, 0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB, 0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF, 0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2, 0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5, 0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8, 0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC, 0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6, 0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2, 0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6, 0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9, 0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC, 0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF, 0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3, 0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB, 0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9, 0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD, 0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1, 0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5, 0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9, 0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED, 0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1, 0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5, 0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9, 0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB, 0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF, 0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341, 0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345, 0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4, 0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7, 0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A, 0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC, 0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE, 0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2, 0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350, 0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5, 0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354, 0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357, 0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359, 0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362, 0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365, 0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369, 0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE, 0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C, 0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F, 0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371, 0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374, 0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378, 0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382, 0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385, 0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389, 0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D, 0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391, 0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395, 0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399, 0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D, 0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1, 0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5, 0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9, 0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB, 0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9, 0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF, 0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3, 0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE, 0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6, 0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA, 0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC, 0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6, 0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1, 0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5, 0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA, 0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8, 0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC, 0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE, 0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1, 0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4, 0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8, 0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2, 0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC, 0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF, 0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2, 0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5, 0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9, 0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED, 0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1, 0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5, 0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9, 0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA, 0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD, 0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442, 0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446, 0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF, 0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A, 0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E, 0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451, 0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454, 0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458, 0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462, 0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466, 0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469, 0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D, 0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470, 0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474, 0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478, 0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482, 0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486, 0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489, 0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D, 0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F, 0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492, 0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495, 0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499, 0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B, 0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F, 0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3, 0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6, 0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9, 0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD, 0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1, 0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5, 0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9, 0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD, 0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF, 0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1, 0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2, 0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6, 0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7, 0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA, 0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC, 0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF, 0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3, 0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6, 0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA, 0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE, 0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1, 0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5, 0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8, 0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC, 0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0, 0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4, 0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8, 0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC, 0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542, 0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544, 0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547, 0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A, 0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E, 0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552, 0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555, 0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559, 0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562, 0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565, 0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568, 0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C, 0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8, 0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571, 0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575, 0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577, 0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A, 0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583, 0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587, 0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0, 0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C, 0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590, 0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594, 0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598, 0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C, 0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0, 0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4, 0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8, 0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC, 0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE, 0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1, 0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3, 0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7, 0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8, 0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB, 0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD, 0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF, 0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2, 0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4, 0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8, 0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5, 0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB, 0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8, 0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0, 0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3, 0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6, 0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA, 0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF, 0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD, 0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1, 0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3, 0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7, 0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB, 0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF, 0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2, 0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6, 0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA, 0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE, 0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644, 0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648, 0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C, 0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650, 0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654, 0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658, 0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A, 0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8, 0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665, 0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669, 0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB, 0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D, 0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671, 0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674, 0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678, 0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682, 0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686, 0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A, 0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D, 0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691, 0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693, 0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697, 0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B, 0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F, 0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4, 0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2, 0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6, 0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA, 0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE, 0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2, 0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6, 0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA, 0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE, 0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2, 0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4, 0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7, 0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA, 0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE, 0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0, 0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3, 0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7, 0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB, 0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF, 0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3, 0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7, 0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB, 0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF, 0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3, 0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7, 0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB, 0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741, 0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745, 0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749, 0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D, 0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751, 0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754, 0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758, 0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762, 0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766, 0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A, 0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E, 0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772, 0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775, 0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779, 0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783, 0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787, 0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B, 0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E, 0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792, 0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794, 0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797, 0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A, 0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E, 0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6, 0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3, 0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7, 0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB, 0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF, 0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3, 0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7, 0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB, 0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF, 0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3, 0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7, 0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB, 0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF, 0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3, 0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7, 0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB, 0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF, 0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3, 0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7, 0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB, 0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF, 0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3, 0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7, 0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB, 0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE, 0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844, 0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848, 0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C, 0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850, 0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853, 0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857, 0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A, 0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863, 0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866, 0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A, 0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C, 0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870, 0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874, 0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878, 0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882, 0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886, 0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A, 0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E, 0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892, 0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896, 0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898, 0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B, 0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E, 0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2, 0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5, 0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6, 0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA, 0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9, 0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB, 0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE, 0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2, 0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1, 0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5, 0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8, 0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA, 0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD, 0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0, 0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4, 0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB, 0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7, 0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB, 0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD, 0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0, 0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3, 0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7, 0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6, 0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB, 0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF, 0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2, 0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5, 0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8, 0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC, 0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF, 0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2, 0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6, 0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0, 0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2, 0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5, 0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD, 0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8, 0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942, 0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945, 0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947, 0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A, 0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D, 0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951, 0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2, 0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954, 0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958, 0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A, 0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963, 0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966, 0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A, 0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB, 0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D, 0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971, 0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974, 0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977, 0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A, 0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984, 0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988, 0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B, 0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F, 0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990, 0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993, 0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995, 0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999, 0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA, 0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D, 0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0, 0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2, 0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5, 0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8, 0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC, 0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0, 0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3, 0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7, 0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA, 0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD, 0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0, 0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4, 0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6, 0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9, 0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD, 0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0, 0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3, 0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6, 0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA, 0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED, 0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF, 0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3, 0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5, 0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8, 0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB, 0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF, 0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4, 0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3, 0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7, 0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9, 0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9, 0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE, 0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44, 0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD, 0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1, 0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49, 0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C, 0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50, 0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54, 0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58, 0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62, 0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65, 0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69, 0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B, 0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E, 0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71, 0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75, 0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78, 0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81, 0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85, 0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87, 0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A, 0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D, 0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91, 0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2, 0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95, 0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99, 0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B, 0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F, 0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2, 0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6, 0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8, 0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB, 0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF, 0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1, 0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4, 0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6, 0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA, 0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1, 0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE, 0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2, 0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6, 0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA, 0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE, 0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2, 0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6, 0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA, 0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE, 0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0, 0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6, 0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5, 0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8, 0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB, 0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC, 0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF, 0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0, 0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3, 0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6, 0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA, 0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC, 0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE, 0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7, 0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45, 0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48, 0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B, 0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F, 0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51, 0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53, 0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57, 0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61, 0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65, 0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69, 0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D, 0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71, 0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74, 0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78, 0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82, 0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86, 0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A, 0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E, 0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92, 0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96, 0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A, 0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C, 0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F, 0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1, 0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5, 0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7, 0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9, 0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD, 0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0, 0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3, 0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6, 0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA, 0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE, 0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2, 0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6, 0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA, 0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE, 0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2, 0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6, 0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA, 0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE, 0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2, 0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6, 0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9, 0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED, 0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1, 0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5, 0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9, 0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD, 0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41, 0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1, 0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45, 0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49, 0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B, 0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E, 0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52, 0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54, 0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57, 0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61, 0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65, 0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69, 0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C, 0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70, 0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73, 0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77, 0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81, 0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85, 0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89, 0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C, 0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90, 0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93, 0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96, 0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99, 0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D, 0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F, 0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3, 0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7, 0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA, 0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE, 0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2, 0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6, 0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA, 0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE, 0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2, 0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4, 0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7, 0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA, 0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE, 0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0, 0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3, 0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7, 0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA, 0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE, 0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2, 0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6, 0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA, 0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED, 0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1, 0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4, 0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8, 0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC, 0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42, 0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46, 0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A, 0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E, 0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51, 0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54, 0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58, 0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62, 0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66, 0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A, 0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E, 0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72, 0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76, 0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A, 0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84, 0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88, 0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B, 0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F, 0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91, 0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94, 0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96, 0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7, 0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B, 0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F, 0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3, 0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6, 0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9, 0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC, 0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0, 0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3, 0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7, 0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB, 0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD, 0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0, 0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3, 0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7, 0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4, 0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB, 0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF, 0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1, 0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2, 0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3, 0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE, 0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1, 0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9, 0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB, 0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD, 0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0, 0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3, 0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7, 0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC, 0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA, 0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE, 0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0, 0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3, 0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3, 0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9, 0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6, 0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD, 0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9, 0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44, 0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47, 0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A, 0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E, 0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51, 0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55, 0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59, 0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61, 0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2, 0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63, 0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67, 0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9, 0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68, 0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A, 0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C, 0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F, 0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72, 0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76, 0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7, 0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A, 0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84, 0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85, 0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88, 0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF, 0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D, 0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3, 0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F, 0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8, 0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93, 0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96, 0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99, 0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D, 0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE, 0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1, 0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5, 0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7, 0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA, 0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB, 0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7, 0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA, 0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC, 0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4, 0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6, 0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9, 0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC, 0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0, 0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3, 0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3, 0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7, 0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9, 0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC, 0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0, 0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4, 0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA, 0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9, 0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD, 0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF, 0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2, 0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5, 0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9, 0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2, 0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED, 0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1, 0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3, 0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6, 0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9, 0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD, 0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA, 0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43, 0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47, 0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49, 0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C, 0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D, 0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51, 0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4, 0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55, 0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59, 0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61, 0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64, 0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67, 0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B, 0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D, 0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F, 0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73, 0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75, 0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78, 0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81, 0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85, 0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87, 0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A, 0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E, 0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90, 0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93, 0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96, 0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A, 0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD, 0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E, 0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2, 0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4, 0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7, 0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA, 0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE, 0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5, 0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7, 0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5, 0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7, 0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA, 0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD, 0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0, 0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF, 0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2, 0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6, 0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5, 0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8, 0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB, 0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF, 0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB, 0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5, 0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9, 0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB, 0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE, 0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF, 0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2, 0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5, 0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4, 0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7, 0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9, 0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE, 0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC, 0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0, 0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3, 0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2, 0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6, 0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8, 0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB, 0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE, 0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044, 0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED, 0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047, 0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B, 0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D, 0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F, 0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052, 0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056, 0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059, 0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062, 0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066, 0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069, 0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C, 0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F, 0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073, 0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077, 0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081, 0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085, 0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087, 0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A, 0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C, 0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090, 0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3, 0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093, 0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097, 0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099, 0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C, 0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F, 0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3, 0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC, 0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7, 0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB, 0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE, 0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1, 0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4, 0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8, 0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA, 0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC, 0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0, 0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3, 0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7, 0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB, 0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF, 0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3, 0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7, 0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB, 0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD, 0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0, 0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2, 0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6, 0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD, 0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0, 0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1, 0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED, 0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1, 0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4, 0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8, 0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6, 0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD, 0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143, 0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146, 0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A, 0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E, 0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152, 0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156, 0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158, 0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162, 0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165, 0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168, 0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B, 0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F, 0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0, 0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173, 0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177, 0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179, 0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182, 0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186, 0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A, 0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E, 0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191, 0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195, 0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197, 0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A, 0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B, 0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F, 0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE, 0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243, 0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247, 0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A, 0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E, 0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252, 0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256, 0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A, 0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263, 0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267, 0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A, 0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E, 0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272, 0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276, 0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A, 0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284, 0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288, 0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A, 0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D, 0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290, 0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294, 0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9, 0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299, 0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D, 0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0, 0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343, 0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346, 0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A, 0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D, 0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351, 0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355, 0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357, 0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A, 0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363, 0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367, 0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4, 0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B, 0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F, 0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373, 0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377, 0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381, 0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385, 0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389, 0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D, 0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391, 0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393, 0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9, 0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397, 0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B, 0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE, 0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E, 0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0, 0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442, 0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444, 0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA, 0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A, 0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD, 0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D, 0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451, 0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453, 0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456, 0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459, 0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463, 0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6, 0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466, 0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A, 0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D, 0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470, 0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474, 0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478, 0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482, 0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485, 0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489, 0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D, 0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491, 0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495, 0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499, 0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D, 0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541, 0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545, 0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547, 0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A, 0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D, 0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551, 0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2, 0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554, 0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558, 0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561, 0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565, 0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569, 0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D, 0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571, 0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574, 0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578, 0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581, 0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585, 0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589, 0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D, 0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591, 0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594, 0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598, 0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C, 0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0, 0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644, 0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648, 0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C, 0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650, 0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654, 0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656, 0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659, 0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662, 0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666, 0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF, 0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1, 0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D, 0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F, 0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673, 0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676, 0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A, 0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684, 0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687, 0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B, 0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E, 0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692, 0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696, 0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A, 0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E, 0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741, 0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745, 0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748, 0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B, 0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E, 0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752, 0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754, 0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758, 0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762, 0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766, 0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A, 0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E, 0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772, 0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776, 0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779, 0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783, 0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785, 0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788, 0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B, 0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F, 0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791, 0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794, 0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798, 0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B, 0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F, 0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843, 0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847, 0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B, 0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D, 0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851, 0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855, 0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859, 0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863, 0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867, 0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B, 0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F, 0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873, 0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876, 0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A, 0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884, 0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888, 0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C, 0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890, 0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894, 0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897, 0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B, 0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F, 0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943, 0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947, 0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B, 0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F, 0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952, 0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956, 0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A, 0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964, 0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC, 0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969, 0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D, 0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971, 0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975, 0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979, 0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983, 0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987, 0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B, 0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F, 0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991, 0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994, 0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997, 0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B, 0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D, 0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F, 0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6, 0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44, 0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46, 0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49, 0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D, 0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE, 0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F, 0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53, 0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55, 0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58, 0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61, 0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65, 0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA, 0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68, 0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C, 0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F, 0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71, 0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74, 0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78, 0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81, 0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84, 0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88, 0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C, 0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90, 0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94, 0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98, 0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C, 0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0, 0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44, 0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46, 0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49, 0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C, 0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50, 0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9, 0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53, 0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57, 0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59, 0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62, 0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65, 0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69, 0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2, 0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D, 0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71, 0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74, 0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77, 0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81, 0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85, 0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89, 0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C, 0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90, 0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93, 0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96, 0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A, 0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E, 0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42, 0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45, 0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49, 0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B, 0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E, 0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51, 0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55, 0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0, 0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59, 0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63, 0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66, 0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69, 0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C, 0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70, 0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74, 0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77, 0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81, 0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85, 0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89, 0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D, 0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91, 0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95, 0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99, 0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D, 0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0, 0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43, 0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46, 0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A, 0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB, 0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E, 0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52, 0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55, 0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59, 0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63, 0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67, 0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A, 0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E, 0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72, 0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74, 0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77, 0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A, 0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84, 0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5, 0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88, 0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C, 0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F, 0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93, 0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97, 0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B, 0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F, 0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42, 0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46, 0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49, 0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C, 0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50, 0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54, 0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58, 0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62, 0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66, 0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69, 0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C, 0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F, 0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73, 0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0, 0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77, 0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81, 0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84, 0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87, 0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A, 0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E, 0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91, 0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94, 0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98, 0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A, 0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D, 0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0, 0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44, 0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD, 0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48, 0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C, 0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50, 0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54, 0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58, 0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62, 0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66, 0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A, 0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E, 0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70, 0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4, 0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74, 0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78, 0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9, 0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82, 0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86, 0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88, 0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B, 0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E, 0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92, 0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1, 0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96, 0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A, 0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C, 0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F, 0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042, 0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046, 0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9, 0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049, 0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D, 0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F, 0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053, 0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057, 0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061, 0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065, 0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068, 0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C, 0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070, 0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074, 0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078, 0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082, 0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086, 0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A, 0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E, 0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090, 0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2, 0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095, 0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099, 0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6, 0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C, 0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0, 0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142, 0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145, 0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148, 0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C, 0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF, 0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150, 0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154, 0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157, 0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A, 0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163, 0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167, 0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6, 0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A, 0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E, 0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171, 0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175, 0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179, 0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183, 0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187, 0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B, 0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F, 0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191, 0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194, 0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197, 0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B, 0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0, 0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F, 0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243, 0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245, 0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248, 0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B, 0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F, 0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252, 0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255, 0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259, 0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262, 0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266, 0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A, 0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E, 0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272, 0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275, 0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279, 0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282, 0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286, 0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289, 0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D, 0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291, 0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295, 0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299, 0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C, 0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0, 0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344, 0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348, 0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C, 0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350, 0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354, 0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356, 0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359, 0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362, 0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366, 0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3, 0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A, 0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E, 0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371, 0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374, 0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377, 0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381, 0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385, 0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388, 0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C, 0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F, 0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393, 0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397, 0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B, 0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F, 0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442, 0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446, 0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448, 0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B, 0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E, 0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452, 0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3, 0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456, 0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A, 0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463, 0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466, 0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469, 0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D, 0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470, 0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474, 0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478, 0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A, 0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483, 0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486, 0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A, 0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C, 0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F, 0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493, 0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497, 0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B, 0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F, 0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543, 0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547, 0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B, 0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F, 0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551, 0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554, 0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557, 0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561, 0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6, 0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565, 0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569, 0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B, 0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E, 0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570, 0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574, 0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF, 0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577, 0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581, 0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583, 0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586, 0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589, 0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D, 0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8, 0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590, 0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594, 0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597, 0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B, 0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F, 0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643, 0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647, 0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A, 0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E, 0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652, 0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656, 0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A, 0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664, 0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668, 0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C, 0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670, 0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672, 0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675, 0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677, 0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681, 0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4, 0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684, 0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688, 0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A, 0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D, 0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690, 0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694, 0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD, 0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698, 0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C, 0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F, 0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742, 0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746, 0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A, 0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E, 0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751, 0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755, 0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758, 0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761, 0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765, 0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769, 0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D, 0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771, 0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775, 0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777, 0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A, 0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783, 0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787, 0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA, 0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B, 0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E, 0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791, 0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794, 0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798, 0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C, 0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0, 0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844, 0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848, 0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B, 0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F, 0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853, 0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857, 0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861, 0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865, 0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869, 0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C, 0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F, 0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873, 0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877, 0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2, 0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883, 0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887, 0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A, 0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E, 0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892, 0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896, 0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A, 0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E, 0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942, 0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944, 0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947, 0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A, 0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E, 0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB, 0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952, 0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956, 0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959, 0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963, 0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967, 0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B, 0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F, 0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972, 0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976, 0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979, 0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983, 0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987, 0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B, 0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F, 0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993, 0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997, 0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999, 0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C, 0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F, 0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43, 0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45, 0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48, 0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C, 0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F, 0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52, 0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55, 0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59, 0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62, 0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65, 0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69, 0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B, 0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1, 0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F, 0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73, 0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6, 0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78, 0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82, 0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85, 0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88, 0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B, 0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F, 0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91, 0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95, 0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99, 0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B, 0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E, 0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41, 0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45, 0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2, 0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49, 0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D, 0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E, 0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51, 0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53, 0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57, 0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC, 0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A, 0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63, 0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65, 0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68, 0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B, 0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F, 0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6, 0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72, 0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76, 0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78, 0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82, 0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86, 0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A, 0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E, 0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92, 0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96, 0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A, 0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E, 0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42, 0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46, 0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A, 0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E, 0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52, 0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54, 0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57, 0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A, 0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64, 0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1, 0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67, 0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B, 0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D, 0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70, 0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73, 0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77, 0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA, 0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81, 0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85, 0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88, 0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B, 0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E, 0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92, 0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94, 0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96, 0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A, 0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D, 0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41, 0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44, 0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48, 0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6, 0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E, 0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52, 0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54, 0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57, 0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A, 0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64, 0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD, 0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68, 0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C, 0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F, 0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73, 0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77, 0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81, 0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85, 0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88, 0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C, 0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90, 0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94, 0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98, 0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C, 0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0, 0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44, 0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48, 0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B, 0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E, 0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52, 0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56, 0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A, 0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64, 0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68, 0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B, 0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E, 0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71, 0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75, 0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9, 0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81, 0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85, 0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87, 0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD, 0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B, 0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F, 0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2, 0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93, 0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97, 0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A, 0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E, 0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42, 0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46, 0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A, 0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D, 0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51, 0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55, 0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59, 0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63, 0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67, 0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B, 0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F, 0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73, 0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76, 0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79, 0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82, 0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86, 0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA, 0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C, 0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90, 0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93, 0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96, 0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99, 0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D, 0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF, 0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042, 0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046, 0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049, 0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C, 0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F, 0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053, 0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6, 0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058, 0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062, 0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066, 0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A, 0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E, 0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072, 0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076, 0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A, 0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084, 0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086, 0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089, 0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C, 0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090, 0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD, 0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094, 0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098, 0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A, 0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D, 0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0, 0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143, 0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6, 0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147, 0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B, 0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D, 0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150, 0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153, 0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157, 0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE, 0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A, 0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164, 0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167, 0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B, 0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F, 0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173, 0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177, 0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A, 0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184, 0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188, 0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C, 0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190, 0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194, 0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198, 0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C, 0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0, 0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242, 0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245, 0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247, 0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B, 0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA, 0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F, 0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253, 0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255, 0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258, 0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261, 0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265, 0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2, 0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269, 0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D, 0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F, 0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272, 0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275, 0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279, 0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA, 0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282, 0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286, 0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289, 0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C, 0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F, 0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293, 0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296, 0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A, 0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E, 0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0, 0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343, 0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346, 0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349, 0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA, 0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D, 0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350, 0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352, 0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355, 0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358, 0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362, 0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1, 0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368, 0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C, 0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E, 0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371, 0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375, 0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379, 0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6, 0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385, 0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389, 0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B, 0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E, 0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391, 0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395, 0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD, 0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A, 0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E, 0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441, 0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444, 0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447, 0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B, 0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3, 0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451, 0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455, 0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457, 0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A, 0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463, 0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466, 0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA, 0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B, 0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F, 0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472, 0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475, 0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478, 0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482, 0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485, 0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488, 0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C, 0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E, 0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491, 0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494, 0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498, 0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C, 0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F, 0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543, 0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545, 0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548, 0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B, 0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F, 0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC, 0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553, 0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557, 0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559, 0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562, 0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565, 0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569, 0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3, 0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E, 0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572, 0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574, 0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9, 0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577, 0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581, 0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE, 0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585, 0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588, 0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B, 0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E, 0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591, 0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595, 0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597, 0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A, 0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E, 0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0, 0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643, 0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646, 0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A, 0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD, 0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E, 0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652, 0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF, 0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2, 0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4, 0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC, 0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0, 0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5, 0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA, 0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0, 0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC, 0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3, 0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA, 0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE, 0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6, 0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA, 0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF, 0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3, 0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7, 0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF, 0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5, 0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9, 0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1, 0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5, 0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC, 0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8, 0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5, 0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5, 0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3, 0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD, 0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9, 0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9, 0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE, 0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA, 0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1, 0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF, 0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7, 0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6, 0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6, 0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1, 0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8, 0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF, 0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6, 0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6, 0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD, 0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6, 0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF, 0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4, 0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8, 0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9, 0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC, 0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5, 0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE, 0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA, 0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1, 0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC, 0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2, 0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA, 0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2, 0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0, 0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9, 0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE, 0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8, 0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1, 0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB, 0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7, 0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8, 0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0, 0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9, 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4, 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC, 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, 0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC, 0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC, 0, 0 }; static const WCHAR oem2uni949[] = { /* Korean --> Unicode pairs */ 0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06, 0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E, 0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F, 0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25, 0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29, 0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32, 0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36, 0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D, 0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42, 0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46, 0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A, 0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50, 0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55, 0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A, 0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F, 0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63, 0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67, 0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B, 0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F, 0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76, 0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D, 0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87, 0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F, 0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95, 0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99, 0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2, 0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6, 0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE, 0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4, 0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA, 0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2, 0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7, 0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD, 0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1, 0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6, 0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB, 0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF, 0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6, 0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE, 0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8, 0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE, 0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03, 0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09, 0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10, 0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15, 0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A, 0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F, 0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24, 0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28, 0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F, 0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33, 0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A, 0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F, 0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43, 0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B, 0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F, 0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55, 0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A, 0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E, 0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64, 0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68, 0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E, 0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77, 0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E, 0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85, 0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B, 0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91, 0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95, 0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99, 0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F, 0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3, 0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8, 0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC, 0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0, 0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4, 0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9, 0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD, 0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3, 0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9, 0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD, 0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4, 0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8, 0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD, 0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2, 0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7, 0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB, 0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF, 0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3, 0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7, 0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE, 0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05, 0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C, 0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11, 0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16, 0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A, 0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E, 0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22, 0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26, 0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A, 0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E, 0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35, 0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C, 0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42, 0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49, 0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52, 0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58, 0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E, 0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66, 0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D, 0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72, 0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76, 0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F, 0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83, 0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89, 0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E, 0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92, 0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96, 0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A, 0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E, 0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2, 0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6, 0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA, 0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE, 0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2, 0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6, 0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA, 0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2, 0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7, 0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB, 0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4, 0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA, 0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF, 0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3, 0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7, 0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE, 0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2, 0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7, 0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD, 0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01, 0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05, 0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B, 0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11, 0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15, 0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19, 0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D, 0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21, 0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25, 0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29, 0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F, 0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36, 0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A, 0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44, 0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A, 0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E, 0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53, 0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57, 0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B, 0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61, 0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67, 0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B, 0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F, 0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73, 0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77, 0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C, 0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81, 0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86, 0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B, 0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F, 0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96, 0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A, 0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F, 0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3, 0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7, 0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB, 0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF, 0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3, 0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7, 0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE, 0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3, 0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA, 0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1, 0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6, 0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA, 0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF, 0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3, 0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7, 0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED, 0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3, 0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9, 0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD, 0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003, 0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008, 0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D, 0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012, 0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017, 0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B, 0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021, 0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025, 0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A, 0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E, 0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032, 0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036, 0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A, 0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E, 0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042, 0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049, 0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050, 0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058, 0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E, 0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062, 0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066, 0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A, 0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E, 0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072, 0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076, 0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A, 0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081, 0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086, 0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A, 0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092, 0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096, 0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E, 0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6, 0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2, 0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA, 0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF, 0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3, 0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC, 0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2, 0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7, 0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC, 0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1, 0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6, 0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA, 0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE, 0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2, 0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6, 0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA, 0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE, 0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102, 0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106, 0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E, 0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115, 0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E, 0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122, 0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A, 0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F, 0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133, 0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C, 0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142, 0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147, 0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C, 0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152, 0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159, 0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E, 0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163, 0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167, 0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B, 0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F, 0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173, 0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177, 0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E, 0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184, 0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A, 0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190, 0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197, 0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D, 0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1, 0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5, 0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA, 0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE, 0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2, 0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6, 0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA, 0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE, 0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2, 0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6, 0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA, 0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF, 0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5, 0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9, 0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0, 0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4, 0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA, 0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF, 0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4, 0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8, 0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF, 0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203, 0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A, 0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210, 0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216, 0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C, 0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221, 0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225, 0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229, 0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D, 0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231, 0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236, 0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A, 0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F, 0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243, 0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247, 0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B, 0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F, 0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253, 0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257, 0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D, 0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262, 0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266, 0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C, 0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270, 0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276, 0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A, 0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F, 0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283, 0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A, 0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E, 0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295, 0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C, 0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2, 0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9, 0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF, 0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5, 0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9, 0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD, 0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1, 0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5, 0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB, 0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1, 0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6, 0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE, 0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3, 0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0, 0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC, 0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303, 0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309, 0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D, 0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316, 0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A, 0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F, 0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323, 0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327, 0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B, 0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F, 0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333, 0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337, 0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B, 0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F, 0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343, 0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347, 0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B, 0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F, 0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353, 0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D, 0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363, 0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C, 0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373, 0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379, 0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D, 0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386, 0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A, 0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F, 0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395, 0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399, 0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D, 0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3, 0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7, 0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD, 0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1, 0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5, 0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9, 0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD, 0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1, 0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7, 0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF, 0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6, 0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE, 0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3, 0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9, 0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED, 0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1, 0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5, 0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9, 0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE, 0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402, 0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406, 0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A, 0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E, 0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413, 0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417, 0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D, 0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422, 0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426, 0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D, 0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431, 0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436, 0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A, 0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E, 0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442, 0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446, 0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A, 0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E, 0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455, 0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A, 0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E, 0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466, 0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A, 0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F, 0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473, 0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477, 0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B, 0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F, 0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484, 0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489, 0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D, 0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491, 0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495, 0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499, 0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E, 0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2, 0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7, 0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD, 0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1, 0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6, 0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC, 0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1, 0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6, 0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB, 0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF, 0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4, 0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9, 0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF, 0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7, 0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB, 0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3, 0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7, 0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC, 0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500, 0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504, 0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508, 0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C, 0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510, 0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516, 0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D, 0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521, 0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B, 0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F, 0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536, 0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B, 0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F, 0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548, 0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F, 0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555, 0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559, 0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562, 0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566, 0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A, 0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E, 0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572, 0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576, 0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A, 0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E, 0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582, 0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586, 0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A, 0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E, 0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592, 0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596, 0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A, 0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E, 0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5, 0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC, 0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2, 0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9, 0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1, 0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6, 0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA, 0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3, 0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7, 0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC, 0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0, 0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4, 0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8, 0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED, 0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1, 0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5, 0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9, 0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD, 0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601, 0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605, 0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609, 0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D, 0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613, 0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619, 0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D, 0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621, 0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626, 0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A, 0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F, 0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633, 0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638, 0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C, 0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640, 0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644, 0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649, 0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D, 0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651, 0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655, 0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659, 0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D, 0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661, 0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666, 0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B, 0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F, 0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673, 0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677, 0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B, 0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F, 0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683, 0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687, 0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B, 0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F, 0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693, 0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697, 0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B, 0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2, 0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7, 0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD, 0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2, 0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6, 0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA, 0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE, 0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2, 0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6, 0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA, 0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE, 0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2, 0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7, 0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB, 0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF, 0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3, 0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7, 0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB, 0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF, 0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5, 0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA, 0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE, 0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704, 0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709, 0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D, 0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711, 0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715, 0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719, 0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D, 0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721, 0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725, 0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B, 0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732, 0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736, 0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D, 0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741, 0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746, 0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B, 0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750, 0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756, 0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A, 0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E, 0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763, 0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769, 0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D, 0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774, 0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779, 0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F, 0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785, 0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789, 0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793, 0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B, 0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1, 0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5, 0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE, 0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2, 0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9, 0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD, 0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1, 0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5, 0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB, 0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF, 0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3, 0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7, 0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB, 0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF, 0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3, 0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7, 0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB, 0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2, 0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7, 0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB, 0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804, 0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B, 0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811, 0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815, 0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C, 0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821, 0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827, 0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D, 0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831, 0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A, 0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E, 0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843, 0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848, 0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C, 0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850, 0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856, 0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A, 0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861, 0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866, 0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A, 0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872, 0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876, 0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B, 0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880, 0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884, 0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888, 0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C, 0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891, 0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895, 0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899, 0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D, 0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1, 0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5, 0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA, 0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE, 0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3, 0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9, 0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD, 0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4, 0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9, 0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE, 0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3, 0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8, 0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC, 0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3, 0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7, 0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE, 0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3, 0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7, 0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF, 0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903, 0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908, 0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C, 0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910, 0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914, 0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919, 0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D, 0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922, 0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926, 0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A, 0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E, 0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932, 0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936, 0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A, 0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941, 0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946, 0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A, 0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950, 0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955, 0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B, 0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961, 0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965, 0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C, 0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971, 0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977, 0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D, 0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981, 0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988, 0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990, 0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994, 0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998, 0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C, 0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0, 0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4, 0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8, 0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE, 0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3, 0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8, 0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE, 0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4, 0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA, 0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4, 0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA, 0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2, 0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA, 0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF, 0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3, 0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD, 0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03, 0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07, 0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C, 0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10, 0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14, 0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19, 0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D, 0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21, 0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25, 0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29, 0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D, 0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31, 0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35, 0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B, 0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41, 0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46, 0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F, 0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56, 0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B, 0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60, 0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66, 0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D, 0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73, 0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79, 0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D, 0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81, 0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89, 0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E, 0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92, 0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96, 0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A, 0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E, 0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2, 0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6, 0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE, 0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4, 0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA, 0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0, 0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5, 0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA, 0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE, 0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2, 0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6, 0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC, 0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0, 0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4, 0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8, 0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC, 0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0, 0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4, 0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8, 0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD, 0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02, 0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07, 0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B, 0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12, 0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16, 0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B, 0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21, 0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25, 0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A, 0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F, 0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33, 0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F, 0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43, 0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B, 0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52, 0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57, 0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C, 0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60, 0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66, 0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A, 0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F, 0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73, 0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77, 0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B, 0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F, 0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83, 0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87, 0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D, 0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92, 0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96, 0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A, 0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E, 0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2, 0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7, 0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD, 0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1, 0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6, 0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB, 0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF, 0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5, 0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA, 0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE, 0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4, 0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8, 0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC, 0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0, 0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4, 0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8, 0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC, 0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0, 0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4, 0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA, 0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01, 0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06, 0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10, 0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A, 0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23, 0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B, 0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32, 0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37, 0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C, 0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42, 0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A, 0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51, 0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55, 0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59, 0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E, 0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62, 0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66, 0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A, 0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E, 0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72, 0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76, 0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A, 0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E, 0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82, 0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89, 0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90, 0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96, 0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D, 0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3, 0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA, 0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE, 0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7, 0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB, 0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2, 0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7, 0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB, 0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3, 0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9, 0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE, 0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2, 0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6, 0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA, 0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE, 0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2, 0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA, 0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF, 0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03, 0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B, 0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F, 0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15, 0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19, 0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D, 0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21, 0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26, 0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A, 0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F, 0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33, 0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37, 0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B, 0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F, 0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44, 0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A, 0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F, 0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54, 0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A, 0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E, 0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62, 0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67, 0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C, 0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70, 0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74, 0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78, 0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C, 0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82, 0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B, 0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F, 0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97, 0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E, 0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2, 0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7, 0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB, 0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF, 0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4, 0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9, 0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD, 0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1, 0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5, 0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9, 0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD, 0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1, 0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7, 0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD, 0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1, 0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5, 0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA, 0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE, 0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3, 0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9, 0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD, 0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02, 0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08, 0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E, 0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13, 0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18, 0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E, 0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23, 0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27, 0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B, 0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F, 0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33, 0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37, 0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B, 0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F, 0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43, 0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A, 0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50, 0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56, 0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E, 0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65, 0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B, 0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F, 0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78, 0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F, 0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85, 0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89, 0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92, 0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96, 0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C, 0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0, 0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4, 0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9, 0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD, 0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1, 0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5, 0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9, 0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD, 0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1, 0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5, 0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9, 0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD, 0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3, 0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA, 0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE, 0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6, 0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA, 0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF, 0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3, 0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7, 0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB, 0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF, 0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04, 0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A, 0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E, 0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12, 0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16, 0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F, 0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23, 0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27, 0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B, 0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F, 0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33, 0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37, 0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B, 0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F, 0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46, 0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B, 0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F, 0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56, 0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A, 0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E, 0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62, 0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66, 0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A, 0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E, 0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72, 0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76, 0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A, 0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E, 0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82, 0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86, 0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A, 0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E, 0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92, 0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97, 0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B, 0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F, 0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3, 0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7, 0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB, 0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF, 0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4, 0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8, 0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC, 0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0, 0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4, 0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9, 0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF, 0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5, 0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9, 0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE, 0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4, 0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8, 0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC, 0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0, 0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4, 0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8, 0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC, 0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000, 0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004, 0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008, 0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C, 0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010, 0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014, 0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018, 0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C, 0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020, 0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024, 0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028, 0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C, 0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030, 0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034, 0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038, 0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D, 0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041, 0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045, 0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049, 0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D, 0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052, 0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056, 0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B, 0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061, 0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065, 0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B, 0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F, 0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073, 0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077, 0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B, 0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F, 0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083, 0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087, 0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B, 0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F, 0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096, 0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B, 0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F, 0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7, 0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB, 0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7, 0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB, 0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4, 0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB, 0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1, 0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5, 0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE, 0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2, 0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9, 0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE, 0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2, 0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA, 0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE, 0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103, 0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109, 0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D, 0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112, 0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117, 0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B, 0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128, 0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E, 0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135, 0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D, 0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142, 0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146, 0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F, 0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153, 0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A, 0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F, 0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163, 0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C, 0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171, 0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176, 0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B, 0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F, 0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183, 0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188, 0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F, 0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195, 0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A, 0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2, 0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7, 0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE, 0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3, 0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7, 0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB, 0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0, 0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5, 0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA, 0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF, 0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3, 0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA, 0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE, 0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3, 0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9, 0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED, 0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4, 0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8, 0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE, 0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203, 0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208, 0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E, 0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214, 0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A, 0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221, 0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225, 0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C, 0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235, 0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239, 0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D, 0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241, 0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245, 0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A, 0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E, 0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255, 0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A, 0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E, 0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263, 0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268, 0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E, 0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273, 0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278, 0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E, 0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284, 0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A, 0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E, 0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293, 0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297, 0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E, 0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2, 0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9, 0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF, 0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3, 0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB, 0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF, 0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3, 0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7, 0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB, 0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF, 0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3, 0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7, 0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB, 0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2, 0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8, 0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0, 0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5, 0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE, 0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303, 0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307, 0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F, 0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316, 0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B, 0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320, 0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326, 0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C, 0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330, 0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334, 0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338, 0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C, 0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340, 0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344, 0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349, 0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D, 0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351, 0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355, 0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359, 0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D, 0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361, 0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365, 0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B, 0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371, 0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376, 0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E, 0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382, 0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387, 0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D, 0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391, 0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395, 0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399, 0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D, 0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1, 0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5, 0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9, 0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD, 0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1, 0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5, 0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9, 0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD, 0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2, 0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6, 0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA, 0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE, 0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2, 0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6, 0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD, 0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4, 0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA, 0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF, 0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3, 0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA, 0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE, 0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402, 0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406, 0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B, 0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F, 0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414, 0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418, 0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C, 0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420, 0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425, 0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429, 0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E, 0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433, 0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438, 0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E, 0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442, 0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446, 0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B, 0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F, 0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453, 0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457, 0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B, 0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F, 0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463, 0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A, 0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F, 0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473, 0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A, 0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E, 0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483, 0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487, 0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B, 0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F, 0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493, 0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498, 0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D, 0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1, 0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5, 0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9, 0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD, 0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1, 0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5, 0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA, 0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF, 0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3, 0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7, 0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB, 0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF, 0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3, 0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7, 0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB, 0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF, 0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3, 0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7, 0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC, 0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2, 0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7, 0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD, 0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504, 0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508, 0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D, 0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512, 0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517, 0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B, 0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520, 0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524, 0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A, 0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F, 0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534, 0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A, 0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540, 0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546, 0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550, 0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A, 0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562, 0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567, 0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C, 0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572, 0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579, 0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F, 0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585, 0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A, 0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592, 0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599, 0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E, 0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3, 0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7, 0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC, 0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0, 0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6, 0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0, 0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB, 0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3, 0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9, 0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD, 0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4, 0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9, 0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1, 0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8, 0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602, 0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A, 0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F, 0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614, 0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A, 0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620, 0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626, 0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B, 0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636, 0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D, 0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643, 0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649, 0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D, 0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656, 0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A, 0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661, 0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665, 0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669, 0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E, 0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674, 0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A, 0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F, 0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684, 0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A, 0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690, 0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696, 0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B, 0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0, 0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6, 0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC, 0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2, 0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7, 0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE, 0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6, 0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA, 0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1, 0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6, 0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA, 0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2, 0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6, 0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED, 0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2, 0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6, 0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC, 0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701, 0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707, 0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D, 0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711, 0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718, 0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D, 0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723, 0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729, 0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D, 0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734, 0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A, 0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741, 0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746, 0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B, 0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A, 0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F, 0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764, 0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769, 0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E, 0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772, 0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779, 0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780, 0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B, 0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792, 0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B, 0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F, 0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9, 0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF, 0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5, 0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9, 0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2, 0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6, 0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD, 0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3, 0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7, 0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC, 0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1, 0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6, 0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB, 0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0, 0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4, 0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8, 0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC, 0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802, 0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807, 0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D, 0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814, 0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A, 0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821, 0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826, 0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A, 0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832, 0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836, 0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B, 0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841, 0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845, 0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B, 0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851, 0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856, 0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A, 0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E, 0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862, 0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866, 0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A, 0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E, 0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875, 0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B, 0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F, 0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889, 0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890, 0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895, 0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899, 0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E, 0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4, 0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9, 0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD, 0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1, 0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5, 0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9, 0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF, 0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3, 0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9, 0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE, 0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2, 0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA, 0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE, 0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5, 0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9, 0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED, 0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1, 0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6, 0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA, 0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901, 0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908, 0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, 0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003, 0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C, 0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010, 0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7, 0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E, 0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033, 0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1, 0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220, 0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207, 0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B, 0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF, 0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1, 0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD, 0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191, 0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A, 0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D, 0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208, 0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282, 0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227, 0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912, 0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916, 0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B, 0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F, 0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923, 0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927, 0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B, 0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930, 0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935, 0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939, 0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D, 0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941, 0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945, 0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949, 0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D, 0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953, 0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959, 0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D, 0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964, 0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968, 0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D, 0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4, 0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E, 0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA, 0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1, 0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211, 0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030, 0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6, 0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665, 0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8, 0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592, 0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7, 0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F, 0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6, 0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197, 0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D, 0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F, 0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122, 0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC, 0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973, 0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978, 0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D, 0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981, 0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985, 0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B, 0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991, 0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995, 0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C, 0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1, 0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5, 0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9, 0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD, 0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1, 0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5, 0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9, 0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD, 0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3, 0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB, 0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF, 0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8, 0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, 0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, 0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE, 0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5, 0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA, 0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3, 0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7, 0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE, 0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03, 0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07, 0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10, 0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15, 0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A, 0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E, 0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22, 0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26, 0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B, 0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F, 0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33, 0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37, 0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B, 0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F, 0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43, 0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131, 0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135, 0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139, 0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D, 0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141, 0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145, 0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149, 0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D, 0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151, 0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155, 0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159, 0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D, 0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161, 0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165, 0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169, 0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D, 0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171, 0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175, 0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179, 0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D, 0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181, 0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185, 0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189, 0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D, 0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49, 0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F, 0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55, 0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59, 0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62, 0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66, 0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B, 0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F, 0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73, 0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77, 0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B, 0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80, 0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85, 0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89, 0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D, 0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91, 0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95, 0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A, 0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E, 0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2, 0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6, 0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172, 0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176, 0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160, 0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164, 0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168, 0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393, 0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397, 0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B, 0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F, 0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4, 0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8, 0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3, 0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7, 0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB, 0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF, 0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4, 0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8, 0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA, 0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE, 0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2, 0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6, 0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA, 0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1, 0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6, 0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA, 0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2, 0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7, 0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD, 0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2, 0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6, 0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA, 0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF, 0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3, 0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8, 0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC, 0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00, 0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04, 0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09, 0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C, 0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C, 0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C, 0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513, 0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533, 0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520, 0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F, 0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538, 0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A, 0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E, 0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521, 0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529, 0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531, 0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539, 0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540, 0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545, 0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549, 0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D, 0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12, 0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17, 0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C, 0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22, 0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26, 0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A, 0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E, 0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32, 0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36, 0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A, 0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E, 0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43, 0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47, 0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E, 0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53, 0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57, 0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E, 0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62, 0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67, 0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B, 0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397, 0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3, 0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399, 0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D, 0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1, 0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E, 0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389, 0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0, 0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4, 0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8, 0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382, 0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB, 0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF, 0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393, 0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1, 0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6, 0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF, 0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB, 0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3, 0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6, 0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70, 0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74, 0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A, 0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E, 0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82, 0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86, 0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A, 0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E, 0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92, 0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96, 0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A, 0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F, 0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3, 0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7, 0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB, 0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF, 0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3, 0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7, 0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC, 0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0, 0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4, 0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126, 0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8, 0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166, 0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262, 0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266, 0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A, 0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E, 0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272, 0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276, 0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A, 0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2, 0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6, 0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA, 0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE, 0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2, 0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6, 0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460, 0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464, 0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468, 0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C, 0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153, 0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B, 0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5, 0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9, 0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD, 0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1, 0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6, 0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA, 0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE, 0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2, 0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8, 0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED, 0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1, 0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5, 0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9, 0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD, 0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01, 0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05, 0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09, 0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F, 0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15, 0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19, 0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F, 0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6, 0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131, 0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142, 0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE, 0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200, 0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204, 0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208, 0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C, 0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210, 0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214, 0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218, 0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C, 0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0, 0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4, 0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8, 0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC, 0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0, 0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4, 0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476, 0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A, 0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E, 0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482, 0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074, 0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083, 0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A, 0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31, 0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35, 0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F, 0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43, 0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A, 0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F, 0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53, 0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C, 0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61, 0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67, 0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C, 0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71, 0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76, 0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A, 0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E, 0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82, 0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86, 0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A, 0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E, 0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92, 0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043, 0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047, 0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B, 0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F, 0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053, 0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057, 0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B, 0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F, 0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063, 0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067, 0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B, 0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F, 0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073, 0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077, 0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B, 0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F, 0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083, 0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087, 0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B, 0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F, 0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093, 0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97, 0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E, 0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3, 0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7, 0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0, 0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6, 0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB, 0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0, 0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6, 0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC, 0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1, 0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6, 0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA, 0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE, 0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2, 0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7, 0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB, 0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1, 0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5, 0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9, 0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD, 0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4, 0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8, 0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC, 0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0, 0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4, 0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8, 0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC, 0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0, 0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4, 0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8, 0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC, 0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0, 0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4, 0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8, 0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC, 0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0, 0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4, 0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8, 0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC, 0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0, 0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4, 0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF, 0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04, 0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A, 0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F, 0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14, 0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A, 0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20, 0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25, 0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A, 0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F, 0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33, 0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37, 0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C, 0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40, 0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44, 0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48, 0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C, 0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50, 0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54, 0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58, 0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D, 0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411, 0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415, 0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418, 0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C, 0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420, 0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424, 0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428, 0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C, 0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430, 0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434, 0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437, 0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B, 0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F, 0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443, 0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447, 0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B, 0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F, 0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65, 0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69, 0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70, 0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75, 0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A, 0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E, 0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82, 0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86, 0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B, 0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F, 0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93, 0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A, 0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F, 0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3, 0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB, 0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF, 0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4, 0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8, 0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC, 0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0, 0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5, 0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9, 0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE, 0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3, 0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7, 0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB, 0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF, 0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3, 0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7, 0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED, 0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2, 0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6, 0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE, 0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02, 0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07, 0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D, 0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11, 0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16, 0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B, 0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F, 0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26, 0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B, 0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F, 0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37, 0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B, 0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F, 0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43, 0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47, 0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B, 0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F, 0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53, 0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57, 0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E, 0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65, 0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C, 0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71, 0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77, 0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D, 0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81, 0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88, 0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D, 0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93, 0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99, 0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D, 0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6, 0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA, 0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0, 0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4, 0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8, 0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC, 0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0, 0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5, 0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9, 0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD, 0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1, 0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5, 0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9, 0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD, 0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1, 0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7, 0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE, 0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2, 0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB, 0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF, 0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07, 0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10, 0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14, 0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19, 0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D, 0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D, 0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38, 0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B, 0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C, 0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77, 0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81, 0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86, 0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C, 0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D, 0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8, 0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF, 0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB, 0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4, 0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7, 0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7, 0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF, 0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5, 0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00, 0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03, 0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09, 0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D, 0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14, 0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19, 0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E, 0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23, 0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28, 0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E, 0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35, 0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A, 0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E, 0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42, 0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46, 0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A, 0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E, 0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52, 0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59, 0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E, 0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62, 0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A, 0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D, 0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C, 0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D, 0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C, 0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49, 0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61, 0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70, 0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76, 0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F, 0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89, 0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D, 0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1, 0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1, 0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4, 0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF, 0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09, 0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30, 0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38, 0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43, 0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C, 0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54, 0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F, 0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68, 0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78, 0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72, 0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77, 0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C, 0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81, 0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86, 0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A, 0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F, 0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93, 0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97, 0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B, 0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F, 0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4, 0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9, 0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD, 0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2, 0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6, 0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA, 0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE, 0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2, 0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7, 0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB, 0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D, 0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC, 0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4, 0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0, 0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC, 0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4, 0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08, 0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D, 0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C, 0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42, 0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50, 0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65, 0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88, 0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C, 0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0, 0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB, 0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC, 0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1, 0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001, 0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014, 0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044, 0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C, 0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055, 0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD, 0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1, 0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5, 0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9, 0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD, 0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3, 0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9, 0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED, 0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4, 0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9, 0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE, 0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003, 0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008, 0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C, 0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010, 0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015, 0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A, 0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E, 0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022, 0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026, 0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A, 0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C, 0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C, 0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098, 0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F, 0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8, 0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD, 0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3, 0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC, 0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8, 0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4, 0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108, 0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110, 0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119, 0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123, 0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C, 0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138, 0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144, 0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154, 0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160, 0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180, 0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B, 0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194, 0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC, 0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD, 0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031, 0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037, 0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D, 0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041, 0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048, 0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D, 0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052, 0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057, 0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C, 0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061, 0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065, 0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069, 0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F, 0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075, 0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079, 0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F, 0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084, 0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088, 0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C, 0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090, 0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094, 0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC, 0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD, 0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B, 0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217, 0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C, 0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268, 0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C, 0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290, 0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299, 0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3, 0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC, 0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9, 0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8, 0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2, 0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8, 0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE, 0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5, 0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA, 0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301, 0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311, 0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C, 0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358, 0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F, 0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096, 0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A, 0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E, 0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2, 0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9, 0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE, 0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2, 0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA, 0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE, 0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5, 0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB, 0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF, 0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8, 0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE, 0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3, 0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8, 0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE, 0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5, 0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA, 0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE, 0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102, 0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369, 0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371, 0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381, 0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C, 0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1, 0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5, 0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE, 0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7, 0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0, 0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410, 0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428, 0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450, 0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460, 0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C, 0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4, 0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7, 0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8, 0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD, 0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6, 0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1, 0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518, 0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525, 0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A, 0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538, 0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108, 0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C, 0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111, 0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115, 0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119, 0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D, 0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121, 0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125, 0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129, 0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D, 0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133, 0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139, 0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E, 0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147, 0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B, 0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152, 0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157, 0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B, 0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163, 0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167, 0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D, 0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544, 0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D, 0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D, 0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0, 0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA, 0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3, 0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC, 0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC, 0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1, 0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611, 0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C, 0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668, 0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4, 0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4, 0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700, 0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729, 0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738, 0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748, 0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760, 0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771, 0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D, 0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D, 0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792, 0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F, 0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173, 0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177, 0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B, 0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180, 0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185, 0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A, 0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E, 0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192, 0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196, 0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A, 0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E, 0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5, 0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA, 0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE, 0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6, 0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB, 0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1, 0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5, 0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9, 0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD, 0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799, 0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9, 0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4, 0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9, 0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4, 0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800, 0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809, 0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819, 0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825, 0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835, 0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840, 0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C, 0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C, 0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878, 0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0, 0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1, 0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0, 0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1, 0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0, 0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD, 0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C, 0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C, 0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959, 0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969, 0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3, 0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7, 0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC, 0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0, 0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4, 0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8, 0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC, 0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0, 0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5, 0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA, 0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE, 0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202, 0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206, 0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C, 0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211, 0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215, 0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219, 0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D, 0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221, 0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225, 0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229, 0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975, 0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985, 0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D, 0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0, 0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF, 0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC, 0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1, 0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB, 0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3, 0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC, 0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8, 0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01, 0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39, 0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48, 0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E, 0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58, 0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67, 0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71, 0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84, 0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8, 0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0, 0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB, 0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8, 0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B, 0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232, 0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237, 0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B, 0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243, 0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247, 0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C, 0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250, 0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254, 0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258, 0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D, 0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261, 0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266, 0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A, 0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E, 0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272, 0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276, 0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A, 0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E, 0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285, 0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A, 0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04, 0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18, 0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B, 0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38, 0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E, 0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49, 0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54, 0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C, 0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4, 0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7, 0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0, 0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC, 0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08, 0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D, 0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15, 0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B, 0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F, 0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29, 0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34, 0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43, 0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C, 0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84, 0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C, 0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97, 0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292, 0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297, 0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B, 0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1, 0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6, 0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA, 0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF, 0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4, 0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA, 0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1, 0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6, 0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD, 0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1, 0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6, 0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB, 0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0, 0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6, 0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA, 0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE, 0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5, 0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA, 0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1, 0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0, 0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5, 0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4, 0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1, 0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4, 0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC, 0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09, 0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C, 0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C, 0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64, 0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84, 0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A, 0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95, 0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4, 0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5, 0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0, 0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03, 0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10, 0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F, 0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C, 0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57, 0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60, 0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC, 0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302, 0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308, 0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F, 0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315, 0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A, 0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323, 0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A, 0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F, 0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334, 0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A, 0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341, 0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347, 0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B, 0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F, 0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353, 0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357, 0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B, 0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F, 0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363, 0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367, 0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A, 0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74, 0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D, 0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D, 0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98, 0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1, 0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0, 0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC, 0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18, 0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D, 0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48, 0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94, 0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD, 0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF, 0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058, 0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069, 0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098, 0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5, 0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0, 0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6, 0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0, 0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9, 0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9, 0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4, 0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D, 0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371, 0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375, 0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379, 0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F, 0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385, 0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389, 0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392, 0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396, 0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D, 0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2, 0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6, 0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE, 0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2, 0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7, 0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD, 0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1, 0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7, 0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD, 0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2, 0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6, 0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4, 0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100, 0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115, 0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F, 0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126, 0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F, 0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138, 0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148, 0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D, 0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C, 0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168, 0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178, 0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E, 0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C, 0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5, 0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0, 0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC, 0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0, 0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1, 0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200, 0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F, 0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C, 0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229, 0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9, 0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD, 0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2, 0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7, 0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB, 0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2, 0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7, 0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB, 0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403, 0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407, 0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C, 0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410, 0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414, 0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418, 0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C, 0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421, 0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425, 0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429, 0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D, 0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431, 0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435, 0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231, 0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250, 0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260, 0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270, 0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F, 0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290, 0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4, 0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD, 0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9, 0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3, 0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED, 0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8, 0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300, 0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D, 0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318, 0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328, 0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369, 0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378, 0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384, 0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8, 0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0, 0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED, 0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408, 0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430, 0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B, 0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F, 0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445, 0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449, 0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D, 0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451, 0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455, 0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459, 0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E, 0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463, 0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468, 0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C, 0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472, 0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476, 0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D, 0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484, 0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A, 0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490, 0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495, 0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499, 0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D, 0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448, 0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C, 0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480, 0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC, 0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4, 0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500, 0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514, 0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C, 0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B, 0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548, 0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D, 0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555, 0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D, 0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564, 0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573, 0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D, 0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C, 0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595, 0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0, 0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8, 0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD, 0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6, 0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA, 0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F, 0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3, 0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7, 0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC, 0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0, 0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4, 0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8, 0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC, 0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0, 0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4, 0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8, 0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD, 0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2, 0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7, 0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB, 0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1, 0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5, 0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA, 0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF, 0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4, 0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9, 0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1, 0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1, 0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED, 0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6, 0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE, 0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605, 0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C, 0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B, 0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628, 0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630, 0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637, 0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641, 0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651, 0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C, 0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F, 0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C, 0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B, 0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698, 0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7, 0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4, 0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0, 0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC, 0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC, 0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8, 0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501, 0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506, 0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B, 0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510, 0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516, 0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B, 0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F, 0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523, 0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527, 0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B, 0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F, 0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533, 0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537, 0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B, 0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542, 0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547, 0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B, 0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553, 0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557, 0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E, 0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563, 0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8, 0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705, 0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715, 0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721, 0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731, 0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C, 0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A, 0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751, 0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755, 0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C, 0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774, 0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D, 0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785, 0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A, 0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794, 0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A, 0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4, 0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD, 0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD, 0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8, 0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0, 0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8, 0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804, 0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566, 0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E, 0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572, 0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579, 0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E, 0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582, 0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B, 0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F, 0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594, 0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598, 0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C, 0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0, 0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4, 0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9, 0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD, 0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1, 0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5, 0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9, 0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD, 0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1, 0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5, 0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811, 0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C, 0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C, 0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838, 0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849, 0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870, 0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A, 0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885, 0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C, 0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F, 0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD, 0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4, 0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0, 0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC, 0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905, 0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F, 0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934, 0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958, 0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C, 0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988, 0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998, 0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0, 0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8, 0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3, 0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE, 0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4, 0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA, 0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0, 0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6, 0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB, 0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0, 0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6, 0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC, 0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602, 0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607, 0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C, 0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612, 0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619, 0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E, 0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623, 0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628, 0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C, 0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631, 0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635, 0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B, 0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA, 0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2, 0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED, 0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8, 0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08, 0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D, 0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C, 0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C, 0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61, 0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98, 0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4, 0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1, 0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0, 0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10, 0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21, 0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C, 0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D, 0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C, 0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7, 0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10, 0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21, 0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29, 0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38, 0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E, 0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643, 0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A, 0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650, 0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657, 0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D, 0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661, 0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665, 0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B, 0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F, 0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676, 0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A, 0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E, 0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682, 0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688, 0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E, 0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693, 0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698, 0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C, 0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3, 0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7, 0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D, 0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48, 0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57, 0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64, 0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75, 0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0, 0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC, 0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8, 0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7, 0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4, 0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08, 0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18, 0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24, 0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C, 0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D, 0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88, 0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C, 0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9, 0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0, 0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8, 0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04, 0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19, 0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28, 0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35, 0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF, 0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4, 0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8, 0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE, 0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2, 0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9, 0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE, 0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3, 0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA, 0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE, 0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3, 0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9, 0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED, 0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2, 0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7, 0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB, 0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702, 0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707, 0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B, 0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F, 0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714, 0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F, 0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69, 0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75, 0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85, 0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91, 0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1, 0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC, 0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5, 0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4, 0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9, 0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08, 0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15, 0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C, 0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31, 0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58, 0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67, 0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74, 0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C, 0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4, 0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8, 0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5, 0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011, 0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035, 0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716, 0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D, 0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722, 0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726, 0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E, 0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732, 0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739, 0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E, 0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742, 0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748, 0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D, 0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753, 0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C, 0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762, 0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768, 0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E, 0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773, 0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778, 0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E, 0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783, 0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787, 0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045, 0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054, 0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D, 0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D, 0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8, 0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7, 0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4, 0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1, 0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC, 0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC, 0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1, 0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131, 0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140, 0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145, 0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154, 0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161, 0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184, 0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4, 0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3, 0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0, 0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207, 0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D, 0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D, 0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C, 0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791, 0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795, 0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C, 0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1, 0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280, 0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290, 0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0, 0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8, 0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0, 0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB, 0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4, 0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4, 0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303, 0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E, 0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C, 0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321, 0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C, 0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B, 0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345, 0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384, 0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390, 0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C, 0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB, 0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC, 0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9, 0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3, 0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4, 0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401, 0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444, 0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D, 0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C, 0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488, 0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494, 0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4, 0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC, 0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD, 0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514, 0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D, 0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D, 0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559, 0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568, 0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574, 0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584, 0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589, 0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9, 0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8, 0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4, 0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4, 0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600, 0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610, 0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615, 0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D, 0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640, 0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B, 0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655, 0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669, 0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683, 0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690, 0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1, 0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9, 0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8, 0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7, 0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8, 0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD, 0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718, 0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728, 0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734, 0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744, 0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751, 0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758, 0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763, 0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770, 0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781, 0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790, 0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D, 0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9, 0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5, 0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687, 0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C, 0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB, 0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36, 0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6, 0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404, 0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF, 0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3, 0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978, 0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7, 0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F, 0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5, 0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D, 0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593, 0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34, 0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910, 0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E, 0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE, 0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44, 0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3, 0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451, 0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC, 0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598, 0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1, 0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A, 0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586, 0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C, 0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941, 0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47, 0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1, 0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168, 0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5, 0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5, 0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B, 0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901, 0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028, 0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2, 0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20, 0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E, 0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8, 0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE, 0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171, 0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B, 0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840, 0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2, 0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB, 0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9, 0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84, 0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694, 0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504, 0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B, 0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289, 0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A, 0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D, 0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC, 0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106, 0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770, 0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176, 0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F, 0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87, 0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5, 0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC, 0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93, 0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396, 0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1, 0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8, 0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951, 0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212, 0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA, 0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D, 0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08, 0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4, 0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471, 0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B, 0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545, 0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1, 0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E, 0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1, 0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0, 0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5, 0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7, 0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED, 0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40, 0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764, 0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD, 0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4, 0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B, 0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54, 0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1, 0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A, 0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32, 0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC, 0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2, 0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846, 0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED, 0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC, 0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C, 0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50, 0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC, 0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC, 0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321, 0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38, 0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50, 0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B, 0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A, 0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0, 0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18, 0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1, 0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0, 0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821, 0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF, 0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E, 0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA, 0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18, 0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1, 0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3, 0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775, 0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0, 0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8, 0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6, 0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078, 0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF, 0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009, 0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF, 0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0, 0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6, 0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7, 0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA, 0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B, 0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD, 0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398, 0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79, 0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026, 0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708, 0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3, 0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568, 0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3, 0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B, 0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4, 0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D, 0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA, 0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE, 0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035, 0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547, 0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908, 0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287, 0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699, 0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3, 0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E, 0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2, 0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909, 0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611, 0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD, 0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F, 0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA, 0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A, 0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC, 0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176, 0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B, 0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947, 0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E, 0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280, 0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F, 0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F, 0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82, 0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A, 0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F, 0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947, 0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00, 0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D, 0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48, 0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2, 0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65, 0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409, 0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB, 0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C, 0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF, 0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911, 0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914, 0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918, 0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B, 0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156, 0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920, 0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921, 0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922, 0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925, 0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872, 0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929, 0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43, 0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0, 0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74, 0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C, 0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7, 0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29, 0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932, 0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935, 0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1, 0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C, 0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940, 0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3, 0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2, 0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166, 0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A, 0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E, 0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9, 0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952, 0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956, 0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959, 0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA, 0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6, 0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7, 0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80, 0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF, 0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892, 0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE, 0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556, 0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7, 0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9, 0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541, 0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F, 0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F, 0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858, 0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0, 0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8, 0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927, 0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85, 0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA, 0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB, 0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012, 0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835, 0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6, 0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC, 0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843, 0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21, 0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC, 0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404, 0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48, 0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD, 0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2, 0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368, 0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B, 0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566, 0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E, 0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D, 0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD, 0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771, 0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C, 0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4, 0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597, 0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7, 0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017, 0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A, 0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97, 0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B, 0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127, 0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B, 0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA, 0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B, 0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D, 0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E, 0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12, 0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E, 0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5, 0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43, 0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD, 0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA, 0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405, 0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86, 0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7, 0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006, 0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11, 0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F, 0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6, 0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC, 0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA, 0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823, 0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97, 0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77, 0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742, 0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23, 0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F, 0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A, 0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C, 0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582, 0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375, 0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F, 0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2, 0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046, 0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748, 0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7, 0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE, 0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3, 0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7, 0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF, 0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA, 0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0, 0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93, 0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727, 0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E, 0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA, 0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7, 0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6, 0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD, 0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27, 0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62, 0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B, 0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938, 0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2, 0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C, 0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559, 0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E, 0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96, 0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8, 0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817, 0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B, 0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C, 0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA, 0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E, 0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8, 0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406, 0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C, 0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF, 0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2, 0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0, 0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3, 0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB, 0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C, 0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469, 0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8, 0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE, 0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB, 0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29, 0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D, 0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B, 0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513, 0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B, 0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB, 0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1, 0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B, 0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B, 0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB, 0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627, 0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164, 0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081, 0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C, 0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13, 0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C, 0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195, 0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704, 0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762, 0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5, 0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D, 0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791, 0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169, 0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE, 0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D, 0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE, 0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB, 0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738, 0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305, 0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728, 0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766, 0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92, 0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F, 0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF, 0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B, 0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9, 0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A, 0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959, 0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7, 0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302, 0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727, 0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011, 0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587, 0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E, 0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF, 0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A, 0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE, 0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C, 0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E, 0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761, 0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D, 0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC, 0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9, 0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C, 0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD, 0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38, 0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94, 0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236, 0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1, 0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB, 0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591, 0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED, 0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC, 0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46, 0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812, 0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5, 0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB, 0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43, 0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8, 0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F, 0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609, 0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5, 0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B, 0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A, 0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90, 0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9, 0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F, 0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC, 0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919, 0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A, 0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF, 0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44, 0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4, 0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543, 0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F, 0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06, 0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB, 0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5, 0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1, 0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656, 0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739, 0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A, 0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225, 0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19, 0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77, 0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5, 0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9, 0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08, 0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6, 0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A, 0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9, 0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14, 0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C, 0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F, 0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907, 0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5, 0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8, 0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0, 0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2, 0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702, 0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D, 0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256, 0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0, 0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75, 0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276, 0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5, 0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36, 0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240, 0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0, 0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA, 0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644, 0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206, 0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954, 0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E, 0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6, 0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC, 0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B, 0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29, 0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43, 0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315, 0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62, 0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249, 0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7, 0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8, 0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA, 0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8, 0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5, 0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A, 0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB, 0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B, 0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C, 0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1, 0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7, 0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37, 0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B, 0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C, 0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2, 0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB, 0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB, 0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B, 0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C, 0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD, 0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23, 0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E, 0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9, 0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D, 0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF, 0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC, 0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC, 0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969, 0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A, 0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA, 0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C, 0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492, 0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09, 0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17, 0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7, 0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A, 0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546, 0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19, 0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0, 0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61, 0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0, 0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4, 0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61, 0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD, 0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61, 0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F, 0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885, 0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6, 0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F, 0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8, 0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E, 0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72, 0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F, 0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD, 0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D, 0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790, 0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3, 0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B, 0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584, 0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E, 0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401, 0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C, 0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8, 0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A, 0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078, 0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE, 0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4, 0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B, 0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA, 0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2, 0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583, 0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE, 0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC, 0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F, 0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB, 0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072, 0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16, 0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05, 0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0, 0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5, 0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240, 0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3, 0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F, 0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F, 0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0, 0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C, 0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D, 0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6, 0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F, 0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16, 0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD, 0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1, 0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E, 0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001, 0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051, 0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7, 0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA, 0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88, 0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101, 0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C, 0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A, 0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7, 0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2, 0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57, 0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC, 0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331, 0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896, 0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042, 0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9, 0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6, 0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3, 0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919, 0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A, 0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085, 0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA, 0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F, 0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3, 0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D, 0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340, 0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4, 0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4, 0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265, 0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F, 0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE, 0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E, 0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347, 0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805, 0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636, 0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E, 0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043, 0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE, 0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A, 0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996, 0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55, 0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F, 0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96, 0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755, 0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE, 0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B, 0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0, 0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E, 0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398, 0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A, 0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5, 0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089, 0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81, 0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A, 0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341, 0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E, 0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25, 0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD, 0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D, 0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09, 0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD, 0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1, 0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354, 0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89, 0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848, 0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854, 0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB, 0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6, 0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4, 0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE, 0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F, 0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26, 0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16, 0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D, 0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384, 0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A, 0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C, 0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B, 0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6, 0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974, 0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976, 0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB, 0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F, 0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43, 0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D, 0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23, 0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2, 0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B, 0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D, 0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E, 0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC, 0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E, 0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104, 0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6, 0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109, 0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616, 0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944, 0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D, 0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F, 0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982, 0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984, 0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207, 0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D, 0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988, 0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF, 0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C, 0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D, 0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827, 0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E, 0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350, 0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87, 0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5, 0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136, 0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5, 0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995, 0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F, 0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998, 0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B, 0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E, 0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1, 0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD, 0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3, 0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430, 0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB, 0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7, 0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9, 0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8, 0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E, 0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3, 0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B, 0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370, 0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4, 0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF, 0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE, 0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719, 0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A, 0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3, 0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F, 0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602, 0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D, 0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8, 0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D, 0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E, 0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA, 0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F, 0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF, 0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3, 0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D, 0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07, 0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389, 0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F, 0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140, 0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515, 0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD, 0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9, 0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778, 0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B, 0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9, 0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9, 0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E, 0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0, 0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A, 0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A, 0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD, 0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB, 0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D, 0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC, 0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416, 0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC, 0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF, 0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF, 0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170, 0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20, 0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952, 0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F, 0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD, 0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889, 0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995, 0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194, 0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073, 0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394, 0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51, 0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB, 0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24, 0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B, 0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950, 0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD, 0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2, 0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685, 0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67, 0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C, 0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91, 0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90, 0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553, 0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB, 0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A, 0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1, 0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B, 0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F, 0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72, 0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457, 0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060, 0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B, 0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D, 0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D, 0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170, 0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B, 0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466, 0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918, 0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F, 0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A, 0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A, 0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE, 0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109, 0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8, 0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961, 0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA, 0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336, 0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531, 0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF, 0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5, 0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30, 0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A, 0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0, 0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3, 0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4, 0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5, 0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4, 0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F, 0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB, 0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68, 0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069, 0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280, 0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB, 0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE, 0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD, 0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D, 0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F, 0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5, 0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264, 0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC, 0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5, 0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937, 0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B, 0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1, 0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5, 0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5, 0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033, 0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7, 0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087, 0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C, 0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA, 0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A, 0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370, 0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB, 0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E, 0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335, 0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1, 0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3, 0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9, 0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0, 0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A, 0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5, 0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3, 0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8, 0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55, 0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8, 0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57, 0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB, 0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7, 0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005, 0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9, 0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C, 0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628, 0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD, 0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72, 0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A, 0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B, 0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC, 0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834, 0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07, 0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C, 0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3, 0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA, 0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7, 0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A, 0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF, 0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577, 0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728, 0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D, 0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D, 0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09, 0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F, 0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E, 0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95, 0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17, 0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A, 0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7, 0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B, 0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8, 0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A, 0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575, 0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684, 0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E, 0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA, 0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA, 0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43, 0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178, 0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C, 0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB, 0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF, 0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420, 0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672, 0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6, 0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49, 0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B, 0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E, 0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59, 0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76, 0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38, 0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E, 0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776, 0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C, 0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A, 0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81, 0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574, 0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE, 0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40, 0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E, 0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD, 0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E, 0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E, 0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E, 0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266, 0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756, 0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236, 0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D, 0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF, 0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD, 0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44, 0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D, 0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146, 0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14, 0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9, 0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D, 0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15, 0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A, 0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A, 0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97, 0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087, 0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF, 0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D, 0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5, 0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3, 0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9, 0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E, 0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9, 0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C, 0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35, 0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750, 0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A, 0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A, 0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468, 0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE, 0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1, 0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A, 0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587, 0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2, 0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85, 0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031, 0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0, 0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101, 0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB, 0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96, 0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3, 0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB, 0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2, 0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB, 0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E, 0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD, 0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8, 0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA, 0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7, 0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F, 0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3, 0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C, 0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957, 0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3, 0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C, 0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072, 0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54, 0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875, 0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B, 0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25, 0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1, 0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E, 0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D, 0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A, 0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032, 0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707, 0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9, 0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE, 0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED, 0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F, 0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57, 0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6, 0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14, 0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF, 0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64, 0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49, 0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E, 0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F, 0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6, 0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12, 0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A, 0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C, 0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D, 0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879, 0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC, 0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009, 0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C, 0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E, 0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD, 0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621, 0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6, 0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0, 0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826, 0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7, 0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56, 0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD, 0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254, 0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3, 0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620, 0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB, 0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929, 0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA, 0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6, 0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7, 0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8, 0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4, 0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D, 0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE, 0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D, 0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E, 0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252, 0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC, 0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8, 0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751, 0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF, 0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6, 0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D, 0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284, 0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A, 0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D, 0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D, 0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349, 0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162, 0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1, 0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8, 0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8, 0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4, 0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070, 0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC, 0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD, 0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E, 0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB, 0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD, 0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310, 0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36, 0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D, 0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E, 0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8, 0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443, 0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145, 0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D, 0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403, 0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634, 0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0, 0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3, 0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074, 0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C, 0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4, 0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894, 0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4, 0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49, 0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4, 0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3, 0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED, 0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06, 0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88, 0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD, 0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31, 0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E, 0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253, 0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235, 0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C, 0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01, 0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B, 0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422, 0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451, 0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A, 0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB, 0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2, 0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854, 0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11, 0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C, 0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B, 0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E, 0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0, 0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4, 0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410, 0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876, 0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71, 0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F, 0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078, 0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F, 0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6, 0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A, 0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2, 0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834, 0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817, 0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248, 0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211, 0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C, 0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557, 0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD, 0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D, 0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E, 0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247, 0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D, 0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A, 0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55, 0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2, 0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D, 0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305, 0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA, 0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B, 0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1, 0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE, 0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2, 0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA, 0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4, 0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07, 0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153, 0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2, 0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7, 0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F, 0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8, 0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2, 0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642, 0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC, 0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46, 0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C, 0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F, 0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455, 0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050, 0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78, 0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2, 0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57, 0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55, 0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650, 0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD, 0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A, 0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266, 0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408, 0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4, 0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09, 0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052, 0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86, 0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A, 0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5, 0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A, 0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977, 0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3, 0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED, 0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016, 0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C, 0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6, 0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957, 0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B, 0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B, 0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57, 0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769, 0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8, 0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384, 0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D, 0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237, 0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249, 0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840, 0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354, 0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79, 0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2, 0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144, 0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2, 0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF, 0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A, 0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2, 0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57, 0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559, 0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E, 0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA, 0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236, 0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB, 0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8, 0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D, 0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0, 0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E, 0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF, 0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77, 0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865, 0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A, 0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F, 0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F, 0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3, 0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679, 0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C, 0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575, 0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF, 0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774, 0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA, 0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A, 0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3, 0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853, 0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08, 0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B, 0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA, 0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D, 0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643, 0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F, 0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C, 0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352, 0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3, 0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A, 0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666, 0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE, 0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE, 0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4, 0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B, 0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D, 0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F, 0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4, 0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019, 0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589, 0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D, 0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB, 0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104, 0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13, 0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684, 0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599, 0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE, 0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D, 0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB, 0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E, 0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308, 0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615, 0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403, 0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20, 0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070, 0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6, 0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD, 0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199, 0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6, 0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7, 0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70, 0, 0 }; #endif #if FF_CODE_PAGE == 950 || FF_CODE_PAGE == 0 /* Traditional Chinese */ static const WCHAR uni2oem950[] = { /* Unicode --> Big5 pairs */ 0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3, 0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE, 0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5, 0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346, 0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A, 0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E, 0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352, 0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356, 0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A, 0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E, 0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362, 0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366, 0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A, 0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E, 0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372, 0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5, 0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C, 0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB, 0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1, 0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB, 0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF, 0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6, 0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8, 0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241, 0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7, 0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5, 0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE, 0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8, 0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6, 0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A, 0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275, 0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271, 0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6, 0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1, 0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3, 0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5, 0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7, 0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7, 0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6, 0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3, 0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1, 0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2, 0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE, 0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264, 0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268, 0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E, 0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A, 0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD, 0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF, 0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3, 0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9, 0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8, 0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142, 0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172, 0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176, 0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A, 0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9, 0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5, 0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9, 0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375, 0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379, 0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D, 0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3, 0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7, 0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB, 0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF, 0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3, 0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7, 0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0, 0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251, 0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253, 0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440, 0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456, 0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946, 0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2, 0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540, 0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1, 0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950, 0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1, 0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964, 0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947, 0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547, 0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4, 0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445, 0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5, 0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1, 0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6, 0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA, 0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB, 0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45, 0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8, 0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA, 0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3, 0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF, 0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2, 0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5, 0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B, 0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550, 0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551, 0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F, 0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5, 0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA, 0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4, 0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8, 0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3, 0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE, 0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0, 0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED, 0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7, 0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4, 0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9, 0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7, 0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA, 0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D, 0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED, 0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E, 0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF, 0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2, 0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63, 0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE, 0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF, 0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB, 0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6, 0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1, 0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5, 0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2, 0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4, 0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA, 0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4, 0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA, 0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0, 0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7, 0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8, 0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE, 0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED, 0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58, 0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54, 0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E, 0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4, 0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6, 0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F, 0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48, 0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1, 0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4, 0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA, 0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA, 0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF, 0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB, 0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6, 0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA, 0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9, 0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0, 0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0, 0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3, 0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC, 0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8, 0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C, 0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6, 0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456, 0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451, 0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458, 0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D, 0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460, 0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E, 0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464, 0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465, 0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD, 0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E, 0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855, 0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7, 0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9, 0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851, 0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3, 0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7, 0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6, 0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3, 0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC, 0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE, 0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6, 0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9, 0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4, 0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF, 0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7, 0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE, 0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7, 0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD, 0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4, 0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9, 0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6, 0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5, 0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB, 0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF, 0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5, 0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8, 0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD, 0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA, 0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8, 0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078, 0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7, 0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C, 0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461, 0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552, 0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA, 0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0, 0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259, 0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C, 0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8, 0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE, 0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB, 0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4, 0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC, 0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641, 0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0, 0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955, 0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE, 0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642, 0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B, 0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2, 0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1, 0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5, 0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140, 0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C, 0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9, 0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557, 0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E, 0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2, 0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646, 0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD, 0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC, 0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F, 0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED, 0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2, 0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9, 0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63, 0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1, 0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65, 0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB, 0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6, 0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6, 0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469, 0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6, 0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0, 0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9, 0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142, 0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40, 0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2, 0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0, 0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1, 0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648, 0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754, 0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1, 0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C, 0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A, 0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA, 0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8, 0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2, 0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3, 0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45, 0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079, 0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3, 0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D, 0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6, 0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC, 0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450, 0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943, 0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B, 0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA, 0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC, 0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8, 0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF, 0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD, 0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8, 0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3, 0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3, 0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB, 0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6, 0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C, 0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A, 0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F, 0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC, 0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9, 0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9, 0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED, 0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6, 0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46, 0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1, 0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD, 0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC, 0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F, 0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574, 0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573, 0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569, 0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B, 0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570, 0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B, 0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651, 0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A, 0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C, 0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C, 0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770, 0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761, 0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774, 0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76, 0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F, 0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B, 0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772, 0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A, 0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769, 0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB, 0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF, 0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950, 0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49, 0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6, 0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941, 0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952, 0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD, 0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB, 0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8, 0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947, 0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E, 0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD, 0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7, 0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC, 0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5, 0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77, 0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C, 0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E, 0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46, 0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76, 0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E, 0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6, 0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF, 0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA, 0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5, 0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141, 0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1, 0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6, 0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140, 0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44, 0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8, 0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41, 0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2, 0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2, 0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A, 0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8, 0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7, 0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3, 0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474, 0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478, 0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8, 0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8, 0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3, 0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472, 0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875, 0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871, 0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2, 0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3, 0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F, 0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1, 0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA, 0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A, 0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868, 0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0, 0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6, 0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870, 0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0, 0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6, 0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF, 0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC, 0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6, 0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB, 0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD, 0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA, 0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB, 0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2, 0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155, 0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE, 0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150, 0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5, 0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C, 0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3, 0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0, 0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147, 0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47, 0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542, 0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546, 0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543, 0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA, 0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6, 0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F, 0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2, 0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE, 0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941, 0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3, 0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC, 0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940, 0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7, 0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B, 0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4, 0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1, 0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C, 0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA, 0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE, 0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456, 0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1, 0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459, 0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A, 0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9, 0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7, 0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9, 0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5, 0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C, 0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D, 0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8, 0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778, 0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA, 0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46, 0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB, 0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9, 0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE, 0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B, 0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F, 0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664, 0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661, 0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3, 0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1, 0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC, 0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4, 0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE, 0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958, 0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2, 0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC, 0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956, 0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9, 0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54, 0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E, 0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D, 0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52, 0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53, 0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153, 0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151, 0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47, 0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49, 0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156, 0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1, 0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF, 0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5, 0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC, 0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9, 0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5, 0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD, 0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6, 0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF, 0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE, 0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2, 0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA, 0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB, 0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8, 0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4, 0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3, 0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB, 0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E, 0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF, 0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4, 0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA, 0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2, 0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED, 0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB, 0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4, 0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3, 0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0, 0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166, 0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C, 0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2, 0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165, 0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162, 0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3, 0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B, 0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552, 0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5, 0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A, 0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D, 0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1, 0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3, 0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B, 0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD, 0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA, 0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8, 0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363, 0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2, 0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7, 0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2, 0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A, 0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159, 0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469, 0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668, 0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB, 0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3, 0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1, 0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A, 0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961, 0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E, 0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7, 0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3, 0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD, 0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8, 0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D, 0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4, 0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1, 0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD, 0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC, 0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B, 0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6, 0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2, 0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE, 0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB, 0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4, 0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967, 0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970, 0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966, 0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50, 0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D, 0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52, 0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B, 0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968, 0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E, 0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8, 0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62, 0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1, 0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56, 0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D, 0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B, 0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A, 0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65, 0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162, 0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55, 0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51, 0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163, 0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A, 0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164, 0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3, 0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE, 0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0, 0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB, 0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6, 0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0, 0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142, 0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2, 0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB, 0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9, 0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8, 0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9, 0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6, 0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB, 0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443, 0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5, 0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF, 0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE, 0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF, 0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8, 0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9, 0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46, 0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD, 0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9, 0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3, 0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5, 0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2, 0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170, 0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178, 0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174, 0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B, 0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177, 0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555, 0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A, 0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556, 0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559, 0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E, 0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957, 0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951, 0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5, 0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1, 0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3, 0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE, 0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0, 0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA, 0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D, 0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB, 0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C, 0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5, 0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7, 0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973, 0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56, 0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0, 0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446, 0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9, 0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972, 0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674, 0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9, 0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57, 0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A, 0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8, 0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6, 0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167, 0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62, 0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65, 0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149, 0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146, 0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1, 0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448, 0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49, 0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E, 0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED, 0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB, 0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65, 0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8, 0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F, 0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67, 0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C, 0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9, 0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974, 0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B, 0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE, 0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E, 0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8, 0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0, 0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59, 0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D, 0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB, 0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B, 0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3, 0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0, 0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561, 0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD, 0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473, 0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7, 0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7, 0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3, 0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1, 0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3, 0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D, 0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C, 0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60, 0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61, 0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B, 0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A, 0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4, 0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D, 0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79, 0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6, 0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2, 0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F, 0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E, 0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71, 0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D, 0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72, 0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9, 0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158, 0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E, 0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6, 0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157, 0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC, 0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544, 0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3, 0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9, 0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED, 0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC, 0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452, 0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F, 0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5, 0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56, 0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54, 0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744, 0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0, 0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD, 0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3, 0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC, 0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565, 0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563, 0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A, 0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B, 0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960, 0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964, 0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967, 0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF, 0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4, 0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445, 0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA, 0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD, 0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B, 0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F, 0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8, 0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476, 0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1, 0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D, 0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C, 0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE, 0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D, 0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD, 0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0, 0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3, 0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75, 0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163, 0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456, 0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454, 0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B, 0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7, 0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3, 0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D, 0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4, 0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E, 0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5, 0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A, 0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D, 0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE, 0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A, 0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE, 0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1, 0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1, 0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6, 0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA, 0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177, 0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176, 0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B, 0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164, 0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A, 0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F, 0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459, 0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6, 0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA, 0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB, 0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72, 0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575, 0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971, 0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366, 0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF, 0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8, 0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD, 0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9, 0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749, 0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1, 0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3, 0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73, 0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8, 0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A, 0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A, 0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF, 0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576, 0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573, 0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B, 0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE, 0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D, 0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E, 0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C, 0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4, 0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76, 0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75, 0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC, 0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1, 0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F, 0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E, 0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174, 0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461, 0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B, 0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577, 0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD, 0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD, 0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF, 0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4, 0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6, 0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3, 0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78, 0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE, 0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6, 0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5, 0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2, 0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF, 0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2, 0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7, 0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3, 0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6, 0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD, 0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5, 0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6, 0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB, 0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A, 0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4, 0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0, 0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE, 0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6, 0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3, 0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4, 0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8, 0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC, 0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0, 0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1, 0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1, 0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176, 0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8, 0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3, 0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB, 0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC, 0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA, 0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9, 0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A, 0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C, 0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA, 0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5, 0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565, 0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1, 0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8, 0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564, 0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557, 0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B, 0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C, 0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB, 0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F, 0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944, 0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753, 0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948, 0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A, 0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755, 0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D, 0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474, 0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942, 0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467, 0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C, 0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2, 0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B, 0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A, 0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758, 0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F, 0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757, 0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8, 0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5, 0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C, 0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43, 0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A, 0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB, 0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA, 0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79, 0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1, 0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579, 0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3, 0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC, 0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978, 0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5, 0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5, 0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7, 0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3, 0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB, 0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2, 0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1, 0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979, 0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3, 0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF, 0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8, 0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4, 0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0, 0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA, 0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A, 0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A, 0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC, 0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9, 0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0, 0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7, 0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9, 0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF, 0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72, 0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76, 0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49, 0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4, 0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1, 0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0, 0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3, 0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476, 0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3, 0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4, 0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB, 0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA, 0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5, 0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA, 0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5, 0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3, 0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3, 0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE, 0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE, 0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2, 0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED, 0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB, 0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1, 0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF, 0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF, 0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8, 0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD, 0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7, 0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6, 0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF, 0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4, 0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD, 0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB, 0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4, 0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA, 0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1, 0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF, 0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3, 0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42, 0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45, 0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6, 0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8, 0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1, 0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1, 0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4, 0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6, 0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA, 0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE, 0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8, 0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9, 0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC, 0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4, 0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2, 0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1, 0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7, 0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579, 0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA, 0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6, 0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B, 0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569, 0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573, 0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478, 0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574, 0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3, 0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE, 0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E, 0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477, 0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0, 0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5, 0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954, 0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A, 0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77, 0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C, 0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E, 0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1, 0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970, 0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB, 0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D, 0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956, 0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA, 0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958, 0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B, 0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE, 0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6, 0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769, 0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B, 0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5, 0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764, 0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8, 0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB, 0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9, 0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0, 0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF, 0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767, 0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE, 0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5, 0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA, 0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB, 0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F, 0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3, 0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0, 0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0, 0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD, 0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E, 0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1, 0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A, 0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5, 0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB, 0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2, 0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3, 0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0, 0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7, 0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0, 0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB, 0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9, 0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6, 0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5, 0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7, 0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6, 0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4, 0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC, 0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC, 0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB, 0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE, 0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258, 0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D, 0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1, 0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2, 0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246, 0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243, 0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C, 0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD, 0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0, 0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD, 0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC, 0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4, 0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7, 0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1, 0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8, 0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5, 0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7, 0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1, 0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD, 0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975, 0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977, 0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56, 0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD, 0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE, 0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF, 0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248, 0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3, 0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE, 0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7, 0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5, 0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8, 0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48, 0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773, 0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F, 0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3, 0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2, 0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF, 0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD, 0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE, 0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9, 0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E, 0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE, 0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE, 0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB, 0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4, 0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB, 0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD, 0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4, 0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC, 0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF, 0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD, 0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D, 0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B, 0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3, 0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52, 0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE, 0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0, 0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5, 0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB, 0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF, 0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3, 0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0, 0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7, 0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7, 0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9, 0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC, 0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4, 0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777, 0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0, 0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6, 0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A, 0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7, 0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5, 0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9, 0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9, 0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6, 0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4, 0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8, 0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7, 0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7, 0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB, 0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D, 0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450, 0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA, 0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2, 0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1, 0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0, 0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA, 0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2, 0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA, 0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3, 0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2, 0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB, 0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC, 0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE, 0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5, 0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3, 0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF, 0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE, 0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42, 0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7, 0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA, 0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9, 0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE, 0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D, 0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48, 0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49, 0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8, 0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F, 0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3, 0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44, 0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52, 0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8, 0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2, 0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0, 0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56, 0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B, 0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE, 0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51, 0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58, 0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63, 0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66, 0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56, 0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63, 0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67, 0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48, 0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E, 0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59, 0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57, 0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D, 0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E, 0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA, 0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB, 0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9, 0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE, 0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5, 0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2, 0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4, 0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE, 0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC, 0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9, 0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF, 0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0, 0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC, 0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9, 0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD, 0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0, 0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9, 0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC, 0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1, 0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3, 0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2, 0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0, 0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA, 0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA, 0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC, 0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4, 0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE, 0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB, 0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE, 0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2, 0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE, 0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3, 0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD, 0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5, 0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1, 0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0, 0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2, 0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA, 0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4, 0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9, 0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8, 0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB, 0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5, 0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4, 0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC, 0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6, 0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9, 0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA, 0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2, 0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0, 0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB, 0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF, 0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8, 0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1, 0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB, 0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0, 0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1, 0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E, 0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE, 0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2, 0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3, 0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A, 0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258, 0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D, 0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D, 0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F, 0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249, 0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67, 0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D, 0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68, 0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253, 0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C, 0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E, 0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254, 0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241, 0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252, 0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD, 0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5, 0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0, 0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB, 0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4, 0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA, 0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7, 0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6, 0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9, 0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF, 0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6, 0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2, 0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC, 0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE, 0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC, 0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4, 0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1, 0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0, 0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2, 0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA, 0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB, 0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7, 0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0, 0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5, 0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4, 0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8, 0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48, 0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3, 0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A, 0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4, 0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC, 0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA, 0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6, 0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7, 0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6, 0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE, 0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267, 0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5, 0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256, 0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250, 0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370, 0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0, 0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455, 0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A, 0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1, 0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF, 0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6, 0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4, 0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1, 0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1, 0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED, 0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64, 0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8, 0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6, 0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB, 0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA, 0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7, 0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9, 0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71, 0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0, 0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9, 0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A, 0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF, 0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B, 0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1, 0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA, 0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65, 0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC, 0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC, 0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE, 0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD, 0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267, 0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC, 0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2, 0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C, 0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71, 0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF, 0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269, 0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5, 0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0, 0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48, 0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68, 0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2, 0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241, 0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240, 0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3, 0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42, 0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7, 0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5, 0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB, 0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA, 0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2, 0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E, 0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A, 0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B, 0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244, 0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF, 0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2, 0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1, 0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3, 0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2, 0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40, 0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1, 0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD, 0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC, 0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3, 0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851, 0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55, 0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856, 0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B, 0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857, 0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855, 0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56, 0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F, 0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50, 0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C, 0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846, 0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44, 0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71, 0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42, 0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F, 0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66, 0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70, 0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73, 0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79, 0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8, 0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4, 0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2, 0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41, 0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69, 0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60, 0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD, 0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74, 0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C, 0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77, 0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74, 0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD, 0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73, 0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78, 0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D, 0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A, 0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78, 0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB, 0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77, 0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4, 0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79, 0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3, 0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E, 0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255, 0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D, 0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA, 0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6, 0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F, 0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248, 0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245, 0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261, 0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265, 0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9, 0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260, 0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269, 0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B, 0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265, 0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250, 0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B, 0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647, 0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267, 0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258, 0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE, 0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645, 0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259, 0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF, 0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C, 0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253, 0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7, 0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268, 0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D, 0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252, 0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245, 0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256, 0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7, 0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D, 0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6, 0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7, 0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC, 0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1, 0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4, 0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7, 0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5, 0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED, 0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9, 0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF, 0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA, 0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA, 0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51, 0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF, 0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547, 0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543, 0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9, 0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3, 0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5, 0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52, 0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60, 0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49, 0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2, 0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE, 0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63, 0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1, 0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5, 0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C, 0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB, 0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3, 0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47, 0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9, 0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45, 0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0, 0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66, 0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA, 0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C, 0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4, 0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77, 0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271, 0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF, 0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE, 0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3, 0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E, 0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C, 0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A, 0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7, 0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E, 0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279, 0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B, 0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7, 0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9, 0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1, 0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79, 0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD, 0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2, 0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B, 0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7, 0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2, 0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED, 0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660, 0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9, 0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2, 0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB, 0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB, 0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1, 0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB, 0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640, 0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651, 0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE, 0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40, 0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48, 0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB, 0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8, 0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45, 0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE, 0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2, 0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC, 0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC, 0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA, 0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC, 0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB, 0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9, 0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52, 0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B, 0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54, 0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8, 0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271, 0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2, 0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF, 0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8, 0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1, 0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378, 0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C, 0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377, 0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262, 0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D, 0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260, 0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B, 0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E, 0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467, 0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466, 0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4, 0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7, 0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB, 0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579, 0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4, 0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5, 0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C, 0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5, 0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F, 0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861, 0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52, 0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56, 0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1, 0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59, 0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6, 0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6, 0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1, 0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5, 0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278, 0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E, 0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C, 0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271, 0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A, 0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C, 0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E, 0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A, 0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B, 0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656, 0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A, 0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649, 0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B, 0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F, 0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C, 0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A, 0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B, 0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64, 0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1, 0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A, 0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D, 0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC, 0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4, 0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F, 0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1, 0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB, 0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E, 0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1, 0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF, 0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA, 0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB, 0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3, 0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A, 0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E, 0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7, 0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663, 0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672, 0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55, 0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C, 0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56, 0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F, 0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52, 0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F, 0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53, 0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7, 0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60, 0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E, 0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61, 0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277, 0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD, 0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C, 0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B, 0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C, 0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB, 0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED, 0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC, 0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6, 0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7, 0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8, 0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7, 0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9, 0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66, 0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6, 0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67, 0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8, 0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60, 0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA, 0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9, 0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1, 0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E, 0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552, 0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A, 0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6, 0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7, 0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA, 0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9, 0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D, 0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F, 0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7, 0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6, 0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62, 0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867, 0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64, 0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64, 0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61, 0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E, 0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2, 0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF, 0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3, 0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7, 0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4, 0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6, 0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662, 0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79, 0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274, 0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275, 0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669, 0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76, 0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F, 0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555, 0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD, 0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1, 0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB, 0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD, 0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC, 0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E, 0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677, 0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1, 0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57, 0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E, 0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2, 0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278, 0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E, 0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A, 0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8, 0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A, 0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45, 0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68, 0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3, 0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66, 0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1, 0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2, 0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC, 0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1, 0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4, 0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4, 0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6, 0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB, 0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA, 0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3, 0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1, 0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2, 0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C, 0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C, 0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B, 0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279, 0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671, 0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677, 0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1, 0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2, 0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B, 0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558, 0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A, 0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA, 0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D, 0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8, 0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2, 0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8, 0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE, 0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4, 0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6, 0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3, 0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4, 0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2, 0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA, 0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41, 0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5, 0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4, 0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65, 0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63, 0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64, 0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5, 0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A, 0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4, 0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045, 0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046, 0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041, 0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274, 0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED, 0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0, 0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA, 0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D, 0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B, 0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260, 0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF, 0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2, 0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6, 0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC, 0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72, 0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049, 0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE, 0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3, 0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563, 0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46, 0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9, 0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2, 0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E, 0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70, 0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB, 0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60, 0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62, 0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B, 0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566, 0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7, 0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4, 0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A, 0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C, 0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9, 0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74, 0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF, 0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC, 0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68, 0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E, 0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B, 0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7, 0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66, 0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2, 0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4, 0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA, 0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0, 0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4, 0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569, 0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2, 0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2, 0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1, 0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4, 0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB, 0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9, 0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6, 0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF, 0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD, 0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7, 0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45, 0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4, 0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4, 0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B, 0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F, 0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62, 0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74, 0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76, 0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E, 0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C, 0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278, 0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470, 0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4, 0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6, 0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E, 0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47, 0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2, 0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB, 0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8, 0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5, 0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9, 0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471, 0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75, 0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1, 0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472, 0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF, 0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC, 0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0, 0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1, 0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9, 0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64, 0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA, 0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E, 0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76, 0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB, 0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF, 0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2, 0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC, 0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3, 0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5, 0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75, 0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0, 0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA, 0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE, 0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2, 0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1, 0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC, 0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF, 0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0, 0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8, 0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA, 0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA, 0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844, 0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE, 0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2, 0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3, 0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7, 0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB, 0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE, 0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D, 0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1, 0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79, 0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65, 0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68, 0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B, 0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2, 0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A, 0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4, 0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054, 0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A, 0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476, 0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4, 0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666, 0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3, 0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8, 0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575, 0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C, 0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A, 0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B, 0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED, 0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5, 0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB, 0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C, 0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB, 0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A, 0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0, 0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD, 0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3, 0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B, 0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5, 0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA, 0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576, 0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6, 0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB, 0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC, 0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE, 0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851, 0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8, 0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D, 0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F, 0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1, 0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5, 0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC, 0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3, 0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC, 0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849, 0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54, 0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF, 0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7, 0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3, 0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59, 0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A, 0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC, 0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7, 0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3, 0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146, 0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143, 0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9, 0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147, 0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A, 0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D, 0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3, 0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D, 0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D, 0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C, 0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473, 0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6, 0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72, 0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2, 0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6, 0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4, 0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7, 0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6, 0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE, 0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB, 0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0, 0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC, 0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD, 0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2, 0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5, 0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341, 0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5, 0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE, 0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340, 0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE, 0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE, 0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149, 0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7, 0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1, 0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8, 0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856, 0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870, 0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE, 0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC, 0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5, 0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2, 0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3, 0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED, 0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6, 0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE, 0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA, 0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B, 0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7, 0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC, 0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858, 0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B, 0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348, 0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346, 0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F, 0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C, 0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0, 0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E, 0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A, 0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1, 0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9, 0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC, 0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8, 0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873, 0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6, 0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0, 0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC, 0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9, 0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF, 0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1, 0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D, 0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A, 0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C, 0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3, 0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2, 0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7, 0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB, 0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF, 0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA, 0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3, 0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D, 0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB, 0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1, 0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342, 0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345, 0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA, 0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6, 0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7, 0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1, 0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4, 0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8, 0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA, 0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB, 0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6, 0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5, 0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB, 0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE, 0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5, 0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47, 0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A, 0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E, 0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1, 0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D, 0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E, 0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354, 0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351, 0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2, 0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F, 0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C, 0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63, 0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6, 0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68, 0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76, 0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA, 0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74, 0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA, 0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79, 0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC, 0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A, 0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC, 0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F, 0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9, 0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7, 0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA, 0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2, 0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB, 0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061, 0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064, 0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B, 0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062, 0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066, 0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0, 0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1, 0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478, 0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6, 0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0, 0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC, 0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3, 0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4, 0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8, 0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D, 0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045, 0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047, 0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F, 0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C, 0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE, 0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF, 0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7, 0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9, 0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865, 0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361, 0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB, 0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B, 0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA, 0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C, 0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153, 0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152, 0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE, 0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B, 0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD, 0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9, 0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4, 0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA, 0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF, 0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353, 0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358, 0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355, 0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5, 0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350, 0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1, 0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8, 0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9, 0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5, 0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF, 0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED, 0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD, 0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB, 0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2, 0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7, 0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C, 0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8, 0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0, 0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5, 0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB, 0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868, 0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65, 0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60, 0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57, 0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B, 0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63, 0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78, 0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7, 0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377, 0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376, 0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4, 0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA, 0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373, 0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368, 0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369, 0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2, 0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC, 0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75, 0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0, 0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB, 0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5, 0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE, 0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D, 0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA, 0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7, 0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB, 0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1, 0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5, 0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3, 0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0, 0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4, 0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6, 0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169, 0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3, 0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C, 0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD, 0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168, 0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E, 0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9, 0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E, 0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4, 0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071, 0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6, 0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072, 0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8, 0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2, 0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0, 0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6, 0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D, 0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1, 0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7, 0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1, 0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE, 0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942, 0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE, 0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA, 0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A, 0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9, 0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8, 0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D, 0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D, 0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1, 0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A, 0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B, 0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870, 0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D, 0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1, 0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB, 0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9, 0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA, 0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362, 0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC, 0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB, 0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873, 0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872, 0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E, 0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079, 0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD, 0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3, 0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365, 0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD, 0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7, 0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC, 0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE, 0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70, 0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42, 0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9, 0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6, 0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4, 0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B, 0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B, 0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE, 0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1, 0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF, 0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41, 0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42, 0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366, 0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741, 0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71, 0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6, 0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5, 0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055, 0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5, 0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744, 0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45, 0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45, 0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB, 0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F, 0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C, 0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2, 0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB, 0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46, 0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9, 0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877, 0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75, 0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878, 0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE, 0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0, 0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C, 0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD, 0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D, 0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061, 0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064, 0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062, 0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F, 0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F, 0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E, 0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA, 0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A, 0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD, 0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2, 0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D, 0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF, 0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745, 0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C, 0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5, 0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7, 0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3, 0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F, 0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9, 0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB, 0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47, 0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4, 0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B, 0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72, 0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76, 0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879, 0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD, 0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1, 0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D, 0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A, 0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9, 0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744, 0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3, 0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE, 0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9, 0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED, 0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8, 0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC, 0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8, 0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177, 0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9, 0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179, 0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1, 0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2, 0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4, 0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6, 0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA, 0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B, 0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4, 0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50, 0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F, 0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068, 0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57, 0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C, 0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9, 0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51, 0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF, 0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1, 0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA, 0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371, 0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB, 0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE, 0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A, 0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8, 0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A, 0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748, 0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7, 0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0, 0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4, 0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6, 0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB, 0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2, 0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A, 0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E, 0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B, 0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C, 0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E, 0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC, 0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC, 0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6, 0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9, 0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2, 0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7, 0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8, 0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0, 0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE, 0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4, 0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61, 0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B, 0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65, 0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1, 0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F, 0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5, 0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078, 0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C, 0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C, 0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53, 0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E, 0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41, 0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3, 0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E, 0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5, 0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED, 0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC, 0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4, 0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8, 0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A, 0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE, 0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6, 0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0, 0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2, 0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF, 0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765, 0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D, 0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F, 0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340, 0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8, 0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF, 0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9, 0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773, 0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C, 0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3, 0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776, 0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D, 0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774, 0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7, 0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5, 0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77, 0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74, 0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1, 0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8, 0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A, 0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD, 0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63, 0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A, 0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD, 0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA, 0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E, 0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0, 0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1, 0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78, 0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3, 0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B, 0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F, 0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC, 0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5, 0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8, 0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0, 0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA, 0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC, 0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD, 0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0, 0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF, 0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8, 0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD, 0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0, 0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4, 0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0, 0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA, 0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4, 0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB, 0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5, 0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2, 0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB, 0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59, 0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1, 0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6, 0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4, 0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A, 0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6, 0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55, 0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57, 0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54, 0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9, 0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62, 0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9, 0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774, 0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4, 0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9, 0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770, 0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758, 0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6, 0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD, 0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B, 0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E, 0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3, 0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778, 0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B, 0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2, 0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772, 0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E, 0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C, 0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D, 0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43, 0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41, 0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6, 0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC, 0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46, 0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54, 0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44, 0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53, 0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE, 0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D, 0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40, 0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB, 0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D, 0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51, 0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42, 0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A, 0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4, 0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54, 0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3, 0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8, 0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC, 0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4, 0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3, 0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4, 0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9, 0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6, 0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2, 0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7, 0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3, 0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2, 0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC, 0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2, 0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3, 0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF, 0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8, 0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF, 0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7, 0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB, 0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF, 0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0, 0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8, 0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6, 0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4, 0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5, 0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8, 0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5, 0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749, 0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9, 0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3, 0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC, 0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7, 0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68, 0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342, 0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8, 0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E, 0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB, 0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4, 0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7, 0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6, 0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8, 0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041, 0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB, 0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE, 0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA, 0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC, 0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047, 0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA, 0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5, 0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348, 0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7, 0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF, 0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2, 0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3, 0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D, 0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF, 0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD, 0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF, 0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB, 0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3, 0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9, 0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE, 0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6, 0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED, 0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0, 0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC, 0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF, 0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB, 0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE, 0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC, 0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68, 0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D, 0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA, 0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5, 0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0, 0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2, 0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED, 0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9, 0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD, 0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B, 0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF, 0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4, 0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB, 0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA, 0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0, 0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF, 0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9, 0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD, 0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61, 0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67, 0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4, 0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F, 0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D, 0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D, 0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3, 0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1, 0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67, 0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A, 0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D, 0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60, 0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC, 0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B, 0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69, 0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF, 0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9, 0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1, 0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5, 0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1, 0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0, 0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC, 0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE, 0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6, 0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB, 0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7, 0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7, 0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5, 0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF, 0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642, 0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643, 0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644, 0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640, 0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9, 0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8, 0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE, 0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E, 0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5, 0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0, 0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C, 0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2, 0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1, 0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC, 0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE, 0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8, 0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB, 0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E, 0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7, 0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9, 0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2, 0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352, 0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF, 0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE, 0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5, 0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6, 0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD, 0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5, 0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8, 0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF, 0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3, 0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF, 0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4, 0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6, 0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6, 0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442, 0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440, 0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70, 0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71, 0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73, 0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2, 0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA, 0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5, 0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4, 0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7, 0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C, 0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8, 0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6, 0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74, 0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7, 0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77, 0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA, 0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8, 0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5, 0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76, 0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF, 0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE, 0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB, 0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0, 0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B, 0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8, 0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC, 0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B, 0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E, 0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0, 0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356, 0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1, 0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446, 0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0, 0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB, 0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1, 0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1, 0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B, 0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8, 0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5, 0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041, 0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE, 0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447, 0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2, 0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2, 0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C, 0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C, 0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0, 0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052, 0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059, 0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057, 0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359, 0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A, 0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB, 0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644, 0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9, 0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA, 0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643, 0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7, 0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1, 0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647, 0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641, 0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF, 0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6, 0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0, 0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4, 0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A, 0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9, 0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E, 0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8, 0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E, 0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF, 0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6, 0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A, 0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7, 0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6, 0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA, 0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3, 0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4, 0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5, 0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0, 0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC, 0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7, 0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB, 0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8, 0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7, 0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF, 0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9, 0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3, 0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1, 0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5, 0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7, 0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA, 0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB, 0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3, 0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9, 0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE, 0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2, 0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC, 0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB, 0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5, 0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4, 0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6, 0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2, 0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF, 0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0, 0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD, 0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340, 0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE, 0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7, 0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7, 0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5, 0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8, 0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3, 0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D, 0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756, 0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757, 0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC, 0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE, 0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640, 0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D, 0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD, 0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5, 0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344, 0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A, 0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC, 0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7, 0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF, 0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5, 0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055, 0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8, 0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5, 0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7, 0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4, 0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1, 0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059, 0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7, 0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3, 0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7, 0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0, 0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73, 0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2, 0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366, 0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364, 0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C, 0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652, 0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F, 0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654, 0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE, 0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB, 0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC, 0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455, 0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED, 0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9, 0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8, 0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8, 0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7, 0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4, 0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC, 0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6, 0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348, 0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9, 0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542, 0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC, 0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A, 0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE, 0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9, 0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75, 0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5, 0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658, 0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656, 0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061, 0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063, 0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF, 0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF, 0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC, 0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B, 0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F, 0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7, 0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6, 0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7, 0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9, 0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659, 0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1, 0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0, 0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5, 0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1, 0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9, 0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7, 0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4, 0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5, 0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B, 0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458, 0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F, 0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A, 0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841, 0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA, 0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846, 0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5, 0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0, 0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD, 0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7, 0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3, 0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5, 0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7, 0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1, 0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE, 0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB, 0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145, 0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9, 0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143, 0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142, 0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD, 0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352, 0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB, 0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350, 0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC, 0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7, 0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543, 0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655, 0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE, 0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763, 0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3, 0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951, 0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE, 0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060, 0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF, 0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE, 0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8, 0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF, 0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD, 0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1, 0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46, 0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42, 0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44, 0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40, 0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD, 0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B, 0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079, 0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C, 0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465, 0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4, 0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A, 0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE, 0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848, 0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC, 0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC, 0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9, 0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7, 0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4, 0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146, 0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149, 0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359, 0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1, 0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE, 0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659, 0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF, 0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF, 0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC, 0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547, 0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B, 0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3, 0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF, 0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE, 0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2, 0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3, 0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4, 0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5, 0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1, 0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE, 0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED, 0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B, 0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3, 0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376, 0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C, 0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D, 0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374, 0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373, 0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F, 0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666, 0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3, 0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945, 0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943, 0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B, 0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944, 0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB, 0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC, 0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852, 0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44, 0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0, 0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0, 0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2, 0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3, 0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB, 0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3, 0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5, 0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6, 0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53, 0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7, 0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA, 0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8, 0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3, 0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5, 0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9, 0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD, 0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6, 0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB, 0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA, 0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3, 0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD, 0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9, 0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8, 0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED, 0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4, 0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E, 0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B, 0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50, 0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA, 0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4, 0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8, 0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E, 0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2, 0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B, 0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48, 0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855, 0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854, 0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5, 0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4, 0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D, 0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1, 0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766, 0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9, 0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441, 0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6, 0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4, 0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60, 0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73, 0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC, 0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6, 0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474, 0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F, 0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C, 0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C, 0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA, 0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5, 0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF, 0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6, 0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E, 0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F, 0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6, 0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4, 0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849, 0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D, 0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC, 0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD, 0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7, 0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442, 0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444, 0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8, 0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842, 0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7, 0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA, 0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB, 0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A, 0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F, 0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675, 0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68, 0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672, 0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74, 0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674, 0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70, 0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3, 0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0, 0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1, 0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B, 0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962, 0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963, 0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960, 0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB, 0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5, 0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F, 0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB, 0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7, 0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A, 0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5, 0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6, 0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE, 0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E, 0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C, 0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA, 0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE, 0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC, 0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1, 0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D, 0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55, 0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50, 0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865, 0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864, 0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874, 0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F, 0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862, 0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878, 0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E, 0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2, 0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872, 0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870, 0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7, 0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB, 0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9, 0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF, 0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED, 0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8, 0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45, 0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6, 0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5, 0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7, 0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3, 0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB, 0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5, 0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA, 0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7, 0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1, 0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9, 0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1, 0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED, 0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA, 0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6, 0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB, 0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6, 0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6, 0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2, 0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9, 0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC, 0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F, 0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161, 0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D, 0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A, 0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A, 0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE, 0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164, 0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153, 0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB, 0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C, 0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362, 0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D, 0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2, 0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE, 0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0, 0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375, 0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3, 0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366, 0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3, 0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2, 0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD, 0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7, 0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9, 0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8, 0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0, 0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668, 0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E, 0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667, 0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F, 0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669, 0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C, 0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A, 0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2, 0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C, 0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF, 0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644, 0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954, 0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956, 0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668, 0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671, 0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF, 0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78, 0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC, 0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC, 0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3, 0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2, 0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0, 0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2, 0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3, 0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B, 0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D, 0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A, 0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48, 0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2, 0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0, 0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47, 0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D, 0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377, 0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547, 0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D, 0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA, 0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59, 0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2, 0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD, 0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB, 0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC, 0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE, 0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0, 0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4, 0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1, 0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446, 0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3, 0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848, 0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB, 0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3, 0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7, 0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC, 0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E, 0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA, 0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2, 0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969, 0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB, 0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047, 0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6, 0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F, 0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6, 0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD, 0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE, 0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E, 0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C, 0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50, 0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174, 0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8, 0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379, 0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42, 0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8, 0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973, 0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6, 0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD, 0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E, 0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51, 0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53, 0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D, 0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA, 0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177, 0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E, 0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9, 0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549, 0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551, 0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5, 0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647, 0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957, 0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE, 0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44, 0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053, 0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9, 0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA, 0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC, 0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF, 0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7, 0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF, 0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62, 0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55, 0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE, 0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD, 0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2, 0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C, 0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1, 0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B, 0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F, 0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669, 0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9, 0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43, 0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6, 0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5, 0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2, 0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5, 0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7, 0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554, 0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC, 0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC, 0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF, 0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978, 0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1, 0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7, 0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B, 0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9, 0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055, 0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056, 0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A, 0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4, 0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342, 0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9, 0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440, 0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9, 0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F, 0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555, 0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3, 0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE, 0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1, 0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4, 0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB, 0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC, 0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552, 0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673, 0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9, 0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8, 0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD, 0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2, 0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1, 0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5, 0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8, 0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1, 0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5, 0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061, 0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060, 0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D, 0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D, 0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54, 0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD, 0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348, 0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443, 0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558, 0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8, 0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9, 0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556, 0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959, 0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55, 0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60, 0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2, 0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8, 0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6, 0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5, 0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5, 0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3, 0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1, 0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E, 0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA, 0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE, 0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D, 0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64, 0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67, 0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65, 0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B, 0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F, 0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240, 0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3, 0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1, 0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D, 0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5, 0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9, 0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB, 0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6, 0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA, 0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB, 0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD, 0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678, 0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1, 0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559, 0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D, 0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB, 0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2, 0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852, 0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6, 0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A, 0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5, 0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD, 0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA, 0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C, 0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D, 0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9, 0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564, 0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4, 0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9, 0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA, 0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC, 0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068, 0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6, 0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70, 0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66, 0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC, 0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3, 0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4, 0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3, 0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5, 0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856, 0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB, 0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6, 0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC, 0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7, 0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE, 0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A, 0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0, 0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352, 0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D, 0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5, 0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF, 0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA, 0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0, 0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE, 0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76, 0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79, 0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2, 0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A, 0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C, 0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71, 0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243, 0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75, 0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD, 0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7, 0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3, 0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA, 0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0, 0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2, 0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD, 0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449, 0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1, 0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356, 0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B, 0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572, 0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574, 0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD, 0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF, 0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF, 0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6, 0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1, 0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570, 0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB, 0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F, 0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857, 0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC, 0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D, 0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8, 0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B, 0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A, 0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE, 0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7, 0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3, 0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0, 0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC, 0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA, 0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D, 0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC, 0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4, 0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9, 0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB, 0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E, 0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B, 0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79, 0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7, 0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77, 0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2, 0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359, 0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6, 0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD, 0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB, 0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1, 0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450, 0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E, 0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8, 0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3, 0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC, 0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0, 0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1, 0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2, 0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578, 0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A, 0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6, 0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF, 0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4, 0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3, 0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD, 0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF, 0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9, 0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB, 0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7, 0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE, 0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8, 0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3, 0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7, 0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF, 0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867, 0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0, 0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A, 0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871, 0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862, 0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861, 0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2, 0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7, 0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4, 0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F, 0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B, 0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678, 0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF, 0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651, 0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0, 0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB, 0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC, 0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453, 0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3, 0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF, 0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1, 0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2, 0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7, 0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3, 0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE, 0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248, 0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072, 0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF, 0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249, 0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4, 0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB, 0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8, 0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964, 0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6, 0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1, 0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652, 0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2, 0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D, 0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0, 0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB, 0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4, 0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5, 0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3, 0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA, 0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B, 0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D, 0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D, 0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4, 0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9, 0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5, 0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC, 0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD, 0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6, 0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569, 0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5, 0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1, 0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED, 0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969, 0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365, 0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE, 0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF, 0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A, 0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F, 0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167, 0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F, 0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177, 0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6, 0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8, 0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E, 0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153, 0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1, 0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC, 0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF, 0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242, 0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149, 0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE, 0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF, 0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE, 0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2, 0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6, 0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146, 0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148, 0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1, 0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5, 0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9, 0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD, 0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1, 0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5, 0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240, 0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB, 0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF, 0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3, 0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7, 0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB, 0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340, 0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161, 0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246, 0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0 }; static const WCHAR oem2uni950[] = { /* Big5 --> Unicode pairs */ 0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002, 0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A, 0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026, 0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52, 0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56, 0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31, 0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34, 0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35, 0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37, 0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39, 0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B, 0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D, 0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F, 0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41, 0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43, 0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B, 0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018, 0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D, 0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03, 0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7, 0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3, 0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605, 0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0, 0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105, 0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD, 0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E, 0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60, 0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7, 0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C, 0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267, 0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261, 0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65, 0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A, 0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF, 0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E, 0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642, 0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193, 0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197, 0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223, 0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68, 0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0, 0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103, 0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B, 0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E, 0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F, 0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B, 0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163, 0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581, 0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585, 0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F, 0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B, 0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534, 0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594, 0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C, 0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D, 0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550, 0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2, 0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571, 0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11, 0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15, 0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19, 0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163, 0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167, 0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022, 0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026, 0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341, 0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22, 0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26, 0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A, 0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E, 0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32, 0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36, 0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A, 0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44, 0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48, 0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C, 0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50, 0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54, 0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58, 0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392, 0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396, 0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A, 0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E, 0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3, 0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7, 0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2, 0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6, 0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA, 0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE, 0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3, 0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7, 0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106, 0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A, 0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E, 0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112, 0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116, 0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A, 0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E, 0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122, 0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126, 0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9, 0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB, 0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01, 0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86, 0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165, 0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201, 0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C, 0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08, 0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1, 0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E, 0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203, 0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3, 0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927, 0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53, 0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38, 0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1, 0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72, 0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D, 0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D, 0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39, 0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92, 0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0, 0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD, 0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143, 0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E, 0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206, 0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE, 0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348, 0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384, 0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC, 0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D, 0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A, 0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF, 0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208, 0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F, 0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9, 0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728, 0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB, 0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34, 0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B, 0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC, 0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15, 0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D, 0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8, 0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7, 0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE, 0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A, 0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8, 0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305, 0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF, 0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360, 0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF, 0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE, 0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8, 0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA, 0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5, 0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA, 0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974, 0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C, 0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02, 0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01, 0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A, 0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251, 0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C, 0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63, 0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38, 0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF, 0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6, 0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529, 0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533, 0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF, 0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3, 0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB, 0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53, 0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6, 0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19, 0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10, 0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6, 0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD, 0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147, 0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171, 0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211, 0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3, 0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370, 0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C, 0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B, 0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408, 0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412, 0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733, 0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C, 0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A, 0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978, 0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982, 0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87, 0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA, 0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06, 0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B, 0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C, 0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B, 0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8, 0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3, 0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731, 0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B, 0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59, 0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55, 0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E, 0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E, 0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36, 0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003, 0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F, 0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3, 0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C, 0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272, 0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C, 0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32, 0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47, 0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B, 0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51, 0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43, 0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63, 0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E, 0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48, 0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D, 0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225, 0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228, 0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC, 0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D, 0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426, 0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443, 0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B, 0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B, 0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436, 0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431, 0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA, 0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A, 0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747, 0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F, 0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D, 0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3, 0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4, 0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D, 0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C, 0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40, 0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90, 0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB, 0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A, 0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64, 0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8, 0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1, 0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212, 0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296, 0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D, 0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279, 0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298, 0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291, 0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538, 0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E, 0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C, 0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746, 0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65, 0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99, 0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85, 0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90, 0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96, 0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72, 0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76, 0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82, 0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078, 0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4, 0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B, 0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF, 0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF, 0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096, 0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B, 0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292, 0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2, 0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55, 0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3, 0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0, 0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4, 0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA, 0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6, 0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631, 0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56, 0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E, 0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D, 0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C, 0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83, 0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69, 0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F, 0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152, 0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176, 0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B, 0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230, 0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE, 0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353, 0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378, 0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7, 0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478, 0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477, 0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C, 0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C, 0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B, 0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783, 0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761, 0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C, 0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944, 0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4, 0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6, 0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3, 0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2, 0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63, 0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C, 0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48, 0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1, 0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1, 0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16, 0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78, 0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95, 0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27, 0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F, 0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD, 0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014, 0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A, 0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029, 0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215, 0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F, 0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF, 0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB, 0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB, 0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC, 0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD, 0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8, 0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC, 0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC, 0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C, 0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600, 0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607, 0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B, 0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773, 0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797, 0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789, 0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A, 0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772, 0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F, 0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8, 0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5, 0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC, 0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3, 0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1, 0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1, 0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB, 0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC, 0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E, 0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C, 0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267, 0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9, 0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8, 0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D, 0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684, 0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5, 0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941, 0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79, 0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C, 0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5, 0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB, 0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF, 0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3, 0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD, 0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC, 0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3, 0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E, 0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB, 0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5, 0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7, 0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C, 0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644, 0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752, 0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE, 0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF, 0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD, 0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF, 0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0, 0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE, 0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192, 0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243, 0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B, 0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3, 0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B, 0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0, 0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8, 0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2, 0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4, 0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1, 0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF, 0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0, 0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE, 0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F, 0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8, 0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03, 0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6, 0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3, 0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5, 0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D, 0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7, 0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D, 0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08, 0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85, 0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C, 0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020, 0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D, 0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046, 0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A, 0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316, 0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301, 0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1, 0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE, 0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F, 0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2, 0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627, 0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631, 0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3, 0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC, 0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9, 0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4, 0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF, 0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9, 0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A, 0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2, 0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B, 0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25, 0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17, 0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36, 0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27, 0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35, 0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA, 0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD, 0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230, 0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9, 0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA, 0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0, 0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F, 0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB, 0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3, 0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688, 0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5, 0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709, 0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707, 0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C, 0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948, 0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1, 0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81, 0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02, 0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07, 0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E, 0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D, 0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5, 0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC, 0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE, 0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222, 0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3, 0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5, 0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7, 0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4, 0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF, 0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679, 0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B, 0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02, 0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74, 0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC, 0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA, 0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4, 0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1, 0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD, 0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C, 0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB, 0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8, 0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999, 0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D, 0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025, 0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006, 0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012, 0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014, 0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B, 0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE, 0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B, 0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5, 0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6, 0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254, 0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F, 0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8, 0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC, 0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA, 0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1, 0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6, 0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F, 0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4, 0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F, 0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11, 0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B, 0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23, 0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09, 0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3, 0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5, 0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51, 0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD, 0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0, 0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE, 0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD, 0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91, 0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065, 0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069, 0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A, 0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085, 0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308, 0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F, 0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F, 0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D, 0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D, 0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599, 0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649, 0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C, 0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714, 0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838, 0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839, 0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3, 0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D, 0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C, 0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813, 0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89, 0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28, 0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A, 0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66, 0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93, 0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A, 0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A, 0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94, 0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9, 0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279, 0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8, 0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409, 0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE, 0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A, 0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7, 0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC, 0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B, 0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE, 0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728, 0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838, 0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825, 0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832, 0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F, 0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957, 0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7, 0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8, 0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06, 0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17, 0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22, 0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A, 0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B, 0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5, 0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015, 0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F, 0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105, 0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8, 0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A, 0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC, 0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B, 0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B, 0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338, 0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334, 0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336, 0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328, 0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA, 0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C, 0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877, 0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879, 0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C, 0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13, 0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48, 0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2, 0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4, 0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006, 0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4, 0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8, 0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2, 0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8, 0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9, 0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661, 0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658, 0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC, 0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32, 0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D, 0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C, 0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076, 0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074, 0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F, 0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0, 0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9, 0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F, 0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E, 0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A, 0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561, 0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556, 0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564, 0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C, 0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557, 0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF, 0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0, 0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835, 0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962, 0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66, 0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62, 0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70, 0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2, 0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08, 0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D, 0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B, 0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29, 0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27, 0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36, 0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8, 0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35, 0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69, 0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E, 0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C, 0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0, 0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6, 0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5, 0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5, 0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA, 0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248, 0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396, 0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367, 0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9, 0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B, 0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399, 0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F, 0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368, 0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551, 0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F, 0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C, 0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB, 0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A, 0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E, 0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881, 0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5, 0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7, 0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4, 0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894, 0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1, 0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB, 0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC, 0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1, 0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA, 0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF, 0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9, 0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5, 0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA, 0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1, 0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4, 0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6, 0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD, 0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281, 0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313, 0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A, 0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D, 0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C, 0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562, 0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5, 0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E, 0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737, 0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738, 0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E, 0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB, 0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28, 0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19, 0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97, 0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71, 0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40, 0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F, 0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D, 0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE, 0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046, 0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B, 0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202, 0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239, 0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378, 0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB, 0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389, 0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C, 0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A, 0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4, 0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1, 0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E, 0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896, 0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F, 0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25, 0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B, 0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9, 0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA, 0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE, 0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019, 0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023, 0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015, 0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022, 0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8, 0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE, 0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7, 0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A, 0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670, 0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C, 0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0, 0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A, 0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5, 0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085, 0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096, 0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1, 0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269, 0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A, 0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7, 0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598, 0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594, 0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3, 0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2, 0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1, 0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599, 0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834, 0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821, 0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA, 0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F, 0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73, 0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3, 0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31, 0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47, 0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40, 0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1, 0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D, 0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1, 0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0, 0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115, 0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168, 0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109, 0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249, 0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0, 0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD, 0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1, 0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376, 0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452, 0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566, 0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590, 0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674, 0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A, 0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF, 0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5, 0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905, 0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7, 0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3, 0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912, 0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E, 0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D, 0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF, 0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F, 0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32, 0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25, 0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58, 0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D, 0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D, 0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D, 0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19, 0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72, 0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A, 0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136, 0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284, 0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334, 0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433, 0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436, 0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426, 0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B, 0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3, 0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0, 0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693, 0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED, 0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D, 0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00, 0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5, 0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46, 0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D, 0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F, 0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68, 0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72, 0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70, 0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5, 0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155, 0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E, 0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C, 0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C, 0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D, 0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1, 0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457, 0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC, 0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438, 0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407, 0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF, 0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB, 0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857, 0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983, 0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55, 0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54, 0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34, 0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61, 0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3, 0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0, 0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF, 0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81, 0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA, 0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6, 0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C, 0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038, 0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5, 0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165, 0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223, 0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210, 0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F, 0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592, 0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B, 0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D, 0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5, 0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF, 0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806, 0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF, 0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE, 0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1, 0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2, 0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC, 0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7, 0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF, 0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3, 0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3, 0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7, 0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF, 0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6, 0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713, 0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857, 0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C, 0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852, 0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9, 0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC, 0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69, 0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9, 0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC, 0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148, 0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9, 0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C, 0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134, 0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137, 0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E, 0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D, 0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414, 0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417, 0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0, 0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688, 0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D, 0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A, 0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975, 0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968, 0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979, 0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B, 0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF, 0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF, 0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90, 0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5, 0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB, 0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4, 0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4, 0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164, 0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C, 0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E, 0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A, 0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F, 0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455, 0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F, 0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576, 0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601, 0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF, 0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF, 0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E, 0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C, 0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762, 0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897, 0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C, 0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A, 0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD, 0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14, 0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0, 0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E, 0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5, 0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81, 0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69, 0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8, 0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086, 0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178, 0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B, 0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205, 0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D, 0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B, 0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C, 0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469, 0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C, 0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708, 0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB, 0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A, 0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9, 0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1, 0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C, 0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73, 0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87, 0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71, 0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E, 0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E, 0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89, 0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4, 0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5, 0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF, 0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4, 0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09, 0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2, 0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042, 0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050, 0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D, 0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112, 0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169, 0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238, 0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B, 0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234, 0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239, 0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698, 0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB, 0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB, 0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774, 0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813, 0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC, 0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3, 0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9, 0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20, 0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6, 0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF, 0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9, 0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282, 0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600, 0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614, 0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E, 0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608, 0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716, 0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893, 0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D, 0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924, 0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6, 0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8, 0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7, 0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8, 0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D, 0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B, 0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54, 0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46, 0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F, 0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163, 0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175, 0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454, 0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A, 0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D, 0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7, 0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D, 0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1, 0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B, 0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4, 0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC, 0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49, 0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14, 0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29, 0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F, 0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF, 0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32, 0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F, 0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01, 0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194, 0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184, 0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296, 0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463, 0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504, 0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B, 0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3, 0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761, 0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3, 0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F, 0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA, 0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1, 0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97, 0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8, 0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD, 0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C, 0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA, 0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA, 0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8, 0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC, 0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF, 0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150, 0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A, 0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA, 0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B, 0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4, 0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C, 0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3, 0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA, 0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722, 0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755, 0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902, 0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD, 0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6, 0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D, 0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA, 0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91, 0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D, 0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2, 0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC, 0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13, 0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C, 0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062, 0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118, 0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177, 0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285, 0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293, 0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291, 0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3, 0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C, 0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700, 0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817, 0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903, 0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1, 0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41, 0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3, 0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104, 0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9, 0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105, 0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289, 0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2, 0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632, 0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653, 0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636, 0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F, 0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE, 0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09, 0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C, 0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9, 0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D, 0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61, 0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD, 0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71, 0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167, 0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182, 0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E, 0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E, 0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194, 0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F, 0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488, 0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493, 0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE, 0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC, 0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575, 0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB, 0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F, 0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19, 0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A, 0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED, 0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4, 0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C, 0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54, 0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78, 0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70, 0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5, 0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F, 0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256, 0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469, 0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480, 0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F, 0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622, 0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E, 0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B, 0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA, 0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0, 0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D, 0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE, 0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4, 0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0, 0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4, 0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC, 0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA, 0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9, 0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77, 0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B, 0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A, 0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A, 0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513, 0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514, 0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506, 0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760, 0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759, 0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B, 0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912, 0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC, 0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95, 0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9, 0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6, 0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB, 0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0, 0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC, 0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC, 0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F, 0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D, 0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F, 0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D, 0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26, 0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25, 0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D, 0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127, 0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B, 0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7, 0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1, 0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7, 0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1, 0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709, 0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F, 0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3, 0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918, 0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB, 0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9, 0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27, 0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F, 0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9, 0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52, 0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110, 0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD, 0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659, 0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664, 0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665, 0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662, 0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7, 0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34, 0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A, 0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A, 0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA, 0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1, 0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA, 0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD, 0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE, 0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9, 0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D, 0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B, 0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62, 0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35, 0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77, 0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1, 0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7, 0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6, 0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE, 0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8, 0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9, 0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368, 0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F, 0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D, 0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7, 0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F, 0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC, 0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E, 0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA, 0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4, 0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6, 0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11, 0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E, 0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79, 0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE, 0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8, 0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259, 0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568, 0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D, 0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F, 0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861, 0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B, 0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6, 0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00, 0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE, 0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED, 0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B, 0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44, 0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39, 0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38, 0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075, 0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C, 0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320, 0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F, 0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304, 0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321, 0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB, 0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5, 0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D, 0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C, 0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838, 0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839, 0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E, 0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED, 0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC, 0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91, 0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28, 0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4, 0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F, 0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E, 0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687, 0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1, 0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24, 0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC, 0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B, 0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2, 0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232, 0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8, 0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC, 0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582, 0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80, 0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C, 0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97, 0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE, 0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1, 0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4, 0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC, 0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE, 0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE, 0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC, 0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246, 0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0, 0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642, 0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA, 0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD, 0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4, 0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA, 0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D, 0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0, 0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2, 0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E, 0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32, 0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31, 0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39, 0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F, 0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071, 0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073, 0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2, 0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9, 0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271, 0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C, 0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B, 0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667, 0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2, 0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA, 0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936, 0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC, 0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B, 0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04, 0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73, 0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8, 0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B, 0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E, 0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F, 0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082, 0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E, 0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328, 0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B, 0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B, 0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA, 0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6, 0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C, 0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846, 0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF, 0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD, 0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF, 0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB, 0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695, 0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38, 0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4, 0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA, 0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC, 0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3, 0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE, 0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF, 0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006, 0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB, 0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377, 0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515, 0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD, 0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E, 0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60, 0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27, 0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21, 0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E, 0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59, 0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077, 0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A, 0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0, 0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9, 0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2, 0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4, 0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B, 0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63, 0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55, 0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087, 0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC, 0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396, 0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC, 0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397, 0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5, 0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB, 0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6, 0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F, 0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA, 0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E, 0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03, 0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D, 0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8, 0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60, 0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133, 0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2, 0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2, 0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500, 0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5, 0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B, 0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D, 0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D, 0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A, 0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587, 0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7, 0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69, 0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D, 0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D, 0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85, 0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8, 0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA, 0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7, 0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9, 0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956, 0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58, 0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F, 0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A, 0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76, 0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54, 0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B, 0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1, 0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC, 0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD, 0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8, 0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A, 0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB, 0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC, 0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19, 0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6, 0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72, 0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97, 0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8, 0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC, 0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D, 0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA, 0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6, 0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030, 0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF, 0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A, 0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6, 0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF, 0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C, 0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA, 0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611, 0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607, 0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964, 0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C, 0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B, 0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81, 0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB, 0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1, 0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951, 0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37, 0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79, 0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F, 0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138, 0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914, 0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE, 0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9, 0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2, 0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6, 0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50, 0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617, 0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822, 0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C, 0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D, 0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B, 0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E, 0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438, 0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738, 0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867, 0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43, 0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54, 0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF, 0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D, 0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66, 0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8, 0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4, 0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524, 0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058, 0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E, 0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F, 0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972, 0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16, 0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61, 0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452, 0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1, 0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D, 0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31, 0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7, 0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94, 0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523, 0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10, 0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63, 0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94, 0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831, 0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463, 0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F, 0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57, 0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54, 0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F, 0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C, 0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7, 0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839, 0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96, 0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A, 0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6, 0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58, 0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C, 0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72, 0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C, 0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1, 0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871, 0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC, 0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477, 0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C, 0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D, 0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78, 0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A, 0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B, 0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C, 0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07, 0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7, 0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F, 0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93, 0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198, 0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720, 0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF, 0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14, 0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8, 0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD, 0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C, 0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F, 0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B, 0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80, 0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250, 0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F, 0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A, 0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E, 0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14, 0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08, 0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22, 0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12, 0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210, 0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D, 0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF, 0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C, 0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B, 0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56, 0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A, 0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75, 0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74, 0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C, 0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266, 0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A, 0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E, 0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A, 0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18, 0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F, 0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C, 0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5, 0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75, 0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280, 0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E, 0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B, 0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620, 0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62, 0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E, 0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41, 0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F, 0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C, 0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE, 0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E, 0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A, 0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C, 0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F, 0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447, 0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741, 0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B, 0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6, 0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E, 0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7, 0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28, 0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88, 0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A, 0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0, 0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89, 0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05, 0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2, 0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8, 0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4, 0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7, 0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A, 0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F, 0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B, 0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288, 0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274, 0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3, 0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747, 0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748, 0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B, 0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78, 0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B, 0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69, 0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95, 0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65, 0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A, 0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3, 0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5, 0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394, 0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594, 0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034, 0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092, 0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285, 0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A, 0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9, 0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5, 0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630, 0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33, 0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D, 0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74, 0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C, 0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79, 0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C, 0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82, 0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E, 0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232, 0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC, 0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392, 0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481, 0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B, 0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C, 0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F, 0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463, 0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9, 0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B, 0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780, 0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774, 0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C, 0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF, 0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1, 0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6, 0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8, 0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65, 0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47, 0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5, 0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F, 0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA, 0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6, 0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14, 0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23, 0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E, 0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D, 0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B, 0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033, 0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022, 0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013, 0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C, 0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4, 0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6, 0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF, 0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8, 0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609, 0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608, 0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D, 0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610, 0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C, 0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B, 0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774, 0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F, 0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D, 0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794, 0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE, 0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB, 0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4, 0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0, 0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6, 0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD, 0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80, 0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD, 0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF, 0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098, 0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084, 0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A, 0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB, 0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2, 0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1, 0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6, 0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D, 0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540, 0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF, 0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5, 0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB, 0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F, 0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB, 0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F, 0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5, 0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0, 0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B, 0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC, 0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8, 0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4, 0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670, 0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56, 0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD, 0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2, 0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0, 0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A, 0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3, 0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1, 0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB, 0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6, 0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC, 0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2, 0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396, 0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1, 0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3, 0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6, 0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0, 0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE, 0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5, 0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C, 0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794, 0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5, 0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D, 0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE, 0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA, 0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4, 0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9, 0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE, 0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C, 0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7, 0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA, 0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6, 0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8, 0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8, 0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23, 0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4, 0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5, 0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86, 0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072, 0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047, 0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040, 0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044, 0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242, 0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B, 0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB, 0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8, 0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314, 0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0, 0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF, 0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635, 0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633, 0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634, 0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710, 0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA, 0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8, 0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB, 0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD, 0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE, 0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE, 0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC, 0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE, 0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9, 0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB, 0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6, 0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20, 0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D, 0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12, 0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04, 0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11, 0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01, 0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F, 0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C, 0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10, 0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1, 0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5, 0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A, 0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E, 0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB, 0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3, 0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8, 0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5, 0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7, 0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8, 0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E, 0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA, 0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703, 0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7, 0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8, 0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805, 0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809, 0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C, 0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5, 0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE, 0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00, 0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79, 0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03, 0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91, 0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E, 0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8, 0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8, 0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3, 0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5, 0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6, 0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294, 0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307, 0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A, 0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC, 0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C, 0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA, 0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3, 0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C, 0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867, 0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04, 0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1, 0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD, 0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE, 0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4, 0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651, 0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E, 0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022, 0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4, 0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6, 0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020, 0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031, 0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193, 0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8, 0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252, 0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262, 0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526, 0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7, 0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF, 0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511, 0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB, 0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E, 0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702, 0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2, 0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC, 0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7, 0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E, 0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D, 0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17, 0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C, 0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03, 0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF, 0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00, 0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8, 0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33, 0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A, 0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088, 0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D, 0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097, 0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219, 0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356, 0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336, 0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B, 0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341, 0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359, 0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A, 0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340, 0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6, 0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A, 0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712, 0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849, 0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B, 0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C, 0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F, 0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D, 0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828, 0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825, 0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D, 0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082, 0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8, 0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25, 0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76, 0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58, 0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91, 0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86, 0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97, 0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82, 0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B, 0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16, 0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75, 0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1, 0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2, 0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0, 0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6, 0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1, 0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276, 0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE, 0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301, 0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6, 0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9, 0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4, 0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8, 0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4, 0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F, 0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4, 0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA, 0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B, 0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723, 0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A, 0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C, 0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828, 0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829, 0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954, 0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953, 0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC, 0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA, 0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86, 0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C, 0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10, 0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F, 0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09, 0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A, 0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85, 0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E, 0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F, 0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C, 0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D, 0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3, 0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E, 0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9, 0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100, 0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333, 0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351, 0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341, 0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342, 0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308, 0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324, 0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329, 0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353, 0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327, 0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2, 0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691, 0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686, 0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5, 0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695, 0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690, 0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D, 0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880, 0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883, 0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12, 0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4, 0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5, 0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3, 0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF, 0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6, 0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA, 0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8, 0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4, 0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5, 0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F, 0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F, 0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061, 0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B, 0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D, 0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062, 0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069, 0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046, 0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057, 0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D, 0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3, 0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576, 0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534, 0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536, 0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545, 0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E, 0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B, 0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707, 0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6, 0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED, 0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B, 0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE, 0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC, 0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810, 0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1, 0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804, 0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55, 0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35, 0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65, 0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57, 0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44, 0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E, 0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70, 0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56, 0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E, 0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E, 0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20, 0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26, 0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12, 0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E, 0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9, 0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38, 0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A, 0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0, 0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF, 0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8, 0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA, 0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0, 0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382, 0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD, 0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E, 0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E, 0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D, 0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B, 0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381, 0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553, 0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B, 0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718, 0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C, 0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB, 0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC, 0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2, 0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C, 0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880, 0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896, 0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4, 0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C, 0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33, 0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F, 0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A, 0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3, 0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2, 0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00, 0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6, 0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD, 0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD, 0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5, 0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0, 0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7, 0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA, 0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4, 0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3, 0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106, 0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6, 0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E, 0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D, 0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318, 0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F, 0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8, 0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD, 0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC, 0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4, 0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE, 0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC, 0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689, 0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D, 0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733, 0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735, 0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D, 0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845, 0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969, 0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961, 0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6, 0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90, 0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25, 0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33, 0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31, 0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32, 0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94, 0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35, 0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A, 0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41, 0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A, 0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95, 0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA, 0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1, 0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F, 0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043, 0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119, 0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C, 0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127, 0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238, 0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232, 0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8, 0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4, 0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395, 0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9, 0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D, 0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E, 0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397, 0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387, 0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659, 0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2, 0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0, 0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8, 0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC, 0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852, 0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2, 0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1, 0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899, 0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC, 0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982, 0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30, 0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39, 0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D, 0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79, 0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF, 0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD, 0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1, 0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C, 0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA, 0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3, 0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9, 0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153, 0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1, 0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9, 0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8, 0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588, 0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671, 0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804, 0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095, 0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3, 0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D, 0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082, 0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312, 0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591, 0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577, 0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588, 0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3, 0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C, 0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1, 0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837, 0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823, 0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825, 0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F, 0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838, 0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961, 0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A, 0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6, 0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95, 0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A, 0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9, 0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C, 0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA, 0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1, 0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30, 0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41, 0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51, 0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A, 0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59, 0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38, 0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40, 0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58, 0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9, 0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE, 0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A, 0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113, 0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1, 0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110, 0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A, 0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE, 0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3, 0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0, 0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5, 0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD, 0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3, 0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB, 0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9, 0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564, 0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C, 0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0, 0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B, 0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A, 0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3, 0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC, 0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6, 0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6, 0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1, 0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970, 0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6, 0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD, 0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A, 0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD, 0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1, 0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915, 0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B, 0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97, 0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0, 0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC, 0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49, 0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45, 0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41, 0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33, 0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B, 0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68, 0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28, 0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39, 0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65, 0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77, 0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66, 0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120, 0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E, 0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122, 0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A, 0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288, 0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B, 0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322, 0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332, 0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335, 0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430, 0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421, 0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423, 0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432, 0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C, 0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6, 0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7, 0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746, 0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745, 0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C, 0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864, 0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871, 0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869, 0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974, 0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02, 0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04, 0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A, 0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C, 0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45, 0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1, 0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53, 0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F, 0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52, 0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F, 0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65, 0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1, 0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050, 0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A, 0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D, 0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE, 0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204, 0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275, 0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423, 0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7, 0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410, 0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3, 0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5, 0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB, 0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9, 0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411, 0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5, 0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA, 0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE, 0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2, 0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8, 0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3, 0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB, 0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7, 0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856, 0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9, 0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6, 0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2, 0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998, 0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB, 0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59, 0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44, 0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51, 0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F, 0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE, 0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84, 0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3, 0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC, 0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8, 0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7, 0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE, 0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8, 0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC, 0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034, 0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104, 0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9, 0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107, 0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164, 0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201, 0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A, 0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200, 0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206, 0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C, 0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205, 0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C, 0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688, 0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2, 0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0, 0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807, 0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9, 0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD, 0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4, 0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2, 0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1, 0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8, 0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B, 0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC, 0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD, 0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9, 0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF, 0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8, 0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2, 0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864, 0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F, 0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859, 0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863, 0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4, 0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1, 0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8, 0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0, 0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD, 0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8, 0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71, 0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72, 0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67, 0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E, 0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5, 0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7, 0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7, 0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145, 0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146, 0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140, 0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225, 0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB, 0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420, 0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F, 0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437, 0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426, 0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435, 0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440, 0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7, 0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E, 0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686, 0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B, 0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678, 0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938, 0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F, 0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942, 0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948, 0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933, 0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978, 0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F, 0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941, 0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B, 0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951, 0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B, 0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43, 0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B, 0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9, 0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6, 0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F, 0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1, 0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD, 0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7, 0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF, 0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC, 0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E, 0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF, 0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97, 0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154, 0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141, 0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178, 0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158, 0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F, 0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D, 0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C, 0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C, 0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340, 0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A, 0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457, 0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E, 0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454, 0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD, 0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983, 0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7, 0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8, 0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED, 0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5, 0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760, 0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769, 0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D, 0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894, 0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885, 0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879, 0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B, 0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979, 0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12, 0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13, 0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2, 0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64, 0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72, 0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70, 0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63, 0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88, 0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F, 0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B, 0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94, 0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D, 0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C, 0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB, 0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160, 0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B, 0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E, 0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144, 0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244, 0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1, 0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479, 0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451, 0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430, 0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459, 0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507, 0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434, 0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432, 0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B, 0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F, 0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C, 0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E, 0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433, 0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B, 0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450, 0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C, 0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D, 0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701, 0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6, 0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE, 0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0, 0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5, 0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2, 0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86, 0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77, 0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83, 0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C, 0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64, 0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85, 0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91, 0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D, 0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92, 0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1, 0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3, 0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB, 0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01, 0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08, 0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F, 0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110, 0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116, 0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E, 0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230, 0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265, 0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A, 0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F, 0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236, 0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254, 0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E, 0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232, 0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B, 0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697, 0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8, 0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778, 0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E, 0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF, 0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD, 0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED, 0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6, 0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3, 0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4, 0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF, 0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280, 0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330, 0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C, 0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C, 0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA, 0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9, 0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898, 0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874, 0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891, 0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888, 0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE, 0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5, 0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED, 0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0, 0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD, 0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77, 0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82, 0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A, 0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89, 0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D, 0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59, 0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7, 0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9, 0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43, 0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128, 0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173, 0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C, 0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A, 0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A, 0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227, 0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B, 0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472, 0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466, 0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E, 0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460, 0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C, 0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477, 0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0, 0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722, 0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0, 0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC, 0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E, 0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE, 0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD, 0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA, 0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993, 0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9, 0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5, 0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D, 0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0, 0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE, 0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25, 0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E, 0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A, 0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12, 0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73, 0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40, 0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB, 0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05, 0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C, 0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D, 0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187, 0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185, 0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186, 0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253, 0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343, 0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462, 0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472, 0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502, 0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616, 0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611, 0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781, 0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E, 0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783, 0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD, 0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E, 0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2, 0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B, 0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993, 0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990, 0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F, 0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB, 0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C, 0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96, 0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E, 0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99, 0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF, 0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7, 0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1, 0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE, 0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC, 0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC, 0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9, 0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2, 0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024, 0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186, 0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C, 0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4, 0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE, 0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB, 0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD, 0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0, 0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2, 0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B, 0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6, 0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0, 0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB, 0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733, 0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740, 0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719, 0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741, 0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732, 0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712, 0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742, 0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724, 0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7, 0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA, 0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6, 0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB, 0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E, 0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB, 0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F, 0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69, 0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96, 0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D, 0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07, 0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00, 0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E, 0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120, 0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A, 0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A, 0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5, 0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A, 0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D, 0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279, 0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE, 0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2, 0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A, 0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7, 0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D, 0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1, 0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A, 0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782, 0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F, 0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD, 0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907, 0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9, 0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD, 0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7, 0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61, 0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5, 0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130, 0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6, 0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD, 0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1, 0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C, 0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649, 0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640, 0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E, 0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A, 0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0, 0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5, 0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4, 0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03, 0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01, 0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67, 0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92, 0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0, 0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E, 0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C, 0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1, 0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183, 0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2, 0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF, 0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA, 0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3, 0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496, 0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C, 0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C, 0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1, 0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579, 0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5, 0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7, 0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06, 0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15, 0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF, 0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D, 0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE, 0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40, 0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D, 0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04, 0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6, 0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16, 0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2, 0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF, 0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E, 0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D, 0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F, 0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76, 0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72, 0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94, 0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61, 0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90, 0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F, 0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A, 0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B, 0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9, 0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E, 0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C, 0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A, 0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F, 0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361, 0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487, 0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481, 0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C, 0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E, 0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D, 0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628, 0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E, 0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789, 0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF, 0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4, 0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9, 0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C, 0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39, 0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7, 0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE, 0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5, 0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB, 0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7, 0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA, 0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0, 0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC, 0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB, 0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8, 0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F, 0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199, 0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253, 0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251, 0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500, 0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D, 0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C, 0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508, 0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2, 0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3, 0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9, 0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D, 0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E, 0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7, 0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9, 0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B, 0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756, 0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1, 0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B, 0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751, 0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750, 0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F, 0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C, 0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775, 0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A, 0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B, 0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906, 0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909, 0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED, 0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6, 0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4, 0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE, 0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3, 0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E, 0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF, 0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD, 0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1, 0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25, 0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B, 0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26, 0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18, 0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A, 0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A, 0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17, 0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067, 0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129, 0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E, 0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181, 0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0, 0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9, 0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF, 0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD, 0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8, 0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6, 0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0, 0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3, 0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4, 0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE, 0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3, 0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A, 0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0, 0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826, 0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B, 0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA, 0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917, 0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF, 0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9, 0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7, 0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB, 0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46, 0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71, 0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70, 0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC, 0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7, 0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB, 0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83, 0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C, 0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111, 0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670, 0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666, 0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E, 0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8, 0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA, 0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17, 0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14, 0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28, 0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF, 0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7, 0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA, 0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF, 0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66, 0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6, 0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC, 0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5, 0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC, 0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C, 0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF, 0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3, 0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533, 0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8, 0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB, 0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA, 0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66, 0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68, 0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76, 0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A, 0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A, 0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54, 0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C, 0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D, 0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54, 0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB, 0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03, 0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3, 0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8, 0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E, 0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5, 0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA, 0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2, 0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF, 0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2, 0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0, 0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA, 0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8, 0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB, 0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366, 0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B, 0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0, 0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1, 0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D, 0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C, 0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB, 0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1, 0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3, 0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD, 0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE, 0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2, 0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4, 0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6, 0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7, 0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD, 0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8, 0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2, 0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF, 0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0, 0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17, 0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13, 0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A, 0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16, 0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24, 0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A, 0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029, 0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE, 0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0, 0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7, 0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256, 0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B, 0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558, 0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541, 0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547, 0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571, 0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555, 0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566, 0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C, 0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B, 0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792, 0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798, 0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785, 0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784, 0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789, 0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D, 0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922, 0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C, 0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2, 0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD, 0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0, 0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8, 0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91, 0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE, 0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C, 0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33, 0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45, 0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41, 0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36, 0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39, 0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079, 0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133, 0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190, 0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327, 0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306, 0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C, 0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301, 0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D, 0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325, 0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334, 0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329, 0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314, 0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309, 0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC, 0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA, 0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD, 0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712, 0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794, 0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F, 0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927, 0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC, 0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3, 0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9, 0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6, 0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33, 0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C, 0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93, 0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95, 0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17, 0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29, 0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10, 0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86, 0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5, 0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D, 0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124, 0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693, 0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684, 0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F, 0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF, 0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32, 0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26, 0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1, 0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A, 0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5, 0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5, 0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF, 0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4, 0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6, 0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96, 0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F, 0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87, 0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83, 0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F, 0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C, 0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09, 0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4, 0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7, 0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD, 0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1, 0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0, 0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F, 0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490, 0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5, 0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512, 0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648, 0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9, 0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7, 0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8, 0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902, 0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905, 0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB, 0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56, 0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE, 0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F, 0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB, 0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3, 0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01, 0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0, 0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8, 0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33, 0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49, 0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C, 0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44, 0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E, 0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C, 0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA, 0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9, 0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583, 0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595, 0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B, 0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577, 0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A, 0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596, 0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D, 0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588, 0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598, 0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE, 0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0, 0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC, 0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2, 0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4, 0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF, 0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2, 0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E, 0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942, 0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2, 0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16, 0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22, 0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07, 0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C, 0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70, 0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95, 0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E, 0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C, 0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085, 0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2, 0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1, 0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383, 0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347, 0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376, 0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360, 0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A, 0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352, 0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B, 0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367, 0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7, 0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5, 0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC, 0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D, 0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C, 0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4, 0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A, 0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925, 0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933, 0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931, 0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1, 0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7, 0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB, 0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03, 0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01, 0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8, 0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1, 0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2, 0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41, 0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F, 0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45, 0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37, 0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D, 0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0, 0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF, 0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54, 0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E, 0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A, 0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C, 0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D, 0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED, 0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0, 0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF, 0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501, 0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB, 0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5, 0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6, 0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7, 0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9, 0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D, 0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E, 0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026, 0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201, 0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD, 0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5, 0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB, 0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C, 0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653, 0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD, 0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF, 0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909, 0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD, 0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29, 0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D, 0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22, 0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50, 0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62, 0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57, 0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7, 0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2, 0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4, 0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2, 0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7, 0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE, 0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6, 0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7, 0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6, 0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA, 0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4, 0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED, 0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7, 0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8, 0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F, 0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951, 0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23, 0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47, 0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31, 0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36, 0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D, 0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99, 0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04, 0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62, 0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E, 0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A, 0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54, 0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B, 0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E, 0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF, 0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392, 0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389, 0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E, 0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399, 0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391, 0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4, 0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3, 0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA, 0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD, 0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC, 0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4, 0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7, 0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA, 0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8, 0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F, 0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04, 0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07, 0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08, 0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35, 0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7, 0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1, 0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6, 0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C, 0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B, 0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C, 0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F, 0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C, 0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16, 0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29, 0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134, 0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4, 0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7, 0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD, 0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E, 0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF, 0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D, 0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584, 0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7, 0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9, 0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0, 0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE, 0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019, 0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B, 0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029, 0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A, 0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202, 0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4, 0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5, 0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660, 0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1, 0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C, 0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67, 0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39, 0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA, 0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70, 0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72, 0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A, 0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD, 0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5, 0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB, 0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1, 0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC, 0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF, 0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0, 0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2, 0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6, 0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B, 0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF, 0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A, 0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C, 0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988, 0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50, 0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53, 0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55, 0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57, 0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A, 0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC, 0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D, 0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F, 0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51, 0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4, 0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD, 0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2, 0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC, 0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6, 0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3, 0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0, 0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA, 0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B, 0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3, 0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE, 0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D, 0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB, 0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943, 0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15, 0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B, 0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23, 0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2, 0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C, 0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0, 0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2, 0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC, 0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5, 0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81, 0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71, 0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B, 0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74, 0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85, 0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F, 0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68, 0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC, 0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D, 0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337, 0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3, 0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE, 0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9, 0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513, 0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4, 0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8, 0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF, 0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037, 0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038, 0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040, 0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213, 0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C, 0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE, 0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF, 0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923, 0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929, 0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D, 0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A, 0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B, 0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA, 0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9, 0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622, 0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B, 0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609, 0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819, 0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813, 0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9, 0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D, 0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67, 0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88, 0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57, 0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D, 0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5, 0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413, 0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414, 0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428, 0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400, 0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416, 0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8, 0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C, 0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE, 0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F, 0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE, 0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F, 0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E, 0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953, 0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C, 0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E, 0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA, 0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11, 0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05, 0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07, 0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14, 0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4, 0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90, 0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C, 0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A, 0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3, 0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6, 0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A, 0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6, 0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60, 0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91, 0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297, 0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48, 0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1, 0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC, 0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043, 0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049, 0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A, 0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A, 0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F, 0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A, 0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86, 0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030, 0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626, 0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619, 0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620, 0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829, 0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824, 0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D, 0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA, 0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A, 0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF, 0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B, 0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145, 0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436, 0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430, 0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C, 0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4, 0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF, 0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6, 0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39, 0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42, 0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD, 0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16, 0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D, 0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28, 0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7, 0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7, 0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5, 0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE, 0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8, 0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3, 0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C, 0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B, 0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E, 0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9, 0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971, 0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1, 0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526, 0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09, 0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057, 0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9, 0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9, 0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935, 0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57, 0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A, 0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F, 0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634, 0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632, 0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826, 0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF, 0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84, 0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F, 0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A, 0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97, 0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C, 0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F, 0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449, 0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A, 0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B, 0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C, 0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49, 0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19, 0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55, 0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44, 0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C, 0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D, 0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE, 0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC, 0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9, 0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5, 0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35, 0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B, 0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299, 0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D, 0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201, 0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525, 0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12, 0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A, 0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383, 0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66, 0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640, 0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B, 0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E, 0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973, 0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B, 0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98, 0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462, 0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E, 0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56, 0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20, 0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A, 0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59, 0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7, 0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8, 0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE, 0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2, 0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8, 0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2, 0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38, 0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F, 0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F, 0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D, 0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13, 0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060, 0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5, 0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A, 0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643, 0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B, 0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F, 0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD, 0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469, 0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747, 0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5, 0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66, 0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02, 0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06, 0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09, 0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0, 0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75, 0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8, 0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A, 0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8, 0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B, 0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B, 0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646, 0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A, 0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98, 0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3, 0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471, 0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F, 0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B, 0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12, 0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09, 0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A, 0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F, 0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3, 0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475, 0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71, 0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6, 0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065, 0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D, 0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9, 0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874, 0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64, 0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15, 0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E, 0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482, 0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68, 0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B, 0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7, 0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D, 0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E, 0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9, 0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7, 0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557, 0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A, 0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564, 0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561, 0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553, 0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B, 0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C, 0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E, 0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0 }; #endif #if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0 static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0 static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */ 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0 static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0 static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0 static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */ 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0 static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0 static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0 static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */ 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0 static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0 static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0 static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0 static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0 static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0, 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0 static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */ 0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518, 0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000, 0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5, 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F, 0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9, 0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9, 0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1, 0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000 }; #endif #if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0 static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0 static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 }; #endif #if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0 static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */ 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, 0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF, 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384, 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0 }; #endif /*------------------------------------------------------------------------*/ /* OEM <==> Unicode Conversions for Static Code Page Configuration with */ /* SBCS Fixed Code Page */ /*------------------------------------------------------------------------*/ #if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900 WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ DWORD uni, /* UTF-16 encoded character to be converted */ WORD cp /* Code page for the conversion */ ) { WCHAR c = 0; const WCHAR* p = CVTBL(uc, FF_CODE_PAGE); if (uni < 0x80) { /* ASCII? */ c = (WCHAR)uni; } else { /* Non-ASCII */ if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ for (c = 0; c < 0x80 && uni != p[c]; c++) ; c = (c + 0x80) & 0xFF; } } return c; } WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */ WCHAR oem, /* OEM code to be converted */ WORD cp /* Code page for the conversion */ ) { WCHAR c = 0; const WCHAR* p = CVTBL(uc, FF_CODE_PAGE); if (oem < 0x80) { /* ASCII? */ c = oem; } else { /* Extended char */ if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */ if (oem < 0x100) c = p[oem - 0x80]; } } return c; } #endif /*------------------------------------------------------------------------*/ /* OEM <==> Unicode Conversions for Static Code Page Configuration with */ /* DBCS Fixed Code Page */ /*------------------------------------------------------------------------*/ #if FF_CODE_PAGE >= 900 WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ DWORD uni, /* UTF-16 encoded character to be converted */ WORD cp /* Code page for the conversion */ ) { const WCHAR* p; WCHAR c = 0, uc; UINT i = 0, n, li, hi; if (uni < 0x80) { /* ASCII? */ c = (WCHAR)uni; } else { /* Non-ASCII */ if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ uc = (WCHAR)uni; p = CVTBL(uni2oem, FF_CODE_PAGE); hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1; li = 0; for (n = 16; n; n--) { i = li + (hi - li) / 2; if (uc == p[i * 2]) break; if (uc > p[i * 2]) { li = i; } else { hi = i; } } if (n != 0) c = p[i * 2 + 1]; } } return c; } WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */ WCHAR oem, /* OEM code to be converted */ WORD cp /* Code page for the conversion */ ) { const WCHAR* p; WCHAR c = 0; UINT i = 0, n, li, hi; if (oem < 0x80) { /* ASCII? */ c = oem; } else { /* Extended char */ if (cp == FF_CODE_PAGE) { /* Is it valid code page? */ p = CVTBL(oem2uni, FF_CODE_PAGE); hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1; li = 0; for (n = 16; n; n--) { i = li + (hi - li) / 2; if (oem == p[i * 2]) break; if (oem > p[i * 2]) { li = i; } else { hi = i; } } if (n != 0) c = p[i * 2 + 1]; } } return c; } #endif /*------------------------------------------------------------------------*/ /* OEM <==> Unicode Conversions for Dynamic Code Page Configuration */ /*------------------------------------------------------------------------*/ #if FF_CODE_PAGE == 0 static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0}; static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0}; WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ DWORD uni, /* UTF-16 encoded character to be converted */ WORD cp /* Code page for the conversion */ ) { const WCHAR* p; WCHAR c = 0, uc; UINT i, n, li, hi; if (uni < 0x80) { /* ASCII? */ c = (WCHAR)uni; } else { /* Non-ASCII */ if (uni < 0x10000) { /* Is it in BMP? */ uc = (WCHAR)uni; p = 0; if (cp < 900) { /* SBCS */ for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */ p = cp_table[i]; if (p) { /* Is it valid code page ? */ for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */ c = (c + 0x80) & 0xFF; } } else { /* DBCS */ switch (cp) { /* Get conversion table */ case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break; case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break; case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break; case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break; } if (p) { /* Is it valid code page? */ li = 0; for (n = 16; n; n--) { /* Find OEM code */ i = li + (hi - li) / 2; if (uc == p[i * 2]) break; if (uc > p[i * 2]) { li = i; } else { hi = i; } } if (n != 0) c = p[i * 2 + 1]; } } } } return c; } WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */ WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */ WORD cp /* Code page for the conversion */ ) { const WCHAR* p; WCHAR c = 0; UINT i, n, li, hi; if (oem < 0x80) { /* ASCII? */ c = oem; } else { /* Extended char */ p = 0; if (cp < 900) { /* SBCS */ for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */ p = cp_table[i]; if (p) { /* Is it a valid CP ? */ if (oem < 0x100) c = p[oem - 0x80]; } } else { /* DBCS */ switch (cp) { case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break; case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break; case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break; case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break; } if (p) { li = 0; for (n = 16; n; n--) { i = li + (hi - li) / 2; if (oem == p[i * 2]) break; if (oem > p[i * 2]) { li = i; } else { hi = i; } } if (n != 0) c = p[i * 2 + 1]; } } } return c; } #endif /*------------------------------------------------------------------------*/ /* Unicode Up-case Conversion */ /*------------------------------------------------------------------------*/ DWORD ff_wtoupper ( /* Returns up-converted code point */ DWORD uni /* Unicode code point to be up-converted */ ) { const WORD* p; WORD uc, bc, nc, cmd; static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */ /* Basic Latin */ 0x0061,0x031A, /* Latin-1 Supplement */ 0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178, /* Latin Extended-A */ 0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106, /* Latin Extended-B */ 0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA, 0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128, 0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A, /* IPA Extensions */ 0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7, /* Greek, Coptic */ 0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311, 0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118, 0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA, /* Cyrillic */ 0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144, /* Armenian */ 0x0561,0x0426, 0x0000 /* EOT */ }; static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */ /* Phonetic Extensions */ 0x1D7D,0x0001,0x2C63, /* Latin Extended Additional */ 0x1E00,0x0196, 0x1EA0,0x015A, /* Greek Extended */ 0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606, 0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608, 0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB, 0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC, 0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF3,0x0001,0x1FFC, /* Letterlike Symbols */ 0x214E,0x0001,0x2132, /* Number forms */ 0x2170,0x0210, 0x2184,0x0001,0x2183, /* Enclosed Alphanumerics */ 0x24D0,0x051A, 0x2C30,0x042F, /* Latin Extended-C */ 0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102, /* Coptic */ 0x2C80,0x0164, /* Georgian Supplement */ 0x2D00,0x0826, /* Full-width */ 0xFF41,0x031A, 0x0000 /* EOT */ }; if (uni < 0x10000) { /* Is it in BMP? */ uc = (WORD)uni; p = uc < 0x1000 ? cvt1 : cvt2; for (;;) { bc = *p++; /* Get the block base */ if (bc == 0 || uc < bc) break; /* Not matched? */ nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */ if (uc < bc + nc) { /* In the block? */ switch (cmd) { case 0: uc = p[uc - bc]; break; /* Table conversion */ case 1: uc -= (uc - bc) & 1; break; /* Case pairs */ case 2: uc -= 16; break; /* Shift -16 */ case 3: uc -= 32; break; /* Shift -32 */ case 4: uc -= 48; break; /* Shift -48 */ case 5: uc -= 26; break; /* Shift -26 */ case 6: uc += 8; break; /* Shift +8 */ case 7: uc -= 80; break; /* Shift -80 */ case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */ } break; } if (cmd == 0) p += nc; /* Skip table if needed */ } uni = uc; } return uni; } #endif /* #if FF_USE_LFN != 0 */ ================================================ FILE: lib/networking/dhserver.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * 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 "dhserver.h" /* DHCP message type */ #define DHCP_DISCOVER 1 #define DHCP_OFFER 2 #define DHCP_REQUEST 3 #define DHCP_DECLINE 4 #define DHCP_ACK 5 #define DHCP_NAK 6 #define DHCP_RELEASE 7 #define DHCP_INFORM 8 /* DHCP options */ enum DHCP_OPTIONS { DHCP_PAD = 0, DHCP_SUBNETMASK = 1, DHCP_ROUTER = 3, DHCP_DNSSERVER = 6, DHCP_HOSTNAME = 12, DHCP_DNSDOMAIN = 15, DHCP_MTU = 26, DHCP_BROADCAST = 28, DHCP_PERFORMROUTERDISC = 31, DHCP_STATICROUTE = 33, DHCP_NISDOMAIN = 40, DHCP_NISSERVER = 41, DHCP_NTPSERVER = 42, DHCP_VENDOR = 43, DHCP_IPADDRESS = 50, DHCP_LEASETIME = 51, DHCP_OPTIONSOVERLOADED = 52, DHCP_MESSAGETYPE = 53, DHCP_SERVERID = 54, DHCP_PARAMETERREQUESTLIST = 55, DHCP_MESSAGE = 56, DHCP_MAXMESSAGESIZE = 57, DHCP_RENEWALTIME = 58, DHCP_REBINDTIME = 59, DHCP_CLASSID = 60, DHCP_CLIENTID = 61, DHCP_USERCLASS = 77, /* RFC 3004 */ DHCP_FQDN = 81, DHCP_DNSSEARCH = 119, /* RFC 3397 */ DHCP_CSR = 121, /* RFC 3442 */ DHCP_MSCSR = 249, /* MS code for RFC 3442 */ DHCP_END = 255 }; typedef struct { uint8_t dp_op; /* packet opcode type */ uint8_t dp_htype; /* hardware addr type */ uint8_t dp_hlen; /* hardware addr length */ uint8_t dp_hops; /* gateway hops */ uint32_t dp_xid; /* transaction ID */ uint16_t dp_secs; /* seconds since boot began */ uint16_t dp_flags; uint8_t dp_ciaddr[4]; /* client IP address */ uint8_t dp_yiaddr[4]; /* 'your' IP address */ uint8_t dp_siaddr[4]; /* server IP address */ uint8_t dp_giaddr[4]; /* gateway IP address */ uint8_t dp_chaddr[16]; /* client hardware address */ uint8_t dp_legacy[192]; uint8_t dp_magic[4]; uint8_t dp_options[275]; /* options area */ } DHCP_TYPE; DHCP_TYPE dhcp_data; static struct udp_pcb *pcb = NULL; static const dhcp_config_t *config = NULL; char magic_cookie[] = {0x63,0x82,0x53,0x63}; static ip4_addr_t get_ip(const uint8_t *pnt) { ip4_addr_t result; memcpy(&result, pnt, sizeof(result)); return result; } static void set_ip(uint8_t *pnt, ip4_addr_t value) { memcpy(pnt, &value.addr, sizeof(value.addr)); } static dhcp_entry_t *entry_by_ip(ip4_addr_t ip) { int i; for (i = 0; i < config->num_entry; i++) if (config->entries[i].addr.addr == ip.addr) return &config->entries[i]; return NULL; } static dhcp_entry_t *entry_by_mac(uint8_t *mac) { int i; for (i = 0; i < config->num_entry; i++) if (memcmp(config->entries[i].mac, mac, 6) == 0) return &config->entries[i]; return NULL; } static __inline bool is_vacant(dhcp_entry_t *entry) { return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; } static dhcp_entry_t *vacant_address(void) { int i; for (i = 0; i < config->num_entry; i++) if (is_vacant(config->entries + i)) return config->entries + i; return NULL; } static __inline void free_entry(dhcp_entry_t *entry) { memset(entry->mac, 0, 6); } static uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) { int i = 0; while ((i + 1) < size) { int next = i + attrs[i + 1] + 2; if (next > size) return NULL; if (attrs[i] == attr) return attrs + i; i = next; } return NULL; } static int fill_options(void *dest, uint8_t msg_type, const char *domain, ip4_addr_t dns, int lease_time, ip4_addr_t serverid, ip4_addr_t router, ip4_addr_t subnet) { uint8_t *ptr = (uint8_t *)dest; /* ACK message type */ *ptr++ = 53; *ptr++ = 1; *ptr++ = msg_type; /* dhcp server identifier */ *ptr++ = DHCP_SERVERID; *ptr++ = 4; set_ip(ptr, serverid); ptr += 4; /* lease time */ *ptr++ = DHCP_LEASETIME; *ptr++ = 4; *ptr++ = (lease_time >> 24) & 0xFF; *ptr++ = (lease_time >> 16) & 0xFF; *ptr++ = (lease_time >> 8) & 0xFF; *ptr++ = (lease_time >> 0) & 0xFF; /* subnet mask */ *ptr++ = DHCP_SUBNETMASK; *ptr++ = 4; set_ip(ptr, subnet); ptr += 4; /* router */ if (router.addr != 0) { *ptr++ = DHCP_ROUTER; *ptr++ = 4; set_ip(ptr, router); ptr += 4; } /* domain name */ if (domain != NULL) { int len = strlen(domain); *ptr++ = DHCP_DNSDOMAIN; *ptr++ = len; memcpy(ptr, domain, len); ptr += len; } /* domain name server (DNS) */ if (dns.addr != 0) { *ptr++ = DHCP_DNSSERVER; *ptr++ = 4; set_ip(ptr, dns); ptr += 4; } /* end */ *ptr++ = DHCP_END; return ptr - (uint8_t *)dest; } /* * RFC 2131 Section 4.1 compliant destination address selection */ static ip_addr_t get_dhcp_destination(struct netif *netif, const DHCP_TYPE *dhcp, const ip4_addr_t *yiaddr, bool is_nak) { ip4_addr_t giaddr = get_ip(dhcp->dp_giaddr); ip4_addr_t ciaddr = get_ip(dhcp->dp_ciaddr); bool giaddr_zero = ip4_addr_isany_val(giaddr); bool ciaddr_zero = ip4_addr_isany_val(ciaddr); bool broadcast_flag = (dhcp->dp_flags & htons(0x8000)) != 0; ip_addr_t dest_addr; if (!giaddr_zero) { // If giaddr is not zero, send to giaddr (relay agent) ip_addr_set_ip4_u32(&dest_addr, giaddr.addr); return dest_addr; } if (is_nak) { // RFC 2131: "In all cases, when 'giaddr' is zero, // the server broadcasts any DHCPNAK messages to 0xffffffff" goto dest_broadcast; } if (!ciaddr_zero) { // RFC 2131: "If the 'giaddr' field is zero and the 'ciaddr' field is nonzero, // then the server unicasts DHCPOFFER and DHCPACK messages to the address in 'ciaddr'" ip_addr_set_ip4_u32(&dest_addr, ciaddr.addr); return dest_addr; } if (broadcast_flag) { // RFC 2131: "If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is set, // then the server broadcasts DHCPOFFER and DHCPACK messages to 0xffffffff" goto dest_broadcast; } // RFC 2131: "If the broadcast bit is not set and 'giaddr' is zero and 'ciaddr' is zero, // then the server unicasts DHCPOFFER and DHCPACK messages to the client's hardware // address and 'yiaddr' address" if (yiaddr && !ip4_addr_isany(yiaddr)) { ip_addr_set_ip4_u32(&dest_addr, yiaddr->addr); // TODO: This requires ARP table manipulation to associate yiaddr with client MAC // For now, fall back to broadcast as this is complex to implement correctly goto dest_broadcast; } dest_broadcast: ip_addr_set_ip4_u32(&dest_addr, ip4_addr_get_u32(netif_ip4_addr(netif)) | ~ip4_addr_get_u32(netif_ip4_netmask(netif))); return dest_addr; } static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *ptr; dhcp_entry_t *entry; struct pbuf *pp; struct netif *netif = netif_get_by_index(p->if_idx); ip_addr_t dest_addr; (void)arg; (void)addr; unsigned n = p->len; if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); memcpy(&dhcp_data, p->payload, n); ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_MESSAGETYPE); if (ptr == NULL) { pbuf_free(p); return; } switch (ptr[2]) { case DHCP_DISCOVER: entry = entry_by_mac(dhcp_data.dp_chaddr); if (entry == NULL) entry = vacant_address(); if (entry == NULL) break; dhcp_data.dp_op = 2; /* reply */ dhcp_data.dp_secs = 0; dhcp_data.dp_flags = 0; set_ip(dhcp_data.dp_yiaddr, entry->addr); memcpy(dhcp_data.dp_magic, magic_cookie, 4); memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); fill_options(dhcp_data.dp_options, DHCP_OFFER, config->domain, config->dns, entry->lease, *netif_ip4_addr(netif), config->router, *netif_ip4_netmask(netif)); pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); if (pp == NULL) break; memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); // RFC 2131 compliant destination selection for DHCP OFFER dest_addr = get_dhcp_destination(netif, &dhcp_data, &entry->addr, false); udp_sendto(upcb, pp, &dest_addr, port); pbuf_free(pp); break; case DHCP_REQUEST: /* 1. find requested ipaddr in option list */ ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); if (ptr == NULL) break; if (ptr[1] != 4) break; ptr += 2; /* 2. does hw-address registered? */ entry = entry_by_mac(dhcp_data.dp_chaddr); if (entry != NULL) free_entry(entry); /* 3. find requested ipaddr */ entry = entry_by_ip(get_ip(ptr)); if (entry == NULL) break; if (!is_vacant(entry)) break; /* 4. fill struct fields */ memcpy(dhcp_data.dp_yiaddr, ptr, 4); dhcp_data.dp_op = 2; /* reply */ dhcp_data.dp_secs = 0; dhcp_data.dp_flags = 0; memcpy(dhcp_data.dp_magic, magic_cookie, 4); /* 5. fill options */ memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); fill_options(dhcp_data.dp_options, DHCP_ACK, config->domain, config->dns, entry->lease, *netif_ip4_addr(netif), config->router, *netif_ip4_netmask(netif)); /* 6. send ACK */ pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); if (pp == NULL) break; memcpy(entry->mac, dhcp_data.dp_chaddr, 6); memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); // RFC 2131 compliant destination selection for DHCP ACK dest_addr = get_dhcp_destination(netif, &dhcp_data, &entry->addr, false); udp_sendto(upcb, pp, &dest_addr, port); pbuf_free(pp); break; default: break; } pbuf_free(p); } err_t dhserv_init(const dhcp_config_t *c) { err_t err; udp_init(); dhserv_free(); pcb = udp_new(); if (pcb == NULL) return ERR_MEM; err = udp_bind(pcb, IP_ADDR_ANY, c->port); if (err != ERR_OK) { dhserv_free(); return err; } udp_recv(pcb, udp_recv_proc, NULL); config = c; return ERR_OK; } void dhserv_free(void) { if (pcb == NULL) return; udp_remove(pcb); pcb = NULL; } ================================================ FILE: lib/networking/dhserver.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * 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. */ /* * version: 1.0 demo (7.02.2015) * brief: tiny dhcp ipv4 server using lwip (pcb) * ref: https://lists.gnu.org/archive/html/lwip-users/2012-12/msg00016.html */ #ifndef DHSERVER_H #define DHSERVER_H #include #include #include #include #include "lwip/err.h" #include "lwip/udp.h" #include "netif/etharp.h" typedef struct dhcp_entry { uint8_t mac[6]; ip4_addr_t addr; uint32_t lease; } dhcp_entry_t; typedef struct dhcp_config { ip4_addr_t router; uint16_t port; ip4_addr_t dns; const char *domain; int num_entry; dhcp_entry_t *entries; } dhcp_config_t; #ifdef __cplusplus extern "C" { #endif err_t dhserv_init(const dhcp_config_t *c); void dhserv_free(void); #ifdef __cplusplus } #endif #endif /* DHSERVER_H */ ================================================ FILE: lib/networking/dnserver.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * 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. */ /* * version: 1.0 demo (7.02.2015) * brief: tiny dns ipv4 server using lwip (pcb) */ #include "dnserver.h" #define DNS_MAX_HOST_NAME_LEN 128 static struct udp_pcb *pcb = NULL; dns_query_proc_t query_proc = NULL; #pragma pack(push, 1) typedef struct { #if BYTE_ORDER == LITTLE_ENDIAN uint8_t rd: 1, /* Recursion Desired */ tc: 1, /* Truncation Flag */ aa: 1, /* Authoritative Answer Flag */ opcode: 4, /* Operation code */ qr: 1; /* Query/Response Flag */ uint8_t rcode: 4, /* Response Code */ z: 3, /* Zero */ ra: 1; /* Recursion Available */ #else uint8_t qr: 1, /* Query/Response Flag */ opcode: 4, /* Operation code */ aa: 1, /* Authoritative Answer Flag */ tc: 1, /* Truncation Flag */ rd: 1; /* Recursion Desired */ uint8_t ra: 1, /* Recursion Available */ z: 3, /* Zero */ rcode: 4; /* Response Code */ #endif } dns_header_flags_t; typedef struct { uint16_t id; dns_header_flags_t flags; uint16_t n_record[4]; } dns_header_t; typedef struct dns_answer { uint16_t name; uint16_t type; uint16_t Class; uint32_t ttl; uint16_t len; uint32_t addr; } dns_answer_t; #pragma pack(pop) typedef struct dns_query { char name[DNS_MAX_HOST_NAME_LEN]; uint16_t type; uint16_t Class; } dns_query_t; static uint16_t get_uint16(const uint8_t *pnt) { uint16_t result; memcpy(&result, pnt, sizeof(result)); return result; } static int parse_next_query(void *data, int size, dns_query_t *query) { int len; int labels; uint8_t *ptr; len = 0; labels = 0; ptr = (uint8_t *)data; while (true) { uint8_t lable_len; if (size <= 0) return -1; lable_len = *ptr++; size--; if (lable_len == 0) break; if (labels > 0) { if (len == DNS_MAX_HOST_NAME_LEN) return -2; query->name[len++] = '.'; } if (lable_len > size) return -1; if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2; memcpy(&query->name[len], ptr, lable_len); len += lable_len; ptr += lable_len; size -= lable_len; labels++; } if (size < 4) return -1; query->name[len] = 0; query->type = get_uint16(ptr); ptr += 2; query->Class = get_uint16(ptr); ptr += 2; return ptr - (uint8_t *)data; } static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { int len; dns_header_t *header; static dns_query_t query; struct pbuf *out; ip4_addr_t host_addr; dns_answer_t *answer; (void)arg; if (p->len <= sizeof(dns_header_t)) goto error; header = (dns_header_t *)p->payload; if (header->flags.qr != 0) goto error; if (ntohs(header->n_record[0]) != 1) goto error; len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query); if (len < 0) goto error; if (!query_proc(query.name, &host_addr)) goto error; len += sizeof(dns_header_t); out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL); if (out == NULL) goto error; memcpy(out->payload, p->payload, len); header = (dns_header_t *)out->payload; header->flags.qr = 1; header->n_record[1] = htons(1); answer = (struct dns_answer *)((uint8_t *)out->payload + len); answer->name = htons(0xC00C); answer->type = htons(1); answer->Class = htons(1); answer->ttl = htonl(32); answer->len = htons(4); answer->addr = host_addr.addr; udp_sendto(upcb, out, addr, port); pbuf_free(out); error: pbuf_free(p); } err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) { err_t err; udp_init(); dnserv_free(); pcb = udp_new(); if (pcb == NULL) return ERR_MEM; err = udp_bind(pcb, bind, port); if (err != ERR_OK) { dnserv_free(); return err; } udp_recv(pcb, udp_recv_proc, NULL); query_proc = qp; return ERR_OK; } void dnserv_free(void) { if (pcb == NULL) return; udp_remove(pcb); pcb = NULL; } ================================================ FILE: lib/networking/dnserver.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * 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. */ /* * version: 1.0 demo (7.02.2015) * brief: tiny dns ipv4 server using lwip (pcb) */ #ifndef DNSERVER #define DNSERVER #include #include #include #include #include "lwip/def.h" #include "lwip/err.h" #include "lwip/udp.h" #include "netif/etharp.h" typedef bool (*dns_query_proc_t)(const char *name, ip4_addr_t *addr); #ifdef __cplusplus extern "C" { #endif err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t query_proc); void dnserv_free(void); #ifdef __cplusplus } #endif #endif ================================================ FILE: lib/networking/ndis.h ================================================ /* This file has been prepared for Doxygen automatic documentation generation.*/ /*! \file ndis.h *************************************************************** * * \brief * This file contains the possible external configuration of the USB. * * \addtogroup usbstick * * ******************************************************************************/ /** \ingroup usbstick \defgroup RNDIS RNDIS Support @{ */ /* * ndis.h * * Modified by Colin O'Flynn * ntddndis.h modified by Benedikt Spranger * * Thanks to the cygwin development team, * especially to Casper S. Hornstrup * * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. You may * use, modify or distribute it freely. * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * */ #ifndef _LINUX_NDIS_H #define _LINUX_NDIS_H #define NDIS_STATUS_MULTICAST_FULL 0xC0010009 #define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A #define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B /* from drivers/net/sk98lin/h/skgepnmi.h */ #define OID_PNP_CAPABILITIES 0xFD010100 #define OID_PNP_SET_POWER 0xFD010101 #define OID_PNP_QUERY_POWER 0xFD010102 #define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 #define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 #define OID_PNP_ENABLE_WAKE_UP 0xFD010106 enum NDIS_DEVICE_POWER_STATE { NdisDeviceStateUnspecified = 0, NdisDeviceStateD0, NdisDeviceStateD1, NdisDeviceStateD2, NdisDeviceStateD3, NdisDeviceStateMaximum }; struct NDIS_PM_WAKE_UP_CAPABILITIES { enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; }; /* NDIS_PNP_CAPABILITIES.Flags constants */ #define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 #define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 #define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 /* struct NDIS_PNP_CAPABILITIES { __le32 Flags; struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; }; struct NDIS_PM_PACKET_PATTERN { __le32 Priority; __le32 Reserved; __le32 MaskSize; __le32 PatternOffset; __le32 PatternSize; __le32 PatternFlags; }; */ /* Required Object IDs (OIDs) */ #define OID_GEN_SUPPORTED_LIST 0x00010101 #define OID_GEN_HARDWARE_STATUS 0x00010102 #define OID_GEN_MEDIA_SUPPORTED 0x00010103 #define OID_GEN_MEDIA_IN_USE 0x00010104 #define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 #define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 #define OID_GEN_LINK_SPEED 0x00010107 #define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 #define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 #define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A #define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B #define OID_GEN_VENDOR_ID 0x0001010C #define OID_GEN_VENDOR_DESCRIPTION 0x0001010D #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E #define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F #define OID_GEN_DRIVER_VERSION 0x00010110 #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 #define OID_GEN_PROTOCOL_OPTIONS 0x00010112 #define OID_GEN_MAC_OPTIONS 0x00010113 #define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 #define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 #define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 #define OID_GEN_SUPPORTED_GUIDS 0x00010117 #define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 #define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 #define OID_GEN_MACHINE_NAME 0x0001021A #define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B #define OID_GEN_VLAN_ID 0x0001021C /* Optional OIDs */ #define OID_GEN_MEDIA_CAPABILITIES 0x00010201 #define OID_GEN_PHYSICAL_MEDIUM 0x00010202 /* Required statistics OIDs */ #define OID_GEN_XMIT_OK 0x00020101 #define OID_GEN_RCV_OK 0x00020102 #define OID_GEN_XMIT_ERROR 0x00020103 #define OID_GEN_RCV_ERROR 0x00020104 #define OID_GEN_RCV_NO_BUFFER 0x00020105 /* Optional statistics OIDs */ #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 #define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 #define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 #define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 #define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 #define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B #define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C #define OID_GEN_RCV_CRC_ERROR 0x0002020D #define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E #define OID_GEN_GET_TIME_CAPS 0x0002020F #define OID_GEN_GET_NETCARD_TIME 0x00020210 #define OID_GEN_NETCARD_LOAD 0x00020211 #define OID_GEN_DEVICE_PROFILE 0x00020212 #define OID_GEN_INIT_TIME_MS 0x00020213 #define OID_GEN_RESET_COUNTS 0x00020214 #define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 #define OID_GEN_FRIENDLY_NAME 0x00020216 #define OID_GEN_MINIPORT_INFO 0x00020217 #define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 /* IEEE 802.3 (Ethernet) OIDs */ #define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 #define OID_802_3_PERMANENT_ADDRESS 0x01010101 #define OID_802_3_CURRENT_ADDRESS 0x01010102 #define OID_802_3_MULTICAST_LIST 0x01010103 #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 #define OID_802_3_MAC_OPTIONS 0x01010105 #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 #define OID_802_3_XMIT_ONE_COLLISION 0x01020102 #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 #define OID_802_3_XMIT_DEFERRED 0x01020201 #define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 #define OID_802_3_RCV_OVERRUN 0x01020203 #define OID_802_3_XMIT_UNDERRUN 0x01020204 #define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 #define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 #define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 /* Wireless LAN OIDs */ /* Mandatory */ #define OID_802_11_BSSID 0x0D010101 /* Q S */ #define OID_802_11_SSID 0x0D010102 /* Q S */ #define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 /* Q S */ #define OID_802_11_RSSI 0x0D010206 /* Q I */ #define OID_802_11_BSSID_LIST 0x0D010217 /* Q */ #define OID_802_11_BSSID_LIST_SCAN 0x0D01011A /* S */ #define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 /* Q S */ #define OID_802_11_SUPPORTED_RATES 0x0D01020E /* Q */ #define OID_802_11_CONFIGURATION 0x0D010211 /* Q S */ #define OID_802_11_ADD_WEP 0x0D010113 /* S */ #define OID_802_11_WEP_STATUS 0x0D01011B /* Q S */ #define OID_802_11_REMOVE_WEP 0x0D010114 /* S */ #define OID_802_11_DISASSOCIATE 0x0D010115 /* S */ #define OID_802_11_AUTHENTICATION_MODE 0x0D010118 /* Q S */ #define OID_802_11_RELOAD_DEFAULTS 0x0D01011C /* S */ /* OID_GEN_MINIPORT_INFO constants */ #define NDIS_MINIPORT_BUS_MASTER 0x00000001 #define NDIS_MINIPORT_WDM_DRIVER 0x00000002 #define NDIS_MINIPORT_SG_LIST 0x00000004 #define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 #define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 #define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 #define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 #define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 #define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 #define NDIS_MINIPORT_IS_NDIS_5 0x00000200 #define NDIS_MINIPORT_IS_CO 0x00000400 #define NDIS_MINIPORT_DESERIALIZE 0x00000800 #define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 #define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 #define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 #define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 #define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 #define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 #define NDIS_MINIPORT_HIDDEN 0x00040000 #define NDIS_MINIPORT_SWENUM 0x00080000 #define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 #define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 #define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 #define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 #define NDIS_MINIPORT_64BITS_DMA 0x01000000 #define NDIS_MEDIUM_802_3 0x00000000 #define NDIS_MEDIUM_802_5 0x00000001 #define NDIS_MEDIUM_FDDI 0x00000002 #define NDIS_MEDIUM_WAN 0x00000003 #define NDIS_MEDIUM_LOCAL_TALK 0x00000004 #define NDIS_MEDIUM_DIX 0x00000005 #define NDIS_MEDIUM_ARCENT_RAW 0x00000006 #define NDIS_MEDIUM_ARCENT_878_2 0x00000007 #define NDIS_MEDIUM_ATM 0x00000008 #define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 #define NDIS_MEDIUM_IRDA 0x0000000A #define NDIS_MEDIUM_BPC 0x0000000B #define NDIS_MEDIUM_CO_WAN 0x0000000C #define NDIS_MEDIUM_1394 0x0000000D #define NDIS_PACKET_TYPE_DIRECTED 0x00000001 #define NDIS_PACKET_TYPE_MULTICAST 0x00000002 #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 #define NDIS_PACKET_TYPE_BROADCAST 0x00000008 #define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 #define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 #define NDIS_PACKET_TYPE_SMT 0x00000040 #define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 #define NDIS_PACKET_TYPE_GROUP 0x00000100 #define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 #define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 #define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 #define NDIS_MEDIA_STATE_CONNECTED 0x00000000 #define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 #define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 #define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 #define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 #define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 #define NDIS_MAC_OPTION_RESERVED 0x80000000 #endif /* _LINUX_NDIS_H */ /** @} */ ================================================ FILE: lib/networking/rndis_protocol.h ================================================ /** * \file rndis_protocol.h * RNDIS Defines * * \author * Colin O'Flynn * * \addtogroup usbstick */ /* Copyright (c) 2008 Colin O'Flynn Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ #ifndef _RNDIS_H #define _RNDIS_H /** \addtogroup RNDIS @{ */ #include #define RNDIS_MAJOR_VERSION 1 #define RNDIS_MINOR_VERSION 0 #define RNDIS_STATUS_SUCCESS 0X00000000 #define RNDIS_STATUS_FAILURE 0XC0000001 #define RNDIS_STATUS_INVALID_DATA 0XC0010015 #define RNDIS_STATUS_NOT_SUPPORTED 0XC00000BB #define RNDIS_STATUS_MEDIA_CONNECT 0X4001000B #define RNDIS_STATUS_MEDIA_DISCONNECT 0X4001000C /* Message set for Connectionless (802.3) Devices */ #define REMOTE_NDIS_PACKET_MSG 0x00000001 #define REMOTE_NDIS_INITIALIZE_MSG 0X00000002 #define REMOTE_NDIS_HALT_MSG 0X00000003 #define REMOTE_NDIS_QUERY_MSG 0X00000004 #define REMOTE_NDIS_SET_MSG 0X00000005 #define REMOTE_NDIS_RESET_MSG 0X00000006 #define REMOTE_NDIS_INDICATE_STATUS_MSG 0X00000007 #define REMOTE_NDIS_KEEPALIVE_MSG 0X00000008 #define REMOTE_NDIS_INITIALIZE_CMPLT 0X80000002 #define REMOTE_NDIS_QUERY_CMPLT 0X80000004 #define REMOTE_NDIS_SET_CMPLT 0X80000005 #define REMOTE_NDIS_RESET_CMPLT 0X80000006 #define REMOTE_NDIS_KEEPALIVE_CMPLT 0X80000008 typedef uint32_t rndis_MessageType_t; typedef uint32_t rndis_MessageLength_t; typedef uint32_t rndis_RequestId_t; typedef uint32_t rndis_MajorVersion_t; typedef uint32_t rndis_MinorVersion_t; typedef uint32_t rndis_MaxTransferSize_t; typedef uint32_t rndis_Status_t; /* Device Flags */ #define RNDIS_DF_CONNECTIONLESS 0x00000001 #define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 typedef uint32_t rndis_DeviceFlags_t; /* Mediums */ #define RNDIS_MEDIUM_802_3 0x00000000 typedef uint32_t rndis_Medium_t; typedef uint32_t rndis_MaxPacketsPerTransfer_t; typedef uint32_t rndis_PacketAlignmentFactor_t; typedef uint32_t rndis_AfListOffset_t; typedef uint32_t rndis_AfListSize_t; /*** Remote NDIS Generic Message type ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; } rndis_generic_msg_t; /*** Remote NDIS Initialize Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_MajorVersion_t MajorVersion; rndis_MinorVersion_t MinorVersion; rndis_MaxTransferSize_t MaxTransferSize; } rndis_initialize_msg_t; /* Response: */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Status_t Status; rndis_MajorVersion_t MajorVersion; rndis_MinorVersion_t MinorVersion; rndis_DeviceFlags_t DeviceFlags; rndis_Medium_t Medium; rndis_MaxPacketsPerTransfer_t MaxPacketsPerTransfer; rndis_MaxTransferSize_t MaxTransferSize; rndis_PacketAlignmentFactor_t PacketAlignmentFactor; rndis_AfListOffset_t AfListOffset; rndis_AfListSize_t AfListSize; } rndis_initialize_cmplt_t; /*** Remote NDIS Halt Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; } rndis_halt_msg_t; typedef uint32_t rndis_Oid_t; typedef uint32_t rndis_InformationBufferLength_t; typedef uint32_t rndis_InformationBufferOffset_t; typedef uint32_t rndis_DeviceVcHandle_t; /*** Remote NDIS Query Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Oid_t Oid; rndis_InformationBufferLength_t InformationBufferLength; rndis_InformationBufferOffset_t InformationBufferOffset; rndis_DeviceVcHandle_t DeviceVcHandle; } rndis_query_msg_t; /* Response: */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Status_t Status; rndis_InformationBufferLength_t InformationBufferLength; rndis_InformationBufferOffset_t InformationBufferOffset; } rndis_query_cmplt_t; /*** Remote NDIS Set Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Oid_t Oid; rndis_InformationBufferLength_t InformationBufferLength; rndis_InformationBufferOffset_t InformationBufferOffset; rndis_DeviceVcHandle_t DeviceVcHandle; } rndis_set_msg_t; /* Response */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Status_t Status; }rndis_set_cmplt_t; /* Information buffer layout for OID_GEN_RNDIS_CONFIG_PARAMETER */ typedef uint32_t rndis_ParameterNameOffset_t; typedef uint32_t rndis_ParameterNameLength_t; typedef uint32_t rndis_ParameterType_t; typedef uint32_t rndis_ParameterValueOffset_t; typedef uint32_t rndis_ParameterValueLength_t; #define PARAMETER_TYPE_STRING 2 #define PARAMETER_TYPE_NUMERICAL 0 typedef struct{ rndis_ParameterNameOffset_t ParameterNameOffset; rndis_ParameterNameLength_t ParameterNameLength; rndis_ParameterType_t ParameterType; rndis_ParameterValueOffset_t ParameterValueOffset; rndis_ParameterValueLength_t ParameterValueLength; }rndis_config_parameter_t; typedef uint32_t rndis_Reserved_t; /*** Remote NDIS Soft Reset Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_Reserved_t Reserved; } rndis_reset_msg_t; typedef uint32_t rndis_AddressingReset_t; /* Response: */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_Status_t Status; rndis_AddressingReset_t AddressingReset; } rndis_reset_cmplt_t; /*** Remote NDIS Indicate Status Message ***/ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_Status_t Status; rndis_Status_t StatusBufferLength; rndis_Status_t StatusBufferOffset; } rndis_indicate_status_t; typedef uint32_t rndis_DiagStatus_t; typedef uint32_t rndis_ErrorOffset_t; typedef struct { rndis_DiagStatus_t DiagStatus; rndis_ErrorOffset_t ErrorOffset; }rndis_diagnostic_info_t; /*** Remote NDIS Keepalive Message */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; }rndis_keepalive_msg_t; /* Response: */ typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_RequestId_t RequestId; rndis_Status_t Status; }rndis_keepalive_cmplt_t; /*** Remote NDIS Data Packet ***/ typedef uint32_t rndis_DataOffset_t; typedef uint32_t rndis_DataLength_t; typedef uint32_t rndis_OOBDataOffset_t; typedef uint32_t rndis_OOBDataLength_t; typedef uint32_t rndis_NumOOBDataElements_t; typedef uint32_t rndis_PerPacketInfoOffset_t; typedef uint32_t rndis_PerPacketInfoLength_t; typedef struct{ rndis_MessageType_t MessageType; rndis_MessageLength_t MessageLength; rndis_DataOffset_t DataOffset; rndis_DataLength_t DataLength; rndis_OOBDataOffset_t OOBDataOffset; rndis_OOBDataLength_t OOBDataLength; rndis_NumOOBDataElements_t NumOOBDataElements; rndis_PerPacketInfoOffset_t PerPacketInfoOffset; rndis_PerPacketInfoLength_t PerPacketInfoLength; rndis_DeviceVcHandle_t DeviceVcHandle; rndis_Reserved_t Reserved; }rndis_data_packet_t; typedef uint32_t rndis_ClassInformationOffset_t; typedef uint32_t rndis_Size_t; typedef uint32_t rndis_Type_t; typedef struct{ rndis_Size_t Size; rndis_Type_t Type; rndis_ClassInformationOffset_t ClassInformationType; }rndis_OOB_packet_t; #include "ndis.h" typedef enum rnids_state_e { rndis_uninitialized, rndis_initialized, rndis_data_initialized } rndis_state_t; typedef struct { uint32_t txok; uint32_t rxok; uint32_t txbad; uint32_t rxbad; } usb_eth_stat_t; #endif /* _RNDIS_H */ /** @} */ ================================================ FILE: lib/networking/rndis_reports.c ================================================ /* The original version of this code was lrndis/usbd_rndis_core.c from https://github.com/fetisov/lrndis It has since been overhauled to suit this application */ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * 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 #include #include "tusb.h" #if CFG_TUD_ECM_RNDIS #include "rndis_protocol.h" #include "netif/ethernet.h" #define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */ #define RNDIS_VENDOR "TinyUSB" /* NIC vendor name */ static const uint8_t *const station_hwaddr = tud_network_mac_address; static const uint8_t *const permanent_hwaddr = tud_network_mac_address; static usb_eth_stat_t usb_eth_stat = { 0, 0, 0, 0 }; static uint32_t oid_packet_filter = 0x0000000; TU_ATTR_UNUSED static rndis_state_t rndis_state; static const uint32_t OIDSupportedList[] = { OID_GEN_SUPPORTED_LIST, OID_GEN_HARDWARE_STATUS, OID_GEN_MEDIA_SUPPORTED, OID_GEN_MEDIA_IN_USE, OID_GEN_MAXIMUM_FRAME_SIZE, OID_GEN_LINK_SPEED, OID_GEN_TRANSMIT_BLOCK_SIZE, OID_GEN_RECEIVE_BLOCK_SIZE, OID_GEN_VENDOR_ID, OID_GEN_VENDOR_DESCRIPTION, OID_GEN_VENDOR_DRIVER_VERSION, OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_MAXIMUM_TOTAL_SIZE, OID_GEN_PROTOCOL_OPTIONS, OID_GEN_MAC_OPTIONS, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_MAXIMUM_SEND_PACKETS, OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MULTICAST_LIST, OID_802_3_MAXIMUM_LIST_SIZE, OID_802_3_MAC_OPTIONS }; #define OID_LIST_LENGTH TU_ARRAY_SIZE(OIDSupportedList) #define ENC_BUF_SIZE (OID_LIST_LENGTH * 4 + 32) static void *encapsulated_buffer; static void rndis_report(void) { uint8_t ndis_report[8] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; netd_report(ndis_report, sizeof(ndis_report)); } static void rndis_query_cmplt32(int status, uint32_t data) { rndis_query_cmplt_t *c; c = (rndis_query_cmplt_t *)encapsulated_buffer; c->MessageType = REMOTE_NDIS_QUERY_CMPLT; c->MessageLength = sizeof(rndis_query_cmplt_t) + 4; c->InformationBufferLength = 4; c->InformationBufferOffset = 16; c->Status = status; memcpy(c + 1, &data, sizeof(data)); rndis_report(); } static void rndis_query_cmplt(int status, const void *data, int size) { rndis_query_cmplt_t *c; c = (rndis_query_cmplt_t *)encapsulated_buffer; c->MessageType = REMOTE_NDIS_QUERY_CMPLT; c->MessageLength = sizeof(rndis_query_cmplt_t) + size; c->InformationBufferLength = size; c->InformationBufferOffset = 16; c->Status = status; memcpy(c + 1, data, size); rndis_report(); } #define MAC_OPT NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \ NDIS_MAC_OPTION_RECEIVE_SERIALIZED | \ NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \ NDIS_MAC_OPTION_NO_LOOPBACK static const char *rndis_vendor = RNDIS_VENDOR; static void rndis_query(void) { switch (((rndis_query_msg_t *)encapsulated_buffer)->Oid) { case OID_GEN_SUPPORTED_LIST: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, OIDSupportedList, 4 * OID_LIST_LENGTH); return; case OID_GEN_VENDOR_DRIVER_VERSION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00001000); return; case OID_802_3_CURRENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, station_hwaddr, 6); return; case OID_802_3_PERMANENT_ADDRESS: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, permanent_hwaddr, 6); return; case OID_GEN_MEDIA_SUPPORTED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; case OID_GEN_MEDIA_IN_USE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; case OID_GEN_PHYSICAL_MEDIUM: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return; case OID_GEN_HARDWARE_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; case OID_GEN_LINK_SPEED: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, RNDIS_LINK_SPEED / 100); return; case OID_GEN_VENDOR_ID: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0x00FFFFFF); return; case OID_GEN_VENDOR_DESCRIPTION: rndis_query_cmplt(RNDIS_STATUS_SUCCESS, rndis_vendor, strlen(rndis_vendor) + 1); return; case OID_GEN_CURRENT_PACKET_FILTER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, oid_packet_filter); return; case OID_GEN_MAXIMUM_FRAME_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU - SIZEOF_ETH_HDR); return; case OID_GEN_MAXIMUM_TOTAL_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; case OID_GEN_TRANSMIT_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; case OID_GEN_RECEIVE_BLOCK_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, CFG_TUD_NET_MTU); return; case OID_GEN_MEDIA_CONNECT_STATUS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, NDIS_MEDIA_STATE_CONNECTED); return; case OID_GEN_RNDIS_CONFIG_PARAMETER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; case OID_802_3_MAXIMUM_LIST_SIZE: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 1); return; case OID_802_3_MULTICAST_LIST: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return; case OID_802_3_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_NOT_SUPPORTED, 0); return; case OID_GEN_MAC_OPTIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, /*MAC_OPT*/ 0); return; case OID_802_3_RCV_ERROR_ALIGNMENT: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; case OID_802_3_XMIT_ONE_COLLISION: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; case OID_802_3_XMIT_MORE_COLLISIONS: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; case OID_GEN_XMIT_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txok); return; case OID_GEN_RCV_OK: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxok); return; case OID_GEN_RCV_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.rxbad); return; case OID_GEN_XMIT_ERROR: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, usb_eth_stat.txbad); return; case OID_GEN_RCV_NO_BUFFER: rndis_query_cmplt32(RNDIS_STATUS_SUCCESS, 0); return; default: rndis_query_cmplt(RNDIS_STATUS_FAILURE, NULL, 0); return; } } #define INFBUF ((uint8_t *)&(m->RequestId) + m->InformationBufferOffset) static void rndis_handle_config_parm(const char *data, int keyoffset, int valoffset, int keylen, int vallen) { (void)data; (void)keyoffset; (void)valoffset; (void)keylen; (void)vallen; } static void rndis_packetFilter(uint32_t newfilter) { (void)newfilter; } static void rndis_handle_set_msg(void) { rndis_set_cmplt_t *c; rndis_set_msg_t *m; rndis_Oid_t oid; c = (rndis_set_cmplt_t *)encapsulated_buffer; m = (rndis_set_msg_t *)encapsulated_buffer; oid = m->Oid; c->MessageType = REMOTE_NDIS_SET_CMPLT; c->MessageLength = sizeof(rndis_set_cmplt_t); c->Status = RNDIS_STATUS_SUCCESS; switch (oid) { /* Parameters set up in 'Advanced' tab */ case OID_GEN_RNDIS_CONFIG_PARAMETER: { rndis_config_parameter_t *p; char *ptr = (char *)m; ptr += sizeof(rndis_generic_msg_t); ptr += m->InformationBufferOffset; p = (rndis_config_parameter_t *) ((void*) ptr); rndis_handle_config_parm(ptr, p->ParameterNameOffset, p->ParameterValueOffset, p->ParameterNameLength, p->ParameterValueLength); } break; /* Mandatory general OIDs */ case OID_GEN_CURRENT_PACKET_FILTER: memcpy(&oid_packet_filter, INFBUF, 4); if (oid_packet_filter) { rndis_packetFilter(oid_packet_filter); rndis_state = rndis_data_initialized; } else { rndis_state = rndis_initialized; } break; case OID_GEN_CURRENT_LOOKAHEAD: break; case OID_GEN_PROTOCOL_OPTIONS: break; /* Mandatory 802_3 OIDs */ case OID_802_3_MULTICAST_LIST: break; /* Power Management: fails for now */ case OID_PNP_ADD_WAKE_UP_PATTERN: case OID_PNP_REMOVE_WAKE_UP_PATTERN: case OID_PNP_ENABLE_WAKE_UP: default: c->Status = RNDIS_STATUS_FAILURE; break; } /* c->MessageID is same as before */ rndis_report(); return; } void rndis_class_set_handler(uint8_t *data, int size) { encapsulated_buffer = data; (void)size; switch (((rndis_generic_msg_t *)encapsulated_buffer)->MessageType) { case REMOTE_NDIS_INITIALIZE_MSG: { rndis_initialize_cmplt_t *m; m = ((rndis_initialize_cmplt_t *)encapsulated_buffer); /* m->MessageID is same as before */ m->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; m->MessageLength = sizeof(rndis_initialize_cmplt_t); m->MajorVersion = RNDIS_MAJOR_VERSION; m->MinorVersion = RNDIS_MINOR_VERSION; m->Status = RNDIS_STATUS_SUCCESS; m->DeviceFlags = RNDIS_DF_CONNECTIONLESS; m->Medium = RNDIS_MEDIUM_802_3; m->MaxPacketsPerTransfer = 1; m->MaxTransferSize = CFG_TUD_NET_MTU + sizeof(rndis_data_packet_t); m->PacketAlignmentFactor = 0; m->AfListOffset = 0; m->AfListSize = 0; rndis_state = rndis_initialized; rndis_report(); } break; case REMOTE_NDIS_QUERY_MSG: rndis_query(); break; case REMOTE_NDIS_SET_MSG: rndis_handle_set_msg(); break; case REMOTE_NDIS_RESET_MSG: { rndis_reset_cmplt_t * m; m = ((rndis_reset_cmplt_t *)encapsulated_buffer); rndis_state = rndis_uninitialized; m->MessageType = REMOTE_NDIS_RESET_CMPLT; m->MessageLength = sizeof(rndis_reset_cmplt_t); m->Status = RNDIS_STATUS_SUCCESS; m->AddressingReset = 1; /* Make it look like we did something */ /* m->AddressingReset = 0; - Windows halts if set to 1 for some reason */ rndis_report(); } break; case REMOTE_NDIS_KEEPALIVE_MSG: { rndis_keepalive_cmplt_t * m; m = (rndis_keepalive_cmplt_t *)encapsulated_buffer; m->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; m->MessageLength = sizeof(rndis_keepalive_cmplt_t); m->Status = RNDIS_STATUS_SUCCESS; } /* We have data to send back */ rndis_report(); break; default: break; } } #endif ================================================ FILE: lib/rt-thread/SConscript ================================================ import rtconfig from building import * cwd = GetCurrentDir() src = Split(""" ../../src/tusb.c ../../src/common/tusb_fifo.c ./tusb_rt_thread_port.c """) path = [cwd, cwd + "/../../src"] LOCAL_CFLAGS = '' # for device stack if GetDepend(["PKG_TINYUSB_DEVICE_ENABLE"]): src += ["../../src/device/usbd.c", "../../src/device/usbd_control.c"] # BSP if GetDepend(["SOC_FAMILY_STM32"]): src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c", "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c", "../../src/portable/st/stm32_fsdev/fsdev_common.c"] if GetDepend(["SOC_NRF52840"]): src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"] if GetDepend(["SOC_FAMILY_RENESAS"]): src += ["../../src/portable/renesas/rusb2/dcd_rusb2.c", "../../src/portable/renesas/rusb2/rusb2_common.c"] # Device class if GetDepend(["PKG_TINYUSB_DEVICE_UVC"]): src += ["../../src/class/video/video_device.c"] if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]): src += ["../../src/class/cdc/cdc_device.c"] if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] if GetDepend(["PKG_TINYUSB_DEVICE_MTP"]): src += ["../../src/class/mtp/mtp_device.c"] if GetDepend(["PKG_TINYUSB_DEVICE_HID"]): src += ["../../src/class/hid/hid_device.c"] # for host stack if GetDepend(["PKG_TINYUSB_HOST_ENABLE"]): src += ["../../src/host/usbh.c", "../../src/host/hub.c"] if GetDepend(["SOC_FAMILY_RENESAS"]): src += ["../../src/portable/renesas/rusb2/hcd_rusb2.c", "../../src/portable/renesas/rusb2/rusb2_common.c"] if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 LOCAL_CFLAGS += ' -std=c99' elif rtconfig.PLATFORM == 'armcc': # Keil AC5 LOCAL_CFLAGS += ' --c99 --gnu' group = DefineGroup('TinyUSB', src, depend = ['PKG_USING_TINYUSB'], CPPPATH = path, LOCAL_CFLAGS = LOCAL_CFLAGS) Return('group') ================================================ FILE: lib/rt-thread/port/msc_device_port.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifdef __RTTHREAD__ #include #include #include #include static bool ejected = false; static rt_device_t flash_device; static struct rt_device_blk_geometry blk_geom; #ifdef __CC_ARM uint16_t __builtin_bswap16(uint16_t x) { return (x << 8) | (x >> 8); } #endif void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { (void) lun; const char vid[] = PKG_TINYUSB_DEVICE_MSC_VID; const char pid[] = PKG_TINYUSB_DEVICE_MSC_PID; const char rev[] = PKG_TINYUSB_DEVICE_MSC_REV; memcpy(vendor_id, vid, strlen(vid)); memcpy(product_id, pid, strlen(pid)); memcpy(product_rev, rev, strlen(rev)); } bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; if (ejected) { tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); return false; } if (flash_device == NULL) { flash_device = rt_device_find(PKG_TINYUSB_DEVICE_MSC_NAME); } if (flash_device != NULL) { static uint8_t open_flg = 0; if (!open_flg) { open_flg = 1; rt_device_open(flash_device, 0); } rt_device_control(flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &blk_geom); return true; } return false; } void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { (void) lun; *block_count = blk_geom.sector_count; *block_size = blk_geom.bytes_per_sector; } bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; if (load_eject) { if (start) { ejected = false; } else { // unload disk storage ejected = true; } } return true; } int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { (void) lun; (void) offset; (void) bufsize; return (int32_t) rt_device_read(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; } int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) { (void) lun; (void) offset; (void) bufsize; return (int32_t) rt_device_write(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; } int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { void const *response = NULL; uint16_t resplen = 0; // most scsi handled is input bool in_xfer = true; switch (scsi_cmd[0]) { case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: // Host is about to read/write etc ... better not to disconnect disk resplen = 0; break; default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // negative means error -> tinyusb could stall and/or response with failed status resplen = -1; break; } // return resplen must not larger than bufsize if (resplen > bufsize) resplen = bufsize; if (response && (resplen > 0)) { if (in_xfer) { memcpy(buffer, response, resplen); } else { // SCSI output } } return resplen; } #endif /*__RTTHREAD__*/ ================================================ FILE: lib/rt-thread/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __RTTHREAD__ #include #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- #if defined(SOC_SERIES_STM32F0) #define CFG_TUSB_MCU OPT_MCU_STM32F0 #elif defined(SOC_SERIES_STM32F1) #define CFG_TUSB_MCU OPT_MCU_STM32F1 #elif defined(SOC_SERIES_STM32F2) #define CFG_TUSB_MCU OPT_MCU_STM32F2 #elif defined(SOC_SERIES_STM32F3) #define CFG_TUSB_MCU OPT_MCU_STM32F3 #elif defined(SOC_SERIES_STM32F4) #define CFG_TUSB_MCU OPT_MCU_STM32F4 #elif defined(SOC_SERIES_STM32F7) #define CFG_TUSB_MCU OPT_MCU_STM32F7 #elif defined(SOC_SERIES_STM32H7) #define CFG_TUSB_MCU OPT_MCU_STM32H7 #elif defined(SOC_SERIES_STM32L0) #define CFG_TUSB_MCU OPT_MCU_STM32L0 #elif defined(SOC_SERIES_STM32L1) #define CFG_TUSB_MCU OPT_MCU_STM32L1 #elif defined(SOC_SERIES_STM32L4) #define CFG_TUSB_MCU OPT_MCU_STM32L4 #elif defined(SOC_NRF52840) #define CFG_TUSB_MCU OPT_MCU_NRF5X #elif defined(SOC_HPM6000) #define CFG_TUSB_MCU OPT_MCU_HPM #elif defined(SOC_RP2040) #define CFG_TUSB_MCU OPT_MCU_RP2040 #elif defined(SOC_FAMILY_RENESAS) #define CFG_TUSB_MCU OPT_MCU_RAXXX #else #error "Not support for current MCU" #endif #define CFG_TUSB_OS OPT_OS_RTTHREAD //-------------------------------------------------------------------- // DEBUG CONFIGURATION //-------------------------------------------------------------------- #ifdef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG_PRINTF rt_kprintf #endif /* CFG_TUSB_DEBUG */ #ifndef BOARD_DEVICE_RHPORT_NUM #define BOARD_DEVICE_RHPORT_NUM PKG_TINYUSB_RHPORT_NUM #endif #ifndef BOARD_DEVICE_RHPORT_SPEED #define BOARD_DEVICE_RHPORT_SPEED PKG_TINYUSB_DEVICE_PORT_SPEED #endif #if BOARD_DEVICE_RHPORT_NUM == 0 #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #elif BOARD_DEVICE_RHPORT_NUM == 1 #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #else #error "Incorrect RHPort configuration" #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION rt_section(PKG_TINYUSB_MEM_SECTION) #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN rt_align(PKG_TINYUSB_MEM_ALIGN) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #if defined(PKG_TINYUSB_DEVICE_ENABLE) #define CFG_TUD_ENABLED (1) #else #define CFG_TUD_ENABLED (0) #endif #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE PKG_TINYUSB_EDPT0_SIZE #endif // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_RX_BUFSIZE #define CFG_TUD_CDC_TX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_TX_BUFSIZE #define CFG_TUD_MSC_EP_BUFSIZE PKG_TINYUSB_DEVICE_MSC_EP_BUFSIZE #define CFG_TUD_HID_EP_BUFSIZE PKG_TINYUSB_DEVICE_HID_EP_BUFSIZE #ifndef PKG_TINYUSB_DEVICE_CDC_STRING #define PKG_TINYUSB_DEVICE_CDC_STRING "" #endif #ifndef PKG_TINYUSB_DEVICE_MSC_STRING #define PKG_TINYUSB_DEVICE_MSC_STRING "" #endif #ifndef PKG_TINYUSB_DEVICE_HID_STRING #define PKG_TINYUSB_DEVICE_HID_STRING "" #endif //-------------------------------------------------------------------- // HOST CONFIGURATION //-------------------------------------------------------------------- #if defined(PKG_TINYUSB_HOST_ENABLE) #define CFG_TUH_ENABLED (1) #else #define CFG_TUH_ENABLED (0) #endif #if (PKG_TINYUSB_HOST_PORT == 0) && defined(PKG_TINYUSB_HOST_ENABLE) #undef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) #endif #if (PKG_TINYUSB_HOST_PORT == 1) && defined(PKG_TINYUSB_HOST_ENABLE) #undef CFG_TUSB_RHPORT1_MODE #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | PKG_TINYUSB_HOST_PORT_SPEED) #endif #define BOARD_TUH_RHPORT PKG_TINYUSB_HOST_PORT // FULL SPEED #define BOARD_TUH_MAX_SPEED PKG_TINYUSB_HOST_PORT_SPEED // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED //------------------------- Board Specific -------------------------- // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUH_MAX_SPEED #define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 2 // number of supported hubs #define CFG_TUH_CDC 0 // CDC ACM #define CFG_TUH_CDC_FTDI 0 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 0 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 0 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 0 //#define CFG_TUH_VENDOR 3 // max device support (excluding hub device): 1 hub typically has 4 ports #define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- HID -------------// #define CFG_TUH_HID_EPIN_BUFSIZE 64 #define CFG_TUH_HID_EPOUT_BUFSIZE 64 //------------- CDC -------------// // Set Line Control state on enumeration/mounted: // DTR ( bit 0), RTS (bit 1) #define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width #define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } #ifdef __cplusplus } #endif #endif /*__RTTHREAD__*/ #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: lib/rt-thread/tusb_rt_thread_port.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifdef __RTTHREAD__ #include #define DBG_TAG "TinyUSB" #define DBG_LVL DBG_INFO #include #include #ifndef RT_USING_HEAP /* if there is not enable heap, we should use static thread and stack. */ static rt_uint8_t tusb_stack[PKG_TINYUSB_STACK_SIZE]; static struct rt_thread tusb_thread; #endif /* RT_USING_HEAP */ extern int tusb_board_init(void); static void tusb_thread_entry(void *parameter) { (void) parameter; while (1) { #if CFG_TUH_ENABLED tuh_task(); #endif #if CFG_TUD_ENABLED tud_task(); #endif } } static int init_tinyusb(void) { rt_thread_t tid; tusb_board_init(); tusb_init(); #ifdef RT_USING_HEAP tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, PKG_TINYUSB_STACK_SIZE, PKG_TINYUSB_THREAD_PRIORITY, 10); if (tid == RT_NULL) #else rt_err_t result; tid = &tusb_thread; result = rt_thread_init(tid, "tusb", tusb_thread_entry, RT_NULL, tusb_stack, sizeof(tusb_stack), 4, 10); if (result != RT_EOK) #endif /* RT_USING_HEAP */ { LOG_E("Fail to create TinyUSB thread"); return -1; } rt_thread_startup(tid); return 0; } INIT_APP_EXPORT(init_tinyusb); #endif /*__RTTHREAD__*/ ================================================ FILE: library.json ================================================ { "name": "TinyUSB", "version": "0.20.0", "description": "TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.", "keywords": "usb, host, device", "repository": { "type": "git", "url": "https://github.com/hathach/tinyusb.git" }, "authors": [ { "name": "Ha Thach", "email": "thach@tinyusb.org", "maintainer": true } ], "license": "MIT", "homepage": "https://www.tinyusb.org/", "frameworks": "*", "platforms": "*" } ================================================ FILE: pkg.yml ================================================ pkg.name: tinyusb pkg.description: An open source cross-platform USB stack for embedded system pkg.author: "Ha Thach " pkg.homepage: "https://github.com/hathach/tinyusb" pkg.keywords: - usb pkg.type: sdk pkg.deps: - "@apache-mynewt-core/kernel/os" pkg.include_dirs: - src ================================================ FILE: repository.yml ================================================ repo.name: tinyusb repo.versions: "0.0.0": "master" "0.5.0": "0.5.0" "0.6.0": "0.6.0" "0.7.0": "0.7.0" "0.8.0": "0.8.0" "0.9.0": "0.9.0" "0.10.0": "0.10.0" "0.10.1": "0.10.1" "0.11.0": "0.11.0" "0.12.0": "0.12.0" "0.13.0": "0.13.0" "0.14.0": "0.14.0" "0.15.0": "0.15.0" "0.16.0": "0.16.0" "0.17.0": "0.17.0" "0.18.0": "0.18.0" "0.19.0": "0.19.0" "0.20.0": "0.20.0" "0-latest": "0.20.0" "0-dev": "0.0.0" ================================================ FILE: sonar-project.properties ================================================ sonar.projectKey=hathach_tinyusb sonar.organization=hathach # This is the name and version displayed in the SonarCloud UI. sonar.projectName=tinyusb sonar.projectVersion=0.20.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. #sonar.sources=. sonar.exclusions=lib/**,hw/mcu/**,test/** # Encoding of the source code. Default is default system encoding #sonar.sourceEncoding=UTF-8 ================================================ FILE: src/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) # Get TinyUSB sources. Note: DCD and HCD drivers are not included function(tinyusb_sources_get OUTPUT_VAR) set(${OUTPUT_VAR} # common ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/tusb.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/common/tusb_fifo.c # device ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/device/usbd.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/device/usbd_control.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/audio/audio_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/cdc/cdc_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/dfu/dfu_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/dfu/dfu_rt_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/mtp/mtp_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/net/ecm_rndis_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/net/ncm_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/printer/printer_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/usbtmc/usbtmc_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_device.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/video/video_device.c # host ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/host/usbh.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/host/hub.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/cdc/cdc_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_host.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_host.c # typec ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/typec/usbc.c PARENT_SCOPE ) endfunction() # Add tinyusb to a existing target function(tinyusb_target_add TARGET) tinyusb_sources_get(TINYUSB_SRC) target_sources(${TARGET} PRIVATE ${TINYUSB_SRC}) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} # TODO for net driver, should be removed/changed ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../lib/networking ) endfunction() ================================================ FILE: src/class/audio/audio.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2020 Reinhard Panhuber * * 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. * * This file is part of the TinyUSB stack. */ /** \ingroup group_class * \defgroup ClassDriver_Audio Audio * Currently only MIDI subclass is supported * @{ */ #ifndef TUSB_AUDIO_H__ #define TUSB_AUDIO_H__ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // GENERIC AUDIO CLASS CODES (COMMON TO UAC1 AND UAC2) //--------------------------------------------------------------------+ /// A.2 - Audio Function Subclass Codes typedef enum { AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00, } audio_function_subclass_type_t; /// A.3 - Audio Function Protocol Codes typedef enum { AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00, AUDIO_FUNC_PROTOCOL_CODE_V1 = 0x00,///< Version 1.0 - same as undefined for backward compatibility AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20,///< Version 2.0 } audio_function_protocol_code_t; /// A.5 - Audio Interface Subclass Codes typedef enum { AUDIO_SUBCLASS_UNDEFINED = 0x00, AUDIO_SUBCLASS_CONTROL, ///< Audio Control AUDIO_SUBCLASS_STREAMING, ///< Audio Streaming AUDIO_SUBCLASS_MIDI_STREAMING,///< MIDI Streaming } audio_subclass_type_t; /// A.6 - Audio Interface Protocol Codes typedef enum { AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00, AUDIO_INT_PROTOCOL_CODE_V1 = 0x00,///< Version 1.0 - same as undefined for backward compatibility AUDIO_INT_PROTOCOL_CODE_V2 = 0x20,///< Version 2.0 } audio_interface_protocol_code_t; /// Terminal Types /// 2.1 - Audio Class-Terminal Types typedef enum { AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100, AUDIO_TERM_TYPE_USB_STREAMING = 0x0101, AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF, } audio_terminal_type_t; /// 2.2 - Audio Class-Input Terminal Types typedef enum { AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200, AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201, AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202, AUDIO_TERM_TYPE_IN_PERSONAL_MIC = 0x0203, AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204, AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205, AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206, } audio_terminal_input_type_t; /// 2.3 - Audio Class-Output Terminal Types typedef enum { AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300, AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301, AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302, AUDIO_TERM_TYPE_OUT_HEAD_MNT_DISP_AUIDO = 0x0303, AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER = 0x0304, AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305, AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306, AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307, } audio_terminal_output_type_t; /// Rest is yet to be implemented //--------------------------------------------------------------------+ // USB AUDIO CLASS 1.0 (UAC1) DEFINITIONS //--------------------------------------------------------------------+ /// A.5 - Audio Class-Specific AC Interface Descriptor Subtypes UAC1 typedef enum { AUDIO10_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, AUDIO10_CS_AC_INTERFACE_HEADER = 0x01, AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, AUDIO10_CS_AC_INTERFACE_MIXER_UNIT = 0x04, AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT = 0x07, AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT = 0x08, } audio10_cs_ac_interface_subtype_t; /// A.6 - Audio Class-Specific AS Interface Descriptor Subtypes UAC1 typedef enum { AUDIO10_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, AUDIO10_CS_AS_INTERFACE_AS_GENERAL = 0x01, AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, } audio10_cs_as_interface_subtype_t; /// A.8 - Audio Class-Specific EP Descriptor Subtypes UAC1 typedef enum { AUDIO10_CS_EP_SUBTYPE_UNDEF = 0x00, AUDIO10_CS_EP_SUBTYPE_GENERAL = 0x01, } audio10_cs_ep_subtype_t; /// A.9 - Audio Class-Specific Request Codes UAC1 typedef enum { AUDIO10_CS_REQ_UNDEF = 0x00, AUDIO10_CS_REQ_SET_CUR = 0x01, AUDIO10_CS_REQ_GET_CUR = 0x81, AUDIO10_CS_REQ_SET_MIN = 0x02, AUDIO10_CS_REQ_GET_MIN = 0x82, AUDIO10_CS_REQ_SET_MAX = 0x03, AUDIO10_CS_REQ_GET_MAX = 0x83, AUDIO10_CS_REQ_SET_RES = 0x04, AUDIO10_CS_REQ_GET_RES = 0x84, AUDIO10_CS_REQ_SET_MEM = 0x05, AUDIO10_CS_REQ_GET_MEM = 0x85, AUDIO10_CS_REQ_GET_STAT = 0xFF, } audio10_cs_req_t; /// A.10.1 - Terminal Control Selectors UAC1 typedef enum { AUDIO10_TE_CTRL_UNDEF = 0x00, AUDIO10_TE_CTRL_COPY_PROTECT = 0x01, } audio10_terminal_control_selector_t; /// A.10.2 - Feature Unit Control Selectors UAC1 typedef enum { AUDIO10_FU_CTRL_UNDEF = 0x00, AUDIO10_FU_CTRL_MUTE = 0x01, AUDIO10_FU_CTRL_VOLUME = 0x02, AUDIO10_FU_CTRL_BASS = 0x03, AUDIO10_FU_CTRL_MID = 0x04, AUDIO10_FU_CTRL_TREBLE = 0x05, AUDIO10_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, AUDIO10_FU_CTRL_AGC = 0x07, AUDIO10_FU_CTRL_DELAY = 0x08, AUDIO10_FU_CTRL_BASS_BOOST = 0x09, AUDIO10_FU_CTRL_LOUDNESS = 0x0A, } audio10_feature_unit_control_selector_t; /// A.10.3.1 - Up/Down-mix Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_UD_CTRL_UNDEF = 0x00, AUDIO10_UD_CTRL_ENABLE = 0x01, AUDIO10_UD_CTRL_MODE_SELECT = 0x02, } audio10_up_down_mix_control_selector_t; /// A.10.3.2 - Dolby Prologic Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_DP_CTRL_UNDEF = 0x00, AUDIO10_DP_CTRL_ENABLE = 0x01, AUDIO10_DP_CTRL_MODE_SELECT = 0x02, } audio10_dolby_prologic_control_selector_t; /// A.10.3.3 - 3D Stereo Extender Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_3D_CTRL_UNDEF = 0x00, AUDIO10_3D_CTRL_ENABLE = 0x01, AUDIO10_3D_CTRL_SPACIOUSNESS = 0x02, } audio10_3d_stereo_extender_control_selector_t; /// A.10.3.4 - Reverberation Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_RV_CTRL_UNDEF = 0x00, AUDIO10_RV_CTRL_ENABLE = 0x01, AUDIO10_RV_CTRL_REVERB_LEVEL = 0x02, AUDIO10_RV_CTRL_REVERB_TIME = 0x03, AUDIO10_RV_CTRL_REVERB_FEEDBACK = 0x04, } audio10_reverberation_control_selector_t; /// A.10.3.5 - Chorus Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_CH_CTRL_UNDEF = 0x00, AUDIO10_CH_CTRL_ENABLE = 0x01, AUDIO10_CH_CTRL_CHORUS_LEVEL = 0x02, AUDIO10_CH_CTRL_CHORUS_RATE = 0x03, AUDIO10_CH_CTRL_CHORUS_DEPTH = 0x04, } audio10_chorus_control_selector_t; /// A.10.3.6 - Dynamic Range Compressor Processing Unit Control Selectors UAC1 typedef enum { AUDIO10_DR_CTRL_UNDEF = 0x00, AUDIO10_DR_CTRL_ENABLE = 0x01, AUDIO10_DR_CTRL_COMPRESSION_RATE = 0x02, AUDIO10_DR_CTRL_MAXAMPL = 0x03, AUDIO10_DR_CTRL_THRESHOLD = 0x04, AUDIO10_DR_CTRL_ATTACK_TIME = 0x05, AUDIO10_DR_CTRL_RELEASE_TIME = 0x06, } audio10_dynamic_range_compression_control_selector_t; /// A.10.4 - Extension Unit Control Selectors UAC1 typedef enum { AUDIO10_XU_CTRL_UNDEF = 0x00, AUDIO10_XU_CTRL_ENABLE = 0x01, } audio10_extension_unit_control_selector_t; /// A.10.5 - Endpoint Control Selectors UAC1 typedef enum { AUDIO10_EP_CTRL_UNDEF = 0x00, AUDIO10_EP_CTRL_SAMPLING_FREQ = 0x01, AUDIO10_EP_CTRL_PITCH = 0x02, } audio10_ep_control_selector_t; /// Audio Class-Specific AS Isochronous Data EP Attributes UAC1 typedef enum { AUDIO10_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, AUDIO10_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ = 0x01, AUDIO10_CS_AS_ISO_DATA_EP_ATT_PITCH = 0x02, } audio10_cs_as_iso_data_ep_attribute_t; /// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC1 typedef enum { AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, } audio10_cs_as_iso_data_ep_lock_delay_unit_t; /// Audio Class-Feature Unit Controls UAC1 typedef enum { AUDIO10_FU_CONTROL_BM_MUTE = 1 << 0, AUDIO10_FU_CONTROL_BM_VOLUME = 1 << 1, AUDIO10_FU_CONTROL_BM_BASS = 1 << 2, AUDIO10_FU_CONTROL_BM_MID = 1 << 3, AUDIO10_FU_CONTROL_BM_TREBLE = 1 << 4, AUDIO10_FU_CONTROL_BM_GRAPHIC_EQUALIZER = 1 << 5, AUDIO10_FU_CONTROL_BM_AGC = 1 << 6, AUDIO10_FU_CONTROL_BM_DELAY = 1 << 7, AUDIO10_FU_CONTROL_BM_BASS_BOOST = 1 << 8, AUDIO10_FU_CONTROL_BM_LOUDNESS = 1 << 9, } audio10_feature_unit_control_bitmap_t; /// A.1 - Audio Class-Format Type Codes UAC1 typedef enum { AUDIO10_FORMAT_TYPE_UNDEFINED = 0x00, AUDIO10_FORMAT_TYPE_I = 0x01, AUDIO10_FORMAT_TYPE_II = 0x02, AUDIO10_FORMAT_TYPE_III = 0x03, } audio10_format_type_t; // A.1.1 - Audio Class-Audio Data Format Type I UAC1 typedef enum { AUDIO10_DATA_FORMAT_TYPE_I_PCM = 0x0001, AUDIO10_DATA_FORMAT_TYPE_I_PCM8 = 0x0002, AUDIO10_DATA_FORMAT_TYPE_I_IEEE_FLOAT = 0x0003, AUDIO10_DATA_FORMAT_TYPE_I_ALAW = 0x0004, AUDIO10_DATA_FORMAT_TYPE_I_MULAW = 0x0005, } audio10_data_format_type_I_t; // A.1.2 - Audio Class-Audio Data Format Type II UAC1 typedef enum { AUDIO10_DATA_FORMAT_TYPE_II_MPEG = 0x1001, AUDIO10_DATA_FORMAT_TYPE_II_AC3 = 0x1002, } audio10_data_format_type_II_t; // A.1.3 - Audio Class-Audio Data Format Type III UAC1 typedef enum { AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_AC3_1 = 0x2001, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L1_1 = 0x2002, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG1_L23_1 = 0x2003, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_EXT_1 = 0x2004, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_L1_LS_1 = 0x2005, AUDIO10_DATA_FORMAT_TYPE_III_IEC1937_MPEG2_L23_LS_1 = 0x2006, } audio10_data_format_type_III_t; /// Audio Class-Audio Channel Configuration UAC1 (Table A-7) typedef enum { AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED = 0x0000, AUDIO10_CHANNEL_CONFIG_LEFT_FRONT = 0x0001, AUDIO10_CHANNEL_CONFIG_RIGHT_FRONT = 0x0002, AUDIO10_CHANNEL_CONFIG_CENTER_FRONT = 0x0004, AUDIO10_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x0008, AUDIO10_CHANNEL_CONFIG_LEFT_SURROUND = 0x0010, AUDIO10_CHANNEL_CONFIG_RIGHT_SURROUND = 0x0020, AUDIO10_CHANNEL_CONFIG_LEFT_OF_CENTER = 0x0040, AUDIO10_CHANNEL_CONFIG_RIGHT_OF_CENTER = 0x0080, AUDIO10_CHANNEL_CONFIG_SURROUND = 0x0100, AUDIO10_CHANNEL_CONFIG_SIDE_LEFT = 0x0200, AUDIO10_CHANNEL_CONFIG_SIDE_RIGHT = 0x0400, AUDIO10_CHANNEL_CONFIG_TOP = 0x0800, } audio10_channel_config_t; //--------------------------------------------------------------------+ // USB AUDIO CLASS 1.0 (UAC1) DESCRIPTORS //--------------------------------------------------------------------+ /// AUDIO Class-Specific AC Interface Header Descriptor UAC1 (4.3.2) #define audio10_desc_cs_ac_interface_n_t(numInterfaces) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 8+n. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_HEADER. */ \ uint16_t bcdADC; /* Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: 0x0100 for UAC1. */ \ uint16_t wTotalLength; /* Total number of bytes returned for the class-specific AudioControl interface descriptor. */ \ uint8_t bInCollection; /* The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface Collection. */ \ uint8_t baInterfaceNr[numInterfaces]; /* Interface number of the AudioStreaming or MIDIStreaming interface in the Collection. */ \ } /// AUDIO Input Terminal Descriptor UAC1 (4.3.2.1) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 12. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL. uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. uint8_t bAssocTerminal; ///< ID of the Output Terminal to which this Input Terminal is associated. uint8_t bNrChannels; ///< Number of logical output channels in the Terminal's output audio channel cluster. uint16_t wChannelConfig; ///< Describes the spatial location of the logical channels. uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first logical channel. uint8_t iTerminal; ///< Index of a string descriptor, describing the Input Terminal. } audio10_desc_input_terminal_t; /// AUDIO Output Terminal Descriptor UAC1 (4.3.2.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 9. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL. uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. uint8_t bAssocTerminal; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Terminal is connected. uint8_t iTerminal; ///< Index of a string descriptor, describing the Output Terminal. } audio10_desc_output_terminal_t; /// AUDIO Mixer Unit Descriptor UAC1 (4.3.2.3) #define audio10_desc_mixer_unit_n_t(numInputPins, numControlBytes) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 10+p+n. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_MIXER_UNIT. */ \ uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Mixer Unit are connected. */ \ uint8_t bNrChannels; /* Number of logical output channels in the Mixer Unit's output audio channel cluster. */ \ uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ uint8_t bmControls[numControlBytes]; /* Mixer Unit Controls bitmap. */ \ uint8_t iMixer; /* Index of a string descriptor, describing the Mixer Unit. */ \ } /// AUDIO Selector Unit Descriptor UAC1 (4.3.2.4) #define audio10_desc_selector_unit_n_t(numInputPins) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 6+p. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT. */ \ uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Selector Unit are connected. */ \ uint8_t iSelector; /* Index of a string descriptor, describing the Selector Unit. */ \ } /// AUDIO Feature Unit Descriptor UAC1 (4.3.2.5) #define audio10_desc_feature_unit_n_t(numChannels, controlSize) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 7+(ch+1)*n. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT. */ \ uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ uint8_t bSourceID; /* ID of the Unit or Terminal to which this Feature Unit is connected. */ \ uint8_t bControlSize; /* Size in bytes of an element of the bmaControls() array. */ \ uint8_t bmaControls[(numChannels + 1) * controlSize]; /* Control bitmaps for master + logical channels. */ \ uint8_t iFeature; /* Index of a string descriptor, describing this Feature Unit. */ \ } /// AUDIO Processing Unit Descriptor UAC1 (4.3.2.6) #define audio10_desc_processing_unit_n_t(numInputPins, numControlBytes) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 13+p+n. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_PROCESSING_UNIT. */ \ uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ uint16_t wProcessType; /* Constant identifying the type of processing this Unit is performing. */ \ uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Processing Unit are connected. */ \ uint8_t bNrChannels; /* Number of logical output channels in the Processing Unit's output audio channel cluster. */ \ uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ uint8_t bControlSize; /* Size in bytes of the bmControls field. */ \ uint8_t bmControls[numControlBytes]; /* Processing Unit Controls bitmap. */ \ uint8_t iProcessing; /* Index of a string descriptor, describing the Processing Unit. */ \ } /// AUDIO Extension Unit Descriptor UAC1 (4.3.2.7) #define audio10_desc_extension_unit_n_t(numInputPins, numControlBytes) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 13+p+n. */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AC_INTERFACE_EXTENSION_UNIT. */ \ uint8_t bUnitID; /* Constant uniquely identifying the Unit within the audio function. */ \ uint16_t wExtensionCode; /* Vendor-specific code identifying the Extension Unit. */ \ uint8_t bNrInPins; /* Number of Input Pins of this Unit: p. */ \ uint8_t baSourceID[numInputPins]; /* ID of the Unit or Terminal to which Input Pins of this Extension Unit are connected. */ \ uint8_t bNrChannels; /* Number of logical output channels in the Extension Unit's output audio channel cluster. */ \ uint16_t wChannelConfig; /* Describes the spatial location of the logical channels. */ \ uint8_t iChannelNames; /* Index of a string descriptor, describing the name of the first logical channel. */ \ uint8_t bControlSize; /* Size in bytes of the bmControls field. */ \ uint8_t bmControls[numControlBytes]; /* Extension Unit Controls bitmap. */ \ uint8_t iExtension; /* Index of a string descriptor, describing the Extension Unit. */ \ } /// AUDIO Class-Specific AS Interface Descriptor UAC1 (4.5.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 7. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_AS_GENERAL. uint8_t bTerminalLink; ///< The Terminal ID of the Terminal to which the endpoint of this interface is connected. uint8_t bDelay; ///< Expressed in number of frames. uint16_t wFormatTag; ///< The Audio Data Format that has to be used to communicate with this interface. } audio10_desc_cs_as_interface_t; /// AUDIO Type I Format Type Descriptor UAC1 (2.2.5) #define audio10_desc_type_I_format_n_t(numSamFreq) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 8+(ns*3). */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ uint8_t bNrChannels; /* Indicates the number of physical channels in the audio data stream. */ \ uint8_t bSubFrameSize; /* The number of bytes occupied by one audio subframe. */ \ uint8_t bBitResolution; /* The number of effectively used bits from the available bits in an audio subframe. */ \ uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ } /// AUDIO Type II Format Type Descriptor UAC1 (2.3.5) #define audio10_desc_type_II_format_n_t(numSamFreq) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 9+(ns*3). */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ uint16_t wMaxBitRate; /* Indicates the maximum number of bits per second this interface can handle. */ \ uint16_t wSamplesPerFrame; /* Indicates the number of PCM audio samples contained in one encoded audio frame. */ \ uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ } /// AUDIO Type III Format Type Descriptor UAC1 (2.4.5) #define audio10_desc_type_III_format_n_t(numSamFreq) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* Size of this descriptor in bytes: 8+(ns*3). */ \ uint8_t bDescriptorType; /* Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. */ \ uint8_t bDescriptorSubType; /* Descriptor SubType. Value: AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE. */ \ uint8_t bFormatType; /* Constant identifying the Format Type the AudioStreaming interface is using. */ \ uint8_t bNrChannels; /* Indicates the number of physical channels in the audio data stream. */ \ uint8_t bSubFrameSize; /* The number of bytes occupied by one audio subframe. */ \ uint8_t bBitResolution; /* The number of effectively used bits from the available bits in an audio subframe. */ \ uint8_t bSamFreqType; /* Indicates how the sampling frequency can be programmed. */ \ uint8_t tSamFreq[numSamFreq * 3]; /* Sampling frequency or lower/upper bounds in Hz for the sampling frequency range. */ \ } /// Standard AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.1) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 9. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_ENDPOINT. uint8_t bEndpointAddress;///< The address of the endpoint on the USB device described by this descriptor. struct TU_ATTR_PACKED { uint8_t xfer : 2; // Control, ISO, Bulk, Interrupt uint8_t sync : 2; // None, Asynchronous, Adaptive, Synchronous uint8_t usage : 2; // Data, Feedback, Implicit feedback uint8_t : 2; } bmAttributes; uint16_t wMaxPacketSize; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. uint8_t bInterval; ///< Interval for polling endpoint for data transfers. uint8_t bRefresh; ///< The rate at which the endpoint is refreshed. uint8_t bSynchAddress; ///< The address of the endpoint used to send synchronization information for the data endpoint. } audio10_desc_as_iso_data_ep_t; /// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 7. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO10_CS_EP_SUBTYPE_GENERAL. uint8_t bmAttributes; ///< Bit 0: Sampling Frequency, Bit 1: Pitch, Bit 7: MaxPacketsOnly. uint8_t bLockDelayUnits; ///< Indicates the units used for the wLockDelay field. uint16_t wLockDelay; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. } audio10_desc_cs_as_iso_data_ep_t; /// AUDIO Interrupt Data Message Format UAC1 (3.7.1.2) typedef struct TU_ATTR_PACKED { uint8_t bStatusType;///< Indicates the type of status information being reported. uint8_t bOriginator;///< Indicates the entity that originated this status information. } audio10_interrupt_data_t; //--------------------------------------------------------------------+ // USB AUDIO CLASS 2.0 (UAC2) DEFINITIONS //--------------------------------------------------------------------+ /// A.7 - Audio Function Category Codes typedef enum { AUDIO20_FUNC_UNDEF = 0x00, AUDIO20_FUNC_DESKTOP_SPEAKER = 0x01, AUDIO20_FUNC_HOME_THEATER = 0x02, AUDIO20_FUNC_MICROPHONE = 0x03, AUDIO20_FUNC_HEADSET = 0x04, AUDIO20_FUNC_TELEPHONE = 0x05, AUDIO20_FUNC_CONVERTER = 0x06, AUDIO20_FUNC_SOUND_RECODER = 0x07, AUDIO20_FUNC_IO_BOX = 0x08, AUDIO20_FUNC_MUSICAL_INSTRUMENT = 0x09, AUDIO20_FUNC_PRO_AUDIO = 0x0A, AUDIO20_FUNC_AUDIO_VIDEO = 0x0B, AUDIO20_FUNC_CONTROL_PANEL = 0x0C, AUDIO20_FUNC_OTHER = 0xFF, } audio20_function_code_t; /// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2 typedef enum { AUDIO20_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, AUDIO20_CS_AC_INTERFACE_HEADER = 0x01, AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03, AUDIO20_CS_AC_INTERFACE_MIXER_UNIT = 0x04, AUDIO20_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT = 0x06, AUDIO20_CS_AC_INTERFACE_EFFECT_UNIT = 0x07, AUDIO20_CS_AC_INTERFACE_PROCESSING_UNIT = 0x08, AUDIO20_CS_AC_INTERFACE_EXTENSION_UNIT = 0x09, AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE = 0x0A, AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B, AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C, AUDIO20_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D, } audio20_cs_ac_interface_subtype_t; /// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2 typedef enum { AUDIO20_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, AUDIO20_CS_AS_INTERFACE_AS_GENERAL = 0x01, AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, AUDIO20_CS_AS_INTERFACE_ENCODER = 0x03, AUDIO20_CS_AS_INTERFACE_DECODER = 0x04, } audio20_cs_as_interface_subtype_t; /// A.11 - Effect Unit Effect Types typedef enum { AUDIO20_EFFECT_TYPE_UNDEF = 0x00, AUDIO20_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01, AUDIO20_EFFECT_TYPE_REVERBERATION = 0x02, AUDIO20_EFFECT_TYPE_MOD_DELAY = 0x03, AUDIO20_EFFECT_TYPE_DYN_RANGE_COMP = 0x04, } audio20_effect_unit_effect_type_t; /// A.12 - Processing Unit Process Types typedef enum { AUDIO20_PROCESS_TYPE_UNDEF = 0x00, AUDIO20_PROCESS_TYPE_UP_DOWN_MIX = 0x01, AUDIO20_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02, AUDIO20_PROCESS_TYPE_STEREO_EXTENDER = 0x03, } audio20_processing_unit_process_type_t; /// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2 typedef enum { AUDIO20_CS_EP_SUBTYPE_UNDEF = 0x00, AUDIO20_CS_EP_SUBTYPE_GENERAL = 0x01, } audio20_cs_ep_subtype_t; /// A.14 - Audio Class-Specific Request Codes UAC2 typedef enum { AUDIO20_CS_REQ_UNDEF = 0x00, AUDIO20_CS_REQ_CUR = 0x01, AUDIO20_CS_REQ_RANGE = 0x02, AUDIO20_CS_REQ_MEM = 0x03, } audio20_cs_req_t; /// A.17 - Control Selector Codes UAC2 /// A.17.1 - Clock Source Control Selectors typedef enum { AUDIO20_CS_CTRL_UNDEF = 0x00, AUDIO20_CS_CTRL_SAM_FREQ = 0x01, AUDIO20_CS_CTRL_CLK_VALID = 0x02, } audio20_clock_src_control_selector_t; /// A.17.2 - Clock Selector Control Selectors typedef enum { AUDIO20_CX_CTRL_UNDEF = 0x00, AUDIO20_CX_CTRL_CONTROL = 0x01, } audio20_clock_sel_control_selector_t; /// A.17.3 - Clock Multiplier Control Selectors typedef enum { AUDIO20_CM_CTRL_UNDEF = 0x00, AUDIO20_CM_CTRL_NUMERATOR_CONTROL = 0x01, AUDIO20_CM_CTRL_DENOMINATOR_CONTROL = 0x02, } audio20_clock_mul_control_selector_t; /// A.17.4 - Terminal Control Selectors UAC2 typedef enum { AUDIO20_TE_CTRL_UNDEF = 0x00, AUDIO20_TE_CTRL_COPY_PROTECT = 0x01, AUDIO20_TE_CTRL_CONNECTOR = 0x02, AUDIO20_TE_CTRL_OVERLOAD = 0x03, AUDIO20_TE_CTRL_CLUSTER = 0x04, AUDIO20_TE_CTRL_UNDERFLOW = 0x05, AUDIO20_TE_CTRL_OVERFLOW = 0x06, AUDIO20_TE_CTRL_LATENCY = 0x07, } audio20_terminal_control_selector_t; /// A.17.5 - Mixer Control Selectors typedef enum { AUDIO20_MU_CTRL_UNDEF = 0x00, AUDIO20_MU_CTRL_MIXER = 0x01, AUDIO20_MU_CTRL_CLUSTER = 0x02, AUDIO20_MU_CTRL_UNDERFLOW = 0x03, AUDIO20_MU_CTRL_OVERFLOW = 0x04, AUDIO20_MU_CTRL_LATENCY = 0x05, } audio20_mixer_control_selector_t; /// A.17.6 - Selector Control Selectors typedef enum { AUDIO20_SU_CTRL_UNDEF = 0x00, AUDIO20_SU_CTRL_SELECTOR = 0x01, AUDIO20_SU_CTRL_LATENCY = 0x02, } audio20_sel_control_selector_t; /// A.17.7 - Feature Unit Control Selectors UAC2 typedef enum { AUDIO20_FU_CTRL_UNDEF = 0x00, AUDIO20_FU_CTRL_MUTE = 0x01, AUDIO20_FU_CTRL_VOLUME = 0x02, AUDIO20_FU_CTRL_BASS = 0x03, AUDIO20_FU_CTRL_MID = 0x04, AUDIO20_FU_CTRL_TREBLE = 0x05, AUDIO20_FU_CTRL_GRAPHIC_EQUALIZER = 0x06, AUDIO20_FU_CTRL_AGC = 0x07, AUDIO20_FU_CTRL_DELAY = 0x08, AUDIO20_FU_CTRL_BASS_BOOST = 0x09, AUDIO20_FU_CTRL_LOUDNESS = 0x0A, AUDIO20_FU_CTRL_INPUT_GAIN = 0x0B, AUDIO20_FU_CTRL_GAIN_PAD = 0x0C, AUDIO20_FU_CTRL_INVERTER = 0x0D, AUDIO20_FU_CTRL_UNDERFLOW = 0x0E, AUDIO20_FU_CTRL_OVERVLOW = 0x0F, AUDIO20_FU_CTRL_LATENCY = 0x10, } audio20_feature_unit_control_selector_t; /// A.17.8 Effect Unit Control Selectors /// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors typedef enum { AUDIO20_PE_CTRL_UNDEF = 0x00, AUDIO20_PE_CTRL_ENABLE = 0x01, AUDIO20_PE_CTRL_CENTERFREQ = 0x02, AUDIO20_PE_CTRL_QFACTOR = 0x03, AUDIO20_PE_CTRL_GAIN = 0x04, AUDIO20_PE_CTRL_UNDERFLOW = 0x05, AUDIO20_PE_CTRL_OVERFLOW = 0x06, AUDIO20_PE_CTRL_LATENCY = 0x07, } audio20_parametric_equalizer_control_selector_t; /// A.17.8.2 Reverberation Effect Unit Control Selectors typedef enum { AUDIO20_RV_CTRL_UNDEF = 0x00, AUDIO20_RV_CTRL_ENABLE = 0x01, AUDIO20_RV_CTRL_TYPE = 0x02, AUDIO20_RV_CTRL_LEVEL = 0x03, AUDIO20_RV_CTRL_TIME = 0x04, AUDIO20_RV_CTRL_FEEDBACK = 0x05, AUDIO20_RV_CTRL_PREDELAY = 0x06, AUDIO20_RV_CTRL_DENSITY = 0x07, AUDIO20_RV_CTRL_HIFREQ_ROLLOFF = 0x08, AUDIO20_RV_CTRL_UNDERFLOW = 0x09, AUDIO20_RV_CTRL_OVERFLOW = 0x0A, AUDIO20_RV_CTRL_LATENCY = 0x0B, } audio20_reverberation_effect_control_selector_t; /// A.17.8.3 Modulation Delay Effect Unit Control Selectors typedef enum { AUDIO20_MD_CTRL_UNDEF = 0x00, AUDIO20_MD_CTRL_ENABLE = 0x01, AUDIO20_MD_CTRL_BALANCE = 0x02, AUDIO20_MD_CTRL_RATE = 0x03, AUDIO20_MD_CTRL_DEPTH = 0x04, AUDIO20_MD_CTRL_TIME = 0x05, AUDIO20_MD_CTRL_FEEDBACK = 0x06, AUDIO20_MD_CTRL_UNDERFLOW = 0x07, AUDIO20_MD_CTRL_OVERFLOW = 0x08, AUDIO20_MD_CTRL_LATENCY = 0x09, } audio20_modulation_delay_control_selector_t; /// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors typedef enum { AUDIO20_DR_CTRL_UNDEF = 0x00, AUDIO20_DR_CTRL_ENABLE = 0x01, AUDIO20_DR_CTRL_COMPRESSION_RATE = 0x02, AUDIO20_DR_CTRL_MAXAMPL = 0x03, AUDIO20_DR_CTRL_THRESHOLD = 0x04, AUDIO20_DR_CTRL_ATTACK_TIME = 0x05, AUDIO20_DR_CTRL_RELEASE_TIME = 0x06, AUDIO20_DR_CTRL_UNDERFLOW = 0x07, AUDIO20_DR_CTRL_OVERFLOW = 0x08, AUDIO20_DR_CTRL_LATENCY = 0x09, } audio20_dynamic_range_compression_control_selector_t; /// A.17.9 Processing Unit Control Selectors /// A.17.9.1 Up/Down-mix Processing Unit Control Selectors typedef enum { AUDIO20_UD_CTRL_UNDEF = 0x00, AUDIO20_UD_CTRL_ENABLE = 0x01, AUDIO20_UD_CTRL_MODE_SELECT = 0x02, AUDIO20_UD_CTRL_CLUSTER = 0x03, AUDIO20_UD_CTRL_UNDERFLOW = 0x04, AUDIO20_UD_CTRL_OVERFLOW = 0x05, AUDIO20_UD_CTRL_LATENCY = 0x06, } audio20_up_down_mix_control_selector_t; /// A.17.9.2 Dolby Prologic ™ Processing Unit Control Selectors typedef enum { AUDIO20_DP_CTRL_UNDEF = 0x00, AUDIO20_DP_CTRL_ENABLE = 0x01, AUDIO20_DP_CTRL_MODE_SELECT = 0x02, AUDIO20_DP_CTRL_CLUSTER = 0x03, AUDIO20_DP_CTRL_UNDERFLOW = 0x04, AUDIO20_DP_CTRL_OVERFLOW = 0x05, AUDIO20_DP_CTRL_LATENCY = 0x06, } audio20_dolby_prologic_control_selector_t; /// A.17.9.3 Stereo Extender Processing Unit Control Selectors typedef enum { AUDIO20_ST_EXT_CTRL_UNDEF = 0x00, AUDIO20_ST_EXT_CTRL_ENABLE = 0x01, AUDIO20_ST_EXT_CTRL_WIDTH = 0x02, AUDIO20_ST_EXT_CTRL_UNDERFLOW = 0x03, AUDIO20_ST_EXT_CTRL_OVERFLOW = 0x04, AUDIO20_ST_EXT_CTRL_LATENCY = 0x05, } audio20_stereo_extender_control_selector_t; /// A.17.10 Extension Unit Control Selectors typedef enum { AUDIO20_XU_CTRL_UNDEF = 0x00, AUDIO20_XU_CTRL_ENABLE = 0x01, AUDIO20_XU_CTRL_CLUSTER = 0x02, AUDIO20_XU_CTRL_UNDERFLOW = 0x03, AUDIO20_XU_CTRL_OVERFLOW = 0x04, AUDIO20_XU_CTRL_LATENCY = 0x05, } audio20_extension_unit_control_selector_t; /// A.17.11 AudioStreaming Interface Control Selectors typedef enum { AUDIO20_AS_CTRL_UNDEF = 0x00, AUDIO20_AS_CTRL_ACT_ALT_SETTING = 0x01, AUDIO20_AS_CTRL_VAL_ALT_SETTINGS = 0x02, AUDIO20_AS_CTRL_AUDIO_DATA_FORMAT = 0x03, } audio20_audiostreaming_interface_control_selector_t; /// A.17.12 Encoder Control Selectors typedef enum { AUDIO20_EN_CTRL_UNDEF = 0x00, AUDIO20_EN_CTRL_BIT_RATE = 0x01, AUDIO20_EN_CTRL_QUALITY = 0x02, AUDIO20_EN_CTRL_VBR = 0x03, AUDIO20_EN_CTRL_TYPE = 0x04, AUDIO20_EN_CTRL_UNDERFLOW = 0x05, AUDIO20_EN_CTRL_OVERFLOW = 0x06, AUDIO20_EN_CTRL_ENCODER_ERROR = 0x07, AUDIO20_EN_CTRL_PARAM1 = 0x08, AUDIO20_EN_CTRL_PARAM2 = 0x09, AUDIO20_EN_CTRL_PARAM3 = 0x0A, AUDIO20_EN_CTRL_PARAM4 = 0x0B, AUDIO20_EN_CTRL_PARAM5 = 0x0C, AUDIO20_EN_CTRL_PARAM6 = 0x0D, AUDIO20_EN_CTRL_PARAM7 = 0x0E, AUDIO20_EN_CTRL_PARAM8 = 0x0F, } audio20_encoder_control_selector_t; /// A.17.13 Decoder Control Selectors /// A.17.13.1 MPEG Decoder Control Selectors typedef enum { AUDIO20_MPD_CTRL_UNDEF = 0x00, AUDIO20_MPD_CTRL_DUAL_CHANNEL = 0x01, AUDIO20_MPD_CTRL_SECOND_STEREO = 0x02, AUDIO20_MPD_CTRL_MULTILINGUAL = 0x03, AUDIO20_MPD_CTRL_DYN_RANGE = 0x04, AUDIO20_MPD_CTRL_SCALING = 0x05, AUDIO20_MPD_CTRL_HILO_SCALING = 0x06, AUDIO20_MPD_CTRL_UNDERFLOW = 0x07, AUDIO20_MPD_CTRL_OVERFLOW = 0x08, AUDIO20_MPD_CTRL_DECODER_ERROR = 0x09, } audio20_MPEG_decoder_control_selector_t; /// A.17.13.2 AC-3 Decoder Control Selectors typedef enum { AUDIO20_AD_CTRL_UNDEF = 0x00, AUDIO20_AD_CTRL_MODE = 0x01, AUDIO20_AD_CTRL_DYN_RANGE = 0x02, AUDIO20_AD_CTRL_SCALING = 0x03, AUDIO20_AD_CTRL_HILO_SCALING = 0x04, AUDIO20_AD_CTRL_UNDERFLOW = 0x05, AUDIO20_AD_CTRL_OVERFLOW = 0x06, AUDIO20_AD_CTRL_DECODER_ERROR = 0x07, } audio20_AC3_decoder_control_selector_t; /// A.17.13.3 WMA Decoder Control Selectors typedef enum { AUDIO20_WD_CTRL_UNDEF = 0x00, AUDIO20_WD_CTRL_UNDERFLOW = 0x01, AUDIO20_WD_CTRL_OVERFLOW = 0x02, AUDIO20_WD_CTRL_DECODER_ERROR = 0x03, } audio20_WMA_decoder_control_selector_t; /// A.17.13.4 DTS Decoder Control Selectors typedef enum { AUDIO20_DD_CTRL_UNDEF = 0x00, AUDIO20_DD_CTRL_UNDERFLOW = 0x01, AUDIO20_DD_CTRL_OVERFLOW = 0x02, AUDIO20_DD_CTRL_DECODER_ERROR = 0x03, } audio20_DTS_decoder_control_selector_t; /// A.17.14 Endpoint Control Selectors typedef enum { AUDIO20_EP_CTRL_UNDEF = 0x00, AUDIO20_EP_CTRL_PITCH = 0x01, AUDIO20_EP_CTRL_DATA_OVERRUN = 0x02, AUDIO20_EP_CTRL_DATA_UNDERRUN = 0x03, } audio20_EP_control_selector_t; /// Additional Audio Device Class Codes - Source: Audio Data Formats /// A.1 - Audio Class-Format Type Codes UAC2 typedef enum { AUDIO20_FORMAT_TYPE_UNDEFINED = 0x00, AUDIO20_FORMAT_TYPE_I = 0x01, AUDIO20_FORMAT_TYPE_II = 0x02, AUDIO20_FORMAT_TYPE_III = 0x03, AUDIO20_FORMAT_TYPE_IV = 0x04, AUDIO20_EXT_FORMAT_TYPE_I = 0x81, AUDIO20_EXT_FORMAT_TYPE_II = 0x82, AUDIO20_EXT_FORMAT_TYPE_III = 0x83, } audio20_format_type_t; // A.2.1 - Audio Class-Audio Data Format Type I UAC2 typedef enum { AUDIO20_DATA_FORMAT_TYPE_I_PCM = 1 << 0, AUDIO20_DATA_FORMAT_TYPE_I_PCM8 = 1 << 1, AUDIO20_DATA_FORMAT_TYPE_I_IEEE_FLOAT = 1 << 2, AUDIO20_DATA_FORMAT_TYPE_I_ALAW = 1 << 3, AUDIO20_DATA_FORMAT_TYPE_I_MULAW = 1 << 4, AUDIO20_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio20_data_format_type_I_t; /// Audio Class-Audio Channel Configuration UAC2 (Table A-11) typedef enum { AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000, AUDIO20_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001, AUDIO20_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002, AUDIO20_CHANNEL_CONFIG_FRONT_CENTER = 0x00000004, AUDIO20_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x00000008, AUDIO20_CHANNEL_CONFIG_BACK_LEFT = 0x00000010, AUDIO20_CHANNEL_CONFIG_BACK_RIGHT = 0x00000020, AUDIO20_CHANNEL_CONFIG_FRONT_LEFT_OF_CENTER = 0x00000040, AUDIO20_CHANNEL_CONFIG_FRONT_RIGHT_OF_CENTER = 0x00000080, AUDIO20_CHANNEL_CONFIG_BACK_CENTER = 0x00000100, AUDIO20_CHANNEL_CONFIG_SIDE_LEFT = 0x00000200, AUDIO20_CHANNEL_CONFIG_SIDE_RIGHT = 0x00000400, AUDIO20_CHANNEL_CONFIG_TOP_CENTER = 0x00000800, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_LEFT = 0x00001000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_CENTER = 0x00002000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_RIGHT = 0x00004000, AUDIO20_CHANNEL_CONFIG_TOP_BACK_LEFT = 0x00008000, AUDIO20_CHANNEL_CONFIG_TOP_BACK_CENTER = 0x00010000, AUDIO20_CHANNEL_CONFIG_TOP_BACK_RIGHT = 0x00020000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_LEFT_OF_CENTER = 0x00040000, AUDIO20_CHANNEL_CONFIG_TOP_FRONT_RIGHT_OF_CENTER = 0x00080000, AUDIO20_CHANNEL_CONFIG_LEFT_LOW_FRQ_EFFECTS = 0x00100000, AUDIO20_CHANNEL_CONFIG_RIGHT_LOW_FRQ_EFFECTS = 0x00200000, AUDIO20_CHANNEL_CONFIG_TOP_SIDE_LEFT = 0x00400000, AUDIO20_CHANNEL_CONFIG_TOP_SIDE_RIGHT = 0x00800000, AUDIO20_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO20_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO20_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, AUDIO20_CHANNEL_CONFIG_RAW_DATA = 0x80000000u, } audio20_channel_config_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification /// Audio Class-Control Values UAC2 typedef enum { AUDIO20_CTRL_NONE = 0x00,///< No Host access AUDIO20_CTRL_R = 0x01, ///< Host read access only AUDIO20_CTRL_RW = 0x03, ///< Host read write access } audio20_control_t; /// Audio Class-Specific AC Interface Descriptor Controls UAC2 typedef enum { AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0, } audio20_cs_ac_interface_control_pos_t; /// Audio Class-Specific AS Interface Descriptor Controls UAC2 typedef enum { AUDIO20_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0, AUDIO20_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2, } audio20_cs_as_interface_control_pos_t; /// Audio Class-Specific AS Isochronous Data EP Attributes UAC2 typedef enum { AUDIO20_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00, } audio20_cs_as_iso_data_ep_attribute_t; /// Audio Class-Specific AS Isochronous Data EP Controls UAC2 typedef enum { AUDIO20_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0, AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_OVERRUN_POS = 2, AUDIO20_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4, } audio20_cs_as_iso_data_ep_control_pos_t; /// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2 typedef enum { AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01, AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, } audio20_cs_as_iso_data_ep_lock_delay_unit_t; /// Audio Class-Clock Source Attributes UAC2 typedef enum { AUDIO20_CLOCK_SOURCE_ATT_EXT_CLK = 0x00, AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01, AUDIO20_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02, AUDIO20_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03, AUDIO20_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04, } audio20_clock_source_attribute_t; /// Audio Class-Clock Source Controls UAC2 typedef enum { AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0, AUDIO20_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2, } audio20_clock_source_control_pos_t; /// Audio Class-Clock Selector Controls UAC2 typedef enum { AUDIO20_CLOCK_SELECTOR_CTRL_POS = 0, } audio20_clock_selector_control_pos_t; /// Audio Class-Clock Multiplier Controls UAC2 typedef enum { AUDIO20_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0, AUDIO20_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2, } audio20_clock_multiplier_control_pos_t; /// Audio Class-Input Terminal Controls UAC2 typedef enum { AUDIO20_IN_TERM_CTRL_CPY_PROT_POS = 0, AUDIO20_IN_TERM_CTRL_CONNECTOR_POS = 2, AUDIO20_IN_TERM_CTRL_OVERLOAD_POS = 4, AUDIO20_IN_TERM_CTRL_CLUSTER_POS = 6, AUDIO20_IN_TERM_CTRL_UNDERFLOW_POS = 8, AUDIO20_IN_TERM_CTRL_OVERFLOW_POS = 10, } audio20_terminal_input_control_pos_t; /// Audio Class-Output Terminal Controls UAC2 typedef enum { AUDIO20_OUT_TERM_CTRL_CPY_PROT_POS = 0, AUDIO20_OUT_TERM_CTRL_CONNECTOR_POS = 2, AUDIO20_OUT_TERM_CTRL_OVERLOAD_POS = 4, AUDIO20_OUT_TERM_CTRL_UNDERFLOW_POS = 6, AUDIO20_OUT_TERM_CTRL_OVERFLOW_POS = 8, } audio20_terminal_output_control_pos_t; /// Audio Class-Feature Unit Controls UAC2 typedef enum { AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS = 0, AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS = 2, AUDIO20_FEATURE_UNIT_CTRL_BASS_POS = 4, AUDIO20_FEATURE_UNIT_CTRL_MID_POS = 6, AUDIO20_FEATURE_UNIT_CTRL_TREBLE_POS = 8, AUDIO20_FEATURE_UNIT_CTRL_GRAPHIC_EQU_POS = 10, AUDIO20_FEATURE_UNIT_CTRL_AGC_POS = 12, AUDIO20_FEATURE_UNIT_CTRL_DELAY_POS = 14, AUDIO20_FEATURE_UNIT_CTRL_BASS_BOOST_POS = 16, AUDIO20_FEATURE_UNIT_CTRL_LOUDNESS_POS = 18, AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_POS = 20, AUDIO20_FEATURE_UNIT_CTRL_INPUT_GAIN_PAD_POS = 22, AUDIO20_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24, AUDIO20_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26, AUDIO20_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28, } audio20_feature_unit_control_pos_t; //--------------------------------------------------------------------+ // USB AUDIO CLASS 2.0 (UAC2) DESCRIPTORS //--------------------------------------------------------------------+ /// AUDIO Channel Cluster Descriptor UAC2 (4.1) typedef struct TU_ATTR_PACKED { uint8_t bNrChannels; ///< Number of channels currently connected. uint32_t bmChannelConfig;///< Bitmap according to 'audio20_channel_config_t' with a 1 set if channel is connected and 0 else. In case channels are non-predefined ignore them here (see UAC2 specification 4.1 Audio Channel Cluster Descriptor. uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first inserted channel with a non-predefined spatial location. } audio20_desc_channel_cluster_t; /// AUDIO Class-Specific AC Interface Header Descriptor UAC2 (4.7.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 9. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_HEADER. uint16_t bcdADC; ///< Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: U16_TO_U8S_LE(0x0200). uint8_t bCategory; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio20_function_code_t. uint16_t wTotalLength; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors. uint8_t bmControls; ///< See: audio20_cs_ac_interface_control_pos_t. } audio20_desc_cs_ac_interface_t; TU_VERIFY_STATIC(sizeof(audio20_desc_cs_ac_interface_t) == 9, "size is not correct"); /// AUDIO Clock Source Descriptor UAC2 (4.7.2.1) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes: 8. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE. uint8_t bClockID; ///< Constant uniquely identifying the Clock Source Entity within the audio function. This value is used in all requests to address this Entity. uint8_t bmAttributes; ///< See: audio20_clock_source_attribute_t. uint8_t bmControls; ///< See: audio20_clock_source_control_pos_t. uint8_t bAssocTerminal; ///< Terminal ID of the Terminal that is associated with this Clock Source. uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Source Entity. } audio20_desc_clock_source_t; /// AUDIO Clock Selector Descriptor UAC2 (4.7.2.2) for ONE pin typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 7+p. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_SELECTOR. uint8_t bClockID; ///< Constant uniquely identifying the Clock Selector Entity within the audio function. This value is used in all requests to address this Entity. uint8_t bNrInPins; ///< Number of Input Pins of this Unit: p = 1 thus bNrInPins = 1. uint8_t baCSourceID; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected.. uint8_t bmControls; ///< See: audio20_clock_selector_control_pos_t. uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Selector Entity. } audio20_desc_clock_selector_t; /// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins #define audio20_desc_clock_selector_n_t(source_num) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bClockID; \ uint8_t bNrInPins; \ struct TU_ATTR_PACKED { \ uint8_t baSourceID; \ } sourceID[source_num]; \ uint8_t bmControls; \ uint8_t iClockSource; \ } /// AUDIO Clock Multiplier Descriptor UAC2 (4.7.2.3) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 7. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_CLOCK_MULTIPLIER. uint8_t bClockID; ///< Constant uniquely identifying the Clock Multiplier Entity within the audio function. This value is used in all requests to address this Entity. uint8_t bCSourceID; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected. uint8_t bmControls; ///< See: audio20_clock_multiplier_control_pos_t. uint8_t iClockSource; ///< Index of a string descriptor, describing the Clock Multiplier Entity. } audio20_desc_clock_multiplier_t; /// AUDIO Input Terminal Descriptor(4.7.2.4) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 17. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this terminal. uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types. uint8_t bAssocTerminal; ///< ID of the Output Terminal to which this Input Terminal is associated. uint8_t bCSourceID; ///< ID of the Clock Entity to which this Input Terminal is connected. uint8_t bNrChannels; ///< Number of logical output channels in the Terminal’s output audio channel cluster. uint32_t bmChannelConfig; ///< Describes the spatial location of the logical channels. See:audio20_channel_config_t. uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first logical channel. uint16_t bmControls; ///< See: audio_terminal_input_control_pos_t. uint8_t iTerminal; ///< Index of a string descriptor, describing the Input Terminal. } audio20_desc_input_terminal_t; /// AUDIO Output Terminal Descriptor UAC2 (4.7.2.5) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 12. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL. uint8_t bTerminalID; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this Terminal. uint16_t wTerminalType; ///< Constant characterizing the type of Terminal. See: audio20_terminal_type_t for USB streaming and audio20_terminal_output_type_t for other output types. uint8_t bAssocTerminal; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated. uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Terminal is connected. uint8_t bCSourceID; ///< ID of the Clock Entity to which this Output Terminal is connected. uint16_t bmControls; ///< See: audio20_terminal_output_control_pos_t. uint8_t iTerminal; ///< Index of a string descriptor, describing the Output Terminal. } audio20_desc_output_terminal_t; /// AUDIO Feature Unit Descriptor UAC2 (4.7.2.8) for ONE channel typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 14. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT. uint8_t bUnitID; ///< Constant uniquely identifying the Unit within the audio function. This value is used in all requests to address this Unit. uint8_t bSourceID; ///< ID of the Unit or Terminal to which this Feature Unit is connected. struct TU_ATTR_PACKED { uint32_t bmaControls;///< See: audio20_feature_unit_control_pos_t. Controls0 is master channel 0 (always present) and Controls1 is logical channel 1. } controls[2]; uint8_t iTerminal;///< Index of a string descriptor, describing this Feature Unit. } audio20_desc_feature_unit_t; /// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels #define audio20_desc_feature_unit_n_t(ch_num) \ struct TU_ATTR_PACKED { \ uint8_t bLength; /* 6+(ch_num+1)*4 */ \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bUnitID; \ uint8_t bSourceID; \ struct TU_ATTR_PACKED { \ uint32_t bmaControls; \ } controls[ch_num + 1]; \ uint8_t iTerminal; \ } /// AUDIO Class-Specific AS Interface Descriptor(4.9.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 16. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_AS_GENERAL. uint8_t bTerminalLink; ///< The Terminal ID of the Terminal to which this interface is connected. uint8_t bmControls; ///< See: audio20_cs_as_interface_control_pos_t. uint8_t bFormatType; ///< Constant identifying the Format Type the AudioStreaming interface is using. See: audio20_format_type_t. uint32_t bmFormats; ///< The Audio Data Format(s) that can be used to communicate with this interface.See: audio20_data_format_type_I_t. uint8_t bNrChannels; ///< Number of physical channels in the AS Interface audio channel cluster. uint32_t bmChannelConfig; ///< Describes the spatial location of the physical channels. See: audio20_channel_config_t. uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first physical channel. } audio20_desc_cs_as_interface_t; /// AUDIO Type I Format Type Descriptor(2.3.1.6 - Audio Formats) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 6. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE. uint8_t bFormatType; ///< Constant identifying the Format Type the AudioStreaming interface is using. Value: AUDIO20_FORMAT_TYPE_I. uint8_t bSubslotSize; ///< The number of bytes occupied by one audio subslot. Can be 1, 2, 3 or 4. uint8_t bBitResolution; ///< The number of effectively used bits from the available bits in an audio subslot. } audio20_desc_type_I_format_t; /// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor, in bytes: 8. uint8_t bDescriptorType; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT. uint8_t bDescriptorSubType;///< Descriptor SubType. Value: AUDIO20_CS_EP_SUBTYPE_GENERAL. uint8_t bmAttributes; ///< See: audio20_cs_as_iso_data_ep_attribute_t. uint8_t bmControls; ///< See: audio20_cs_as_iso_data_ep_control_pos_t. uint8_t bLockDelayUnits; ///< Indicates the units used for the wLockDelay field. See: audio20_cs_as_iso_data_ep_lock_delay_unit_t. uint16_t wLockDelay; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field. } audio20_desc_cs_as_iso_data_ep_t; // 5.2.2 Control Request Layout typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5;///< Recipient type tusb_request_recipient_t. uint8_t type : 2; ///< Request type tusb_request_type_t. uint8_t direction : 1;///< Direction type. tusb_dir_t } bmRequestType_bit; uint8_t bmRequestType; }; uint8_t bRequest;///< Request type audio_cs_req_t uint8_t bChannelNumber; uint8_t bControlSelector; union { uint8_t bInterface; uint8_t bEndpoint; }; uint8_t bEntityID; uint16_t wLength; } audio20_control_request_t; //// 5.2.3 Control Request Parameter Block Layout // 5.2.3.1 1-byte Control CUR Parameter Block typedef struct TU_ATTR_PACKED { int8_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_1_t; // 5.2.3.2 2-byte Control CUR Parameter Block typedef struct TU_ATTR_PACKED { int16_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_2_t; // 5.2.3.3 4-byte Control CUR Parameter Block typedef struct TU_ATTR_PACKED { int32_t bCur;///< The setting for the CUR attribute of the addressed Control } audio20_control_cur_4_t; // Use the following ONLY for RECEIVED data - compiler does not know how many subranges are defined! Use the #define macros below for predefined lengths. // 5.2.3.1 1-byte Control RANGE Parameter Block #define audio20_control_range_1_n_t(numSubRanges) \ struct TU_ATTR_PACKED { \ uint16_t wNumSubRanges; \ struct TU_ATTR_PACKED { \ int8_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ int8_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ uint8_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ } subrange[numSubRanges]; \ } /// 5.2.3.2 2-byte Control RANGE Parameter Block #define audio20_control_range_2_n_t(numSubRanges) \ struct TU_ATTR_PACKED { \ uint16_t wNumSubRanges; \ struct TU_ATTR_PACKED { \ int16_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ int16_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ uint16_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ } subrange[numSubRanges]; \ } // 5.2.3.3 4-byte Control RANGE Parameter Block #define audio20_control_range_4_n_t(numSubRanges) \ struct TU_ATTR_PACKED { \ uint16_t wNumSubRanges; \ struct TU_ATTR_PACKED { \ int32_t bMin; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/ \ int32_t bMax; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/ \ uint32_t bRes; /*The setting for the RES attribute of the nth subrange of the addressed Control*/ \ } subrange[numSubRanges]; \ } // 6.1 Interrupt Data Message Format typedef struct TU_ATTR_PACKED { uint8_t bInfo; uint8_t bAttribute; union { uint16_t wValue; struct { uint8_t wValue_cn_or_mcn; uint8_t wValue_cs; }; }; union { uint16_t wIndex; struct { uint8_t wIndex_ep_or_int; uint8_t wIndex_entity_id; }; }; } audio20_interrupt_data_t; //--------------------------------------------------------------------+ // APPLICATION HELPER DEFINITIONS //--------------------------------------------------------------------+ // Combined Interrupt Data Message Format for both UAC1 and UAC2 typedef union { audio10_interrupt_data_t v1; audio20_interrupt_data_t v2; } audio_interrupt_data_t; // MIDI1.0 use the same CS AC Interface Descriptor as UAC1 typedef audio10_desc_cs_ac_interface_n_t(1) midi10_desc_cs_ac_interface_t; // UAC1.0 AC Interface Descriptor with 1 interface, used to read fields other than baInterfaceNr typedef audio10_desc_cs_ac_interface_n_t(1) audio10_desc_cs_ac_interface_1_t; /** @} */ #ifdef __cplusplus } #endif #endif /** @} */ ================================================ FILE: src/class/audio/audio_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Reinhard Panhuber, Jerzy Kasenberg * Copyright (c) 2023 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /* * This driver supports at most one out EP, one in EP, one control EP, and one feedback EP and one alternative interface other than zero. Hence, only one input terminal and one output terminal are support, if you need more adjust the driver! * It supports multiple TX and RX channels. * * In case you need more alternate interfaces, you need to define additional defines for this specific alternate interface. Just define them and set them in the set_interface function. * * There are three data flow structures currently implemented, where at least one SW-FIFO is used to decouple the asynchronous processes MCU vs. host * * 1. Input data -> SW-FIFO -> MCU USB * * The most easiest version, available in case the target MCU can handle the software FIFO (SW-FIFO) and if it is implemented in the device driver (if yes then dcd_edpt_xfer_fifo() is available) * * 2. Input data -> SW-FIFO -> Linear buffer -> MCU USB * * In case the target MCU can not handle a SW-FIFO, a linear buffer is used. This uses the default function dcd_edpt_xfer(). In this case more memory is required. * * 3. (Input data 1 | Input data 2 | ... | Input data N) -> (SW-FIFO 1 | SW-FIFO 2 | ... | SW-FIFO N) -> Linear buffer -> MCU USB * * This case is used if you have more channels which need to be combined into one stream. Every channel has its own SW-FIFO. All data is encoded into an Linear buffer. * * The same holds in the RX case. * * */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_AUDIO) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "device/usbd.h" #include "device/usbd_pvt.h" #include "audio_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // Declaration of buffers // Check for maximum supported numbers #if CFG_TUD_AUDIO > 3 #error Maximum number of audio functions restricted to three! #endif // Put swap buffer in USB section only if necessary #if !CFG_TUD_EDPT_DEDICATED_HWFIFO #define IN_SW_BUF_MEM_ATTR TU_ATTR_ALIGNED(4) #else #define IN_SW_BUF_MEM_ATTR CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN #endif #if !CFG_TUD_EDPT_DEDICATED_HWFIFO #define OUT_SW_BUF_MEM_ATTR TU_ATTR_ALIGNED(4) #else #define OUT_SW_BUF_MEM_ATTR CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN #endif // EP IN software buffers #if CFG_TUD_AUDIO_ENABLE_EP_IN tu_static IN_SW_BUF_MEM_ATTR struct { #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ); #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ); #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ); #endif } ep_in_sw_buf; #endif// CFG_TUD_AUDIO_ENABLE_EP_IN // Linear buffer TX in case: // - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO tu_static CFG_TUD_MEM_SECTION struct { #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX); #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 TUD_EPBUF_DEF(buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX); #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX); #endif } lin_buf_in; #endif// CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO // EP OUT software buffers #if CFG_TUD_AUDIO_ENABLE_EP_OUT tu_static OUT_SW_BUF_MEM_ATTR struct { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ); #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ); #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ); #endif } ep_out_sw_buf; #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT // Linear buffer RX in case: // - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR #if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO tu_static CFG_TUD_MEM_SECTION struct { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX); #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 TUD_EPBUF_DEF(buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX); #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX); #endif } lin_buf_out; #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO // Control buffer #if CFG_TUD_AUDIO_CTRL_BUF_SZ > CFG_TUD_ENDPOINT0_BUFSIZE tu_static CFG_TUD_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_AUDIO_CTRL_BUF_SZ]; #endif // Aligned buffer for feedback EP #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP tu_static CFG_TUD_MEM_SECTION struct { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 TUD_EPBUF_TYPE_DEF(uint32_t, buf_1); #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 TUD_EPBUF_TYPE_DEF(uint32_t, buf_2); #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 TUD_EPBUF_TYPE_DEF(uint32_t, buf_3); #endif } fb_ep_buf; #endif // Aligned buffer for interrupt EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP tu_static CFG_TUD_MEM_SECTION struct { TUD_EPBUF_DEF(buf, CFG_TUD_AUDIO_INTERRUPT_EP_SZ); } int_ep_buf[CFG_TUD_AUDIO]; #endif typedef struct { uint8_t rhport; uint8_t const *p_desc;// Pointer pointing to Standard AC Interface Descriptor(4.7.1) - Audio Control descriptor defining audio function uint8_t const *p_desc_as;// Pointer pointing to 1st Standard AS Interface Descriptor(4.9.1) - Audio Streaming descriptor defining audio function uint16_t desc_length;// Length of audio function descriptor #if CFG_TUD_AUDIO_ENABLE_EP_IN uint8_t ep_in; // TX audio data EP. uint16_t ep_in_sz; // Current size of TX EP uint8_t ep_in_as_intf_num;// Corresponding Standard AS Interface Descriptor (4.9.1) belonging to output terminal to which this EP belongs - 0 is invalid (this fits to UAC2 specification since AS interfaces can not have interface number equal to zero) uint8_t ep_in_alt; // Current alternate setting of TX EP uint16_t ep_in_fifo_threshold;// Target size for the EP IN FIFO. #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT uint8_t ep_out; // Incoming (into uC) audio data EP. uint16_t ep_out_sz; // Current size of RX EP uint8_t ep_out_as_intf_num;// Corresponding Standard AS Interface Descriptor (4.9.1) belonging to input terminal to which this EP belongs - 0 is invalid (this fits to UAC2 specification since AS interfaces can not have interface number equal to zero) uint8_t ep_out_alt; // Current alternate setting of RX EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint8_t ep_fb;// Feedback EP. #endif #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP uint8_t ep_int;// Audio control interrupt EP. #endif bool mounted;// Device opened #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP struct { uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). uint32_t min_value;// min value according to UAC2 FMT-2.0 section 2.3.1.1. uint32_t max_value;// max value according to UAC2 FMT-2.0 section 2.3.1.1. uint8_t frame_shift;// bInterval-1 in unit of frame (FS), micro-frame (HS) uint8_t compute_method; union { uint8_t power_of_2;// pre-computed power of 2 shift float float_const; // pre-computed float constant struct { uint32_t sample_freq; uint32_t mclk_freq; } fixed; struct { uint32_t nom_value; // In 16.16 format uint32_t fifo_lvl_avg; // In 16.16 format uint16_t fifo_lvl_thr; // fifo level threshold uint16_t rate_const[2];// pre-computed feedback/fifo_depth rate } fifo_count; } compute; } feedback; #endif// CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL uint32_t sample_rate_tx; uint16_t packet_sz_tx[3]; uint8_t bclock_id_tx; uint8_t interval_tx; uint8_t format_type_tx; uint8_t n_channels_tx; uint8_t n_bytes_per_sample_tx; #endif /*------------- From this point, data is not cleared by bus reset -------------*/ // EP Transfer buffers and FIFOs #if CFG_TUD_AUDIO_ENABLE_EP_OUT tu_fifo_t ep_out_ff; #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN tu_fifo_t ep_in_ff; #endif // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically #if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *lin_buf_out; #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *lin_buf_in; #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint32_t *fb_buf; #endif } audiod_function_t; #if CFG_TUD_AUDIO_ENABLE_EP_OUT #define ITF_MEM_RESET_SIZE offsetof(audiod_function_t, ep_out_ff) #else #define ITF_MEM_RESET_SIZE offsetof(audiod_function_t, ep_in_ff) #endif //--------------------------------------------------------------------+ // WEAK FUNCTION STUBS //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_IN TU_ATTR_WEAK bool tud_audio_tx_done_isr(uint8_t rhport, uint16_t n_bytes_sent, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting) { (void) rhport; (void) n_bytes_sent; (void) func_id; (void) ep_in; (void) cur_alt_setting; return true; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT TU_ATTR_WEAK bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) { (void) rhport; (void) n_bytes_received; (void) func_id; (void) ep_out; (void) cur_alt_setting; return true; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t *feedback_param) { (void) func_id; (void) alt_itf; feedback_param->method = AUDIO_FEEDBACK_METHOD_DISABLED; } TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift) { (void) func_id; (void) frame_number; (void) interval_shift; } #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport) { (void) rhport; } #endif // Invoked when audio set interface request received TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; return true; } // Invoked when audio set interface request received which closes an EP TU_ATTR_WEAK bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; return true; } // Invoked when audio class specific set request received for an EP TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) p_request; (void) pBuff; TU_LOG2(" No EP set request callback available!\r\n"); return false;// In case no callback function is present or request can not be conducted we stall it } // Invoked when audio class specific set request received for an interface TU_ATTR_WEAK bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) p_request; (void) pBuff; TU_LOG2(" No interface set request callback available!\r\n"); return false;// In case no callback function is present or request can not be conducted we stall it } // Invoked when audio class specific set request received for an entity TU_ATTR_WEAK bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { (void) rhport; (void) p_request; (void) pBuff; TU_LOG2(" No entity set request callback available!\r\n"); return false;// In case no callback function is present or request can not be conducted we stall it } // Invoked when audio class specific get request received for an EP TU_ATTR_WEAK bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; TU_LOG2(" No EP get request callback available!\r\n"); return false;// Stall } // Invoked when audio class specific get request received for an interface TU_ATTR_WEAK bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; TU_LOG2(" No interface get request callback available!\r\n"); return false;// Stall } // Invoked when audio class specific get request received for an entity TU_ATTR_WEAK bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; (void) p_request; TU_LOG2(" No entity get request callback available!\r\n"); return false;// Stall } //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ tu_static CFG_TUD_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO]; #if CFG_TUD_AUDIO_ENABLE_EP_OUT static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN static bool audiod_tx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_sent); #endif static bool audiod_get_interface(uint8_t rhport, tusb_control_request_t const *p_request); static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p_request); static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t *func_id); static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id); static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id); static inline uint8_t audiod_get_audio_fct_idx(audiod_function_t *audio); #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL static void audiod_parse_flow_control_params(audiod_function_t *audio, uint8_t const *p_desc); static bool audiod_calc_tx_packet_sz(audiod_function_t *audio); static uint16_t audiod_tx_packet_size(const uint16_t *nominal_size, uint16_t data_count, uint16_t fifo_depth, uint16_t fifo_threshold, uint16_t max_size); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static bool audiod_fb_params_prepare(uint8_t func_id, uint8_t alt); static void audiod_fb_fifo_count_update(audiod_function_t *audio, uint16_t lvl_new); #endif bool tud_audio_n_mounted(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO); audiod_function_t *audio = &_audiod_fct[func_id]; return audio->mounted; } static inline uint8_t* get_ctrl_buffer(void) { // Use EP0 buffer if it is large enough, otherwise use dedicated buffer #if CFG_TUD_AUDIO_CTRL_BUF_SZ > CFG_TUD_ENDPOINT0_BUFSIZE return ctrl_buf; #else return usbd_get_ctrl_buf(); #endif } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_OUT uint16_t tud_audio_n_available(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); return tu_fifo_count(&_audiod_fct[func_id].ep_out_ff); } uint16_t tud_audio_n_read(uint8_t func_id, void *buffer, uint16_t bufsize) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); return tu_fifo_read_n(&_audiod_fct[func_id].ep_out_ff, buffer, bufsize); } bool tud_audio_n_clear_ep_out_ff(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff); return true; } tu_fifo_t *tud_audio_n_get_ep_out_ff(uint8_t func_id) { if (func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) { return &_audiod_fct[func_id].ep_out_ff; } return NULL; } static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) { uint8_t idx_audio_fct = audiod_get_audio_fct_idx(audio); #if !CFG_TUD_EDPT_DEDICATED_HWFIFO // Data currently is in linear buffer, copy into EP OUT FIFO TU_VERIFY(0 < tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); // Schedule for next receive TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, true)); #else // Data is already placed in EP FIFO, schedule for next receive TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, true)); #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP if (audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FIFO_COUNT) { audiod_fb_fifo_count_update(audio, tu_fifo_count(&audio->ep_out_ff)); } #endif // Call a weak callback here - a possibility for user to get informed an audio packet was received and data gets now loaded into EP FIFO TU_VERIFY(tud_audio_rx_done_isr(rhport, n_bytes_received, idx_audio_fct, audio->ep_out, audio->ep_out_alt)); return true; } #endif//CFG_TUD_AUDIO_ENABLE_EP_OUT //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_IN uint16_t tud_audio_n_write(uint8_t func_id, const void *data, uint16_t len) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); return tu_fifo_write_n(&_audiod_fct[func_id].ep_in_ff, data, len); } bool tud_audio_n_clear_ep_in_ff(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff); return true; } tu_fifo_t *tud_audio_n_get_ep_in_ff(uint8_t func_id) { if (func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) { return &_audiod_fct[func_id].ep_in_ff; } return NULL; } uint16_t tud_audio_n_get_ep_in_fifo_threshold(uint8_t func_id) { if (func_id < CFG_TUD_AUDIO) return _audiod_fct[func_id].ep_in_fifo_threshold; return 0; } void tud_audio_n_set_ep_in_fifo_threshold(uint8_t func_id, uint16_t threshold) { if (func_id < CFG_TUD_AUDIO && threshold < _audiod_fct[func_id].ep_in_ff.depth) { _audiod_fct[func_id].ep_in_fifo_threshold = threshold; } } static bool audiod_tx_xfer_isr(uint8_t rhport, audiod_function_t * audio, uint16_t n_bytes_sent) { uint8_t idx_audio_fct = audiod_get_audio_fct_idx(audio); // Only send something if current alternate interface is not 0 as in this case nothing is to be sent due to UAC2 specifications if (audio->ep_in_alt == 0) { return false; } // Send everything in ISO EP FIFO uint16_t n_bytes_tx; #if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL // packet_sz_tx is based on total packet size, here we want size for each support buffer. n_bytes_tx = audiod_tx_packet_size(audio->packet_sz_tx, tu_fifo_count(&audio->ep_in_ff), audio->ep_in_ff.depth, audio->ep_in_fifo_threshold, audio->ep_in_sz); #else n_bytes_tx = tu_min16(tu_fifo_count(&audio->ep_in_ff), audio->ep_in_sz);// Limit up to max packet size, more can not be done for ISO #endif #if !CFG_TUD_EDPT_DEDICATED_HWFIFO tu_fifo_read_n(&audio->ep_in_ff, audio->lin_buf_in, n_bytes_tx); TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx, true)); #else // Send everything in ISO EP FIFO TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, n_bytes_tx, true)); #endif // Call a weak callback here - a possibility for user to get informed former TX was completed and data gets now loaded into EP in buffer TU_VERIFY(tud_audio_tx_done_isr(rhport, n_bytes_sent, idx_audio_fct, audio->ep_in, audio->ep_in_alt)); return true; } #endif //--------------------------------------------------------------------+ // OTHER API //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t *data) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); TU_VERIFY(_audiod_fct[func_id].ep_int != 0); // We write directly into the EP's buffer - abort if previous transfer not complete TU_VERIFY(usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); uint8_t size = tud_audio_n_version(func_id) == 2 ? sizeof(audio20_interrupt_data_t) : sizeof(audio10_interrupt_data_t); // INT EP buffer must be large enough TU_ASSERT(size <= sizeof(int_ep_buf[func_id].buf)); // Check length if (tu_memcpy_s(int_ep_buf[func_id].buf, sizeof(int_ep_buf[func_id].buf), data, size) == 0) { // Schedule transmit TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, int_ep_buf[func_id].buf, size, false)); } else { // Release endpoint since we don't make any transfer usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int); } return true; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // This function is called once a transmit of a feedback packet was successfully completed. Here, we get the next feedback value to be sent static inline bool audiod_fb_send(uint8_t func_id, bool is_isr) { audiod_function_t *audio = &_audiod_fct[func_id]; uint8_t uac_version = tud_audio_n_version(func_id); // Format the feedback value if (uac_version == 1) { uint8_t *fb = (uint8_t *) audio->fb_buf; // For FS format is 10.14 *(fb++) = (audio->feedback.value >> 2) & 0xFF; *(fb++) = (audio->feedback.value >> 10) & 0xFF; *(fb++) = (audio->feedback.value >> 18) & 0xFF; *fb = 0; } else { *audio->fb_buf = audio->feedback.value; } return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) audio->fb_buf, uac_version == 1 ? 3 : 4, is_isr); } uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) { audiod_function_t *audio = &_audiod_fct[func_id]; uint32_t feedback; switch (audio->feedback.compute_method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: feedback = (cycles << audio->feedback.compute.power_of_2); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: feedback = (uint32_t) ((float) cycles * audio->feedback.compute.float_const); break; case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: { uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - (audio->feedback.frame_shift - 1)); feedback = (uint32_t) (fb64 / audio->feedback.compute.fixed.mclk_freq); } break; default: return 0; } // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot // (audio slot = channel count samples). if (feedback > audio->feedback.max_value) { feedback = audio->feedback.max_value; } if (feedback < audio->feedback.min_value) { feedback = audio->feedback.min_value; } tud_audio_n_fb_set(func_id, feedback); return feedback; } bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); _audiod_fct[func_id].feedback.value = feedback; return true; } #endif uint8_t tud_audio_n_version(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); uint8_t bIntfProtocol = ((tusb_desc_interface_t const *)_audiod_fct[func_id].p_desc)->bInterfaceProtocol; if (bIntfProtocol == AUDIO_INT_PROTOCOL_CODE_V1) { return 1; } else if (bIntfProtocol == AUDIO_INT_PROTOCOL_CODE_V2) { return 2; } else { return 0; // Unknown version } } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void audiod_init(void) { tu_memclr(_audiod_fct, sizeof(_audiod_fct)); for (uint8_t i = 0; i < CFG_TUD_AUDIO; i++) { audiod_function_t *audio = &_audiod_fct[i]; // Initialize IN EP FIFO if required #if CFG_TUD_AUDIO_ENABLE_EP_IN switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 case 0: tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, true); break; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 case 1: tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, true); break; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 case 2: tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, true); break; #endif } // Initialize linear buffers #if !CFG_TUD_EDPT_DEDICATED_HWFIFO switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 case 0: audio->lin_buf_in = lin_buf_in.buf_1; break; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 case 1: audio->lin_buf_in = lin_buf_in.buf_2; break; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 case 2: audio->lin_buf_in = lin_buf_in.buf_3; break; #endif } #endif// !CFG_TUD_EDPT_DEDICATED_HWFIFO #endif// CFG_TUD_AUDIO_ENABLE_EP_IN // Initialize OUT EP FIFO if required #if CFG_TUD_AUDIO_ENABLE_EP_OUT switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 case 0: tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, true); break; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 case 1: tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, true); break; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 case 2: tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, true); break; #endif } #if !CFG_TUD_EDPT_DEDICATED_HWFIFO // Initialize linear buffers switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 case 0: audio->lin_buf_out = lin_buf_out.buf_1; break; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 case 1: audio->lin_buf_out = lin_buf_out.buf_2; break; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 case 2: audio->lin_buf_out = lin_buf_out.buf_3; break; #endif } #endif// !CFG_TUD_EDPT_DEDICATED_HWFIFO #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 case 0: audio->fb_buf = &fb_ep_buf.buf_1; break; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 case 1: audio->fb_buf = &fb_ep_buf.buf_2; break; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 case 2: audio->fb_buf = &fb_ep_buf.buf_3; break; #endif } #endif// CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } } bool audiod_deinit(void) { return false;// TODO not implemented yet } void audiod_reset(uint8_t rhport) { (void) rhport; for (uint8_t i = 0; i < CFG_TUD_AUDIO; i++) { audiod_function_t *audio = &_audiod_fct[i]; tu_memclr(audio, ITF_MEM_RESET_SIZE); #if CFG_TUD_AUDIO_ENABLE_EP_IN tu_fifo_clear(&audio->ep_in_ff); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT tu_fifo_clear(&audio->ep_out_ff); #endif } } uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) max_len; TU_VERIFY(TUSB_CLASS_AUDIO == itf_desc->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass, 0); // Verify version is correct - this check can be omitted TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V1 || itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2, 0); // Verify 2nd interface descriptor is Audio Streaming to avoid mess with MIDI class // Audio Control interface is followed by Audio Streaming interface(s) // MIDI class also starts with Audio Control but is followed by MIDI Streaming { uint8_t const *p_desc = (uint8_t const *) itf_desc; uint8_t const *p_desc_end = p_desc + max_len; // Advance to next interface descriptor p_desc = tu_desc_next(p_desc); while (tu_desc_in_bounds(p_desc, p_desc_end) && tu_desc_type(p_desc) != TUSB_DESC_INTERFACE) { p_desc = tu_desc_next(p_desc); } // Verify next interface is Audio Streaming (subclass 2), not MIDI Streaming (subclass 3) if (p_desc_end - p_desc >= (int)sizeof(tusb_desc_interface_t)) { tusb_desc_interface_t const *next_itf = (tusb_desc_interface_t const *) p_desc; TU_VERIFY(next_itf->bInterfaceClass == TUSB_CLASS_AUDIO && next_itf->bInterfaceSubClass == AUDIO_SUBCLASS_STREAMING, 0); } else { // No further interface found or not enough bytes for interface descriptor return 0; } } // Verify interrupt control EP is enabled if demanded by descriptor TU_ASSERT(itf_desc->bNumEndpoints <= 1, 0);// 0 or 1 EPs are allowed if (itf_desc->bNumEndpoints == 1) { TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP, 0); } // Alternate setting MUST be zero - this check can be omitted TU_VERIFY(itf_desc->bAlternateSetting == 0, 0); // Find available audio driver interface uint8_t i; for (i = 0; i < CFG_TUD_AUDIO; i++) { if (!_audiod_fct[i].p_desc) { _audiod_fct[i].p_desc = (uint8_t const *) itf_desc;// Save pointer to AC descriptor which is by specification always the first one _audiod_fct[i].rhport = rhport; // Calculate descriptor length { uint8_t const *p_desc = (uint8_t const *) itf_desc; uint8_t const *p_desc_end = p_desc + max_len; uint16_t total_len = sizeof(tusb_desc_interface_t); // Skip Standard AC interface descriptor p_desc = tu_desc_next(p_desc); while (p_desc_end - p_desc > 0) { // Stop if: // - Non audio streaming interface descriptor found // - IAD found if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && !(((tusb_desc_interface_t const *) p_desc)->bInterfaceClass == TUSB_CLASS_AUDIO && ((tusb_desc_interface_t const *) p_desc)->bInterfaceSubClass == AUDIO_SUBCLASS_STREAMING)) || tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { break; } else if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *) p_desc)->bInterfaceSubClass == AUDIO_SUBCLASS_STREAMING) { if (_audiod_fct[i].p_desc_as == NULL) { _audiod_fct[i].p_desc_as = p_desc; } } else { // nothing to do } total_len += p_desc[0]; p_desc = tu_desc_next(p_desc); } _audiod_fct[i].desc_length = total_len; } #ifdef TUP_DCD_EDPT_ISO_ALLOC { #if CFG_TUD_AUDIO_ENABLE_EP_IN uint8_t ep_in = 0; uint16_t ep_in_size = 0; #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT uint8_t ep_out = 0; uint16_t ep_out_size = 0; #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP uint8_t ep_fb = 0; #endif uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { // Unified UAC1/UAC2 endpoint processing tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; bool is_feedback_ep = false; bool is_data_ep = false; if (tud_audio_n_version(i) == 1) { // UAC1: Use bRefresh field to distinguish endpoint types audio10_desc_as_iso_data_ep_t const *desc_ep_uac1 = (audio10_desc_as_iso_data_ep_t const *) p_desc; is_data_ep = (desc_ep_uac1->bmAttributes.sync != TUSB_ISO_EP_ATT_NO_SYNC); is_feedback_ep = (desc_ep_uac1->bmAttributes.sync == TUSB_ISO_EP_ATT_NO_SYNC); } else { // UAC2: Use bmAttributes.usage to distinguish endpoint types is_data_ep = (desc_ep->bmAttributes.usage == 0 || desc_ep->bmAttributes.usage == 2); is_feedback_ep = (desc_ep->bmAttributes.usage == 1); } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Explicit feedback EP if (is_feedback_ep) { ep_fb = desc_ep->bEndpointAddress; } #else (void) is_feedback_ep; #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN // Data or data with implicit feedback IN EP if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN && is_data_ep) { ep_in = desc_ep->bEndpointAddress; ep_in_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size); } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT // Data OUT EP if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_OUT && is_data_ep) { ep_out = desc_ep->bEndpointAddress; ep_out_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size); } #endif } p_desc = tu_desc_next(p_desc); } #if CFG_TUD_AUDIO_ENABLE_EP_IN if (ep_in != 0) { usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size); } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT if (ep_out != 0) { usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size); } #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP if (ep_fb != 0) { usbd_edpt_iso_alloc(rhport, ep_fb, 4); } #endif } #endif// TUP_DCD_EDPT_ISO_ALLOC #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL { uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { // For data or data with implicit feedback IN EP // For UAC1 this is always the case since there is no usage field if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN && (desc_ep->bmAttributes.usage == 0 || desc_ep->bmAttributes.usage == 2)) { _audiod_fct[i].interval_tx = desc_ep->bInterval; } } } else if (tud_audio_n_version(i) == 2 && tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL) { // For UAC2 only, UAC1 doesn't have a clock source if (tu_unaligned_read16(p_desc + 4) == AUDIO_TERM_TYPE_USB_STREAMING) { _audiod_fct[i].bclock_id_tx = p_desc[8]; } } else { // nothing to do } p_desc = tu_desc_next(p_desc); } } #endif// CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP { uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { // For each endpoint if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; uint8_t const ep_addr = desc_ep->bEndpointAddress; // If endpoint is input-direction and interrupt-type if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT) { // Store endpoint number and open endpoint _audiod_fct[i].ep_int = ep_addr; TU_ASSERT(usbd_edpt_open(_audiod_fct[i].rhport, desc_ep)); } } p_desc = tu_desc_next(p_desc); } } #endif _audiod_fct[i].mounted = true; break; } } // Verify we found a free one TU_ASSERT(i < CFG_TUD_AUDIO); // This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification) uint16_t drv_len = _audiod_fct[i].desc_length; return drv_len; } static bool audiod_get_interface(uint8_t rhport, tusb_control_request_t const *p_request) { uint8_t const itf = tu_u16_low(p_request->wIndex); // Find index of audio streaming interface uint8_t func_id; TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); // Default to 0 if interface not yet activated uint8_t alt = 0; #if CFG_TUD_AUDIO_ENABLE_EP_IN if (_audiod_fct[func_id].ep_in_as_intf_num == itf) { alt = _audiod_fct[func_id].ep_in_alt; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT if (_audiod_fct[func_id].ep_out_as_intf_num == itf) { alt = _audiod_fct[func_id].ep_out_alt; } #endif TU_VERIFY(tud_control_xfer(rhport, p_request, &alt, 1)); TU_LOG2(" Get itf: %u - current alt: %u\r\n", itf, alt); return true; } static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Here we need to do the following: // 1. Find the audio driver assigned to the given interface to be set // Since one audio driver interface has to be able to cover an unknown number of interfaces (AC, AS + its alternate settings), the best memory efficient way to solve this is to always search through the descriptors. // The audio driver is mapped to an audio function by a reference pointer to the corresponding AC interface of this audio function which serves as a starting point for searching // 2. Close EPs which are currently open // To do so it is not necessary to know the current active alternate interface since we already save the current EP addresses - we simply close them // 3. Open new EP uint8_t const itf = tu_u16_low(p_request->wIndex); uint8_t const alt = tu_u16_low(p_request->wValue); TU_LOG2(" Set itf: %u - alt: %u\r\n", itf, alt); // Find index of audio streaming interface and index of interface uint8_t func_id; TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); audiod_function_t *audio = &_audiod_fct[func_id]; // Look if there is an EP to be closed - for this driver, there are only 3 possible EPs which may be closed (only AS related EPs can be closed, AC EP (if present) is always open) #if CFG_TUD_AUDIO_ENABLE_EP_IN if (audio->ep_in_as_intf_num == itf) { audio->ep_in_as_intf_num = 0; audio->ep_in_alt = 0; #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_in); #endif // Clear FIFOs, since data is no longer valid tu_fifo_clear(&audio->ep_in_ff); // Invoke callback - can be used to stop data sampling TU_VERIFY(tud_audio_set_itf_close_ep_cb(rhport, p_request)); audio->ep_in = 0;// Necessary? #if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL audio->packet_sz_tx[0] = 0; audio->packet_sz_tx[1] = 0; audio->packet_sz_tx[2] = 0; #endif } #endif// CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_OUT if (audio->ep_out_as_intf_num == itf) { audio->ep_out_as_intf_num = 0; audio->ep_out_alt = 0; #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_out); #endif // Clear FIFOs, since data is no longer valid tu_fifo_clear(&audio->ep_out_ff); // Invoke callback - can be used to stop data sampling TU_VERIFY(tud_audio_set_itf_close_ep_cb(rhport, p_request)); audio->ep_out = 0;// Necessary? // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_fb); #endif audio->ep_fb = 0; tu_memclr(&audio->feedback, sizeof(audio->feedback)); #endif } #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT // Open new EP if necessary - EPs are only to be closed or opened for AS interfaces - Look for AS interface with correct alternate interface uint8_t const *p_desc = audio->p_desc_as; // Get pointer at end uint8_t const *p_desc_end = audio->p_desc + audio->desc_length; // p_desc starts at required interface with alternate setting zero // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { // Find correct interface if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *) p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const *) p_desc)->bAlternateSetting == alt) { #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL uint8_t const *p_desc_parse_for_params = p_desc; #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const *) p_desc)->bNumEndpoints; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (foundEPs < nEps && (p_desc_end - p_desc > 0)) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; #ifdef TUP_DCD_EDPT_ISO_ALLOC TU_ASSERT(usbd_edpt_iso_activate(rhport, desc_ep)); #else TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); #endif uint8_t const ep_addr = desc_ep->bEndpointAddress; bool is_feedback_ep = false; bool is_data_ep = false; if (tud_audio_n_version(func_id) == 1) { // UAC1: Use bRefresh field to distinguish endpoint types audio10_desc_as_iso_data_ep_t const *desc_ep_uac1 = (audio10_desc_as_iso_data_ep_t const *) p_desc; is_data_ep = (desc_ep_uac1->bmAttributes.sync != TUSB_ISO_EP_ATT_NO_SYNC); is_feedback_ep = (desc_ep_uac1->bmAttributes.sync == TUSB_ISO_EP_ATT_NO_SYNC); } else { // UAC2: Use bmAttributes.usage to distinguish endpoint types is_data_ep = (desc_ep->bmAttributes.usage == 0 || desc_ep->bmAttributes.usage == 2); is_feedback_ep = (desc_ep->bmAttributes.usage == 1); } //TODO: We need to set EP non busy since this is not taken care of right now in ep_close() - THIS IS A WORKAROUND! usbd_edpt_clear_stall(rhport, ep_addr); #if CFG_TUD_AUDIO_ENABLE_EP_IN // For data or data with implicit feedback IN EP if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && is_data_ep) { // Save address audio->ep_in = ep_addr; audio->ep_in_as_intf_num = itf; audio->ep_in_alt = alt; audio->ep_in_sz = tu_edpt_packet_size(desc_ep); // Set the default EP IN FIFO threshold to half fifo depth. audio->ep_in_fifo_threshold = audio->ep_in_ff.depth / 2; // If flow control is enabled, parse for the corresponding parameters - doing this here means only AS interfaces with EPs get scanned for parameters #if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL audiod_parse_flow_control_params(audio, p_desc_parse_for_params); #endif // Schedule first transmit if alternate interface is not zero, as sample data is available a ZLP is loaded #if !CFG_TUD_EDPT_DEDICATED_HWFIFO TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, 0, false)); #else // Send everything in ISO EP FIFO TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, 0, false)); #endif } #endif// CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_OUT // Checking usage not necessary if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT && is_data_ep) { // Save address audio->ep_out = ep_addr; audio->ep_out_as_intf_num = itf; audio->ep_out_alt = alt; audio->ep_out_sz = tu_edpt_packet_size(desc_ep); // Prepare for incoming data #if !CFG_TUD_EDPT_DEDICATED_HWFIFO TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, false)); #else TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, false)); #endif } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Check if usage is explicit data feedback if (is_feedback_ep) { audio->ep_fb = ep_addr; audio->feedback.frame_shift = desc_ep->bInterval - 1; // Schedule first feedback transmit audiod_fb_send(func_id, false); } #else (void) is_feedback_ep; #endif #else (void) is_feedback_ep; #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT foundEPs += 1; } p_desc = tu_desc_next(p_desc); } TU_VERIFY(foundEPs == nEps); // Invoke one callback for a final set interface TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Prepare feedback computation parameters TU_VERIFY(audiod_fb_params_prepare(func_id, alt)); #endif// CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // We are done - abort loop break; } // Moving forward p_desc = tu_desc_next(p_desc); } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Disable SOF interrupt if no driver has any enabled feedback EP bool enable_sof = false; for (uint8_t i = 0; i < CFG_TUD_AUDIO; i++) { if (_audiod_fct[i].ep_fb != 0 && (_audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED || _audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT || _audiod_fct[i].feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2)) { enable_sof = true; break; } } usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, enable_sof); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL audiod_calc_tx_packet_sz(audio); #endif tud_control_status(rhport, p_request); return true; } // Invoked when class request DATA stage is finished. // return false to stall control EP (e.g Host send non-sense DATA) static bool audiod_control_complete(uint8_t rhport, tusb_control_request_t const *p_request) { // Handle audio class specific set requests if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && p_request->bmRequestType_bit.direction == TUSB_DIR_OUT) { uint8_t func_id; switch (p_request->bmRequestType_bit.recipient) { case TUSB_REQ_RCPT_INTERFACE: { uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t entityID = TU_U16_HIGH(p_request->wIndex); if (entityID != 0) { // Check if entity is present and get corresponding driver index TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL if (tud_audio_n_version(func_id) == 2) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); if (_audiod_fct[func_id].bclock_id_tx == entityID && ctrlSel == AUDIO20_CS_CTRL_SAM_FREQ && p_request->bRequest == AUDIO20_CS_REQ_CUR) { _audiod_fct[func_id].sample_rate_tx = tu_unaligned_read32(get_ctrl_buffer()); audiod_calc_tx_packet_sz(&_audiod_fct[func_id]); } } #endif // Invoke callback return tud_audio_set_req_entity_cb(rhport, p_request, get_ctrl_buffer()); } else { // Find index of audio driver structure and verify interface really exists TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); // Invoke callback return tud_audio_set_req_itf_cb(rhport, p_request, get_ctrl_buffer()); } } break; case TUSB_REQ_RCPT_ENDPOINT: { uint8_t ep = TU_U16_LOW(p_request->wIndex); // Check if entity is present and get corresponding driver index TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL if (tud_audio_n_version(func_id) == 1) { if (_audiod_fct[func_id].ep_in == ep) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); if (ctrlSel == AUDIO10_EP_CTRL_SAMPLING_FREQ && p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { _audiod_fct[func_id].sample_rate_tx = tu_unaligned_read32(get_ctrl_buffer()) & 0x00FFFFFF; audiod_calc_tx_packet_sz(&_audiod_fct[func_id]); } } } #endif // Invoke callback bool ret = tud_audio_set_req_ep_cb(rhport, p_request, get_ctrl_buffer()); #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP if (ret && tud_audio_n_version(func_id) == 1) { if (_audiod_fct[func_id].ep_out == ep) { uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); if (ctrlSel == AUDIO10_EP_CTRL_SAMPLING_FREQ && p_request->bRequest == AUDIO10_CS_REQ_SET_CUR) { audiod_fb_params_prepare(func_id, _audiod_fct[func_id].ep_out_alt); } } } #endif return ret; } break; // Unknown/Unsupported recipient default: TU_BREAKPOINT(); return false; } } return true; } // Handle class control request // return false to stall control endpoint (e.g unsupported request) static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const *p_request) { (void) rhport; // Handle standard requests - standard set requests usually have no data stage so we also handle set requests here if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { switch (p_request->bRequest) { case TUSB_REQ_GET_INTERFACE: return audiod_get_interface(rhport, p_request); case TUSB_REQ_SET_INTERFACE: return audiod_set_interface(rhport, p_request); case TUSB_REQ_CLEAR_FEATURE: return true; // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } } // Handle class requests if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { uint8_t itf = TU_U16_LOW(p_request->wIndex); uint8_t func_id; // Conduct checks which depend on the recipient switch (p_request->bmRequestType_bit.recipient) { case TUSB_REQ_RCPT_INTERFACE: { uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Verify if entity is present if (entityID != 0) { // Find index of audio driver structure and verify entity really exists TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { return tud_audio_get_req_entity_cb(rhport, p_request); } } else { // Find index of audio driver structure and verify interface really exists TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { return tud_audio_get_req_itf_cb(rhport, p_request); } } } break; case TUSB_REQ_RCPT_ENDPOINT: { uint8_t ep = TU_U16_LOW(p_request->wIndex); // Find index of audio driver structure and verify EP really exists TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { return tud_audio_get_req_ep_cb(rhport, p_request); } } break; // Unknown/Unsupported recipient default: TU_LOG2(" Unsupported recipient: %d\r\n", p_request->bmRequestType_bit.recipient); TU_BREAKPOINT(); return false; } // If we end here, the received request is a set request - we schedule a receive for the data stage and return true here. We handle the rest later in audiod_control_complete() once the data stage was finished TU_VERIFY(tud_control_xfer(rhport, p_request, get_ctrl_buffer(), CFG_TUD_AUDIO_CTRL_BUF_SZ)); return true; } // There went something wrong - unsupported control request type TU_BREAKPOINT(); return false; } bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { if (stage == CONTROL_STAGE_SETUP) { return audiod_control_request(rhport, request); } else if (stage == CONTROL_STAGE_DATA) { return audiod_control_complete(rhport, request); } else { // nothing to do } return true; } bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; (void) xferred_bytes; #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // Search for interface belonging to given end point address and proceed as required for (uint8_t func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) { audiod_function_t *audio = &_audiod_fct[func_id]; // Data transmission of control interrupt finished if (audio->ep_int == ep_addr) { // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? // In case of an erroneous transmission a retransmission is conducted - this is taken care of by PHY ??? // I assume here, that things above are handled by PHY // All transmission is done - what remains to do is to inform job was completed tud_audio_int_done_cb(rhport); return true; } } #else (void) rhport; (void) ep_addr; #endif return false; } bool audiod_xfer_isr(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; (void) xferred_bytes; // Search for interface belonging to given end point address and proceed as required for (uint8_t func_id = 0; func_id < CFG_TUD_AUDIO; func_id++) { audiod_function_t* audio = &_audiod_fct[func_id]; #if CFG_TUD_AUDIO_ENABLE_EP_IN // Data transmission of audio packet finished if (audio->ep_in == ep_addr) { // USB 2.0, section 5.6.4, third paragraph, states "An isochronous endpoint must specify its required bus access period. However, an isochronous endpoint must be prepared to handle poll rates faster than the one specified." // That paragraph goes on to say "An isochronous IN endpoint must return a zero-length packet whenever data is requested at a faster interval than the specified interval and data is not available." // This can only be solved reliably if we load a ZLP after every IN transmission since we can not say if the host requests samples earlier than we declared! Once all samples are collected we overwrite the loaded ZLP. // Check if there is data to load into EPs buffer - if not load it with ZLP // Be aware - we as a device are not able to know if the host polls for data with a faster rate as we stated this in the descriptors. Therefore we always have to put something into the EPs buffer. However, once we did that, there is no way of aborting this or replacing what we put into the buffer before! // This is the only place where we can fill something into the EPs buffer! // Load new data audiod_tx_xfer_isr(rhport, audio, (uint16_t) xferred_bytes); return true; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT // New audio packet received if (audio->ep_out == ep_addr) { audiod_rx_xfer_isr(rhport, audio, (uint16_t) xferred_bytes); return true; } #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Transmission of feedback EP finished if (audio->ep_fb == ep_addr) { // Schedule a transmit with the new value if EP is not busy // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent audiod_fb_send(func_id, true); return true; } #endif #endif } return false; } #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static bool audiod_fb_params_prepare(uint8_t func_id, uint8_t alt) { audiod_function_t *audio = &_audiod_fct[func_id]; // Prepare feedback computation if endpoint is available if (audio->ep_fb != 0) { audio_feedback_params_t fb_param = {0}; tud_audio_feedback_params_cb(func_id, alt, &fb_param); audio->feedback.compute_method = fb_param.method; // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame) uint32_t const frame_div = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000; audio->feedback.min_value = ((fb_param.sample_freq - 1) / frame_div) << 16; audio->feedback.max_value = (fb_param.sample_freq / frame_div + 1) << 16; switch (fb_param.method) { case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT: case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2: { // Check if frame interval is within sane limits // The interval value n_frames was taken from the descriptors within audiod_set_interface() // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed // this lower limit ensures the measures feedback value has sufficient precision uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13; uint32_t const n_frame = (1UL << audio->feedback.frame_shift); if ((((1UL << k) * fb_param.sample_freq / fb_param.frequency.mclk_freq) + 1) > n_frame) { TU_LOG1(" UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false; } // Check if parameters really allow for a power of two division if ((fb_param.frequency.mclk_freq % fb_param.sample_freq) == 0 && tu_is_power_of_two(fb_param.frequency.mclk_freq / fb_param.sample_freq)) { audio->feedback.compute_method = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2; audio->feedback.compute.power_of_2 = (uint8_t) (16 - (audio->feedback.frame_shift - 1) - tu_log2(fb_param.frequency.mclk_freq / fb_param.sample_freq)); } else if (audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) { audio->feedback.compute.float_const = (float) fb_param.sample_freq / (float) fb_param.frequency.mclk_freq * (1UL << (16 - (audio->feedback.frame_shift - 1))); } else { audio->feedback.compute.fixed.sample_freq = fb_param.sample_freq; audio->feedback.compute.fixed.mclk_freq = fb_param.frequency.mclk_freq; } } break; case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: { // Determine FIFO threshold uint16_t fifo_threshold = fb_param.fifo_count.fifo_threshold ? fb_param.fifo_count.fifo_threshold : tu_fifo_depth(&audio->ep_out_ff) / 2; audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_threshold; audio->feedback.compute.fifo_count.fifo_lvl_avg = ((uint32_t) fifo_threshold) << 16; // Avoid 64bit division uint32_t nominal = ((fb_param.sample_freq / 100) << 16) / (frame_div / 100); audio->feedback.compute.fifo_count.nom_value = nominal; audio->feedback.compute.fifo_count.rate_const[0] = (uint16_t) ((audio->feedback.max_value - nominal) / fifo_threshold); audio->feedback.compute.fifo_count.rate_const[1] = (uint16_t) ((nominal - audio->feedback.min_value) / fifo_threshold); // On HS feedback is more sensitive since packet size can vary every MSOF, could cause instability if (tud_speed_get() == TUSB_SPEED_HIGH) { audio->feedback.compute.fifo_count.rate_const[0] /= 8; audio->feedback.compute.fifo_count.rate_const[1] /= 8; } } break; // nothing to do default: break; } } return true; } static void audiod_fb_fifo_count_update(audiod_function_t *audio, uint16_t lvl_new) { /* Low-pass (averaging) filter */ uint32_t lvl = audio->feedback.compute.fifo_count.fifo_lvl_avg; lvl = (uint32_t) (((uint64_t) lvl * 63 + ((uint32_t) lvl_new << 16)) >> 6); audio->feedback.compute.fifo_count.fifo_lvl_avg = lvl; uint32_t const ff_lvl = lvl >> 16; uint16_t const ff_thr = audio->feedback.compute.fifo_count.fifo_lvl_thr; uint16_t const *rate = audio->feedback.compute.fifo_count.rate_const; uint32_t feedback; if (ff_lvl < ff_thr) { feedback = audio->feedback.compute.fifo_count.nom_value + (ff_thr - ff_lvl) * rate[0]; } else { feedback = audio->feedback.compute.fifo_count.nom_value - (ff_lvl - ff_thr) * rate[1]; } if (feedback > audio->feedback.max_value) { feedback = audio->feedback.max_value; } if (feedback < audio->feedback.min_value) { feedback = audio->feedback.min_value; } audio->feedback.value = feedback; } #endif TU_ATTR_FAST_FUNC void audiod_sof_isr(uint8_t rhport, uint32_t frame_count) { (void) rhport; (void) frame_count; #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s) // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K) // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames // Iterate over audio functions and set feedback value for (uint8_t i = 0; i < CFG_TUD_AUDIO; i++) { audiod_function_t *audio = &_audiod_fct[i]; if (audio->ep_fb != 0) { // HS shift need to be adjusted since SOF event is generated for frame only uint8_t const hs_adjust = (TUSB_SPEED_HIGH == tud_speed_get()) ? 3 : 0; uint32_t const interval = 1UL << (audio->feedback.frame_shift - hs_adjust); if (0 == (frame_count & (interval - 1))) { tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift); } } } #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP } bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const *p_request, void *data, uint16_t len) { // Handles only sending of data not receiving if (p_request->bmRequestType_bit.direction == TUSB_DIR_OUT) return false; // Get corresponding driver index uint8_t func_id; uint8_t itf = TU_U16_LOW(p_request->wIndex); // Conduct checks which depend on the recipient switch (p_request->bmRequestType_bit.recipient) { case TUSB_REQ_RCPT_INTERFACE: { uint8_t entityID = TU_U16_HIGH(p_request->wIndex); // Verify if entity is present if (entityID != 0) { // Find index of audio driver structure and verify entity really exists TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); } else { // Find index of audio driver structure and verify interface really exists TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); } } break; case TUSB_REQ_RCPT_ENDPOINT: { uint8_t ep = TU_U16_LOW(p_request->wIndex); // Find index of audio driver structure and verify EP really exists TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); } break; // Unknown/Unsupported recipient default: TU_LOG2(" Unsupported recipient: %d\r\n", p_request->bmRequestType_bit.recipient); TU_BREAKPOINT(); return false; } // Copy into buffer TU_VERIFY(0 == tu_memcpy_s(get_ctrl_buffer(), CFG_TUD_AUDIO_CTRL_BUF_SZ, data, (size_t) len)); #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL if (tud_audio_n_version(func_id) == 2) { // Find data for sampling_frequency_control if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && p_request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) { uint8_t entityID = TU_U16_HIGH(p_request->wIndex); uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); if (_audiod_fct[func_id].bclock_id_tx == entityID && ctrlSel == AUDIO20_CS_CTRL_SAM_FREQ && p_request->bRequest == AUDIO20_CS_REQ_CUR) { _audiod_fct[func_id].sample_rate_tx = tu_unaligned_read32(get_ctrl_buffer()); audiod_calc_tx_packet_sz(&_audiod_fct[func_id]); } } } #endif // Schedule transmit return tud_control_xfer(rhport, p_request, get_ctrl_buffer(), len); } // Verify an entity with the given ID exists and returns also the corresponding driver index static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t *func_id) { uint8_t i; for (i = 0; i < CFG_TUD_AUDIO; i++) { // Look for the correct driver by checking if the unique standard AC interface number fits if (_audiod_fct[i].p_desc && ((tusb_desc_interface_t const *) _audiod_fct[i].p_desc)->bInterfaceNumber == itf) { // Get pointers after class specific AC descriptors and end of AC descriptors - entities are defined in between uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc);// Points to CS AC descriptor p_desc = tu_desc_next(p_desc);// Get past CS AC descriptor while (_audiod_fct[i].p_desc_as - p_desc > 0) { // Entity IDs are always at offset 3 if (p_desc[3] == entityID) { *func_id = i; return true; } p_desc = tu_desc_next(p_desc); } } } return false; } static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) { uint8_t i; for (i = 0; i < CFG_TUD_AUDIO; i++) { if (_audiod_fct[i].p_desc != NULL) { // Get pointer at beginning and end uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *)p_desc)->bInterfaceNumber == itf) { *func_id = i; return true; } p_desc = tu_desc_next(p_desc); } } } return false; } static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) { uint8_t i; for (i = 0; i < CFG_TUD_AUDIO; i++) { if (_audiod_fct[i].p_desc) { // Get pointer at end uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length; // Advance past AC descriptors - EP we look for are streaming EPs uint8_t const *p_desc = _audiod_fct[i].p_desc_as; // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT && ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress == ep) { *func_id = i; return true; } p_desc = tu_desc_next(p_desc); } } } return false; } #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL static void audiod_parse_flow_control_params(audiod_function_t *audio, uint8_t const *p_desc) { p_desc = tu_desc_next(p_desc);// Exclude standard AS interface descriptor of current alternate interface descriptor if (tud_audio_n_version(audiod_get_audio_fct_idx(audio)) == 1) { p_desc = tu_desc_next(p_desc);// Exclude Class-Specific AS Interface Descriptor(4.5.2) to get to format type descriptor if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE) { audio->format_type_tx = ((audio10_desc_type_I_format_n_t(1) const *) p_desc)->bFormatType; if (audio->format_type_tx == AUDIO10_FORMAT_TYPE_I) { audio->n_channels_tx = ((audio10_desc_type_I_format_n_t(1) const *) p_desc)->bNrChannels; audio->n_bytes_per_sample_tx = ((audio10_desc_type_I_format_n_t(1) const *) p_desc)->bSubFrameSize; // Save sample rate - needed when EP doesn't support setting sample rate audio->sample_rate_tx = tu_unaligned_read32(((audio10_desc_type_I_format_n_t(1) const *) p_desc)->tSamFreq) & 0x00FFFFFF; } } } else { // Look for a Class-Specific AS Interface Descriptor(4.9.2) to verify format type and format and also to get number of physical channels if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO20_CS_AS_INTERFACE_AS_GENERAL) { audio->n_channels_tx = ((audio20_desc_cs_as_interface_t const *) p_desc)->bNrChannels; audio->format_type_tx = ((audio20_desc_cs_as_interface_t const *) p_desc)->bFormatType; // Look for a Type I Format Type Descriptor(2.3.1.6 - Audio Formats) p_desc = tu_desc_next(p_desc); if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE && ((audio20_desc_type_I_format_t const *) p_desc)->bFormatType == AUDIO20_FORMAT_TYPE_I) { audio->n_bytes_per_sample_tx = ((audio20_desc_type_I_format_t const *) p_desc)->bSubslotSize; } } } } static bool audiod_calc_tx_packet_sz(audiod_function_t *audio) { // AUDIO20_FORMAT_TYPE_I = AUDIO10_FORMAT_TYPE_I TU_VERIFY(audio->format_type_tx == AUDIO20_FORMAT_TYPE_I); TU_VERIFY(audio->n_channels_tx); TU_VERIFY(audio->n_bytes_per_sample_tx); TU_VERIFY(audio->interval_tx); TU_VERIFY(audio->sample_rate_tx); const uint8_t interval = (tud_speed_get() == TUSB_SPEED_FULL) ? audio->interval_tx : 1 << (audio->interval_tx - 1); const uint16_t sample_normimal = (uint16_t) (audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_reminder = (uint16_t) (audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t packet_sz_tx_min = (uint16_t) ((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); const uint16_t packet_sz_tx_norm = (uint16_t) (sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sample_tx); const uint16_t packet_sz_tx_max = (uint16_t) ((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); // Endpoint size must larger than packet size TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); // Frmt20.pdf 2.3.1.1 USB Packets if (sample_reminder) { // All virtual frame packets must either contain INT(nav) audio slots (small VFP) or INT(nav)+1 (large VFP) audio slots audio->packet_sz_tx[0] = packet_sz_tx_norm; audio->packet_sz_tx[1] = packet_sz_tx_norm; audio->packet_sz_tx[2] = packet_sz_tx_max; } else { // In the case where nav = INT(nav), ni may vary between INT(nav)-1 (small VFP), INT(nav) // (medium VFP) and INT(nav)+1 (large VFP). audio->packet_sz_tx[0] = packet_sz_tx_min; audio->packet_sz_tx[1] = packet_sz_tx_norm; audio->packet_sz_tx[2] = packet_sz_tx_max; } return true; } static uint16_t audiod_tx_packet_size(const uint16_t *nominal_size, uint16_t data_count, uint16_t fifo_depth, uint16_t fifo_threshold, uint16_t max_depth) { // Flow control need a FIFO size of at least 4*Navg if (nominal_size[1] && nominal_size[1] <= fifo_depth * 4) { // Use blackout to prioritize normal size packet static int ctrl_blackout = 0; uint16_t packet_size; uint16_t slot_size = nominal_size[2] - nominal_size[1]; if (data_count < nominal_size[0]) { // If you get here frequently, then your I2S clock deviation is too big ! packet_size = 0; } else if (data_count < (fifo_threshold - slot_size) && !ctrl_blackout) { packet_size = nominal_size[0]; ctrl_blackout = 10; } else if (data_count > (fifo_threshold + slot_size) && !ctrl_blackout) { packet_size = nominal_size[2]; if (nominal_size[0] == nominal_size[1]) { // nav > INT(nav), eg. 44.1k, 88.2k ctrl_blackout = 0; } else { // nav = INT(nav), eg. 48k, 96k ctrl_blackout = 10; } } else { packet_size = nominal_size[1]; if (ctrl_blackout) { ctrl_blackout--; } } // Normally this cap is not necessary return tu_min16(packet_size, max_depth); } else { return tu_min16(data_count, max_depth); } } #endif // No security checks here - internal function only which should always succeed static inline uint8_t audiod_get_audio_fct_idx(audiod_function_t *audio) { return (uint8_t) (audio - _audiod_fct); } #endif // (CFG_TUD_ENABLED && CFG_TUD_AUDIO) ================================================ FILE: src/class/audio/audio_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Ha Thach (tinyusb.org) * Copyright (c) 2020 Reinhard Panhuber * Copyright (c) 2023 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_AUDIO_DEVICE_H_ #define TUSB_AUDIO_DEVICE_H_ #include "audio.h" //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ // All sizes are in bytes! // Size of control buffer used to receive and send control messages via EP0 - has to be big enough to hold your // biggest request structure e.g. range requests with multiple intervals defined or cluster descriptors #ifndef CFG_TUD_AUDIO_CTRL_BUF_SZ #define CFG_TUD_AUDIO_CTRL_BUF_SZ 64 #endif // End point sizes IN BYTES - Limits: Full Speed <= 1023, High Speed <= 1024 #ifndef CFG_TUD_AUDIO_ENABLE_EP_IN #define CFG_TUD_AUDIO_ENABLE_EP_IN 0 // TX #endif #ifndef CFG_TUD_AUDIO_ENABLE_EP_OUT #define CFG_TUD_AUDIO_ENABLE_EP_OUT 0 // RX #endif // Maximum EP sizes for all alternate AS interface settings - used for checks and buffer allocation #if CFG_TUD_AUDIO_ENABLE_EP_IN #ifndef CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX #error You must tell the driver the biggest EP IN size! #endif #if CFG_TUD_AUDIO > 1 #ifndef CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX #error You must tell the driver the biggest EP IN size! #endif #endif #if CFG_TUD_AUDIO > 2 #ifndef CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX #error You must tell the driver the biggest EP IN size! #endif #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_OUT #ifndef CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX #error You must tell the driver the biggest EP OUT size! #endif #if CFG_TUD_AUDIO > 1 #ifndef CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX #error You must tell the driver the biggest EP OUT size! #endif #endif #if CFG_TUD_AUDIO > 2 #ifndef CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX #error You must tell the driver the biggest EP OUT size! #endif #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT // Software EP FIFO buffer sizes - must be >= max EP SIZEs! #ifndef CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ 0 #endif #ifndef CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ 0 #endif #ifndef CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ 0 #endif #ifndef CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ 0 #endif #ifndef CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ 0 #endif #ifndef CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ #define CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ 0 #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #if CFG_TUD_AUDIO > 1 #if CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #endif #if CFG_TUD_AUDIO > 2 #if CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #endif #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #if CFG_TUD_AUDIO > 1 #if CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #endif #if CFG_TUD_AUDIO > 2 #if CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ < CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX #error EP software buffer size MUST BE at least as big as maximum EP size #endif #endif #endif // (For TYPE-I format only) Flow control is necessary to allow IN ep send correct amount of data, unless it's a // virtual device where data is perfectly synchronized to USB clock. #ifndef CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL #define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 #endif // Enable/disable feedback EP (required for asynchronous RX applications) #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 #endif // Enable/disable interrupt EP (required for notifying host of control changes) #ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP #define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 #endif // Audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) #define CFG_TUD_AUDIO_INTERRUPT_EP_SZ 6 #ifdef __cplusplus extern "C" { #endif /** \addtogroup AUDIO_Serial Serial * @{ * \defgroup AUDIO_Serial_Device Device * @{ */ //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) // CFG_TUD_AUDIO > 1 //--------------------------------------------------------------------+ bool tud_audio_n_mounted(uint8_t func_id); uint8_t tud_audio_n_version(uint8_t func_id); #if CFG_TUD_AUDIO_ENABLE_EP_OUT uint16_t tud_audio_n_available (uint8_t func_id); uint16_t tud_audio_n_read (uint8_t func_id, void* buffer, uint16_t bufsize); bool tud_audio_n_clear_ep_out_ff (uint8_t func_id); tu_fifo_t* tud_audio_n_get_ep_out_ff (uint8_t func_id); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN uint16_t tud_audio_n_write (uint8_t func_id, const void * data, uint16_t len); bool tud_audio_n_clear_ep_in_ff (uint8_t func_id); tu_fifo_t* tud_audio_n_get_ep_in_ff (uint8_t func_id); uint16_t tud_audio_n_get_ep_in_fifo_threshold(uint8_t func_id); void tud_audio_n_set_ep_in_fifo_threshold(uint8_t func_id, uint16_t threshold); #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP bool tud_audio_int_n_write (uint8_t func_id, const audio_interrupt_data_t * data); #endif //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ static inline bool tud_audio_mounted (void); static inline uint8_t tud_audio_version (void); #if CFG_TUD_AUDIO_ENABLE_EP_OUT static inline uint16_t tud_audio_available (void); static inline bool tud_audio_clear_ep_out_ff (void); static inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize); static inline tu_fifo_t* tud_audio_get_ep_out_ff (void); #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN static inline uint16_t tud_audio_write (const void * data, uint16_t len); static inline bool tud_audio_clear_ep_in_ff (void); static inline tu_fifo_t* tud_audio_get_ep_in_ff (void); #endif // INT CTR API #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP static inline bool tud_audio_int_write (const audio_interrupt_data_t * data); #endif // Buffer control EP data and schedule a transmit // This function is intended to be used if you do not have a persistent buffer or memory location available // (e.g. non-local variables) and need to answer onto a get request. This function buffers your answer request // frame into the control buffer of the corresponding audio driver and schedules a transmit for sending it. // Since transmission is triggered via interrupts, a persistent memory location is required onto which the buffer // pointer in pointing. If you already have such available you may directly use 'tud_control_xfer(...)'. In this // case data does not need to be copied into an additional buffer and you save some time. // If the request's wLength is zero, a status packet is sent instead. bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len); //--------------------------------------------------------------------+ // Application Callback API //--------------------------------------------------------------------+ #if CFG_TUD_AUDIO_ENABLE_EP_IN // Invoked in ISR context once an audio packet was sent successfully. // Normally this function is not needed, since the data transfer should be driven by audio clock (i.e. I2S clock), // call tud_audio_write() in I2S receive callback. bool tud_audio_tx_done_isr(uint8_t rhport, uint16_t n_bytes_sent, uint8_t func_id, uint8_t ep_in, uint8_t cur_alt_setting); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT // Invoked in ISR context once an audio packet was received successfully. // Normally this function is not needed, since the data transfer should be driven by audio clock (i.e. I2S clock), // call tud_audio_read() in I2S transmit callback. bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting); #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // Note about feedback calculation // // Option 1 - AUDIO_FEEDBACK_METHOD_FIFO_COUNT // Feedback value is calculated within the audio driver by regulating the FIFO level to half fill. // Advantage: No SOF interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus // less CPU load, well tested (Windows, Linux, OSX) with a reliable result so far. // Disadvantage: A FIFO of minimal 4 frames is needed to compensate for jitter, an average delay of 2 frames is // introduced. // // Option 2 - AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED / AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT // Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information // about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle // count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter). // See tud_audio_set_fb_params() and tud_audio_feedback_update() // Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller and thus a // smaller delay is possible. // Disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. (The most critical point // is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, // hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is // introduced). Long-term drift will cause the FIFO under/overflow, you still needs to correct it somehow. // // Option 3 - manual // Determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined // e.g. from some fill status of some FIFO buffer. // Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus // less CPU load. // Disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 6 frames), i.e. a larger delay // is introduced. // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at // FB endpoint interval till it's changed. // // The feedback format is specified to be 16.16 for HS and 10.14 for FS devices (see Universal Serial Bus // Specification Revision 2.0 5.12.4.2). For simplicity, this function always uses 16.16 format. For FS devices, // the driver will automatically convert the value to 10.14 format. // // Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 // devices. On Linux and it seems the driver can work with either format. // // Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the // feature is used, the user can not set the feedback value. // // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec // Boiled down, the feedback value Ff = n_samples / (micro)frame. // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames // need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency // e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is // available and locked to f_s) // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where // P = min( ceil(log2(f_m / f_s)), K) // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles // within fb_n_frames bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback); // Update feedback value with passed MCLK cycles since last time this update function is called. // Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented // This function will also call tud_audio_feedback_set() // return feedback value in 16.16 for reference (0 for error) // Example : // binterval=3 (4ms); FS = 48kHz; MCLK = 12.288MHz // In 4 SOF MCLK counted 49152 cycles uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles); enum { AUDIO_FEEDBACK_METHOD_DISABLED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED, AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT, AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2, // For driver internal use only AUDIO_FEEDBACK_METHOD_FIFO_COUNT }; typedef struct { uint8_t method; uint32_t sample_freq; // sample frequency in Hz union { struct { uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on } frequency; struct { uint16_t fifo_threshold; // Target FIFO threshold level, default to half FIFO if not set } fifo_count; }; } audio_feedback_params_t; // Invoked when needed to set feedback parameters void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param); // Callback in ISR context, invoked periodically according to feedback endpoint bInterval. // Could be used to compute and update feedback value, should be placed in RAM if possible // frame_number : current SOF count // interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift); #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // Invoked when an interrupt notification transfer is complete void tud_audio_int_done_cb(uint8_t rhport); #endif // Invoked when audio set interface request received bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio set interface request received which closes an EP bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request); // backward compatible for typo #define tud_audio_set_itf_close_EP_cb tud_audio_set_itf_close_ep_cb // Invoked when audio class specific set request received for an EP bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific set request received for an interface bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific set request received for an entity bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff); // Invoked when audio class specific get request received for an EP bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio class specific get request received for an interface bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request); // Invoked when audio class specific get request received for an entity bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request); //--------------------------------------------------------------------+ // Inline Functions //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool tud_audio_mounted(void) { return tud_audio_n_mounted(0); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_audio_version(void) { return tud_audio_n_version(0); } #if CFG_TUD_AUDIO_ENABLE_EP_OUT TU_ATTR_ALWAYS_INLINE static inline uint16_t tud_audio_available(void) { return tud_audio_n_available(0); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tud_audio_read(void* buffer, uint16_t bufsize) { return tud_audio_n_read(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline bool tud_audio_clear_ep_out_ff(void) { return tud_audio_n_clear_ep_out_ff(0); } TU_ATTR_ALWAYS_INLINE static inline tu_fifo_t* tud_audio_get_ep_out_ff(void) { return tud_audio_n_get_ep_out_ff(0); } #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN TU_ATTR_ALWAYS_INLINE static inline uint16_t tud_audio_write(const void * data, uint16_t len) { return tud_audio_n_write(0, data, len); } TU_ATTR_ALWAYS_INLINE static inline bool tud_audio_clear_ep_in_ff(void) { return tud_audio_n_clear_ep_in_ff(0); } TU_ATTR_ALWAYS_INLINE static inline tu_fifo_t* tud_audio_get_ep_in_ff(void) { return tud_audio_n_get_ep_in_ff(0); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tud_audio_get_ep_in_fifo_threshold(void) { return tud_audio_n_get_ep_in_fifo_threshold(0); } TU_ATTR_ALWAYS_INLINE static inline void tud_audio_set_ep_in_fifo_threshold(uint16_t threshold) { tud_audio_n_set_ep_in_fifo_threshold(0, threshold); } #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP TU_ATTR_ALWAYS_INLINE static inline bool tud_audio_int_write(const audio_interrupt_data_t * data) { return tud_audio_int_n_write(0, data); } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP TU_ATTR_ALWAYS_INLINE static inline bool tud_audio_fb_set(uint32_t feedback) { return tud_audio_n_fb_set(0, feedback); } #endif //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void audiod_init (void); bool audiod_deinit (void); void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); bool audiod_xfer_isr (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); void audiod_sof_isr (uint8_t rhport, uint32_t frame_count); #ifdef __cplusplus } #endif #endif /* TUSB_AUDIO_DEVICE_H_ */ /** @} */ /** @} */ ================================================ FILE: src/class/bth/bth_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_BTH) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "bth_device.h" #include //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t itf_num; uint8_t ep_ev; uint8_t ep_acl_in; uint16_t ep_acl_in_pkt_sz; uint8_t ep_acl_out; uint8_t ep_voice[2];// Not used yet uint8_t ep_voice_size[2][CFG_TUD_BTH_ISO_ALT_COUNT]; // Previous amount of bytes sent when issuing ZLP uint32_t prev_xferred_bytes; } btd_interface_t; typedef struct { TUD_EPBUF_DEF(epout_buf, CFG_TUD_BTH_DATA_EPSIZE); TUD_EPBUF_TYPE_DEF(bt_hci_cmd_t, hci_cmd); } btd_epbuf_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static btd_interface_t _btd_itf; CFG_TUD_MEM_SECTION static btd_epbuf_t _btd_epbuf; static bool bt_tx_data(uint8_t ep, void *data, uint16_t len) { uint8_t const rhport = 0; // skip if previous transfer not complete TU_VERIFY(!usbd_edpt_busy(rhport, ep)); TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len, false)); return true; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_bt_hci_cmd_cb(void *hci_cmd, size_t cmd_len) { (void) hci_cmd; (void) cmd_len; } TU_ATTR_WEAK void tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len) { (void) acl_data; (void) data_len; } TU_ATTR_WEAK void tud_bt_event_sent_cb(uint16_t sent_bytes) { (void) sent_bytes; } TU_ATTR_WEAK void tud_bt_acl_data_sent_cb(uint16_t sent_bytes) { (void) sent_bytes; } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ bool tud_bt_event_send(void *event, uint16_t event_len) { return bt_tx_data(_btd_itf.ep_ev, event, event_len); } bool tud_bt_acl_data_send(void *event, uint16_t event_len) { return bt_tx_data(_btd_itf.ep_acl_in, event, event_len); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void btd_init(void) { tu_memclr(&_btd_itf, sizeof(_btd_itf)); } bool btd_deinit(void) { return true; } void btd_reset(uint8_t rhport) { (void) rhport; } uint16_t btd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { tusb_desc_endpoint_t const *desc_ep; uint16_t drv_len = 0; // Size of single alternative of ISO interface const uint16_t iso_alt_itf_size = sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t); // Size of hci interface const uint16_t hci_itf_size = sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t); // Ensure this is BT Primary Controller TU_VERIFY(TUSB_CLASS_WIRELESS_CONTROLLER == itf_desc->bInterfaceClass && TUD_BT_APP_SUBCLASS == itf_desc->bInterfaceSubClass && TUD_BT_PROTOCOL_PRIMARY_CONTROLLER == itf_desc->bInterfaceProtocol, 0); TU_ASSERT(itf_desc->bNumEndpoints == 3 && max_len >= hci_itf_size); _btd_itf.itf_num = itf_desc->bInterfaceNumber; desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); _btd_itf.ep_ev = desc_ep->bEndpointAddress; desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); // Open endpoint pair TU_ASSERT(usbd_open_edpt_pair(rhport, (uint8_t const *) desc_ep, 2, TUSB_XFER_BULK, &_btd_itf.ep_acl_out, &_btd_itf.ep_acl_in), 0); // Save acl in endpoint max packet size tusb_desc_endpoint_t const *desc_ep_acl_in = desc_ep; for (size_t p = 0; p < 2; p++) { if (tu_edpt_dir(desc_ep_acl_in->bEndpointAddress) == TUSB_DIR_IN) { _btd_itf.ep_acl_in_pkt_sz = tu_edpt_packet_size(desc_ep_acl_in); break; } desc_ep_acl_in = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep_acl_in); } itf_desc = (tusb_desc_interface_t const *) tu_desc_next(tu_desc_next(desc_ep)); // Prepare for incoming data from host TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE, false), 0); drv_len = hci_itf_size; // Ensure this is still BT Primary Controller TU_ASSERT(TUSB_CLASS_WIRELESS_CONTROLLER == itf_desc->bInterfaceClass && TUD_BT_APP_SUBCLASS == itf_desc->bInterfaceSubClass && TUD_BT_PROTOCOL_PRIMARY_CONTROLLER == itf_desc->bInterfaceProtocol, 0); TU_ASSERT(itf_desc->bNumEndpoints == 2 && max_len >= iso_alt_itf_size + drv_len); uint8_t dir; desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); TU_ASSERT(itf_desc->bAlternateSetting < CFG_TUD_BTH_ISO_ALT_COUNT, 0); TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT, 0); dir = tu_edpt_dir(desc_ep->bEndpointAddress); _btd_itf.ep_voice[dir] = desc_ep->bEndpointAddress; // Store endpoint size for alternative _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT, 0); dir = tu_edpt_dir(desc_ep->bEndpointAddress); _btd_itf.ep_voice[dir] = desc_ep->bEndpointAddress; // Store endpoint size for alternative _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); drv_len += iso_alt_itf_size; for (int i = 1; i < CFG_TUD_BTH_ISO_ALT_COUNT && drv_len + iso_alt_itf_size <= max_len; ++i) { // Make sure rest of alternatives matches itf_desc = (tusb_desc_interface_t const *) tu_desc_next(desc_ep); if (itf_desc->bDescriptorType != TUSB_DESC_INTERFACE || TUSB_CLASS_WIRELESS_CONTROLLER != itf_desc->bInterfaceClass || TUD_BT_APP_SUBCLASS != itf_desc->bInterfaceSubClass || TUD_BT_PROTOCOL_PRIMARY_CONTROLLER != itf_desc->bInterfaceProtocol) { // Not an Iso interface instance break; } TU_ASSERT(itf_desc->bAlternateSetting < CFG_TUD_BTH_ISO_ALT_COUNT, 0); desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); dir = tu_edpt_dir(desc_ep->bEndpointAddress); // Verify that alternative endpoint are same as first ones TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT && _btd_itf.ep_voice[dir] == desc_ep->bEndpointAddress, 0); _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); dir = tu_edpt_dir(desc_ep->bEndpointAddress); // Verify that alternative endpoint are same as first ones TU_ASSERT(desc_ep->bDescriptorType == TUSB_DESC_ENDPOINT && _btd_itf.ep_voice[dir] == desc_ep->bEndpointAddress, 0); _btd_itf.ep_voice_size[dir][itf_desc->bAlternateSetting] = (uint8_t) tu_edpt_packet_size(desc_ep); drv_len += iso_alt_itf_size; } return drv_len; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { (void) rhport; if (stage == CONTROL_STAGE_SETUP) { if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE) { // HCI command packet addressing for single function Primary Controllers // also compatible with historical mode if enabled TU_VERIFY((request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0) || (CFG_TUD_BTH_HISTORICAL_COMPATIBLE && request->bRequest == 0xe0)); } else if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) { if (request->bRequest == TUSB_REQ_SET_INTERFACE && _btd_itf.itf_num + 1 == request->wIndex) { // TODO: Set interface it would involve changing size of endpoint size } else { // HCI command packet for Primary Controller function in a composite device TU_VERIFY(request->bRequest == 0 && request->wValue == 0 && request->wIndex == _btd_itf.itf_num); } } else return false; return tud_control_xfer(rhport, request, &_btd_epbuf.hci_cmd, sizeof(bt_hci_cmd_t)); } else if (stage == CONTROL_STAGE_DATA) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); tud_bt_hci_cmd_cb(&_btd_epbuf.hci_cmd, tu_min16(request->wLength, sizeof(bt_hci_cmd_t))); } return true; } bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { // received new data from host if (ep_addr == _btd_itf.ep_acl_out) { tud_bt_acl_data_received_cb(_btd_epbuf.epout_buf, xferred_bytes); // prepare for next data TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE, false)); } else if (ep_addr == _btd_itf.ep_ev) { tud_bt_event_sent_cb((uint16_t) xferred_bytes); } else if (ep_addr == _btd_itf.ep_acl_in) { if ((result == XFER_RESULT_SUCCESS) && (xferred_bytes > 0) && ((xferred_bytes & (_btd_itf.ep_acl_in_pkt_sz - 1)) == 0)) { // Save number of transferred bytes _btd_itf.prev_xferred_bytes = xferred_bytes; // Send zero-length packet tud_bt_acl_data_send(NULL, 0); } else { if (xferred_bytes == 0) { xferred_bytes = _btd_itf.prev_xferred_bytes; _btd_itf.prev_xferred_bytes = 0; } tud_bt_acl_data_sent_cb((uint16_t) xferred_bytes); } } return true; } #endif ================================================ FILE: src/class/bth/bth_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_BTH_DEVICE_H_ #define TUSB_BTH_DEVICE_H_ #include #include //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_BTH_EVENT_EPSIZE #define CFG_TUD_BTH_EVENT_EPSIZE 16 #endif #ifndef CFG_TUD_BTH_DATA_EPSIZE #define CFG_TUD_BTH_DATA_EPSIZE 64 #endif // Allow BTH class to work in historically compatibility mode where the bRequest is always 0xe0. // See Bluetooth Core v5.3, Vol. 4, Part B, Section 2.2 #ifndef CFG_TUD_BTH_HISTORICAL_COMPATIBLE #define CFG_TUD_BTH_HISTORICAL_COMPATIBLE 0 #endif typedef struct TU_ATTR_PACKED { uint16_t op_code; uint8_t param_length; uint8_t param[255]; } bt_hci_cmd_t; #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when HCI command was received over USB from Bluetooth host. // Detailed format is described in Bluetooth core specification Vol 2, // Part E, 5.4.1. // Length of the command is from 3 bytes (2 bytes for OpCode, // 1 byte for parameter total length) to 258. void tud_bt_hci_cmd_cb(void *hci_cmd, size_t cmd_len); // Invoked when ACL data was received over USB from Bluetooth host. // Detailed format is described in Bluetooth core specification Vol 2, // Part E, 5.4.2. // Length is from 4 bytes, (12 bits for Handle, 4 bits for flags // and 16 bits for data total length) to endpoint size. void tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len); // Called when event sent with tud_bt_event_send() was delivered to BT stack. // Controller can release/reuse buffer with Event packet at this point. void tud_bt_event_sent_cb(uint16_t sent_bytes); // Called when ACL data that was sent with tud_bt_acl_data_send() // was delivered to BT stack. // Controller can release/reuse buffer with ACL packet at this point. void tud_bt_acl_data_sent_cb(uint16_t sent_bytes); // Bluetooth controller calls this function when it wants to send even packet // as described in Bluetooth core specification Vol 2, Part E, 5.4.4. // Event has at least 2 bytes, first is Event code second contains parameter // total length. Controller can release/reuse event memory after // tud_bt_event_sent_cb() is called. bool tud_bt_event_send(void *event, uint16_t event_len); // Bluetooth controller calls this to send ACL data packet // as described in Bluetooth core specification Vol 2, Part E, 5.4.2 // Minimum length is 4 bytes, (12 bits for Handle, 4 bits for flags // and 16 bits for data total length). Upper limit is not limited // to endpoint size since buffer is allocate by controller // and must not be reused till tud_bt_acl_data_sent_cb() is called. bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void btd_init (void); bool btd_deinit (void); void btd_reset (uint8_t rhport); uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request); bool btd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif /* TUSB_BTH_DEVICE_H_ */ ================================================ FILE: src/class/cdc/cdc.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /** \ingroup group_class * \defgroup ClassDriver_CDC Communication Device Class (CDC) * Currently only Abstract Control Model subclass is supported * @{ */ #ifndef TUSB_CDC_H__ #define TUSB_CDC_H__ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif /** \defgroup ClassDriver_CDC_Common Common Definitions * @{ */ //--------------------------------------------------------------------+ // CDC Communication Interface Class //--------------------------------------------------------------------+ /// Communication Interface Subclass Codes typedef enum { CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2] CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL = 0x02 , ///< Abstract Control Model [USBPSTN1.2] CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL = 0x03 , ///< Telephone Control Model [USBPSTN1.2] CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL = 0x04 , ///< Multi-Channel Control Model [USBISDN1.2] CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL = 0x05 , ///< CAPI Control Model [USBISDN1.2] CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL = 0x06 , ///< Ethernet Networking Control Model [USBECM1.2] CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL = 0x07 , ///< ATM Networking Control Model [USBATM1.2] CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL = 0x08 , ///< Wireless Handset Control Model [USBWMC1.1] CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT = 0x09 , ///< Device Management [USBWMC1.1] CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL = 0x0A , ///< Mobile Direct Line Model [USBWMC1.1] CDC_COMM_SUBCLASS_OBEX = 0x0B , ///< OBEX [USBWMC1.1] CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL = 0x0C , ///< Ethernet Emulation Model [USBEEM1.0] CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL = 0x0D ///< Network Control Model [USBNCM1.0] } cdc_comm_sublcass_type_t; /// Communication Interface Protocol Codes typedef enum { CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol CDC_COMM_PROTOCOL_ATCOMMAND = 0x01 , ///< AT Commands: V.250 etc CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 = 0x02 , ///< AT Commands defined by PCCA-101 CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO = 0x03 , ///< AT Commands defined by PCCA-101 & Annex O CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 = 0x04 , ///< AT Commands defined by GSM 07.07 CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 = 0x05 , ///< AT Commands defined by 3GPP 27.007 CDC_COMM_PROTOCOL_ATCOMMAND_CDMA = 0x06 , ///< AT Commands defined by TIA for CDMA CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL = 0x07 ///< Ethernet Emulation Model } cdc_comm_protocol_type_t; //------------- SubType Descriptor in COMM Functional Descriptor -------------// /// Communication Interface SubType Descriptor typedef enum { CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor. CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor. CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor. CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor. CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor. CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 , ///< OBEX Service Identifier Functional Descriptor CDC_FUNC_DESC_NCM = 0x1A , ///< NCM Functional Descriptor }cdc_func_desc_type_t; //--------------------------------------------------------------------+ // CDC Data Interface Class //--------------------------------------------------------------------+ // SUBCLASS code of Data Interface is not used and should/must be zero // Data Interface Protocol Codes typedef enum{ CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931 CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack. CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface }cdc_data_protocol_type_t; //--------------------------------------------------------------------+ // Management Element Request (Control Endpoint) //--------------------------------------------------------------------+ /// Communication Interface Management Element Request Codes typedef enum { CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. CDC_REQUEST_SET_COMM_FEATURE = 0x02, CDC_REQUEST_GET_COMM_FEATURE = 0x03, CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04, CDC_REQUEST_SET_AUX_LINE_STATE = 0x10, CDC_REQUEST_SET_HOOK_STATE = 0x11, CDC_REQUEST_PULSE_SETUP = 0x12, CDC_REQUEST_SEND_PULSE = 0x13, CDC_REQUEST_SET_PULSE_TIME = 0x14, CDC_REQUEST_RING_AUX_JACK = 0x15, CDC_REQUEST_SET_LINE_CODING = 0x20, CDC_REQUEST_GET_LINE_CODING = 0x21, CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22, CDC_REQUEST_SEND_BREAK = 0x23, CDC_REQUEST_SET_RINGER_PARMS = 0x30, CDC_REQUEST_GET_RINGER_PARMS = 0x31, CDC_REQUEST_SET_OPERATION_PARMS = 0x32, CDC_REQUEST_GET_OPERATION_PARMS = 0x33, CDC_REQUEST_SET_LINE_PARMS = 0x34, CDC_REQUEST_GET_LINE_PARMS = 0x35, CDC_REQUEST_DIAL_DIGITS = 0x36, CDC_REQUEST_SET_UNIT_PARAMETER = 0x37, CDC_REQUEST_GET_UNIT_PARAMETER = 0x38, CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39, CDC_REQUEST_GET_PROFILE = 0x3A, CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40, CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43, CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44, CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50, CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51, CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52, CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53, CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, } cdc_management_request_t; typedef enum { CDC_CONTROL_LINE_STATE_DTR = 0x01, CDC_CONTROL_LINE_STATE_RTS = 0x02, } cdc_control_line_state_t; typedef enum { CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits } cdc_line_coding_stopbits_t; #define CDC_LINE_CODING_STOP_BITS_TEXT(STOP_BITS) ( \ (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \ (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \ (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?" ) // TODO Backward compatible for typos. Maybe removed in the future release #define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 #define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5 #define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2 typedef enum { CDC_LINE_CODING_PARITY_NONE = 0, CDC_LINE_CODING_PARITY_ODD = 1, CDC_LINE_CODING_PARITY_EVEN = 2, CDC_LINE_CODING_PARITY_MARK = 3, CDC_LINE_CODING_PARITY_SPACE = 4, } cdc_line_coding_parity_t; #define CDC_LINE_CODING_PARITY_CHAR(PARITY) ( \ (PARITY) == CDC_LINE_CODING_PARITY_NONE ? 'N' : \ (PARITY) == CDC_LINE_CODING_PARITY_ODD ? 'O' : \ (PARITY) == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \ (PARITY) == CDC_LINE_CODING_PARITY_MARK ? 'M' : \ (PARITY) == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?' ) //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ #define CDC_REQ_TYPE_NOTIF 0xA1 ///< Direction IN; Type Class; Recipient Interface /// 6.3 Notification Codes typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, // notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, // notify the host that a response is available. CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, CDC_NOTIF_RING_DETECT = 0x09, CDC_NOTIF_SERIAL_STATE = 0x20, CDC_NOTIF_CALL_STATE_CHANGE = 0x28, CDC_NOTIF_LINE_STATE_CHANGE = 0x29, CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, // notify the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred CDC_NOTIF_MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40, } cdc_notify_request_t; //--------------------------------------------------------------------+ // Class Specific Functional Descriptor (Communication Interface) //--------------------------------------------------------------------+ // Start of all packed definitions for compiler without per-type packed TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN /// Header Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_ uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal }cdc_desc_func_header_t; /// Union Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ uint8_t bControlInterface ; ///< Interface number of Communication Interface uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface }cdc_desc_func_union_t; #define cdc_desc_func_union_n_t(no_slave)\ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ uint8_t bDescriptorSubType ;\ uint8_t bControlInterface ;\ uint8_t bSubordinateInterface[no_slave] ;\ } /// Country Selection Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes. uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. } cdc_desc_func_country_selection_t; #define cdc_desc_func_country_selection_n_t(no_country) \ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ uint8_t bDescriptorSubType ;\ uint8_t iCountryCodeRelDate ;\ uint16_t wCountryCode[no_country] ;\ } //--------------------------------------------------------------------+ // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS //--------------------------------------------------------------------+ /// \brief Call Management Functional Descriptor /// \details This functional descriptor describes the processing of calls for the Communications Class interface. typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ struct { uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface. uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself. uint8_t TU_RESERVED : 6; } bmCapabilities; uint8_t bDataInterface; }cdc_desc_func_call_management_t; typedef struct TU_ATTR_PACKED { uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State. uint8_t support_send_break : 1; ///< Device supports the request Send_Break uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection. uint8_t TU_RESERVED : 4; }cdc_acm_capability_t; TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); /// Abstract Control Management Functional Descriptor /// This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ cdc_acm_capability_t bmCapabilities ; }cdc_desc_func_acm_t; /// \brief Direct Line Management Functional Descriptor /// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ struct { uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit. uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State. uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time. uint8_t TU_RESERVED : 5; } bmCapabilities; }cdc_desc_func_direct_line_management_t; /// \brief Telephone Ringer Functional Descriptor /// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface, /// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ uint8_t bRingerVolSteps ; uint8_t bNumRingerPatterns ; }cdc_desc_func_telephone_ringer_t; /// \brief Telephone Operational Modes Functional Descriptor /// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by /// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ struct { uint8_t simple_mode : 1; uint8_t standalone_mode : 1; uint8_t computer_centric_mode : 1; uint8_t TU_RESERVED : 5; } bmCapabilities; }cdc_desc_func_telephone_operational_modes_t; /// \brief Telephone Call and Line State Reporting Capabilities Descriptor /// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a /// telephone device to report optional call and line states. typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ struct { uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states. uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information. uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns. uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line. uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification uint32_t TU_RESERVED0 : 2; uint32_t TU_RESERVED1 : 16; uint32_t TU_RESERVED2 : 8; } bmCapabilities; }cdc_desc_func_telephone_call_state_reporting_capabilities_t; // TODO remove TU_ATTR_ALWAYS_INLINE static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) { return p_desc[2]; } //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { uint32_t bit_rate; uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 } cdc_line_coding_t; TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); typedef union TU_ATTR_PACKED { struct TU_ATTR_PACKED { uint8_t dtr : 1; uint8_t rts : 1; uint8_t : 6; }; uint8_t value; } cdc_line_control_state_t; TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 1, "size is not correct"); //--------------------------------------------------------------------+ // Notifications //--------------------------------------------------------------------+ // PSTN 1.2 section 6.5.4 table 31 typedef union TU_ATTR_PACKED { struct TU_ATTR_PACKED { uint16_t bRxCarrier : 1; // DCD uint16_t bTxCarrier : 1; // DSR uint16_t bBreak : 1; // Break Detected uint16_t bRingSignal : 1; uint16_t bFraming : 1; uint16_t bParity : 1; uint16_t bOverRun : 1; uint16_t : 9; }; struct TU_ATTR_PACKED { uint16_t dcd : 1; uint16_t dsr : 1; uint16_t brk : 1; uint16_t :13; }; uint16_t value; } cdc_notify_uart_state_t; TU_VERIFY_STATIC(sizeof(cdc_notify_uart_state_t) == 2, "size is not correct"); // CDC 1.2 section 6.3.3 table 21 typedef struct TU_ATTR_PACKED { uint32_t upstream_bitrate; uint32_t downstream_bitrate; } cdc_notify_conn_speed_change_t; typedef struct TU_ATTR_PACKED { tusb_control_request_t request; union { cdc_notify_uart_state_t serial_state; cdc_notify_conn_speed_change_t conn_speed_change; }; } cdc_notify_msg_t; TU_VERIFY_STATIC(sizeof(cdc_notify_msg_t) == 16, "size is not correct"); TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END #ifdef __cplusplus } #endif #endif /** @} */ ================================================ FILE: src/class/cdc/cdc_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_CDC) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "cdc_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_CDC_LOG_LEVEL #define CFG_TUD_CDC_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_CDC_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t rhport; uint8_t itf_num; uint8_t ep_notify; uint8_t line_state; // Bit 0: DTR, Bit 1: RTS /*------------- From this point, data is not cleared by bus reset -------------*/ TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; char wanted_char; tu_edpt_stream_t tx_stream; tu_edpt_stream_t rx_stream; uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; } cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) // Skip local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_CDC_RX_EPSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_CDC_TX_EPSIZE); #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); #endif } cdcd_epbuf_t; CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf) { (void)itf; } TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; (void)wanted_char; } TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf) { (void)itf; } TU_ATTR_WEAK void tud_cdc_notify_complete_cb(uint8_t itf) { (void)itf; } TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void)itf; (void)dtr; (void)rts; } TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, const cdc_line_coding_t *p_line_coding) { (void)itf; (void)p_line_coding; } TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { (void)itf; (void)duration_ms; } //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { const cdcd_interface_t *p_cdc = &_cdcd_itf[idx]; if (ep_addr == p_cdc->rx_stream.ep_addr || ep_addr == p_cdc->tx_stream.ep_addr || (ep_addr == p_cdc->ep_notify && ep_addr != 0)) { return idx; } } return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_cdc_n_ready(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->tx_stream); const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->rx_stream); return in_opened && out_opened; } bool tud_cdc_n_connected(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); // DTR (bit 0) active is considered as connected return tu_bit_test(_cdcd_itf[itf].line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); return _cdcd_itf[itf].line_state; } void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { TU_VERIFY(itf < CFG_TUD_CDC, ); (*coding) = _cdcd_itf[itf].line_coding; } #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg) { TU_VERIFY(itf < CFG_TUD_CDC); const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); #if CFG_TUD_EDPT_DEDICATED_HWFIFO cdc_notify_msg_t *msg_epbuf = msg; #else cdc_notify_msg_t *msg_epbuf = &_cdcd_epbuf[itf].epnotify; *msg_epbuf = *msg; #endif msg_epbuf->request.wIndex = p_cdc->itf_num; return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)msg_epbuf, 8 + msg_epbuf->request.wLength, false); } #endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { TU_VERIFY(itf < CFG_TUD_CDC, ); _cdcd_itf[itf].wanted_char = wanted; } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); return tu_edpt_stream_read_available(&_cdcd_itf[itf].rx_stream); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; return tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize); } bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { TU_VERIFY(itf < CFG_TUD_CDC); return tu_edpt_stream_peek(&_cdcd_itf[itf].rx_stream, chr); } void tud_cdc_n_read_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, ); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; tu_edpt_stream_clear(&p_cdc->rx_stream); tu_edpt_stream_read_xfer(&p_cdc->rx_stream); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; return tu_edpt_stream_write(&p_cdc->tx_stream, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; return tu_edpt_stream_write_xfer(&p_cdc->tx_stream); } uint32_t tud_cdc_n_write_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; return tu_edpt_stream_write_available(&p_cdc->tx_stream); } bool tud_cdc_n_write_clear(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; tu_edpt_stream_clear(&p_cdc->tx_stream); return true; } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t *p_cdc = &_cdcd_itf[i]; p_cdc->wanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 p_cdc->line_coding.bit_rate = 115200; p_cdc->line_coding.stop_bits = 0; p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; #if CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *epout_buf = NULL; uint8_t *epin_buf = NULL; #else uint8_t *epout_buf = _cdcd_epbuf[i].epout; uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable tu_edpt_stream_init(&p_cdc->tx_stream, false, true, CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED, p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf); } } bool cdcd_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_edpt_stream_deinit(&p_cdc->rx_stream); tu_edpt_stream_deinit(&p_cdc->tx_stream); } return true; } void cdcd_reset(uint8_t rhport) { (void) rhport; for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED); // back to default tu_edpt_stream_close(&p_cdc->rx_stream); tu_edpt_stream_close(&p_cdc->tx_stream); } } uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY(TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); const uint8_t cdc_id = find_cdc_itf(0); // Find available interface TU_ASSERT(cdc_id < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[cdc_id]; //------------- Control Interface -------------// p_cdc->rhport = rhport; p_cdc->itf_num = itf_desc->bInterfaceNumber; const uint8_t *p_desc = (const uint8_t *)itf_desc; const uint8_t *desc_end = p_desc + max_len; // Skip all class-specific descriptor p_desc = tu_desc_next(itf_desc); while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); } // notification endpoint (optional) if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notify = desc_ep->bEndpointAddress; p_desc = tu_desc_next(p_desc); } //------------- Data Interface (optional) -------------// if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { const tusb_desc_interface_t *data_itf_desc = (const tusb_desc_interface_t *)p_desc; if (TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass) { for (uint8_t e = 0; e < data_itf_desc->bNumEndpoints; e++) { if (!tu_desc_in_bounds(p_desc, desc_end)) { break; } p_desc = tu_desc_next(p_desc); const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE); #if CFG_TUD_CDC_TX_PERSISTENT tu_edpt_stream_write_xfer(stream_tx); // flush pending data #else tu_edpt_stream_clear(stream_tx); #endif } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; #if CFG_TUD_CDC_RX_NEED_ZLP const uint16_t xfer_len = CFG_TUD_CDC_RX_EPSIZE; #else const uint16_t xfer_len = tu_edpt_packet_size(desc_ep); #endif tu_edpt_stream_open(stream_rx, rhport, desc_ep, xfer_len); #if !CFG_TUD_CDC_RX_PERSISTENT tu_edpt_stream_clear(stream_rx); #endif TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data } } p_desc = tu_desc_next(p_desc); } } return (uint16_t)(p_desc - (const uint8_t *)itf_desc); } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); uint8_t itf; cdcd_interface_t* p_cdc; // Identify which interface to use for (itf = 0; itf < CFG_TUD_CDC; itf++) { p_cdc = &_cdcd_itf[itf]; if (p_cdc->itf_num == request->wIndex) { break; } } TU_VERIFY(itf < CFG_TUD_CDC); switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if (stage == CONTROL_STAGE_ACK) { tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); } else { // nothing to do } break; case CDC_REQUEST_GET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Get Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { // CDC PSTN v1.2 section 6.3.12 // Bit 0: Indicates if DTE is present or not. // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready) // Bit 1: Carrier control for half-duplex modems. // This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send) bool const dtr = tu_bit_test(request->wValue, 0); bool const rts = tu_bit_test(request->wValue, 1); p_cdc->line_state = (uint8_t) request->wValue; // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa #if CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED const bool is_overwritable = !dtr; #else const bool is_overwritable = false; #endif tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, is_overwritable); TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback } else { // nothing to do } break; case CDC_REQUEST_SEND_BREAK: if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); tud_cdc_send_break_cb(itf, request->wValue); } else { // nothing to do } break; default: return false; // stall unsupported request } return true; } bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; uint8_t itf = find_cdc_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_CDC); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; // Received new data, move to fifo if (ep_addr == stream_rx->ep_addr) { tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); // Check for wanted char and invoke wanted callback if (((signed char)p_cdc->wanted_char) != -1) { tu_fifo_buffer_info_t buf_info; tu_fifo_get_read_info(&stream_rx->ff, &buf_info); // find backward uint8_t *ptr; if (buf_info.wrapped.len > 0) { ptr = buf_info.wrapped.ptr + buf_info.wrapped.len - 1; // last byte of wrap buffer } else if (buf_info.linear.len > 0) { ptr = buf_info.linear.ptr + buf_info.linear.len - 1; // last byte of linear buffer } else { ptr = NULL; // no data } if (ptr != NULL) { for (uint32_t i = 0; i < xferred_bytes; i++) { if (p_cdc->wanted_char == (char)*ptr) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); break; // only invoke once per transfer, even if multiple wanted chars are present } if (ptr == buf_info.wrapped.ptr) { ptr = buf_info.linear.ptr + buf_info.linear.len - 1; // last byte of linear buffer } else if (ptr == buf_info.linear.ptr) { break; // reached the beginning } else { ptr--; } } } } // invoke receive callback if there is still data if (!tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_cb(itf); } tu_edpt_stream_read_xfer(stream_rx); // prepare for more data } // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. Though maybe the baudrate is not really important! if (ep_addr == stream_tx->ep_addr) { tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo if (0 == tu_edpt_stream_write_xfer(stream_tx)) { // If there is no data left, a ZLP should be sent if needed tu_edpt_stream_write_zlp_if_needed(stream_tx, xferred_bytes); } } // Sent notification to host if (ep_addr == p_cdc->ep_notify) { tud_cdc_notify_complete_cb(itf); } return true; } #endif ================================================ FILE: src/class/cdc/cdc_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_CDC_DEVICE_H_ #define TUSB_CDC_DEVICE_H_ #include "cdc.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_CDC_NOTIFY #define CFG_TUD_CDC_NOTIFY 0 #endif #ifndef CFG_TUD_CDC_TX_BUFSIZE #define CFG_TUD_CDC_TX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif #ifndef CFG_TUD_CDC_RX_BUFSIZE #define CFG_TUD_CDC_RX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif // EP_BUFSIZE is separated to RX_EPSIZE and TX_EPSIZE #ifndef CFG_TUD_CDC_RX_EPSIZE #ifdef CFG_TUD_CDC_EP_BUFSIZE #define CFG_TUD_CDC_RX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE #else #define CFG_TUD_CDC_RX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif #ifndef CFG_TUD_CDC_TX_EPSIZE #ifdef CFG_TUD_CDC_EP_BUFSIZE #define CFG_TUD_CDC_TX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE #else #define CFG_TUD_CDC_TX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif // Enable multi-packet RX transfer with ZLP termination for better throughput. Requires host support for ZLP. #ifndef CFG_TUD_CDC_RX_NEED_ZLP #define CFG_TUD_CDC_RX_NEED_ZLP 0 #endif // Keep rx fifo data even with bus reset or disconnect #ifndef CFG_TUD_CDC_RX_PERSISTENT #define CFG_TUD_CDC_RX_PERSISTENT 0 #endif // Keep tx fifo data even with bus reset or disconnect #ifndef CFG_TUD_CDC_TX_PERSISTENT #define CFG_TUD_CDC_TX_PERSISTENT 0 #endif // If not connected, tx fifo can be overwritten #ifndef CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED #define CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED 1 #endif // Backward compatible: tud_cdc_configure_t and tud_cdc_configure() are no longer used. // Configuration is now done via compile-time macros above. typedef struct { bool rx_persistent; bool tx_persistent; bool tx_overwritabe_if_not_connected; } tud_cdc_configure_t; #define tud_cdc_configure(_cfg) ((void)(_cfg)) #define tud_cdc_configure_fifo_t tud_cdc_configure_t #define tud_cdc_configure_fifo(_cfg) ((void)(_cfg)) //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if the interface is ready bool tud_cdc_n_ready(uint8_t itf); // Check if the terminal is connected to this port bool tud_cdc_n_connected(uint8_t itf); // Get the current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) uint8_t tud_cdc_n_get_line_state(uint8_t itf); // Get current line encoding: bit rate, stop bits parity etc .. void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding); // Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted); // Get the number of bytes available for reading uint32_t tud_cdc_n_available(uint8_t itf); // Read received bytes uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize); // Read a byte, return -1 if there is none TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_n_read_char(uint8_t itf) { uint8_t ch; return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; } // Clear the received FIFO void tud_cdc_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it bool tud_cdc_n_peek(uint8_t itf, uint8_t* ui8); // Write bytes to TX FIFO, data may remain in the FIFO for a while uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize); // Write a byte TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) { return tud_cdc_n_write(itf, &ch, 1); } // Write a null-terminated string TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_str(uint8_t itf, char const* str) { return tud_cdc_n_write(itf, str, strlen(str)); } // Force sending data if possible, return number of forced bytes uint32_t tud_cdc_n_write_flush(uint8_t itf); // Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. uint32_t tud_cdc_n_write_available(uint8_t itf); // Clear the TX FIFO bool tud_cdc_n_write_clear(uint8_t itf); #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg); // Send UART status notification: DCD, DSR etc .. TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_n_notify_uart_state(uint8_t itf, const cdc_notify_uart_state_t *state) { cdc_notify_msg_t notify_msg; notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; notify_msg.request.bRequest = CDC_NOTIF_SERIAL_STATE; notify_msg.request.wValue = 0; notify_msg.request.wIndex = 0; // filled later notify_msg.request.wLength = sizeof(cdc_notify_uart_state_t); notify_msg.serial_state = *state; return tud_cdc_n_notify_msg(itf, ¬ify_msg); } // Send connection speed change notification TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t *conn_speed_change) { cdc_notify_msg_t notify_msg; notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; notify_msg.request.bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE; notify_msg.request.wValue = 0; notify_msg.request.wIndex = 0; // filled later notify_msg.request.wLength = sizeof(cdc_notify_conn_speed_change_t); notify_msg.conn_speed_change = *conn_speed_change; return tud_cdc_n_notify_msg(itf, ¬ify_msg); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_msg(cdc_notify_msg_t *msg) { return tud_cdc_n_notify_msg(0, msg); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_uart_state(const cdc_notify_uart_state_t* state) { return tud_cdc_n_notify_uart_state(0, state); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_conn_speed_change(const cdc_notify_conn_speed_change_t* conn_speed_change) { return tud_cdc_n_notify_conn_speed_change(0, conn_speed_change); } #endif //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_ready(void) { return tud_cdc_n_ready(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_cdc_get_line_state(void) { return tud_cdc_n_get_line_state(0); } TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) { tud_cdc_n_get_line_coding(0, coding); } TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_wanted_char(char wanted) { tud_cdc_n_set_wanted_char(0, wanted); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_available(void) { return tud_cdc_n_available(0); } TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_read_char(void) { return tud_cdc_n_read_char(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_read(void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_read_flush(void) { tud_cdc_n_read_flush(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_peek(uint8_t* ui8) { return tud_cdc_n_peek(0, ui8); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_char(char ch) { return tud_cdc_n_write_char(0, ch); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write(void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_str(char const* str) { return tud_cdc_n_write_str(0, str); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_flush(void) { return tud_cdc_n_write_flush(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_available(void) { return tud_cdc_n_write_available(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_write_clear(void) { return tud_cdc_n_write_clear(0); } //--------------------------------------------------------------------+ // Application Callback API //--------------------------------------------------------------------+ // Invoked when received new data void tud_cdc_rx_cb(uint8_t itf); // Invoked when received `wanted_char` void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); // Invoked when a TX is complete and therefore space becomes available in TX buffer void tud_cdc_tx_complete_cb(uint8_t itf); // Invoked when a notification is sent to host void tud_cdc_notify_complete_cb(uint8_t itf); // Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); // Invoked when line coding is change via SET_LINE_CODING void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); // Invoked when received send break // \param[in] itf interface for which send break was received. // \param[in] duration_ms the length of time, in milliseconds, of the break signal. If a value of FFFFh, then the // device will send a break until another SendBreak request is received with value 0000h. void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void cdcd_init (void); bool cdcd_deinit (void); void cdcd_reset (uint8_t rhport); uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif /* TUSB_CDC_DEVICE_H_ */ ================================================ FILE: src/class/cdc/cdc_host.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. * * Contribution * - Heiko Kuester: add support of CH34x & PL2303, improve support of FTDI & CP210x */ #include "tusb_option.h" #include #if (CFG_TUH_ENABLED && CFG_TUH_CDC) #include "host/usbh.h" #include "host/usbh_pvt.h" #include "cdc_host.h" #include "serial/ftdi_sio.h" #include "serial/cp210x.h" #include "serial/ch34x.h" #include "serial/pl2303.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUH_CDC_LOG_LEVEL #define CFG_TUH_CDC_LOG_LEVEL 2 #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__) #define TU_LOG_CDC(_cdc, _format, ...) \ TU_LOG_DRV("[:%u:%u] CDCh %s " _format "\r\n", _cdc->daddr, _cdc->bInterfaceNumber, \ serial_drivers[_cdc->serial_drid].name, ##__VA_ARGS__) //--------------------------------------------------------------------+ // Host CDC Interface //--------------------------------------------------------------------+ typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; uint8_t ep_notif; uint8_t serial_drid; // Serial Driver ID bool mounted; // Enumeration is complete struct { TU_ATTR_ALIGNED(4) cdc_line_coding_t coding; // Baudrate, stop bits, parity, data width cdc_line_control_state_t control_state; // DTR, RTS } line, requested_line; tuh_xfer_cb_t user_complete_cb; // required since we handle request internally first union { struct { cdc_acm_capability_t capability; } acm; #if CFG_TUH_CDC_FTDI ftdi_private_t ftdi; #endif #if CFG_TUH_CDC_PL2303 pl2303_private_t pl2303; #endif }; struct { tu_edpt_stream_t tx; tu_edpt_stream_t rx; uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; uint8_t rx_ff_buf[CFG_TUH_CDC_RX_BUFSIZE]; } stream; } cdch_interface_t; typedef struct { TUH_EPBUF_DEF(tx, CFG_TUH_CDC_TX_EPSIZE); TUH_EPBUF_DEF(rx, CFG_TUH_CDC_RX_EPSIZE); } cdch_epbuf_t; static cdch_interface_t cdch_data[CFG_TUH_CDC]; CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC]; //--------------------------------------------------------------------+ // Serial Driver //--------------------------------------------------------------------+ // General driver static void cdch_process_set_config(tuh_xfer_t *xfer); static void cdch_process_line_state_on_enum(tuh_xfer_t *xfer); // invoked after set config is processed static void cdch_internal_control_complete(tuh_xfer_t *xfer); static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer); static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer); //------------- ACM prototypes -------------// static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //------------- FTDI prototypes -------------// #if CFG_TUH_CDC_FTDI static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static bool ftdi_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void ftdi_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CP210X prototypes -------------// #if CFG_TUH_CDC_CP210X static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool cp210x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CH34x prototypes -------------// #if CFG_TUH_CDC_CH34X static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ch34x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- PL2303 prototypes -------------// #if CFG_TUH_CDC_PL2303 static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIST}; static const pl2303_type_data_t pl2303_type_data[PL2303_TYPE_COUNT] = {PL2303_TYPE_DATA}; static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- Common -------------// enum { SERIAL_DRIVER_ACM = 0, #if CFG_TUH_CDC_FTDI SERIAL_DRIVER_FTDI, #endif #if CFG_TUH_CDC_CP210X SERIAL_DRIVER_CP210X, #endif #if CFG_TUH_CDC_CH34X SERIAL_DRIVER_CH34X, #endif #if CFG_TUH_CDC_PL2303 SERIAL_DRIVER_PL2303, #endif SERIAL_DRIVER_COUNT }; typedef bool (*serial_driver_func_t)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data); typedef struct { const uint16_t (*vid_pid_list)[2]; const uint16_t vid_pid_count; uint16_t (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool (*const process_set_config)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); // internal request complete handler to update line state void (*const request_complete)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer); serial_driver_func_t set_control_line_state, set_baudrate, set_data_format, set_line_coding; #if CFG_TUSB_DEBUG && CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL const char * name; #endif } cdch_serial_driver_t; #if CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL #define DRIVER_NAME_DECLARE(_str) .name = _str #else #define DRIVER_NAME_DECLARE(_str) #endif // clang-format off // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { { .vid_pid_list = NULL, .vid_pid_count = 0, .open = acm_open, .process_set_config = acm_process_set_config, .request_complete = acm_internal_control_complete, .set_control_line_state = acm_set_control_line_state, .set_baudrate = acm_set_line_coding, .set_data_format = acm_set_line_coding, .set_line_coding = acm_set_line_coding, DRIVER_NAME_DECLARE("ACM") }, #if CFG_TUH_CDC_FTDI { .vid_pid_list = ftdi_vid_pid_list, .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), .open = ftdi_open, .process_set_config = ftdi_process_set_config, .request_complete = ftdi_internal_control_complete, .set_control_line_state = ftdi_set_modem_ctrl, .set_baudrate = ftdi_set_baudrate, .set_data_format = ftdi_set_data_format, .set_line_coding = NULL, // 2 stage set line coding DRIVER_NAME_DECLARE("FTDI") }, #endif #if CFG_TUH_CDC_CP210X { .vid_pid_list = cp210x_vid_pid_list, .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), .open = cp210x_open, .process_set_config = cp210x_process_set_config, .request_complete = cp210x_internal_control_complete, .set_control_line_state = cp210x_set_modem_ctrl, .set_baudrate = cp210x_set_baudrate, .set_data_format = cp210x_set_data_format, .set_line_coding = NULL, // 2 stage set line coding DRIVER_NAME_DECLARE("CP210x") }, #endif #if CFG_TUH_CDC_CH34X { .vid_pid_list = ch34x_vid_pid_list, .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), .open = ch34x_open, .process_set_config = ch34x_process_set_config, .request_complete = ch34x_internal_control_complete, .set_control_line_state = ch34x_set_modem_ctrl, .set_baudrate = ch34x_set_baudrate, .set_data_format = ch34x_set_data_format, .set_line_coding = NULL, // 2 stage set line coding DRIVER_NAME_DECLARE("CH34x") }, #endif #if CFG_TUH_CDC_PL2303 { .vid_pid_list = pl2303_vid_pid_list, .vid_pid_count = TU_ARRAY_SIZE(pl2303_vid_pid_list), .open = pl2303_open, .process_set_config = pl2303_process_set_config, .request_complete = pl2303_internal_control_complete, .set_control_line_state = pl2303_set_modem_ctrl, .set_baudrate = pl2303_set_line_coding, .set_data_format = pl2303_set_line_coding, .set_line_coding = pl2303_set_line_coding, DRIVER_NAME_DECLARE("PL2303") } #endif }; // clang-format on TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial driver count mismatch"); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, const tusb_desc_endpoint_t *desc_ep); TU_ATTR_ALWAYS_INLINE static inline cdch_interface_t * get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); cdch_interface_t * p_cdc = &cdch_data[idx]; return (p_cdc->daddr != 0) ? p_cdc : NULL; } TU_ATTR_ALWAYS_INLINE static inline uint8_t get_idx_by_ptr(cdch_interface_t* p_cdc) { return (uint8_t) (p_cdc - cdch_data); } static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { for(uint8_t i=0; idaddr == daddr) && (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) { return i; } } return TUSB_INDEX_INVALID_8; } // determine the interface from the completed transfer static cdch_interface_t* get_itf_by_xfer(const tuh_xfer_t * xfer) { TU_VERIFY(xfer->daddr != 0, NULL); for(uint8_t i=0; idaddr == xfer->daddr) { switch (p_cdc->serial_drid) { #if CFG_TUH_CDC_CP210X case SERIAL_DRIVER_CP210X: #endif case SERIAL_DRIVER_ACM: { // Driver use wIndex for bInterfaceNumber const uint8_t itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); if (p_cdc->bInterfaceNumber == itf_num) { return p_cdc; } break; } #if CFG_TUH_CDC_FTDI case SERIAL_DRIVER_FTDI: { // FTDI uses wIndex for channel number, if channel is 0 then it is the default channel const uint8_t channel = (uint8_t) tu_le16toh(xfer->setup->wIndex); if (p_cdc->ftdi.channel == 0 || p_cdc->ftdi.channel == channel) { return p_cdc; } break; } #endif #if CFG_TUH_CDC_CH34X case SERIAL_DRIVER_CH34X: // ch34x has only one interface return p_cdc; #endif #if CFG_TUH_CDC_PL2303 case SERIAL_DRIVER_PL2303: // pl2303 has only one interface return p_cdc; #endif default: break; // unknown driver } } } return NULL; } static cdch_interface_t * make_new_itf(uint8_t daddr, tusb_desc_interface_t const * itf_desc) { for(uint8_t i=0; idaddr = daddr; p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; p_cdc->line.coding = (cdc_line_coding_t) { 0, 0, 0, 0 }; p_cdc->line.control_state.value = 0; return p_cdc; } } return NULL; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t idx) { (void) idx; } TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t idx) { (void) idx; } TU_ATTR_WEAK void tuh_cdc_rx_cb(uint8_t idx) { (void) idx; } TU_ATTR_WEAK void tuh_cdc_tx_complete_cb(uint8_t idx) { (void) idx; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) { for (uint8_t i = 0; i < CFG_TUH_CDC; i++) { const cdch_interface_t * p_cdc = &cdch_data[i]; if (p_cdc->daddr == daddr && p_cdc->bInterfaceNumber == itf_num) { return i; } } return TUSB_INDEX_INVALID_8; } bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t * info) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc && info); info->daddr = p_cdc->daddr; // re-construct interface descriptor tusb_desc_interface_t * desc = &info->desc; desc->bLength = sizeof(tusb_desc_interface_t); desc->bDescriptorType = TUSB_DESC_INTERFACE; desc->bInterfaceNumber = p_cdc->bInterfaceNumber; desc->bAlternateSetting = 0; desc->bNumEndpoints = 2u + (p_cdc->ep_notif ? 1u : 0u); desc->bInterfaceClass = TUSB_CLASS_CDC; desc->bInterfaceSubClass = p_cdc->bInterfaceSubClass; desc->bInterfaceProtocol = p_cdc->bInterfaceProtocol; desc->iInterface = 0; // not used yet return true; } bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return p_cdc->mounted; } bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t* line_state) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); *line_state = p_cdc->line.control_state.value; return true; } bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t * line_coding) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); *line_coding = p_cdc->line.coding; return true; } //--------------------------------------------------------------------+ // Write //--------------------------------------------------------------------+ uint32_t tuh_cdc_write(uint8_t idx, void const * buffer, uint32_t bufsize) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); tu_edpt_stream_clear(&p_cdc->stream.tx); return true; } uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_write_available(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ // Read //--------------------------------------------------------------------+ uint32_t tuh_cdc_read (uint8_t idx, void * buffer, uint32_t bufsize) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read_available(&p_cdc->stream.rx); } bool tuh_cdc_peek(uint8_t idx, uint8_t * ch) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_peek(&p_cdc->stream.rx, ch); } bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); tu_edpt_stream_clear(&p_cdc->stream.rx); (void)tu_edpt_stream_read_xfer(&p_cdc->stream.rx); return true; } //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); TU_LOG_CDC(p_cdc, "set control line state dtr = %u rts = %u", p_cdc->requested_line.control_state.dtr, p_cdc->requested_line.control_state.rts); const cdch_serial_driver_t * driver = &serial_drivers[p_cdc->serial_drid]; p_cdc->requested_line.control_state.value = (uint8_t) line_state; p_cdc->user_complete_cb = complete_cb; TU_VERIFY(driver->set_control_line_state(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); if (!complete_cb) { // blocking, update line state if request was successful p_cdc->line.control_state.value = (uint8_t) line_state; } return true; } bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t *p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); TU_LOG_CDC(p_cdc, "set baudrate %lu", baudrate); const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; p_cdc->requested_line = p_cdc->line; // keep current line coding p_cdc->requested_line.coding.bit_rate = baudrate; p_cdc->user_complete_cb = complete_cb; TU_VERIFY(driver->set_baudrate(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); if (!complete_cb) { p_cdc->line.coding.bit_rate = baudrate; } return true; } bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t *p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); TU_LOG_CDC(p_cdc, "set data format %u%c%s", data_bits, CDC_LINE_CODING_PARITY_CHAR(parity), CDC_LINE_CODING_STOP_BITS_TEXT(stop_bits)); const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; p_cdc->requested_line = p_cdc->line; // keep current line coding p_cdc->requested_line.coding.stop_bits = stop_bits; p_cdc->requested_line.coding.parity = parity; p_cdc->requested_line.coding.data_bits = data_bits; p_cdc->user_complete_cb = complete_cb; TU_VERIFY(driver->set_data_format(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); if (!complete_cb) { // blocking p_cdc->line.coding.stop_bits = stop_bits; p_cdc->line.coding.parity = parity; p_cdc->line.coding.data_bits = data_bits; } return true; } bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t *p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); TU_LOG_CDC(p_cdc, "set line coding %lu %u%c%s", line_coding->bit_rate, line_coding->data_bits, CDC_LINE_CODING_PARITY_CHAR(line_coding->parity), CDC_LINE_CODING_STOP_BITS_TEXT(line_coding->stop_bits)); cdch_serial_driver_t const *driver = &serial_drivers[p_cdc->serial_drid]; p_cdc->requested_line.coding = *line_coding; p_cdc->user_complete_cb = complete_cb; if (driver->set_line_coding != NULL) { // driver support set_line_coding request TU_VERIFY(driver->set_line_coding(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); if (!complete_cb) { p_cdc->line.coding = *line_coding; } } else { // driver does not support set_line_coding and need 2 stage to set baudrate and data format separately if (complete_cb != NULL) { // non-blocking TU_VERIFY(driver->set_baudrate(p_cdc, cdch_set_line_coding_stage1_baudrate_complete, user_data)); } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_baudrate(p_cdc, NULL, (uintptr_t) &result)); if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; // update baudrate result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_data_format(p_cdc, NULL, (uintptr_t) &result)); if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); p_cdc->line.coding = p_cdc->requested_line.coding; // update data format } } return true; } //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ bool cdch_init(void) { TU_LOG_DRV("sizeof(cdch_interface_t) = %u\r\n", sizeof(cdch_interface_t)); tu_memclr(cdch_data, sizeof(cdch_data)); for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; cdch_epbuf_t *epbuf = &cdch_epbuf[i]; TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, epbuf->tx)); TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx)); } return true; } bool cdch_deinit(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; (void)tu_edpt_stream_deinit(&p_cdc->stream.tx); (void)tu_edpt_stream_deinit(&p_cdc->stream.rx); } return true; } void cdch_close(uint8_t daddr) { for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { cdch_interface_t *p_cdc = &cdch_data[idx]; if (p_cdc->daddr == daddr) { TU_LOG_CDC(p_cdc, "close"); tuh_cdc_umount_cb(idx); // invoke callback p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); tu_edpt_stream_close(&p_cdc->stream.rx); } } } bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { // TODO handle stall response, retry failed transfer ... TU_VERIFY(event == XFER_RESULT_SUCCESS); uint8_t const idx = get_idx_by_ep_addr(daddr, ep_addr); cdch_interface_t *p_cdc = get_itf(idx); TU_ASSERT(p_cdc); if (ep_addr == p_cdc->stream.tx.ep_addr) { tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback if (0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx)) { // If there is no data left, a ZLP should be sent if: // - xferred_bytes is multiple of EP Packet size and not zero (void)tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } } else if (ep_addr == p_cdc->stream.rx.ep_addr) { #if CFG_TUH_CDC_FTDI if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { // FTDI reserve 2 bytes for status // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; if (xferred_bytes > 2) { tu_edpt_stream_read_xfer_complete_with_buf(&p_cdc->stream.rx, p_cdc->stream.rx.ep_buf + 2, xferred_bytes - 2); tuh_cdc_rx_cb(idx); // invoke receive callback } } else #endif { tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); tuh_cdc_rx_cb(idx); // invoke receive callback } // prepare for next transfer if needed tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { return false; } return true; } //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t const *desc_ep) { for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); } return true; } uint16_t cdch_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { (void)rhport; // For CDC: only support ACM subclass // Note: Protocol 0xFF can be RNDIS device if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); } else if (SERIAL_DRIVER_COUNT > 1 && TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid), 0); for (size_t drv = 1; drv < SERIAL_DRIVER_COUNT; drv++) { const cdch_serial_driver_t *driver = &serial_drivers[drv]; for (size_t i = 0; i < driver->vid_pid_count; i++) { if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { const uint16_t drv_len = driver->open(daddr, itf_desc, max_len); TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, drv_len > 0 ? "OK" : "FAILED"); return drv_len; } } } } else { // not supported class } return 0; } static void set_config_complete(cdch_interface_t *p_cdc, bool success) { if (success) { const uint8_t idx = get_idx_by_ptr(p_cdc); p_cdc->mounted = true; tuh_cdc_mount_cb(idx); // Prepare for incoming data tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else { // clear the interface entry p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; } // notify usbh that driver enumeration is complete const uint8_t itf_offset = (p_cdc->serial_drid == SERIAL_DRIVER_ACM) ? 1 : 0; usbh_driver_set_config_complete(p_cdc->daddr, p_cdc->bInterfaceNumber + itf_offset); } bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { const uint8_t idx = tuh_cdc_itf_get_index(daddr, itf_num); cdch_interface_t *p_cdc = get_itf(idx); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); TU_LOG_CDC(p_cdc, "set config"); // fake transfer to kick-off process_set_config() tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t)itf_num); tuh_xfer_t xfer; xfer.daddr = daddr; xfer.ep_addr = 0; xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.complete_cb = NULL; xfer.buffer = NULL; xfer.user_data = 0; // initial state 0 const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; if (!driver->process_set_config(p_cdc, &xfer)) { set_config_complete(p_cdc, false); } return true; } static void cdch_process_set_config(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); TU_LOG_DRV(" state = %u\r\n", xfer->user_data); const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; if (!driver->process_set_config(p_cdc, xfer)) { set_config_complete(p_cdc, false); } } // return false if there is no active transfer static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { enum { ENUM_SET_LINE_CODING = 0, ENUM_SET_LINE_CONTROL, ENUM_SET_LINE_COMPLETE, }; #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM const uint8_t idx = get_idx_by_ptr(p_cdc); #endif const uintptr_t state = xfer->user_data; switch (state) { case ENUM_SET_LINE_CODING: { #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM #if CFG_TUH_CDC_CH34X // ch34x already set line coding in serial init if (p_cdc->serial_drid != SERIAL_DRIVER_CH34X) #endif { const cdc_line_coding_t line_coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM; TU_ASSERT(tuh_cdc_set_line_coding(idx, &line_coding, cdch_process_line_state_on_enum, ENUM_SET_LINE_CONTROL)); break; } #endif TU_ATTR_FALLTHROUGH; } case ENUM_SET_LINE_CONTROL: #ifdef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM TU_ASSERT(tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cdch_process_line_state_on_enum, ENUM_SET_LINE_COMPLETE)); break; #else TU_ATTR_FALLTHROUGH; #endif case ENUM_SET_LINE_COMPLETE: set_config_complete(p_cdc, true); break; default: return false; } return true; } static void cdch_process_line_state_on_enum(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); if (xfer->result != XFER_RESULT_SUCCESS || !set_line_state_on_enum(p_cdc, xfer)) { set_config_complete(p_cdc, false); } } static void cdch_internal_control_complete(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); TU_LOG_DRV(" request result = %u\r\n", xfer->result); const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; driver->request_complete(p_cdc, xfer); // Invoke application callback xfer->complete_cb = p_cdc->user_complete_cb; if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); TU_LOG_DRV(" stage1 set baudrate result = %u\r\n", xfer->result); const cdch_serial_driver_t *driver = &serial_drivers[p_cdc->serial_drid]; if (xfer->result == XFER_RESULT_SUCCESS) { p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; // update baudrate TU_ASSERT(driver->set_data_format(p_cdc, cdch_set_line_coding_stage2_data_format_complete, xfer->user_data),); } else { xfer->complete_cb = p_cdc->user_complete_cb; if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } } static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer) { cdch_interface_t *p_cdc = get_itf_by_xfer(xfer); TU_ASSERT(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT,); TU_LOG_DRV(" stage2 set data format result = %u\r\n", xfer->result); if (xfer->result == XFER_RESULT_SUCCESS) { p_cdc->line.coding = p_cdc->requested_line.coding; // update data format } xfer->complete_cb = p_cdc->user_complete_cb; if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } //--------------------------------------------------------------------+ // ACM //--------------------------------------------------------------------+ // internal control complete to update state such as line state, encoding static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_VERIFY (xfer->result == XFER_RESULT_SUCCESS,); const tusb_control_request_t * setup = xfer->setup; switch (setup->bRequest) { case CDC_REQUEST_SET_CONTROL_LINE_STATE: p_cdc->line.control_state = p_cdc->requested_line.control_state; break; case CDC_REQUEST_SET_LINE_CODING: p_cdc->line.coding = p_cdc->requested_line.coding; break; default: break; // unknown request } } static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); const tusb_control_request_t request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, .wValue = tu_htole16((uint16_t) p_cdc->requested_line.control_state.value), .wIndex = tu_htole16((uint16_t) p_cdc->bInterfaceNumber), .wLength = 0 }; tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); TU_VERIFY((p_cdc->requested_line.coding.data_bits >= 5 && p_cdc->requested_line.coding.data_bits <= 8) || p_cdc->requested_line.coding.data_bits == 16); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = CDC_REQUEST_SET_LINE_CODING, .wValue = 0, .wIndex = tu_htole16((uint16_t) p_cdc->bInterfaceNumber), .wLength = tu_htole16((uint16_t) sizeof(cdc_line_coding_t)) }; // use usbh enum buf to hold line coding since user line_coding variable does not live long enough uint8_t *enum_buf = usbh_get_enum_buf(); memcpy(enum_buf, &p_cdc->requested_line.coding, sizeof(cdc_line_coding_t)); tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request, .buffer = enum_buf, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } //------------- Enumeration -------------// enum { CONFIG_ACM_COMPLETE = 0 }; static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { const uint8_t *p_desc = (const uint8_t *)itf_desc; const uint8_t *desc_end = p_desc + max_len; cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// p_desc = tu_desc_next(p_desc); // Communication Functional Descriptors while ((p_desc < desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) { // save ACM bmCapabilities p_cdc->acm.capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; } p_desc = tu_desc_next(p_desc); } // Open notification endpoint of control interface if any if (itf_desc->bNumEndpoints == 1) { TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { const tusb_desc_interface_t *data_itf = (const tusb_desc_interface_t *)p_desc; if (data_itf->bInterfaceClass == TUSB_CLASS_CDC_DATA) { p_desc = tu_desc_next(p_desc); // next to endpoint descriptor // data endpoints expected to be in pairs TU_ASSERT(open_ep_stream_pair(p_cdc, (const tusb_desc_endpoint_t *)p_desc), 0); p_desc += data_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t); } } return (uint16_t)((uintptr_t)p_desc - (uintptr_t)itf_desc); } static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); (void) p_cdc; const uintptr_t state = xfer->user_data; switch (state) { case CONFIG_ACM_COMPLETE: { xfer->user_data = 0; // kick-off set line state on enum cdch_process_line_state_on_enum(xfer); break; } default: return false; // invalid state } return true; } //--------------------------------------------------------------------+ // FTDI //--------------------------------------------------------------------+ #if CFG_TUH_CDC_FTDI static bool ftdi_determine_type(cdch_interface_t *p_cdc); static uint32_t ftdi_get_divisor(cdch_interface_t *p_cdc); //------------- Control Request -------------// // set request without data static bool ftdi_set_request(cdch_interface_t *p_cdc, uint8_t request, uint8_t requesttype, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { .bmRequestType = requesttype, .bRequest = request, .wValue = tu_htole16(value), .wIndex = tu_htole16(index), .wLength = 0 }; tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request_setup, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } #ifdef CFG_TUH_CDC_FTDI_LATENCY static int8_t ftdi_write_latency_timer(cdch_interface_t * p_cdc, uint16_t latency, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { if (p_cdc->ftdi.chip_type == FTDI_SIO /* || p_cdc->ftdi.chip_type == FT232A */ ) return FTDI_NOT_POSSIBLE; return ftdi_set_request(p_cdc, FTDI_SIO_SET_LATENCY_TIMER_REQUEST, FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, latency, p_cdc->ftdi.channel, complete_cb, user_data) ? FTDI_REQUESTED : FTDI_FAIL; } #endif static inline bool ftdi_sio_reset(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ftdi_set_request(p_cdc, FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, FTDI_SIO_RESET_SIO, p_cdc->ftdi.channel, complete_cb, user_data); } //------------- Driver API -------------// // internal control complete to update state such as line state, line_coding static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer) { const tusb_control_request_t * setup = xfer->setup; if (xfer->result == XFER_RESULT_SUCCESS) { if (setup->bRequest == FTDI_SIO_SET_MODEM_CTRL_REQUEST && setup->bmRequestType == FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE ) { p_cdc->line.control_state = p_cdc->requested_line.control_state; } if (setup->bRequest == FTDI_SIO_SET_DATA_REQUEST && setup->bmRequestType == FTDI_SIO_SET_DATA_REQUEST_TYPE ) { p_cdc->line.coding.stop_bits = p_cdc->requested_line.coding.stop_bits; p_cdc->line.coding.parity = p_cdc->requested_line.coding.parity; p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; } if (setup->bRequest == FTDI_SIO_SET_BAUDRATE_REQUEST && setup->bmRequestType == FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE ) { p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; } } } static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->requested_line.coding.data_bits >= 7 && p_cdc->requested_line.coding.data_bits <= 8, 0); uint16_t value = (uint16_t) ((p_cdc->requested_line.coding.data_bits & 0xfUL) | // data bit quantity is stored in bits 0-3 (p_cdc->requested_line.coding.parity & 0x7UL) << 8 | // parity is stored in bits 8-10, same coding (p_cdc->requested_line.coding.stop_bits & 0x3UL) << 11); // stop bits quantity is stored in bits 11-12, same coding // not each FTDI supports 1.5 stop bits return ftdi_set_request(p_cdc, FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, value, p_cdc->ftdi.channel, complete_cb, user_data); } static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint32_t index_value = ftdi_get_divisor(p_cdc); TU_VERIFY(index_value != 0); uint16_t value = (uint16_t) index_value; uint16_t index = (uint16_t) (index_value >> 16); if (p_cdc->ftdi.channel != 0) { index = (uint16_t) ((index << 8) | p_cdc->ftdi.channel); } return ftdi_set_request(p_cdc, FTDI_SIO_SET_BAUDRATE_REQUEST, FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, value, index, complete_cb, user_data); } static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t line_state = (uint16_t) ((p_cdc->requested_line.control_state.dtr ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW) | (p_cdc->requested_line.control_state.rts ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW)); return ftdi_set_request(p_cdc, FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, line_state, p_cdc->ftdi.channel, complete_cb ? cdch_internal_control_complete : NULL, user_data); } //------------- Enumeration -------------// enum { CONFIG_FTDI_DETERMINE_TYPE = 0, CONFIG_FTDI_WRITE_LATENCY, CONFIG_FTDI_SIO_RESET, CONFIG_FTDI_FLOW_CONTROL, CONFIG_FTDI_COMPLETE }; static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // FTDI Interface includes 1 vendor interface + 2 bulk endpoints TU_VERIFY(itf_desc->bInterfaceSubClass == 0xff && itf_desc->bInterfaceProtocol == 0xff && itf_desc->bNumEndpoints == 2, 0); const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_FTDI; // endpoint pair const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); /* NOTE: Some users have programmed FT232R/FT245R devices * with an endpoint size of 0 !!! */ TU_ASSERT(desc_ep->wMaxPacketSize != 0, 0); TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); return drv_len; } static bool ftdi_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); const uintptr_t state = xfer->user_data; switch (state) { // from here sequence overtaken from Linux Kernel function ftdi_port_probe() case CONFIG_FTDI_DETERMINE_TYPE: // determine type TU_ASSERT(ftdi_determine_type(p_cdc)); TU_ATTR_FALLTHROUGH; case CONFIG_FTDI_WRITE_LATENCY: #ifdef CFG_TUH_CDC_FTDI_LATENCY int8_t result = ftdi_write_latency_timer(p_cdc, CFG_TUH_CDC_FTDI_LATENCY, ftdi_process_config, CONFIG_FTDI_SIO_RESET); TU_ASSERT(result != FTDI_FAIL); if (result == FTDI_REQUESTED) { break; }// else FTDI_NOT_POSSIBLE => continue directly with next state #endif TU_ATTR_FALLTHROUGH; // from here sequence overtaken from Linux Kernel function ftdi_open() case CONFIG_FTDI_SIO_RESET: TU_ASSERT(ftdi_sio_reset(p_cdc, cdch_process_set_config, CONFIG_FTDI_FLOW_CONTROL)); break; case CONFIG_FTDI_FLOW_CONTROL: // disable flow control TU_ASSERT(ftdi_set_request(p_cdc, FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, FTDI_SIO_DISABLE_FLOW_CTRL, p_cdc->ftdi.channel, cdch_process_set_config, CONFIG_FTDI_COMPLETE)); break; case CONFIG_FTDI_COMPLETE: { xfer->user_data = 0; // kick-off set line state on enum cdch_process_line_state_on_enum(xfer); break; } default: return false; } return true; } //------------- Helper -------------// static bool ftdi_determine_type(cdch_interface_t *p_cdc) { tusb_desc_device_t desc_dev; TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev)); uint16_t const version = desc_dev.bcdDevice; uint8_t const itf_num = p_cdc->bInterfaceNumber; p_cdc->ftdi.chip_type = FTDI_UNKNOWN; /* Assume Hi-Speed type */ p_cdc->ftdi.channel = CHANNEL_A + itf_num; switch (version) { case 0x200: // FT232A not supported to keep it simple (no extra _read_latency_timer()) not testable // p_cdc->ftdi.chip_type = FT232A; // p_cdc->ftdi.baud_base = 48000000 / 2; // p_cdc->ftdi.channel = 0; // /* // * FT232B devices have a bug where bcdDevice gets set to 0x200 // * when iSerialNumber is 0. Assume it is an FT232B in case the // * latency timer is readable. // */ // if (desc->iSerialNumber == 0 && // _read_latency_timer(port) >= 0) { // p_cdc->ftdi.chip_type = FTDI_FT232B; // } break; case 0x400 : p_cdc->ftdi.chip_type = FTDI_FT232B; p_cdc->ftdi.channel = 0; break; case 0x500 : p_cdc->ftdi.chip_type = FTDI_FT2232C; break; case 0x600 : p_cdc->ftdi.chip_type = FTDI_FT232R; p_cdc->ftdi.channel = 0; break; case 0x700 : p_cdc->ftdi.chip_type = FTDI_FT2232H; break; case 0x800 : p_cdc->ftdi.chip_type = FTDI_FT4232H; break; case 0x900 : p_cdc->ftdi.chip_type = FTDI_FT232H; break; case 0x1000: p_cdc->ftdi.chip_type = FTDI_FTX; break; case 0x2800: p_cdc->ftdi.chip_type = FTDI_FT2233HP; break; case 0x2900: p_cdc->ftdi.chip_type = FTDI_FT4233HP; break; case 0x3000: p_cdc->ftdi.chip_type = FTDI_FT2232HP; break; case 0x3100: p_cdc->ftdi.chip_type = FTDI_FT4232HP; break; case 0x3200: p_cdc->ftdi.chip_type = FTDI_FT233HP; break; case 0x3300: p_cdc->ftdi.chip_type = FTDI_FT232HP; break; case 0x3600: p_cdc->ftdi.chip_type = FTDI_FT4232HA; break; default: if (version < 0x200) { p_cdc->ftdi.chip_type = FTDI_SIO; p_cdc->ftdi.channel = 0; } break; } #if CFG_TUSB_DEBUG >= CFG_TUH_CDC_LOG_LEVEL const char * ftdi_chip_name[] = { FTDI_CHIP_NAMES }; TU_LOG_CDC(p_cdc, "%s detected (bcdDevice = 0x%04x)", ftdi_chip_name[p_cdc->ftdi.chip_type], version); #endif return (p_cdc->ftdi.chip_type != FTDI_UNKNOWN); } // FT232A not supported //static uint32_t ftdi_232am_baud_base_to_divisor(uint32_t baud, uint32_t base) //{ // uint32_t divisor; // /* divisor shifted 3 bits to the left */ // uint32_t divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); // if ((divisor3 & 0x7) == 7) // divisor3++; /* round x.7/8 up to x+1 */ // divisor = divisor3 >> 3; // divisor3 &= 0x7; // if (divisor3 == 1) // divisor |= 0xc000; /* +0.125 */ // else if (divisor3 >= 4) // divisor |= 0x4000; /* +0.5 */ // else if (divisor3 != 0) // divisor |= 0x8000; /* +0.25 */ // else if (divisor == 1) // divisor = 0; /* special case for maximum baud rate */ // return divisor; //} // FT232A not supported //static inline uint32_t ftdi_232am_baud_to_divisor(uint32_t baud) //{ // return ftdi_232am_baud_base_to_divisor(baud, (uint32_t) 48000000); //} static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { uint8_t divfrac[8] = {0, 3, 2, 4, 1, 5, 6, 7}; uint32_t divisor; /* divisor shifted 3 bits to the left */ uint32_t divisor3 = tu_div_round_nearest(base, 2 * baud); divisor = divisor3 >> 3; divisor |= (uint32_t) divfrac[divisor3 & 0x7] << 14; /* Deal with special cases for highest baud rates. */ if (divisor == 1) /* 1.0 */ { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; } else { // nothing to do } return divisor; } static inline uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { return ftdi_232bm_baud_base_to_divisor(baud, 48000000); } static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, uint32_t base) { static const unsigned char divfrac[8] = {0, 3, 2, 4, 1, 5, 6, 7}; uint32_t divisor; uint32_t divisor3; /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ divisor3 = tu_div_round_nearest(8 * base, 10 * baud); divisor = divisor3 >> 3; divisor |= (uint32_t) divfrac[divisor3 & 0x7] << 14; /* Deal with special cases for highest baud rates. */ if (divisor == 1) /* 1.0 */ { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; } else { // nothing to do } /* Set this bit to turn off a divide by 2.5 on baud rate generator * This enables baud rates up to 12Mbaud but cannot reach below 1200 * baud with this bit set */ divisor |= 0x00020000; return divisor; } static inline uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud) { return ftdi_2232h_baud_base_to_divisor(baud, (uint32_t) 120000000); } static inline uint32_t ftdi_get_divisor(cdch_interface_t *p_cdc) { uint32_t baud = p_cdc->requested_line.coding.bit_rate; uint32_t div_value = 0; TU_VERIFY(baud != 0); switch (p_cdc->ftdi.chip_type) { case FTDI_UNKNOWN: return 0; case FTDI_SIO: switch (baud) { case 300: div_value = ftdi_sio_b300; break; case 600: div_value = ftdi_sio_b600; break; case 1200: div_value = ftdi_sio_b1200; break; case 2400: div_value = ftdi_sio_b2400; break; case 4800: div_value = ftdi_sio_b4800; break; case 9600: div_value = ftdi_sio_b9600; break; case 19200: div_value = ftdi_sio_b19200; break; case 38400: div_value = ftdi_sio_b38400; break; case 57600: div_value = ftdi_sio_b57600; break; case 115200: div_value = ftdi_sio_b115200; break; default: // Baudrate not supported return 0; break; } break; // FT232A not supported // case FT232A: // if (baud <= 3000000) { // div_value = ftdi_232am_baud_to_divisor(baud); // } else { // // Baud rate too high! // baud = 9600; // div_value = ftdi_232am_baud_to_divisor(9600); // div_okay = false; // } // break; case FTDI_FT232B: case FTDI_FT2232C: case FTDI_FT232R: case FTDI_FTX: TU_VERIFY(baud <= 3000000); // else Baud rate too high! div_value = ftdi_232bm_baud_to_divisor(baud); break; case FTDI_FT232H: case FTDI_FT2232H: case FTDI_FT4232H: case FTDI_FT4232HA: case FTDI_FT232HP: case FTDI_FT233HP: case FTDI_FT2232HP: case FTDI_FT2233HP: case FTDI_FT4232HP: case FTDI_FT4233HP: default: TU_VERIFY(baud <= 12000000); // else Baud rate too high! if (baud >= 1200) { div_value = ftdi_2232h_baud_to_divisor(baud); } else { div_value = ftdi_232bm_baud_to_divisor(baud); } break; } TU_LOG_CDC(p_cdc, "Baudrate divisor = 0x%lu", div_value); return div_value; } #endif //--------------------------------------------------------------------+ // CP210x //--------------------------------------------------------------------+ #if CFG_TUH_CDC_CP210X //------------- Control Request -------------// static bool cp210x_set_request(cdch_interface_t * p_cdc, uint8_t command, uint16_t value, uint8_t * buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_VENDOR, .direction = TUSB_DIR_OUT }, .bRequest = command, .wValue = tu_htole16(value), .wIndex = tu_htole16((uint16_t) p_cdc->bInterfaceNumber), .wLength = tu_htole16(length) }; // use usbh enum buf since application variable does not live long enough uint8_t * enum_buf = NULL; if (buffer && length > 0) { enum_buf = usbh_get_enum_buf(); tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); } tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request, .buffer = enum_buf, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } TU_ATTR_ALWAYS_INLINE static inline bool cp210x_ifc_enable(cdch_interface_t *p_cdc, uint16_t enabled, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return cp210x_set_request(p_cdc, CP210X_IFC_ENABLE, enabled, NULL, 0, complete_cb, user_data); } TU_ATTR_ALWAYS_INLINE static inline bool cp210x_set_mhs(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // CP210x has the same bit coding return cp210x_set_request(p_cdc, CP210X_SET_MHS, (uint16_t) (CP210X_CONTROL_WRITE_DTR | CP210X_CONTROL_WRITE_RTS | p_cdc->requested_line.control_state.value), NULL, 0, complete_cb, user_data); } //------------- Driver API -------------// // internal control complete to update state such as line state, encoding static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,); switch (xfer->setup->bRequest) { case CP210X_SET_MHS: p_cdc->line.control_state = p_cdc->requested_line.control_state; break; case CP210X_SET_LINE_CTL: p_cdc->line.coding.stop_bits = p_cdc->requested_line.coding.stop_bits; p_cdc->line.coding.parity = p_cdc->requested_line.coding.parity; p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; break; case CP210X_SET_BAUDRATE: p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; break; default: break; // unsupported request } } static bool cp210x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // Not every baud rate is supported. See datasheets and AN205 "CP210x Baud Rate Support" uint32_t baud_le = tu_htole32(p_cdc->requested_line.coding.bit_rate); return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, complete_cb, user_data); } static bool cp210x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->requested_line.coding.data_bits >= 5 && p_cdc->requested_line.coding.data_bits <= 8, 0); uint16_t lcr = (uint16_t) ((p_cdc->requested_line.coding.data_bits & 0xfUL) << 8 | // data bit quantity is stored in bits 8-11 (p_cdc->requested_line.coding.parity & 0xfUL) << 4 | // parity is stored in bits 4-7, same coding (p_cdc->requested_line.coding.stop_bits & 0xfUL)); // parity is stored in bits 0-3, same coding return cp210x_set_request(p_cdc, CP210X_SET_LINE_CTL, lcr, NULL, 0, complete_cb, user_data); } static bool cp210x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return cp210x_set_mhs(p_cdc, complete_cb, user_data); } //------------- Enumeration -------------// enum { CONFIG_CP210X_IFC_ENABLE = 0, CONFIG_CP210X_COMPLETE }; static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // CP210x Interface includes 1 vendor interface + 2 bulk endpoints TU_VERIFY(itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0 && itf_desc->bNumEndpoints == 2, 0); const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_CP210X; // data endpoints expected to be in pairs const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); return drv_len; } static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); const uintptr_t state = xfer->user_data; switch (state) { case CONFIG_CP210X_IFC_ENABLE: TU_ASSERT(cp210x_ifc_enable(p_cdc, CP210X_UART_ENABLE, cdch_process_set_config, CONFIG_CP210X_COMPLETE)); break; case CONFIG_CP210X_COMPLETE: xfer->user_data = 0;// kick-off set line state on enum cdch_process_line_state_on_enum(xfer); break; default: return false; } return true; } #endif //--------------------------------------------------------------------+ // CH34x (CH340 & CH341) //--------------------------------------------------------------------+ #if CFG_TUH_CDC_CH34X static uint8_t ch34x_get_lcr(cdch_interface_t *p_cdc); static uint16_t ch34x_get_divisor_prescaler(cdch_interface_t *p_cdc); //------------- Control Request -------------// static bool ch34x_set_request(cdch_interface_t *p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_VENDOR, .direction = direction & 0x01u }, .bRequest = request, .wValue = tu_htole16(value), .wIndex = tu_htole16(index), .wLength = tu_htole16(length) }; // use usbh enum buf since application variable does not live long enough uint8_t *enum_buf = NULL; if (buffer && length > 0) { enum_buf = usbh_get_enum_buf(); if (direction == TUSB_DIR_OUT) { tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); } } tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request_setup, .buffer = enum_buf, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } TU_ATTR_ALWAYS_INLINE static inline bool ch34x_control_out(cdch_interface_t *p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ch34x_set_request(p_cdc, TUSB_DIR_OUT, request, value, index, NULL, 0, complete_cb, user_data); } TU_ATTR_ALWAYS_INLINE static inline bool ch34x_control_in(cdch_interface_t *p_cdc, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ch34x_set_request(p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, complete_cb, user_data); } TU_ATTR_ALWAYS_INLINE static inline bool ch34x_write_reg(cdch_interface_t *p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, reg_value, complete_cb, user_data); } //static bool ch34x_read_reg_request ( cdch_interface_t * p_cdc, uint16_t reg, // uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) //{ // return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); //} //------------- Driver API -------------// // internal control complete to update state such as line state, encoding static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,); switch (xfer->setup->bRequest) { case CH34X_REQ_WRITE_REG: // register write request switch (tu_le16toh(xfer->setup->wValue)) { case CH34X_REG16_DIVISOR_PRESCALER: // baudrate p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; break; case CH32X_REG16_LCR2_LCR: // data format p_cdc->line.coding.stop_bits = p_cdc->requested_line.coding.stop_bits; p_cdc->line.coding.parity = p_cdc->requested_line.coding.parity; p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; break; default: break; // unsupported } break; case CH34X_REQ_MODEM_CTRL: p_cdc->line.control_state = p_cdc->requested_line.control_state; break; default: break; // unsupported request } } static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint8_t lcr = ch34x_get_lcr(p_cdc); TU_VERIFY(lcr > 0); return ch34x_write_reg(p_cdc, CH32X_REG16_LCR2_LCR, lcr, complete_cb, user_data); } static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint16_t div_ps = ch34x_get_divisor_prescaler(p_cdc); TU_VERIFY(div_ps > 0); return ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb, user_data); } static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // CH34x signals are inverted uint8_t control = ~((p_cdc->requested_line.control_state.rts ? CH34X_BIT_RTS : 0) | (p_cdc->requested_line.control_state.dtr ? CH34X_BIT_DTR : 0)); return ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, complete_cb, user_data); } //------------- Enumeration -------------// enum { CONFIG_CH34X_READ_VERSION = 0, CONFIG_CH34X_SERIAL_INIT, CONFIG_CH34X_SPECIAL_REG_WRITE, CONFIG_CH34X_FLOW_CONTROL, CONFIG_CH34X_COMPLETE }; static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints TU_VERIFY(itf_desc->bNumEndpoints == 3, 0); const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_CH34X; const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc); // data endpoints expected to be in pairs TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); desc_ep = (const tusb_desc_endpoint_t *)((uintptr_t)desc_ep + 2 * sizeof(tusb_desc_endpoint_t)); // Interrupt endpoint: not used for now TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; return drv_len; } static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS); const uintptr_t state = xfer->user_data; switch (state) { case CONFIG_CH34X_READ_VERSION: { uint8_t* enum_buf = usbh_get_enum_buf(); TU_ASSERT(ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, enum_buf, 2, cdch_process_set_config, CONFIG_CH34X_SERIAL_INIT)); break; } case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, set CH34x line coding (incl. baudrate) uint8_t const version = xfer->buffer[0]; TU_LOG_CDC(p_cdc, "Chip Version = 0x%02x", version); // only versions >= 0x30 are tested, below 0x30 seems having other programming // see drivers from WCH vendor, Linux kernel and FreeBSD if (version >= 0x30) { // init CH34x with line coding p_cdc->requested_line.coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; uint16_t const div_ps = ch34x_get_divisor_prescaler(p_cdc); uint8_t const lcr = ch34x_get_lcr(p_cdc); TU_ASSERT(div_ps != 0 && lcr != 0); TU_ASSERT(ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, cdch_process_set_config, CONFIG_CH34X_SPECIAL_REG_WRITE)); } break; } case CONFIG_CH34X_SPECIAL_REG_WRITE: // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver p_cdc->line.coding = (cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; TU_ASSERT(ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x0F, CH341_REG_0x2C), 0x0007, cdch_process_set_config, CONFIG_CH34X_FLOW_CONTROL)); break; case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control TU_ASSERT(ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x27, CH341_REG_0x27), 0x0000, cdch_process_set_config, CONFIG_CH34X_COMPLETE)); break; case CONFIG_CH34X_COMPLETE: xfer->user_data = 0; // kick-off set line state on enum cdch_process_line_state_on_enum(xfer); break; default: return false; } return true; } //------------- Helper -------------// // calculate divisor and prescaler for baudrate, return it as 16-bit combined value static uint16_t ch34x_get_divisor_prescaler(cdch_interface_t *p_cdc) { uint32_t const baval = p_cdc->requested_line.coding.bit_rate; uint8_t a; uint8_t b; uint32_t c; TU_VERIFY(baval != 0 && baval <= 2000000, 0); switch (baval) { case 921600: a = 0xf3; b = 7; break; case 307200: a = 0xd9; b = 7; break; default: if (baval > 6000000 / 255) { b = 3; c = 6000000; } else if (baval > 750000 / 255) { b = 2; c = 750000; } else if (baval > 93750 / 255) { b = 1; c = 93750; } else { b = 0; c = 11719; } a = (uint8_t) (c / baval); if (a == 0 || a == 0xFF) { return 0; } if ((c / a - baval) > (baval - c / (a + 1))) { a++; } a = (uint8_t) (256 - a); break; } // reg divisor = a, reg prescaler = b // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, // otherwise the chip will buffer data. return (uint16_t) ((uint16_t) a << 8 | 0x80 | b); } // calculate lcr value from data coding static uint8_t ch34x_get_lcr(cdch_interface_t *p_cdc) { uint8_t const stop_bits = p_cdc->requested_line.coding.stop_bits; uint8_t const parity = p_cdc->requested_line.coding.parity; uint8_t const data_bits = p_cdc->requested_line.coding.data_bits; uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; TU_VERIFY(data_bits >= 5 && data_bits <= 8); lcr |= (uint8_t) (data_bits - 5); switch (parity) { case CDC_LINE_CODING_PARITY_NONE: break; case CDC_LINE_CODING_PARITY_ODD: lcr |= CH34X_LCR_ENABLE_PAR; break; case CDC_LINE_CODING_PARITY_EVEN: lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN; break; case CDC_LINE_CODING_PARITY_MARK: lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE; break; case CDC_LINE_CODING_PARITY_SPACE: lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; break; default: break; // invalid parity } // 1.5 stop bits not supported TU_VERIFY(stop_bits != CDC_LINE_CODING_STOP_BITS_1_5); if (stop_bits == CDC_LINE_CODING_STOP_BITS_2) { lcr |= CH34X_LCR_STOP_BITS_2; } return lcr; } #endif // CFG_TUH_CDC_CH34X //--------------------------------------------------------------------+ // PL2303 //--------------------------------------------------------------------+ #if CFG_TUH_CDC_PL2303 static pl2303_type_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step); static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_LINE_CODING_BAUDRATE_BUFSIZE]); //------------- Control Request -------------// static bool pl2303_set_request(cdch_interface_t *p_cdc, uint8_t request, uint8_t requesttype, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { .bmRequestType = requesttype, .bRequest = request, .wValue = tu_htole16(value), .wIndex = tu_htole16(index), .wLength = tu_htole16(length) }; // use usbh enum buf since application variable does not live long enough uint8_t *enum_buf = NULL; if (buffer && length > 0) { enum_buf = usbh_get_enum_buf(); if (request_setup.bmRequestType_bit.direction == TUSB_DIR_OUT) { tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); } } tuh_xfer_t xfer = { .daddr = p_cdc->daddr, .ep_addr = 0, .setup = &request_setup, .buffer = enum_buf, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } static bool pl2303_vendor_read(cdch_interface_t *p_cdc, uint16_t value, uint8_t *buf, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint8_t request = p_cdc->pl2303.type == PL2303_TYPE_HXN ? PL2303_VENDOR_READ_NREQUEST : PL2303_VENDOR_READ_REQUEST; return pl2303_set_request(p_cdc, request, PL2303_VENDOR_READ_REQUEST_TYPE, value, 0, buf, 1, complete_cb, user_data); } static bool pl2303_vendor_write(cdch_interface_t *p_cdc, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint8_t request = p_cdc->pl2303.type == PL2303_TYPE_HXN ? PL2303_VENDOR_WRITE_NREQUEST : PL2303_VENDOR_WRITE_REQUEST; return pl2303_set_request(p_cdc, request, PL2303_VENDOR_WRITE_REQUEST_TYPE, value, index, NULL, 0, complete_cb, user_data); } static inline bool pl2303_supports_hx_status(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint8_t buf = 0; return pl2303_set_request(p_cdc, PL2303_VENDOR_READ_REQUEST, PL2303_VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS, 0, &buf, 1, complete_cb, user_data); } //static bool pl2303_get_line_request(cdch_interface_t * p_cdc, uint8_t buf[PL2303_LINE_CODING_BUFSIZE]) { // return pl2303_set_request(p_cdc, PL2303_GET_LINE_REQUEST, PL2303_GET_LINE_REQUEST_TYPE, 0, 0, buf, PL2303_LINE_CODING_BUFSIZE); //} //static bool pl2303_set_break(cdch_interface_t * p_cdc, bool enable) { // uint16_t state = enable ? PL2303_BREAK_ON : PL2303_BREAK_OFF; // return pl2303_set_request(p_cdc, PL2303_BREAK_REQUEST, PL2303_BREAK_REQUEST_TYPE, state, 0, NULL, 0); //} static inline bool pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { /* we don't care if it wasn't halted first. in fact some devices * (like some ibmcam model 1 units) seem to expect hosts to make * this request for iso endpoints, which can't halt! */ return pl2303_set_request( p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp, NULL, 0, complete_cb, user_data); } //------------- Driver API -------------// // internal control complete to update state such as line state, encoding static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,); if (xfer->setup->bRequest == PL2303_SET_LINE_REQUEST && xfer->setup->bmRequestType == PL2303_SET_LINE_REQUEST_TYPE) { p_cdc->line.coding = p_cdc->requested_line.coding; } if (xfer->setup->bRequest == PL2303_SET_CONTROL_REQUEST && xfer->setup->bmRequestType == PL2303_SET_CONTROL_REQUEST_TYPE) { p_cdc->line.control_state = p_cdc->requested_line.control_state; } } static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // the caller has to precheck, that the new line coding different than the current, else false returned uint8_t buf[PL2303_LINE_CODING_BUFSIZE]; /* * Some PL2303 are known to lose bytes if you change serial settings * even to the same values as before. Thus we actually need to filter * in this specific case. */ TU_VERIFY(p_cdc->requested_line.coding.data_bits != p_cdc->line.coding.data_bits || p_cdc->requested_line.coding.stop_bits != p_cdc->line.coding.stop_bits || p_cdc->requested_line.coding.parity != p_cdc->line.coding.parity || p_cdc->requested_line.coding.bit_rate != p_cdc->line.coding.bit_rate ); /* For reference buf[6] data bits value */ TU_VERIFY(p_cdc->requested_line.coding.data_bits >= 5 && p_cdc->requested_line.coding.data_bits <= 8, 0); buf[6] = p_cdc->requested_line.coding.data_bits; /* For reference buf[0]:buf[3] baud rate value */ TU_VERIFY(pl2303_encode_baud_rate(p_cdc, &buf[0])); /* For reference buf[4]=0 is 1 stop bits */ /* For reference buf[4]=1 is 1.5 stop bits */ /* For reference buf[4]=2 is 2 stop bits */ buf[4] = p_cdc->requested_line.coding.stop_bits; // PL2303 has the same coding /* For reference buf[5]=0 is none parity */ /* For reference buf[5]=1 is odd parity */ /* For reference buf[5]=2 is even parity */ /* For reference buf[5]=3 is mark parity */ /* For reference buf[5]=4 is space parity */ buf[5] = p_cdc->requested_line.coding.parity; // PL2303 has the same coding return pl2303_set_request(p_cdc, PL2303_SET_LINE_REQUEST, PL2303_SET_LINE_REQUEST_TYPE, 0, 0, buf, PL2303_LINE_CODING_BUFSIZE, complete_cb, user_data); } static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // PL2303 has the same bit coding return pl2303_set_request(p_cdc, PL2303_SET_CONTROL_REQUEST, PL2303_SET_CONTROL_REQUEST_TYPE, p_cdc->requested_line.control_state.value, 0, NULL, 0, complete_cb, user_data); } //------------- Enumeration -------------// enum { CONFIG_PL2303_DETECT_TYPE = 0, CONFIG_PL2303_READ1, CONFIG_PL2303_WRITE1, CONFIG_PL2303_READ2, CONFIG_PL2303_READ3, CONFIG_PL2303_READ4, CONFIG_PL2303_WRITE2, CONFIG_PL2303_READ5, CONFIG_PL2303_READ6, CONFIG_PL2303_WRITE3, CONFIG_PL2303_WRITE4, CONFIG_PL2303_WRITE5, CONFIG_PL2303_RESET_ENDP1, CONFIG_PL2303_RESET_ENDP2, // CONFIG_PL2303_FLOW_CTRL_READ, // CONFIG_PL2303_FLOW_CTRL_WRITE, CONFIG_PL2303_COMPLETE }; static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { // PL2303 Interface includes 1 vendor interface + 1 interrupt endpoints + 2 bulk TU_VERIFY(itf_desc->bNumEndpoints == 3, 0); const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_VERIFY(drv_len <= max_len, 0); cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc, 0); p_cdc->serial_drid = SERIAL_DRIVER_PL2303; p_cdc->pl2303.quirks = 0; p_cdc->pl2303.supports_hx_status = false; tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); // Interrupt endpoint: not used for now TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; desc_ep += 1; // data endpoints expected to be in pairs TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0); return drv_len; } static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { // state CONFIG_PL2303_READ1 may have no success due to expected stall by pl2303_supports_hx_status() const uintptr_t state = xfer->user_data; TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS || state == CONFIG_PL2303_READ1); uint8_t* enum_buf = usbh_get_enum_buf(); pl2303_type_t type; switch (state) { // from here sequence overtaken from Linux Kernel function pl2303_startup() case CONFIG_PL2303_DETECT_TYPE: // get type and quirks (step 1) type = pl2303_detect_type(p_cdc, 1); TU_ASSERT(type != PL2303_TYPE_UNKNOWN); if (type == PL2303_TYPE_NEED_SUPPORTS_HX_STATUS) { TU_ASSERT(pl2303_supports_hx_status(p_cdc, cdch_process_set_config, CONFIG_PL2303_READ1)); break; } // no transfer triggered and continue with CONFIG_PL2303_READ1 TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ1: // get supports_hx_status, type and quirks (step 2), do special read // will not be true, if coming directly from previous case if (xfer->user_data == CONFIG_PL2303_READ1 && xfer->result == XFER_RESULT_SUCCESS) { p_cdc->pl2303.supports_hx_status = true; } type = pl2303_detect_type(p_cdc, 2); // step 2 now with supports_hx_status TU_ASSERT(type != PL2303_TYPE_UNKNOWN); TU_LOG_DRV(" PL2303 type detected: %u\r\n", type); p_cdc->pl2303.type = type; p_cdc->pl2303.quirks |= pl2303_type_data[type].quirks; // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8484, enum_buf, cdch_process_set_config, CONFIG_PL2303_WRITE1)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_WRITE1: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_write(p_cdc, 0x0404, 0, cdch_process_set_config, CONFIG_PL2303_READ2)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ2: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8484, enum_buf, cdch_process_set_config, CONFIG_PL2303_READ3)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ3: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8383, enum_buf, cdch_process_set_config, CONFIG_PL2303_READ4)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ4: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8484, enum_buf, cdch_process_set_config, CONFIG_PL2303_WRITE2)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_WRITE2: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_write(p_cdc, 0x0404, 1, cdch_process_set_config, CONFIG_PL2303_READ5)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ5: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8484, enum_buf, cdch_process_set_config, CONFIG_PL2303_READ6)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ6: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_read(p_cdc, 0x8383, enum_buf, cdch_process_set_config, CONFIG_PL2303_WRITE3)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_WRITE3: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_write(p_cdc, 0, 1, cdch_process_set_config, CONFIG_PL2303_WRITE4)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_WRITE4: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_write(p_cdc, 1, 0, cdch_process_set_config, CONFIG_PL2303_WRITE5)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_WRITE5: // purpose unknown, overtaken from Linux Kernel driver if (p_cdc->pl2303.type != PL2303_TYPE_HXN) { uint16_t const windex = (p_cdc->pl2303.quirks & PL2303_QUIRK_LEGACY) ? 0x24 : 0x44; TU_ASSERT(pl2303_vendor_write(p_cdc, 2, windex, cdch_process_set_config, CONFIG_PL2303_RESET_ENDP1)); break; }// else: continue with next step TU_ATTR_FALLTHROUGH; // from here sequence overtaken from Linux Kernel function pl2303_open() case CONFIG_PL2303_RESET_ENDP1: // step 1 if (p_cdc->pl2303.quirks & PL2303_QUIRK_LEGACY) { TU_ASSERT(pl2303_clear_halt(p_cdc, PL2303_OUT_EP, cdch_process_set_config, CONFIG_PL2303_RESET_ENDP2)); } else { /* reset upstream data pipes */ if (p_cdc->pl2303.type == PL2303_TYPE_HXN) { TU_ASSERT(pl2303_vendor_write(p_cdc, PL2303_HXN_RESET_REG,// skip CONFIG_PL2303_RESET_ENDP2, no 2nd step PL2303_HXN_RESET_UPSTREAM_PIPE | PL2303_HXN_RESET_DOWNSTREAM_PIPE, cdch_process_set_config, CONFIG_PL2303_COMPLETE)); } else { pl2303_vendor_write(p_cdc, 8, 0, cdch_process_set_config, CONFIG_PL2303_RESET_ENDP2); } } break; case CONFIG_PL2303_RESET_ENDP2: // step 2 if (p_cdc->pl2303.quirks & PL2303_QUIRK_LEGACY) { TU_ASSERT(pl2303_clear_halt(p_cdc, PL2303_IN_EP, cdch_process_set_config, CONFIG_PL2303_COMPLETE)); } else { /* reset upstream data pipes */ if (p_cdc->pl2303.type == PL2303_TYPE_HXN) { // here nothing to do, only structure of previous step overtaken for better reading and comparison } else { TU_ASSERT(pl2303_vendor_write(p_cdc, 9, 0, cdch_process_set_config, CONFIG_PL2303_COMPLETE)); } } break; // skipped, because it's not working with each PL230x. flow control can be also set by PL2303 EEPROM Writer Program // case CONFIG_PL2303_FLOW_CTRL_READ: // // read flow control register for modify & write back in next step // if (p_cdc->pl2303.type == PL2303_TYPE_HXN) { // TU_LOG_P_CDC ( "1\r\n" ); // TU_ASSERT(pl2303_vendor_read(p_cdc, PL2303_HXN_FLOWCTRL_REG, &buf, // cdch_process_set_config, CONFIG_PL2303_FLOW_CTRL_WRITE)); // } else { // TU_LOG_P_CDC ( "2\r\n" ); // TU_ASSERT(pl2303_vendor_read(p_cdc, 0, &buf, cdch_process_set_config, CONFIG_PL2303_FLOW_CTRL_WRITE)); // } // break; // // case CONFIG_PL2303_FLOW_CTRL_WRITE: // // no flow control // buf = xfer->buffer[0]; // if (p_cdc->pl2303.type == PL2303_TYPE_HXN) { // buf &= (uint8_t) ~PL2303_HXN_FLOWCTRL_MASK; // buf |= PL2303_HXN_FLOWCTRL_NONE; // TU_ASSERT(pl2303_vendor_write(p_cdc, PL2303_HXN_FLOWCTRL_REG, buf, // cdch_process_set_config, CONFIG_PL2303_COMPLETE)); // } else { // buf &= (uint8_t) ~PL2303_FLOWCTRL_MASK; // TU_ASSERT(pl2303_vendor_write(p_cdc, 0, buf, // cdch_process_set_config, CONFIG_PL2303_COMPLETE)); // } // break; case CONFIG_PL2303_COMPLETE: xfer->user_data = 0; // kick-off set line state on enum cdch_process_line_state_on_enum(xfer); break; default: return false; } return true; } //------------- Helper -------------// static pl2303_type_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step) { tusb_desc_device_t desc_dev; TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev), PL2303_TYPE_UNKNOWN); // Legacy PL2303H, variants 0 and 1 (difference unknown). if (desc_dev.bDeviceClass == 0x02) { return PL2303_TYPE_H; /* variant 0 */ } if (desc_dev.bMaxPacketSize0 != 0x40) { if (desc_dev.bDeviceClass == 0x00 || desc_dev.bDeviceClass == 0xff) { return PL2303_TYPE_H; /* variant 1 */ } return PL2303_TYPE_H; /* variant 0 */ } switch (desc_dev.bcdUSB) { case 0x101: /* USB 1.0.1? Let's assume they meant 1.1... */ TU_ATTR_FALLTHROUGH; case 0x110: switch (desc_dev.bcdDevice) { case 0x300: return PL2303_TYPE_HX; case 0x400: return PL2303_TYPE_HXD; default: return PL2303_TYPE_HX; } break; case 0x200: switch (desc_dev.bcdDevice) { case 0x100: /* GC */ case 0x105: return PL2303_TYPE_HXN; case 0x300: /* GT / TA */ if (step == 1) { // step 1 trigger pl2303_supports_hx_status() request return PL2303_TYPE_NEED_SUPPORTS_HX_STATUS; } else { // step 2 use supports_hx_status if (p_cdc->pl2303.supports_hx_status) { return PL2303_TYPE_TA; } } TU_ATTR_FALLTHROUGH; case 0x305: case 0x400: /* GL */ case 0x405: return PL2303_TYPE_HXN; case 0x500: /* GE / TB */ if (step == 1) { // step 1 trigger pl2303_supports_hx_status() request return PL2303_TYPE_NEED_SUPPORTS_HX_STATUS; } else { // step 2 use supports_hx_status if (p_cdc->pl2303.supports_hx_status) { return PL2303_TYPE_TB; } } TU_ATTR_FALLTHROUGH; case 0x505: case 0x600: /* GS */ case 0x605: case 0x700: /* GR */ case 0x705: return PL2303_TYPE_HXN; default: break; // unknown device } break; default: break; // unknown device } TU_LOG_CDC(p_cdc, "unknown device type bcdUSB = 0x%04x", desc_dev.bcdUSB); return PL2303_TYPE_UNKNOWN; } /* * Returns the nearest supported baud rate that can be set directly without * using divisors. */ static uint32_t pl2303_get_supported_baud_rate(uint32_t baud) { static const uint32_t baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400, 460800, 614400, 921600, 1228800, 2457600, 3000000, 6000000 }; uint8_t i; for (i = 0; i < TU_ARRAY_SIZE(baud_sup); ++i) { if (baud_sup[i] > baud) { break; } } if (i == TU_ARRAY_SIZE(baud_sup)) { baud = baud_sup[i - 1]; } else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) { baud = baud_sup[i - 1]; } else { baud = baud_sup[i]; } return baud; } /* * NOTE: If unsupported baud rates are set directly, the PL2303 seems to * use 9600 baud. */ static uint32_t pl2303_encode_baud_rate_direct(uint8_t buf[PL2303_LINE_CODING_BAUDRATE_BUFSIZE], uint32_t baud) { uint32_t baud_le = tu_htole32(baud); buf[0] = (uint8_t) ( baud_le & 0xff); buf[1] = (uint8_t) ((baud_le >> 8) & 0xff); buf[2] = (uint8_t) ((baud_le >> 16) & 0xff); buf[3] = (uint8_t) ((baud_le >> 24) & 0xff); return baud; } static uint32_t pl2303_encode_baud_rate_divisor(uint8_t buf[PL2303_LINE_CODING_BAUDRATE_BUFSIZE], uint32_t baud) { uint32_t baseline, mantissa, exponent; /* * Apparently the formula is: * baudrate = 12M * 32 / (mantissa * 4^exponent) * where * mantissa = buf[8:0] * exponent = buf[11:9] */ baseline = 12000000 * 32; mantissa = baseline / baud; if (mantissa == 0) { mantissa = 1; /* Avoid dividing by zero if baud > 32 * 12M. */ } exponent = 0; while (mantissa >= 512) { if (exponent < 7) { mantissa >>= 2; /* divide by 4 */ exponent++; } else { /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 511; break; } } buf[3] = 0x80; buf[2] = 0; buf[1] = (uint8_t) ((exponent << 1 | mantissa >> 8) & 0xff); buf[0] = (uint8_t) (mantissa & 0xff); /* Calculate and return the exact baud rate. */ baud = (baseline / mantissa) >> (exponent << 1); return baud; } static uint32_t pl2303_encode_baud_rate_divisor_alt(uint8_t buf[PL2303_LINE_CODING_BAUDRATE_BUFSIZE], uint32_t baud) { uint32_t baseline, mantissa, exponent; /* * Apparently, for the TA version the formula is: * baudrate = 12M * 32 / (mantissa * 2^exponent) * where * mantissa = buf[10:0] * exponent = buf[15:13 16] */ baseline = 12000000 * 32; mantissa = baseline / baud; if (mantissa == 0) { mantissa = 1; /* Avoid dividing by zero if baud > 32 * 12M. */ } exponent = 0; while (mantissa >= 2048) { if (exponent < 15) { mantissa >>= 1; /* divide by 2 */ exponent++; } else { /* Exponent is maxed. Trim mantissa and leave. */ mantissa = 2047; break; } } buf[3] = 0x80; buf[2] = (uint8_t) (exponent & 0x01); buf[1] = (uint8_t) (((exponent & (uint32_t) ~0x01) << 4 | mantissa >> 8) & 0xff); buf[0] = (uint8_t) (mantissa & 0xff); /* Calculate and return the exact baud rate. */ baud = (baseline / mantissa) >> exponent; return baud; } static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_LINE_CODING_BAUDRATE_BUFSIZE]) { uint32_t baud = p_cdc->requested_line.coding.bit_rate; uint32_t baud_sup; const pl2303_type_data_t* type_data = &pl2303_type_data[p_cdc->pl2303.type]; TU_VERIFY(baud && baud <= type_data->max_baud_rate); /* * Use direct method for supported baud rates, otherwise use divisors. * Newer chip types do not support divisor encoding. */ if (type_data->no_divisors != 0) { baud_sup = baud; } else { baud_sup = pl2303_get_supported_baud_rate(baud); } if (baud == baud_sup) { baud = pl2303_encode_baud_rate_direct(buf, baud); } else if (type_data->alt_divisors != 0) { baud = pl2303_encode_baud_rate_divisor_alt(buf, baud); } else { baud = pl2303_encode_baud_rate_divisor(buf, baud); } TU_LOG_CDC(p_cdc, "real baudrate %lu", baud); return true; } #endif // CFG_TUH_CDC_PL2303 #endif ================================================ FILE: src/class/cdc/cdc_host.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_CDC_HOST_H_ #define TUSB_CDC_HOST_H_ #include "cdc.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MAX #endif // TX FIFO size #ifndef CFG_TUH_CDC_TX_BUFSIZE #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MAX #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Get Interface index from device address + interface number // return TUSB_INDEX_INVALID_8 (0xFF) if not found uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get Interface information // return true if index is correct and interface is currently mounted bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t *info); // Check if an interface is mounted bool tuh_cdc_mounted(uint8_t idx); // Get local (cached) line state // This function should return correct values if tuh_cdc_set_control_line_state() / tuh_cdc_get_control_line_state() // are invoked previously or CFG_TUH_CDC_LINE_STATE_ON_ENUM is defined. bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t *line_state); // Get current DTR status TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_get_dtr(uint8_t idx) { uint16_t line_state; TU_VERIFY(tuh_cdc_get_control_line_state_local(idx, &line_state)); return (line_state & CDC_CONTROL_LINE_STATE_DTR) != 0; } // Get current RTS status TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_get_rts(uint8_t idx) { uint16_t line_state; TU_VERIFY(tuh_cdc_get_control_line_state_local(idx, &line_state)); return (line_state & CDC_CONTROL_LINE_STATE_RTS) != 0; } // Check if interface is connected (DTR active) TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) { return tuh_cdc_get_dtr(idx); } // Get local (saved/cached) version of line coding. // This function should return correct values if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() // are invoked previously or CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined. // NOTE: This function does not make any USB transfer request to device. bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t *line_coding); #define tuh_cdc_get_local_line_coding tuh_cdc_get_line_coding_local // backward compatibility //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ // Get the number of bytes available for writing uint32_t tuh_cdc_write_available(uint8_t idx); // Write to cdc interface uint32_t tuh_cdc_write(uint8_t idx, const void *buffer, uint32_t bufsize); // Force sending data if possible, return number of forced bytes uint32_t tuh_cdc_write_flush(uint8_t idx); // Clear the transmit FIFO bool tuh_cdc_write_clear(uint8_t idx); //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ // Get the number of bytes available for reading uint32_t tuh_cdc_read_available(uint8_t idx); // Read from cdc interface uint32_t tuh_cdc_read(uint8_t idx, void *buffer, uint32_t bufsize); // Get a byte from RX FIFO without removing it bool tuh_cdc_peek(uint8_t idx, uint8_t *ch); // Clear the received FIFO bool tuh_cdc_read_clear(uint8_t idx); //--------------------------------------------------------------------+ // Control Request API // Each Function will make a USB control transfer request to/from device // - If complete_cb is provided, the function will return immediately and invoke // the callback when request is complete. // - If complete_cb is NULL, the function will block until request is complete. // In this case, user_data should be usb_xfer_result_t* to hold the transfer result. //--------------------------------------------------------------------+ // Request to Set Control Line State: DTR (bit 0), RTS (bit 1) bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Set DTR TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_dtr(uint8_t idx, bool dtr_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdc_line_control_state_t line_state = {.dtr = dtr_state}; line_state.rts = tuh_cdc_get_rts(idx); return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data); } // Request to Set RTS TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdc_line_control_state_t line_state = {.rts = rts_state}; line_state.dtr = tuh_cdc_get_dtr(idx); return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data); } // Request to set baudrate bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to set data format bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Set Line Coding = baudrate + data format // Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet bool tuh_cdc_set_line_coding(uint8_t idx, const cdc_line_coding_t *line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Get Line Coding (ACM only) // Should only use if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() never got invoked and // CFG_TUH_CDC_LINE_CODING_ON_ENUM is not defined // bool tuh_cdc_get_line_coding(uint8_t idx, cdc_line_coding_t* coding); // Connect by set both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); } // Disconnect by clear both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } //--------------------------------------------------------------------+ // Control Request Sync API // Each Function will make a USB control transfer request to/from device the function will block until request is // complete. The function will return the transfer request result //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_control_line_state_sync(uint8_t idx, uint16_t line_state) { TU_API_SYNC(tuh_cdc_set_control_line_state, idx, line_state); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_dtr_sync(uint8_t idx, bool dtr_state) { TU_API_SYNC(tuh_cdc_set_dtr, idx, dtr_state); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_rts_sync(uint8_t idx, bool rts_state) { TU_API_SYNC(tuh_cdc_set_rts, idx, rts_state); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_baudrate_sync(uint8_t idx, uint32_t baudrate) { TU_API_SYNC(tuh_cdc_set_baudrate, idx, baudrate); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_data_format_sync(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { TU_API_SYNC(tuh_cdc_set_data_format, idx, stop_bits, parity, data_bits); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_line_coding_sync(uint8_t idx, const cdc_line_coding_t *line_coding) { TU_API_SYNC(tuh_cdc_set_line_coding, idx, line_coding); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_connect_sync(uint8_t idx) { TU_API_SYNC(tuh_cdc_connect, idx); } TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_disconnect_sync(uint8_t idx) { TU_API_SYNC(tuh_cdc_disconnect, idx); } //--------------------------------------------------------------------+ // CDC APPLICATION CALLBACKS //--------------------------------------------------------------------+ // Invoked when a device with CDC interface is mounted // idx is index of cdc interface in the internal pool. extern void tuh_cdc_mount_cb(uint8_t idx); // Invoked when a device with CDC interface is unmounted extern void tuh_cdc_umount_cb(uint8_t idx); // Invoked when received new data extern void tuh_cdc_rx_cb(uint8_t idx); // Invoked when a TX is complete and therefore space becomes available in TX buffer extern void tuh_cdc_tx_complete_cb(uint8_t idx); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ bool cdch_init(void); bool cdch_deinit(void); uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num); bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); void cdch_close(uint8_t dev_addr); #ifdef __cplusplus } #endif #endif /* TUSB_CDC_HOST_H_ */ ================================================ FILE: src/class/cdc/cdc_rndis.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /** \ingroup ClassDriver_CDC Communication Device Class (CDC) * \defgroup CDC_RNDIS Remote Network Driver Interface Specification (RNDIS) * @{ * \defgroup CDC_RNDIS_Common Common Definitions * @{ */ #ifndef TUSB_CDC_RNDIS_H_ #define TUSB_CDC_RNDIS_H_ #include "cdc.h" #ifdef __cplusplus extern "C" { #endif #ifdef __CC_ARM #pragma diag_suppress 66 // Suppress Keil warnings #66-D: enumeration value is out of "int" range #endif /// RNDIS Message Types typedef enum { RNDIS_MSG_PACKET = 0x00000001UL, ///< The host and device use this to send network data to one another. RNDIS_MSG_INITIALIZE = 0x00000002UL, ///< Sent by the host to initialize the device. RNDIS_MSG_INITIALIZE_CMPLT = 0x80000002UL, ///< Device response to an initialize message. RNDIS_MSG_HALT = 0x00000003UL, ///< Sent by the host to halt the device. This does not have a response. It is optional for the device to send this message to the host. RNDIS_MSG_QUERY = 0x00000004UL, ///< Sent by the host to send a query OID. RNDIS_MSG_QUERY_CMPLT = 0x80000004UL, ///< Device response to a query OID. RNDIS_MSG_SET = 0x00000005UL, ///< Sent by the host to send a set OID. RNDIS_MSG_SET_CMPLT = 0x80000005UL, ///< Device response to a set OID. RNDIS_MSG_RESET = 0x00000006UL, ///< Sent by the host to perform a soft reset on the device. RNDIS_MSG_RESET_CMPLT = 0x80000006UL, ///< Device response to reset message. RNDIS_MSG_INDICATE_STATUS = 0x00000007UL, ///< Sent by the device to indicate its status or an error when an unrecognized message is received. RNDIS_MSG_KEEP_ALIVE = 0x00000008UL, ///< During idle periods, sent every few seconds by the host to check that the device is still responsive. It is optional for the device to send this message to check if the host is active. RNDIS_MSG_KEEP_ALIVE_CMPLT = 0x80000008UL ///< The device response to a keepalivemessage. The host can respond with this message to a keepalive message from the device when the device implements the optional KeepAliveTimer. }rndis_msg_type_t; /// RNDIS Message Status Values typedef enum { RNDIS_STATUS_SUCCESS = 0x00000000UL, ///< Success RNDIS_STATUS_FAILURE = 0xC0000001UL, ///< Unspecified error RNDIS_STATUS_INVALID_DATA = 0xC0010015UL, ///< Invalid data error RNDIS_STATUS_NOT_SUPPORTED = 0xC00000BBUL, ///< Unsupported request error RNDIS_STATUS_MEDIA_CONNECT = 0x4001000BUL, ///< Device is connected to a network medium. RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000CUL ///< Device is disconnected from the medium. }rndis_msg_status_t; #ifdef __CC_ARM #pragma diag_default 66 // return Keil 66 to normal severity #endif //--------------------------------------------------------------------+ // MESSAGE STRUCTURE //--------------------------------------------------------------------+ //------------- Initialize -------------// /// \brief Initialize Message /// \details This message MUST be sent by the host to initialize the device. typedef struct { uint32_t type ; ///< Message type, must be \ref RNDIS_MSG_INITIALIZE uint32_t length ; ///< Message length in bytes, must be 0x18 uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device. uint32_t major_version ; ///< The major version of the RNDIS Protocol implemented by the host. uint32_t minor_version ; ///< The minor version of the RNDIS Protocol implemented by the host uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the host expects to receive from the device. }rndis_msg_initialize_t; /// \brief Initialize Complete Message /// \details This message MUST be sent by the device in response to an initialize message. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_INITIALIZE_CMPLT uint32_t length ; ///< Message length in bytes, must be 0x30 uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_initialize_t to which this message is a response. uint32_t status ; ///< The initialization status of the device, has value from \ref rndis_msg_status_t uint32_t major_version ; ///< the highest-numbered RNDIS Protocol version supported by the device. uint32_t minor_version ; ///< the highest-numbered RNDIS Protocol version supported by the device. uint32_t device_flags ; ///< MUST be set to 0x000000010. Other values are reserved for future use. uint32_t medium ; ///< is 0x00 for RNDIS_MEDIUM_802_3 uint32_t max_packet_per_xfer ; ///< The maximum number of concatenated \ref RNDIS_MSG_PACKET messages that the device can handle in a single bus transfer to it. This value MUST be at least 1. uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the device expects to receive from the host. uint32_t packet_alignment_factor ; ///< The byte alignment the device expects for each RNDIS message that is part of a multimessage transfer to it. The value is specified as an exponent of 2; for example, the host uses 2{PacketAlignmentFactor} as the alignment value. uint32_t reserved[2] ; } rndis_msg_initialize_cmplt_t; //------------- Query -------------// /// \brief Query Message /// \details This message MUST be sent by the host to query an OID. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device. uint32_t oid ; ///< The integer value of the host operating system-defined identifier, for the parameter of the device being queried for. uint32_t buffer_length ; ///< The length, in bytes, of the input data required for the OID query. This MUST be set to 0 when there is no input data associated with the OID. uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the input data for the query is located in the message. This value MUST be set to 0 when there is no input data associated with the OID. uint32_t reserved ; uint8_t oid_buffer[] ; ///< Flexible array contains the input data supplied by the host, required for the OID query request processing by the device, as per the host NDIS specification. } rndis_msg_query_t, rndis_msg_set_t; TU_VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout"); /// \brief Query Complete Message /// \details This message MUST be sent by the device in response to a query OID message. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY_CMPLT uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_query_t to which this message is a response. uint32_t status ; ///< The status of processing for the query request, has value from \ref rndis_msg_status_t. uint32_t buffer_length ; ///< The length, in bytes, of the data in the response to the query. This MUST be set to 0 when there is no OIDInputBuffer. uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the response data for the query is located in the message. This MUST be set to 0 when there is no \ref oid_buffer. uint8_t oid_buffer[] ; ///< Flexible array member contains the response data to the OID query request as specified by the host. } rndis_msg_query_cmplt_t; TU_VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout"); //------------- Reset -------------// /// \brief Reset Message /// \details This message MUST be sent by the host to perform a soft reset on the device. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET uint32_t length ; ///< Message length in bytes, MUST be 0x06 uint32_t reserved ; } rndis_msg_reset_t; /// \brief Reset Complete Message /// \details This message MUST be sent by the device in response to a reset message. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET_CMPLT uint32_t length ; ///< Message length in bytes, MUST be 0x10 uint32_t status ; ///< The status of processing for the \ref rndis_msg_reset_t, has value from \ref rndis_msg_status_t. uint32_t addressing_reset ; ///< This field indicates whether the addressing information, which is the multicast address list or packet filter, has been lost during the reset operation. This MUST be set to 0x00000001 if the device requires that the host to resend addressing information or MUST be set to zero otherwise. } rndis_msg_reset_cmplt_t; //typedef struct { // uint32_t type; // uint32_t length; // uint32_t status; // uint32_t buffer_length; // uint32_t buffer_offset; // uint32_t diagnostic_status; // optional // uint32_t diagnostic_error_offset; // optional // uint32_t status_buffer[0]; // optional //} rndis_msg_indicate_status_t; /// \brief Keep Alive Message /// \details This message MUST be sent by the host to check that device is still responsive. It is optional for the device to send this message to check if the host is active typedef struct { uint32_t type ; ///< Message Type uint32_t length ; ///< Message length in bytes, MUST be 0x10 uint32_t request_id ; } rndis_msg_keep_alive_t, rndis_msg_halt_t; /// \brief Set Complete Message /// \brief This message MUST be sent in response to a the request message typedef struct { uint32_t type ; ///< Message Type uint32_t length ; ///< Message length in bytes, MUST be 0x10 uint32_t request_id ; ///< must be the same as requesting message uint32_t status ; ///< The status of processing for the request message request by the device to which this message is the response. } rndis_msg_set_cmplt_t, rndis_msg_keep_alive_cmplt_t; /// \brief Packet Data Message /// \brief This message MUST be used by the host and the device to send network data to one another. typedef struct { uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_PACKET uint32_t length ; ///< Message length in bytes, The total length of this RNDIS message including the header, payload, and padding. uint32_t data_offset ; ///< Specifies the offset, in bytes, from the start of this \a data_offset field of this message to the start of the data. This MUST be an integer multiple of 4. uint32_t data_length ; ///< Specifies the number of bytes in the payload of this message. uint32_t out_of_band_data_offet ; ///< Specifies the offset, in bytes, of the first out-of-band data record from the start of the DataOffset field in this message. MUST be an integer multiple of 4 when out-of-band data is present or set to 0 otherwise. When there are multiple out-ofband data records, each subsequent record MUST immediately follow the previous out-of-band data record. uint32_t out_of_band_data_length ; ///< Specifies, in bytes, the total length of the out-of-band data. uint32_t num_out_of_band_data_elements ; ///< Specifies the number of out-of-band records in this message. uint32_t per_packet_info_offset ; ///< Specifies the offset, in bytes, of the start of per-packet-info data record from the start of the \a data_offset field in this message. MUST be an integer multiple of 4 when per-packet-info data record is present or MUST be set to 0 otherwise. When there are multiple per-packet-info data records, each subsequent record MUST immediately follow the previous record. uint32_t per_packet_info_length ; ///< Specifies, in bytes, the total length of per-packetinformation contained in this message. uint32_t reserved[2] ; uint32_t payload[0] ; ///< Network data contained in this message. // uint8_t padding[0] // Additional bytes of zeros added at the end of the message to comply with // the internal and external padding requirements. Internal padding SHOULD be as per the // specification of the out-of-band data record and per-packet-info data record. The external //padding size SHOULD be determined based on the PacketAlignmentFactor field specification //in REMOTE_NDIS_INITIALIZE_CMPLT message by the device, when multiple //REMOTE_NDIS_PACKET_MSG messages are bundled together in a single bus-native message. //In this case, all but the very last REMOTE_NDIS_PACKET_MSG MUST respect the //PacketAlignmentFactor field. // rndis_msg_packet_t [0] : (optional) more packet if multiple packet per bus transaction is supported } rndis_msg_packet_t; typedef struct { uint32_t size ; ///< Length, in bytes, of this header and appended data and padding. This value MUST be an integer multiple of 4. uint32_t type ; ///< MUST be as per host operating system specification. uint32_t offset ; ///< The byte offset from the beginning of this record to the beginning of data. uint32_t data[0] ; ///< Flexible array contains data } rndis_msg_out_of_band_data_t, rndis_msg_per_packet_info_t; //--------------------------------------------------------------------+ // NDIS Object ID //--------------------------------------------------------------------+ /// NDIS Object ID typedef enum { //------------- General Required OIDs -------------// RNDIS_OID_GEN_SUPPORTED_LIST = 0x00010101, ///< List of supported OIDs RNDIS_OID_GEN_HARDWARE_STATUS = 0x00010102, ///< Hardware status RNDIS_OID_GEN_MEDIA_SUPPORTED = 0x00010103, ///< Media types supported (encoded) RNDIS_OID_GEN_MEDIA_IN_USE = 0x00010104, ///< Media types in use (encoded) RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, ///< RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, ///< Maximum frame size in bytes RNDIS_OID_GEN_LINK_SPEED = 0x00010107, ///< Link speed in units of 100 bps RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, ///< Transmit buffer space RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, ///< Receive buffer space RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010A, ///< Minimum amount of storage, in bytes, that a single packet occupies in the transmit buffer space of the NIC RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010B, ///< Amount of storage, in bytes, that a single packet occupies in the receive buffer space of the NIC RNDIS_OID_GEN_VENDOR_ID = 0x0001010C, ///< Vendor NIC code RNDIS_OID_GEN_VENDOR_DESCRIPTION = 0x0001010D, ///< Vendor network card description RNDIS_OID_GEN_CURRENT_PACKET_FILTER = 0x0001010E, ///< Current packet filter (encoded) RNDIS_OID_GEN_CURRENT_LOOKAHEAD = 0x0001010F, ///< Current lookahead size in bytes RNDIS_OID_GEN_DRIVER_VERSION = 0x00010110, ///< NDIS version number used by the driver RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, ///< Maximum total packet length in bytes RNDIS_OID_GEN_PROTOCOL_OPTIONS = 0x00010112, ///< Optional protocol flags (encoded) RNDIS_OID_GEN_MAC_OPTIONS = 0x00010113, ///< Optional NIC flags (encoded) RNDIS_OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, ///< Whether the NIC is connected to the network RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, ///< The maximum number of send packets the driver can accept per call to its MiniportSendPacketsfunction //------------- General Optional OIDs -------------// RNDIS_OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, ///< Vendor-assigned version number of the driver RNDIS_OID_GEN_SUPPORTED_GUIDS = 0x00010117, ///< The custom GUIDs (Globally Unique Identifier) supported by the miniport driver RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, ///< List of network-layer addresses associated with the binding between a transport and the driver RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, ///< Size of packets' additional headers RNDIS_OID_GEN_MEDIA_CAPABILITIES = 0x00010201, ///< RNDIS_OID_GEN_PHYSICAL_MEDIUM = 0x00010202, ///< Physical media supported by the miniport driver (encoded) //------------- 802.3 Objects (Ethernet) -------------// RNDIS_OID_802_3_PERMANENT_ADDRESS = 0x01010101, ///< Permanent station address RNDIS_OID_802_3_CURRENT_ADDRESS = 0x01010102, ///< Current station address RNDIS_OID_802_3_MULTICAST_LIST = 0x01010103, ///< Current multicast address list RNDIS_OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, ///< Maximum size of multicast address list } rndis_oid_type_t; /// RNDIS Packet Filter Bits \ref RNDIS_OID_GEN_CURRENT_PACKET_FILTER. typedef enum { RNDIS_PACKET_TYPE_DIRECTED = 0x00000001, ///< Directed packets. Directed packets contain a destination address equal to the station address of the NIC. RNDIS_PACKET_TYPE_MULTICAST = 0x00000002, ///< Multicast address packets sent to addresses in the multicast address list. RNDIS_PACKET_TYPE_ALL_MULTICAST = 0x00000004, ///< All multicast address packets, not just the ones enumerated in the multicast address list. RNDIS_PACKET_TYPE_BROADCAST = 0x00000008, ///< Broadcast packets. RNDIS_PACKET_TYPE_SOURCE_ROUTING = 0x00000010, ///< All source routing packets. If the protocol driver sets this bit, the NDIS library attempts to act as a source routing bridge. RNDIS_PACKET_TYPE_PROMISCUOUS = 0x00000020, ///< Specifies all packets regardless of whether VLAN filtering is enabled or not and whether the VLAN identifier matches or not. RNDIS_PACKET_TYPE_SMT = 0x00000040, ///< SMT packets that an FDDI NIC receives. RNDIS_PACKET_TYPE_ALL_LOCAL = 0x00000080, ///< All packets sent by installed protocols and all packets indicated by the NIC that is identified by a given NdisBindingHandle. RNDIS_PACKET_TYPE_GROUP = 0x00001000, ///< Packets sent to the current group address. RNDIS_PACKET_TYPE_ALL_FUNCTIONAL = 0x00002000, ///< All functional address packets, not just the ones in the current functional address. RNDIS_PACKET_TYPE_FUNCTIONAL = 0x00004000, ///< Functional address packets sent to addresses included in the current functional address. RNDIS_PACKET_TYPE_MAC_FRAME = 0x00008000, ///< NIC driver frames that a Token Ring NIC receives. RNDIS_PACKET_TYPE_NO_LOCAL = 0x00010000, } rndis_packet_filter_type_t; #ifdef __cplusplus } #endif #endif /* TUSB_CDC_RNDIS_H_ */ /** @} */ /** @} */ ================================================ FILE: src/class/cdc/serial/ch34x.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Heiko Kuester * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_CH34X_H #define TUSB_CH34X_H // There is no official documentation for the CH34x (CH340, CH341) chips. Reference can be found // - https://github.com/WCHSoftGroup/ch341ser_linux // - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c // - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c // set line_coding @ enumeration #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM #define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM #else // this default is necessary to work properly #define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } #endif // USB requests #define CH34X_REQ_READ_VERSION 0x5F // dec 95 #define CH34X_REQ_WRITE_REG 0x9A // dec 154 #define CH34X_REQ_READ_REG 0x95 // dec 149 #define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 #define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 // registers #define CH34X_REG_BREAK 0x05 #define CH34X_REG_PRESCALER 0x12 #define CH34X_REG_DIVISOR 0x13 #define CH34X_REG_LCR 0x18 #define CH34X_REG_LCR2 0x25 #define CH34X_REG_MCR_MSR 0x06 #define CH34X_REG_MCR_MSR2 0x07 #define CH34X_NBREAK_BITS 0x01 #define CH341_REG_0x0F 0x0F // undocumented register #define CH341_REG_0x2C 0x2C // undocumented register #define CH341_REG_0x27 0x27 // hardware flow control (cts/rts) #define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) #define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR) // modem control bits #define CH34X_BIT_RTS (1 << 6) #define CH34X_BIT_DTR (1 << 5) // line control bits #define CH34X_LCR_ENABLE_RX 0x80 #define CH34X_LCR_ENABLE_TX 0x40 #define CH34X_LCR_MARK_SPACE 0x20 #define CH34X_LCR_PAR_EVEN 0x10 #define CH34X_LCR_ENABLE_PAR 0x08 #define CH34X_LCR_PAR_MASK 0x38 // all parity bits #define CH34X_LCR_STOP_BITS_2 0x04 #define CH34X_LCR_CS8 0x03 #define CH34X_LCR_CS7 0x02 #define CH34X_LCR_CS6 0x01 #define CH34X_LCR_CS5 0x00 #define CH34X_LCR_CS_MASK 0x03 // all CSx bits #endif // TUSB_CH34X_H ================================================ FILE: src/class/cdc/serial/cp210x.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries * * 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. */ #ifndef TUSB_CP210X_H #define TUSB_CP210X_H // Protocol details can be found at AN571: CP210x Virtual COM Port Interface // https://www.silabs.com/documents/public/application-notes/AN571.pdf // parts are overtaken from vendors driver // https://www.silabs.com/documents/public/software/cp210x-3.1.0.tar.gz // Config request codes #define CP210X_IFC_ENABLE 0x00 #define CP210X_SET_BAUDDIV 0x01 #define CP210X_GET_BAUDDIV 0x02 #define CP210X_SET_LINE_CTL 0x03 // Set parity, data bits, stop bits #define CP210X_GET_LINE_CTL 0x04 #define CP210X_SET_BREAK 0x05 #define CP210X_IMM_CHAR 0x06 #define CP210X_SET_MHS 0x07 // Set DTR, RTS #define CP210X_GET_MDMSTS 0x08 // Get modem status (DTR, RTS, CTS, DSR, RI, DCD) #define CP210X_SET_XON 0x09 #define CP210X_SET_XOFF 0x0A #define CP210X_SET_EVENTMASK 0x0B #define CP210X_GET_EVENTMASK 0x0C #define CP210X_SET_CHAR 0x0D #define CP210X_GET_CHARS 0x0E #define CP210X_GET_PROPS 0x0F #define CP210X_GET_COMM_STATUS 0x10 #define CP210X_RESET 0x11 #define CP210X_PURGE 0x12 #define CP210X_SET_FLOW 0x13 #define CP210X_GET_FLOW 0x14 #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 #define CP210X_GET_BAUDRATE 0x1D #define CP210X_SET_BAUDRATE 0x1E #define CP210X_VENDOR_SPECIFIC 0xFF // GPIO, Recipient must be Device // SILABSER_IFC_ENABLE_REQUEST_CODE #define CP210X_UART_ENABLE 0x0001 #define CP210X_UART_DISABLE 0x0000 // SILABSER_SET_BAUDDIV_REQUEST_CODE #define CP210X_BAUD_RATE_GEN_FREQ 0x384000 // SILABSER_SET_LINE_CTL_REQUEST_CODE #define CP210X_BITS_DATA_MASK 0x0f00 #define CP210X_BITS_DATA_5 0x0500 #define CP210X_BITS_DATA_6 0x0600 #define CP210X_BITS_DATA_7 0x0700 #define CP210X_BITS_DATA_8 0x0800 #define CP210X_BITS_DATA_9 0x0900 #define CP210X_BITS_PARITY_MASK 0x00f0 #define CP210X_BITS_PARITY_NONE 0x0000 #define CP210X_BITS_PARITY_ODD 0x0010 #define CP210X_BITS_PARITY_EVEN 0x0020 #define CP210X_BITS_PARITY_MARK 0x0030 #define CP210X_BITS_PARITY_SPACE 0x0040 #define CP210X_BITS_STOP_MASK 0x000f #define CP210X_BITS_STOP_1 0x0000 #define CP210X_BITS_STOP_1_5 0x0001 #define CP210X_BITS_STOP_2 0x0002 // SILABSER_SET_BREAK_REQUEST_CODE #define CP210X_BREAK_ON 0x0001 #define CP210X_BREAK_OFF 0x0000 // SILABSER_SET_MHS_REQUEST_CODE #define CP210X_MCR_DTR 0x0001 #define CP210X_MCR_RTS 0x0002 #define CP210X_MCR_ALL 0x0003 #define CP210X_MSR_CTS 0x0010 #define CP210X_MSR_DSR 0x0020 #define CP210X_MSR_RING 0x0040 #define CP210X_MSR_DCD 0x0080 #define CP210X_MSR_ALL 0x00F0 #define CP210X_CONTROL_WRITE_DTR 0x0100UL #define CP210X_CONTROL_WRITE_RTS 0x0200UL #define CP210X_LSR_BREAK 0x0001 #define CP210X_LSR_FRAMING_ERROR 0x0002 #define CP210X_LSR_HW_OVERRUN 0x0004 #define CP210X_LSR_QUEUE_OVERRUN 0x0008 #define CP210X_LSR_PARITY_ERROR 0x0010 #define CP210X_LSR_ALL 0x001F #endif //TUSB_CP210X_H ================================================ FILE: src/class/cdc/serial/ftdi_sio.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries * * 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. */ #ifndef TUSB_FTDI_SIO_H #define TUSB_FTDI_SIO_H #include // Commands #define FTDI_SIO_RESET 0 // Reset the port #define FTDI_SIO_MODEM_CTRL 1 // Set the modem control register #define FTDI_SIO_SET_FLOW_CTRL 2 // Set flow control register #define FTDI_SIO_SET_BAUD_RATE 3 // Set baud rate #define FTDI_SIO_SET_DATA 4 // Set the data characteristics of the port #define FTDI_SIO_GET_MODEM_STATUS 5 // Retrieve current value of modem status register #define FTDI_SIO_SET_EVENT_CHAR 6 // Set the event character #define FTDI_SIO_SET_ERROR_CHAR 7 // Set the error character #define FTDI_SIO_SET_LATENCY_TIMER 9 // Set the latency timer #define FTDI_SIO_GET_LATENCY_TIMER 10 // Get the latency timer #define FTDI_SIO_SET_BITMODE 11 // Set bitbang mode #define FTDI_SIO_READ_PINS 12 // Read immediate value of pins #define FTDI_SIO_READ_EEPROM 0x90 // Read EEPROM // Channel indices for FT2232, FT2232H and FT4232H devices #define CHANNEL_A 1 #define CHANNEL_B 2 #define CHANNEL_C 3 #define CHANNEL_D 4 // Port Identifier Table #define PIT_DEFAULT 0 // SIOA #define PIT_SIOA 1 // SIOA // The device this driver is tested with one has only one port #define PIT_SIOB 2 // SIOB #define PIT_PARALLEL 3 // Parallel // FTDI_SIO_RESET #define FTDI_SIO_RESET_REQUEST FTDI_SIO_RESET #define FTDI_SIO_RESET_REQUEST_TYPE 0x40 #define FTDI_SIO_RESET_SIO 0 #define FTDI_SIO_RESET_PURGE_RX 1 #define FTDI_SIO_RESET_PURGE_TX 2 // FTDI_SIO_SET_BAUDRATE #define FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE 0x40 #define FTDI_SIO_SET_BAUDRATE_REQUEST 3 enum ftdi_sio_baudrate { ftdi_sio_b300 = 0, ftdi_sio_b600 = 1, ftdi_sio_b1200 = 2, ftdi_sio_b2400 = 3, ftdi_sio_b4800 = 4, ftdi_sio_b9600 = 5, ftdi_sio_b19200 = 6, ftdi_sio_b38400 = 7, ftdi_sio_b57600 = 8, ftdi_sio_b115200 = 9 }; // FTDI_SIO_SET_DATA #define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA #define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40 #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8) #define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8) #define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8) #define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8) #define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8) #define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11) // same coding as ACM #define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11) // 1.5 not supported, for future use? #define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11) #define FTDI_SIO_SET_BREAK (0x1 << 14) // FTDI_SIO_MODEM_CTRL #define FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40 #define FTDI_SIO_SET_MODEM_CTRL_REQUEST FTDI_SIO_MODEM_CTRL #define FTDI_SIO_SET_DTR_MASK 0x1UL #define FTDI_SIO_SET_DTR_HIGH ((FTDI_SIO_SET_DTR_MASK << 8) | 1UL) #define FTDI_SIO_SET_DTR_LOW ((FTDI_SIO_SET_DTR_MASK << 8) | 0UL) #define FTDI_SIO_SET_RTS_MASK 0x2UL #define FTDI_SIO_SET_RTS_HIGH ((FTDI_SIO_SET_RTS_MASK << 8) | 2UL) #define FTDI_SIO_SET_RTS_LOW ((FTDI_SIO_SET_RTS_MASK << 8) | 0UL) // FTDI_SIO_SET_FLOW_CTRL #define FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40 #define FTDI_SIO_SET_FLOW_CTRL_REQUEST FTDI_SIO_SET_FLOW_CTRL #define FTDI_SIO_DISABLE_FLOW_CTRL 0x0 #define FTDI_SIO_RTS_CTS_HS (0x1 << 8) #define FTDI_SIO_DTR_DSR_HS (0x2 << 8) #define FTDI_SIO_XON_XOFF_HS (0x4 << 8) // FTDI_SIO_GET_LATENCY_TIMER #define FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER #define FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0 // FTDI_SIO_SET_LATENCY_TIMER #define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER #define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40 // FTDI_SIO_SET_EVENT_CHAR #define FTDI_SIO_SET_EVENT_CHAR_REQUEST FTDI_SIO_SET_EVENT_CHAR #define FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE 0x40 // FTDI_SIO_GET_MODEM_STATUS #define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0 #define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS #define FTDI_SIO_CTS_MASK 0x10 #define FTDI_SIO_DSR_MASK 0x20 #define FTDI_SIO_RI_MASK 0x40 #define FTDI_SIO_RLSD_MASK 0x80 // FTDI_SIO_SET_BITMODE #define FTDI_SIO_SET_BITMODE_REQUEST_TYPE 0x40 #define FTDI_SIO_SET_BITMODE_REQUEST FTDI_SIO_SET_BITMODE // Possible bitmodes for FTDI_SIO_SET_BITMODE_REQUEST #define FTDI_SIO_BITMODE_RESET 0x00 #define FTDI_SIO_BITMODE_CBUS 0x20 // FTDI_SIO_READ_PINS #define FTDI_SIO_READ_PINS_REQUEST_TYPE 0xc0 #define FTDI_SIO_READ_PINS_REQUEST FTDI_SIO_READ_PINS // FTDI_SIO_READ_EEPROM #define FTDI_SIO_READ_EEPROM_REQUEST_TYPE 0xc0 #define FTDI_SIO_READ_EEPROM_REQUEST FTDI_SIO_READ_EEPROM #define FTDI_FTX_CBUS_MUX_GPIO 0x8 #define FTDI_FT232R_CBUS_MUX_GPIO 0xa #define FTDI_RS0_CTS (1 << 4) #define FTDI_RS0_DSR (1 << 5) #define FTDI_RS0_RI (1 << 6) #define FTDI_RS0_RLSD (1 << 7) #define FTDI_RS_DR 1 #define FTDI_RS_OE (1 << 1) #define FTDI_RS_PE (1 << 2) #define FTDI_RS_FE (1 << 3) #define FTDI_RS_BI (1 << 4) #define FTDI_RS_THRE (1 << 5) #define FTDI_RS_TEMT (1 << 6) #define FTDI_RS_FIFO (1 << 7) // chip types and names typedef enum ftdi_chip_type { FTDI_SIO = 0, // FTDI_FT232A, FTDI_FT232B, FTDI_FT2232C, FTDI_FT232R, FTDI_FT232H, FTDI_FT2232H, FTDI_FT4232H, FTDI_FT4232HA, FTDI_FT232HP, FTDI_FT233HP, FTDI_FT2232HP, FTDI_FT2233HP, FTDI_FT4232HP, FTDI_FT4233HP, FTDI_FTX, FTDI_UNKNOWN } ftdi_chip_type_t; #define FTDI_CHIP_NAMES \ [FTDI_SIO] = "SIO", /* the serial part of FT8U100AX */ \ /* [FTDI_FT232A] = "FT232A", */ \ [FTDI_FT232B] = "FT232B", \ [FTDI_FT2232C] = "FT2232C/D", \ [FTDI_FT232R] = "FT232R", \ [FTDI_FT232H] = "FT232H", \ [FTDI_FT2232H] = "FTDI_FT2232H", \ [FTDI_FT4232H] = "FT4232H", \ [FTDI_FT4232HA] = "FT4232HA", \ [FTDI_FT232HP] = "FT232HP", \ [FTDI_FT233HP] = "FT233HP", \ [FTDI_FT2232HP] = "FT2232HP", \ [FTDI_FT2233HP] = "FT2233HP", \ [FTDI_FT4232HP] = "FT4232HP", \ [FTDI_FT4233HP] = "FT4233HP", \ [FTDI_FTX] = "FT-X", \ [FTDI_UNKNOWN] = "UNKNOWN" // private interface data typedef struct ftdi_private { ftdi_chip_type_t chip_type; uint8_t channel; // channel index, or 0 for legacy types } ftdi_private_t; #define FTDI_OK true #define FTDI_FAIL false #define FTDI_NOT_POSSIBLE -1 #define FTDI_REQUESTED -2 #endif //TUSB_FTDI_SIO_H ================================================ FILE: src/class/cdc/serial/pl2303.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Heiko Kuester * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_PL2303_H #define TUSB_PL2303_H #include #include // There is no official documentation for the PL2303 chips. // Reference can be found // - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/pl2303.h and // https://github.com/torvalds/linux/blob/master/drivers/usb/serial/pl2303.c // - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uplcom.c // quirks #define PL2303_QUIRK_UART_STATE_IDX0 1 #define PL2303_QUIRK_LEGACY 2 #define PL2303_QUIRK_ENDPOINT_HACK 4 // requests and bits #define PL2303_SET_LINE_REQUEST_TYPE 0x21 // class request host to device interface #define PL2303_SET_LINE_REQUEST 0x20 // dec 32 #define PL2303_SET_CONTROL_REQUEST_TYPE 0x21 // class request host to device interface #define PL2303_SET_CONTROL_REQUEST 0x22 // dec 34 #define PL2303_CONTROL_DTR 0x01 // dec 1 #define PL2303_CONTROL_RTS 0x02 // dec 2 #define PL2303_BREAK_REQUEST_TYPE 0x21 // class request host to device interface #define PL2303_BREAK_REQUEST 0x23 // dec 35 #define PL2303_BREAK_ON 0xffff #define PL2303_BREAK_OFF 0x0000 #define PL2303_GET_LINE_REQUEST_TYPE 0xa1 // class request device to host interface #define PL2303_GET_LINE_REQUEST 0x21 // dec 33 #define PL2303_VENDOR_WRITE_REQUEST_TYPE 0x40 // vendor request host to device interface #define PL2303_VENDOR_WRITE_REQUEST 0x01 // dec 1 #define PL2303_VENDOR_WRITE_NREQUEST 0x80 // dec 128 #define PL2303_VENDOR_READ_REQUEST_TYPE 0xc0 // vendor request device to host interface #define PL2303_VENDOR_READ_REQUEST 0x01 // dec 1 #define PL2303_VENDOR_READ_NREQUEST 0x81 // dec 129 #define PL2303_UART_STATE_INDEX 8 #define PL2303_UART_STATE_MSR_MASK 0x8b #define PL2303_UART_STATE_TRANSIENT_MASK 0x74 #define PL2303_UART_DCD 0x01 #define PL2303_UART_DSR 0x02 #define PL2303_UART_BREAK_ERROR 0x04 #define PL2303_UART_RING 0x08 #define PL2303_UART_FRAME_ERROR 0x10 #define PL2303_UART_PARITY_ERROR 0x20 #define PL2303_UART_OVERRUN_ERROR 0x40 #define PL2303_UART_CTS 0x80 #define PL2303_FLOWCTRL_MASK 0xf0 #define PL2303_CLEAR_HALT_REQUEST_TYPE 0x02 // standard request host to device endpoint // registers via vendor read/write requests #define PL2303_READ_TYPE_HX_STATUS 0x8080 #define PL2303_HXN_RESET_REG 0x07 #define PL2303_HXN_RESET_UPSTREAM_PIPE 0x02 #define PL2303_HXN_RESET_DOWNSTREAM_PIPE 0x01 #define PL2303_HXN_FLOWCTRL_REG 0x0a #define PL2303_HXN_FLOWCTRL_MASK 0x1c #define PL2303_HXN_FLOWCTRL_NONE 0x1c #define PL2303_HXN_FLOWCTRL_RTS_CTS 0x18 #define PL2303_HXN_FLOWCTRL_XON_XOFF 0x0c // type data typedef enum pl2303_type { PL2303_TYPE_H = 0, // 0 PL2303_TYPE_HX, // 1 PL2303_TYPE_TA, // 2 PL2303_TYPE_TB, // 3 PL2303_TYPE_HXD, // 4 PL2303_TYPE_HXN, // 5 PL2303_TYPE_COUNT, PL2303_TYPE_NEED_SUPPORTS_HX_STATUS, PL2303_TYPE_UNKNOWN, } pl2303_type_t; typedef struct pl2303_type_data { uint32_t max_baud_rate; uint8_t quirks; uint8_t no_autoxonxoff : 1; uint8_t no_divisors : 1; uint8_t alt_divisors : 1; } pl2303_type_data_t; #define PL2303_TYPE_DATA \ [PL2303_TYPE_H] = { \ .max_baud_rate = 1228800, .quirks = PL2303_QUIRK_LEGACY, \ .no_autoxonxoff = 1, .no_divisors = 0, .alt_divisors = 0 \ }, \ [PL2303_TYPE_HX] = { \ .max_baud_rate = 6000000, .quirks = 0, \ .no_autoxonxoff = 0, .no_divisors = 0, .alt_divisors = 0 \ }, \ [PL2303_TYPE_TA] = { \ .max_baud_rate = 6000000, .quirks = 0, \ .no_autoxonxoff = 0, .no_divisors = 0, .alt_divisors = 1 \ }, \ [PL2303_TYPE_TB] = { \ .max_baud_rate = 12000000, .quirks = 0, \ .no_autoxonxoff = 0, .no_divisors = 0, .alt_divisors = 1 \ }, \ [PL2303_TYPE_HXD] = { \ .max_baud_rate = 12000000, .quirks = 0, \ .no_autoxonxoff = 0, .no_divisors = 0, .alt_divisors = 0 \ }, \ [PL2303_TYPE_HXN] = { \ .max_baud_rate = 12000000, .quirks = 0, \ .no_autoxonxoff = 0, .no_divisors = 1, .alt_divisors = 0 \ } typedef struct TU_ATTR_PACKED { pl2303_type_t type; uint8_t quirks; bool supports_hx_status; } pl2303_private_t; // buffer sizes for line coding data #define PL2303_LINE_CODING_BUFSIZE 7 #define PL2303_LINE_CODING_BAUDRATE_BUFSIZE 4 // bulk endpoints #define PL2303_OUT_EP 0x02 #define PL2303_IN_EP 0x83 #endif // TUSB_PL2303_H ================================================ FILE: src/class/dfu/dfu.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 XMOS LIMITED * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DFU_H_ #define TUSB_DFU_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Common Definitions //--------------------------------------------------------------------+ // DFU Protocol typedef enum { DFU_PROTOCOL_RT = 0x01, DFU_PROTOCOL_DFU = 0x02, } dfu_protocol_type_t; // DFU Descriptor Type typedef enum { DFU_DESC_FUNCTIONAL = 0x21, } dfu_descriptor_type_t; // DFU Requests typedef enum { DFU_REQUEST_DETACH = 0, DFU_REQUEST_DNLOAD = 1, DFU_REQUEST_UPLOAD = 2, DFU_REQUEST_GETSTATUS = 3, DFU_REQUEST_CLRSTATUS = 4, DFU_REQUEST_GETSTATE = 5, DFU_REQUEST_ABORT = 6, } dfu_requests_t; // DFU States typedef enum { APP_IDLE = 0, APP_DETACH = 1, DFU_IDLE = 2, DFU_DNLOAD_SYNC = 3, DFU_DNBUSY = 4, DFU_DNLOAD_IDLE = 5, DFU_MANIFEST_SYNC = 6, DFU_MANIFEST = 7, DFU_MANIFEST_WAIT_RESET = 8, DFU_UPLOAD_IDLE = 9, DFU_ERROR = 10, } dfu_state_t; // DFU Status typedef enum { DFU_STATUS_OK = 0x00, DFU_STATUS_ERR_TARGET = 0x01, DFU_STATUS_ERR_FILE = 0x02, DFU_STATUS_ERR_WRITE = 0x03, DFU_STATUS_ERR_ERASE = 0x04, DFU_STATUS_ERR_CHECK_ERASED = 0x05, DFU_STATUS_ERR_PROG = 0x06, DFU_STATUS_ERR_VERIFY = 0x07, DFU_STATUS_ERR_ADDRESS = 0x08, DFU_STATUS_ERR_NOTDONE = 0x09, DFU_STATUS_ERR_FIRMWARE = 0x0A, DFU_STATUS_ERR_VENDOR = 0x0B, DFU_STATUS_ERR_USBR = 0x0C, DFU_STATUS_ERR_POR = 0x0D, DFU_STATUS_ERR_UNKNOWN = 0x0E, DFU_STATUS_ERR_STALLEDPKT = 0x0F, } dfu_status_t; #define DFU_ATTR_CAN_DOWNLOAD (1u << 0) #define DFU_ATTR_CAN_UPLOAD (1u << 1) #define DFU_ATTR_MANIFESTATION_TOLERANT (1u << 2) #define DFU_ATTR_WILL_DETACH (1u << 3) // DFU Status Request Payload typedef struct TU_ATTR_PACKED { uint8_t bStatus; uint8_t bwPollTimeout[3]; uint8_t bState; uint8_t iString; } dfu_status_response_t; TU_VERIFY_STATIC( sizeof(dfu_status_response_t) == 6, "size is not correct"); #ifdef __cplusplus } #endif #endif /* TUSB_DFU_H_ */ ================================================ FILE: src/class/dfu/dfu_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 XMOS LIMITED * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_DFU) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "dfu_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_DFU_LOG_LEVEL #define CFG_TUD_DFU_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ typedef struct { uint8_t attrs; uint8_t alt; uint8_t state; uint8_t status; bool flashing_in_progress; uint16_t block; uint16_t length; } dfu_state_ctx_t; static dfu_state_ctx_t _dfu_ctx; #if CFG_TUD_DFU_XFER_BUFSIZE > CFG_TUD_ENDPOINT0_BUFSIZE TU_ATTR_ALIGNED(4) uint8_t _transfer_buf[CFG_TUD_DFU_XFER_BUFSIZE]; #endif static void reset_state(void) { _dfu_ctx.state = DFU_IDLE; _dfu_ctx.status = DFU_STATUS_OK; _dfu_ctx.flashing_in_progress = false; } static inline uint8_t* get_xfer_buffer(void) { // Use EP0 buffer if it is large enough, otherwise use dedicated buffer #if CFG_TUD_DFU_XFER_BUFSIZE > CFG_TUD_ENDPOINT0_BUFSIZE return _transfer_buf; #else return usbd_get_ctrl_buf(); #endif } static bool reply_getstatus(uint8_t rhport, const tusb_control_request_t* request, dfu_state_t state, dfu_status_t status, uint32_t timeout); static bool process_download_get_status(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request); static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request); //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_dfu_detach_cb(void) { } TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt) { (void) alt; } TU_ATTR_WEAK uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) { (void) alt; (void) block_num; (void) data; (void) length; return 0; } //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= 2 tu_static tu_lookup_entry_t const _dfu_request_lookup[] = { { .key = DFU_REQUEST_DETACH , .data = "DETACH" }, { .key = DFU_REQUEST_DNLOAD , .data = "DNLOAD" }, { .key = DFU_REQUEST_UPLOAD , .data = "UPLOAD" }, { .key = DFU_REQUEST_GETSTATUS, .data = "GETSTATUS" }, { .key = DFU_REQUEST_CLRSTATUS, .data = "CLRSTATUS" }, { .key = DFU_REQUEST_GETSTATE , .data = "GETSTATE" }, { .key = DFU_REQUEST_ABORT , .data = "ABORT" }, }; tu_static tu_lookup_table_t const _dfu_request_table = { .count = TU_ARRAY_SIZE(_dfu_request_lookup), .items = _dfu_request_lookup }; tu_static tu_lookup_entry_t const _dfu_state_lookup[] = { { .key = APP_IDLE , .data = "APP_IDLE" }, { .key = APP_DETACH , .data = "APP_DETACH" }, { .key = DFU_IDLE , .data = "IDLE" }, { .key = DFU_DNLOAD_SYNC , .data = "DNLOAD_SYNC" }, { .key = DFU_DNBUSY , .data = "DNBUSY" }, { .key = DFU_DNLOAD_IDLE , .data = "DNLOAD_IDLE" }, { .key = DFU_MANIFEST_SYNC , .data = "MANIFEST_SYNC" }, { .key = DFU_MANIFEST , .data = "MANIFEST" }, { .key = DFU_MANIFEST_WAIT_RESET, .data = "MANIFEST_WAIT_RESET" }, { .key = DFU_UPLOAD_IDLE , .data = "UPLOAD_IDLE" }, { .key = DFU_ERROR , .data = "ERROR" }, }; tu_static tu_lookup_table_t const _dfu_state_table = { .count = TU_ARRAY_SIZE(_dfu_state_lookup), .items = _dfu_state_lookup }; tu_static tu_lookup_entry_t const _dfu_status_lookup[] = { { .key = DFU_STATUS_OK , .data = "OK" }, { .key = DFU_STATUS_ERR_TARGET , .data = "errTARGET" }, { .key = DFU_STATUS_ERR_FILE , .data = "errFILE" }, { .key = DFU_STATUS_ERR_WRITE , .data = "errWRITE" }, { .key = DFU_STATUS_ERR_ERASE , .data = "errERASE" }, { .key = DFU_STATUS_ERR_CHECK_ERASED , .data = "errCHECK_ERASED" }, { .key = DFU_STATUS_ERR_PROG , .data = "errPROG" }, { .key = DFU_STATUS_ERR_VERIFY , .data = "errVERIFY" }, { .key = DFU_STATUS_ERR_ADDRESS , .data = "errADDRESS" }, { .key = DFU_STATUS_ERR_NOTDONE , .data = "errNOTDONE" }, { .key = DFU_STATUS_ERR_FIRMWARE , .data = "errFIRMWARE" }, { .key = DFU_STATUS_ERR_VENDOR , .data = "errVENDOR" }, { .key = DFU_STATUS_ERR_USBR , .data = "errUSBR" }, { .key = DFU_STATUS_ERR_POR , .data = "errPOR" }, { .key = DFU_STATUS_ERR_UNKNOWN , .data = "errUNKNOWN" }, { .key = DFU_STATUS_ERR_STALLEDPKT , .data = "errSTALLEDPKT" }, }; tu_static tu_lookup_table_t const _dfu_status_table = { .count = TU_ARRAY_SIZE(_dfu_status_lookup), .items = _dfu_status_lookup }; #endif //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void dfu_moded_reset(uint8_t rhport) { (void) rhport; _dfu_ctx.attrs = 0; _dfu_ctx.alt = 0; reset_state(); } void dfu_moded_init(void) { dfu_moded_reset(0); } bool dfu_moded_deinit(void) { return true; } uint16_t dfu_moded_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { (void) rhport; //------------- Interface (with Alt) descriptor -------------// const uint8_t itf_num = itf_desc->bInterfaceNumber; uint8_t alt_count = 0; uint16_t drv_len = 0; TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU, 0); while(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU) { TU_ASSERT(max_len > drv_len, 0); // Alternate must have the same interface number TU_ASSERT(itf_desc->bInterfaceNumber == itf_num, 0); // Alt should increase by one every time TU_ASSERT(itf_desc->bAlternateSetting == alt_count, 0); alt_count++; drv_len += tu_desc_len(itf_desc); itf_desc = (const tusb_desc_interface_t*) tu_desc_next(itf_desc); } //------------- DFU Functional descriptor -------------// const tusb_desc_dfu_functional_t*func_desc = (const tusb_desc_dfu_functional_t*) itf_desc; TU_ASSERT(tu_desc_type(func_desc) == TUSB_DESC_FUNCTIONAL, 0); drv_len += sizeof(tusb_desc_dfu_functional_t); _dfu_ctx.attrs = func_desc->bAttributes; // CFG_TUD_DFU_XFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR const uint16_t transfer_size = tu_le16toh( tu_unaligned_read16((const uint8_t*) func_desc + offsetof(tusb_desc_dfu_functional_t, wTransferSize)) ); TU_ASSERT(transfer_size <= CFG_TUD_DFU_XFER_BUFSIZE, drv_len); return drv_len; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); TU_LOG_DRV(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status)); if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { // Standard request include GET/SET_INTERFACE switch (request->bRequest) { case TUSB_REQ_SET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { // Switch Alt interface and reset state machine _dfu_ctx.alt = (uint8_t)request->wValue; reset_state(); return tud_control_status(rhport, request); } break; case TUSB_REQ_GET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { return tud_control_xfer(rhport, request, &_dfu_ctx.alt, 1); } break; // unsupported request default: return false; } } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { TU_LOG_DRV(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); // Class request switch (request->bRequest) { case DFU_REQUEST_DETACH: if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { tud_dfu_detach_cb(); } else { // nothing to do } break; case DFU_REQUEST_CLRSTATUS: if (stage == CONTROL_STAGE_SETUP) { reset_state(); tud_control_status(rhport, request); } break; case DFU_REQUEST_GETSTATE: if (stage == CONTROL_STAGE_SETUP) { tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); } break; case DFU_REQUEST_ABORT: if (stage == CONTROL_STAGE_SETUP) { reset_state(); tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { tud_dfu_abort_cb(_dfu_ctx.alt); } else { // nothing to do } break; case DFU_REQUEST_UPLOAD: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_UPLOAD); TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); const uint16_t xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt, request->wValue, get_xfer_buffer(), request->wLength); return tud_control_xfer(rhport, request, get_xfer_buffer(), xfer_len); } break; case DFU_REQUEST_DNLOAD: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD); TU_VERIFY(_dfu_ctx.state == DFU_IDLE || _dfu_ctx.state == DFU_DNLOAD_IDLE); TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); // set to true for both download and manifest _dfu_ctx.flashing_in_progress = true; // save block and length for flashing _dfu_ctx.block = request->wValue; _dfu_ctx.length = request->wLength; if (request->wLength > 0) { // Download with payload -> transition to DOWNLOAD SYNC _dfu_ctx.state = DFU_DNLOAD_SYNC; return tud_control_xfer(rhport, request, get_xfer_buffer(), request->wLength); } else { // Download is complete -> transition to MANIFEST SYNC _dfu_ctx.state = DFU_MANIFEST_SYNC; return tud_control_status(rhport, request); } } break; case DFU_REQUEST_GETSTATUS: switch (_dfu_ctx.state) { case DFU_DNLOAD_SYNC: return process_download_get_status(rhport, stage, request); break; case DFU_MANIFEST_SYNC: return process_manifest_get_status(rhport, stage, request); break; default: if (stage == CONTROL_STAGE_SETUP) { return reply_getstatus(rhport, request, (dfu_state_t) _dfu_ctx.state, (dfu_status_t) _dfu_ctx.status, 0); } break; } break; default: return false; // stall unsupported request } } else { return false; // unsupported request } return true; } void tud_dfu_finish_flashing(uint8_t status) { _dfu_ctx.flashing_in_progress = false; if (status == DFU_STATUS_OK) { if (_dfu_ctx.state == DFU_DNBUSY) { _dfu_ctx.state = DFU_DNLOAD_SYNC; } else if (_dfu_ctx.state == DFU_MANIFEST) { _dfu_ctx.state = (_dfu_ctx.attrs & DFU_ATTR_MANIFESTATION_TOLERANT) ? DFU_MANIFEST_SYNC : DFU_MANIFEST_WAIT_RESET; } else { // nothing to do } } else { // failed while flashing, move to dfuError _dfu_ctx.state = DFU_ERROR; _dfu_ctx.status = (dfu_status_t)status; } } static bool process_download_get_status(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { if (stage == CONTROL_STAGE_SETUP) { // only transition to next state on CONTROL_STAGE_ACK dfu_state_t next_state; uint32_t timeout; if (_dfu_ctx.flashing_in_progress) { next_state = DFU_DNBUSY; timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, (uint8_t)next_state); } else { next_state = DFU_DNLOAD_IDLE; timeout = 0; } return reply_getstatus(rhport, request, next_state, (dfu_status_t) _dfu_ctx.status, timeout); } else if (stage == CONTROL_STAGE_ACK) { if (_dfu_ctx.flashing_in_progress) { _dfu_ctx.state = DFU_DNBUSY; tud_dfu_download_cb(_dfu_ctx.alt, _dfu_ctx.block, get_xfer_buffer(), _dfu_ctx.length); } else { _dfu_ctx.state = DFU_DNLOAD_IDLE; } } else { // nothing to do } return true; } static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { if (stage == CONTROL_STAGE_SETUP) { // only transition to next state on CONTROL_STAGE_ACK dfu_state_t next_state; uint32_t timeout; if (_dfu_ctx.flashing_in_progress) { next_state = DFU_MANIFEST; timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, next_state); } else { next_state = DFU_IDLE; timeout = 0; } return reply_getstatus(rhport, request, next_state, (dfu_status_t) _dfu_ctx.status, timeout); } else if (stage == CONTROL_STAGE_ACK) { if (_dfu_ctx.flashing_in_progress) { _dfu_ctx.state = DFU_MANIFEST; tud_dfu_manifest_cb(_dfu_ctx.alt); } else { _dfu_ctx.state = DFU_IDLE; } } else { // nothing to do } return true; } static bool reply_getstatus(uint8_t rhport, const tusb_control_request_t* request, dfu_state_t state, dfu_status_t status, uint32_t timeout) { dfu_status_response_t resp; resp.bStatus = (uint8_t)status; resp.bwPollTimeout[0] = TU_U32_BYTE0(timeout); resp.bwPollTimeout[1] = TU_U32_BYTE1(timeout); resp.bwPollTimeout[2] = TU_U32_BYTE2(timeout); resp.bState = (uint8_t)state; resp.iString = 0; return tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); } #endif ================================================ FILE: src/class/dfu/dfu_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 XMOS LIMITED * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DFU_DEVICE_H_ #define TUSB_DFU_DEVICE_H_ #include "dfu.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ #if !defined(CFG_TUD_DFU_XFER_BUFSIZE) #error "CFG_TUD_DFU_XFER_BUFSIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Must be called when the application is done with flashing started by // tud_dfu_download_cb() and tud_dfu_manifest_cb(). // status is DFU_STATUS_OK if successful, any other error status will cause state to enter dfuError void tud_dfu_finish_flashing(uint8_t status); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. // Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) // Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. // During this period, USB host won't try to communicate with us. uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state); // Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests // This callback could be returned before flashing op is complete (async). // Once finished flashing, application must call tud_dfu_finish_flashing() void tud_dfu_download_cb (uint8_t alt, uint16_t block_num, uint8_t const *data, uint16_t length); // Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) // Application can do checksum, or actual flashing if buffered entire image previously. // Once finished flashing, application must call tud_dfu_finish_flashing() void tud_dfu_manifest_cb(uint8_t alt); // Invoked when received DFU_UPLOAD request // Application must populate data with up to length bytes and // Return the number of written bytes uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); // Invoked when a DFU_DETACH request is received void tud_dfu_detach_cb(void); // Invoked when the Host has terminated a download or upload transfer void tud_dfu_abort_cb(uint8_t alt); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_moded_init(void); bool dfu_moded_deinit(void); void dfu_moded_reset(uint8_t rhport); uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); #ifdef __cplusplus } #endif #endif /* TUSB_DFU_MODE_DEVICE_H_ */ ================================================ FILE: src/class/dfu/dfu_rt_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Sylvain Munaut * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_DFU_RUNTIME) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "dfu_rt_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_DFU_RUNTIME_LOG_LEVEL #define CFG_TUD_DFU_RUNTIME_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_RUNTIME_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void dfu_rtd_init(void) { } bool dfu_rtd_deinit(void) { return true; } void dfu_rtd_reset(uint8_t rhport) { (void) rhport; } uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void) rhport; (void) max_len; // Ensure this is DFU Runtime TU_VERIFY((itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && (itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT), 0); uint8_t const * p_desc = tu_desc_next( itf_desc ); uint16_t drv_len = sizeof(tusb_desc_interface_t); if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) { drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } return drv_len; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // nothing to do with DATA or ACK stage if ( stage != CONTROL_STAGE_SETUP ) return true; TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); // dfu-util will try to claim the interface with SET_INTERFACE request before sending DFU request if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && TUSB_REQ_SET_INTERFACE == request->bRequest ) { tud_control_status(rhport, request); return true; } // Handle class request only from here TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); switch (request->bRequest) { case DFU_REQUEST_DETACH: { TU_LOG_DRV(" DFU RT Request: DETACH\r\n"); tud_control_status(rhport, request); tud_dfu_runtime_reboot_to_dfu_cb(); } break; case DFU_REQUEST_GETSTATUS: { TU_LOG_DRV(" DFU RT Request: GETSTATUS\r\n"); dfu_status_response_t resp; // Status = OK, Poll timeout is ignored during RT, State = APP_IDLE, IString = 0 TU_VERIFY(tu_memset_s(&resp, sizeof(resp), 0x00, sizeof(resp))==0); tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); } break; default: { TU_LOG_DRV(" DFU RT Unexpected Request: %d\r\n", request->bRequest); return false; // stall unsupported request } } return true; } #endif ================================================ FILE: src/class/dfu/dfu_rt_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Sylvain Munaut * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DFU_RT_DEVICE_H_ #define TUSB_DFU_RT_DEVICE_H_ #include "dfu.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when a DFU_DETACH request is received and bitWillDetach is set void tud_dfu_runtime_reboot_to_dfu_cb(void); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_rtd_init(void); bool dfu_rtd_deinit(void); void dfu_rtd_reset(uint8_t rhport); uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); #ifdef __cplusplus } #endif #endif /* TUSB_DFU_RT_DEVICE_H_ */ ================================================ FILE: src/class/hid/hid.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /** \ingroup group_class * \defgroup ClassDriver_HID Human Interface Device (HID) * @{ */ #ifndef TUSB_HID_H_ #define TUSB_HID_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Common Definitions //--------------------------------------------------------------------+ /** \defgroup ClassDriver_HID_Common Common Definitions * @{ */ /// USB HID Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */ uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */ uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */ uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */ uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */ uint8_t bReportType; /**< Type of HID class report. */ uint16_t wReportLength; /**< the total size of the Report descriptor. */ } tusb_hid_descriptor_hid_t; /// HID Subclass typedef enum { HID_SUBCLASS_NONE = 0, ///< No Subclass HID_SUBCLASS_BOOT = 1 ///< Boot Interface Subclass }hid_subclass_enum_t; /// HID Interface Protocol typedef enum { HID_ITF_PROTOCOL_NONE = 0, ///< None HID_ITF_PROTOCOL_KEYBOARD = 1, ///< Keyboard HID_ITF_PROTOCOL_MOUSE = 2 ///< Mouse }hid_interface_protocol_enum_t; /// HID Descriptor Type typedef enum { HID_DESC_TYPE_HID = 0x21, ///< HID Descriptor HID_DESC_TYPE_REPORT = 0x22, ///< Report Descriptor HID_DESC_TYPE_PHYSICAL = 0x23 ///< Physical Descriptor }hid_descriptor_enum_t; /// HID Request Report Type typedef enum { HID_REPORT_TYPE_INVALID = 0, HID_REPORT_TYPE_INPUT, ///< Input HID_REPORT_TYPE_OUTPUT, ///< Output HID_REPORT_TYPE_FEATURE ///< Feature }hid_report_type_t; /// HID Class Specific Control Request typedef enum { HID_REQ_CONTROL_GET_REPORT = 0x01, ///< Get Report HID_REQ_CONTROL_GET_IDLE = 0x02, ///< Get Idle HID_REQ_CONTROL_GET_PROTOCOL = 0x03, ///< Get Protocol HID_REQ_CONTROL_SET_REPORT = 0x09, ///< Set Report HID_REQ_CONTROL_SET_IDLE = 0x0a, ///< Set Idle HID_REQ_CONTROL_SET_PROTOCOL = 0x0b ///< Set Protocol }hid_request_enum_t; /// HID Local Code typedef enum { HID_LOCAL_NotSupported = 0 , ///< NotSupported HID_LOCAL_Arabic , ///< Arabic HID_LOCAL_Belgian , ///< Belgian HID_LOCAL_Canadian_Bilingual , ///< Canadian_Bilingual HID_LOCAL_Canadian_French , ///< Canadian_French HID_LOCAL_Czech_Republic , ///< Czech_Republic HID_LOCAL_Danish , ///< Danish HID_LOCAL_Finnish , ///< Finnish HID_LOCAL_French , ///< French HID_LOCAL_German , ///< German HID_LOCAL_Greek , ///< Greek HID_LOCAL_Hebrew , ///< Hebrew HID_LOCAL_Hungary , ///< Hungary HID_LOCAL_International , ///< International HID_LOCAL_Italian , ///< Italian HID_LOCAL_Japan_Katakana , ///< Japan_Katakana HID_LOCAL_Korean , ///< Korean HID_LOCAL_Latin_American , ///< Latin_American HID_LOCAL_Netherlands_Dutch , ///< Netherlands/Dutch HID_LOCAL_Norwegian , ///< Norwegian HID_LOCAL_Persian_Farsi , ///< Persian (Farsi) HID_LOCAL_Poland , ///< Poland HID_LOCAL_Portuguese , ///< Portuguese HID_LOCAL_Russia , ///< Russia HID_LOCAL_Slovakia , ///< Slovakia HID_LOCAL_Spanish , ///< Spanish HID_LOCAL_Swedish , ///< Swedish HID_LOCAL_Swiss_French , ///< Swiss/French HID_LOCAL_Swiss_German , ///< Swiss/German HID_LOCAL_Switzerland , ///< Switzerland HID_LOCAL_Taiwan , ///< Taiwan HID_LOCAL_Turkish_Q , ///< Turkish-Q HID_LOCAL_UK , ///< UK HID_LOCAL_US , ///< US HID_LOCAL_Yugoslavia , ///< Yugoslavia HID_LOCAL_Turkish_F ///< Turkish-F } hid_local_enum_t; // HID protocol value used by GetProtocol / SetProtocol typedef enum { HID_PROTOCOL_BOOT = 0, HID_PROTOCOL_REPORT = 1 } hid_protocol_mode_enum_t; /** @} */ //--------------------------------------------------------------------+ // GAMEPAD //--------------------------------------------------------------------+ /** \addtogroup ClassDriver_HID_Gamepad Gamepad * @{ */ /* From https://www.kernel.org/doc/html/latest/input/gamepad.html ____________________________ __ / [__ZL__] [__ZR__] \ | / [__ TL __] [__ TR __] \ | Front Triggers __/________________________________\__ __| / _ \ | / /\ __ (N) \ | / || __ |MO| __ _ _ \ | Main Pad | <===DP===> |SE| |ST| (W) -|- (E) | | \ || ___ ___ _ / | /\ \/ / \ / \ (S) /\ __| / \________ | LS | ____ | RS | ________/ \ | | / \ \___/ / \ \___/ / \ | | Control Sticks | / \_____/ \_____/ \ | __| | / \ | \_____/ \_____/ |________|______| |______|___________| D-Pad Left Right Action Pad Stick Stick |_____________| Menu Pad Most gamepads have the following features: - Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST. - D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right. - Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START. - Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also provide a digital button if you press them. - Triggers are located on the upper-side of the pad in vertical direction. The upper buttons are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right. - Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors. */ /// HID Gamepad Protocol Report. typedef struct TU_ATTR_PACKED { int8_t x; ///< Delta x movement of left analog-stick int8_t y; ///< Delta y movement of left analog-stick int8_t z; ///< Delta z movement of right analog-joystick int8_t rz; ///< Delta Rz movement of right analog-joystick int8_t rx; ///< Delta Rx movement of analog left trigger int8_t ry; ///< Delta Ry movement of analog right trigger uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat uint32_t buttons; ///< Buttons mask for currently pressed buttons }hid_gamepad_report_t; /// Standard Gamepad Buttons Bitmap typedef enum { GAMEPAD_BUTTON_0 = TU_BIT(0), GAMEPAD_BUTTON_1 = TU_BIT(1), GAMEPAD_BUTTON_2 = TU_BIT(2), GAMEPAD_BUTTON_3 = TU_BIT(3), GAMEPAD_BUTTON_4 = TU_BIT(4), GAMEPAD_BUTTON_5 = TU_BIT(5), GAMEPAD_BUTTON_6 = TU_BIT(6), GAMEPAD_BUTTON_7 = TU_BIT(7), GAMEPAD_BUTTON_8 = TU_BIT(8), GAMEPAD_BUTTON_9 = TU_BIT(9), GAMEPAD_BUTTON_10 = TU_BIT(10), GAMEPAD_BUTTON_11 = TU_BIT(11), GAMEPAD_BUTTON_12 = TU_BIT(12), GAMEPAD_BUTTON_13 = TU_BIT(13), GAMEPAD_BUTTON_14 = TU_BIT(14), GAMEPAD_BUTTON_15 = TU_BIT(15), GAMEPAD_BUTTON_16 = TU_BIT(16), GAMEPAD_BUTTON_17 = TU_BIT(17), GAMEPAD_BUTTON_18 = TU_BIT(18), GAMEPAD_BUTTON_19 = TU_BIT(19), GAMEPAD_BUTTON_20 = TU_BIT(20), GAMEPAD_BUTTON_21 = TU_BIT(21), GAMEPAD_BUTTON_22 = TU_BIT(22), GAMEPAD_BUTTON_23 = TU_BIT(23), GAMEPAD_BUTTON_24 = TU_BIT(24), GAMEPAD_BUTTON_25 = TU_BIT(25), GAMEPAD_BUTTON_26 = TU_BIT(26), GAMEPAD_BUTTON_27 = TU_BIT(27), GAMEPAD_BUTTON_28 = TU_BIT(28), GAMEPAD_BUTTON_29 = TU_BIT(29), GAMEPAD_BUTTON_30 = TU_BIT(30), GAMEPAD_BUTTON_31 = TU_BIT(31), }hid_gamepad_button_bm_t; /// Standard Gamepad Buttons Naming from Linux input event codes /// https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h #define GAMEPAD_BUTTON_A GAMEPAD_BUTTON_0 #define GAMEPAD_BUTTON_SOUTH GAMEPAD_BUTTON_0 #define GAMEPAD_BUTTON_B GAMEPAD_BUTTON_1 #define GAMEPAD_BUTTON_EAST GAMEPAD_BUTTON_1 #define GAMEPAD_BUTTON_C GAMEPAD_BUTTON_2 #define GAMEPAD_BUTTON_X GAMEPAD_BUTTON_3 #define GAMEPAD_BUTTON_NORTH GAMEPAD_BUTTON_3 #define GAMEPAD_BUTTON_Y GAMEPAD_BUTTON_4 #define GAMEPAD_BUTTON_WEST GAMEPAD_BUTTON_4 #define GAMEPAD_BUTTON_Z GAMEPAD_BUTTON_5 #define GAMEPAD_BUTTON_TL GAMEPAD_BUTTON_6 #define GAMEPAD_BUTTON_TR GAMEPAD_BUTTON_7 #define GAMEPAD_BUTTON_TL2 GAMEPAD_BUTTON_8 #define GAMEPAD_BUTTON_TR2 GAMEPAD_BUTTON_9 #define GAMEPAD_BUTTON_SELECT GAMEPAD_BUTTON_10 #define GAMEPAD_BUTTON_START GAMEPAD_BUTTON_11 #define GAMEPAD_BUTTON_MODE GAMEPAD_BUTTON_12 #define GAMEPAD_BUTTON_THUMBL GAMEPAD_BUTTON_13 #define GAMEPAD_BUTTON_THUMBR GAMEPAD_BUTTON_14 /// Standard Gamepad HAT/DPAD Buttons (from Linux input event codes) typedef enum { GAMEPAD_HAT_CENTERED = 0, ///< DPAD_CENTERED GAMEPAD_HAT_UP = 1, ///< DPAD_UP GAMEPAD_HAT_UP_RIGHT = 2, ///< DPAD_UP_RIGHT GAMEPAD_HAT_RIGHT = 3, ///< DPAD_RIGHT GAMEPAD_HAT_DOWN_RIGHT = 4, ///< DPAD_DOWN_RIGHT GAMEPAD_HAT_DOWN = 5, ///< DPAD_DOWN GAMEPAD_HAT_DOWN_LEFT = 6, ///< DPAD_DOWN_LEFT GAMEPAD_HAT_LEFT = 7, ///< DPAD_LEFT GAMEPAD_HAT_UP_LEFT = 8, ///< DPAD_UP_LEFT }hid_gamepad_hat_t; /// @} //--------------------------------------------------------------------+ // MOUSE //--------------------------------------------------------------------+ /** \addtogroup ClassDriver_HID_Mouse Mouse * @{ */ /// Standard HID Boot Protocol Mouse Report. typedef struct TU_ATTR_PACKED { uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ int8_t x; /**< Current delta x movement of the mouse. */ int8_t y; /**< Current delta y movement on the mouse. */ int8_t wheel; /**< Current delta wheel movement on the mouse. */ int8_t pan; // using AC Pan } hid_mouse_report_t; // Absolute Mouse: same as the Standard (relative) Mouse Report but // with int16_t instead of int8_t for X and Y coordinates. typedef struct TU_ATTR_PACKED { uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ int16_t x; /**< Current x position of the mouse. */ int16_t y; /**< Current y position of the mouse. */ int8_t wheel; /**< Current delta wheel movement on the mouse. */ int8_t pan; // using AC Pan } hid_abs_mouse_report_t; /// Standard Mouse Buttons Bitmap typedef enum { MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button, MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button, }hid_mouse_button_bm_t; /// @} //--------------------------------------------------------------------+ // Digitizer Stylus Pen //--------------------------------------------------------------------+ /** \addtogroup ClassDriver_HID_Stylus Stylus * @{ */ // Standard Stylus Pen Report. typedef struct TU_ATTR_PACKED { uint8_t attr; /**< Attribute mask for describing current status of the stylus pen. */ uint16_t x; /**< Current x position of the mouse. */ uint16_t y; /**< Current y position of the mouse. */ } hid_stylus_report_t; // Standard Stylus Pen Attributes Bitmap. typedef enum { STYLUS_ATTR_TIP_SWITCH = TU_BIT(0), ///< Tip switch STYLUS_ATTR_IN_RANGE = TU_BIT(1), ///< In-range bit. } hid_stylus_attr_bm_t; /// @} //--------------------------------------------------------------------+ // Keyboard //--------------------------------------------------------------------+ /** \addtogroup ClassDriver_HID_Keyboard Keyboard * @{ */ /// Standard HID Boot Protocol Keyboard Report. typedef struct TU_ATTR_PACKED { uint8_t modifier; /**< Keyboard modifier (KEYBOARD_MODIFIER_* masks). */ uint8_t reserved; /**< Reserved for OEM use, always set to 0. */ uint8_t keycode[6]; /**< Key codes of the currently pressed keys. */ } hid_keyboard_report_t; /// Keyboard modifier codes bitmap typedef enum { KEYBOARD_MODIFIER_LEFTCTRL = TU_BIT(0), ///< Left Control KEYBOARD_MODIFIER_LEFTSHIFT = TU_BIT(1), ///< Left Shift KEYBOARD_MODIFIER_LEFTALT = TU_BIT(2), ///< Left Alt KEYBOARD_MODIFIER_LEFTGUI = TU_BIT(3), ///< Left Window KEYBOARD_MODIFIER_RIGHTCTRL = TU_BIT(4), ///< Right Control KEYBOARD_MODIFIER_RIGHTSHIFT = TU_BIT(5), ///< Right Shift KEYBOARD_MODIFIER_RIGHTALT = TU_BIT(6), ///< Right Alt KEYBOARD_MODIFIER_RIGHTGUI = TU_BIT(7) ///< Right Window }hid_keyboard_modifier_bm_t; typedef enum { KEYBOARD_LED_NUMLOCK = TU_BIT(0), ///< Num Lock LED KEYBOARD_LED_CAPSLOCK = TU_BIT(1), ///< Caps Lock LED KEYBOARD_LED_SCROLLLOCK = TU_BIT(2), ///< Scroll Lock LED KEYBOARD_LED_COMPOSE = TU_BIT(3), ///< Composition Mode KEYBOARD_LED_KANA = TU_BIT(4) ///< Kana mode }hid_keyboard_led_bm_t; /// @} //--------------------------------------------------------------------+ // HID KEYCODE //--------------------------------------------------------------------+ #define HID_KEY_NONE 0x00 #define HID_KEY_A 0x04 #define HID_KEY_B 0x05 #define HID_KEY_C 0x06 #define HID_KEY_D 0x07 #define HID_KEY_E 0x08 #define HID_KEY_F 0x09 #define HID_KEY_G 0x0A #define HID_KEY_H 0x0B #define HID_KEY_I 0x0C #define HID_KEY_J 0x0D #define HID_KEY_K 0x0E #define HID_KEY_L 0x0F #define HID_KEY_M 0x10 #define HID_KEY_N 0x11 #define HID_KEY_O 0x12 #define HID_KEY_P 0x13 #define HID_KEY_Q 0x14 #define HID_KEY_R 0x15 #define HID_KEY_S 0x16 #define HID_KEY_T 0x17 #define HID_KEY_U 0x18 #define HID_KEY_V 0x19 #define HID_KEY_W 0x1A #define HID_KEY_X 0x1B #define HID_KEY_Y 0x1C #define HID_KEY_Z 0x1D #define HID_KEY_1 0x1E #define HID_KEY_2 0x1F #define HID_KEY_3 0x20 #define HID_KEY_4 0x21 #define HID_KEY_5 0x22 #define HID_KEY_6 0x23 #define HID_KEY_7 0x24 #define HID_KEY_8 0x25 #define HID_KEY_9 0x26 #define HID_KEY_0 0x27 #define HID_KEY_ENTER 0x28 #define HID_KEY_ESCAPE 0x29 #define HID_KEY_BACKSPACE 0x2A #define HID_KEY_TAB 0x2B #define HID_KEY_SPACE 0x2C #define HID_KEY_MINUS 0x2D #define HID_KEY_EQUAL 0x2E #define HID_KEY_BRACKET_LEFT 0x2F #define HID_KEY_BRACKET_RIGHT 0x30 #define HID_KEY_BACKSLASH 0x31 #define HID_KEY_EUROPE_1 0x32 #define HID_KEY_SEMICOLON 0x33 #define HID_KEY_APOSTROPHE 0x34 #define HID_KEY_GRAVE 0x35 #define HID_KEY_COMMA 0x36 #define HID_KEY_PERIOD 0x37 #define HID_KEY_SLASH 0x38 #define HID_KEY_CAPS_LOCK 0x39 #define HID_KEY_F1 0x3A #define HID_KEY_F2 0x3B #define HID_KEY_F3 0x3C #define HID_KEY_F4 0x3D #define HID_KEY_F5 0x3E #define HID_KEY_F6 0x3F #define HID_KEY_F7 0x40 #define HID_KEY_F8 0x41 #define HID_KEY_F9 0x42 #define HID_KEY_F10 0x43 #define HID_KEY_F11 0x44 #define HID_KEY_F12 0x45 #define HID_KEY_PRINT_SCREEN 0x46 #define HID_KEY_SCROLL_LOCK 0x47 #define HID_KEY_PAUSE 0x48 #define HID_KEY_INSERT 0x49 #define HID_KEY_HOME 0x4A #define HID_KEY_PAGE_UP 0x4B #define HID_KEY_DELETE 0x4C #define HID_KEY_END 0x4D #define HID_KEY_PAGE_DOWN 0x4E #define HID_KEY_ARROW_RIGHT 0x4F #define HID_KEY_ARROW_LEFT 0x50 #define HID_KEY_ARROW_DOWN 0x51 #define HID_KEY_ARROW_UP 0x52 #define HID_KEY_NUM_LOCK 0x53 #define HID_KEY_KEYPAD_DIVIDE 0x54 #define HID_KEY_KEYPAD_MULTIPLY 0x55 #define HID_KEY_KEYPAD_SUBTRACT 0x56 #define HID_KEY_KEYPAD_ADD 0x57 #define HID_KEY_KEYPAD_ENTER 0x58 #define HID_KEY_KEYPAD_1 0x59 #define HID_KEY_KEYPAD_2 0x5A #define HID_KEY_KEYPAD_3 0x5B #define HID_KEY_KEYPAD_4 0x5C #define HID_KEY_KEYPAD_5 0x5D #define HID_KEY_KEYPAD_6 0x5E #define HID_KEY_KEYPAD_7 0x5F #define HID_KEY_KEYPAD_8 0x60 #define HID_KEY_KEYPAD_9 0x61 #define HID_KEY_KEYPAD_0 0x62 #define HID_KEY_KEYPAD_DECIMAL 0x63 #define HID_KEY_EUROPE_2 0x64 #define HID_KEY_APPLICATION 0x65 #define HID_KEY_POWER 0x66 #define HID_KEY_KEYPAD_EQUAL 0x67 #define HID_KEY_F13 0x68 #define HID_KEY_F14 0x69 #define HID_KEY_F15 0x6A #define HID_KEY_F16 0x6B #define HID_KEY_F17 0x6C #define HID_KEY_F18 0x6D #define HID_KEY_F19 0x6E #define HID_KEY_F20 0x6F #define HID_KEY_F21 0x70 #define HID_KEY_F22 0x71 #define HID_KEY_F23 0x72 #define HID_KEY_F24 0x73 #define HID_KEY_EXECUTE 0x74 #define HID_KEY_HELP 0x75 #define HID_KEY_MENU 0x76 #define HID_KEY_SELECT 0x77 #define HID_KEY_STOP 0x78 #define HID_KEY_AGAIN 0x79 #define HID_KEY_UNDO 0x7A #define HID_KEY_CUT 0x7B #define HID_KEY_COPY 0x7C #define HID_KEY_PASTE 0x7D #define HID_KEY_FIND 0x7E #define HID_KEY_MUTE 0x7F #define HID_KEY_VOLUME_UP 0x80 #define HID_KEY_VOLUME_DOWN 0x81 #define HID_KEY_LOCKING_CAPS_LOCK 0x82 #define HID_KEY_LOCKING_NUM_LOCK 0x83 #define HID_KEY_LOCKING_SCROLL_LOCK 0x84 #define HID_KEY_KEYPAD_COMMA 0x85 #define HID_KEY_KEYPAD_EQUAL_SIGN 0x86 #define HID_KEY_KANJI1 0x87 #define HID_KEY_KANJI2 0x88 #define HID_KEY_KANJI3 0x89 #define HID_KEY_KANJI4 0x8A #define HID_KEY_KANJI5 0x8B #define HID_KEY_KANJI6 0x8C #define HID_KEY_KANJI7 0x8D #define HID_KEY_KANJI8 0x8E #define HID_KEY_KANJI9 0x8F #define HID_KEY_LANG1 0x90 #define HID_KEY_LANG2 0x91 #define HID_KEY_LANG3 0x92 #define HID_KEY_LANG4 0x93 #define HID_KEY_LANG5 0x94 #define HID_KEY_LANG6 0x95 #define HID_KEY_LANG7 0x96 #define HID_KEY_LANG8 0x97 #define HID_KEY_LANG9 0x98 #define HID_KEY_ALTERNATE_ERASE 0x99 #define HID_KEY_SYSREQ_ATTENTION 0x9A #define HID_KEY_CANCEL 0x9B #define HID_KEY_CLEAR 0x9C #define HID_KEY_PRIOR 0x9D #define HID_KEY_RETURN 0x9E #define HID_KEY_SEPARATOR 0x9F #define HID_KEY_OUT 0xA0 #define HID_KEY_OPER 0xA1 #define HID_KEY_CLEAR_AGAIN 0xA2 #define HID_KEY_CRSEL_PROPS 0xA3 #define HID_KEY_EXSEL 0xA4 // RESERVED 0xA5-AF #define HID_KEY_KEYPAD_00 0xB0 #define HID_KEY_KEYPAD_000 0xB1 #define HID_KEY_THOUSANDS_SEPARATOR 0xB2 #define HID_KEY_DECIMAL_SEPARATOR 0xB3 #define HID_KEY_CURRENCY_UNIT 0xB4 #define HID_KEY_CURRENCY_SUBUNIT 0xB5 #define HID_KEY_KEYPAD_LEFT_PARENTHESIS 0xB6 #define HID_KEY_KEYPAD_RIGHT_PARENTHESIS 0xB7 #define HID_KEY_KEYPAD_LEFT_BRACE 0xB8 #define HID_KEY_KEYPAD_RIGHT_BRACE 0xB9 #define HID_KEY_KEYPAD_TAB 0xBA #define HID_KEY_KEYPAD_BACKSPACE 0xBB #define HID_KEY_KEYPAD_A 0xBC #define HID_KEY_KEYPAD_B 0xBD #define HID_KEY_KEYPAD_C 0xBE #define HID_KEY_KEYPAD_D 0xBF #define HID_KEY_KEYPAD_E 0xC0 #define HID_KEY_KEYPAD_F 0xC1 #define HID_KEY_KEYPAD_XOR 0xC2 #define HID_KEY_KEYPAD_CARET 0xC3 #define HID_KEY_KEYPAD_PERCENT 0xC4 #define HID_KEY_KEYPAD_LESS_THAN 0xC5 #define HID_KEY_KEYPAD_GREATER_THAN 0xC6 #define HID_KEY_KEYPAD_AMPERSAND 0xC7 #define HID_KEY_KEYPAD_DOUBLE_AMPERSAND 0xC8 #define HID_KEY_KEYPAD_VERTICAL_BAR 0xC9 #define HID_KEY_KEYPAD_DOUBLE_VERTICAL_BAR 0xCA #define HID_KEY_KEYPAD_COLON 0xCB #define HID_KEY_KEYPAD_HASH 0xCC #define HID_KEY_KEYPAD_SPACE 0xCD #define HID_KEY_KEYPAD_AT 0xCE #define HID_KEY_KEYPAD_EXCLAMATION 0xCF #define HID_KEY_KEYPAD_MEMORY_STORE 0xD0 #define HID_KEY_KEYPAD_MEMORY_RECALL 0xD1 #define HID_KEY_KEYPAD_MEMORY_CLEAR 0xD2 #define HID_KEY_KEYPAD_MEMORY_ADD 0xD3 #define HID_KEY_KEYPAD_MEMORY_SUBTRACT 0xD4 #define HID_KEY_KEYPAD_MEMORY_MULTIPLY 0xD5 #define HID_KEY_KEYPAD_MEMORY_DIVIDE 0xD6 #define HID_KEY_KEYPAD_PLUS_MINUS 0xD7 #define HID_KEY_KEYPAD_CLEAR 0xD8 #define HID_KEY_KEYPAD_CLEAR_ENTRY 0xD9 #define HID_KEY_KEYPAD_BINARY 0xDA #define HID_KEY_KEYPAD_OCTAL 0xDB #define HID_KEY_KEYPAD_DECIMAL_2 0xDC #define HID_KEY_KEYPAD_HEXADECIMAL 0xDD // RESERVED 0xDE-DF #define HID_KEY_CONTROL_LEFT 0xE0 #define HID_KEY_SHIFT_LEFT 0xE1 #define HID_KEY_ALT_LEFT 0xE2 #define HID_KEY_GUI_LEFT 0xE3 #define HID_KEY_CONTROL_RIGHT 0xE4 #define HID_KEY_SHIFT_RIGHT 0xE5 #define HID_KEY_ALT_RIGHT 0xE6 #define HID_KEY_GUI_RIGHT 0xE7 //--------------------------------------------------------------------+ // REPORT DESCRIPTOR //--------------------------------------------------------------------+ //------------- ITEM & TAG -------------// #define HID_REPORT_DATA_0(data) #define HID_REPORT_DATA_1(data) , data #define HID_REPORT_DATA_2(data) , U16_TO_U8S_LE(data) #define HID_REPORT_DATA_3(data) , U32_TO_U8S_LE(data) #define HID_REPORT_ITEM(data, tag, type, size) \ (((tag) << 4) | ((type) << 2) | (size)) HID_REPORT_DATA_##size(data) // Report Item Types enum { RI_TYPE_MAIN = 0, RI_TYPE_GLOBAL = 1, RI_TYPE_LOCAL = 2 }; //------------- Main Items - HID 1.11 section 6.2.2.4 -------------// // Report Item Main group enum { RI_MAIN_INPUT = 8, RI_MAIN_OUTPUT = 9, RI_MAIN_COLLECTION = 10, RI_MAIN_FEATURE = 11, RI_MAIN_COLLECTION_END = 12 }; #define HID_INPUT(x) HID_REPORT_ITEM(x, RI_MAIN_INPUT , RI_TYPE_MAIN, 1) #define HID_OUTPUT(x) HID_REPORT_ITEM(x, RI_MAIN_OUTPUT , RI_TYPE_MAIN, 1) #define HID_COLLECTION(x) HID_REPORT_ITEM(x, RI_MAIN_COLLECTION , RI_TYPE_MAIN, 1) #define HID_FEATURE(x) HID_REPORT_ITEM(x, RI_MAIN_FEATURE , RI_TYPE_MAIN, 1) #define HID_COLLECTION_END HID_REPORT_ITEM(x, RI_MAIN_COLLECTION_END, RI_TYPE_MAIN, 0) //------------- Input, Output, Feature - HID 1.11 section 6.2.2.5 -------------// #define HID_DATA (0<<0) #define HID_CONSTANT (1<<0) #define HID_ARRAY (0<<1) #define HID_VARIABLE (1<<1) #define HID_ABSOLUTE (0<<2) #define HID_RELATIVE (1<<2) #define HID_WRAP_NO (0<<3) #define HID_WRAP (1<<3) #define HID_LINEAR (0<<4) #define HID_NONLINEAR (1<<4) #define HID_PREFERRED_STATE (0<<5) #define HID_PREFERRED_NO (1<<5) #define HID_NO_NULL_POSITION (0<<6) #define HID_NULL_STATE (1<<6) #define HID_NON_VOLATILE (0<<7) #define HID_VOLATILE (1<<7) #define HID_BITFIELD (0<<8) #define HID_BUFFERED_BYTES (1<<8) //------------- Collection Item - HID 1.11 section 6.2.2.6 -------------// enum { HID_COLLECTION_PHYSICAL = 0, HID_COLLECTION_APPLICATION, HID_COLLECTION_LOGICAL, HID_COLLECTION_REPORT, HID_COLLECTION_NAMED_ARRAY, HID_COLLECTION_USAGE_SWITCH, HID_COLLECTION_USAGE_MODIFIER }; //------------- Global Items - HID 1.11 section 6.2.2.7 -------------// // Report Item Global group enum { RI_GLOBAL_USAGE_PAGE = 0, RI_GLOBAL_LOGICAL_MIN = 1, RI_GLOBAL_LOGICAL_MAX = 2, RI_GLOBAL_PHYSICAL_MIN = 3, RI_GLOBAL_PHYSICAL_MAX = 4, RI_GLOBAL_UNIT_EXPONENT = 5, RI_GLOBAL_UNIT = 6, RI_GLOBAL_REPORT_SIZE = 7, RI_GLOBAL_REPORT_ID = 8, RI_GLOBAL_REPORT_COUNT = 9, RI_GLOBAL_PUSH = 10, RI_GLOBAL_POP = 11 }; #define HID_USAGE_PAGE(x) HID_REPORT_ITEM(x, RI_GLOBAL_USAGE_PAGE, RI_TYPE_GLOBAL, 1) #define HID_USAGE_PAGE_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_USAGE_PAGE, RI_TYPE_GLOBAL, n) #define HID_LOGICAL_MIN(x) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MIN, RI_TYPE_GLOBAL, 1) #define HID_LOGICAL_MIN_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MIN, RI_TYPE_GLOBAL, n) #define HID_LOGICAL_MAX(x) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MAX, RI_TYPE_GLOBAL, 1) #define HID_LOGICAL_MAX_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_LOGICAL_MAX, RI_TYPE_GLOBAL, n) #define HID_PHYSICAL_MIN(x) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MIN, RI_TYPE_GLOBAL, 1) #define HID_PHYSICAL_MIN_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MIN, RI_TYPE_GLOBAL, n) #define HID_PHYSICAL_MAX(x) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MAX, RI_TYPE_GLOBAL, 1) #define HID_PHYSICAL_MAX_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_PHYSICAL_MAX, RI_TYPE_GLOBAL, n) #define HID_UNIT_EXPONENT(x) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT_EXPONENT, RI_TYPE_GLOBAL, 1) #define HID_UNIT_EXPONENT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT_EXPONENT, RI_TYPE_GLOBAL, n) #define HID_UNIT(x) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT, RI_TYPE_GLOBAL, 1) #define HID_UNIT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_UNIT, RI_TYPE_GLOBAL, n) #define HID_REPORT_SIZE(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_SIZE, RI_TYPE_GLOBAL, 1) #define HID_REPORT_SIZE_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_SIZE, RI_TYPE_GLOBAL, n) #define HID_REPORT_ID(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, 1), #define HID_REPORT_ID_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_ID, RI_TYPE_GLOBAL, n), #define HID_REPORT_COUNT(x) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, 1) #define HID_REPORT_COUNT_N(x, n) HID_REPORT_ITEM(x, RI_GLOBAL_REPORT_COUNT, RI_TYPE_GLOBAL, n) #define HID_PUSH HID_REPORT_ITEM(x, RI_GLOBAL_PUSH, RI_TYPE_GLOBAL, 0) #define HID_POP HID_REPORT_ITEM(x, RI_GLOBAL_POP, RI_TYPE_GLOBAL, 0) //------------- LOCAL ITEMS 6.2.2.8 -------------// enum { RI_LOCAL_USAGE = 0, RI_LOCAL_USAGE_MIN = 1, RI_LOCAL_USAGE_MAX = 2, RI_LOCAL_DESIGNATOR_INDEX = 3, RI_LOCAL_DESIGNATOR_MIN = 4, RI_LOCAL_DESIGNATOR_MAX = 5, // 6 is reserved RI_LOCAL_STRING_INDEX = 7, RI_LOCAL_STRING_MIN = 8, RI_LOCAL_STRING_MAX = 9, RI_LOCAL_DELIMITER = 10, }; #define HID_USAGE(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE, RI_TYPE_LOCAL, 1) #define HID_USAGE_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE, RI_TYPE_LOCAL, n) #define HID_USAGE_MIN(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MIN, RI_TYPE_LOCAL, 1) #define HID_USAGE_MIN_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MIN, RI_TYPE_LOCAL, n) #define HID_USAGE_MAX(x) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MAX, RI_TYPE_LOCAL, 1) #define HID_USAGE_MAX_N(x, n) HID_REPORT_ITEM(x, RI_LOCAL_USAGE_MAX, RI_TYPE_LOCAL, n) //--------------------------------------------------------------------+ // Usage Table /* Usage Types Data Sel Selector Array SV Static Value Constant, Variable, Absolute SF Static Flag Constant, Variable, Absolute DV Dynamic Value Constant, Variable, Absolute DF Dynamic Flag Constant, Variable, Absolute */ /* Usage Types Collection NAry Named Array Logical CA Collection Application Application CL Collection Logical Logical CP Collection Physical Physical US Usage Switch Logical UM Usage Modifier Logical */ //--------------------------------------------------------------------+ /// HID Usage Table - Table 1: Usage Page Summary enum { HID_USAGE_PAGE_DESKTOP = 0x01, HID_USAGE_PAGE_SIMULATE = 0x02, HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, HID_USAGE_PAGE_SPORT = 0x04, HID_USAGE_PAGE_GAME = 0x05, HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, HID_USAGE_PAGE_KEYBOARD = 0x07, HID_USAGE_PAGE_LED = 0x08, HID_USAGE_PAGE_BUTTON = 0x09, HID_USAGE_PAGE_ORDINAL = 0x0a, HID_USAGE_PAGE_TELEPHONY = 0x0b, HID_USAGE_PAGE_CONSUMER = 0x0c, HID_USAGE_PAGE_DIGITIZER = 0x0d, HID_USAGE_PAGE_PID = 0x0f, HID_USAGE_PAGE_UNICODE = 0x10, HID_USAGE_PAGE_SOC = 0x11, HID_USAGE_PAGE_EYE_AND_HEAD_TRACKERS = 0x12, // 0x13 is reserved HID_USAGE_PAGE_AUXILIARY_DISPLAY = 0x14, // 0x15 - 0x1f is reserved HID_USAGE_PAGE_SENSORS = 0x20, // 0x21 - 0x3f is reserved HID_USAGE_PAGE_MEDICAL_INSTRUMENT = 0x40, HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83 HID_USAGE_PAGE_POWER = 0x84, HID_USAGE_PAGE_BATTERY = 0x85, // 0x86 - 0x87 is reserved for Power Device HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, HID_USAGE_PAGE_SCALE = 0x8d, HID_USAGE_PAGE_MSR = 0x8e, HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page enum { HID_USAGE_DESKTOP_POINTER = 0x01, HID_USAGE_DESKTOP_MOUSE = 0x02, HID_USAGE_DESKTOP_JOYSTICK = 0x04, HID_USAGE_DESKTOP_GAMEPAD = 0x05, HID_USAGE_DESKTOP_KEYBOARD = 0x06, HID_USAGE_DESKTOP_KEYPAD = 0x07, HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08, HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09, HID_USAGE_DESKTOP_X = 0x30, HID_USAGE_DESKTOP_Y = 0x31, HID_USAGE_DESKTOP_Z = 0x32, HID_USAGE_DESKTOP_RX = 0x33, HID_USAGE_DESKTOP_RY = 0x34, HID_USAGE_DESKTOP_RZ = 0x35, HID_USAGE_DESKTOP_SLIDER = 0x36, HID_USAGE_DESKTOP_DIAL = 0x37, HID_USAGE_DESKTOP_WHEEL = 0x38, HID_USAGE_DESKTOP_HAT_SWITCH = 0x39, HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3a, HID_USAGE_DESKTOP_BYTE_COUNT = 0x3b, HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3c, HID_USAGE_DESKTOP_START = 0x3d, HID_USAGE_DESKTOP_SELECT = 0x3e, HID_USAGE_DESKTOP_VX = 0x40, HID_USAGE_DESKTOP_VY = 0x41, HID_USAGE_DESKTOP_VZ = 0x42, HID_USAGE_DESKTOP_VBRX = 0x43, HID_USAGE_DESKTOP_VBRY = 0x44, HID_USAGE_DESKTOP_VBRZ = 0x45, HID_USAGE_DESKTOP_VNO = 0x46, HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47, HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48, HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80, HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81, HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82, HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83, HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84, HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85, HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86, HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87, HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88, HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89, HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A, HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B, HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C, HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D, HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E, HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F, HID_USAGE_DESKTOP_DPAD_UP = 0x90, HID_USAGE_DESKTOP_DPAD_DOWN = 0x91, HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92, HID_USAGE_DESKTOP_DPAD_LEFT = 0x93, HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0, HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1, HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2, HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3, HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4, HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5, HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6, HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7, HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6, HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7 }; /// HID Usage Table: Consumer Page (0x0C) /// Only contains controls that supported by Windows (whole list is too long) enum { HID_USAGE_CONSUMER_UNASSIGNED = 0x0000, // Generic Control HID_USAGE_CONSUMER_CONTROL = 0x0001, HID_USAGE_CONSUMER_NUMERIC_KEY_PAD = 0x0002, HID_USAGE_CONSUMER_PROGRAMMABLE_BUTTONS = 0x0003, HID_USAGE_CONSUMER_MICROPHONE = 0x0004, HID_USAGE_CONSUMER_HEADPHONE = 0x0005, HID_USAGE_CONSUMER_GRAPHIC_EQUALIZER = 0x0006, // 07-1F Reserved HID_USAGE_CONSUMER_PLUS_10 = 0x0020, HID_USAGE_CONSUMER_PLUS_100 = 0x0021, HID_USAGE_CONSUMER_AM_PM = 0x0022, // 23-3F Reserved // Power Control HID_USAGE_CONSUMER_POWER = 0x0030, HID_USAGE_CONSUMER_RESET = 0x0031, HID_USAGE_CONSUMER_SLEEP = 0x0032, HID_USAGE_CONSUMER_SLEEP_AFTER = 0x0033, HID_USAGE_CONSUMER_SLEEP_MODE = 0x0034, HID_USAGE_CONSUMER_ILLUMINATION = 0x0035, HID_USAGE_CONSUMER_FUNCTION_BUTTONS = 0x0036, // 37-3F Reserved HID_USAGE_CONSUMER_MENU = 0x0040, HID_USAGE_CONSUMER_MENU_PICK = 0x0041, HID_USAGE_CONSUMER_MENU_UP = 0x0042, HID_USAGE_CONSUMER_MENU_DOWN = 0x0043, HID_USAGE_CONSUMER_MENU_LEFT = 0x0044, HID_USAGE_CONSUMER_MENU_RIGHT = 0x0045, HID_USAGE_CONSUMER_MENU_ESCAPE = 0x0046, HID_USAGE_CONSUMER_MENU_VALUE_INCREASE = 0x0047, HID_USAGE_CONSUMER_MENU_VALUE_DECREASE = 0x0048, // 49-5F Reserved HID_USAGE_CONSUMER_DATA_ON_SCREEN = 0x0060, HID_USAGE_CONSUMER_CLOSED_CAPTION = 0x0061, HID_USAGE_CONSUMER_CLOSED_CAPTION_SELECT = 0x0062, HID_USAGE_CONSUMER_VCR_TV = 0x0063, HID_USAGE_CONSUMER_BROADCAST_MODE = 0x0064, HID_USAGE_CONSUMER_SNAPSHOT = 0x0065, HID_USAGE_CONSUMER_STILL = 0x0066, // 67-7F Reserved // Screen Brightness HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F, HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070, // These HID usages operate only on mobile systems (battery powered) and // require Windows 8 (build 8302 or greater). HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C, HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6, HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7, HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8, HID_USAGE_CONSUMER_SELECTION = 0x0080, HID_USAGE_CONSUMER_ASSIGN_SELECTION = 0x0081, HID_USAGE_CONSUMER_MODE_STEP = 0x0082, HID_USAGE_CONSUMER_RECALL_LAST = 0x0083, HID_USAGE_CONSUMER_ENTER_CHANNEL = 0x0084, HID_USAGE_CONSUMER_ORDER_MOVIE = 0x0085, HID_USAGE_CONSUMER_CHANNEL = 0x0086, HID_USAGE_CONSUMER_MEDIA_SELECTION = 0x0087, HID_USAGE_CONSUMER_MEDIA_SELECT_COMPUTER = 0x0088, HID_USAGE_CONSUMER_MEDIA_SELECT_TV = 0x0089, HID_USAGE_CONSUMER_MEDIA_SELECT_WWW = 0x008A, HID_USAGE_CONSUMER_MEDIA_SELECT_DVD = 0x008B, HID_USAGE_CONSUMER_MEDIA_SELECT_TELEPHONE = 0x008C, HID_USAGE_CONSUMER_MEDIA_SELECT_PROGRAM_GUIDE = 0x008D, HID_USAGE_CONSUMER_MEDIA_SELECT_VIDEO_PHONE = 0x008E, HID_USAGE_CONSUMER_MEDIA_SELECT_GAMES = 0x008F, HID_USAGE_CONSUMER_MEDIA_SELECT_MESSAGES = 0x0090, HID_USAGE_CONSUMER_MEDIA_SELECT_CD = 0x0091, HID_USAGE_CONSUMER_MEDIA_SELECT_VCR = 0x0092, HID_USAGE_CONSUMER_MEDIA_SELECT_TUNER = 0x0093, HID_USAGE_CONSUMER_QUIT = 0x0094, HID_USAGE_CONSUMER_HELP = 0x0095, HID_USAGE_CONSUMER_MEDIA_SELECT_TAPE = 0x0096, HID_USAGE_CONSUMER_MEDIA_SELECT_CABLE = 0x0097, HID_USAGE_CONSUMER_MEDIA_SELECT_SATELLITE = 0x0098, HID_USAGE_CONSUMER_MEDIA_SELECT_SECURITY = 0x0099, HID_USAGE_CONSUMER_MEDIA_SELECT_HOME = 0x009A, HID_USAGE_CONSUMER_MEDIA_SELECT_CALL = 0x009B, HID_USAGE_CONSUMER_CHANNEL_INCREMENT = 0x009C, HID_USAGE_CONSUMER_CHANNEL_DECREMENT = 0x009D, HID_USAGE_CONSUMER_MEDIA_SELECT_SAP = 0x009E, // 9F Reserved HID_USAGE_CONSUMER_VCR_PLUS = 0x00A0, HID_USAGE_CONSUMER_ONCE = 0x00A1, HID_USAGE_CONSUMER_DAILY = 0x00A2, HID_USAGE_CONSUMER_WEEKLY = 0x00A3, HID_USAGE_CONSUMER_MONTHLY = 0x00A4, // A5-AF Reserved HID_USAGE_CONSUMER_PLAY = 0x00B0, HID_USAGE_CONSUMER_PAUSE = 0x00B1, HID_USAGE_CONSUMER_RECORD = 0x00B2, HID_USAGE_CONSUMER_FAST_FORWARD = 0x00B3, HID_USAGE_CONSUMER_REWIND = 0x00B4, HID_USAGE_CONSUMER_SCAN_NEXT_TRACK = 0x00B5, HID_USAGE_CONSUMER_SCAN_PREVIOUS_TRACK = 0x00B6, HID_USAGE_CONSUMER_STOP = 0x00B7, HID_USAGE_CONSUMER_EJECT = 0x00B8, HID_USAGE_CONSUMER_RANDOM_PLAY = 0x00B9, HID_USAGE_CONSUMER_SELECT_DISC = 0x00BA, HID_USAGE_CONSUMER_ENTER_DISC = 0x00BB, HID_USAGE_CONSUMER_REPEAT = 0x00BC, HID_USAGE_CONSUMER_TRACKING = 0x00BD, HID_USAGE_CONSUMER_TRACK_NORMAL = 0x00BE, HID_USAGE_CONSUMER_SLOW_TRACKING = 0x00BF, HID_USAGE_CONSUMER_FRAME_FORWARD = 0x00C0, HID_USAGE_CONSUMER_FRAME_BACK = 0x00C1, HID_USAGE_CONSUMER_MARK = 0x00C2, HID_USAGE_CONSUMER_CLEAR_MARK = 0x00C3, HID_USAGE_CONSUMER_REPEAT_FROM_MARK = 0x00C4, HID_USAGE_CONSUMER_RETURN_TO_MARK = 0x00C5, HID_USAGE_CONSUMER_SEARCH_MARK_FORWARD = 0x00C6, HID_USAGE_CONSUMER_SEARCH_MARK_BACKWARDS = 0x00C7, HID_USAGE_CONSUMER_COUNTER_RESET = 0x00C8, HID_USAGE_CONSUMER_SHOW_COUNTER = 0x00C9, HID_USAGE_CONSUMER_TRACKING_INCREMENT = 0x00CA, HID_USAGE_CONSUMER_TRACKING_DECREMENT = 0x00CB, HID_USAGE_CONSUMER_STOP_EJECT = 0x00CC, // Media Control HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD, HID_USAGE_CONSUMER_PLAY_SKIP = 0x00CE, // CF-DF Reserved HID_USAGE_CONSUMER_VOLUME = 0x00E0, HID_USAGE_CONSUMER_BALANCE = 0x00E1, HID_USAGE_CONSUMER_MUTE = 0x00E2, HID_USAGE_CONSUMER_BASS = 0x00E3, HID_USAGE_CONSUMER_TREBLE = 0x00E4, HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5, HID_USAGE_CONSUMER_SURROUND_MODE = 0x00E6, HID_USAGE_CONSUMER_LOUDNESS = 0x00E7, HID_USAGE_CONSUMER_MPX = 0x00E8, HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9, HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA, // EB-EF Reserved HID_USAGE_CONSUMER_SPEED_SELECT = 0x00F0, HID_USAGE_CONSUMER_PLAYBACK_SPEED = 0x00F1, HID_USAGE_CONSUMER_STANDARD_PLAY = 0x00F2, HID_USAGE_CONSUMER_LONG_PLAY = 0x00F3, HID_USAGE_CONSUMER_EXTENDED_PLAY = 0x00F4, HID_USAGE_CONSUMER_SLOW = 0x00F5, // F6-FF Reserved HID_USAGE_CONSUMER_FAN_ENABLE = 0x0100, HID_USAGE_CONSUMER_FAN_SPEED = 0x0101, HID_USAGE_CONSUMER_LIGHT_ENABLE = 0x0102, HID_USAGE_CONSUMER_LIGHT_ILLUMINATION_LEVEL = 0x0103, HID_USAGE_CONSUMER_CLIMATE_CONTROL_ENABLE = 0x0104, HID_USAGE_CONSUMER_ROOM_TEMPERATURE = 0x0105, HID_USAGE_CONSUMER_SECURITY_ENABLE = 0x0106, HID_USAGE_CONSUMER_FIRE_ALARM = 0x0107, HID_USAGE_CONSUMER_POLICE_ALARM = 0x0108, HID_USAGE_CONSUMER_PROXIMITY = 0x0109, HID_USAGE_CONSUMER_MOTION = 0x010A, HID_USAGE_CONSUMER_DURESS_ALARM = 0x010B, HID_USAGE_CONSUMER_HOLDUP_ALARM = 0x010C, HID_USAGE_CONSUMER_MEDICAL_ALARM = 0x010D, // 10E-14F Reserved HID_USAGE_CONSUMER_BALANCE_RIGHT = 0x0150, HID_USAGE_CONSUMER_BALANCE_LEFT = 0x0151, HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152, HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153, HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154, HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155, // 156-15F Reserved HID_USAGE_CONSUMER_SPEAKER_SYSTEM = 0x0160, HID_USAGE_CONSUMER_CHANNEL_LEFT = 0x0161, HID_USAGE_CONSUMER_CHANNEL_RIGHT = 0x0162, HID_USAGE_CONSUMER_CHANNEL_CENTER = 0x0163, HID_USAGE_CONSUMER_CHANNEL_FRONT = 0x0164, HID_USAGE_CONSUMER_CHANNEL_CENTER_FRONT = 0x0165, HID_USAGE_CONSUMER_CHANNEL_SIDE = 0x0166, HID_USAGE_CONSUMER_CHANNEL_SURROUND = 0x0167, HID_USAGE_CONSUMER_CHANNEL_LOW_FREQUENCY = 0x0168, // Enhancement // CL 15.12.1 HID_USAGE_CONSUMER_CHANNEL_TOP = 0x0169, HID_USAGE_CONSUMER_CHANNEL_UNKNOWN = 0x016A, // 16B-16F Reserved HID_USAGE_CONSUMER_SUB_CHANNEL = 0x0170, HID_USAGE_CONSUMER_SUB_CHANNEL_INCREMENT = 0x0171, HID_USAGE_CONSUMER_SUB_CHANNEL_DECREMENT = 0x0172, HID_USAGE_CONSUMER_ALTERNATE_AUDIO_INCREMENT = 0x0173, HID_USAGE_CONSUMER_ALTERNATE_AUDIO_DECREMENT = 0x0174, // 175-17F Reserved HID_USAGE_CONSUMER_APPLICATION_LAUNCH_BUTTONS = 0x0180, HID_USAGE_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION = 0x0181, // Tool // Sel 15.15 HID_USAGE_CONSUMER_AL_PROGRAMMABLE_BUTTON = 0x0182, // Configuration // Sel 15.15 HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183, // Configuration // Sel 15.15 HID_USAGE_CONSUMER_AL_WORD_PROCESSOR = 0x0184, HID_USAGE_CONSUMER_AL_TEXT_EDITOR = 0x0185, HID_USAGE_CONSUMER_AL_SPREADSHEET = 0x0186, HID_USAGE_CONSUMER_AL_GRAPHICS_EDITOR = 0x0187, HID_USAGE_CONSUMER_AL_PRESENTATION_APP = 0x0188, HID_USAGE_CONSUMER_AL_DATABASE_APP = 0x0189, HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A, HID_USAGE_CONSUMER_AL_NEWSREADER = 0x018B, HID_USAGE_CONSUMER_AL_VOICEMAIL = 0x018C, HID_USAGE_CONSUMER_AL_CONTACTS_ADDRESS_BOOK = 0x018D, HID_USAGE_CONSUMER_AL_CALENDAR_SCHEDULE = 0x018E, HID_USAGE_CONSUMER_AL_TASK_PROJECT_MANAGER = 0x018F, HID_USAGE_CONSUMER_AL_LOG_JOURNAL_TIMECARD = 0x0190, HID_USAGE_CONSUMER_AL_CHECKBOOK_FINANCE = 0x0191, HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192, HID_USAGE_CONSUMER_AL_A_V_CAPTURE_PLAYBACK = 0x0193, HID_USAGE_CONSUMER_AL_LOCAL_MACHINE_BROWSER = 0x0194, HID_USAGE_CONSUMER_AL_LAN_WAN_BROWSER = 0x0195, HID_USAGE_CONSUMER_AL_INTERNET_BROWSER = 0x0196, HID_USAGE_CONSUMER_AL_REMOTE_NETWORKING_ISP = 0x0197, // Connect // Sel 15.15 HID_USAGE_CONSUMER_AL_NETWORK_CONFERENCE = 0x0198, HID_USAGE_CONSUMER_AL_NETWORK_CHAT = 0x0199, HID_USAGE_CONSUMER_AL_TELEPHONY_DIALER = 0x019A, HID_USAGE_CONSUMER_AL_LOGON = 0x019B, HID_USAGE_CONSUMER_AL_LOGOFF = 0x019C, HID_USAGE_CONSUMER_AL_LOGON_LOGOFF = 0x019D, HID_USAGE_CONSUMER_AL_TERMINAL_LOCK_SCREENSAVER = 0x019E, HID_USAGE_CONSUMER_AL_CONTROL_PANEL = 0x019F, HID_USAGE_CONSUMER_AL_COMMAND_LINE_PROCESSOR_RUN = 0x01A0, HID_USAGE_CONSUMER_AL_PROCESS_TASK_MANAGER = 0x01A1, HID_USAGE_CONSUMER_AL_SELECT_TASK_APPLICATION = 0x01A2, HID_USAGE_CONSUMER_AL_NEXT_TASK_APPLICATION = 0x01A3, HID_USAGE_CONSUMER_AL_PREVIOUS_TASK_APPLICATION = 0x01A4, HID_USAGE_CONSUMER_AL_PREEMPTIVE_HALT = 0x01A5, // Task_Application // Sel 15.15 HID_USAGE_CONSUMER_AL_INTEGRATED_HELP_CENTER = 0x01A6, HID_USAGE_CONSUMER_AL_DOCUMENTS = 0x01A7, HID_USAGE_CONSUMER_AL_THESAURUS = 0x01A8, HID_USAGE_CONSUMER_AL_DICTIONARY = 0x01A9, HID_USAGE_CONSUMER_AL_DESKTOP = 0x01AA, HID_USAGE_CONSUMER_AL_SPELL_CHECK = 0x01AB, HID_USAGE_CONSUMER_AL_GRAMMAR_CHECK = 0x01AC, HID_USAGE_CONSUMER_AL_WIRELESS_STATUS = 0x01AD, HID_USAGE_CONSUMER_AL_KEYBOARD_LAYOUT = 0x01AE, HID_USAGE_CONSUMER_AL_VIRUS_PROTECTION = 0x01AF, HID_USAGE_CONSUMER_AL_ENCRYPTION = 0x01B0, HID_USAGE_CONSUMER_AL_SCREEN_SAVER = 0x01B1, HID_USAGE_CONSUMER_AL_ALARMS = 0x01B2, HID_USAGE_CONSUMER_AL_CLOCK = 0x01B3, HID_USAGE_CONSUMER_AL_FILE_BROWSER = 0x01B4, HID_USAGE_CONSUMER_AL_POWER_STATUS = 0x01B5, HID_USAGE_CONSUMER_AL_IMAGE_BROWSER = 0x01B6, HID_USAGE_CONSUMER_AL_AUDIO_BROWSER = 0x01B7, HID_USAGE_CONSUMER_AL_MOVIE_BROWSER = 0x01B8, HID_USAGE_CONSUMER_AL_DIGITAL_RIGHTS_MANAGER = 0x01B9, HID_USAGE_CONSUMER_AL_DIGITAL_WALLET = 0x01BA, // 1BB Reserved HID_USAGE_CONSUMER_AL_INSTANT_MESSAGING = 0x01BC, HID_USAGE_CONSUMER_AL_OEM_FEATURES_TIPS_TUTORIAL = 0x01BD, // Browser // Sel 15.15 HID_USAGE_CONSUMER_AL_OEM_HELP = 0x01BE, HID_USAGE_CONSUMER_AL_ONLINE_COMMUNITY = 0x01BF, HID_USAGE_CONSUMER_AL_ENTERTAINMENT_CONTENT = 0x01C0, // Browser // Sel 15.15 HID_USAGE_CONSUMER_AL_ONLINE_SHOPPING_BROWSER = 0x01C1, HID_USAGE_CONSUMER_AL_SMARTCARD_INFORMATION_HELP = 0x01C2, HID_USAGE_CONSUMER_AL_MARKET_MONITOR_FINANCE = 0x01C3, // Browser // Sel 15.15 HID_USAGE_CONSUMER_AL_CUSTOMIZED_CORPORATE_NEWS = 0x01C4, // Browser // Sel 15.15 HID_USAGE_CONSUMER_AL_ONLINE_ACTIVITY_BROWSER = 0x01C5, HID_USAGE_CONSUMER_AL_RESEARCH_SEARCH_BROWSER = 0x01C6, HID_USAGE_CONSUMER_AL_AUDIO_PLAYER = 0x01C7, // 1C8-1FF Reserved HID_USAGE_CONSUMER_GENERIC_GUI_APPLICATION = 0x0200, // ' Controls // ' HID_USAGE_CONSUMER_AC_NEW = 0x0201, HID_USAGE_CONSUMER_AC_OPEN = 0x0202, HID_USAGE_CONSUMER_AC_CLOSE = 0x0203, HID_USAGE_CONSUMER_AC_EXIT = 0x0204, HID_USAGE_CONSUMER_AC_MAXIMIZE = 0x0205, HID_USAGE_CONSUMER_AC_MINIMIZE = 0x0206, HID_USAGE_CONSUMER_AC_SAVE = 0x0207, HID_USAGE_CONSUMER_AC_PRINT = 0x0208, HID_USAGE_CONSUMER_AC_PROPERTIES = 0x0209, HID_USAGE_CONSUMER_AC_UNDO = 0x021A, HID_USAGE_CONSUMER_AC_COPY = 0x021B, HID_USAGE_CONSUMER_AC_CUT = 0x021C, HID_USAGE_CONSUMER_AC_PASTE = 0x021D, HID_USAGE_CONSUMER_AC_SELECT_ALL = 0x021E, HID_USAGE_CONSUMER_AC_FIND = 0x021F, HID_USAGE_CONSUMER_AC_FIND_AND_REPLACE = 0x0220, // Browser/Explorer Specific HID_USAGE_CONSUMER_AC_SEARCH = 0x0221, HID_USAGE_CONSUMER_AC_GO_TO = 0x0222, HID_USAGE_CONSUMER_AC_HOME = 0x0223, HID_USAGE_CONSUMER_AC_BACK = 0x0224, HID_USAGE_CONSUMER_AC_FORWARD = 0x0225, HID_USAGE_CONSUMER_AC_STOP = 0x0226, HID_USAGE_CONSUMER_AC_REFRESH = 0x0227, HID_USAGE_CONSUMER_AC_PREVIOUS_LINK = 0x0228, HID_USAGE_CONSUMER_AC_NEXT_LINK = 0x0229, HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A, HID_USAGE_CONSUMER_AC_HISTORY = 0x022B, HID_USAGE_CONSUMER_AC_SUBSCRIPTIONS = 0x022C, HID_USAGE_CONSUMER_AC_ZOOM_IN = 0x022D, HID_USAGE_CONSUMER_AC_ZOOM_OUT = 0x022E, HID_USAGE_CONSUMER_AC_ZOOM = 0x022F, HID_USAGE_CONSUMER_AC_FULL_SCREEN_VIEW = 0x0230, HID_USAGE_CONSUMER_AC_NORMAL_VIEW = 0x0231, HID_USAGE_CONSUMER_AC_VIEW_TOGGLE = 0x0232, HID_USAGE_CONSUMER_AC_SCROLL_UP = 0x0233, HID_USAGE_CONSUMER_AC_SCROLL_DOWN = 0x0234, HID_USAGE_CONSUMER_AC_SCROLL = 0x0235, HID_USAGE_CONSUMER_AC_PAN_LEFT = 0x0236, HID_USAGE_CONSUMER_AC_PAN_RIGHT = 0x0237, // Mouse Horizontal scroll HID_USAGE_CONSUMER_AC_PAN = 0x0238, HID_USAGE_CONSUMER_AC_NEW_WINDOW = 0x0239, HID_USAGE_CONSUMER_AC_TILE_HORIZONTALLY = 0x023A, HID_USAGE_CONSUMER_AC_TILE_VERTICALLY = 0x023B, HID_USAGE_CONSUMER_AC_FORMAT = 0x023C, HID_USAGE_CONSUMER_AC_EDIT = 0x023D, HID_USAGE_CONSUMER_AC_BOLD = 0x023E, HID_USAGE_CONSUMER_AC_ITALICS = 0x023F, HID_USAGE_CONSUMER_AC_UNDERLINE = 0x0240, HID_USAGE_CONSUMER_AC_STRIKETHROUGH = 0x0241, HID_USAGE_CONSUMER_AC_SUBSCRIPT = 0x0242, HID_USAGE_CONSUMER_AC_SUPERSCRIPT = 0x0243, HID_USAGE_CONSUMER_AC_ALL_CAPS = 0x0244, HID_USAGE_CONSUMER_AC_ROTATE = 0x0245, HID_USAGE_CONSUMER_AC_RESIZE = 0x0246, HID_USAGE_CONSUMER_AC_FLIP_HORIZONTAL = 0x0247, HID_USAGE_CONSUMER_AC_FLIP_VERTICAL = 0x0248, HID_USAGE_CONSUMER_AC_MIRROR_HORIZONTAL = 0x0249, HID_USAGE_CONSUMER_AC_MIRROR_VERTICAL = 0x024A, HID_USAGE_CONSUMER_AC_FONT_SELECT = 0x024B, HID_USAGE_CONSUMER_AC_FONT_COLOR = 0x024C, HID_USAGE_CONSUMER_AC_FONT_SIZE = 0x024D, HID_USAGE_CONSUMER_AC_JUSTIFY_LEFT = 0x024E, HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_H = 0x024F, HID_USAGE_CONSUMER_AC_JUSTIFY_RIGHT = 0x0250, HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_H = 0x0251, HID_USAGE_CONSUMER_AC_JUSTIFY_TOP = 0x0252, HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_V = 0x0253, HID_USAGE_CONSUMER_AC_JUSTIFY_BOTTOM = 0x0254, HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_V = 0x0255, HID_USAGE_CONSUMER_AC_INDENT_DECREASE = 0x0256, HID_USAGE_CONSUMER_AC_INDENT_INCREASE = 0x0257, HID_USAGE_CONSUMER_AC_NUMBERED_LIST = 0x0258, HID_USAGE_CONSUMER_AC_RESTART_NUMBERING = 0x0259, HID_USAGE_CONSUMER_AC_BULLETED_LIST = 0x025A, HID_USAGE_CONSUMER_AC_PROMOTE = 0x025B, HID_USAGE_CONSUMER_AC_DEMOTE = 0x025C, HID_USAGE_CONSUMER_AC_YES = 0x025D, HID_USAGE_CONSUMER_AC_NO = 0x025E, HID_USAGE_CONSUMER_AC_CANCEL = 0x025F, HID_USAGE_CONSUMER_AC_CATALOG = 0x0260, HID_USAGE_CONSUMER_AC_BUY_CHECKOUT = 0x0261, HID_USAGE_CONSUMER_AC_ADD_TO_CART = 0x0262, HID_USAGE_CONSUMER_AC_EXPAND = 0x0263, HID_USAGE_CONSUMER_AC_EXPAND_ALL = 0x0264, HID_USAGE_CONSUMER_AC_COLLAPSE = 0x0265, HID_USAGE_CONSUMER_AC_COLLAPSE_ALL = 0x0266, HID_USAGE_CONSUMER_AC_PRINT_PREVIEW = 0x0267, HID_USAGE_CONSUMER_AC_PASTE_SPECIAL = 0x0268, HID_USAGE_CONSUMER_AC_INSERT_MODE = 0x0269, HID_USAGE_CONSUMER_AC_DELETE = 0x026A, HID_USAGE_CONSUMER_AC_LOCK = 0x026B, HID_USAGE_CONSUMER_AC_UNLOCK = 0x026C, HID_USAGE_CONSUMER_AC_PROTECT = 0x026D, HID_USAGE_CONSUMER_AC_UNPROTECT = 0x026E, HID_USAGE_CONSUMER_AC_ATTACH_COMMENT = 0x026F, HID_USAGE_CONSUMER_AC_DELETE_COMMENT = 0x0270, HID_USAGE_CONSUMER_AC_VIEW_COMMENT = 0x0271, HID_USAGE_CONSUMER_AC_SELECT_WORD = 0x0272, HID_USAGE_CONSUMER_AC_SELECT_SENTENCE = 0x0273, HID_USAGE_CONSUMER_AC_SELECT_PARAGRAPH = 0x0274, HID_USAGE_CONSUMER_AC_SELECT_COLUMN = 0x0275, HID_USAGE_CONSUMER_AC_SELECT_ROW = 0x0276, HID_USAGE_CONSUMER_AC_SELECT_TABLE = 0x0277, HID_USAGE_CONSUMER_AC_SELECT_OBJECT = 0x0278, HID_USAGE_CONSUMER_AC_REDO_REPEAT = 0x0279, HID_USAGE_CONSUMER_AC_SORT = 0x027A, HID_USAGE_CONSUMER_AC_SORT_ASCENDING = 0x027B, HID_USAGE_CONSUMER_AC_SORT_DESCENDING = 0x027C, HID_USAGE_CONSUMER_AC_FILTER = 0x027D, HID_USAGE_CONSUMER_AC_SET_CLOCK = 0x027E, HID_USAGE_CONSUMER_AC_VIEW_CLOCK = 0x027F, HID_USAGE_CONSUMER_AC_SELECT_TIME_ZONE = 0x0280, HID_USAGE_CONSUMER_AC_EDIT_TIME_ZONES = 0x0281, HID_USAGE_CONSUMER_AC_SET_ALARM = 0x0282, HID_USAGE_CONSUMER_AC_CLEAR_ALARM = 0x0283, HID_USAGE_CONSUMER_AC_SNOOZE_ALARM = 0x0284, HID_USAGE_CONSUMER_AC_RESET_ALARM = 0x0285, HID_USAGE_CONSUMER_AC_SYNCHRONIZE = 0x0286, HID_USAGE_CONSUMER_AC_SEND_RECEIVE = 0x0287, HID_USAGE_CONSUMER_AC_SEND_TO = 0x0288, HID_USAGE_CONSUMER_AC_REPLY = 0x0289, HID_USAGE_CONSUMER_AC_REPLY_ALL = 0x028A, HID_USAGE_CONSUMER_AC_FORWARD_MSG = 0x028B, HID_USAGE_CONSUMER_AC_SEND = 0x028C, HID_USAGE_CONSUMER_AC_ATTACH_FILE = 0x028D, HID_USAGE_CONSUMER_AC_UPLOAD = 0x028E, HID_USAGE_CONSUMER_AC_DOWNLOAD_SAVE_TARGET_AS = 0x028F, HID_USAGE_CONSUMER_AC_SET_BORDERS = 0x0290, HID_USAGE_CONSUMER_AC_INSERT_ROW = 0x0291, HID_USAGE_CONSUMER_AC_INSERT_COLUMN = 0x0292, HID_USAGE_CONSUMER_AC_INSERT_FILE = 0x0293, HID_USAGE_CONSUMER_AC_INSERT_PICTURE = 0x0294, HID_USAGE_CONSUMER_AC_INSERT_OBJECT = 0x0295, HID_USAGE_CONSUMER_AC_INSERT_SYMBOL = 0x0296, HID_USAGE_CONSUMER_AC_SAVE_AND_CLOSE = 0x0297, HID_USAGE_CONSUMER_AC_RENAME = 0x0298, HID_USAGE_CONSUMER_AC_MERGE = 0x0299, HID_USAGE_CONSUMER_AC_SPLIT = 0x029A, HID_USAGE_CONSUMER_AC_DISRIBUTE_HORIZONTALLY = 0x029B, HID_USAGE_CONSUMER_AC_DISTRIBUTE_VERTICALLY = 0x029C, // 29D-FFFF Reserved }; /// HID Usage Table: Digitizer Page (0x0D) enum { HID_USAGE_DIGITIZER_UNDEFINED = 0x00, HID_USAGE_DIGITIZER_DIGITIZER = 0x01, // CA HID_USAGE_DIGITIZER_PEN = 0x02, // CA HID_USAGE_DIGITIZER_LIGHT_PEN = 0x03, // CA HID_USAGE_DIGITIZER_TOUCH_SCREEN = 0x04, // CA HID_USAGE_DIGITIZER_TOUCH_PAD = 0x05, // CA HID_USAGE_DIGITIZER_WHITEBOARD = 0x06, // CA HID_USAGE_DIGITIZER_COORDINATE_MEASURING_MACHINE = 0x07, // CA HID_USAGE_DIGITIZER_3D_DIGITIZER = 0x08, // CA HID_USAGE_DIGITIZER_STEREO_PLOTTER = 0x09, // CA HID_USAGE_DIGITIZER_ARTICULATED_ARM = 0x0A, // CA HID_USAGE_DIGITIZER_ARMATURE = 0x0B, // CA HID_USAGE_DIGITIZER_MULTIPLE_POINT_DIGITIZER = 0x0C, // CA HID_USAGE_DIGITIZER_FREE_SPACE_WAND = 0x0D, // CA HID_USAGE_DIGITIZER_DEVICE_CONFIGURATION = 0x0E, // CA HID_USAGE_DIGITIZER_CAPACITIVE_HEAT_MAP_DIGITIZER = 0x0F, // CA // Reserved (0x10 - 0x1F) HID_USAGE_DIGITIZER_STYLUS = 0x20, // CA/CL HID_USAGE_DIGITIZER_PUCK = 0x21, // CL HID_USAGE_DIGITIZER_FINGER = 0x22, // CL HID_USAGE_DIGITIZER_DEVICE_SETTINGS = 0x23, // CL HID_USAGE_DIGITIZER_CHARACTER_GESTURE = 0x24, // CL // Reserved (0x25 - 0x2F) HID_USAGE_DIGITIZER_TIP_PRESSURE = 0x30, // DV HID_USAGE_DIGITIZER_BARREL_PRESSURE = 0x31, // DV HID_USAGE_DIGITIZER_IN_RANGE = 0x32, // MC HID_USAGE_DIGITIZER_TOUCH = 0x33, // MC HID_USAGE_DIGITIZER_UNTOUCH = 0x34, // OSC HID_USAGE_DIGITIZER_TAP = 0x35, // OSC HID_USAGE_DIGITIZER_QUALITY = 0x36, // DV HID_USAGE_DIGITIZER_DATA_VALID = 0x37, // MC HID_USAGE_DIGITIZER_TRANSDUCER_INDEX = 0x38, // DV HID_USAGE_DIGITIZER_TABLET_FUNCTION_KEYS = 0x39, // CL HID_USAGE_DIGITIZER_PROGRAM_CHANGE_KEYS = 0x3A, // CL HID_USAGE_DIGITIZER_BATTERY_STRENGTH = 0x3B, // DV HID_USAGE_DIGITIZER_INVERT = 0x3C, // MC HID_USAGE_DIGITIZER_X_TILT = 0x3D, // DV HID_USAGE_DIGITIZER_Y_TILT = 0x3E, // DV HID_USAGE_DIGITIZER_AZIMUTH = 0x3F, // DV HID_USAGE_DIGITIZER_ALTITUDE = 0x40, // DV HID_USAGE_DIGITIZER_TWIST = 0x41, // DV HID_USAGE_DIGITIZER_TIP_SWITCH = 0x42, // MC HID_USAGE_DIGITIZER_SECONDARY_TIP_SWITCH = 0x43, // MC HID_USAGE_DIGITIZER_BARREL_SWITCH = 0x44, // MC HID_USAGE_DIGITIZER_ERASER = 0x45, // MC HID_USAGE_DIGITIZER_TABLET_PICK = 0x46, // MC HID_USAGE_DIGITIZER_TOUCH_VALID = 0x47, // MC HID_USAGE_DIGITIZER_WIDTH = 0x48, // DV HID_USAGE_DIGITIZER_HEIGHT = 0x49, // DV // Reserved (0x4A - 0x50) HID_USAGE_DIGITIZER_CONTACT_IDENTIFIER = 0x51, // DV HID_USAGE_DIGITIZER_DEVICE_MODE = 0x52, // DV HID_USAGE_DIGITIZER_DEVICE_IDENTIFIER = 0x53, // DV/SV HID_USAGE_DIGITIZER_CONTACT_COUNT = 0x54, // DV HID_USAGE_DIGITIZER_CONTACT_COUNT_MAXIMUM = 0x55, // SV HID_USAGE_DIGITIZER_SCAN_TIME = 0x56, // DV HID_USAGE_DIGITIZER_SURFACE_SWITCH = 0x57, // DF HID_USAGE_DIGITIZER_BUTTON_SWITCH = 0x58, // DF HID_USAGE_DIGITIZER_PAD_TYPE = 0x59, // SF HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL_NUMBER = 0x5B, // SV HID_USAGE_DIGITIZER_PREFERRED_COLOR = 0x5C, // DV HID_USAGE_DIGITIZER_PREFERRED_COLOR_LOCKED = 0x5D, // MC HID_USAGE_DIGITIZER_PREFERRED_LINE_WIDTH = 0x5E, // DV HID_USAGE_DIGITIZER_PREFERRED_LINE_WIDTH_LOCKED = 0x5F, // MC HID_USAGE_DIGITIZER_LATENCY_MODE = 0x60, // DF HID_USAGE_DIGITIZER_GESTURE_CHARACTER_QUALITY = 0x61, // DV HID_USAGE_DIGITIZER_CHARACTER_GESTURE_DATA_LENGTH = 0x62, // DV HID_USAGE_DIGITIZER_CHARACTER_GESTURE_DATA = 0x63, // DV HID_USAGE_DIGITIZER_GESTURE_CHARACTER_ENCODING = 0x64, // NAry HID_USAGE_DIGITIZER_UTF8_CHARACTER_GESTURE_ENCODING = 0x65, // Sel HID_USAGE_DIGITIZER_UTF16_LE_CHARACTER_GESTURE_ENCODING = 0x66, // Sel HID_USAGE_DIGITIZER_UTF16_BE_CHARACTER_GESTURE_ENCODING = 0x67, // Sel HID_USAGE_DIGITIZER_UTF32_LE_CHARACTER_GESTURE_ENCODING = 0x68, // Sel HID_USAGE_DIGITIZER_UTF32_BE_CHARACTER_GESTURE_ENCODING = 0x69, // Sel HID_USAGE_DIGITIZER_CAPACITIVE_HEAT_MAP_VENDOR_ID = 0x6A, // SV HID_USAGE_DIGITIZER_CAPACITIVE_HEAT_MAP_VERSION = 0x6B, // SV HID_USAGE_DIGITIZER_CAPACITIVE_HEAT_MAP_FRAME_DATA = 0x6C, // DV HID_USAGE_DIGITIZER_GESTURE_CHARACTER_ENABLE = 0x6D, // DF HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL_NUMBER_PART2 = 0x6E, // SV HID_USAGE_DIGITIZER_NO_PREFERRED_COLOR = 0x6F, // DF HID_USAGE_DIGITIZER_PREFERRED_LINE_STYLE = 0x70, // NAry HID_USAGE_DIGITIZER_PREFERRED_LINE_STYLE_LOCKED = 0x71, // MC HID_USAGE_DIGITIZER_INK = 0x72, // Sel HID_USAGE_DIGITIZER_PENCIL = 0x73, // Sel HID_USAGE_DIGITIZER_HIGHLIGHTER = 0x74, // Sel HID_USAGE_DIGITIZER_CHISEL_MARKER = 0x75, // Sel HID_USAGE_DIGITIZER_BRUSH = 0x76, // Sel HID_USAGE_DIGITIZER_NO_PREFERENCE = 0x77, // Sel // Reserved (0x78 - 0x7F) HID_USAGE_DIGITIZER_DIGITIZER_DIAGNOSTIC = 0x80, // CL HID_USAGE_DIGITIZER_DIGITIZER_ERROR = 0x81, // NAry HID_USAGE_DIGITIZER_ERR_NORMAL_STATUS = 0x82, // Sel HID_USAGE_DIGITIZER_ERR_TRANSDUCERS_EXCEEDED = 0x83, // Sel HID_USAGE_DIGITIZER_ERR_FULL_TRANS_FEATURES_UNAVAILABLE = 0x84, // Sel HID_USAGE_DIGITIZER_ERR_CHARGE_LOW = 0x85, // Sel // Reserved (0x86 - 0x8F) HID_USAGE_DIGITIZER_TRANSDUCER_SOFTWARE_INFO = 0x90, // CL HID_USAGE_DIGITIZER_TRANSDUCER_VENDOR_ID = 0x91, // SV HID_USAGE_DIGITIZER_TRANSDUCER_PRODUCT_ID = 0x92, // SV HID_USAGE_DIGITIZER_DEVICE_SUPPORTED_PROTOCOLS = 0x93, // NAry/CL HID_USAGE_DIGITIZER_TRANSDUCER_SUPPORTED_PROTOCOLS = 0x94, // NAry/CL HID_USAGE_DIGITIZER_NO_PROTOCOL = 0x95, // Sel HID_USAGE_DIGITIZER_WACOM_AES_PROTOCOL = 0x96, // Sel HID_USAGE_DIGITIZER_USI_PROTOCOL = 0x97, // Sel HID_USAGE_DIGITIZER_MICROSOFT_PEN_PROTOCOL = 0x98, // Sel // Reserved (0x99 - 0x9F) HID_USAGE_DIGITIZER_SUPPORTED_REPORT_RATES = 0xA0, // SV/CL HID_USAGE_DIGITIZER_REPORT_RATE = 0xA1, // DV HID_USAGE_DIGITIZER_TRANSDUCER_CONNECTED = 0xA2, // SF HID_USAGE_DIGITIZER_SWITCH_DISABLED = 0xA3, // Sel HID_USAGE_DIGITIZER_SWITCH_UNIMPLEMENTED = 0xA4, // Sel HID_USAGE_DIGITIZER_TRANSDUCER_SWITCHES = 0xA5, // CL HID_USAGE_DIGITIZER_TRANSDUCER_INDEX_SELECTOR = 0xA6, // DV // Reserved (0xA7 - 0xAF) HID_USAGE_DIGITIZER_BUTTON_PRESS_THRESHOLD = 0xB0, // DV // Reserved (0xB1 - 0xFFFF) }; /// HID Usage Table: Physical Input Device Page (0x0F) enum { HID_USAGE_PID_UNDEFINED = 0x00, HID_USAGE_PID_PHYSICAL_INPUT_DEVICE = 0x01, HID_USAGE_PID_NORMAL = 0x20, HID_USAGE_PID_SET_EFFECT_REPORT = 0x21, HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_INDEX = 0x22, HID_USAGE_PID_PARAMETER_BLOCK_OFFSET = 0x23, HID_USAGE_PID_ROM_FLAG = 0x24, HID_USAGE_PID_EFFECT_TYPE = 0x25, HID_USAGE_PID_ET_CONSTANTFORCE = 0x26, HID_USAGE_PID_ET_RAMP = 0x27, HID_USAGE_PID_ET_CUSTOMFORCE = 0x28, HID_USAGE_PID_ET_SQUARE = 0x30, HID_USAGE_PID_ET_SINE = 0x31, HID_USAGE_PID_ET_TRIANGLE = 0x32, HID_USAGE_PID_ET_SAWTOOTH_UP = 0x33, HID_USAGE_PID_ET_SAWTOOTH_DOWN = 0x34, HID_USAGE_PID_ET_SPRING = 0x40, HID_USAGE_PID_ET_DAMPER = 0x41, HID_USAGE_PID_ET_INERTIA = 0x42, HID_USAGE_PID_ET_FRICTION = 0x43, HID_USAGE_PID_DURATION = 0x50, HID_USAGE_PID_SAMPLE_PERIOD = 0x51, HID_USAGE_PID_GAIN = 0x52, HID_USAGE_PID_TRIGGER_BUTTON = 0x53, HID_USAGE_PID_TRIGGER_REPEAT_INTERVAL = 0x54, HID_USAGE_PID_AXES_ENABLE = 0x55, HID_USAGE_PID_DIRECTION_ENABLE = 0x56, HID_USAGE_PID_DIRECTION = 0x57, HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_OFFSET = 0x58, HID_USAGE_PID_BLOCK_TYPE = 0x59, HID_USAGE_PID_SET_ENVELOPE_REPORT = 0x5a, HID_USAGE_PID_ATTACK_LEVEL = 0x5b, HID_USAGE_PID_ATTACK_TIME = 0x5c, HID_USAGE_PID_FADE_LEVEL = 0x5d, HID_USAGE_PID_FADE_TIME = 0x5e, HID_USAGE_PID_SET_CONDITION_REPORT = 0x5f, HID_USAGE_PID_CENTERPOINT_OFFSET = 0x60, HID_USAGE_PID_POSITIVE_COEFFICIENT = 0x61, HID_USAGE_PID_NEGATIVE_COEFFICIENT = 0x62, HID_USAGE_PID_POSITIVE_SATURATION = 0x63, HID_USAGE_PID_NEGATIVE_SATURATION = 0x64, HID_USAGE_PID_DEAD_BAND = 0x65, HID_USAGE_PID_DOWNLOAD_FORCE_SAMPLE = 0x66, HID_USAGE_PID_ISOCH_CUSTOMFORCE_ENABLE = 0x67, HID_USAGE_PID_CUSTOMFORCE_DATA_REPORT = 0x68, HID_USAGE_PID_CUSTOMFORCE_DATA = 0x69, HID_USAGE_PID_CUSTOMFORCE_VENDOR_DEFINED_DATA = 0x6a, HID_USAGE_PID_SET_CUSTOMFORCE_REPORT = 0x6b, HID_USAGE_PID_CUSTOMFORCE_DATA_OFFSET = 0x6c, HID_USAGE_PID_SAMPLE_COUNT = 0x6d, HID_USAGE_PID_SET_PERIODIC_REPORT = 0x6e, HID_USAGE_PID_OFFSET = 0x6f, HID_USAGE_PID_MAGNITUDE = 0x70, HID_USAGE_PID_PHASE = 0x71, HID_USAGE_PID_PERIOD = 0x72, HID_USAGE_PID_SET_CONSTANTFORCE_REPORT = 0x73, HID_USAGE_PID_SET_RAMPFORCE_REPORT = 0x74, HID_USAGE_PID_RAMP_START = 0x75, HID_USAGE_PID_RAMP_END = 0x76, HID_USAGE_PID_EFFECT_OPERATION_REPORT = 0x77, HID_USAGE_PID_EFFECT_OPERATION = 0x78, HID_USAGE_PID_OP_EFFECT_START = 0x79, HID_USAGE_PID_OP_EFFECT_START_SOLO = 0x7a, HID_USAGE_PID_OP_EFFECT_STOP = 0x7b, HID_USAGE_PID_LOOP_COUNT = 0x7c, HID_USAGE_PID_DEVICE_GAIN_REPORT = 0x7d, HID_USAGE_PID_DEVICE_GAIN = 0x7e, HID_USAGE_PID_PARAMETER_BLOCK_POOLS_REPORT = 0x7f, HID_USAGE_PID_RAM_POOL_SIZE = 0x80, HID_USAGE_PID_ROM_POOL_SIZE = 0x81, HID_USAGE_PID_ROM_EFFECT_BLOCK_COUNT = 0x82, HID_USAGE_PID_SIMULTANEOUS_EFFECTS_MAX = 0x83, HID_USAGE_PID_POOL_ALIGNMENT = 0x84, HID_USAGE_PID_PARAMETER_BLOCK_MOVE_REPORT = 0x85, HID_USAGE_PID_MOVE_SOURCE = 0x86, HID_USAGE_PID_MOVE_DESTINATION = 0x87, HID_USAGE_PID_MOVE_LENGTH = 0x88, HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_REPORT = 0x89, HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_STATUS = 0x8b, HID_USAGE_PID_BLOCK_LOAD_SUCCESS = 0x8c, HID_USAGE_PID_BLOCK_LOAD_FULL = 0x8d, HID_USAGE_PID_BLOCK_LOAD_ERROR = 0x8e, HID_USAGE_PID_BLOCK_HANDLE = 0x8f, HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_FREE_REPORT = 0x90, HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_HANDLE = 0x91, HID_USAGE_PID_PID_STATE_REPORT = 0x92, HID_USAGE_PID_EFFECT_PLAYING = 0x94, HID_USAGE_PID_PID_DEVICE_CONTROL_REPORT = 0x95, HID_USAGE_PID_PID_DEVICE_CONTROL = 0x96, HID_USAGE_PID_DC_ENABLE_ACTUATORS = 0x97, HID_USAGE_PID_DC_DISABLE_ACTUATORS = 0x98, HID_USAGE_PID_DC_STOP_ALL_EFFECTS = 0x99, HID_USAGE_PID_DC_RESET = 0x9a, HID_USAGE_PID_DC_PAUSE = 0x9b, HID_USAGE_PID_DC_CONTINUE = 0x9c, HID_USAGE_PID_DEVICE_PAUSED = 0x9f, HID_USAGE_PID_ACTUATORS_ENABLED = 0xa0, HID_USAGE_PID_SAFETY_SWITCH = 0xa4, HID_USAGE_PID_ACTUATOR_OVERRIDE_SWITCH = 0xa5, HID_USAGE_PID_ACTUATOR_POWER = 0xa6, HID_USAGE_PID_START_DELAY = 0xa7, HID_USAGE_PID_PARAMETER_BLOCK_SIZE = 0xa8, HID_USAGE_PID_DEVICEMANAGED_POOL = 0xa9, HID_USAGE_PID_SHARED_PARAMETER_BLOCKS = 0xaa, HID_USAGE_PID_CREATE_NEW_EFFECT_PARAMETER_BLOCK_REPORT = 0xab, HID_USAGE_PID_RAM_POOL_AVAILABLE = 0xac, }; /// HID Usage Table - Lighting And Illumination Page (0x59) enum { HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01, HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02, HID_USAGE_LIGHTING_LAMP_COUNT = 0x03, HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04, HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05, HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06, HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07, HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08, HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20, HID_USAGE_LIGHTING_LAMP_ID = 0x21, HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22, HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23, HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24, HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25, HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26, HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27, HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28, HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29, HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A, HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B, HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C, HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D, HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50, HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51, HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52, HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53, HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54, HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55, HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60, HID_USAGE_LIGHTING_LAMP_ID_START = 0x61, HID_USAGE_LIGHTING_LAMP_ID_END = 0x62, HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70, HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71, }; /// HID Usage Table: Power Device Page (0x84) enum { HID_USAGE_POWER_UNDEFINED = 0x00, HID_USAGE_POWER_I_NAME = 0x01, HID_USAGE_POWER_PRESENT_STATUS = 0x02, HID_USAGE_POWER_CHANGED_STATUS = 0x03, HID_USAGE_POWER_UPS = 0x04, HID_USAGE_POWER_POWER_SUPPLY = 0x05, // 06-0F Reserved HID_USAGE_POWER_BATTERY_SYSTEM = 0x10, HID_USAGE_POWER_BATTERY_SYSTEM_ID = 0x11, HID_USAGE_POWER_BATTERY = 0x12, HID_USAGE_POWER_BATTERY_ID = 0x13, HID_USAGE_POWER_CHARGER = 0x14, HID_USAGE_POWER_CHARGER_ID = 0x15, HID_USAGE_POWER_POWER_CONVERTER = 0x16, HID_USAGE_POWER_POWER_CONVERTER_ID = 0x17, HID_USAGE_POWER_OUTLET_SYSTEM = 0x18, HID_USAGE_POWER_OUTLET_SYSTEM_ID = 0x19, HID_USAGE_POWER_INPUT = 0x1A, HID_USAGE_POWER_INPUT_ID = 0x1B, HID_USAGE_POWER_OUTPUT = 0x1C, HID_USAGE_POWER_OUTPUT_ID = 0x1D, HID_USAGE_POWER_FLOW = 0x1E, HID_USAGE_POWER_FLOW_ID = 0x1F, HID_USAGE_POWER_OUTLET = 0x20, HID_USAGE_POWER_OUTLET_ID = 0x21, HID_USAGE_POWER_GANG = 0x22, HID_USAGE_POWER_GANG_ID = 0x23, HID_USAGE_POWER_POWER_SUMMARY = 0x24, HID_USAGE_POWER_POWER_SUMMARY_ID = 0x25, // 26-2F Reserved HID_USAGE_POWER_VOLTAGE = 0x30, HID_USAGE_POWER_CURRENT = 0x31, HID_USAGE_POWER_FREQUENCY = 0x32, HID_USAGE_POWER_APPARENT_POWER = 0x33, HID_USAGE_POWER_ACTIVE_POWER = 0x34, HID_USAGE_POWER_PERCENT_LOAD = 0x35, HID_USAGE_POWER_TEMPERATURE = 0x36, HID_USAGE_POWER_HUMIDITY = 0x37, HID_USAGE_POWER_BAD_COUNT = 0x38, // 39-3F Reserved HID_USAGE_POWER_CONFIG_VOLTAGE = 0x40, HID_USAGE_POWER_CONFIG_CURRENT = 0x41, HID_USAGE_POWER_CONFIG_FREQUENCY = 0x42, HID_USAGE_POWER_CONFIG_APPARENT_POWER = 0x43, HID_USAGE_POWER_CONFIG_ACTIVE_POWER = 0x44, HID_USAGE_POWER_CONFIG_PERCENT_LOAD = 0x45, HID_USAGE_POWER_CONFIG_TEMPERATURE = 0x46, HID_USAGE_POWER_CONFIG_HUMIDITY = 0x47, // 48-4F Reserved HID_USAGE_POWER_SWITCH_ON_CONTROL = 0x50, HID_USAGE_POWER_SWITCH_OFF_CONTROL = 0x51, HID_USAGE_POWER_TOGGLE_CONTROL = 0x52, HID_USAGE_POWER_LOW_VOLTAGE_TRANSFER = 0x53, HID_USAGE_POWER_HIGH_VOLTAGE_TRANSFER = 0x54, HID_USAGE_POWER_DELAY_BEFORE_REBOOT = 0x55, HID_USAGE_POWER_DELAY_BEFORE_STARTUP = 0x56, HID_USAGE_POWER_DELAY_BEFORE_SHUTDOWN = 0x57, HID_USAGE_POWER_TEST = 0x58, HID_USAGE_POWER_MODULE_RESET = 0x59, HID_USAGE_POWER_AUDIBLE_ALARM_CONTROL = 0x5A, // 5B-5F Reserved HID_USAGE_POWER_PRESENT = 0x60, HID_USAGE_POWER_GOOD = 0x61, HID_USAGE_POWER_INTERNAL_FAILURE = 0x62, HID_USAGE_POWER_VOLTAGE_OUT_OF_RANGE = 0x63, HID_USAGE_POWER_FREQUENCY_OUT_OF_RANGE = 0x64, HID_USAGE_POWER_OVERLOAD = 0x65, HID_USAGE_POWER_OVER_CHARGED = 0x66, HID_USAGE_POWER_OVER_TEMPERATURE = 0x67, HID_USAGE_POWER_SHUTDOWN_REQUESTED = 0x68, HID_USAGE_POWER_SHUTDOWN_IMMINENT = 0x69, // 6A Reserved HID_USAGE_POWER_SWITCH_ON_OFF = 0x6B, HID_USAGE_POWER_SWITCHABLE = 0x6C, HID_USAGE_POWER_USED = 0x6D, HID_USAGE_POWER_BOOST = 0x6E, HID_USAGE_POWER_BUCK = 0x6F, HID_USAGE_POWER_INITIALIZED = 0x70, HID_USAGE_POWER_TESTED = 0x71, HID_USAGE_POWER_AWAITING_POWER = 0x72, HID_USAGE_POWER_COMMUNICATION_LOST = 0x73, // 74-FC Reserved HID_USAGE_POWER_I_MANUFACTURER = 0xFD, HID_USAGE_POWER_I_PRODUCT = 0xFE, HID_USAGE_POWER_I_SERIAL_NUMBER = 0xFF }; /// HID Usage Table: Battery System Page (0x85) enum { HID_USAGE_BATTERY_UNDEFINED = 0x00, HID_USAGE_BATTERY_SMB_BATTERY_MODE = 0x01, HID_USAGE_BATTERY_SMB_BATTERY_STATUS = 0x02, HID_USAGE_BATTERY_SMB_ALARM_WARNING = 0x03, HID_USAGE_BATTERY_SMB_CHARGER_MODE = 0x04, HID_USAGE_BATTERY_SMB_CHARGER_STATUS = 0x05, HID_USAGE_BATTERY_SMB_CHARGER_SPEC_INFO = 0x06, HID_USAGE_BATTERY_SMB_SELECTOR_STATE = 0x07, HID_USAGE_BATTERY_SMB_SELECTOR_PRESETS = 0x08, HID_USAGE_BATTERY_SMB_SELECTOR_INFO = 0x09, // 0A-0F Reserved HID_USAGE_BATTERY_OPTIONAL_MFG_FUNCTION_1 = 0x10, HID_USAGE_BATTERY_OPTIONAL_MFG_FUNCTION_2 = 0x11, HID_USAGE_BATTERY_OPTIONAL_MFG_FUNCTION_3 = 0x12, HID_USAGE_BATTERY_OPTIONAL_MFG_FUNCTION_4 = 0x13, HID_USAGE_BATTERY_OPTIONAL_MFG_FUNCTION_5 = 0x14, HID_USAGE_BATTERY_CONNECTION_TO_SMBUS = 0x15, HID_USAGE_BATTERY_OUTPUT_CONNECTION = 0x16, HID_USAGE_BATTERY_CHARGER_CONNECTION = 0x17, HID_USAGE_BATTERY_BATTERY_INSERTION = 0x18, HID_USAGE_BATTERY_USE_NEXT = 0x19, HID_USAGE_BATTERY_OK_TO_USE = 0x1A, HID_USAGE_BATTERY_BATTERY_SUPPORTED = 0x1B, HID_USAGE_BATTERY_SELECTOR_REVISION = 0x1C, HID_USAGE_BATTERY_CHARGING_INDICATOR = 0x1D, // 1E-27 Reserved HID_USAGE_BATTERY_MANUFACTURER_ACCESS = 0x28, HID_USAGE_BATTERY_REMAINING_CAPACITY_LIMIT = 0x29, HID_USAGE_BATTERY_REMAINING_TIME_LIMIT = 0x2A, HID_USAGE_BATTERY_AT_RATE = 0x2B, HID_USAGE_BATTERY_CAPACITY_MODE = 0x2C, HID_USAGE_BATTERY_BROADCAST_TO_CHARGER = 0x2D, HID_USAGE_BATTERY_PRIMARY_BATTERY = 0x2E, HID_USAGE_BATTERY_CHARGE_CONTROLLER = 0x2F, // 30-3F Reserved HID_USAGE_BATTERY_TERMINATE_CHARGE = 0x40, HID_USAGE_BATTERY_TERMINATE_DISCHARGE = 0x41, HID_USAGE_BATTERY_BELOW_REMAINING_CAPACITY_LIMIT = 0x42, HID_USAGE_BATTERY_REMAINING_TIME_LIMIT_EXPIRED = 0x43, HID_USAGE_BATTERY_CHARGING = 0x44, HID_USAGE_BATTERY_DISCHARGING = 0x45, HID_USAGE_BATTERY_FULLY_CHARGED = 0x46, HID_USAGE_BATTERY_FULLY_DISCHARGED = 0x47, HID_USAGE_BATTERY_CONDITIONING_FLAG = 0x48, HID_USAGE_BATTERY_AT_RATE_OK = 0x49, HID_USAGE_BATTERY_SMB_ERROR_CODE = 0x4A, HID_USAGE_BATTERY_NEED_REPLACEMENT = 0x4B, // 4C-5F Reserved HID_USAGE_BATTERY_AT_RATE_TIME_TO_FULL = 0x60, HID_USAGE_BATTERY_AT_RATE_TIME_TO_EMPTY = 0x61, HID_USAGE_BATTERY_AVERAGE_CURRENT = 0x62, HID_USAGE_BATTERY_MAX_ERROR = 0x63, HID_USAGE_BATTERY_RELATIVE_STATE_OF_CHARGE = 0x64, HID_USAGE_BATTERY_ABSOLUTE_STATE_OF_CHARGE = 0x65, HID_USAGE_BATTERY_REMAINING_CAPACITY = 0x66, HID_USAGE_BATTERY_FULL_CHARGE_CAPACITY = 0x67, HID_USAGE_BATTERY_RUN_TIME_TO_EMPTY = 0x68, HID_USAGE_BATTERY_AVERAGE_TIME_TO_EMPTY = 0x69, HID_USAGE_BATTERY_AVERAGE_TIME_TO_FULL = 0x6A, HID_USAGE_BATTERY_CYCLE_COUNT = 0x6B, // 6C-7F Reserved HID_USAGE_BATTERY_BATT_PACK_MODEL_LEVEL = 0x80, HID_USAGE_BATTERY_INTERNAL_CHARGE_CONTROLLER = 0x81, HID_USAGE_BATTERY_PRIMARY_BATTERY_SUPPORT = 0x82, HID_USAGE_BATTERY_DESIGN_CAPACITY = 0x83, HID_USAGE_BATTERY_SPECIFICATION_INFO = 0x84, HID_USAGE_BATTERY_MANUFACTURER_DATE = 0x85, HID_USAGE_BATTERY_SERIAL_NUMBER = 0x86, HID_USAGE_BATTERY_I_MANUFACTURER_NAME = 0x87, HID_USAGE_BATTERY_I_DEVICE_NAME = 0x88, HID_USAGE_BATTERY_I_DEVICE_CHEMISTRY = 0x89, HID_USAGE_BATTERY_MANUFACTURER_DATA = 0x8A, HID_USAGE_BATTERY_RECHARGEABLE = 0x8B, HID_USAGE_BATTERY_WARNING_CAPACITY_LIMIT = 0x8C, HID_USAGE_BATTERY_CAPACITY_GRANULARITY_1 = 0x8D, HID_USAGE_BATTERY_CAPACITY_GRANULARITY_2 = 0x8E, HID_USAGE_BATTERY_I_OEMINFORMATION = 0x8F, // 90-BF Reserved HID_USAGE_BATTERY_INHIBIT_CHARGE = 0xC0, HID_USAGE_BATTERY_ENABLE_POLLING = 0xC1, HID_USAGE_BATTERY_RESET_TO_ZERO = 0xC2, // C3-CF Reserved HID_USAGE_BATTERY_AC_PRESENT = 0xD0, HID_USAGE_BATTERY_BATTERY_PRESENT = 0xD1, HID_USAGE_BATTERY_POWER_FAIL = 0xD2, HID_USAGE_BATTERY_ALARM_INHIBITED = 0xD3, HID_USAGE_BATTERY_THERMISTOR_UNDER_RANGE = 0xD4, HID_USAGE_BATTERY_THERMISTOR_HOT = 0xD5, HID_USAGE_BATTERY_THERMISTOR_COLD = 0xD6, HID_USAGE_BATTERY_THERMISTOR_OVER_RANGE = 0xD7, HID_USAGE_BATTERY_VOLTAGE_OUT_OF_RANGE = 0xD8, HID_USAGE_BATTERY_CURRENT_OUT_OF_RANGE = 0xD9, HID_USAGE_BATTERY_CURRENT_NOT_REGULATED = 0xDA, HID_USAGE_BATTERY_VOLTAGE_NOT_REGULATED = 0xDB, HID_USAGE_BATTERY_MASTER_MODE = 0xDC, // DD-EF Reserved HID_USAGE_BATTERY_CHARGER_SELECTOR_SUPPORT = 0xF0, HID_USAGE_BATTERY_CHARGER_SPEC = 0xF1, HID_USAGE_BATTERY_LEVEL_2 = 0xF2, HID_USAGE_BATTERY_LEVEL_3 = 0xF3 // F4-FF Reserved }; /// HID Usage Table: FIDO Alliance Page (0xF1D0) enum { HID_USAGE_FIDO_U2FHID = 0x01, // U2FHID usage for top-level collection HID_USAGE_FIDO_DATA_IN = 0x20, // Raw IN data report HID_USAGE_FIDO_DATA_OUT = 0x21 // Raw OUT data report }; /*-------------------------------------------------------------------- * ASCII to KEYCODE Conversion * Expand to array of [128][2] (shift, keycode) * * Usage: example to convert input chr into keyboard report (modifier + keycode) * * uint8_t const conv_table[128][2] = { HID_ASCII_TO_KEYCODE }; * * uint8_t keycode[6] = { 0 }; * uint8_t modifier = 0; * * if ( conv_table[chr][0] ) modifier = KEYBOARD_MODIFIER_LEFTSHIFT; * keycode[0] = conv_table[chr][1]; * tud_hid_keyboard_report(report_id, modifier, keycode); * *--------------------------------------------------------------------*/ #define HID_ASCII_TO_KEYCODE \ {0, 0 }, /* 0x00 Null */ \ {0, 0 }, /* 0x01 */ \ {0, 0 }, /* 0x02 */ \ {0, 0 }, /* 0x03 */ \ {0, 0 }, /* 0x04 */ \ {0, 0 }, /* 0x05 */ \ {0, 0 }, /* 0x06 */ \ {0, 0 }, /* 0x07 */ \ {0, HID_KEY_BACKSPACE }, /* 0x08 Backspace */ \ {0, HID_KEY_TAB }, /* 0x09 Tab */ \ {0, HID_KEY_ENTER }, /* 0x0A Line Feed */ \ {0, 0 }, /* 0x0B */ \ {0, 0 }, /* 0x0C */ \ {0, HID_KEY_ENTER }, /* 0x0D CR */ \ {0, 0 }, /* 0x0E */ \ {0, 0 }, /* 0x0F */ \ {0, 0 }, /* 0x10 */ \ {0, 0 }, /* 0x11 */ \ {0, 0 }, /* 0x12 */ \ {0, 0 }, /* 0x13 */ \ {0, 0 }, /* 0x14 */ \ {0, 0 }, /* 0x15 */ \ {0, 0 }, /* 0x16 */ \ {0, 0 }, /* 0x17 */ \ {0, 0 }, /* 0x18 */ \ {0, 0 }, /* 0x19 */ \ {0, 0 }, /* 0x1A */ \ {0, HID_KEY_ESCAPE }, /* 0x1B Escape */ \ {0, 0 }, /* 0x1C */ \ {0, 0 }, /* 0x1D */ \ {0, 0 }, /* 0x1E */ \ {0, 0 }, /* 0x1F */ \ \ {0, HID_KEY_SPACE }, /* 0x20 */ \ {1, HID_KEY_1 }, /* 0x21 ! */ \ {1, HID_KEY_APOSTROPHE }, /* 0x22 " */ \ {1, HID_KEY_3 }, /* 0x23 # */ \ {1, HID_KEY_4 }, /* 0x24 $ */ \ {1, HID_KEY_5 }, /* 0x25 % */ \ {1, HID_KEY_7 }, /* 0x26 & */ \ {0, HID_KEY_APOSTROPHE }, /* 0x27 ' */ \ {1, HID_KEY_9 }, /* 0x28 ( */ \ {1, HID_KEY_0 }, /* 0x29 ) */ \ {1, HID_KEY_8 }, /* 0x2A * */ \ {1, HID_KEY_EQUAL }, /* 0x2B + */ \ {0, HID_KEY_COMMA }, /* 0x2C , */ \ {0, HID_KEY_MINUS }, /* 0x2D - */ \ {0, HID_KEY_PERIOD }, /* 0x2E . */ \ {0, HID_KEY_SLASH }, /* 0x2F / */ \ {0, HID_KEY_0 }, /* 0x30 0 */ \ {0, HID_KEY_1 }, /* 0x31 1 */ \ {0, HID_KEY_2 }, /* 0x32 2 */ \ {0, HID_KEY_3 }, /* 0x33 3 */ \ {0, HID_KEY_4 }, /* 0x34 4 */ \ {0, HID_KEY_5 }, /* 0x35 5 */ \ {0, HID_KEY_6 }, /* 0x36 6 */ \ {0, HID_KEY_7 }, /* 0x37 7 */ \ {0, HID_KEY_8 }, /* 0x38 8 */ \ {0, HID_KEY_9 }, /* 0x39 9 */ \ {1, HID_KEY_SEMICOLON }, /* 0x3A : */ \ {0, HID_KEY_SEMICOLON }, /* 0x3B ; */ \ {1, HID_KEY_COMMA }, /* 0x3C < */ \ {0, HID_KEY_EQUAL }, /* 0x3D = */ \ {1, HID_KEY_PERIOD }, /* 0x3E > */ \ {1, HID_KEY_SLASH }, /* 0x3F ? */ \ \ {1, HID_KEY_2 }, /* 0x40 @ */ \ {1, HID_KEY_A }, /* 0x41 A */ \ {1, HID_KEY_B }, /* 0x42 B */ \ {1, HID_KEY_C }, /* 0x43 C */ \ {1, HID_KEY_D }, /* 0x44 D */ \ {1, HID_KEY_E }, /* 0x45 E */ \ {1, HID_KEY_F }, /* 0x46 F */ \ {1, HID_KEY_G }, /* 0x47 G */ \ {1, HID_KEY_H }, /* 0x48 H */ \ {1, HID_KEY_I }, /* 0x49 I */ \ {1, HID_KEY_J }, /* 0x4A J */ \ {1, HID_KEY_K }, /* 0x4B K */ \ {1, HID_KEY_L }, /* 0x4C L */ \ {1, HID_KEY_M }, /* 0x4D M */ \ {1, HID_KEY_N }, /* 0x4E N */ \ {1, HID_KEY_O }, /* 0x4F O */ \ {1, HID_KEY_P }, /* 0x50 P */ \ {1, HID_KEY_Q }, /* 0x51 Q */ \ {1, HID_KEY_R }, /* 0x52 R */ \ {1, HID_KEY_S }, /* 0x53 S */ \ {1, HID_KEY_T }, /* 0x55 T */ \ {1, HID_KEY_U }, /* 0x55 U */ \ {1, HID_KEY_V }, /* 0x56 V */ \ {1, HID_KEY_W }, /* 0x57 W */ \ {1, HID_KEY_X }, /* 0x58 X */ \ {1, HID_KEY_Y }, /* 0x59 Y */ \ {1, HID_KEY_Z }, /* 0x5A Z */ \ {0, HID_KEY_BRACKET_LEFT }, /* 0x5B [ */ \ {0, HID_KEY_BACKSLASH }, /* 0x5C '\' */ \ {0, HID_KEY_BRACKET_RIGHT }, /* 0x5D ] */ \ {1, HID_KEY_6 }, /* 0x5E ^ */ \ {1, HID_KEY_MINUS }, /* 0x5F _ */ \ \ {0, HID_KEY_GRAVE }, /* 0x60 ` */ \ {0, HID_KEY_A }, /* 0x61 a */ \ {0, HID_KEY_B }, /* 0x62 b */ \ {0, HID_KEY_C }, /* 0x63 c */ \ {0, HID_KEY_D }, /* 0x66 d */ \ {0, HID_KEY_E }, /* 0x65 e */ \ {0, HID_KEY_F }, /* 0x66 f */ \ {0, HID_KEY_G }, /* 0x67 g */ \ {0, HID_KEY_H }, /* 0x68 h */ \ {0, HID_KEY_I }, /* 0x69 i */ \ {0, HID_KEY_J }, /* 0x6A j */ \ {0, HID_KEY_K }, /* 0x6B k */ \ {0, HID_KEY_L }, /* 0x6C l */ \ {0, HID_KEY_M }, /* 0x6D m */ \ {0, HID_KEY_N }, /* 0x6E n */ \ {0, HID_KEY_O }, /* 0x6F o */ \ {0, HID_KEY_P }, /* 0x70 p */ \ {0, HID_KEY_Q }, /* 0x71 q */ \ {0, HID_KEY_R }, /* 0x72 r */ \ {0, HID_KEY_S }, /* 0x73 s */ \ {0, HID_KEY_T }, /* 0x75 t */ \ {0, HID_KEY_U }, /* 0x75 u */ \ {0, HID_KEY_V }, /* 0x76 v */ \ {0, HID_KEY_W }, /* 0x77 w */ \ {0, HID_KEY_X }, /* 0x78 x */ \ {0, HID_KEY_Y }, /* 0x79 y */ \ {0, HID_KEY_Z }, /* 0x7A z */ \ {1, HID_KEY_BRACKET_LEFT }, /* 0x7B { */ \ {1, HID_KEY_BACKSLASH }, /* 0x7C | */ \ {1, HID_KEY_BRACKET_RIGHT }, /* 0x7D } */ \ {1, HID_KEY_GRAVE }, /* 0x7E ~ */ \ {0, HID_KEY_DELETE } /* 0x7F Delete */ \ /*-------------------------------------------------------------------- * KEYCODE to Ascii Conversion * Expand to array of [128][2] (ascii without shift, ascii with shift) * * Usage: example to convert ascii from keycode (key) and shift modifier (shift). * Here we assume key < 128 ( printable ) * * uint8_t const conv_table[128][2] = { HID_KEYCODE_TO_ASCII }; * char ch = shift ? conv_table[chr][1] : conv_table[chr][0]; * *--------------------------------------------------------------------*/ #define HID_KEYCODE_TO_ASCII \ {0 , 0 }, /* 0x00 */ \ {0 , 0 }, /* 0x01 */ \ {0 , 0 }, /* 0x02 */ \ {0 , 0 }, /* 0x03 */ \ {'a' , 'A' }, /* 0x04 */ \ {'b' , 'B' }, /* 0x05 */ \ {'c' , 'C' }, /* 0x06 */ \ {'d' , 'D' }, /* 0x07 */ \ {'e' , 'E' }, /* 0x08 */ \ {'f' , 'F' }, /* 0x09 */ \ {'g' , 'G' }, /* 0x0a */ \ {'h' , 'H' }, /* 0x0b */ \ {'i' , 'I' }, /* 0x0c */ \ {'j' , 'J' }, /* 0x0d */ \ {'k' , 'K' }, /* 0x0e */ \ {'l' , 'L' }, /* 0x0f */ \ {'m' , 'M' }, /* 0x10 */ \ {'n' , 'N' }, /* 0x11 */ \ {'o' , 'O' }, /* 0x12 */ \ {'p' , 'P' }, /* 0x13 */ \ {'q' , 'Q' }, /* 0x14 */ \ {'r' , 'R' }, /* 0x15 */ \ {'s' , 'S' }, /* 0x16 */ \ {'t' , 'T' }, /* 0x17 */ \ {'u' , 'U' }, /* 0x18 */ \ {'v' , 'V' }, /* 0x19 */ \ {'w' , 'W' }, /* 0x1a */ \ {'x' , 'X' }, /* 0x1b */ \ {'y' , 'Y' }, /* 0x1c */ \ {'z' , 'Z' }, /* 0x1d */ \ {'1' , '!' }, /* 0x1e */ \ {'2' , '@' }, /* 0x1f */ \ {'3' , '#' }, /* 0x20 */ \ {'4' , '$' }, /* 0x21 */ \ {'5' , '%' }, /* 0x22 */ \ {'6' , '^' }, /* 0x23 */ \ {'7' , '&' }, /* 0x24 */ \ {'8' , '*' }, /* 0x25 */ \ {'9' , '(' }, /* 0x26 */ \ {'0' , ')' }, /* 0x27 */ \ {'\r' , '\r' }, /* 0x28 */ \ {'\x1b', '\x1b' }, /* 0x29 */ \ {'\b' , '\b' }, /* 0x2a */ \ {'\t' , '\t' }, /* 0x2b */ \ {' ' , ' ' }, /* 0x2c */ \ {'-' , '_' }, /* 0x2d */ \ {'=' , '+' }, /* 0x2e */ \ {'[' , '{' }, /* 0x2f */ \ {']' , '}' }, /* 0x30 */ \ {'\\' , '|' }, /* 0x31 */ \ {'#' , '~' }, /* 0x32 */ \ {';' , ':' }, /* 0x33 */ \ {'\'' , '\"' }, /* 0x34 */ \ {'`' , '~' }, /* 0x35 */ \ {',' , '<' }, /* 0x36 */ \ {'.' , '>' }, /* 0x37 */ \ {'/' , '?' }, /* 0x38 */ \ \ {0 , 0 }, /* 0x39 */ \ {0 , 0 }, /* 0x3a */ \ {0 , 0 }, /* 0x3b */ \ {0 , 0 }, /* 0x3c */ \ {0 , 0 }, /* 0x3d */ \ {0 , 0 }, /* 0x3e */ \ {0 , 0 }, /* 0x3f */ \ {0 , 0 }, /* 0x40 */ \ {0 , 0 }, /* 0x41 */ \ {0 , 0 }, /* 0x42 */ \ {0 , 0 }, /* 0x43 */ \ {0 , 0 }, /* 0x44 */ \ {0 , 0 }, /* 0x45 */ \ {0 , 0 }, /* 0x46 */ \ {0 , 0 }, /* 0x47 */ \ {0 , 0 }, /* 0x48 */ \ {0 , 0 }, /* 0x49 */ \ {0 , 0 }, /* 0x4a */ \ {0 , 0 }, /* 0x4b */ \ {0 , 0 }, /* 0x4c */ \ {0 , 0 }, /* 0x4d */ \ {0 , 0 }, /* 0x4e */ \ {0 , 0 }, /* 0x4f */ \ {0 , 0 }, /* 0x50 */ \ {0 , 0 }, /* 0x51 */ \ {0 , 0 }, /* 0x52 */ \ {0 , 0 }, /* 0x53 */ \ \ {'/' , '/' }, /* 0x54 */ \ {'*' , '*' }, /* 0x55 */ \ {'-' , '-' }, /* 0x56 */ \ {'+' , '+' }, /* 0x57 */ \ {'\r' , '\r' }, /* 0x58 */ \ {'1' , 0 }, /* 0x59 */ \ {'2' , 0 }, /* 0x5a */ \ {'3' , 0 }, /* 0x5b */ \ {'4' , 0 }, /* 0x5c */ \ {'5' , '5' }, /* 0x5d */ \ {'6' , 0 }, /* 0x5e */ \ {'7' , 0 }, /* 0x5f */ \ {'8' , 0 }, /* 0x60 */ \ {'9' , 0 }, /* 0x61 */ \ {'0' , 0 }, /* 0x62 */ \ {'.' , 0 }, /* 0x63 */ \ {0 , 0 }, /* 0x64 */ \ {0 , 0 }, /* 0x65 */ \ {0 , 0 }, /* 0x66 */ \ {'=' , '=' }, /* 0x67 */ \ #ifdef __cplusplus } #endif #endif /* TUSB_HID_H__ */ /// @} ================================================ FILE: src/class/hid/hid_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_HID) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "device/usbd.h" #include "device/usbd_pvt.h" #include "hid_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; // optional Out endpoint uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; uint8_t protocol_mode; // Boot (0) or Report protocol (1) uint8_t idle_rate; // up to application to handle idle rate // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration const tusb_hid_descriptor_hid_t*hid_descriptor; } hidd_interface_t; typedef struct { TUD_EPBUF_DEF(ctrl , CFG_TUD_HID_EP_BUFSIZE); TUD_EPBUF_DEF(epin , CFG_TUD_HID_EP_BUFSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_HID_EP_BUFSIZE); } hidd_epbuf_t; static hidd_interface_t _hidd_itf[CFG_TUD_HID]; CFG_TUD_MEM_SECTION static hidd_epbuf_t _hidd_epbuf[CFG_TUD_HID]; /*------------- Helpers -------------*/ TU_ATTR_ALWAYS_INLINE static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { for (uint8_t i = 0; i < CFG_TUD_HID; i++) { if (itf_num == _hidd_itf[i].itf_num) { return i; } } return 0xFF; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { (void) instance; (void) protocol; } TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate) { (void) instance; (void) idle_rate; return true; } TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { (void) instance; (void) report; (void) len; } // Invoked when a transfer wasn't successful TU_ATTR_WEAK void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes) { (void) instance; (void) report_type; (void) report; (void) xferred_bytes; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_hid_n_ready(uint8_t instance) { uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { TU_VERIFY(instance < CFG_TUD_HID); const uint8_t rhport = 0; hidd_interface_t *p_hid = &_hidd_itf[instance]; hidd_epbuf_t *p_epbuf = &_hidd_epbuf[instance]; // claim endpoint TU_VERIFY(usbd_edpt_claim(rhport, p_hid->ep_in)); // prepare data if (report_id) { p_epbuf->epin[0] = report_id; TU_VERIFY(0 == tu_memcpy_s(p_epbuf->epin + 1, CFG_TUD_HID_EP_BUFSIZE - 1, report, len)); len++; } else { TU_VERIFY(0 == tu_memcpy_s(p_epbuf->epin, CFG_TUD_HID_EP_BUFSIZE, report, len)); } return usbd_edpt_xfer(rhport, p_hid->ep_in, p_epbuf->epin, len, false); } uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]) { hid_keyboard_report_t report; report.modifier = modifier; report.reserved = 0; if (keycode) { memcpy(report.keycode, keycode, sizeof(report.keycode)); } else { tu_memclr(report.keycode, 6); } return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { hid_mouse_report_t report = { .buttons = buttons, .x = x, .y = y, .wheel = vertical, .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { hid_abs_mouse_report_t report = { .buttons = buttons, .x = x, .y = y, .wheel = vertical, .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { hid_gamepad_report_t report = { .x = x, .y = y, .z = z, .rz = rz, .rx = rx, .ry = ry, .hat = hat, .buttons = buttons, }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) { hid_stylus_report_t report = { .attr = attrs, .x = x, .y = y, }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ void hidd_init(void) { hidd_reset(0); } bool hidd_deinit(void) { return true; } void hidd_reset(uint8_t rhport) { (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface hidd_interface_t *p_hid; uint8_t hid_id; for (hid_id = 0; hid_id < CFG_TUD_HID; hid_id++) { p_hid = &_hidd_itf[hid_id]; if (p_hid->ep_in == 0) { break; } } TU_ASSERT(hid_id < CFG_TUD_HID, 0); hidd_epbuf_t *p_epbuf = &_hidd_epbuf[hid_id]; uint8_t const *p_desc = (uint8_t const *)desc_itf; //------------- HID descriptor -------------// p_desc = tu_desc_next(p_desc); TU_ASSERT(HID_DESC_TYPE_HID == tu_desc_type(p_desc), 0); p_hid->hid_descriptor = (tusb_hid_descriptor_hid_t const *)p_desc; //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; } p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode p_hid->itf_num = desc_itf->bInterfaceNumber; // Use offsetof to avoid pointer to the odd/misaligned address p_hid->report_desc_len = tu_unaligned_read16((uint8_t const *)p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Prepare for output endpoint if (p_hid->ep_out) { TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE, false), drv_len); } return drv_len; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); TU_VERIFY(hid_itf < CFG_TUD_HID); hidd_interface_t *p_hid = &_hidd_itf[hid_itf]; hidd_epbuf_t *p_epbuf = &_hidd_epbuf[hid_itf]; if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// if (stage == CONTROL_STAGE_SETUP) { uint8_t const desc_type = tu_u16_high(request->wValue); // uint8_t const desc_index = tu_u16_low (request->wValue); if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { TU_VERIFY(p_hid->hid_descriptor); TU_VERIFY(tud_control_xfer(rhport, request, (void *)(uintptr_t)p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { uint8_t const *desc_report = tud_hid_descriptor_report_cb(hid_itf); tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_report, p_hid->report_desc_len); } else { return false; // stall unsupported request } } } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// switch (request->bRequest) { case HID_REQ_CONTROL_GET_REPORT: if (stage == CONTROL_STAGE_SETUP) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); uint8_t* report_buf = p_epbuf->ctrl; uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); uint16_t xferlen = 0; // If host request a specific Report ID, add ID to as 1 byte of response if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { *report_buf++ = report_id; req_len--; xferlen++; } xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); TU_ASSERT(xferlen > 0); tud_control_xfer(rhport, request, p_epbuf->ctrl, xferlen); } break; case HID_REQ_CONTROL_SET_REPORT: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength <= CFG_TUD_HID_EP_BUFSIZE); tud_control_xfer(rhport, request, p_epbuf->ctrl, request->wLength); } else if (stage == CONTROL_STAGE_ACK) { uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); uint8_t const* report_buf = p_epbuf->ctrl; uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); // If host request a specific Report ID, extract report ID in buffer before invoking callback if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { report_buf++; report_len--; } tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); } break; case HID_REQ_CONTROL_SET_IDLE: if (stage == CONTROL_STAGE_SETUP) { p_hid->idle_rate = tu_u16_high(request->wValue); TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); // stall if false tud_control_status(rhport, request); } break; case HID_REQ_CONTROL_GET_IDLE: if (stage == CONTROL_STAGE_SETUP) { // TODO idle rate of report tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); } break; case HID_REQ_CONTROL_GET_PROTOCOL: if (stage == CONTROL_STAGE_SETUP) { tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); } break; case HID_REQ_CONTROL_SET_PROTOCOL: if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); } else if (stage == CONTROL_STAGE_ACK) { p_hid->protocol_mode = (uint8_t) request->wValue; tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } break; default: return false; // stall unsupported request } } else { return false; // stall unsupported request } return true; } bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t instance; hidd_interface_t *p_hid; // Identify which interface to use for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) { break; } } TU_ASSERT(instance < CFG_TUD_HID); hidd_epbuf_t *p_epbuf = &_hidd_epbuf[instance]; if (ep_addr == p_hid->ep_in) { // Input report if (XFER_RESULT_SUCCESS == result) { tud_hid_report_complete_cb(instance, p_epbuf->epin, (uint16_t) xferred_bytes); } else { tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_INPUT, p_epbuf->epin, (uint16_t) xferred_bytes); } } else { // Output report if (XFER_RESULT_SUCCESS == result) { tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_epbuf->epout, (uint16_t)xferred_bytes); } else { tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_OUTPUT, p_epbuf->epout, (uint16_t) xferred_bytes); } // prepare for new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE, false)); } return true; } #endif ================================================ FILE: src/class/hid/hid_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HID_DEVICE_H_ #define TUSB_HID_DEVICE_H_ #include "hid.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ #if !defined(CFG_TUD_HID_EP_BUFSIZE) & defined(CFG_TUD_HID_BUFSIZE) // TODO warn user to use new name later on // #warning CFG_TUD_HID_BUFSIZE is renamed to CFG_TUD_HID_EP_BUFSIZE, please update to use the new name #define CFG_TUD_HID_EP_BUFSIZE CFG_TUD_HID_BUFSIZE #endif #ifndef CFG_TUD_HID_EP_BUFSIZE #define CFG_TUD_HID_EP_BUFSIZE 64 #endif //--------------------------------------------------------------------+ // Application API (Multiple Instances) i.e. CFG_TUD_HID > 1 //--------------------------------------------------------------------+ // Check if the interface is ready to use bool tud_hid_n_ready(uint8_t instance); // Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values uint8_t tud_hid_n_interface_protocol(uint8_t instance); // Get current active protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) uint8_t tud_hid_n_get_protocol(uint8_t instance); // Send report to host bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len); // KEYBOARD: convenient helper to send keyboard report if application // use template layout report as defined by hid_keyboard_report_t bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]); // MOUSE: convenient helper to send mouse report if application // use template layout report as defined by hid_mouse_report_t bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); // ABSOLUTE MOUSE: convenient helper to send absolute mouse report if application // use template layout report as defined by hid_abs_mouse_report_t bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal); // Gamepad: convenient helper to send gamepad report if application // use template layout report TUD_HID_REPORT_DESC_GAMEPAD bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); // STYLUS PEN: convenient helper to send absolute stylus pen report if application bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_ready(void) { return tud_hid_n_ready(0); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_interface_protocol(void) { return tud_hid_n_interface_protocol(0); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_get_protocol(void) { return tud_hid_n_get_protocol(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { return tud_hid_n_report(0, report_id, report, len); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, const uint8_t keycode[6]) { return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); } TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_stylus_report(uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) { return tud_hid_n_stylus_report(0, report_id, attrs, x, y); } //--------------------------------------------------------------------+ // Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET HID REPORT DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance); // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); // Invoked when received SET_REPORT control request or // received data on OUT endpoint (Report ID = 0, Type = OUTPUT) void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); // Invoked when received SET_IDLE request. return false will stall the request // - Idle Rate = 0 : only send report if there is changes, i.e. skip duplication // - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes); /* --------------------------------------------------------------------+ * HID Report Descriptor Template * * Convenient for declaring popular HID device (keyboard, mouse, consumer, * gamepad etc...). Templates take "HID_REPORT_ID(n)" as input, leave * empty if multiple reports is not used * * - Only 1 report: no parameter * uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; * * - Multiple Reports: "HID_REPORT_ID(ID)" must be passed to template * uint8_t const report_desc[] = * { * TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ) , * TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) ) * }; *--------------------------------------------------------------------*/ // Keyboard Report Descriptor Template #define TUD_HID_REPORT_DESC_KEYBOARD(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ /* 8 bits Modifier Keys (Shift, Control, Alt) */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ HID_USAGE_MIN ( 224 ) ,\ HID_USAGE_MAX ( 231 ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX ( 1 ) ,\ HID_REPORT_COUNT ( 8 ) ,\ HID_REPORT_SIZE ( 1 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 8 bit reserved */ \ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ /* Output 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\ HID_USAGE_MIN ( 1 ) ,\ HID_USAGE_MAX ( 5 ) ,\ HID_REPORT_COUNT ( 5 ) ,\ HID_REPORT_SIZE ( 1 ) ,\ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* led padding */ \ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 3 ) ,\ HID_OUTPUT ( HID_CONSTANT ) ,\ /* 6-byte Keycodes */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ HID_USAGE_MIN ( 0 ) ,\ HID_USAGE_MAX_N ( 255, 2 ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX_N( 255, 2 ) ,\ HID_REPORT_COUNT ( 6 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ // Mouse Report Descriptor Template #define TUD_HID_REPORT_DESC_MOUSE(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ HID_USAGE_MIN ( 1 ) ,\ HID_USAGE_MAX ( 5 ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX ( 1 ) ,\ /* Left, Right, Middle, Backward, Forward buttons */ \ HID_REPORT_COUNT( 5 ) ,\ HID_REPORT_SIZE ( 1 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 3 bit padding */ \ HID_REPORT_COUNT( 1 ) ,\ HID_REPORT_SIZE ( 3 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ /* X, Y position [-127, 127] */ \ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ HID_LOGICAL_MIN ( 0x81 ) ,\ HID_LOGICAL_MAX ( 0x7f ) ,\ HID_REPORT_COUNT( 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ /* Verital wheel scroll [-127, 127] */ \ HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ HID_LOGICAL_MIN ( 0x81 ) ,\ HID_LOGICAL_MAX ( 0x7f ) ,\ HID_REPORT_COUNT( 1 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ /* Horizontal wheel scroll [-127, 127] */ \ HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ HID_LOGICAL_MIN ( 0x81 ), \ HID_LOGICAL_MAX ( 0x7f ), \ HID_REPORT_COUNT( 1 ), \ HID_REPORT_SIZE ( 8 ), \ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ HID_COLLECTION_END , \ HID_COLLECTION_END \ // Stylus Pen Report Descriptor Template #define TUD_HID_REPORT_DESC_STYLUS_PEN(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) , \ HID_USAGE ( HID_USAGE_DIGITIZER_PEN ) , \ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) , \ /* Report ID if any */\ __VA_ARGS__ \ HID_USAGE ( HID_USAGE_DIGITIZER_STYLUS ), \ HID_COLLECTION ( HID_COLLECTION_PHYSICAL ), \ HID_USAGE ( HID_USAGE_DIGITIZER_TIP_SWITCH ), \ HID_USAGE ( HID_USAGE_DIGITIZER_IN_RANGE ), \ HID_LOGICAL_MIN ( 0 ), \ HID_LOGICAL_MAX ( 1 ), \ HID_REPORT_SIZE ( 1 ), \ HID_REPORT_COUNT( 2 ), \ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \ HID_REPORT_SIZE ( 1 ), \ HID_REPORT_COUNT( 6 ), \ HID_INPUT ( HID_CONSTANT | HID_ARRAY | HID_ABSOLUTE), \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), \ HID_PHYSICAL_MAX_N( 0x7fff, 2 ), \ HID_LOGICAL_MAX_N ( 0x7fff, 2 ), \ HID_REPORT_SIZE ( 16 ), \ HID_REPORT_COUNT( 1 ), \ HID_UNIT_EXPONENT( 0x0f ), \ HID_UNIT ( HID_VARIABLE | HID_NONLINEAR ), \ HID_PHYSICAL_MIN( 0 ), \ HID_PHYSICAL_MAX( 0 ), \ HID_USAGE ( HID_USAGE_DESKTOP_X ), \ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \ HID_USAGE ( HID_USAGE_DESKTOP_Y ), \ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \ HID_COLLECTION_END , \ HID_COLLECTION_END \ // Absolute Mouse Report Descriptor Template #define TUD_HID_REPORT_DESC_ABSMOUSE(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ HID_USAGE_MIN ( 1 ) ,\ HID_USAGE_MAX ( 5 ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX ( 1 ) ,\ /* Left, Right, Middle, Backward, Forward buttons */ \ HID_REPORT_COUNT( 5 ) ,\ HID_REPORT_SIZE ( 1 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 3 bit padding */ \ HID_REPORT_COUNT( 1 ) ,\ HID_REPORT_SIZE ( 3 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ /* X, Y absolute position [0, 32767] */ \ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ HID_LOGICAL_MIN ( 0x00 ) ,\ HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\ HID_REPORT_SIZE ( 16 ) ,\ HID_REPORT_COUNT ( 2 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* Vertical wheel scroll [-127, 127] */ \ HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ HID_LOGICAL_MIN ( 0x81 ) ,\ HID_LOGICAL_MAX ( 0x7f ) ,\ HID_REPORT_COUNT( 1 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ /* Horizontal wheel scroll [-127, 127] */ \ HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ HID_LOGICAL_MIN ( 0x81 ), \ HID_LOGICAL_MAX ( 0x7f ), \ HID_REPORT_COUNT( 1 ), \ HID_REPORT_SIZE ( 8 ), \ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ HID_COLLECTION_END , \ HID_COLLECTION_END \ // Consumer Control Report Descriptor Template #define TUD_HID_REPORT_DESC_CONSUMER(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ HID_LOGICAL_MIN ( 0x00 ) ,\ HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\ HID_USAGE_MIN ( 0x00 ) ,\ HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 16 ) ,\ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ /* System Control Report Descriptor Template * 0x00 - do nothing * 0x01 - Power Off * 0x02 - Standby * 0x03 - Wake Host */ #define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ /* 2 bit system power control */ \ HID_LOGICAL_MIN ( 1 ) ,\ HID_LOGICAL_MAX ( 3 ) ,\ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 2 ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\ HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ /* 6 bit padding */ \ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 6 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ HID_COLLECTION_END \ // Gamepad Report Descriptor Template // with 32 buttons, 2 joysticks and 1 hat/dpad with following layout // | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (4 bytes) | #define TUD_HID_REPORT_DESC_GAMEPAD(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */\ __VA_ARGS__ \ /* 8 bit X, Y, Z, Rz, Rx, Ry (min -127, max 127 ) */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\ HID_LOGICAL_MIN ( 0x81 ) ,\ HID_LOGICAL_MAX ( 0x7f ) ,\ HID_REPORT_COUNT ( 6 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 8 bit DPad/Hat Button Map */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\ HID_LOGICAL_MIN ( 1 ) ,\ HID_LOGICAL_MAX ( 8 ) ,\ HID_PHYSICAL_MIN ( 0 ) ,\ HID_PHYSICAL_MAX_N ( 315, 2 ) ,\ HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* 32 bit Button Map */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ HID_USAGE_MIN ( 1 ) ,\ HID_USAGE_MAX ( 32 ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX ( 1 ) ,\ HID_REPORT_COUNT ( 32 ) ,\ HID_REPORT_SIZE ( 1 ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ // FIDO U2F Authenticator Descriptor Template // - 1st parameter is report size, which is 64 bytes maximum in U2F // - 2nd parameter is HID_REPORT_ID(n) (optional) #define TUD_HID_REPORT_DESC_FIDO_U2F(report_size, ...) \ HID_USAGE_PAGE_N ( HID_USAGE_PAGE_FIDO, 2 ) ,\ HID_USAGE ( HID_USAGE_FIDO_U2FHID ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ /* Report ID if any */ \ __VA_ARGS__ \ /* Usage Data In */ \ HID_USAGE ( HID_USAGE_FIDO_DATA_IN ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_REPORT_COUNT ( report_size ) ,\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ /* Usage Data Out */ \ HID_USAGE ( HID_USAGE_FIDO_DATA_OUT ) ,\ HID_LOGICAL_MIN ( 0 ) ,\ HID_LOGICAL_MAX_N ( 0xff, 2 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_REPORT_COUNT ( report_size ) ,\ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ // HID Generic Input & Output // - 1st parameter is report size (mandatory) // - 2nd parameter is report id HID_REPORT_ID(n) (optional) #define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \ HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ HID_USAGE ( 0x01 ),\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ /* Report ID if any */\ __VA_ARGS__ \ /* Input */ \ HID_USAGE ( 0x02 ),\ HID_LOGICAL_MIN ( 0x00 ),\ HID_LOGICAL_MAX_N ( 0xff, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT( report_size ),\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ /* Output */ \ HID_USAGE ( 0x03 ),\ HID_LOGICAL_MIN ( 0x00 ),\ HID_LOGICAL_MAX_N ( 0xff, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT( report_size ),\ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END \ // HID Lighting and Illumination Report Descriptor Template // - 1st parameter is report id (required) // Creates 6 report ids for lighting HID usages in the following order: // report_id+0: HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT // report_id+1: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT // report_id+2: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT // report_id+3: HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT // report_id+4: HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT // report_id+5: HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT #define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ /* Lamp Array Attributes Report */ \ HID_REPORT_ID (report_id ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 65535, 3 ),\ HID_REPORT_SIZE ( 16 ),\ HID_REPORT_COUNT ( 1 ),\ HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_KIND ),\ HID_USAGE ( HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ HID_REPORT_SIZE ( 32 ),\ HID_REPORT_COUNT ( 5 ),\ HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ /* Lamp Attributes Request Report */ \ HID_REPORT_ID ( report_id + 1 ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 65535, 3 ),\ HID_REPORT_SIZE ( 16 ),\ HID_REPORT_COUNT ( 1 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ /* Lamp Attributes Response Report */ \ HID_REPORT_ID ( report_id + 2 ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 65535, 3 ),\ HID_REPORT_SIZE ( 16 ),\ HID_REPORT_COUNT ( 1 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS ),\ HID_USAGE ( HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_PURPOSES ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ HID_REPORT_SIZE ( 32 ),\ HID_REPORT_COUNT ( 5 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_LEVEL_COUNT ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT ),\ HID_USAGE ( HID_USAGE_LIGHTING_IS_PROGRAMMABLE ),\ HID_USAGE ( HID_USAGE_LIGHTING_INPUT_BINDING ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 255, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 6 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ /* Lamp Multi-Update Report */ \ HID_REPORT_ID ( report_id + 3 ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX ( 8 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 2 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 65535, 3 ),\ HID_REPORT_SIZE ( 16 ),\ HID_REPORT_COUNT ( 8 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 255, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 32 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ /* Lamp Range Update Report */ \ HID_REPORT_ID ( report_id + 4 ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX ( 8 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 1 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_START ),\ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_END ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 65535, 3 ),\ HID_REPORT_SIZE ( 16 ),\ HID_REPORT_COUNT ( 2 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX_N ( 255, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 4 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ /* Lamp Array Control Report */ \ HID_REPORT_ID ( report_id + 5 ) \ HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT ),\ HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ HID_USAGE ( HID_USAGE_LIGHTING_AUTONOMOUS_MODE ),\ HID_LOGICAL_MIN ( 0 ),\ HID_LOGICAL_MAX ( 1 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT ( 1 ),\ HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END ,\ HID_COLLECTION_END \ //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void hidd_init (void); bool hidd_deinit (void); void hidd_reset (uint8_t rhport); uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/hid/hid_host.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUH_ENABLED && CFG_TUH_HID) #include "host/usbh.h" #include "host/usbh_pvt.h" #include "hid_host.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUH_HID_LOG_LEVEL #define CFG_TUH_HID_LOG_LEVEL CFG_TUH_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t daddr; uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; bool mounted; // Enumeration is complete uint8_t itf_protocol; // None, Keyboard, Mouse uint8_t protocol_mode; // Boot (0) or Report protocol (1) uint8_t report_desc_type; uint16_t report_desc_len; uint16_t epin_size; uint16_t epout_size; } hidh_interface_t; typedef struct { TUH_EPBUF_DEF(epin, CFG_TUH_HID_EPIN_BUFSIZE); TUH_EPBUF_DEF(epout, CFG_TUH_HID_EPOUT_BUFSIZE); } hidh_epbuf_t; static hidh_interface_t _hidh_itf[CFG_TUH_HID]; CFG_TUH_MEM_SECTION static hidh_epbuf_t _hidh_epbuf[CFG_TUH_HID]; static uint8_t _hidh_default_protocol = HID_PROTOCOL_BOOT; //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report_desc, uint16_t desc_len) { (void) dev_addr; (void) idx; (void) report_desc; (void) desc_len; } TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx) { (void) dev_addr; (void) idx; } TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len) { (void) dev_addr; (void) idx; (void) report; (void) len; } TU_ATTR_WEAK void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len) { (void) dev_addr; (void) idx; (void) report_id; (void) report_type; (void) len; } TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len) { (void) dev_addr; (void) idx; (void) report_id; (void) report_type; (void) len; } TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol) { (void) dev_addr; (void) idx; (void) protocol; } //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx) { TU_ASSERT(daddr > 0 && idx < CFG_TUH_HID, NULL); hidh_interface_t* p_hid = &_hidh_itf[idx]; return (p_hid->daddr == daddr) ? p_hid : NULL; } TU_ATTR_ALWAYS_INLINE static inline hidh_epbuf_t* get_hid_epbuf(uint8_t idx) { return &_hidh_epbuf[idx]; } // Get instance ID by endpoint address static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { hidh_interface_t const* p_hid = &_hidh_itf[idx]; if (p_hid->daddr == daddr && (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr)) { return idx; } } return TUSB_INDEX_INVALID_8; } static hidh_interface_t* find_new_itf(void) { for (uint8_t i = 0; i < CFG_TUH_HID; i++) { if (_hidh_itf[i].daddr == 0) { return &_hidh_itf[i]; } } return NULL; } //--------------------------------------------------------------------+ // Interface API //--------------------------------------------------------------------+ uint8_t tuh_hid_itf_get_count(uint8_t daddr) { uint8_t count = 0; for (uint8_t i = 0; i < CFG_TUH_HID; i++) { if (_hidh_itf[i].daddr == daddr) { count++; } } return count; } uint8_t tuh_hid_itf_get_total_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < CFG_TUH_HID; i++) { if (_hidh_itf[i].daddr != 0) { count++; } } return count; } bool tuh_hid_mounted(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); return p_hid->mounted; } bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && info); info->daddr = daddr; // re-construct descriptor tusb_desc_interface_t* desc = &info->desc; desc->bLength = sizeof(tusb_desc_interface_t); desc->bDescriptorType = TUSB_DESC_INTERFACE; desc->bInterfaceNumber = p_hid->itf_num; desc->bAlternateSetting = 0; desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u)); desc->bInterfaceClass = TUSB_CLASS_HID; desc->bInterfaceSubClass = (p_hid->itf_protocol ? HID_SUBCLASS_BOOT : HID_SUBCLASS_NONE); desc->bInterfaceProtocol = p_hid->itf_protocol; desc->iInterface = 0; // not used yet return true; } uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num) { for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { hidh_interface_t const* p_hid = &_hidh_itf[idx]; if (p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx; } return TUSB_INDEX_INVALID_8; } uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->itf_protocol : 0; } //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->protocol_mode : 0; } static void set_protocol_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const daddr = xfer->daddr; uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid,); if (XFER_RESULT_SUCCESS == xfer->result) { p_hid->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue); } tuh_hid_set_protocol_complete_cb(daddr, idx, p_hid->protocol_mode); } void tuh_hid_set_default_protocol(uint8_t protocol) { _hidh_default_protocol = protocol; } static bool hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("HID Set Protocol = %d\r\n", protocol); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, .wValue = protocol, .wIndex = itf_num, .wLength = 0 }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE); return hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0); } static void get_report_complete(tuh_xfer_t* xfer) { TU_LOG_DRV("HID Get Report complete\r\n"); uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); uint8_t const report_id = tu_u16_low(xfer->setup->wValue); tuh_hid_get_report_complete_cb(xfer->daddr, idx, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } bool tuh_hid_get_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); TU_LOG_DRV("HID Get Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = HID_REQ_CONTROL_GET_REPORT, .wValue = tu_htole16(tu_u16(report_type, report_id)), .wIndex = tu_htole16((uint16_t) p_hid->itf_num), .wLength = len }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = report, .complete_cb = get_report_complete, .user_data = 0 }; return tuh_control_xfer(&xfer); } static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG_DRV("HID Set Report complete\r\n"); uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); uint8_t const report_id = tu_u16_low(xfer->setup->wValue); tuh_hid_set_report_complete_cb(xfer->daddr, idx, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); TU_LOG_DRV("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = HID_REQ_CONTROL_SET_REPORT, .wValue = tu_htole16(tu_u16(report_type, report_id)), .wIndex = tu_htole16((uint16_t) p_hid->itf_num), .wLength = len }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = report, .complete_cb = set_report_complete, .user_data = 0 }; return tuh_control_xfer(&xfer); } static bool hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // SET IDLE request, device can stall if not support this request TU_LOG_DRV("HID Set Idle \r\n"); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = HID_REQ_CONTROL_SET_IDLE, .wValue = tu_htole16(idle_rate), .wIndex = tu_htole16((uint16_t) itf_num), .wLength = 0 }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ // Interrupt Endpoint API //--------------------------------------------------------------------+ // Check if HID interface is ready to receive report bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); return !usbh_edpt_busy(dev_addr, p_hid->ep_in); } bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); hidh_epbuf_t* epbuf = get_hid_epbuf(idx); // claim endpoint TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_in)); if (!usbh_edpt_xfer(daddr, p_hid->ep_in, epbuf->epin, p_hid->epin_size)) { usbh_edpt_release(daddr, p_hid->ep_in); return false; } return true; } bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); return tuh_edpt_abort_xfer(dev_addr, p_hid->ep_in); } bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); return !usbh_edpt_busy(dev_addr, p_hid->ep_out); } bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len) { TU_LOG_DRV("HID Send Report %d\r\n", report_id); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); hidh_epbuf_t* epbuf = get_hid_epbuf(idx); if (p_hid->ep_out == 0) { // This HID does not have an out endpoint (other than control) return false; } else if (len > CFG_TUH_HID_EPOUT_BUFSIZE || (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) { // ep_out buffer is not large enough to hold contents return false; } // claim endpoint TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_out)); if (report_id == 0) { // No report ID in transmission memcpy(&epbuf->epout[0], report, len); } else { epbuf->epout[0] = report_id; memcpy(&epbuf->epout[1], report, len); ++len; // 1 more byte for report_id } TU_LOG3_MEM(epbuf->epout, len, 2); if (!usbh_edpt_xfer(daddr, p_hid->ep_out, epbuf->epout, len)) { usbh_edpt_release(daddr, p_hid->ep_out); return false; } return true; } //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ bool hidh_init(void) { TU_LOG_DRV("sizeof(hidh_interface_t) = %u\r\n", sizeof(hidh_interface_t)); tu_memclr(_hidh_itf, sizeof(_hidh_itf)); return true; } bool hidh_deinit(void) { return true; } bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const idx = get_idx_by_epaddr(daddr, ep_addr); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); hidh_epbuf_t* epbuf = get_hid_epbuf(idx); if (dir == TUSB_DIR_IN) { TU_LOG_DRV(" [idx=%u] Get Report callback\r\n", idx); TU_LOG3_MEM(epbuf->epin, xferred_bytes, 2); tuh_hid_report_received_cb(daddr, idx, epbuf->epin, (uint16_t) xferred_bytes); } else { tuh_hid_report_sent_cb(daddr, idx, epbuf->epout, (uint16_t) xferred_bytes); } return true; } void hidh_close(uint8_t daddr) { for (uint8_t i = 0; i < CFG_TUH_HID; i++) { hidh_interface_t* p_hid = &_hidh_itf[i]; if (p_hid->daddr == daddr) { TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); tuh_hid_umount_cb(daddr, i); tu_memclr(p_hid, sizeof(hidh_interface_t)); } } } //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ uint16_t hidh_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; (void) max_len; TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); TU_LOG_DRV("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len, 0); const uint8_t *p_desc = (const uint8_t *)desc_itf; // HID descriptor: mostly right after interface descriptor, in some rare case it might be after endpoint descriptors p_desc = tu_desc_next(p_desc); const tusb_hid_descriptor_hid_t *desc_hid; if (tu_desc_type(p_desc) == HID_DESC_TYPE_HID) { // HID after interface desc_hid = (const tusb_hid_descriptor_hid_t *)p_desc; p_desc = tu_desc_next(p_desc); } else { // HID after endpoint desc_hid = (const tusb_hid_descriptor_hid_t *)(p_desc + sizeof(tusb_desc_endpoint_t) * desc_itf->bNumEndpoints); TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID, 0); } // Allocate new interface hidh_interface_t *p_hid = find_new_itf(); TU_ASSERT(p_hid, 0); // not enough interface, try to increase CFG_TUH_HID p_hid->daddr = daddr; p_hid->itf_num = desc_itf->bInterfaceNumber; // Endpoint Descriptors for (uint8_t i = 0; i < desc_itf->bNumEndpoints; i++) { const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0); TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_hid->ep_in = desc_ep->bEndpointAddress; p_hid->epin_size = tu_edpt_packet_size(desc_ep); } else { p_hid->ep_out = desc_ep->bEndpointAddress; p_hid->epout_size = tu_edpt_packet_size(desc_ep); } p_desc = tu_desc_next(p_desc); } // Assume bNumDescriptors = 1 p_hid->report_desc_type = desc_hid->bReportType; // Use offsetof to avoid pointer to the odd/misaligned address p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*)desc_hid + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Per HID Specs: default is Report protocol p_hid->protocol_mode = HID_PROTOCOL_REPORT; if (HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; } return drv_len; } //--------------------------------------------------------------------+ // Set Configure //--------------------------------------------------------------------+ enum { CONFG_SET_IDLE, CONFIG_SET_PROTOCOL, CONFIG_GET_REPORT_DESC, CONFIG_COMPLETE }; static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len); static void process_set_config(tuh_xfer_t* xfer); bool hidh_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; xfer.daddr = daddr; xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process process_set_config(&xfer); return true; } static void process_set_config(tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, sometime SET_PROTOCOL as well // therefore we could ignore its result if (!(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE || xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL)) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS,); } uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const daddr = xfer->daddr; uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid,); switch (state) { case CONFG_SET_IDLE: { // Idle rate = 0 mean only report when there are changes const uint16_t idle_rate = 0; const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state); break; } case CONFIG_SET_PROTOCOL: #if CFG_TUH_HID_SET_PROTOCOL_ON_ENUM hidh_set_protocol(daddr, p_hid->itf_num, _hidh_default_protocol, process_set_config, CONFIG_GET_REPORT_DESC); break; #else TU_ATTR_FALLTHROUGH; #endif case CONFIG_GET_REPORT_DESC: if (xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL && xfer->result == XFER_RESULT_SUCCESS) { p_hid->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue); } // Get Report Descriptor if possible // using usbh enumeration buffer since the report descriptor can be very long if (p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE) { TU_LOG_DRV("HID Skip Report Descriptor since it is too large %u bytes\r\n", p_hid->report_desc_len); config_driver_mount_complete(daddr, idx, NULL, 0); } else { tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, usbh_get_enum_buf(), p_hid->report_desc_len, process_set_config, CONFIG_COMPLETE); } break; case CONFIG_COMPLETE: { const uint8_t *desc_report = usbh_get_enum_buf(); const uint16_t desc_len = tu_le16toh(xfer->setup->wLength); config_driver_mount_complete(daddr, idx, desc_report, desc_len); break; } default: break; } } static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid,); p_hid->mounted = true; // enumeration is complete tuh_hid_mount_cb(daddr, idx, desc_report, desc_len); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(daddr, p_hid->itf_num); } //--------------------------------------------------------------------+ // Report Descriptor Parser //--------------------------------------------------------------------+ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) { // Report Item 6.2.2.2 USB HID 1.11 union TU_ATTR_PACKED { uint8_t byte; struct TU_ATTR_PACKED { uint8_t size : 2; uint8_t type : 2; uint8_t tag : 4; }; } header; tu_memclr(report_info_arr, arr_count * sizeof(tuh_hid_report_info_t)); uint8_t report_num = 0; tuh_hid_report_info_t* info = report_info_arr; // current parsed report count & size from descriptor // uint8_t ri_report_count = 0; // uint8_t ri_report_size = 0; uint8_t ri_collection_depth = 0; while (desc_len && report_num < arr_count) { header.byte = *desc_report++; desc_len--; uint8_t const tag = header.tag; uint8_t const type = header.type; uint8_t size = header.size; if (size == 3) { size = 4; // HID 1.11 6.2.2.2 3 is 4 bytes } uint8_t const data8 = (size > 0) ? desc_report[0] : 0; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); for (uint32_t i = 0; i < size; i++) { TU_LOG(3, "%02X ", desc_report[i]); } TU_LOG(3, "\r\n"); switch (type) { case RI_TYPE_MAIN: switch (tag) { case RI_MAIN_INPUT: break; case RI_MAIN_OUTPUT: break; case RI_MAIN_FEATURE: break; case RI_MAIN_COLLECTION: ri_collection_depth++; break; case RI_MAIN_COLLECTION_END: ri_collection_depth--; if (ri_collection_depth == 0) { info++; report_num++; } break; default:break; } break; case RI_TYPE_GLOBAL: switch (tag) { case RI_GLOBAL_USAGE_PAGE: // only take in account the "usage page" before REPORT ID if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, size); break; case RI_GLOBAL_LOGICAL_MIN: break; case RI_GLOBAL_LOGICAL_MAX: break; case RI_GLOBAL_PHYSICAL_MIN: break; case RI_GLOBAL_PHYSICAL_MAX: break; case RI_GLOBAL_REPORT_ID: info->report_id = data8; break; case RI_GLOBAL_REPORT_SIZE: // ri_report_size = data8; break; case RI_GLOBAL_REPORT_COUNT: // ri_report_count = data8; break; case RI_GLOBAL_UNIT_EXPONENT: break; case RI_GLOBAL_UNIT: break; case RI_GLOBAL_PUSH: break; case RI_GLOBAL_POP: break; default: break; } break; case RI_TYPE_LOCAL: switch (tag) { case RI_LOCAL_USAGE: // only take in account the "usage" before starting REPORT ID if (ri_collection_depth == 0) info->usage = data8; break; case RI_LOCAL_USAGE_MIN: break; case RI_LOCAL_USAGE_MAX: break; case RI_LOCAL_DESIGNATOR_INDEX: break; case RI_LOCAL_DESIGNATOR_MIN: break; case RI_LOCAL_DESIGNATOR_MAX: break; case RI_LOCAL_STRING_INDEX: break; case RI_LOCAL_STRING_MIN: break; case RI_LOCAL_STRING_MAX: break; case RI_LOCAL_DELIMITER: break; default: break; } break; // error default: break; } desc_report += size; desc_len -= size; } for (uint8_t i = 0; i < report_num; i++) { info = report_info_arr + i; TU_LOG_DRV("%u: id = %u, usage_page = %u, usage = %u\r\n", i, info->report_id, info->usage_page, info->usage); } return report_num; } #endif ================================================ FILE: src/class/hid/hid_host.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HID_HOST_H_ #define TUSB_HID_HOST_H_ #include "hid.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ // TODO Highspeed interrupt can be up to 512 bytes #ifndef CFG_TUH_HID_EPIN_BUFSIZE #define CFG_TUH_HID_EPIN_BUFSIZE 64 #endif #ifndef CFG_TUH_HID_EPOUT_BUFSIZE #define CFG_TUH_HID_EPOUT_BUFSIZE 64 #endif #ifndef CFG_TUH_HID_SET_PROTOCOL_ON_ENUM #define CFG_TUH_HID_SET_PROTOCOL_ON_ENUM 1 #endif //--------------------------------------------------------------------+ // Interface API //--------------------------------------------------------------------+ typedef struct { uint8_t report_id; uint8_t usage; uint16_t usage_page; // TODO still use the endpoint size for now // uint8_t in_len; // length of IN report // uint8_t out_len; // length of OUT report } tuh_hid_report_info_t; // Get the total number of mounted HID interfaces of a device uint8_t tuh_hid_itf_get_count(uint8_t dev_addr); // Get all mounted interfaces across devices uint8_t tuh_hid_itf_get_total_count(void); // backward compatible rename #define tuh_hid_instance_count tuh_hid_itf_get_count // Get Interface information bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t *itf_info); // Get Interface index from device address + interface number // return TUSB_INDEX_INVALID_8 (0xFF) if not found uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t idx); // Check if HID interface is mounted bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx); // Parse report descriptor into array of report_info struct and return number of reports. // For complicated report, application should write its own parser. TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t *reports_info_arr, uint8_t arr_count, const uint8_t *desc_report, uint16_t desc_len); //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ // Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // Note: Device will be initialized in Boot protocol for simplicity. // Application can use set_protocol() to switch back to Report protocol. uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t idx); // Device by default is enumerated in Boot protocol for simplicity. Application // can use this to modify the default protocol for next enumeration. void tuh_hid_set_default_protocol(uint8_t protocol); // Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); // Get Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, uint16_t len); // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, uint16_t len); //--------------------------------------------------------------------+ // Interrupt Endpoint API //--------------------------------------------------------------------+ // Check if HID interface is ready to receive report bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx); // Try to receive next report on Interrupt Endpoint. Immediately return // - true If succeeded, tuh_hid_report_received_cb() callback will be invoked when report is available // - false if failed to queue the transfer e.g endpoint is busy bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t idx); // Abort receiving report on Interrupt Endpoint bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx); // Check if HID interface is ready to send report bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx); // Send report using interrupt endpoint // If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is // sent. bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void *report, uint16_t len); //--------------------------------------------------------------------+ // Callbacks (Weak is optional) //--------------------------------------------------------------------+ // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. // Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report_desc, uint16_t desc_len); // Invoked when device with hid interface is un-mounted void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx); // Invoked when received report from device via interrupt endpoint // Note: if there is report ID (composite), it is 1st byte of report void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len); // Invoked when sent report to device successfully via interrupt endpoint void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len); // Invoked when Get Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); // Invoked when Sent Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); // Invoked when Set Protocol request is complete void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ bool hidh_init(void); bool hidh_deinit(void); uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void hidh_close(uint8_t dev_addr); #ifdef __cplusplus } #endif #endif /* TUSB_HID_HOST_H_ */ ================================================ FILE: src/class/midi/README_midi_host.md ================================================ # MIDI HOST DRIVER This README file contains the design notes and limitations of the MIDI host driver. # MAXIMUM NUMBER OF MIDI DEVICES ATTACHED TO HOST In this version of the driver, only one MIDI device is supported. This constraint may change in the future. # MAXIMUM NUMBER OF ENDPOINTS Although the USB MIDI 1.0 Class specification allows an arbitrary number of endpoints, this driver supports at most one USB BULK DATA IN endpoint and one USB BULK DATA OUT endpoint. Each endpoint can support up to 16 virtual cables. If a device has multiple IN endpoints or multiple OUT endpoints, it will fail to enumerate. Most USB MIDI devices contain both an IN endpoint and an OUT endpoint, but not all do. For example, some USB pedals only support an OUT endpoint. This driver allows that. # PUBLIC API Applications interact with this driver via 8-bit buffers of MIDI messages formed using the rules for sending bytes on a 5-pin DIN cable per the original MIDI 1.0 specification. To send a message to a device, the Host application composes a sequence of status and data bytes in a byte array and calls the API function. The arguments of the function are a pointer to the byte array, the number of bytes in the array, and the target virtual cable number 0-15. When the host driver receives a message from the device, the host driver will call a callback function that the host application registers. This callback function contains a pointer to a message buffer, a message length, and the virtual cable number of the message buffer. One complete bulk IN endpoint transfer might contain multiple messages targeted to different virtual cables. # SUBCLASS AUDIO CONTROL A MIDI device does not absolutely need to have an Audio Control Interface, unless it adheres to the USB Audio Class 2 spec, but many devices have them even if the devices do not have an audio streaming interface. Because this driver does not support audio streaming, the descriptor parser will skip past any audio control interface and audio streaming interface and open only the MIDI interface. An audio streaming host driver can use this driver by passing a pointer to the MIDI interface descriptor that is found after the audio streaming interface to the midih_open() function. That is, an audio streaming host driver would parse the audio control interface descriptor and then the audio streaming interface and endpoint descriptors. When the next descriptor pointer points to a MIDI interface descriptor, call midih_open() with that descriptor pointer. # CLASS SPECIFIC INTERFACE AND REQUESTS The host driver does not make use of the information in the class specific interface descriptors. In the future, a public API could be created to retrieve the string descriptors for the names of each ELEMENT, IN JACK and OUT JACK, and how the device describes the connections. This driver also does not support class specific requests to control ELEMENT items, nor does it support non-MIDI Streaming bulk endpoints. # MIDI CLASS SPECIFIC DESCRIPTOR TOTAL LENGTH FIELD IGNORED I have observed at least one keyboard by a leading manufacturer that sets the wTotalLength field of the Class-Specific MS Interface Header Descriptor to include the length of the MIDIStreaming Endpoint Descriptors. This is wrong per my reading of the specification. # MESSAGE BUFFER DETAILS Messages buffers composed from USB data received on the IN endpoint will never contain running status because USB MIDI 1.0 class does not support that. Messages buffers to be sent to the device on the OUT endpoint may contain running status (the message might come from a UART data stream from a 5-pin DIN MIDI IN cable on the host, for example). The driver may in the future correctly compose 4-byte USB MIDI Class packets using the running status if need be. However, it does not currently do that. Also, use of running status is not a good idea overall because a single byte error can really mess up the data stream with no way to recover until the next non-real time status byte is in the message buffer. Message buffers to be sent to the device may contain Real time messages such as MIDI clock. Real time messages may be inserted in the message byte stream between status and data bytes of another message without disrupting the running status. However, because MIDI 1.0 class messages are sent as four byte packets, a real-time message so inserted will be re-ordered to be sent to the device in a new 4-byte packet immediately before the interrupted data stream. Real time messages the device sends to the host can only appear between the status byte and data bytes of the message in System Exclusive messages that are longer than 3 bytes. # POORLY FORMED USB MIDI DATA PACKETS FROM THE DEVICE Some devices do not properly encode the code index number (CIN) for the MIDI message status byte even though the 3-byte data payload correctly encodes the MIDI message. This driver looks to the byte after the CIN byte to decide how many bytes to place in the message buffer. Some devices do not properly encode the virtual cable number. If the virtual cable number in the CIN data byte of the packet is not less than bNumEmbMIDIJack for that endpoint, then the host driver assumes virtual cable 0 and does not report an error. Some MIDI devices will always send back exactly wMaxPacketSize bytes on every endpoint even if only one 4-byte packet is required (e.g., NOTE ON). These devices send packets with 4 packet bytes 0. This driver ignores all zero packets without reporting an error. # ENUMERATION FAILURES The host may fail to enumerate a device if it has too many endpoints, if it has if it has a Standard MS Transfer Bulk Data Endpoint Descriptor (not supported), if it has a poorly formed descriptor, or if the descriptor is too long for the host to read the whole thing. ================================================ FILE: src/class/midi/midi.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MIDI_H_ #define TUSB_MIDI_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Constants //--------------------------------------------------------------------+ enum { MIDI_VERSION_1_0 = 0x0100, MIDI_VERSION_2_0 = 0x0200, }; typedef enum { MIDI_CS_INTERFACE_HEADER = 0x01, MIDI_CS_INTERFACE_IN_JACK = 0x02, MIDI_CS_INTERFACE_OUT_JACK = 0x03, MIDI_CS_INTERFACE_ELEMENT = 0x04, } midi_cs_interface_subtype_t; typedef enum { MIDI_CS_ENDPOINT_GENERAL = 0x01, MIDI_CS_ENDPOINT_GENERAL_2_0 = 0x02, } midi_cs_endpoint_subtype_t; typedef enum { MIDI_JACK_EMBEDDED = 0x01, MIDI_JACK_EXTERNAL = 0x02 } midi_jack_type_t; typedef enum { MIDI_CIN_MISC = 0, MIDI_CIN_CABLE_EVENT = 1, MIDI_CIN_SYSCOM_2BYTE = 2, // 2 byte system common message e.g MTC, SongSelect MIDI_CIN_SYSCOM_3BYTE = 3, // 3 byte system common message e.g SPP MIDI_CIN_SYSEX_START = 4, // SysEx starts or continue MIDI_CIN_SYSEX_END_1BYTE = 5, // SysEx ends with 1 data, or 1 byte system common message MIDI_CIN_SYSEX_END_2BYTE = 6, // SysEx ends with 2 data MIDI_CIN_SYSEX_END_3BYTE = 7, // SysEx ends with 3 data MIDI_CIN_NOTE_OFF = 8, MIDI_CIN_NOTE_ON = 9, MIDI_CIN_POLY_KEYPRESS = 10, MIDI_CIN_CONTROL_CHANGE = 11, MIDI_CIN_PROGRAM_CHANGE = 12, MIDI_CIN_CHANNEL_PRESSURE = 13, MIDI_CIN_PITCH_BEND_CHANGE = 14, MIDI_CIN_1BYTE_DATA = 15 } midi_code_index_number_t; // MIDI 1.0 status byte enum { //------------- System Exclusive -------------// MIDI_STATUS_SYSEX_START = 0xF0, MIDI_STATUS_SYSEX_END = 0xF7, //------------- System Common -------------// MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME = 0xF1, MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER = 0xF2, MIDI_STATUS_SYSCOM_SONG_SELECT = 0xF3, // F4, F5 is undefined MIDI_STATUS_SYSCOM_TUNE_REQUEST = 0xF6, //------------- System RealTime -------------// MIDI_STATUS_SYSREAL_TIMING_CLOCK = 0xF8, // 0xF9 is undefined MIDI_STATUS_SYSREAL_START = 0xFA, MIDI_STATUS_SYSREAL_CONTINUE = 0xFB, MIDI_STATUS_SYSREAL_STOP = 0xFC, // 0xFD is undefined MIDI_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE, MIDI_STATUS_SYSREAL_SYSTEM_RESET = 0xFF, }; enum { MIDI_MAX_DATA_VAL = 0x7F, }; //--------------------------------------------------------------------+ // Class Specific Descriptor //--------------------------------------------------------------------+ /// MIDI Interface Header Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes. uint8_t bDescriptorType; ///< must be TUSB_DESC_CS_INTERFACE uint8_t bDescriptorSubType;///< Descriptor SubType uint16_t bcdMSC; ///< MidiStreaming SubClass release number in Binary-Coded Decimal uint16_t wTotalLength; } midi_desc_header_t; TU_VERIFY_STATIC(sizeof(midi_desc_header_t) == 7, "size is not correct"); /// MIDI In Jack Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; ///< Size of this descriptor in bytes. uint8_t bDescriptorType; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType;///< Descriptor SubType uint8_t bJackType; ///< Embedded or External uint8_t bJackID; ///< Unique ID for MIDI IN Jack uint8_t iJack; ///< string descriptor } midi_desc_in_jack_t; TU_VERIFY_STATIC(sizeof(midi_desc_in_jack_t) == 6, "size is not correct"); /// MIDI Out Jack Descriptor with multiple input pins #define midi_desc_out_jack_n_t(input_num) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bJackType; \ uint8_t bJackID; \ uint8_t bNrInputPins; \ struct TU_ATTR_PACKED { \ uint8_t baSourceID; \ uint8_t baSourcePin; \ } input[input_num]; \ uint8_t iJack; \ } typedef midi_desc_out_jack_n_t(1) midi_desc_out_jack_1in_t; // 1 input typedef midi_desc_out_jack_1in_t midi_desc_out_jack_t; // backward compatible TU_VERIFY_STATIC(sizeof(midi_desc_out_jack_1in_t) == 7 + 2 * 1, "size is not correct"); /// MIDI Element Descriptor with multiple pins #define midi_desc_element_n_t(input_num) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bElementID; \ uint8_t bNrInputPins; \ struct TU_ATTR_PACKED { \ uint8_t baSourceID; \ uint8_t baSourcePin; \ } pins[input_num]; \ uint8_t bNrOutputPins; \ uint8_t bInTerminalLink; \ uint8_t bOutTerminalLink; \ uint8_t bElCapsSize; \ uint16_t bmElementCaps; \ uint8_t iElement; \ } // This descriptor follows the standard bulk data endpoint descriptor #define midi_desc_cs_endpoint_n_t(jack_num) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bNumEmbMIDIJack; \ uint8_t baAssocJackID[jack_num]; \ } typedef midi_desc_cs_endpoint_n_t() midi_desc_cs_endpoint_t; // empty/flexible jack list typedef midi_desc_cs_endpoint_n_t(1) midi_desc_cs_endpoint_1jack_t; TU_VERIFY_STATIC(sizeof(midi_desc_cs_endpoint_1jack_t) == 4+1, "size is not correct"); //--------------------------------------------------------------------+ // For Internal Driver Use //--------------------------------------------------------------------+ typedef struct { uint8_t buffer[4]; uint8_t index; uint8_t total; } midi_driver_stream_t; #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/midi/midi_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUD_MIDI //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "device/usbd.h" #include "device/usbd_pvt.h" #include "midi_device.h" //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf) { (void)itf; } //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t rhport; uint8_t itf_num; // For Stream read()/write() API // Messages are always 4 bytes long, queue them for reading and writing so the // callers can use the Stream interface with single-byte read/write calls. midi_driver_stream_t stream_write; midi_driver_stream_t stream_read; /*------------- From this point, data is not cleared by bus reset -------------*/ // Endpoint stream struct { tu_edpt_stream_t tx; tu_edpt_stream_t rx; uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE]; } ep_stream; } midid_interface_t; #define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, ep_stream) static midid_interface_t _midid_itf[CFG_TUD_MIDI]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 // Endpoint Transfer buffer: not used if dedicated hw FIFO is available typedef struct { TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_TX_EPSIZE); TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_RX_EPSIZE); } midid_epbuf_t; CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI]; #endif //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ bool tud_midi_n_mounted (uint8_t itf) { midid_interface_t *p_midi = &_midid_itf[itf]; const bool tx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.tx); const bool rx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); return tx_opened && rx_opened; } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) { (void) cable_num; const midid_interface_t *p_midi = &_midid_itf[itf]; const midi_driver_stream_t *stream = &p_midi->stream_read; const tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; // when using with packet API stream total & index are both zero return tu_edpt_stream_read_available(ep_str) + (uint8_t)(stream->total - stream->index); } uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize) { (void) cable_num; TU_VERIFY(buffer != NULL && bufsize > 0, 0); uint8_t *buf8 = (uint8_t *)buffer; midid_interface_t *p_midi = &_midid_itf[itf]; midi_driver_stream_t *stream = &p_midi->stream_read; uint32_t total_read = 0; while (bufsize > 0) { // Get new packet from fifo, then set packet expected bytes if (stream->total == 0) { if (!tud_midi_n_packet_read(itf, stream->buffer)) { return total_read; // return if there is no more data from fifo } const uint8_t code_index = stream->buffer[0] & 0x0f; // MIDI 1.0 Table 4-1: Code Index Number Classifications switch (code_index) { case MIDI_CIN_MISC: case MIDI_CIN_CABLE_EVENT: // These are reserved and unused, possibly issue somewhere, skip this packet return 0; case MIDI_CIN_SYSEX_END_1BYTE: case MIDI_CIN_1BYTE_DATA: stream->total = 1; break; case MIDI_CIN_SYSCOM_2BYTE : case MIDI_CIN_SYSEX_END_2BYTE : case MIDI_CIN_PROGRAM_CHANGE : case MIDI_CIN_CHANNEL_PRESSURE : stream->total = 2; break; default: stream->total = 3; break; } } // Copy data up to bufsize const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize); // Skip the header (1st byte) in the buffer TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); total_read += count; stream->index += count; buf8 += count; bufsize -= count; // complete current event packet, reset stream if (stream->total == stream->index) { stream->index = 0; stream->total = 0; } } return total_read; } // Note: this function shares stream->buffer with tud_midi_n_stream_read(). // Do not mix calls to both functions on the same interface. uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { TU_VERIFY(p_cable_num != NULL && buffer != NULL && bufsize > 0, 0); midid_interface_t *p_midi = &_midid_itf[itf]; midi_driver_stream_t *stream = &p_midi->stream_read; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; uint8_t *buf8 = (uint8_t *)buffer; uint32_t total_read = 0; // Initialize to invalid cable so callers can detect "no data" even when // the return value is 0. *p_cable_num = 0xff; // If there are leftover bytes from a previous partial read, return them first if (stream->total > 0) { *p_cable_num = (stream->buffer[0] >> 4) & 0x0f; const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize); TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); total_read += count; stream->index += count; buf8 += count; bufsize -= count; if (stream->total == stream->index) { stream->index = 0; stream->total = 0; } if (bufsize == 0) { return total_read; } } while (bufsize > 0) { // Peek at next packet header to get cable number without consuming uint8_t one_byte; if (!tu_edpt_stream_peek(ep_str, &one_byte)) { break; } const uint8_t next_cable = (one_byte >> 4) & 0x0f; // Stop if cable changed (covers both leftover-originated reads and // freshly consumed packets — total_read > 0 in either case) if (total_read > 0 && next_cable != *p_cable_num) { break; } *p_cable_num = next_cable; // Consume the packet if (!tud_midi_n_packet_read(itf, stream->buffer)) { break; } const uint8_t code_index = stream->buffer[0] & 0x0f; uint8_t msg_bytes; // MIDI 1.0 Table 4-1: Code Index Number Classifications switch (code_index) { case MIDI_CIN_MISC: case MIDI_CIN_CABLE_EVENT: // Reserved and unused, skip this packet continue; case MIDI_CIN_SYSEX_END_1BYTE: case MIDI_CIN_1BYTE_DATA: msg_bytes = 1; break; case MIDI_CIN_SYSCOM_2BYTE: case MIDI_CIN_SYSEX_END_2BYTE: case MIDI_CIN_PROGRAM_CHANGE: case MIDI_CIN_CHANNEL_PRESSURE: msg_bytes = 2; break; default: msg_bytes = 3; break; } const uint8_t count = (uint8_t)tu_min32((uint32_t)msg_bytes, bufsize); TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1, count)); total_read += count; buf8 += count; bufsize -= count; if (count < msg_bytes) { // Output buffer full, save remaining for next call stream->total = msg_bytes; stream->index = count; } } return total_read; } bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; return 4 == tu_edpt_stream_read(ep_str, packet, 4); } uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets); return num_read >> 2u; } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { midid_interface_t *p_midi = &_midid_itf[itf]; midi_driver_stream_t *stream = &p_midi->stream_write; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); uint32_t i = 0; while (i < bufsize) { if (tu_edpt_stream_write_available(ep_str) < 4) { break; } const uint8_t data = buffer[i]; i++; if (stream->index == 0) { //------------- New event packet -------------// const uint8_t msg = data >> 4; stream->index = 2; stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. if (((stream->buffer[0]) & 0xF) == MIDI_CIN_SYSEX_START) { if (data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); stream->total = 2; } else { stream->total = 4; } } else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) { // Channel Voice Messages stream->buffer[0] = (uint8_t)((cable_num << 4) | msg); stream->total = 4; } else if (msg == 0xC || msg == 0xD) { // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) stream->buffer[0] = (uint8_t)((cable_num << 4) | msg); stream->total = 3; } else if (msg == 0xf) { // System message if (data == MIDI_STATUS_SYSEX_START) { stream->buffer[0] = MIDI_CIN_SYSEX_START; stream->total = 4; } else if (data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT) { stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE; stream->total = 3; } else if (data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER) { stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE; stream->total = 4; } else { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; } stream->buffer[0] |= (uint8_t)(cable_num << 4); } else { // Pack individual bytes if we don't support packing them into words. stream->buffer[0] = (uint8_t)(cable_num << 4 | 0xf); stream->buffer[2] = 0; stream->buffer[3] = 0; stream->total = 2; // index already set to 2 } } else { //------------- On-going (buffering) packet -------------// TU_ASSERT(stream->index < 4, i); stream->buffer[stream->index] = data; stream->index++; // See if this byte ends a SysEx. if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); stream->total = stream->index; } } // Send out packet if (stream->index == stream->total) { // zeroes unused bytes for (uint8_t idx = stream->total; idx < 4; idx++) { stream->buffer[idx] = 0; } const uint32_t count = tu_edpt_stream_write(ep_str, stream->buffer, 4); // complete current event packet, reset stream stream->index = stream->total = 0; // FIFO overflown, since we already check fifo remaining. It is probably race condition TU_ASSERT(count == 4, i); } } (void)tu_edpt_stream_write_xfer(ep_str); return i; } bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); TU_VERIFY(tu_edpt_stream_write_available(ep_str) >= 4); TU_VERIFY(tu_edpt_stream_write(ep_str, packet, 4) > 0); (void)tu_edpt_stream_write_xfer(ep_str); return true; } uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); uint32_t n_bytes = tu_edpt_stream_write_available(ep_str); n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u); const uint32_t n_write = tu_edpt_stream_write(ep_str, packets, n_bytes); (void)tu_edpt_stream_write_xfer(ep_str); return n_write >> 2u; } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { midid_interface_t *p_midi = &_midid_itf[i]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *epout_buf = NULL; uint8_t *epin_buf = NULL; #else midid_epbuf_t *p_epbuf = &_midid_epbuf[i]; uint8_t *epout_buf = p_epbuf->epout; uint8_t *epin_buf = p_epbuf->epin; #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, epin_buf); } } bool midid_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { midid_interface_t *p_midi = &_midid_itf[i]; tu_edpt_stream_deinit(&p_midi->ep_stream.rx); tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } return true; } void midid_reset(uint8_t rhport) { (void)rhport; for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) { midid_interface_t *p_midi = &_midid_itf[i]; tu_memclr(p_midi, ITF_MEM_RESET_SIZE); tu_edpt_stream_clear(&p_midi->ep_stream.rx); tu_edpt_stream_close(&p_midi->ep_stream.rx); tu_edpt_stream_clear(&p_midi->ep_stream.tx); tu_edpt_stream_close(&p_midi->ep_stream.tx); } } TU_ATTR_ALWAYS_INLINE static inline uint8_t find_midi_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_MIDI; idx++) { const midid_interface_t *p_midi = &_midid_itf[idx]; if (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr) { return idx; } } return TUSB_INDEX_INVALID_8; } uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { const uint8_t *p_desc = (const uint8_t *)desc_itf; const uint8_t *desc_end = p_desc + max_len; // 1st Interface is Audio Control v1 (optional) if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { p_desc = tu_desc_next(desc_itf); // Skip Class Specific descriptors while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); } } // 2nd Interface is MIDI Streaming TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc; TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, 0); uint8_t idx = find_midi_itf(0); // find unused interface TU_ASSERT(idx < CFG_TUD_MIDI, 0); midid_interface_t *p_midi = &_midid_itf[idx]; p_midi->rhport = rhport; p_midi->itf_num = desc_midi->bInterfaceNumber; (void) p_midi->itf_num; p_desc = tu_desc_next(p_desc); // Find and open endpoint descriptors uint8_t found_ep = 0; while ((found_ep < desc_midi->bNumEndpoints) && tu_desc_in_bounds(p_desc, desc_end)) { if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_TX_EPSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream_rx); TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data } p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor found_ep++; } p_desc = tu_desc_next(p_desc); } return (uint16_t)(p_desc - (const uint8_t *)desc_itf); } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { (void) rhport; (void) stage; (void) request; return false; // driver doesn't support any request yet } bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; uint8_t idx = find_midi_itf(ep_addr); TU_ASSERT(idx < CFG_TUD_MIDI); midid_interface_t *p_midi = &_midid_itf[idx]; tu_edpt_stream_t *ep_st_rx = &p_midi->ep_stream.rx; tu_edpt_stream_t *ep_st_tx = &p_midi->ep_stream.tx; if (ep_addr == ep_st_rx->ep_addr) { // Received new data: put into stream's fifo if (result == XFER_RESULT_SUCCESS) { tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes); tud_midi_rx_cb(idx); // invoke callback } tu_edpt_stream_read_xfer(ep_st_rx); // prepare for next data } else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) { // sent complete: try to send more if possible if (0 == tu_edpt_stream_write_xfer(ep_st_tx)) { // If there is no data left, a ZLP should be sent if needed (void)tu_edpt_stream_write_zlp_if_needed(ep_st_tx, xferred_bytes); } } else { return false; } return true; } #endif ================================================ FILE: src/class/midi/midi_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MIDI_DEVICE_H_ #define TUSB_MIDI_DEVICE_H_ #include "class/audio/audio.h" #include "midi.h" //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_MIDI_RX_EPSIZE #ifdef CFG_TUD_MIDI_EP_BUFSIZE #define CFG_TUD_MIDI_RX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE #else #define CFG_TUD_MIDI_RX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif #ifndef CFG_TUD_MIDI_TX_EPSIZE #ifdef CFG_TUD_MIDI_EP_BUFSIZE #define CFG_TUD_MIDI_TX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE #else #define CFG_TUD_MIDI_TX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Application Callback API (optional) //--------------------------------------------------------------------+ void tud_midi_rx_cb(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) // CFG_TUD_MIDI > 1 //--------------------------------------------------------------------+ // Check if midi interface is mounted bool tud_midi_n_mounted(uint8_t itf); // Get the number of bytes available for reading uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num); // Read byte stream (legacy) uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize); // Read byte stream with cable demultiplexing: returns the cable number of the // data that was read. Reads from a single cable per call; stops when the next // packet belongs to a different cable so the caller can dispatch per-cable. // Note: shares internal state with tud_midi_n_stream_read(); do not mix both // on the same interface. uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize); // Write byte Stream (legacy) uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize); // Read an event 4-byte packet bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]); // Read multiple event packets, return number of read packets uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets); // Write an event 4-byte packet bool tud_midi_n_packet_write(uint8_t itf, const uint8_t packet[4]); // Write multiple event packets, return number of written packets uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets); //--------------------------------------------------------------------+ // Application API (Single Interface) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_mounted(void) { return tud_midi_n_mounted(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_available(void) { return tud_midi_n_available(0, 0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer, uint32_t bufsize) { return tud_midi_n_stream_read(0, 0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_demux_stream_read(uint8_t *p_cable_num, void *buffer, uint32_t bufsize) { return tud_midi_n_demux_stream_read(0, p_cable_num, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) { return tud_midi_n_stream_write(0, cable_num, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_read(uint8_t packet[4]) { return tud_midi_n_packet_read(0, packet); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_read_n(uint8_t packets[], uint32_t max_packets) { return tud_midi_n_packet_read_n(0, packets, max_packets); } TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_write(const uint8_t packet[4]) { return tud_midi_n_packet_write(0, packet); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_write_n(const uint8_t packets[], uint32_t n_packets) { return tud_midi_n_packet_write_n(0, packets, n_packets); } //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void midid_init(void); bool midid_deinit(void); void midid_reset(uint8_t rhport); uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request); bool midid_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/midi/midi_host.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUH_ENABLED && CFG_TUH_MIDI) #include "host/usbh.h" #include "host/usbh_pvt.h" #include "midi_host.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUH_MIDI_LOG_LEVEL #define CFG_TUH_MIDI_LOG_LEVEL CFG_TUH_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MIDI_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb_data) { (void) idx; (void) desc_cb_data; } TU_ATTR_WEAK void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data) { (void) idx; (void) mount_cb_data; } TU_ATTR_WEAK void tuh_midi_umount_cb(uint8_t idx) { (void) idx; } TU_ATTR_WEAK void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) idx; (void) xferred_bytes; } TU_ATTR_WEAK void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) idx; (void) xferred_bytes; } //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; // interface number of MIDI streaming uint8_t iInterface; uint8_t itf_count; // number of interfaces including Audio Control + MIDI streaming uint8_t rx_cable_count; // IN endpoint CS descriptor bNumEmbMIDIJack value uint8_t tx_cable_count; // OUT endpoint CS descriptor bNumEmbMIDIJack value #if CFG_TUH_MIDI_STREAM_API // For Stream read()/write() API // Messages are always 4 bytes long, queue them for reading and writing so the // callers can use the Stream interface with single-byte read/write calls. midi_driver_stream_t stream_write; midi_driver_stream_t stream_read; #endif // Endpoint stream struct { tu_edpt_stream_t tx; tu_edpt_stream_t rx; uint8_t rx_ff_buf[CFG_TUH_MIDI_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUH_MIDI_TX_BUFSIZE]; } ep_stream; bool mounted; }midih_interface_t; typedef struct { TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MAX); TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MAX); } midih_epbuf_t; static midih_interface_t _midi_host[CFG_TUH_MIDI]; CFG_TUH_MEM_SECTION static midih_epbuf_t _midi_epbuf[CFG_TUH_MIDI]; //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint8_t find_new_midi_index(void) { for (uint8_t idx = 0; idx < CFG_TUH_MIDI; idx++) { if (_midi_host[idx].daddr == 0) { return idx; } } return TUSB_INDEX_INVALID_8; } static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUH_MIDI; idx++) { const midih_interface_t *p_midi = &_midi_host[idx]; if ((p_midi->daddr == daddr) && (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr)) { return idx; } } return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ bool midih_init(void) { tu_memclr(&_midi_host, sizeof(_midi_host)); for (int inst = 0; inst < CFG_TUH_MIDI; inst++) { midih_interface_t *p_midi_host = &_midi_host[inst]; tu_edpt_stream_init(&p_midi_host->ep_stream.rx, true, false, false, p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf[inst].rx); tu_edpt_stream_init(&p_midi_host->ep_stream.tx, true, true, false, p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf[inst].tx); } return true; } bool midih_deinit(void) { for (size_t i = 0; i < CFG_TUH_MIDI; i++) { midih_interface_t* p_midi = &_midi_host[i]; tu_edpt_stream_deinit(&p_midi->ep_stream.rx); tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } return true; } void midih_close(uint8_t daddr) { for (uint8_t idx = 0; idx < CFG_TUH_MIDI; idx++) { midih_interface_t* p_midi = &_midi_host[idx]; if (p_midi->daddr == daddr) { TU_LOG_DRV(" MIDI close addr = %u index = %u\r\n", daddr, idx); tuh_midi_umount_cb(idx); p_midi->bInterfaceNumber = 0; p_midi->rx_cable_count = 0; p_midi->tx_cable_count = 0; p_midi->daddr = 0; p_midi->mounted = false; #if CFG_TUH_MIDI_STREAM_API tu_memclr(&p_midi->stream_read, sizeof(p_midi->stream_read)); tu_memclr(&p_midi->stream_write, sizeof(p_midi->stream_write)); #endif tu_edpt_stream_close(&p_midi->ep_stream.rx); tu_edpt_stream_close(&p_midi->ep_stream.tx); } } } bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; const uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; tu_edpt_stream_t *ep_str_rx = &p_midi->ep_stream.rx; tu_edpt_stream_t *ep_str_tx = &p_midi->ep_stream.tx; if (ep_addr == ep_str_rx->ep_addr) { // receive new data, put it into FIFO and invoke callback if available // Note: some devices send back all zero packets even if there is no data ready if (xferred_bytes && !tu_mem_is_zero(ep_str_rx->ep_buf, xferred_bytes)) { tu_edpt_stream_read_xfer_complete(ep_str_rx, xferred_bytes); tuh_midi_rx_cb(idx, xferred_bytes); } tu_edpt_stream_read_xfer(ep_str_rx); // prepare for next transfer } else if (ep_addr == ep_str_tx->ep_addr) { tuh_midi_tx_cb(idx, xferred_bytes); if (0 == tu_edpt_stream_write_xfer(ep_str_tx)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP size and not zero tu_edpt_stream_write_zlp_if_needed(ep_str_tx, xferred_bytes); } } return true; } //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); const uint8_t *desc_start = (const uint8_t *)desc_itf; const uint8_t *p_desc = desc_start; const uint8_t *desc_end = desc_start + max_len; const uint8_t idx = find_new_midi_index(); TU_VERIFY(idx < CFG_TUH_MIDI, 0); midih_interface_t *p_midi = &_midi_host[idx]; p_midi->itf_count = 0; tuh_midi_descriptor_cb_t desc_cb = { 0 }; desc_cb.jack_num = 0; // There can be just a MIDI or an Audio + MIDI interface // - If there is Audio Control Interface + Audio Header descriptor, then skip it. // - If there is an Audio Control Interface + Audio Streaming Interface, then ignore the Audio Streaming Interface. // Future: // Note that if this driver is used with an USB Audio Streaming host driver, // then call that driver first. If the MIDI interface comes before the // audio streaming interface, then the audio driver will have to call this // driver after parsing the audio control interface and then resume parsing // the streaming audio interface. if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) { TU_VERIFY(max_len > 2 * sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t), 0); p_desc = tu_desc_next(p_desc); TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER, 0); desc_cb.desc_audio_control = desc_itf; p_desc = tu_desc_next(p_desc); desc_itf = (const tusb_desc_interface_t *)p_desc; p_midi->itf_count = 1; // skip non-interface and non-midi streaming descriptors while (tu_desc_in_bounds(p_desc, desc_end) && (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE || (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO && desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) { if (desc_itf->bDescriptorType == TUSB_DESC_INTERFACE && desc_itf->bAlternateSetting == 0) { p_midi->itf_count++; } p_desc = tu_desc_next(p_desc); desc_itf = (const tusb_desc_interface_t *)p_desc; } TU_VERIFY(p_desc < desc_end, 0); TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0); } TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, 0); TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber; p_midi->iInterface = desc_itf->iInterface; p_midi->itf_count++; desc_cb.desc_midi = desc_itf; bool found_new_interface = false; do { p_desc = tu_desc_next(p_desc); if (!tu_desc_in_bounds(p_desc, desc_end)) { break; } switch (tu_desc_type(p_desc)) { case TUSB_DESC_INTERFACE: found_new_interface = true; break; case TUSB_DESC_CS_INTERFACE: switch (tu_desc_subtype(p_desc)) { case MIDI_CS_INTERFACE_HEADER: TU_LOG_DRV(" Interface Header descriptor\r\n"); desc_cb.desc_header = p_desc; break; case MIDI_CS_INTERFACE_IN_JACK: case MIDI_CS_INTERFACE_OUT_JACK: { TU_LOG_DRV(" Jack %s %s descriptor \r\n", tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_IN_JACK ? "IN" : "OUT", p_desc[3] == MIDI_JACK_EXTERNAL ? "External" : "Embedded"); if (desc_cb.jack_num < TU_ARRAY_SIZE(desc_cb.desc_jack)) { desc_cb.desc_jack[desc_cb.jack_num++] = p_desc; } break; } case MIDI_CS_INTERFACE_ELEMENT: TU_LOG_DRV(" Element descriptor\r\n"); desc_cb.desc_element = p_desc; break; default: TU_LOG_DRV(" Unknown CS Interface sub-type %u\r\n", tu_desc_subtype(p_desc)); break; } break; case TUSB_DESC_ENDPOINT: { const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; p_desc = tu_desc_next(p_desc); // next to CS endpoint TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress); tu_edpt_stream_t *ep_stream; if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { p_midi->tx_cable_count = p_csep->bNumEmbMIDIJack; desc_cb.desc_epout = p_ep; ep_stream = &p_midi->ep_stream.tx; } else { p_midi->rx_cable_count = p_csep->bNumEmbMIDIJack; desc_cb.desc_epin = p_ep; ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0); tu_edpt_stream_open(ep_stream, dev_addr, p_ep, tu_edpt_packet_size(p_ep)); tu_edpt_stream_clear(ep_stream); break; } default: break; // skip unknown descriptor } } while (!found_new_interface); desc_cb.desc_midi_total_len = (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_start); p_midi->daddr = dev_addr; tuh_midi_descriptor_cb(idx, &desc_cb); return desc_cb.desc_midi_total_len; } bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { uint8_t idx = tuh_midi_itf_get_index(dev_addr, itf_num); TU_ASSERT(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; p_midi->mounted = true; const tuh_midi_mount_cb_t mount_cb_data = { .daddr = dev_addr, .bInterfaceNumber = p_midi->bInterfaceNumber, .rx_cable_count = p_midi->rx_cable_count, .tx_cable_count = p_midi->tx_cable_count, }; tuh_midi_mount_cb(idx, &mount_cb_data); tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // prepare for incoming data // No special config things to do for MIDI usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber); return true; } //--------------------------------------------------------------------+ // API //--------------------------------------------------------------------+ bool tuh_midi_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; return p_midi->mounted; } uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num) { for (uint8_t idx = 0; idx < CFG_TUH_MIDI; idx++) { const midih_interface_t *p_midi = &_midi_host[idx]; if (p_midi->daddr == daddr && (p_midi->bInterfaceNumber == itf_num || p_midi->bInterfaceNumber == (uint8_t) (itf_num + p_midi->itf_count - 1))) { return idx; } } return TUSB_INDEX_INVALID_8; } bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { midih_interface_t* p_midi = &_midi_host[idx]; TU_VERIFY(p_midi && info); info->daddr = p_midi->daddr; // re-construct descriptor tusb_desc_interface_t* desc = &info->desc; desc->bLength = sizeof(tusb_desc_interface_t); desc->bDescriptorType = TUSB_DESC_INTERFACE; desc->bInterfaceNumber = p_midi->bInterfaceNumber; desc->bAlternateSetting = 0; desc->bNumEndpoints = 0; if (tu_edpt_stream_is_opened(&p_midi->ep_stream.tx)) { desc->bNumEndpoints++; } if (tu_edpt_stream_is_opened(&p_midi->ep_stream.rx)) { desc->bNumEndpoints++; } desc->bInterfaceClass = TUSB_CLASS_AUDIO; desc->bInterfaceSubClass = AUDIO_SUBCLASS_MIDI_STREAMING; desc->bInterfaceProtocol = 0; desc->iInterface = p_midi->iInterface; return true; } uint8_t tuh_midi_get_tx_cable_count (uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; TU_VERIFY(p_midi->ep_stream.tx.ep_addr != 0, 0); return p_midi->tx_cable_count; } uint8_t tuh_midi_get_rx_cable_count (uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; TU_VERIFY(p_midi->ep_stream.rx.ep_addr != 0, 0); return p_midi->rx_cable_count; } uint32_t tuh_midi_read_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; return tu_edpt_stream_read_available(&p_midi->ep_stream.rx); } uint32_t tuh_midi_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; return tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx); } //--------------------------------------------------------------------+ // Packet API //--------------------------------------------------------------------+ uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUH_MIDI && buffer && bufsize > 0, 0); midih_interface_t *p_midi = &_midi_host[idx]; uint32_t count4 = tu_min32(bufsize, tu_edpt_stream_read_available(&p_midi->ep_stream.rx)); count4 = tu_align4(count4); // round down to multiple of 4 TU_VERIFY(count4 > 0, 0); return tu_edpt_stream_read(&p_midi->ep_stream.rx, buffer, count4); } uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUH_MIDI && buffer && bufsize > 0, 0); midih_interface_t *p_midi = &_midi_host[idx]; const uint32_t bufsize4 = tu_align4(bufsize); TU_VERIFY(bufsize4 > 0, 0); return tu_edpt_stream_write(&p_midi->ep_stream.tx, buffer, bufsize4); } //--------------------------------------------------------------------+ // Stream API //--------------------------------------------------------------------+ #if CFG_TUH_MIDI_STREAM_API uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUH_MIDI && buffer && bufsize > 0); midih_interface_t *p_midi = &_midi_host[idx]; TU_VERIFY(cable_num < p_midi->tx_cable_count); midi_driver_stream_t *stream = &p_midi->stream_write; uint32_t byte_count = 0; while ((byte_count < bufsize) && (tu_edpt_stream_write_available(&p_midi->ep_stream.tx) >= 4)) { const uint8_t data = buffer[byte_count]; byte_count++; if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away midi_driver_stream_t streamrt; streamrt.buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, streamrt.buffer, 4); TU_ASSERT(count == 4, byte_count); // Check FIFO overflown, since we already check fifo remaining. It is probably race condition } else if (stream->index == 0) { //------------- New event packet -------------// uint8_t const msg = data >> 4; stream->index = 2; stream->buffer[1] = data; // Check to see if we're still in a SysEx transmit. if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START) { if (data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE); stream->total = 2; } else { stream->total = 4; } } else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) { // Channel Voice Messages stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 4; } else if (msg == 0xC || msg == 0xD) { // Channel Voice Messages, two-byte variants (Program Change and Channel Pressure) stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg); stream->total = 3; } else if (msg == 0xf) { // System message if (data == MIDI_STATUS_SYSEX_START) { stream->buffer[0] = MIDI_CIN_SYSEX_START; stream->total = 4; } else if (data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT) { stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE; stream->total = 3; } else if (data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER) { stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE; stream->total = 4; } else { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE; stream->total = 2; } stream->buffer[0] |= (uint8_t)(cable_num << 4); } else { // Pack individual bytes if we don't support packing them into words. stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf); stream->buffer[2] = 0; stream->buffer[3] = 0; stream->index = 2; stream->total = 2; } } else { //------------- On-going (buffering) packet -------------// TU_ASSERT(stream->index < 4, byte_count); stream->buffer[stream->index] = data; stream->index++; // See if this byte ends a SysEx. if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) { stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1))); stream->total = stream->index; } } // Send out packet if (stream->index >= 2 && stream->index == stream->total) { // zeroes unused bytes for (uint8_t i = stream->total; i < 4; i++) { stream->buffer[i] = 0; } TU_LOG3_MEM(stream->buffer, 4, 2); const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, stream->buffer, 4); // complete current event packet, reset stream stream->index = 0; stream->total = 0; // FIFO overflown, since we already check fifo remaining. It is probably race condition TU_ASSERT(count == 4, byte_count); } } return byte_count; } uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize) { TU_VERIFY(idx < CFG_TUH_MIDI && p_cable_num && p_buffer && bufsize > 0); midih_interface_t *p_midi = &_midi_host[idx]; uint32_t bytes_buffered = 0; uint8_t one_byte; if (!tu_edpt_stream_peek(&p_midi->ep_stream.rx, &one_byte)) { return 0; } *p_cable_num = (one_byte >> 4) & 0xf; uint32_t nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); static uint16_t cable_sysex_in_progress;// bit i is set if received MIDI_STATUS_SYSEX_START but not MIDI_STATUS_SYSEX_END while (nread == 4 && bytes_buffered < bufsize) { *p_cable_num = (p_midi->stream_read.buffer[0] >> 4) & 0x0f; uint8_t bytes_to_add_to_stream = 0; if (*p_cable_num < p_midi->rx_cable_count) { // ignore the CIN field; too many devices out there encode this wrong uint8_t status = p_midi->stream_read.buffer[1]; uint16_t cable_mask = (uint16_t) (1 << *p_cable_num); if (status <= MIDI_MAX_DATA_VAL || status == MIDI_STATUS_SYSEX_START) { if (status == MIDI_STATUS_SYSEX_START) { cable_sysex_in_progress |= cable_mask; } // only add the packet if a sysex message is in progress if (cable_sysex_in_progress & cable_mask) { ++bytes_to_add_to_stream; for (uint8_t i = 2; i < 4; i++) { if (p_midi->stream_read.buffer[i] <= MIDI_MAX_DATA_VAL) { ++bytes_to_add_to_stream; } else if (p_midi->stream_read.buffer[i] == MIDI_STATUS_SYSEX_END) { ++bytes_to_add_to_stream; cable_sysex_in_progress &= (uint16_t) ~cable_mask; i = 4;// force the loop to exit; I hate break statements in loops } } } else { // bad packet discard nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } } else if (status < MIDI_STATUS_SYSEX_START) { // then it is a channel message either three bytes or two uint8_t fake_cin = (status & 0xf0) >> 4; switch (fake_cin) { case MIDI_CIN_NOTE_OFF: case MIDI_CIN_NOTE_ON: case MIDI_CIN_POLY_KEYPRESS: case MIDI_CIN_CONTROL_CHANGE: case MIDI_CIN_PITCH_BEND_CHANGE: bytes_to_add_to_stream = 3; break; case MIDI_CIN_PROGRAM_CHANGE: case MIDI_CIN_CHANNEL_PRESSURE: bytes_to_add_to_stream = 2; break; default: break;// Should not get this } cable_sysex_in_progress &= (uint16_t) ~cable_mask; } else if (status < MIDI_STATUS_SYSREAL_TIMING_CLOCK) { switch (status) { case MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME: case MIDI_STATUS_SYSCOM_SONG_SELECT: bytes_to_add_to_stream = 2; break; case MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER: bytes_to_add_to_stream = 3; break; case MIDI_STATUS_SYSCOM_TUNE_REQUEST: case MIDI_STATUS_SYSEX_END: bytes_to_add_to_stream = 1; break; default: break; } cable_sysex_in_progress &= (uint16_t) ~cable_mask; } else { // Real-time message: can be inserted into a sysex message, // so do don't clear cable_sysex_in_progress bit bytes_to_add_to_stream = 1; } } else { // bad packet discard nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } for (uint8_t i = 1; i <= bytes_to_add_to_stream; i++) { *p_buffer++ = p_midi->stream_read.buffer[i]; } bytes_buffered += bytes_to_add_to_stream; nread = 0; if (tu_edpt_stream_peek(&p_midi->ep_stream.rx, &one_byte)) { uint8_t new_cable = (one_byte >> 4) & 0xf; if (new_cable == *p_cable_num) { // still on the same cable. Continue reading the stream nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); } } } return bytes_buffered; } #endif #endif ================================================ FILE: src/class/midi/midi_host.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MIDI_HOST_H_ #define TUSB_MIDI_HOST_H_ #include "class/audio/audio.h" #include "midi.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // Enable the MIDI stream read/write API. Some library can work with raw USB MIDI packet // Disable this can save driver footprint. #ifndef CFG_TUH_MIDI_STREAM_API #define CFG_TUH_MIDI_STREAM_API 1 #endif //--------------------------------------------------------------------+ // Application Types //--------------------------------------------------------------------+ typedef struct { const tusb_desc_interface_t *desc_audio_control; const tusb_desc_interface_t *desc_midi; // start of whole midi interface descriptor uint16_t desc_midi_total_len; const uint8_t *desc_header; const uint8_t *desc_element; const tusb_desc_endpoint_t *desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after const tusb_desc_endpoint_t *desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after uint8_t jack_num; const uint8_t *desc_jack[32]; // list of jack descriptors (embedded + external) } tuh_midi_descriptor_cb_t; typedef struct { uint8_t daddr; uint8_t bInterfaceNumber; // interface number of MIDI streaming uint8_t rx_cable_count; uint8_t tx_cable_count; } tuh_midi_mount_cb_t; //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Check if MIDI interface is mounted bool tuh_midi_mounted(uint8_t idx); // Get Interface index from device address + interface number // return TUSB_INDEX_INVALID_8 (0xFF) if not found uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get Interface information // return true if index is correct and interface is currently mounted bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t *info); // return the number of virtual midi cables on the device's IN endpoint uint8_t tuh_midi_get_rx_cable_count(uint8_t idx); // return the number of virtual midi cables on the device's OUT endpoint uint8_t tuh_midi_get_tx_cable_count(uint8_t idx); // return the raw number of bytes available. // Note: this is related but not the same as number of stream bytes available. uint32_t tuh_midi_read_available(uint8_t idx); // Send any queued packets to the device if the host hardware is able to do it // Returns the number of bytes flushed to the host hardware or 0 if // the host hardware is busy or there is nothing in queue to send. uint32_t tuh_midi_write_flush(uint8_t idx); //--------------------------------------------------------------------+ // Packet API //--------------------------------------------------------------------+ // Read all available MIDI packets from the connected device // Return number of bytes read (always multiple of 4) uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t *buffer, uint32_t bufsize); // Read a raw MIDI packet from the connected device // Return true if a packet was returned TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_read(uint8_t idx, uint8_t packet[4]) { return 4 == tuh_midi_packet_read_n(idx, packet, 4); } // Write all 4-byte packets, data is locally buffered and only transferred when buffered bytes // reach the endpoint packet size or tuh_midi_write_flush() is called uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t *buffer, uint32_t bufsize); // Write a 4-bytes packet to the device. // Returns true if the packet was successfully queued. TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_write(uint8_t idx, const uint8_t packet[4]) { return 4 == tuh_midi_packet_write_n(idx, packet, 4); } //--------------------------------------------------------------------+ // Stream API //--------------------------------------------------------------------+ #if CFG_TUH_MIDI_STREAM_API // Queue a message to the device using stream API. data is locally buffered and only transferred when buffered bytes // reach the endpoint packet size or tuh_midi_write_flush() is called // Returns number of bytes was successfully queued. uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, const uint8_t *p_buffer, uint32_t bufsize); // Get the MIDI stream from the device. Set the value pointed // to by p_cable_num to the MIDI cable number intended to receive it. // The MIDI stream will be stored in the buffer pointed to by p_buffer. // Return the number of bytes added to the buffer. // Note that this function ignores the CIN field of the MIDI packet // because a number of commercial devices out there do not encode // it properly. uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buffer, uint16_t bufsize); #endif //--------------------------------------------------------------------+ // Callbacks (Weak is optional) //--------------------------------------------------------------------+ // Invoked when MIDI interface is detected in enumeration. Application can copy/parse descriptor if needed. // Note: may be fired before tuh_midi_mount_cb(), therefore midi interface is not mounted/ready. void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t *desc_cb_data); // Invoked when device with MIDI interface is mounted. void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t *mount_cb_data); // Invoked when device with MIDI interface is un-mounted void tuh_midi_umount_cb(uint8_t idx); // Invoked when received new data void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes); // Invoked when a TX is complete and therefore space becomes available in TX buffer void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ bool midih_init(void); bool midih_deinit(void); uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); bool midih_set_config(uint8_t dev_addr, uint8_t itf_num); bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void midih_close(uint8_t daddr); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/msc/msc.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MSC_H_ #define TUSB_MSC_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Mass Storage Class Constant //--------------------------------------------------------------------+ /// MassStorage Subclass typedef enum { MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device MSC_SUBCLASS_SCSI ///< SCSI transparent command set }msc_subclass_type_t; enum { MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian) MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian) }; /// \brief MassStorage Protocol. /// \details CBI only approved to use with full-speed floppy disk & should not used with highspeed or device other than floppy typedef enum { MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt) MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt) MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport }msc_protocol_type_t; /// MassStorage Class-Specific Control Request typedef enum { MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15 MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host. }msc_request_type_t; /// \brief Command Block Status Values /// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed /// successfully. A non-zero value shall indicate a failure during command execution according to the following typedef enum { MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR }msc_csw_status_t; /// Command Block Wrapper typedef struct TU_ATTR_PACKED { uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW. uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW. uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags. uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host. uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero. uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16 uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block }msc_cbw_t; TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct"); /// Command Status Wrapper typedef struct TU_ATTR_PACKED { uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW. uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW. uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResidue the difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t }msc_csw_t; TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Constant //--------------------------------------------------------------------+ /// SCSI Command Operation Code typedef enum { SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation. SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device. SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters. SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command. SCSI_CMD_START_STOP_UNIT = 0x1B, SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E, SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device. SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device. SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer. SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests that the device server transfer the specified logical block(s) from the data-out buffer and write them. }scsi_cmd_type_t; /// SCSI Sense Key typedef enum { SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< Indicates the last command completed successfully with some recovery action performed by the disc drive. SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed. SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition. SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test. SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset. SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed. SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key. SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command. SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison. SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium. SCSI_SENSE_MISCOMPARE = 0x0e ///< Indicates that the source data did not match the data read from the medium. }scsi_sense_key_type_t; typedef enum { SCSI_PDT_DIRECT_ACCESS = 0x0, SCSI_PDT_SEQUENTIAL_ACCESS = 0x1, SCSI_PDT_PRINTER = 0x2, SCSI_PDT_PROCESSOR = 0x3, SCSI_PDT_WRITE_ONCE = 0x4, SCSI_PDT_CD_DVD = 0x5, SCSI_PDT_SCANNER = 0x6, SCSI_PDT_OPTICAL_DEVICE = 0x7, SCSI_PDT_MEDIUM_CHANGER = 0x8, SCSI_PDT_COMMUNICATIONS = 0x9, // obsolete SCSI_PDT_RAID = 0x0c, SCSI_PDT_ENCLOSURE_SERVICES = 0x0d, SCSI_PDT_SIMPLIFIED_DIRECT_ACCESS = 0x0e, SCSI_PDT_OPTICAL_CARD_READER = 0x0f, SCSI_PDT_BRIDGE = 0x10, ///< Bridge device, e.g. USB to SCSI bridge SCSI_PDT_OBJECT_BASED_STORAGE = 0x11, ///< Object-based storage device SCSI_PDT_AUTOMATION_DRIVE_INTERFACE = 0x12, ///< Automation/Drive Interface (ADI) device } scsi_peripheral_device_type_t; //--------------------------------------------------------------------+ // SCSI Primary Command (SPC-4) //--------------------------------------------------------------------+ /// SCSI Test Unit Ready Command typedef struct TU_ATTR_PACKED { uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY uint8_t lun ; ///< Logical Unit uint8_t reserved[3] ; uint8_t control ; } scsi_test_unit_ready_t; TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct"); /// SCSI Inquiry Command typedef struct TU_ATTR_PACKED { uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY uint8_t reserved1 ; uint8_t page_code ; uint8_t reserved2 ; uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred. uint8_t control ; } scsi_inquiry_t, scsi_request_sense_t; TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct"); /// SCSI Inquiry Response Data typedef struct TU_ATTR_PACKED { uint8_t peripheral_device_type : 5; uint8_t peripheral_qualifier : 3; uint8_t : 7; uint8_t is_removable : 1; uint8_t version; uint8_t response_data_format : 4; uint8_t hierarchical_support : 1; uint8_t normal_aca : 1; uint8_t : 2; uint8_t additional_length; uint8_t protect : 1; uint8_t : 2; uint8_t third_party_copy : 1; uint8_t target_port_group_support : 2; uint8_t access_control_coordinator : 1; uint8_t scc_support : 1; uint8_t addr16 : 1; uint8_t : 3; uint8_t multi_port : 1; uint8_t : 1; // vendor specific uint8_t enclosure_service : 1; uint8_t : 1; uint8_t : 1; // vendor specific uint8_t cmd_que : 1; uint8_t : 2; uint8_t sync : 1; uint8_t wbus16 : 1; uint8_t : 2; uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product. uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor. uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor. } scsi_inquiry_resp_t; TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format uint8_t valid : 1; uint8_t reserved; uint8_t sense_key : 4; uint8_t : 1; uint8_t ili : 1; ///< Incorrect length indicator uint8_t end_of_medium : 1; uint8_t filemark : 1; uint32_t information; uint8_t add_sense_len; uint32_t command_specific_info; uint8_t add_sense_code; uint8_t add_sense_qualifier; uint8_t field_replaceable_unit_code; uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout } scsi_sense_fixed_resp_t; TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6 uint8_t : 3; uint8_t disable_block_descriptor : 1; uint8_t : 4; uint8_t page_code : 6; uint8_t page_control : 2; uint8_t subpage_code; uint8_t alloc_length; uint8_t control; } scsi_mode_sense6_t; TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct"); // This is only a Mode parameter header(6). typedef struct TU_ATTR_PACKED { uint8_t data_len; uint8_t medium_type; uint8_t reserved : 7; bool write_protected : 1; uint8_t block_descriptor_len; } scsi_mode_sense6_resp_t; TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL uint8_t reserved[3]; uint8_t prohibit_removal; uint8_t control; } scsi_prevent_allow_medium_removal_t; TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t cmd_code; uint8_t immded : 1; uint8_t : 7; uint8_t TU_RESERVED; uint8_t power_condition_mod : 4; uint8_t : 4; uint8_t start : 1; uint8_t load_eject : 1; uint8_t no_flush : 1; uint8_t : 1; uint8_t power_condition : 4; uint8_t control; } scsi_start_stop_unit_t; TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct"); //--------------------------------------------------------------------+ // SCSI MMC //--------------------------------------------------------------------+ /// SCSI Read Format Capacity: Write Capacity typedef struct TU_ATTR_PACKED { uint8_t cmd_code; uint8_t reserved[6]; uint16_t alloc_length; uint8_t control; } scsi_read_format_capacity_t; TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct"); typedef struct TU_ATTR_PACKED{ uint8_t reserved[3]; uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it. uint32_t block_num; /// Number of Logical Blocks uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present uint8_t reserved2; uint16_t block_size_u16; } scsi_read_format_capacity_data_t; TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Block Command (SBC-3) // NOTE: All data in SCSI command are in Big Endian //--------------------------------------------------------------------+ /// SCSI Read Capacity 10 Command: Read Capacity typedef struct TU_ATTR_PACKED { uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10 uint8_t reserved1 ; uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command uint16_t reserved2 ; uint8_t partial_medium_indicator ; uint8_t control ; } scsi_read_capacity10_t; TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct"); /// SCSI Read Capacity 10 Response Data typedef struct { uint32_t last_lba ; ///< The last Logical Block Address of the device uint32_t block_size ; ///< Block size in bytes } scsi_read_capacity10_resp_t; TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct"); /// SCSI Read 10 Command typedef struct TU_ATTR_PACKED { uint8_t cmd_code ; ///< SCSI OpCode uint8_t reserved ; // has LUN according to wiki uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command uint8_t reserved2 ; uint16_t block_count ; ///< Number of Blocks used by this command uint8_t control ; } scsi_read10_t, scsi_write10_t; TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct"); TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct"); #ifdef __cplusplus } #endif #endif /* TUSB_MSC_H_ */ ================================================ FILE: src/class/msc/msc_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_MSC) #include "device/dcd.h" // for faking dcd_event_xfer_complete #include "device/usbd.h" #include "device/usbd_pvt.h" #include "msc_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_MSC_LOG_LEVEL #define CFG_TUD_MSC_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MSC_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { (void) lun; (void) vendor_id; (void) product_id; (void) product_rev; } TU_ATTR_WEAK uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uint32_t bufsize) { (void) lun; (void) inquiry_resp; (void) bufsize; return 0; } //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ enum { MSC_STAGE_CMD = 0, MSC_STAGE_DATA, MSC_STAGE_STATUS, MSC_STAGE_STATUS_SENT, MSC_STAGE_NEED_RESET, }; typedef struct { TU_ATTR_ALIGNED(4) msc_cbw_t cbw; // 31 bytes uint8_t rhport; TU_ATTR_ALIGNED(4) msc_csw_t csw; // 13 bytes uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; uint32_t total_len; // byte to be transferred, can be smaller than total_bytes in cbw uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage // Bulk Only Transfer (BOT) Protocol uint8_t stage; // SCSI Sense Response Data uint8_t sense_key; uint8_t add_sense_code; uint8_t add_sense_qualifier; bool pending_io; // pending async IO }mscd_interface_t; static mscd_interface_t _mscd_itf; CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(buf, CFG_TUD_MSC_EP_BUFSIZE); } _mscd_epbuf; TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE >= 64, "CFG_TUD_MSC_EP_BUFSIZE must be at least 64"); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize); static void proc_read10_cmd(mscd_interface_t* p_msc); static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes); static void proc_write10_cmd(mscd_interface_t* p_msc); static void proc_write10_host_data(mscd_interface_t* p_msc, uint32_t xferred_bytes); static void proc_write_io_data(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes); static bool proc_stage_status(mscd_interface_t* p_msc); TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) { return tu_bit_test(dir, 7); } TU_ATTR_ALWAYS_INLINE static inline bool send_csw(mscd_interface_t* p_msc) { // Data residue is always = host expect - actual transferred uint8_t rhport = p_msc->rhport; p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; p_msc->stage = MSC_STAGE_STATUS_SENT; memcpy(_mscd_epbuf.buf, &p_msc->csw, sizeof(msc_csw_t)); //-V1086 return usbd_edpt_xfer(rhport, p_msc->ep_in , _mscd_epbuf.buf, sizeof(msc_csw_t), false); } TU_ATTR_ALWAYS_INLINE static inline bool prepare_cbw(mscd_interface_t* p_msc) { uint8_t rhport = p_msc->rhport; p_msc->stage = MSC_STAGE_CMD; return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); } static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { msc_cbw_t const * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; uint8_t rhport = p_msc->rhport; p_csw->status = status; p_csw->data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; p_msc->stage = MSC_STAGE_STATUS; // failed but sense key is not set: default to Illegal Request if (p_msc->sense_key == 0) { (void) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); } // If there is data stage and not yet complete, stall it if (p_cbw->total_bytes && p_csw->data_residue) { if (is_data_in(p_cbw->dir)) { usbd_edpt_stall(rhport, p_msc->ep_in); } else { usbd_edpt_stall(rhport, p_msc->ep_out); } } } TU_ATTR_ALWAYS_INLINE static inline uint32_t rdwr10_get_lba(uint8_t const command[]) { // use offsetof to avoid pointer to the odd/unaligned address const uint32_t lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); return tu_ntohl(lba); // lba is in Big Endian } TU_ATTR_ALWAYS_INLINE static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) { uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); return tu_ntohs(block_count); } TU_ATTR_ALWAYS_INLINE static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) { // first extract block count in the command uint16_t const block_count = rdwr10_get_blockcount(cbw); if (block_count == 0) { return 0; // invalid block count } return (uint16_t) (cbw->total_bytes / block_count); } static uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) { uint8_t status = MSC_CSW_STATUS_PASSED; uint16_t const block_count = rdwr10_get_blockcount(cbw); if (cbw->total_bytes == 0) { if (block_count > 0) { TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; } else { // no data transfer, only exist in complaint test suite } } else { if (SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir)) { TU_LOG_DRV(" SCSI case 10 (Ho <> Di)\r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; } else if (SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir)) { TU_LOG_DRV(" SCSI case 8 (Hi <> Do)\r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; } else if (0 == block_count) { TU_LOG_DRV(" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n"); status = MSC_CSW_STATUS_FAILED; } else if (cbw->total_bytes / block_count == 0) { TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; } else { // nothing to do } } return status; } static bool proc_stage_status(mscd_interface_t *p_msc) { uint8_t rhport = p_msc->rhport; msc_cbw_t const *p_cbw = &p_msc->cbw; // skip status if epin is currently stalled, will do it when received Clear Stall request if (!usbd_edpt_stalled(rhport, p_msc->ep_in)) { if ((p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir)) { // 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status // TU_LOG_DRV(" SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len); usbd_edpt_stall(rhport, p_msc->ep_in); } else { TU_ASSERT(send_csw(p_msc)); } } #if TU_CHECK_MCU(OPT_MCU_CXD56) // WORKAROUND: cxd56 has its own nuttx usb stack which does not forward Set/ClearFeature(Endpoint) to DCD. // There is no way for us to know when EP is un-stall, therefore we will unconditionally un-stall here and // hope everything will work if (usbd_edpt_stalled(rhport, p_msc->ep_in)) { usbd_edpt_clear_stall(rhport, p_msc->ep_in); send_csw(p_msc); } #endif return true; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun) { (void) lun; } TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun) { (void) lun; } TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]) { (void) lun; (void) scsi_cmd; } TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void) { return 1; } TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; (void) start; (void) load_eject; return true; } TU_ATTR_WEAK bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control) { (void) lun; (void) prohibit_removal; (void) control; return true; } TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize) { (void) lun; (void) buffer; (void) bufsize; return sizeof(scsi_sense_fixed_resp_t); } TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun) { (void) lun; return true; } //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { { .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" }, { .key = SCSI_CMD_INQUIRY , .data = "Inquiry" }, { .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" }, { .key = SCSI_CMD_MODE_SENSE_6 , .data = "Mode_Sense 6" }, { .key = SCSI_CMD_START_STOP_UNIT , .data = "Start Stop Unit" }, { .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent/Allow Medium Removal" }, { .key = SCSI_CMD_READ_CAPACITY_10 , .data = "Read Capacity10" }, { .key = SCSI_CMD_REQUEST_SENSE , .data = "Request Sense" }, { .key = SCSI_CMD_READ_FORMAT_CAPACITY , .data = "Read Format Capacity" }, { .key = SCSI_CMD_READ_10 , .data = "Read10" }, { .key = SCSI_CMD_WRITE_10 , .data = "Write10" } }; TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table = { .count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup), .items = _msc_scsi_cmd_lookup }; #endif //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier) { (void) lun; _mscd_itf.sense_key = sense_key; _mscd_itf.add_sense_code = add_sense_code; _mscd_itf.add_sense_qualifier = add_sense_qualifier; return true; } TU_ATTR_ALWAYS_INLINE static inline void set_sense_medium_not_present(uint8_t lun) { // default sense is NOT READY, MEDIUM NOT PRESENT (void) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); } static void proc_async_io_done(void *bytes_io) { mscd_interface_t *p_msc = &_mscd_itf; TU_VERIFY(p_msc->pending_io, ); const int32_t nbytes = (int32_t) (intptr_t) bytes_io; const uint8_t cmd = p_msc->cbw.command[0]; p_msc->pending_io = false; switch (cmd) { case SCSI_CMD_READ_10: proc_read_io_data(p_msc, nbytes); break; case SCSI_CMD_WRITE_10: proc_write_io_data(p_msc, (uint32_t) nbytes, nbytes); break; default: break; // nothing to do } // send status if stage is transitioned to STATUS if (p_msc->stage == MSC_STAGE_STATUS) { proc_stage_status(p_msc); } } bool tud_msc_async_io_done(int32_t bytes_io, bool in_isr) { // Precheck to avoid queueing multiple RW done callback TU_VERIFY(_mscd_itf.pending_io); if (bytes_io == 0) { bytes_io = TUD_MSC_RET_ERROR; // 0 is treated as error, no reason to call this with BUSY here } usbd_defer_func(proc_async_io_done, (void *) (intptr_t) bytes_io, in_isr); return true; } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void mscd_init(void) { TU_LOG_INT(CFG_TUD_MSC_LOG_LEVEL, sizeof(mscd_interface_t)); tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } bool mscd_deinit(void) { return true; // nothing to do } void mscd_reset(uint8_t rhport) { (void) rhport; tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } uint16_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // only support SCSI's BOT protocol TU_VERIFY(TUSB_CLASS_MSC == itf_desc->bInterfaceClass && MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass && MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol, 0); uint16_t const drv_len = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); TU_ASSERT(max_len >= drv_len, 0); // Max length must be at least 1 interface + 2 endpoints mscd_interface_t * p_msc = &_mscd_itf; p_msc->itf_num = itf_desc->bInterfaceNumber; p_msc->rhport = rhport; // Open endpoint pair TU_ASSERT(usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in), 0); // Prepare for Command Block Wrapper TU_ASSERT(prepare_cbw(p_msc), drv_len); return drv_len; } static void proc_bot_reset(mscd_interface_t* p_msc) { p_msc->stage = MSC_STAGE_CMD; p_msc->total_len = 0; p_msc->xferred_len = 0; p_msc->sense_key = 0; p_msc->add_sense_code = 0; p_msc->add_sense_qualifier = 0; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { if (stage != CONTROL_STAGE_SETUP) { return true; // nothing to do with DATA & ACK stage } mscd_interface_t* p_msc = &_mscd_itf; // Clear Endpoint Feature (stall) for recovery if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && TUSB_REQ_RCPT_ENDPOINT == request->bmRequestType_bit.recipient && TUSB_REQ_CLEAR_FEATURE == request->bRequest && TUSB_REQ_FEATURE_EDPT_HALT == request->wValue ) { uint8_t const ep_addr = tu_u16_low(request->wIndex); if (p_msc->stage == MSC_STAGE_NEED_RESET) { // reset recovery is required to recover from this stage // Clear Stall request cannot resolve this -> continue to stall endpoint usbd_edpt_stall(rhport, ep_addr); } else { if (ep_addr == p_msc->ep_in) { if (p_msc->stage == MSC_STAGE_STATUS) { // resume sending SCSI status if we are in this stage previously before stalled TU_ASSERT(send_csw(p_msc)); } } else if (ep_addr == p_msc->ep_out) { if (p_msc->stage == MSC_STAGE_CMD) { // part of reset recovery (probably due to invalid CBW) -> prepare for new command // Note: skip if already queued previously if (usbd_edpt_ready(rhport, p_msc->ep_out)) { TU_ASSERT(prepare_cbw(p_msc)); } } } else { // nothing to do } } return true; } // From this point only handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); switch ( request->bRequest ) { case MSC_REQ_RESET: TU_LOG_DRV(" MSC BOT Reset\r\n"); TU_VERIFY(request->wValue == 0 && request->wLength == 0); proc_bot_reset(p_msc); // driver state reset tud_control_status(rhport, request); break; case MSC_REQ_GET_MAX_LUN: { TU_LOG_DRV(" MSC Get Max Lun\r\n"); TU_VERIFY(request->wValue == 0 && request->wLength == 1); uint8_t maxlun = tud_msc_get_maxlun_cb(); TU_VERIFY(maxlun != 0); maxlun--; // MAX LUN is minus 1 by specs tud_control_xfer(rhport, request, &maxlun, 1); break; } default: return false; // stall unsupported request } return true; } bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { (void) event; mscd_interface_t* p_msc = &_mscd_itf; msc_cbw_t * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; switch (p_msc->stage) { case MSC_STAGE_CMD: { //------------- new CBW received -------------// // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it if (ep_addr != p_msc->ep_out) { return true; } const uint32_t signature = tu_le32toh(tu_unaligned_read32(_mscd_epbuf.buf)); if (!(xferred_bytes == sizeof(msc_cbw_t) && signature == MSC_CBW_SIGNATURE)) { // BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery TU_LOG_DRV(" SCSI CBW is not valid\r\n"); p_msc->stage = MSC_STAGE_NEED_RESET; usbd_edpt_stall(rhport, p_msc->ep_in); usbd_edpt_stall(rhport, p_msc->ep_out); return false; } memcpy(p_cbw, _mscd_epbuf.buf, sizeof(msc_cbw_t)); TU_LOG_DRV(" SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); // TU_LOG_MEM(CFG_TUD_MSC_LOG_LEVEL, p_cbw, xferred_bytes, 2); p_csw->signature = MSC_CSW_SIGNATURE; p_csw->tag = p_cbw->tag; p_csw->data_residue = 0; p_csw->status = MSC_CSW_STATUS_PASSED; /*------------- Parse command and prepare DATA -------------*/ p_msc->stage = MSC_STAGE_DATA; p_msc->total_len = p_cbw->total_bytes; p_msc->xferred_len = 0; // Read10 or Write10 if ((SCSI_CMD_READ_10 == p_cbw->command[0]) || (SCSI_CMD_WRITE_10 == p_cbw->command[0])) { uint8_t const status = rdwr10_validate_cmd(p_cbw); if (status != MSC_CSW_STATUS_PASSED) { fail_scsi_op(p_msc, status); } else if (p_cbw->total_bytes > 0) { if (SCSI_CMD_READ_10 == p_cbw->command[0]) { proc_read10_cmd(p_msc); } else { proc_write10_cmd(p_msc); } } else { // no data transfer, only exist in complaint test suite p_msc->stage = MSC_STAGE_STATUS; } } else { // For other SCSI commands // 1. OUT : queue transfer (invoke app callback after done) // 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length if ((p_cbw->total_bytes > 0) && !is_data_in(p_cbw->dir)) { if (p_cbw->total_bytes > CFG_TUD_MSC_EP_BUFSIZE) { TU_LOG_DRV(" SCSI reject non READ10/WRITE10 with large data\r\n"); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); } else { // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first // but it is OK to just receive data then responded with failed status TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } else { // First process if it is a built-in commands int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_epbuf.buf, CFG_TUD_MSC_EP_BUFSIZE); // Invoke user callback if not built-in if ((resplen < 0) && (p_msc->sense_key == 0)) { resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_epbuf.buf, (uint16_t)p_msc->total_len); } if (resplen < 0) { // unsupported command TU_LOG_DRV(" SCSI unsupported or failed command\r\n"); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); } else if (resplen == 0) { if (p_cbw->total_bytes > 0) { // 6.7 The 13 Cases: case 4 (Hi > Dn) // TU_LOG_DRV(" SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); } else { // case 1 Hn = Dn: all good p_msc->stage = MSC_STAGE_STATUS; } } else { if (p_cbw->total_bytes == 0) { // 6.7 The 13 Cases: case 2 (Hn < Di) // TU_LOG_DRV(" SCSI case 2 (Hn < Di): %lu\r\n", p_cbw->total_bytes); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); } else { // cannot return more than host expect p_msc->total_len = tu_min32((uint32_t)resplen, p_cbw->total_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } } } break; } case MSC_STAGE_DATA: TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun); TU_ASSERT(xferred_bytes <= CFG_TUD_MSC_EP_BUFSIZE); // sanity check to avoid buffer overflow // TU_LOG_MEM(CFG_TUD_MSC_LOG_LEVEL, _mscd_epbuf.buf, xferred_bytes, 2); if (SCSI_CMD_READ_10 == p_cbw->command[0]) { p_msc->xferred_len += xferred_bytes; if ( p_msc->xferred_len >= p_msc->total_len ) { // Data Stage is complete p_msc->stage = MSC_STAGE_STATUS; }else { proc_read10_cmd(p_msc); } } else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) { proc_write10_host_data(p_msc, xferred_bytes); } else { p_msc->xferred_len += xferred_bytes; // OUT transfer, invoke callback if needed if ( !is_data_in(p_cbw->dir) ) { int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_epbuf.buf, (uint16_t) p_msc->total_len); if ( cb_result < 0 ) { // unsupported command TU_LOG_DRV(" SCSI unsupported command\r\n"); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); }else { // TODO haven't implement this scenario any further yet } } if ( p_msc->xferred_len >= p_msc->total_len ) { // Data Stage is complete p_msc->stage = MSC_STAGE_STATUS; } else { // This scenario with command that take more than one transfer is already rejected at Command stage TU_BREAKPOINT(); } } break; case MSC_STAGE_STATUS: // processed immediately after this switch, supposedly to be empty break; case MSC_STAGE_STATUS_SENT: // Status phase is complete if ((ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t))) { TU_LOG_DRV(" SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status); // TU_LOG_MEM(CFG_TUD_MSC_LOG_LEVEL, p_csw, xferred_bytes, 2); // Invoke complete callback if defined // Note: There is racing issue with samd51 + qspi flash testing with arduino // if complete_cb() is invoked after queuing the status. switch (p_cbw->command[0]) { case SCSI_CMD_READ_10: tud_msc_read10_complete_cb(p_cbw->lun); break; case SCSI_CMD_WRITE_10: tud_msc_write10_complete_cb(p_cbw->lun); break; default: tud_msc_scsi_complete_cb(p_cbw->lun, p_cbw->command); break; } if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) { TU_ASSERT(prepare_cbw(p_msc)); } else { p_msc->stage = MSC_STAGE_CMD; } } else { // Any xfer ended here is considered unknown error, ignore it TU_LOG1(" Warning expect SCSI Status but received unknown data\r\n"); } break; default: break; // nothing to do } if (p_msc->stage == MSC_STAGE_STATUS) { TU_ASSERT(proc_stage_status(p_msc)); } return true; } /*------------------------------------------------------------------*/ /* SCSI Command Process *------------------------------------------------------------------*/ // return response's length (copied to buffer). Negative if it is not an built-in command or indicate Failed status (CSW) // In case of a failed status, sense key must be set for reason of failure static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize) { (void)bufsize; // TODO refractor later int32_t resplen; mscd_interface_t* p_msc = &_mscd_itf; switch (scsi_cmd[0]) { case SCSI_CMD_TEST_UNIT_READY: resplen = 0; if (!tud_msc_test_unit_ready_cb(lun)) { // Failed status response resplen = -1; // set default sense if not set by callback if (p_msc->sense_key == 0) { set_sense_medium_not_present(lun); } } break; case SCSI_CMD_START_STOP_UNIT: { resplen = 0; scsi_start_stop_unit_t const* start_stop = (scsi_start_stop_unit_t const*)scsi_cmd; if (!tud_msc_start_stop_cb(lun, start_stop->power_condition, start_stop->start, start_stop->load_eject)) { // Failed status response resplen = -1; // set default sense if not set by callback if (p_msc->sense_key == 0) { set_sense_medium_not_present(lun); } } break; } case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: { resplen = 0; scsi_prevent_allow_medium_removal_t const* prevent_allow = (scsi_prevent_allow_medium_removal_t const*)scsi_cmd; if (!tud_msc_prevent_allow_medium_removal_cb(lun, prevent_allow->prohibit_removal, prevent_allow->control)) { // Failed status response resplen = -1; // set default sense if not set by callback if (p_msc->sense_key == 0) { set_sense_medium_not_present(lun); } } break; } case SCSI_CMD_READ_CAPACITY_10: { uint32_t block_count; uint32_t block_size; uint16_t block_size_u16; tud_msc_capacity_cb(lun, &block_count, &block_size_u16); block_size = (uint32_t)block_size_u16; // Invalid block size/count from callback, possibly unit is not ready // stall this request, set sense key to NOT READY if (block_count == 0 || block_size == 0) { resplen = -1; // set default sense if not set by callback if (p_msc->sense_key == 0) { set_sense_medium_not_present(lun); } } else { scsi_read_capacity10_resp_t read_capa10; read_capa10.last_lba = tu_htonl(block_count-1); read_capa10.block_size = tu_htonl(block_size); resplen = sizeof(read_capa10); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_capa10, (size_t) resplen)); } break; } case SCSI_CMD_READ_FORMAT_CAPACITY: { scsi_read_format_capacity_data_t read_fmt_capa = { .list_length = 8, .block_num = 0, .descriptor_type = 2, // formatted media .block_size_u16 = 0 }; uint32_t block_count; uint16_t block_size; tud_msc_capacity_cb(lun, &block_count, &block_size); // Invalid block size/count from callback, possibly unit is not ready // stall this request, set sense key to NOT READY if (block_count == 0 || block_size == 0) { resplen = -1; // set default sense if not set by callback if (p_msc->sense_key == 0) { set_sense_medium_not_present(lun); } } else { read_fmt_capa.block_num = tu_htonl(block_count); read_fmt_capa.block_size_u16 = tu_htons(block_size); resplen = sizeof(read_fmt_capa); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_fmt_capa, (size_t) resplen)); } break; } case SCSI_CMD_INQUIRY: { scsi_inquiry_resp_t *inquiry_rsp = (scsi_inquiry_resp_t *) buffer; tu_memclr(inquiry_rsp, sizeof(scsi_inquiry_resp_t)); inquiry_rsp->is_removable = 1; inquiry_rsp->version = 2; inquiry_rsp->response_data_format = 2; inquiry_rsp->additional_length = sizeof(scsi_inquiry_resp_t) - 5; resplen = (int32_t) tud_msc_inquiry2_cb(lun, inquiry_rsp, bufsize); if (resplen == 0) { // stub callback with no response, use v1 callback tud_msc_inquiry_cb(lun, inquiry_rsp->vendor_id, inquiry_rsp->product_id, inquiry_rsp->product_rev); resplen = sizeof(scsi_inquiry_resp_t); } break; } case SCSI_CMD_MODE_SENSE_6: { scsi_mode_sense6_resp_t mode_resp = { .data_len = 3, .medium_type = 0, .write_protected = false, .reserved = 0, .block_descriptor_len = 0 // no block descriptor are included }; bool writable = tud_msc_is_writable_cb(lun); mode_resp.write_protected = !writable; resplen = sizeof(mode_resp); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &mode_resp, (size_t) resplen)); break; } case SCSI_CMD_REQUEST_SENSE: { scsi_sense_fixed_resp_t sense_rsp = { .response_code = 0x70, // current, fixed format .valid = 1 }; sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; sense_rsp.sense_key = (uint8_t)(p_msc->sense_key & 0x0F); sense_rsp.add_sense_code = p_msc->add_sense_code; sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; resplen = sizeof(sense_rsp); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &sense_rsp, (size_t) resplen)); // request sense callback could overwrite the sense data resplen = tud_msc_request_sense_cb(lun, buffer, (uint16_t)bufsize); // Clear sense data after copy (void) tud_msc_set_sense(lun, 0, 0, 0); break; } default: resplen = -1; break; } return resplen; } static void proc_read10_cmd(mscd_interface_t* p_msc) { msc_cbw_t const* p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); // already verified non-zero TU_VERIFY(block_sz != 0, ); // Adjust lba & offset with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); uint32_t const offset = p_msc->xferred_len % block_sz; // remaining bytes capped at class buffer int32_t nbytes = (int32_t)tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes - p_msc->xferred_len); p_msc->pending_io = true; nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, (uint32_t)nbytes); if (nbytes != TUD_MSC_RET_ASYNC) { p_msc->pending_io = false; proc_read_io_data(p_msc, nbytes); } } static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes) { const uint8_t rhport = p_msc->rhport; if (nbytes > 0) { TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) nbytes, false),); } else { // nbytes is status switch (nbytes) { case TUD_MSC_RET_ERROR: // error -> endpoint is stalled & status in CSW set to failed TU_LOG_DRV(" IO read() failed\r\n"); set_sense_medium_not_present(p_msc->cbw.lun); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); break; case TUD_MSC_RET_BUSY: // not ready yet -> fake a transfer complete so that this driver callback will fire again dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, XFER_RESULT_SUCCESS, false); break; default: break; // nothing to do } } } static void proc_write10_cmd(mscd_interface_t* p_msc) { msc_cbw_t const* p_cbw = &p_msc->cbw; const bool writable = tud_msc_is_writable_cb(p_cbw->lun); if (!writable) { // Not writable, complete this SCSI op with error // Sense = Write protected (void) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); return; } // remaining bytes capped at class buffer uint16_t nbytes = (uint16_t)tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes - p_msc->xferred_len); // Write10 callback will be called later when usb transfer complete TU_ASSERT(usbd_edpt_xfer(p_msc->rhport, p_msc->ep_out, _mscd_epbuf.buf, nbytes, false),); } // process new data arrived from WRITE10 static void proc_write10_host_data(mscd_interface_t* p_msc, uint32_t xferred_bytes) { msc_cbw_t const* p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); // already verified non-zero TU_VERIFY(block_sz != 0, ); // Adjust lba & offset with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); uint32_t const offset = p_msc->xferred_len % block_sz; p_msc->pending_io = true; int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, xferred_bytes); if (nbytes != TUD_MSC_RET_ASYNC) { p_msc->pending_io = false; proc_write_io_data(p_msc, xferred_bytes, nbytes); } } static void proc_write_io_data(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes) { if (nbytes < 0) { // nbytes is status switch (nbytes) { case TUD_MSC_RET_ERROR: // IO error -> failed this scsi op TU_LOG_DRV(" IO write() failed\r\n"); set_sense_medium_not_present(p_msc->cbw.lun); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); break; default: break; // nothing to do } } else { if ((uint32_t)nbytes < xferred_bytes) { // Application consume less than what we got including TUD_MSC_RET_BUSY (0) const uint32_t left_over = xferred_bytes - (uint32_t)nbytes; if (nbytes > 0) { memmove(_mscd_epbuf.buf, _mscd_epbuf.buf + nbytes, left_over); } // fake a transfer complete with adjusted parameters --> callback will be invoked with adjusted parameters dcd_event_xfer_complete(p_msc->rhport, p_msc->ep_out, left_over, XFER_RESULT_SUCCESS, false); } else { // Application consume all bytes in our buffer p_msc->xferred_len += xferred_bytes; if (p_msc->xferred_len >= p_msc->total_len) { // Data Stage is complete p_msc->stage = MSC_STAGE_STATUS; } else { // prepare to receive more data from host proc_write10_cmd(p_msc); } } } } #endif ================================================ FILE: src/class/msc/msc_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MSC_DEVICE_H_ #define TUSB_MSC_DEVICE_H_ #include "common/tusb_common.h" #include "msc.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #if !defined(CFG_TUD_MSC_EP_BUFSIZE) & defined(CFG_TUD_MSC_BUFSIZE) // TODO warn user to use new name later on // #warning CFG_TUD_MSC_BUFSIZE is renamed to CFG_TUD_MSC_EP_BUFSIZE, please update to use the new name #define CFG_TUD_MSC_EP_BUFSIZE CFG_TUD_MSC_BUFSIZE #endif #ifndef CFG_TUD_MSC_EP_BUFSIZE #error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better #endif // Return value of callback functions enum { TUD_MSC_RET_BUSY = 0, // Busy, e.g disk I/O is not ready TUD_MSC_RET_ERROR = -1, TUD_MSC_RET_ASYNC = -2, // Asynchronous IO }; TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct"); //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Set SCSI sense response bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier); // Called by Application once asynchronous I/O operation is done // bytes_io is number of bytes in I/O op, typically the bufsize in read/write_cb() or // TUD_MSC_RET_ERROR (-1) for error. Note TUD_MSC_RET_BUSY (0) will be treated as error as well. bool tud_msc_async_io_done(int32_t bytes_io, bool in_isr); //--------------------------------------------------------------------+ // Application Callbacks (WEAK is optional) //--------------------------------------------------------------------+ /* Invoked when received SCSI READ10/WRITE10 command - Address = lba * BLOCK_SIZE + offset - offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE. - Application fill the buffer (up to bufsize) with address contents and return number of bytes read or status. - 0 < ret < bufsize: These bytes are transferred first and callback will be invoked again for remaining data. - TUD_MSC_RET_BUSY Application is buys e.g disk I/O not ready. Callback will be invoked again with the same parameters later on. - TUD_MSC_RET_ERROR error such as invalid address. This request will be STALLed and scsi command will be failed - TUD_MSC_RET_ASYNC Data I/O will be done asynchronously in a background task. Application should return immediately. tud_msc_async_io_done() must be called once IO/ is done to signal completion. */ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize); int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize); // Invoked when received SCSI_CMD_INQUIRY, v1, application should use v2 if possible // Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]); // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uint32_t bufsize); // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun); // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size); /** * Invoked when received an SCSI command not in built-in list below. * - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE * - READ10 and WRITE10 has their own callbacks * * \param[in] lun Logical unit number * \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly * \param[out] buffer Buffer for SCSI Data Stage. * - For INPUT: application must fill this with response. * - For OUTPUT it holds the Data from host * \param[in] bufsize Buffer's length. * * \return Actual bytes processed, can be zero for no-data command. * \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding * endpoint and return failed status in command status wrapper phase. */ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize); /*------------- Optional callbacks -------------*/ // Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation uint8_t tud_msc_get_maxlun_cb(void); // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); //Invoked when we receive the Prevent / Allow Medium Removal command bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control); // Invoked when received REQUEST_SENSE int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); // Invoked when Read10 command is complete void tud_msc_read10_complete_cb(uint8_t lun); // Invoke when Write10 command is complete, can be used to flush flash caching void tud_msc_write10_complete_cb(uint8_t lun); // Invoked when command in tud_msc_scsi_cb is complete void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]); // Invoked to check if device is writable as part of SCSI WRITE10 bool tud_msc_is_writable_cb(uint8_t lun); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void mscd_init (void); bool mscd_deinit (void); void mscd_reset (uint8_t rhport); uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request); bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif /* TUSB_MSC_DEVICE_H_ */ ================================================ FILE: src/class/msc/msc_host.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && CFG_TUH_MSC #include "host/usbh.h" #include "host/usbh_pvt.h" #include "msc_host.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUH_MSC_LOG_LEVEL #define CFG_TUH_MSC_LOG_LEVEL CFG_TUH_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MSC_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ enum { MSC_STAGE_IDLE = 0, MSC_STAGE_CMD, MSC_STAGE_DATA, MSC_STAGE_STATUS, }; typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; uint8_t max_lun; volatile bool configured; // Receive SET_CONFIGURE volatile bool mounted; // Enumeration is complete // SCSI command data uint8_t stage; void* buffer; tuh_msc_complete_cb_t complete_cb; uintptr_t complete_arg; struct { uint32_t block_size; uint32_t block_count; } capacity[CFG_TUH_MSC_MAXLUN]; } msch_interface_t; typedef struct { TUH_EPBUF_TYPE_DEF(msc_cbw_t, cbw); TUH_EPBUF_TYPE_DEF(msc_csw_t, csw); } msch_epbuf_t; static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX]; CFG_TUH_MEM_SECTION static msch_epbuf_t _msch_epbuf[CFG_TUH_DEVICE_MAX]; TU_ATTR_ALWAYS_INLINE static inline msch_interface_t* get_itf(uint8_t daddr) { return &_msch_itf[daddr - 1]; } TU_ATTR_ALWAYS_INLINE static inline msch_epbuf_t* get_epbuf(uint8_t daddr) { return &_msch_epbuf[daddr - 1]; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tuh_msc_mount_cb(uint8_t dev_addr) { (void) dev_addr; } TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; } //--------------------------------------------------------------------+ // PUBLIC API //--------------------------------------------------------------------+ uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->max_lun; } uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_count; } uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_size; } bool tuh_msc_mounted(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->mounted; } bool tuh_msc_ready(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); const bool epin_busy = usbh_edpt_busy(dev_addr, p_msc->ep_in); const bool epout_busy = usbh_edpt_busy(dev_addr, p_msc->ep_out); return !epin_busy && !epout_busy; } //--------------------------------------------------------------------+ // PUBLIC API: SCSI COMMAND //--------------------------------------------------------------------+ static inline void cbw_init(msc_cbw_t* cbw, uint8_t lun) { tu_memclr(cbw, sizeof(msc_cbw_t)); cbw->signature = MSC_CBW_SIGNATURE; cbw->tag = 0x54555342; // TUSB cbw->lun = lun; } bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(daddr); TU_VERIFY(p_msc->configured); // claim endpoint TU_VERIFY(usbh_edpt_claim(daddr, p_msc->ep_out)); msch_epbuf_t* epbuf = get_epbuf(daddr); epbuf->cbw = *cbw; p_msc->buffer = data; p_msc->complete_cb = complete_cb; p_msc->complete_arg = arg; p_msc->stage = MSC_STAGE_CMD; if (!usbh_edpt_xfer(daddr, p_msc->ep_out, (uint8_t*) &epbuf->cbw, sizeof(msc_cbw_t))) { (void) usbh_edpt_release(daddr, p_msc->ep_out); return false; } return true; } bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured); msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t); cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_read_capacity10_t); cbw.command[0] = SCSI_CMD_READ_CAPACITY_10; return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = sizeof(scsi_inquiry_resp_t); cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_inquiry_t); scsi_inquiry_t const cmd_inquiry = { .cmd_code = SCSI_CMD_INQUIRY, .alloc_length = sizeof(scsi_inquiry_resp_t) }; memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured); msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = 0; cbw.dir = TUSB_DIR_OUT; cbw.cmd_len = sizeof(scsi_test_unit_ready_t); cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; cbw.command[1] = lun; // according to wiki TODO need verification return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb, arg); } bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = 18; // TODO sense response cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_request_sense_t); scsi_request_sense_t const cmd_request_sense = { .cmd_code = SCSI_CMD_REQUEST_SENSE, .alloc_length = 18 }; memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void* buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_read10_t); scsi_read10_t const cmd_read10 = { .cmd_code = SCSI_CMD_READ_10, .lba = tu_htonl(lba), .block_count = tu_htons(block_count) }; memcpy(cbw.command, &cmd_read10, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg); } bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const* buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; cbw.dir = TUSB_DIR_OUT; cbw.cmd_len = sizeof(scsi_write10_t); scsi_write10_t const cmd_write10 = { .cmd_code = SCSI_CMD_WRITE_10, .lba = tu_htonl(lba), .block_count = tu_htons(block_count) }; memcpy(cbw.command, &cmd_write10, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, (void*) (uintptr_t) buffer, complete_cb, arg); } #if 0 // MSC interface Reset (not used now) bool tuh_msc_reset(uint8_t dev_addr) { tusb_control_request_t const new_request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = MSC_REQ_RESET, .wValue = 0, .wIndex = p_msc->itf_num, .wLength = 0 }; TU_ASSERT( usbh_control_xfer( dev_addr, &new_request, NULL ) ); } #endif //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ bool msch_init(void) { TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t)); TU_LOG_DRV("sizeof(msch_epbuf_t) = %u\r\n", sizeof(msch_epbuf_t)); tu_memclr(_msch_itf, sizeof(_msch_itf)); return true; } bool msch_deinit(void) { return true; } void msch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured,); TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr); // invoke Application Callback if (p_msc->mounted) { tuh_msc_umount_cb(dev_addr); } tu_memclr(p_msc, sizeof(msch_interface_t)); } bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { msch_interface_t* p_msc = get_itf(dev_addr); msch_epbuf_t* epbuf = get_epbuf(dev_addr); msc_cbw_t const * cbw = &epbuf->cbw; msc_csw_t * csw = &epbuf->csw; switch (p_msc->stage) { case MSC_STAGE_CMD: // Must be Command Block TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); if (cbw->total_bytes && p_msc->buffer) { // Data stage if any p_msc->stage = MSC_STAGE_DATA; uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes)); break; } TU_ATTR_FALLTHROUGH; // fallthrough to data stage case MSC_STAGE_DATA: // Status stage p_msc->stage = MSC_STAGE_STATUS; TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) csw, (uint16_t) sizeof(msc_csw_t))); break; case MSC_STAGE_STATUS: // SCSI op is complete p_msc->stage = MSC_STAGE_IDLE; if (p_msc->complete_cb != NULL) { tuh_msc_complete_data_t const cb_data = { .cbw = cbw, .csw = csw, .scsi_data = p_msc->buffer, .user_arg = p_msc->complete_arg }; (void) p_msc->complete_cb(dev_addr, &cb_data); } break; default: // unknown state break; } return true; } //--------------------------------------------------------------------+ // MSC Enumeration //--------------------------------------------------------------------+ static void config_get_maxlun_complete(tuh_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { (void) rhport; TU_VERIFY(MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol, 0); // msc driver length is fixed const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len, 0); msch_interface_t *p_msc = get_itf(dev_addr); const tusb_desc_endpoint_t *ep_desc = (const tusb_desc_endpoint_t *)tu_desc_next(desc_itf); for (uint32_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc), 0); if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) { p_msc->ep_in = ep_desc->bEndpointAddress; } else { p_msc->ep_out = ep_desc->bEndpointAddress; } ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(ep_desc); } p_msc->itf_num = desc_itf->bInterfaceNumber; return drv_len; } bool msch_set_config(uint8_t daddr, uint8_t itf_num) { msch_interface_t* p_msc = get_itf(daddr); TU_ASSERT(p_msc->itf_num == itf_num); p_msc->configured = true; //------------- Get Max Lun -------------// TU_LOG_DRV("MSC Get Max Lun\r\n"); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = MSC_REQ_GET_MAX_LUN, .wValue = 0, .wIndex = itf_num, .wLength = 1 }; uint8_t* enum_buf = usbh_get_enum_buf(); tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = enum_buf, .complete_cb = config_get_maxlun_complete, .user_data = 0 }; TU_ASSERT(tuh_control_xfer(&xfer)); return true; } static void config_get_maxlun_complete(tuh_xfer_t* xfer) { uint8_t const daddr = xfer->daddr; msch_interface_t* p_msc = get_itf(daddr); // MAXLUN's response is minus 1 by specs, STALL means 1 if (XFER_RESULT_SUCCESS == xfer->result) { uint8_t* enum_buf = usbh_get_enum_buf(); p_msc->max_lun = enum_buf[0] + 1; } else { p_msc->max_lun = 1; } TU_LOG_DRV(" Max LUN = %u\r\n", p_msc->max_lun); // TODO multiple LUN support TU_LOG_DRV("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0); } static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; uint8_t* enum_buf = usbh_get_enum_buf(); if (csw->status == 0) { // Unit is ready, read its capacity TU_LOG_DRV("SCSI Read Capacity\r\n"); tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) (uintptr_t) enum_buf, config_read_capacity_complete, 0); } else { // Note: During enumeration, some device fails Test Unit Ready and require a few retries // with Request Sense to start working !! // TODO limit number of retries TU_LOG_DRV("SCSI Request Sense\r\n"); TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, enum_buf, config_request_sense_complete, 0)); } return true; } static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; TU_ASSERT(csw->status == 0); TU_ASSERT(tuh_msc_test_unit_ready(dev_addr, cbw->lun, config_test_unit_ready_complete, 0)); return true; } static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; TU_ASSERT(csw->status == 0); msch_interface_t* p_msc = get_itf(dev_addr); uint8_t* enum_buf = usbh_get_enum_buf(); // Capacity response field: Block size and Last LBA are both Big-Endian scsi_read_capacity10_resp_t* resp = (scsi_read_capacity10_resp_t*) (uintptr_t) enum_buf; p_msc->capacity[cbw->lun].block_count = (uint32_t) (tu_ntohl(resp->last_lba) + 1u); p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size); // Mark enumeration is complete p_msc->mounted = true; tuh_msc_mount_cb(dev_addr); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(dev_addr, p_msc->itf_num); return true; } #endif ================================================ FILE: src/class/msc/msc_host.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MSC_HOST_H_ #define TUSB_MSC_HOST_H_ #include "msc.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MSC_MAXLUN #define CFG_TUH_MSC_MAXLUN 4 #endif typedef struct { const msc_cbw_t *cbw; // SCSI command const msc_csw_t *csw; // SCSI status void *scsi_data; // SCSI Data uintptr_t user_arg; // user argument } tuh_msc_complete_data_t; typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, const tuh_msc_complete_data_t *cb_data); //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Check if device supports MassStorage interface. // This function true after tuh_msc_mounted_cb() and false after tuh_msc_unmounted_cb() bool tuh_msc_mounted(uint8_t dev_addr); // Check if the interface is currently ready or busy transferring data bool tuh_msc_ready(uint8_t dev_addr); // Get Max Lun uint8_t tuh_msc_get_maxlun(uint8_t dev_addr); // Get number of block uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun); // Get block size in bytes uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun); // Perform a full SCSI command (cbw, data, csw) in non-blocking manner. // Complete callback is invoked when SCSI op is complete. // return true if success, false if there is already pending operation. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_scsi_command(uint8_t daddr, const msc_cbw_t *cbw, void *data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Inquiry command // Complete callback is invoked when SCSI op is complete. // NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Test Unit Ready command // Complete callback is invoked when SCSI op is complete. bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Request Sense 10 command // Complete callback is invoked when SCSI op is complete. // NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer // Complete callback is invoked when SCSI op is complete. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void *buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Write 10 command. Write n blocks starting from LBA to device // Complete callback is invoked when SCSI op is complete. // NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, const void *buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Read Capacity 10 command // Complete callback is invoked when SCSI op is complete. // Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by // simply call tuh_msc_get_block_count() and tuh_msc_get_block_size() bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); //------------- Application Callback -------------// // Invoked when a device with MassStorage interface is mounted void tuh_msc_mount_cb(uint8_t dev_addr); // Invoked when a device with MassStorage interface is unmounted void tuh_msc_umount_cb(uint8_t dev_addr); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ bool msch_init(void); bool msch_deinit(void); uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len); bool msch_set_config(uint8_t daddr, uint8_t itf_num); void msch_close(uint8_t dev_addr); bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/mtp/mtp.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MTP_H_ #define TUSB_MTP_H_ #include "common/tusb_common.h" #if (CFG_TUD_ENABLED && CFG_TUD_MTP) #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Media Transfer Protocol Class Constant //--------------------------------------------------------------------+ // Media Transfer Protocol Subclass typedef enum { MTP_SUBCLASS_STILL_IMAGE = 1 } mtp_subclass_type_t; // MTP Protocol. typedef enum { MTP_PROTOCOL_PIMA_15470 = 1, ///< Picture Transfer Protocol (PIMA 15470) } mtp_protocol_type_t; // PTP/MTP protocol phases typedef enum { MTP_PHASE_COMMAND = 0, MTP_PHASE_DATA, MTP_PHASE_RESPONSE, MTP_PHASE_ERROR } mtp_phase_type_t; // PTP/MTP Class requests, PIMA 15740-2000: D.5.2 typedef enum { MTP_REQ_CANCEL = 0x64, MTP_REQ_GET_EXT_EVENT_DATA = 0x65, MTP_REQ_RESET = 0x66, MTP_REQ_GET_DEVICE_STATUS = 0x67, } mtp_class_request_t; // PTP/MTP Container type typedef enum { MTP_CONTAINER_TYPE_UNDEFINED = 0, MTP_CONTAINER_TYPE_COMMAND_BLOCK = 1, MTP_CONTAINER_TYPE_DATA_BLOCK = 2, MTP_CONTAINER_TYPE_RESPONSE_BLOCK = 3, MTP_CONTAINER_TYPE_EVENT_BLOCK = 4, } mtp_container_type_t; // MTP 1.1 Appendix A: Object formats typedef enum { // ---- Base formats ---- MTP_OBJ_FORMAT_UNDEFINED = 0x3000u, // Undefined object MTP_OBJ_FORMAT_ASSOCIATION = 0x3001u, // Association (for example, a folder) MTP_OBJ_FORMAT_SCRIPT = 0x3002u, // Device model-specific script MTP_OBJ_FORMAT_EXECUTABLE = 0x3003u, // Device model-specific binary executable MTP_OBJ_FORMAT_TEXT = 0x3004u, // Text file MTP_OBJ_FORMAT_HTML = 0x3005u, // Hypertext Markup Language file (text) MTP_OBJ_FORMAT_DPOF = 0x3006u, // Digital Print Order Format file (text) MTP_OBJ_FORMAT_AIFF = 0x3007u, // Audio clip (AIFF) MTP_OBJ_FORMAT_WAV = 0x3008u, // Audio clip (WAV) MTP_OBJ_FORMAT_MP3 = 0x3009u, // MPEG-1 Layer III audio (ISO/IEC 13818-3) MTP_OBJ_FORMAT_AVI = 0x300Au, // Video clip (AVI) MTP_OBJ_FORMAT_MPEG = 0x300Bu, // Video clip (MPEG) MTP_OBJ_FORMAT_ASF = 0x300Cu, // Microsoft Advanced Streaming Format (video) // ---- Image formats ---- MTP_OBJ_FORMAT_UNDEFINED_IMAGE = 0x3800u, // Undefined image object MTP_OBJ_FORMAT_EXIF_JPEG = 0x3801u, // Exchangeable Image Format, JEIDA standard MTP_OBJ_FORMAT_TIFF_EP = 0x3802u, // Tag Image File Format for Electronic Photography MTP_OBJ_FORMAT_FLASHPIX = 0x3803u, // Structured Storage Image Format (FlashPix) MTP_OBJ_FORMAT_BMP = 0x3804u, // Microsoft Windows Bitmap file MTP_OBJ_FORMAT_CIFF = 0x3805u, // Canon Camera Image File Format MTP_OBJ_FORMAT_UNDEFINED_3806 = 0x3806u, // Reserved / Undefined MTP_OBJ_FORMAT_GIF = 0x3807u, // Graphics Interchange Format MTP_OBJ_FORMAT_JFIF = 0x3808u, // JPEG File Interchange Format MTP_OBJ_FORMAT_CD = 0x3809u, // PhotoCD Image Pac MTP_OBJ_FORMAT_PICT = 0x380Au, // Quickdraw Image Format MTP_OBJ_FORMAT_PNG = 0x380Bu, // Portable Network Graphics MTP_OBJ_FORMAT_UNDEFINED_380C = 0x380Cu, // Reserved / Undefined MTP_OBJ_FORMAT_TIFF = 0x380Du, // Tag Image File Format (baseline) MTP_OBJ_FORMAT_TIFF_IT = 0x380Eu, // Tag Image File Format for IT (graphic arts) MTP_OBJ_FORMAT_JP2 = 0x380Fu, // JPEG2000 Baseline File Format MTP_OBJ_FORMAT_JPX = 0x3810u, // JPEG2000 Extended File Format // ---- Firmware & misc ---- MTP_OBJ_FORMAT_UNDEFINED_FIRMWARE = 0xB802u, // Undefined Firmware MTP_OBJ_FORMAT_WBMP = 0xB803u, // Wireless Application Protocol Bitmap Format (.wbmp) MTP_OBJ_FORMAT_WINDOWS_IMAGE = 0xB881u, // Windows Image Format MTP_OBJ_FORMAT_JPEGXR = 0xB804u, // JPEG XR (.hdp, .jxr, .wdp) // ---- Audio formats ---- MTP_OBJ_FORMAT_UNDEFINED_AUDIO = 0xB900u, // Undefined audio object MTP_OBJ_FORMAT_WMA = 0xB901u, // Windows Media Audio MTP_OBJ_FORMAT_OGG = 0xB902u, // OGG container MTP_OBJ_FORMAT_AAC = 0xB903u, // Advanced Audio Coding (.aac) MTP_OBJ_FORMAT_AUDIBLE = 0xB904u, // Audible format MTP_OBJ_FORMAT_FLAC = 0xB906u, // Free Lossless Audio Codec MTP_OBJ_FORMAT_QCELP = 0xB907u, // Qualcomm Code Excited Linear Prediction (.qcp) MTP_OBJ_FORMAT_AMR = 0xB908u, // Adaptive Multi-Rate audio (.amr) // ---- Video formats ---- MTP_OBJ_FORMAT_UNDEFINED_VIDEO = 0xB980u, // Undefined video object MTP_OBJ_FORMAT_WMV = 0xB981u, // Windows Media Video MTP_OBJ_FORMAT_MP4 = 0xB982u, // MP4 Container (ISO 14496-1) MTP_OBJ_FORMAT_MP2 = 0xB983u, // MPEG-1 Layer II audio MTP_OBJ_FORMAT_3GP = 0xB984u, // 3GP Container MTP_OBJ_FORMAT_3G2 = 0xB985u, // 3GPP2 Container MTP_OBJ_FORMAT_AVCHD = 0xB986u, // AVCHD (MPEG-4 AVC + Dolby Digital) MTP_OBJ_FORMAT_ATSC_TS = 0xB987u, // ATSC-compliant MPEG-2 Transport Stream MTP_OBJ_FORMAT_DVB_TS = 0xB988u, // DVB-compliant MPEG-2 Transport Stream // ---- Collections ---- MTP_OBJ_FORMAT_UNDEFINED_COLLECTION = 0xBA00u, // Undefined collection MTP_OBJ_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM = 0xBA01u, // Abstract Multimedia Album MTP_OBJ_FORMAT_ABSTRACT_IMAGE_ALBUM = 0xBA02u, // Abstract Image Album MTP_OBJ_FORMAT_ABSTRACT_AUDIO_ALBUM = 0xBA03u, // Abstract Audio Album MTP_OBJ_FORMAT_ABSTRACT_VIDEO_ALBUM = 0xBA04u, // Abstract Video Album MTP_OBJ_FORMAT_ABSTRACT_AV_PLAYLIST = 0xBA05u, // Abstract Audio & Video Playlist MTP_OBJ_FORMAT_ABSTRACT_CONTACT_GROUP = 0xBA06u, // Abstract Contact Group MTP_OBJ_FORMAT_ABSTRACT_MESSAGE_FOLDER = 0xBA07u, // Abstract Message Folder MTP_OBJ_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION = 0xBA08u, // Abstract Chaptered Production MTP_OBJ_FORMAT_ABSTRACT_AUDIO_PLAYLIST = 0xBA09u, // Abstract Audio Playlist MTP_OBJ_FORMAT_ABSTRACT_VIDEO_PLAYLIST = 0xBA0Au, // Abstract Video Playlist MTP_OBJ_FORMAT_ABSTRACT_MEDIACAST = 0xBA0Bu, // Abstract Mediacast (RSS enclosure) // ---- Playlist formats ---- MTP_OBJ_FORMAT_WPL_PLAYLIST = 0xBA10u, // Windows Media Player Playlist (.wpl) MTP_OBJ_FORMAT_M3U_PLAYLIST = 0xBA11u, // M3U Playlist MTP_OBJ_FORMAT_MPL_PLAYLIST = 0xBA12u, // MPL Playlist MTP_OBJ_FORMAT_ASX_PLAYLIST = 0xBA13u, // ASX Playlist MTP_OBJ_FORMAT_PLS_PLAYLIST = 0xBA14u, // PLS Playlist // ---- Document formats ---- MTP_OBJ_FORMAT_UNDEFINED_DOC = 0xBA80u, // Undefined Document MTP_OBJ_FORMAT_ABSTRACT_DOC = 0xBA81u, // Abstract Document MTP_OBJ_FORMAT_XML_DOC = 0xBA82u, // XML Document MTP_OBJ_FORMAT_DOC = 0xBA83u, // Microsoft Word Document MTP_OBJ_FORMAT_MHT_DOC = 0xBA84u, // MHT Compiled HTML Document MTP_OBJ_FORMAT_XLS = 0xBA85u, // Microsoft Excel Spreadsheet MTP_OBJ_FORMAT_PPT = 0xBA86u, // Microsoft PowerPoint Presentation // ---- Messaging ---- MTP_OBJ_FORMAT_UNDEFINED_MSG = 0xBB00u, // Undefined Message MTP_OBJ_FORMAT_ABSTRACT_MSG = 0xBB01u, // Abstract Message // ---- Bookmarks ---- MTP_OBJ_FORMAT_UNDEFINED_BOOKMARK = 0xBB10u, // Undefined Bookmark MTP_OBJ_FORMAT_ABSTRACT_BOOKMARK = 0xBB11u, // Abstract Bookmark // ---- Appointments ---- MTP_OBJ_FORMAT_UNDEFINED_APPT = 0xBB20u, // Undefined Appointment MTP_OBJ_FORMAT_ABSTRACT_APPT = 0xBB21u, // Abstract Appointment MTP_OBJ_FORMAT_VCALENDAR1 = 0xBB22u, // vCalendar 1.0 // ---- Tasks ---- MTP_OBJ_FORMAT_UNDEFINED_TASK = 0xBB40u, // Undefined Task MTP_OBJ_FORMAT_ABSTRACT_TASK = 0xBB41u, // Abstract Task MTP_OBJ_FORMAT_ICALENDAR = 0xBB42u, // iCalendar // ---- Notes ---- MTP_OBJ_FORMAT_UNDEFINED_NOTE = 0xBB60u, // Undefined Note MTP_OBJ_FORMAT_ABSTRACT_NOTE = 0xBB61u, // Abstract Note // ---- Contacts ---- MTP_OBJ_FORMAT_UNDEFINED_CONTACT= 0xBB80u, // Undefined Contact MTP_OBJ_FORMAT_ABSTRACT_CONTACT = 0xBB81u, // Abstract Contact MTP_OBJ_FORMAT_VCARD2 = 0xBB82u, // vCard 2.1 MTP_OBJ_FORMAT_VCARD3 = 0xBB83u, // vCard 3.0 } mtp_object_formats_t; // MTP 1.1 Appendix B: Object Properties typedef enum { MTP_OBJ_PROP_STORAGE_ID = 0xDC01u, // StorageID MTP_OBJ_PROP_OBJECT_FORMAT = 0xDC02u, // Object Format MTP_OBJ_PROP_PROTECTION_STATUS = 0xDC03u, // Protection Status MTP_OBJ_PROP_OBJECT_SIZE = 0xDC04u, // Object Size MTP_OBJ_PROP_ASSOCIATION_TYPE = 0xDC05u, // Association Type MTP_OBJ_PROP_ASSOCIATION_DESC = 0xDC06u, // Association Description MTP_OBJ_PROP_OBJECT_FILE_NAME = 0xDC07u, // Object File Name MTP_OBJ_PROP_DATE_CREATED = 0xDC08u, // Date Created MTP_OBJ_PROP_DATE_MODIFIED = 0xDC09u, // Date Modified MTP_OBJ_PROP_KEYWORDS = 0xDC0Au, // Keywords MTP_OBJ_PROP_PARENT_OBJECT = 0xDC0Bu, // Parent Object MTP_OBJ_PROP_ALLOWED_FOLDER_CONTENTS = 0xDC0Cu, // Allowed Folder Contents MTP_OBJ_PROP_HIDDEN = 0xDC0Du, // Hidden MTP_OBJ_PROP_SYSTEM_OBJECT = 0xDC0Eu, // System Object // 0xDC0F-0xDC40 is reserved MTP_OBJ_PROP_PERSISTENT_UID = 0xDC41u, // Persistent Unique Object Identifier MTP_OBJ_PROP_SYNC_ID = 0xDC42u, // SyncID MTP_OBJ_PROP_PROPERTY_BAG = 0xDC43u, // Property Bag MTP_OBJ_PROP_NAME = 0xDC44u, // Name MTP_OBJ_PROP_CREATED_BY = 0xDC45u, // Created By MTP_OBJ_PROP_ARTIST = 0xDC46u, // Artist MTP_OBJ_PROP_DATE_AUTHORED = 0xDC47u, // Date Authored MTP_OBJ_PROP_DESCRIPTION = 0xDC48u, // Description MTP_OBJ_PROP_URL_REFERENCE = 0xDC49u, // URL Reference MTP_OBJ_PROP_LANGUAGE_LOCALE = 0xDC4Au, // Language-Locale MTP_OBJ_PROP_COPYRIGHT_INFO = 0xDC4Bu, // Copyright Information MTP_OBJ_PROP_SOURCE = 0xDC4Cu, // Source MTP_OBJ_PROP_ORIGIN_LOCATION = 0xDC4Du, // Origin Location MTP_OBJ_PROP_DATE_ADDED = 0xDC4Eu, // Date Added MTP_OBJ_PROP_NON_CONSUMABLE = 0xDC4Fu, // Non-Consumable MTP_OBJ_PROP_CORRUPT_UNPLAYABLE = 0xDC50u, // Corrupt/Unplayable MTP_OBJ_PROP_PRODUCER_SERIAL_NUMBER = 0xDC51u, // ProducerSerialNumber // 0xDC52-0xDC80 is reserved MTP_OBJ_PROP_REP_SAMPLE_FORMAT = 0xDC81u, // Representative Sample Format MTP_OBJ_PROP_REP_SAMPLE_SIZE = 0xDC82u, // Representative Sample Size MTP_OBJ_PROP_REP_SAMPLE_HEIGHT = 0xDC83u, // Representative Sample Height MTP_OBJ_PROP_REP_SAMPLE_WIDTH = 0xDC84u, // Representative Sample Width MTP_OBJ_PROP_REP_SAMPLE_DURATION = 0xDC85u, // Representative Sample Duration MTP_OBJ_PROP_REP_SAMPLE_DATA = 0xDC86u, // Representative Sample Data MTP_OBJ_PROP_WIDTH = 0xDC87u, // Width MTP_OBJ_PROP_HEIGHT = 0xDC88u, // Height MTP_OBJ_PROP_DURATION = 0xDC89u, // Duration MTP_OBJ_PROP_RATING = 0xDC8Au, // Rating MTP_OBJ_PROP_TRACK = 0xDC8Bu, // Track MTP_OBJ_PROP_GENRE = 0xDC8Cu, // Genre MTP_OBJ_PROP_CREDITS = 0xDC8Du, // Credits MTP_OBJ_PROP_LYRICS = 0xDC8Eu, // Lyrics MTP_OBJ_PROP_SUBSCRIPTION_CONTENT_ID = 0xDC8Fu, // Subscription Content ID MTP_OBJ_PROP_PRODUCED_BY = 0xDC90u, // Produced By MTP_OBJ_PROP_USE_COUNT = 0xDC91u, // Use Count MTP_OBJ_PROP_SKIP_COUNT = 0xDC92u, // Skip Count MTP_OBJ_PROP_LAST_ACCESSED = 0xDC93u, // Last Accessed MTP_OBJ_PROP_PARENTAL_RATING = 0xDC94u, // Parental Rating MTP_OBJ_PROP_META_GENRE = 0xDC95u, // Meta Genre MTP_OBJ_PROP_COMPOSER = 0xDC96u, // Composer MTP_OBJ_PROP_EFFECTIVE_RATING = 0xDC97u, // Effective Rating MTP_OBJ_PROP_SUBTITLE = 0xDC98u, // Subtitle MTP_OBJ_PROP_ORIGINAL_RELEASE_DATE = 0xDC99u, // Original Release Date MTP_OBJ_PROP_ALBUM_NAME = 0xDC9Au, // Album Name MTP_OBJ_PROP_ALBUM_ARTIST = 0xDC9Bu, // Album Artist MTP_OBJ_PROP_MOOD = 0xDC9Cu, // Mood MTP_OBJ_PROP_DRM_STATUS = 0xDC9Du, // DRM Status MTP_OBJ_PROP_SUB_DESCRIPTION = 0xDC9Eu, // Sub Description // 0xDC9F-0xDCD0 is reserved MTP_OBJ_PROP_IS_CROPPED = 0xDCD1u, // Is Cropped MTP_OBJ_PROP_IS_COLOUR_CORRECTED = 0xDCD2u, // Is Colour Corrected MTP_OBJ_PROP_IMAGE_BIT_DEPTH = 0xDCD3u, // Image Bit Depth MTP_OBJ_PROP_FNUMBER = 0xDCD4u, // Fnumber (aperture ×100) MTP_OBJ_PROP_EXPOSURE_TIME = 0xDCD5u, // Exposure Time (sec ×10,000) MTP_OBJ_PROP_EXPOSURE_INDEX = 0xDCD6u, // Exposure Index (ISO) // 0xDCD7-0xDCDF is reserved MTP_OBJ_PROP_DISPLAY_NAME = 0xDCE0u, // Display Name MTP_OBJ_PROP_BODY_TEXT = 0xDCE1u, // Body Text MTP_OBJ_PROP_SUBJECT = 0xDCE2u, // Subject MTP_OBJ_PROP_PRIORITY = 0xDCE3u, // Priority // 0xDCE4-0xDCFF is reserved MTP_OBJ_PROP_GIVEN_NAME = 0xDD00u, // Given Name MTP_OBJ_PROP_MIDDLE_NAMES = 0xDD01u, // Middle Names MTP_OBJ_PROP_FAMILY_NAME = 0xDD02u, // Family Name MTP_OBJ_PROP_PREFIX = 0xDD03u, // Prefix MTP_OBJ_PROP_SUFFIX = 0xDD04u, // Suffix MTP_OBJ_PROP_PHONETIC_GIVEN_NAME = 0xDD05u, // Phonetic Given Name MTP_OBJ_PROP_PHONETIC_FAMILY_NAME = 0xDD06u, // Phonetic Family Name MTP_OBJ_PROP_EMAIL_PRIMARY = 0xDD07u, // Email Primary MTP_OBJ_PROP_EMAIL_PERSONAL_1 = 0xDD08u, // Email Personal 1 MTP_OBJ_PROP_EMAIL_PERSONAL_2 = 0xDD09u, // Email Personal 2 MTP_OBJ_PROP_EMAIL_BUSINESS_1 = 0xDD0Au, // Email Business 1 MTP_OBJ_PROP_EMAIL_BUSINESS_2 = 0xDD0Bu, // Email Business 2 MTP_OBJ_PROP_EMAIL_OTHERS = 0xDD0Cu, // Email Others MTP_OBJ_PROP_PHONE_PRIMARY = 0xDD0Du, // Phone Number Primary MTP_OBJ_PROP_PHONE_PERSONAL_1 = 0xDD0Eu, // Phone Number Personal MTP_OBJ_PROP_PHONE_PERSONAL_2 = 0xDD0Fu, // Phone Number Personal 2 MTP_OBJ_PROP_PHONE_BUSINESS_1 = 0xDD10u, // Phone Number Business MTP_OBJ_PROP_PHONE_BUSINESS_2 = 0xDD11u, // Phone Number Business 2 MTP_OBJ_PROP_PHONE_MOBILE_1 = 0xDD12u, // Phone Number Mobile MTP_OBJ_PROP_PHONE_MOBILE_2 = 0xDD13u, // Phone Number Mobile 2 MTP_OBJ_PROP_FAX_PRIMARY = 0xDD14u, // Fax Number Primary MTP_OBJ_PROP_FAX_PERSONAL = 0xDD15u, // Fax Number Personal MTP_OBJ_PROP_FAX_BUSINESS = 0xDD16u, // Fax Number Business MTP_OBJ_PROP_PAGER_NUMBER = 0xDD17u, // Pager Number MTP_OBJ_PROP_PHONE_OTHERS = 0xDD18u, // Phone Number Others MTP_OBJ_PROP_WEB_PRIMARY = 0xDD19u, // Primary Web Address MTP_OBJ_PROP_WEB_PERSONAL = 0xDD1Au, // Personal Web Address MTP_OBJ_PROP_WEB_BUSINESS = 0xDD1Bu, // Business Web Address MTP_OBJ_PROP_IM_ADDRESS_1 = 0xDD1Cu, // Instant Messenger Address MTP_OBJ_PROP_IM_ADDRESS_2 = 0xDD1Du, // Instant Messenger Address 2 MTP_OBJ_PROP_IM_ADDRESS_3 = 0xDD1Eu, // Instant Messenger Address 3 MTP_OBJ_PROP_ADDR_PERSONAL_FULL = 0xDD1Fu, // Postal Address Personal Full MTP_OBJ_PROP_ADDR_PERSONAL_LINE1 = 0xDD20u, // Postal Address Personal Line 1 MTP_OBJ_PROP_ADDR_PERSONAL_LINE2 = 0xDD21u, // Postal Address Personal Line 2 MTP_OBJ_PROP_ADDR_PERSONAL_CITY = 0xDD22u, // Postal Address Personal City MTP_OBJ_PROP_ADDR_PERSONAL_REGION = 0xDD23u, // Postal Address Personal Region MTP_OBJ_PROP_ADDR_PERSONAL_POSTAL_CODE = 0xDD24u, // Postal Address Personal Postal Code MTP_OBJ_PROP_ADDR_PERSONAL_COUNTRY = 0xDD25u, // Postal Address Personal Country MTP_OBJ_PROP_ADDR_BUSINESS_FULL = 0xDD26u, // Postal Address Business Full MTP_OBJ_PROP_ADDR_BUSINESS_LINE1 = 0xDD27u, // Postal Address Business Line 1 MTP_OBJ_PROP_ADDR_BUSINESS_LINE2 = 0xDD28u, // Postal Address Business Line 2 MTP_OBJ_PROP_ADDR_BUSINESS_CITY = 0xDD29u, // Postal Address Business City MTP_OBJ_PROP_ADDR_BUSINESS_REGION = 0xDD2Au, // Postal Address Business Region MTP_OBJ_PROP_ADDR_BUSINESS_POSTAL_CODE = 0xDD2Bu, // Postal Address Business Postal Code MTP_OBJ_PROP_ADDR_BUSINESS_COUNTRY = 0xDD2Cu, // Postal Address Business Country MTP_OBJ_PROP_ADDR_OTHER_FULL = 0xDD2Du, // Postal Address Other Full MTP_OBJ_PROP_ADDR_OTHER_LINE1 = 0xDD2Eu, // Postal Address Other Line 1 MTP_OBJ_PROP_ADDR_OTHER_LINE2 = 0xDD2Fu, // Postal Address Other Line 2 MTP_OBJ_PROP_ADDR_OTHER_CITY = 0xDD30u, // Postal Address Other City MTP_OBJ_PROP_ADDR_OTHER_REGION = 0xDD31u, // Postal Address Other Region MTP_OBJ_PROP_ADDR_OTHER_POSTAL_CODE = 0xDD32u, // Postal Address Other Postal Code MTP_OBJ_PROP_ADDR_OTHER_COUNTRY = 0xDD33u, // Postal Address Other Country MTP_OBJ_PROP_ORGANIZATION_NAME = 0xDD34u, // Organization Name MTP_OBJ_PROP_PHONETIC_ORG_NAME = 0xDD35u, // Phonetic Organization Name MTP_OBJ_PROP_ROLE = 0xDD36u, // Role MTP_OBJ_PROP_BIRTHDATE = 0xDD37u, // Birthdate // 0xDD38-0xDD3F is reserved MTP_OBJ_PROP_MESSAGE_TO = 0xDD40u, // Message To MTP_OBJ_PROP_MESSAGE_CC = 0xDD41u, // Message CC MTP_OBJ_PROP_MESSAGE_BCC = 0xDD42u, // Message BCC MTP_OBJ_PROP_MESSAGE_READ = 0xDD43u, // Message Read MTP_OBJ_PROP_MESSAGE_RECEIVED_TIME = 0xDD44u, // Message Received Time MTP_OBJ_PROP_MESSAGE_SENDER = 0xDD45u, // Message Sender // 0xDD46-0xDD4F is reserved MTP_OBJ_PROP_ACTIVITY_BEGIN_TIME = 0xDD50u, // Activity Begin Time MTP_OBJ_PROP_ACTIVITY_END_TIME = 0xDD51u, // Activity End Time MTP_OBJ_PROP_ACTIVITY_LOCATION = 0xDD52u, // Activity Location // 0xDD53 is reserved MTP_OBJ_PROP_ACTIVITY_REQUIRED_ATTENDEES= 0xDD54u, // Activity Required Attendees MTP_OBJ_PROP_ACTIVITY_OPTIONAL_ATTENDEES= 0xDD55u, // Activity Optional Attendees MTP_OBJ_PROP_ACTIVITY_RESOURCES = 0xDD56u, // Activity Resources MTP_OBJ_PROP_ACTIVITY_ACCEPTED = 0xDD57u, // Activity Accepted MTP_OBJ_PROP_ACTIVITY_TENTATIVE = 0xDD58u, // Activity Tentative MTP_OBJ_PROP_ACTIVITY_DECLINED = 0xDD59u, // Activity Declined MTP_OBJ_PROP_ACTIVITY_REMINDER_TIME = 0xDD5Au, // Activity Reminder Time MTP_OBJ_PROP_ACTIVITY_OWNER = 0xDD5Bu, // Activity Owner MTP_OBJ_PROP_ACTIVITY_STATUS = 0xDD5Cu, // Activity Status MTP_OBJ_PROP_OWNER = 0xDD5Du, // Owner MTP_OBJ_PROP_EDITOR = 0xDD5Eu, // Editor MTP_OBJ_PROP_WEBMASTER = 0xDD5Fu, // Webmaster MTP_OBJ_PROP_URL_SOURCE = 0xDD60u, // URL Source MTP_OBJ_PROP_URL_DESTINATION = 0xDD61u, // URL Destination MTP_OBJ_PROP_TIME_BOOKMARK = 0xDD62u, // Time Bookmark MTP_OBJ_PROP_OBJECT_BOOKMARK = 0xDD63u, // Object Bookmark MTP_OBJ_PROP_BYTE_BOOKMARK = 0xDD64u, // Byte Bookmark // 0xDD65-0xDD6F is reserved MTP_OBJ_PROP_LAST_BUILD_DATE = 0xDD70u, // Last Build Date MTP_OBJ_PROP_TIME_TO_LIVE = 0xDD71u, // Time to Live (minutes) MTP_OBJ_PROP_MEDIA_GUID = 0xDD72u, // Media GUID // 0xDD73-0xDDFF is reserved // media encoding MTP_OBJ_PROP_TOTAL_BITRATE = 0xDE91u, // Total BitRate MTP_OBJ_PROP_BITRATE_TYPE = 0xDE92u, // Bitrate Type MTP_OBJ_PROP_SAMPLE_RATE = 0xDE93u, // Sample Rate MTP_OBJ_PROP_NUM_CHANNELS = 0xDE94u, // Number Of Channels MTP_OBJ_PROP_AUDIO_BITDEPTH = 0xDE95u, // Audio BitDepth // 0xDE96 is reserved MTP_OBJ_PROP_SCAN_TYPE = 0xDE97u, // Scan Type // 0xDE98 is reserved MTP_OBJ_PROP_AUDIO_WAVE_CODEC = 0xDE99u, // Audio WAVE Codec MTP_OBJ_PROP_AUDIO_BITRATE = 0xDE9Au, // Audio BitRate MTP_OBJ_PROP_VIDEO_FOURCC_CODEC = 0xDE9Bu, // Video FourCC Codec MTP_OBJ_PROP_VIDEO_BITRATE = 0xDE9Cu, // Video BitRate MTP_OBJ_PROP_FRAMES_PER_KSEC = 0xDE9Du, // Frames Per Thousand Seconds MTP_OBJ_PROP_KEYFRAME_DISTANCE = 0xDE9Eu, // KeyFrame Distance (ms) MTP_OBJ_PROP_BUFFER_SIZE = 0xDE9Fu, // Buffer Size MTP_OBJ_PROP_ENCODING_QUALITY = 0xDEA0u, // Encoding Quality MTP_OBJ_PROP_ENCODING_PROFILE = 0xDEA1u // Encoding Profile } mtp_object_properties_t; // MTP 1.1 Appendeix C: Device Properties typedef enum { MTP_DEV_PROP_UNDEFINED = 0x5000u, MTP_DEV_PROP_BATTERY_LEVEL = 0x5001u, MTP_DEV_PROP_FUNCTIONAL_MODE = 0x5002u, MTP_DEV_PROP_IMAGE_SIZE = 0x5003u, MTP_DEV_PROP_COMPRESSION_SETTING = 0x5004u, MTP_DEV_PROP_WHITE_BALANCE = 0x5005u, MTP_DEV_PROP_RGB_GAIN = 0x5006u, MTP_DEV_PROP_F_NUMBER = 0x5007u, MTP_DEV_PROP_FOCAL_LENGTH = 0x5008u, MTP_DEV_PROP_FOCUS_DISTANCE = 0x5009u, MTP_DEV_PROP_FOCUS_MODE = 0x500Au, MTP_DEV_PROP_EXPOSURE_METERING_MODE = 0x500Bu, MTP_DEV_PROP_FLASH_MODE = 0x500Cu, MTP_DEV_PROP_EXPOSURE_TIME = 0x500Du, MTP_DEV_PROP_EXPOSURE_PROGRAM_MODE = 0x500Eu, MTP_DEV_PROP_EXPOSURE_INDEX = 0x500Fu, MTP_DEV_PROP_EXPOSURE_BIAS_COMPENSATION = 0x5010u, MTP_DEV_PROP_DATE_TIME = 0x5011u, MTP_DEV_PROP_CAPTURE_DELAY = 0x5012u, MTP_DEV_PROP_STILL_CAPTURE_MODE = 0x5013u, MTP_DEV_PROP_CONTRAST = 0x5014u, MTP_DEV_PROP_SHARPNESS = 0x5015u, MTP_DEV_PROP_DIGITAL_ZOOM = 0x5016u, MTP_DEV_PROP_EFFECT_MODE = 0x5017u, MTP_DEV_PROP_BURST_NUMBER = 0x5018u, MTP_DEV_PROP_BURST_INTERVAL = 0x5019u, MTP_DEV_PROP_TIMELAPSE_NUMBER = 0x501Au, MTP_DEV_PROP_TIMELAPSE_INTERVAL = 0x501Bu, MTP_DEV_PROP_FOCUS_METERING_MODE = 0x501Cu, MTP_DEV_PROP_UPLOAD_URL = 0x501Du, MTP_DEV_PROP_ARTIST = 0x501Eu, MTP_DEV_PROP_COPYRIGHT_INFO = 0x501Fu, MTP_DEV_PROP_SYNCHRONIZTION_PARTNER = 0xD401, MTP_DEV_PROP_DEVICE_FRIENDLY_NAME = 0xD402u, MTP_DEV_PROP_VOLUME = 0xD403u, MTP_DEV_PROP_SUPPORTED_FORMATS_ORDERED = 0xD404u, MTP_DEV_PROP_DEVICE_ICON = 0xD405u, MTP_DEV_PROP_SECTION_INITIATOR_VERSION_INFO = 0xD406u, MTP_DEV_PROP_PERCEIVED_DEVICE_TYPE = 0xD407u, MTP_DEV_PROP_PLAYBACK_RATE = 0xD410u, MTP_DEV_PROP_PLAYBACK_OBJECT = 0xD411u, MTP_DEV_PROP_PLAYBACK_CONTAINER_INDEX = 0xD412u, } mtp_event_properties_t; // MTP 1.1 Appendix D: Operations typedef enum { MTP_OP_UNDEFINED = 0x1000u, MTP_OP_GET_DEVICE_INFO = 0x1001u, MTP_OP_OPEN_SESSION = 0x1002u, MTP_OP_CLOSE_SESSION = 0x1003u, MTP_OP_GET_STORAGE_IDS = 0x1004u, MTP_OP_GET_STORAGE_INFO = 0x1005u, MTP_OP_GET_NUM_OBJECTS = 0x1006u, MTP_OP_GET_OBJECT_HANDLES = 0x1007u, MTP_OP_GET_OBJECT_INFO = 0x1008u, MTP_OP_GET_OBJECT = 0x1009u, MTP_OP_GET_THUMB = 0x100Au, MTP_OP_DELETE_OBJECT = 0x100Bu, MTP_OP_SEND_OBJECT_INFO = 0x100Cu, MTP_OP_SEND_OBJECT = 0x100Du, MTP_OP_INITIATE_CAPTURE = 0x100Eu, MTP_OP_FORMAT_STORE = 0x100Fu, MTP_OP_RESET_DEVICE = 0x1010u, MTP_OP_SELF_TEST = 0x1011u, MTP_OP_SET_OBJECT_PROTECTION = 0x1012u, MTP_OP_POWER_DOWN = 0x1013u, MTP_OP_GET_DEVICE_PROP_DESC = 0x1014u, MTP_OP_GET_DEVICE_PROP_VALUE = 0x1015u, MTP_OP_SET_DEVICE_PROP_VALUE = 0x1016u, MTP_OP_RESET_DEVICE_PROP_VALUE = 0x1017u, MTP_OP_TERMINATE_OPEN_CAPTURE = 0x1018u, MTP_OP_MOVE_OBJECT = 0x1019u, MTP_OP_COPY_OBJECT = 0x101Au, MTP_OP_GET_PARTIAL_OBJECT = 0x101Bu, MTP_OP_INITIATE_OPEN_CAPTURE = 0x101Bu, MTP_OP_GET_OBJECT_PROPS_SUPPORTED = 0x9801u, MTP_OP_GET_OBJECT_PROP_DESC = 0x9802u, MTP_OP_GET_OBJECT_PROP_VALUE = 0x9803u, MTP_OP_SET_OBJECT_PROP_VALUE = 0x9804u, MTP_OP_GET_OBJECT_PROPLIST = 0x9805u, MTP_OP_GET_OBJECT_PROP_REFERENCES = 0x9810u, MTP_OP_GET_SERVICE_IDS = 0x9301u, MTP_OP_GET_SERVICE_INFO = 0x9302u, MTP_OP_GET_SERVICE_CAPABILITIES = 0x9303u, MTP_OP_GET_SERVICE_PROP_DESC = 0x9304u, // Appendix E: Enhanced Operations MTP_OP_GET_OBJECT_PROP_LIST = 0x9805u, MTP_OP_SET_OBJECT_PROP_LIST = 0x9806u, MTP_OP_GET_INTERDEPENDENT_PROP_DESC = 0x9807u, MTP_OP_SEND_OBJECT_PROP_LIST = 0x9808u, } mtp_operation_code_t; // Appendix F: Responses typedef enum { MTP_RESP_UNDEFINED = 0x2000u, MTP_RESP_OK = 0x2001u, MTP_RESP_GENERAL_ERROR = 0x2002u, MTP_RESP_SESSION_NOT_OPEN = 0x2003u, MTP_RESP_INVALID_TRANSACTION_ID = 0x2004u, MTP_RESP_OPERATION_NOT_SUPPORTED = 0x2005u, MTP_RESP_PARAMETER_NOT_SUPPORTED = 0x2006u, MTP_RESP_INCOMPLETE_TRANSFER = 0x2007u, MTP_RESP_INVALID_STORAGE_ID = 0x2008u, MTP_RESP_INVALID_OBJECT_HANDLE = 0x2009u, MTP_RESP_DEVICE_PROP_NOT_SUPPORTED = 0x200Au, MTP_RESP_INVALID_OBJECT_FORMAT_CODE = 0x200Bu, MTP_RESP_STORE_FULL = 0x200Cu, MTP_RESP_OBJECT_WRITE_PROTECTED = 0x200Du, MPT_RESC_STORE_READ_ONLY = 0x200Eu, MTP_RESP_ACCESS_DENIED = 0x200Fu, MTP_RESP_NO_THUMBNAIL_PRESENT = 0x2010u, MTP_RESP_SELF_TEST_FAILED = 0x2011u, MTP_RESP_PARTIAL_DELETION = 0x2012u, MTP_RESP_STORE_NOT_AVAILABLE = 0x2013u, MTP_RESP_SPECIFICATION_BY_FORMAT_UNSUPPORTED = 0x2014u, MTP_RESP_NO_VALID_OBJECTINFO = 0x2015u, MTP_RESP_INVALID_CODE_FORMAT = 0x2016u, MTP_RESP_UNKNOWN_VENDOR_CODE = 0x2017u, MTP_RESP_CAPTURE_ALREADY_TERMINATED = 0x2018u, MTP_RESP_DEVICE_BUSY = 0x2019u, MTP_RESP_INVALID_PARENT_OBJECT = 0x201Au, MTP_RESP_INVALID_DEVICE_PROP_FORMAT = 0x201Bu, MTP_RESP_INVALID_DEVICE_PROP_VALUE = 0x201Cu, MTP_RESP_INVALID_PARAMETER = 0x201Du, MTP_RESP_SESSION_ALREADY_OPEN = 0x201Eu, MTP_RESP_TRANSACTION_CANCELLED = 0x201Fu, MTP_RESP_SPEC_OF_DESTINATION_UNSUPPORTED = 0x2020u, MTP_RESP_INVALID_OBJECT_PROP_CODE = 0xA801u, MTP_RESP_INVALID_OBJECT_PROP_FORMAT = 0xA802u, MTP_RESP_INVALID_OBJECT_PROP_VALUE = 0xA803u, MTP_RESP_INVALID_OBJECT_REFERENCE = 0xA804u, MTP_RESP_GROUP_NOT_SUPPORTED = 0xA805u, MTP_RESP_INVALID_DATASET = 0xA806u, MTP_RESP_SPEC_BY_GROUP_UNSUPPORTED = 0xA807u, MTP_RESP_SPEC_BY_DEPTH_UNSUPPORTED = 0xA808u, MTP_RESP_OBJECT_TOO_LARGE = 0xA809u, MTP_RESP_OBJECT_PROP_NOT_SUPPORTED = 0xA80Au, } mtp_response_t; // Appendix G: Events typedef enum { MTP_EVENT_UNDEFINED = 0x4000, MTP_EVENT_CANCEL_TRANSACTION = 0x4001, MTP_EVENT_OBJECT_ADDED = 0x4002, MTP_EVENT_OBJECT_REMOVED = 0x4003, MTP_EVENT_STORE_ADDED = 0x4004, MTP_EVENT_STORE_REMOVED = 0x4005, MTP_EVENT_DEVICE_PROP_CHANGED = 0x4006, MTP_EVENT_OBJECT_INFO_CHANGED = 0x4007, MTP_EVENT_DEVICE_INFO_CHANGED = 0x4008, MTP_EVENT_REQUEST_OBJECT_TRANSFER = 0x4009, MTP_EVENT_STORE_FULL = 0x400Au, MTP_EVENT_DEVICE_RESET = 0x400Bu, MTP_EVENT_STORAGE_INFO_CHANGED = 0x400Cu, MTP_EVENT_CAPTURE_COMPLETE = 0x400Du, MTP_EVENT_UNREPORTED_STATUS = 0x400Eu, MTP_EVENT_OBJECT_PROP_CHANGED = 0xC801u, MTP_EVENT_OBJECT_PROP_DESC_CHANGED = 0xC802u, MTP_EVENT_OBJECT_REFERENCES_CHANGED = 0xC803u, } mtp_event_code_t; // Datatypes typedef enum { MTP_DATA_TYPE_UNDEFINED = 0x0000u, // scalars MTP_DATA_TYPE_INT8 = 0x0001u, MTP_DATA_TYPE_UINT8 = 0x0002u, MTP_DATA_TYPE_INT16 = 0x0003u, MTP_DATA_TYPE_UINT16 = 0x0004u, MTP_DATA_TYPE_INT32 = 0x0005u, MTP_DATA_TYPE_UINT32 = 0x0006u, MTP_DATA_TYPE_INT64 = 0x0007u, MTP_DATA_TYPE_UINT64 = 0x0008u, MTP_DATA_TYPE_INT128 = 0x0009u, MTP_DATA_TYPE_UINT128 = 0x000Au, // array MTP_DATA_TYPE_AINT8 = 0x4001u, MTP_DATA_TYPE_AUINT8 = 0x4002u, MTP_DATA_TYPE_AINT16 = 0x4003u, MTP_DATA_TYPE_AUINT16 = 0x4004u, MTP_DATA_TYPE_AINT32 = 0x4005u, MTP_DATA_TYPE_AUINT32 = 0x4006u, MTP_DATA_TYPE_AINT64 = 0x4007u, MTP_DATA_TYPE_AUINT64 = 0x4008u, MTP_DATA_TYPE_AINT128 = 0x4009u, MTP_DATA_TYPE_AUINT128 = 0x400Au, MTP_DATA_TYPE_STR = 0xFFFFu, } mtp_data_type_t; // Get/Set typedef enum { MTP_MODE_GET = 0x00u, MTP_MODE_GET_SET = 0x01u, } mtp_mode_get_set_t; typedef enum { MTP_STORAGE_TYPE_UNDEFINED = 0x0000u, MTP_STORAGE_TYPE_FIXED_ROM = 0x0001u, MTP_STORAGE_TYPE_REMOVABLE_ROM = 0x0002u, MTP_STORAGE_TYPE_FIXED_RAM = 0x0003u, MTP_STORAGE_TYPE_REMOVABLE_RAM = 0x0004u, } mtp_storage_type_t; typedef enum { MTP_FILESYSTEM_TYPE_UNDEFINED = 0x0000u, MTP_FILESYSTEM_TYPE_GENERIC_FLAT = 0x0001u, MTP_FILESYSTEM_TYPE_GENERIC_HIERARCHICAL = 0x0002u, MTP_FILESYSTEM_TYPE_DCF = 0x0003u, } mtp_filesystem_type_t; typedef enum { MTP_ACCESS_CAPABILITY_READ_WRITE = 0x0000u, MTP_ACCESS_CAPABILITY_READ_ONLY_WITHOUT_OBJECT_DELETION = 0x0001u, MTP_ACCESS_CAPABILITY_READ_ONLY_WITH_OBJECT_DELETION = 0x0002u, } mtp_access_capability_t; typedef enum { MTP_PROTECTION_STATUS_NO_PROTECTION = 0x0000u, MTP_PROTECTION_STATUS_READ_ONLY = 0x0001u, MTP_PROTECTION_STATUS_READ_ONLY_DATA = 0x8002u, MTP_PROTECTION_NON_TRANSFERABLE_DATA = 0x8003u, } mtp_protection_status_t; typedef enum { MTP_ASSOCIATION_UNDEFINED = 0x0000u, MTP_ASSOCIATION_GENERIC_FOLDER = 0x0001u, MTP_ASSOCIATION_ALBUM = 0x0002u, MTP_ASSOCIATION_TIME_SEQUENCE = 0x0003u, MTP_ASSOCIATION_HORIZONTAL_PANORAMIC = 0x0004u, MTP_ASSOCIATION_VERTICAL_PANORAMIC = 0x0005u, MTP_ASSOCIATION_2D_PANORAMIC = 0x0006u, MTP_ASSOCIATION_ANCILLARY_DATA = 0x0007u, } mtp_association_t; //--------------------------------------------------------------------+ // Data structures //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { uint32_t len; uint16_t type; uint16_t code; uint32_t transaction_id; } mtp_container_header_t; TU_VERIFY_STATIC(sizeof(mtp_container_header_t) == 12, "size is not correct"); typedef struct TU_ATTR_PACKED { mtp_container_header_t header; uint32_t params[5]; } mtp_container_command_t; TU_VERIFY_STATIC(sizeof(mtp_container_command_t) == 32, "size is not correct"); // PTP/MTP Generic container typedef struct TU_ATTR_PACKED { mtp_container_header_t header; uint8_t payload[(CFG_TUD_MTP_EP_BUFSIZE - sizeof(mtp_container_header_t))]; } mtp_generic_container_t; typedef struct { mtp_container_header_t* header; union { uint8_t* payload; uint16_t* payload16; uint32_t* payload32; }; uint32_t payload_bytes; // available bytes for read/write } mtp_container_info_t; typedef struct TU_ATTR_PACKED { uint16_t code; uint32_t session_id; uint32_t transaction_id; uint32_t params[3]; } mtp_event_t; TU_VERIFY_STATIC(sizeof(mtp_event_t) == 22, "size is not correct"); #define mtp_string_t(_nchars) \ struct TU_ATTR_PACKED { \ uint8_t count; /* in characters including null */ \ uint16_t utf16[_nchars]; \ } #define mtp_array_t(_type, _count) \ struct TU_ATTR_PACKED { \ uint32_t count; \ _type arr[_count];\ } #define mtp_aint8_t(_count) mtp_array_t(int8_t, _count) #define mtp_auint16_t(_count) mtp_array_t(uint16_t, _count) #define mtp_auint32_t(_count) mtp_array_t(uint32_t, _count) #define mtp_auint64_t(_count) mtp_array_t(uint64_t, _count) #define MTP_STORAGE_INFO_STRUCT(_storage_desc_chars, _volume_id_chars) \ struct TU_ATTR_PACKED { \ uint16_t storage_type; \ uint16_t filesystem_type; \ uint16_t access_capability; \ uint64_t max_capacity_in_bytes; \ uint64_t free_space_in_bytes; \ uint32_t free_space_in_objects; \ mtp_string_t(_storage_desc_chars) storage_description; \ mtp_string_t(_volume_id_chars) volume_identifier; \ } // Object Info Dataset without dynamic string: filename, date_created, date_modified, keywords typedef struct TU_ATTR_PACKED { uint32_t storage_id; uint16_t object_format; uint16_t protection_status; uint32_t object_compressed_size; uint16_t thumb_format; uint32_t thumb_compressed_size; uint32_t thumb_pix_width; uint32_t thumb_pix_height; uint32_t image_pix_width; uint32_t image_pix_height; uint32_t image_bit_depth; uint32_t parent_object; // 0: root uint16_t association_type; uint32_t association_desc; uint32_t sequence_number; // mtp_string_t() filename // mtp_string_t() date_created // mtp_string_t() date_modified // mtp_string_t() keywords } mtp_object_info_header_t; // Device property desc up to get/set typedef struct TU_ATTR_PACKED { uint16_t device_property_code; uint16_t datatype; uint8_t get_set; } mtp_device_prop_desc_header_t; // The following fields will be dynamically added to the struct at runtime: // - wstring factory_def_value; // - wstring current_value_len; // - uint8_t form_flag; // no form #define MTP_DEVICE_PROPERTIES_STRUCT(_type) \ struct TU_ATTR_PACKED { \ uint16_t device_property_code; \ uint16_t datatype; \ uint8_t get_set; \ _type factory_default; \ _type current_value; \ uint8_t form_flag; /* 0: none, 1: range, 2: enum */ \ }; typedef struct TU_ATTR_PACKED { uint16_t code; uint32_t transaction_id; } mtp_request_reset_cancel_data_t; TU_VERIFY_STATIC(sizeof(mtp_request_reset_cancel_data_t) == 6, "size is not correct"); //--------------------------------------------------------------------+ // Container helper function // return number of bytes added //--------------------------------------------------------------------+ // return payload buffer for next write TU_ATTR_ALWAYS_INLINE static inline uint8_t* mtp_container_payload_ptr(mtp_container_info_t* p_container) { // only 1st packet include header uint32_t pos = p_container->header->len - sizeof(mtp_container_header_t); while (pos > CFG_TUD_MTP_EP_BUFSIZE) { pos -= CFG_TUD_MTP_EP_BUFSIZE; } return p_container->payload + pos; } // only add_raw does partial copy TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_raw(mtp_container_info_t* p_container, const void* data, uint32_t len) { uint8_t* buf = mtp_container_payload_ptr(p_container); const uint32_t added_len = tu_min32(len, CFG_TUD_MTP_EP_BUFSIZE - p_container->header->len); if (added_len > 0) { memcpy(buf, data, added_len); } p_container->header->len += len; // always increase len, even partial copy return added_len; } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_array(mtp_container_info_t* p_container, uint8_t scalar_size, uint32_t count, const void* data) { const uint32_t added_len = 4 + count * scalar_size; TU_ASSERT(p_container->header->len + added_len < CFG_TUD_MTP_EP_BUFSIZE, 0); uint8_t* buf = p_container->payload + p_container->header->len - sizeof(mtp_container_header_t); tu_unaligned_write32(buf, count); p_container->header->len += 4; buf += 4; memcpy(buf, data, count * scalar_size); p_container->header->len += count * scalar_size; return added_len; } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_string(mtp_container_info_t* p_container, uint16_t* utf16) { uint8_t count = 0; while (utf16[count] != 0u) { count++; } const uint32_t added_len = 1u + (uint32_t) count * 2u; TU_ASSERT(p_container->header->len + added_len < CFG_TUD_MTP_EP_BUFSIZE, 0); uint8_t* buf = p_container->payload + p_container->header->len - sizeof(mtp_container_header_t); *buf++ = count; p_container->header->len++; memcpy(buf, utf16, 2u * (uint32_t) count); p_container->header->len += 2u * count; return added_len; } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_cstring(mtp_container_info_t* p_container, const char* str) { const uint8_t len = (uint8_t) (strlen(str) + 1); // include null TU_ASSERT(p_container->header->len + 1 + 2 * len < CFG_TUD_MTP_EP_BUFSIZE, 0); uint8_t* buf = p_container->payload + p_container->header->len - sizeof(mtp_container_header_t); if (len == 1) { // empty string (null only): single zero byte *buf = 0; p_container->header->len++; return 1u; } else { *buf++ = len; p_container->header->len++; for (uint8_t i = 0; i < len; i++) { buf[0] = str[i]; buf[1] = 0; buf += 2; p_container->header->len += 2; } return 1u + 2u * len; } } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint8(mtp_container_info_t* p_container, uint8_t data) { return mtp_container_add_raw(p_container, &data, 1); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint16(mtp_container_info_t* p_container, uint16_t data) { return mtp_container_add_raw(p_container, &data, 2); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint32(mtp_container_info_t* p_container, uint32_t data) { return mtp_container_add_raw(p_container, &data, 4); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint64(mtp_container_info_t* p_container, uint64_t data) { return mtp_container_add_raw(p_container, &data, 8); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_uint128(mtp_container_info_t* p_container, const void* data) { return mtp_container_add_raw(p_container, data, 16); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_auint8(mtp_container_info_t* p_container, uint32_t count, const uint8_t* data) { return mtp_container_add_array(p_container, sizeof(uint8_t), count, data); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_auint16(mtp_container_info_t* p_container, uint32_t count, const uint16_t* data) { return mtp_container_add_array(p_container, sizeof(uint16_t), count, data); } TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_auint32(mtp_container_info_t* p_container, uint32_t count, const uint32_t* data) { return mtp_container_add_array(p_container, sizeof(uint32_t), count, data); } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_get_string(uint8_t* buf, uint16_t utf16[]) { size_t nchars = *buf++; memcpy(utf16, buf, 2u * nchars); return 1u + 2u * nchars; } #ifdef __cplusplus } #endif #endif #endif ================================================ FILE: src/class/mtp/mtp_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_MTP) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "device/dcd.h" #include "device/usbd.h" #include "device/usbd_pvt.h" #include "mtp_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_MTP_LOG_LEVEL #define CFG_TUD_MTP_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MTP_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK bool tud_mtp_request_cancel_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return false; } TU_ATTR_WEAK bool tud_mtp_request_device_reset_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return false; } TU_ATTR_WEAK int32_t tud_mtp_request_get_extended_event_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return -1; } TU_ATTR_WEAK int32_t tud_mtp_request_get_device_status_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return -1; } TU_ATTR_WEAK bool tud_mtp_request_vendor_cb(tud_mtp_request_cb_data_t* cb_data) { (void) cb_data; return false; } TU_ATTR_WEAK int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t * cb_data) { (void) cb_data; return -1; } TU_ATTR_WEAK int32_t tud_mtp_data_xfer_cb(tud_mtp_cb_data_t* cb_data) { (void) cb_data; return -1; } TU_ATTR_WEAK int32_t tud_mtp_data_complete_cb(tud_mtp_cb_data_t* cb_data) { (void) cb_data; return -1; } TU_ATTR_WEAK int32_t tud_mtp_response_complete_cb(tud_mtp_cb_data_t* cb_data) { (void) cb_data; return -1; } //--------------------------------------------------------------------+ // STRUCT //--------------------------------------------------------------------+ typedef struct { uint8_t rhport; uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; uint8_t ep_event; uint8_t ep_sz_fs; // Bulk Only Transfer (BOT) Protocol uint8_t phase; uint32_t total_len; uint32_t xferred_len; uint32_t session_id; mtp_container_command_t command; mtp_container_header_t io_header; TU_ATTR_ALIGNED(4) uint8_t control_buf[CFG_TUD_MTP_EP_CONTROL_BUFSIZE]; } mtpd_interface_t; typedef struct { TUD_EPBUF_DEF(buf, CFG_TUD_MTP_EP_BUFSIZE); TUD_EPBUF_TYPE_DEF(mtp_event_t, buf_event); } mtpd_epbuf_t; //--------------------------------------------------------------------+ // INTERNAL FUNCTION DECLARATION //--------------------------------------------------------------------+ static mtpd_interface_t _mtpd_itf; CFG_TUD_MEM_SECTION static mtpd_epbuf_t _mtpd_epbuf; static void preprocess_cmd(mtpd_interface_t* p_mtp, tud_mtp_cb_data_t* cb_data); //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_MTP_LOG_LEVEL TU_ATTR_UNUSED static tu_lookup_entry_t const _mpt_op_lookup[] = { {.key = MTP_OP_UNDEFINED , .data = "Undefined" } , {.key = MTP_OP_GET_DEVICE_INFO , .data = "GetDeviceInfo" } , {.key = MTP_OP_OPEN_SESSION , .data = "OpenSession" } , {.key = MTP_OP_CLOSE_SESSION , .data = "CloseSession" } , {.key = MTP_OP_GET_STORAGE_IDS , .data = "GetStorageIDs" } , {.key = MTP_OP_GET_STORAGE_INFO , .data = "GetStorageInfo" } , {.key = MTP_OP_GET_NUM_OBJECTS , .data = "GetNumObjects" } , {.key = MTP_OP_GET_OBJECT_HANDLES , .data = "GetObjectHandles" } , {.key = MTP_OP_GET_OBJECT_INFO , .data = "GetObjectInfo" } , {.key = MTP_OP_GET_OBJECT , .data = "GetObject" } , {.key = MTP_OP_GET_THUMB , .data = "GetThumb" } , {.key = MTP_OP_DELETE_OBJECT , .data = "DeleteObject" } , {.key = MTP_OP_SEND_OBJECT_INFO , .data = "SendObjectInfo" } , {.key = MTP_OP_SEND_OBJECT , .data = "SendObject" } , {.key = MTP_OP_INITIATE_CAPTURE , .data = "InitiateCapture" } , {.key = MTP_OP_FORMAT_STORE , .data = "FormatStore" } , {.key = MTP_OP_RESET_DEVICE , .data = "ResetDevice" } , {.key = MTP_OP_SELF_TEST , .data = "SelfTest" } , {.key = MTP_OP_SET_OBJECT_PROTECTION , .data = "SetObjectProtection" } , {.key = MTP_OP_POWER_DOWN , .data = "PowerDown" } , {.key = MTP_OP_GET_DEVICE_PROP_DESC , .data = "GetDevicePropDesc" } , {.key = MTP_OP_GET_DEVICE_PROP_VALUE , .data = "GetDevicePropValue" } , {.key = MTP_OP_SET_DEVICE_PROP_VALUE , .data = "SetDevicePropValue" } , {.key = MTP_OP_RESET_DEVICE_PROP_VALUE , .data = "ResetDevicePropValue" } , {.key = MTP_OP_TERMINATE_OPEN_CAPTURE , .data = "TerminateOpenCapture" } , {.key = MTP_OP_MOVE_OBJECT , .data = "MoveObject" } , {.key = MTP_OP_COPY_OBJECT , .data = "CopyObject" } , {.key = MTP_OP_GET_PARTIAL_OBJECT , .data = "GetPartialObject" } , {.key = MTP_OP_INITIATE_OPEN_CAPTURE , .data = "InitiateOpenCapture" } , {.key = MTP_OP_GET_OBJECT_PROPS_SUPPORTED , .data = "GetObjectPropsSupported" } , {.key = MTP_OP_GET_OBJECT_PROP_DESC , .data = "GetObjectPropDesc" } , {.key = MTP_OP_GET_OBJECT_PROP_VALUE , .data = "GetObjectPropValue" } , {.key = MTP_OP_SET_OBJECT_PROP_VALUE , .data = "SetObjectPropValue" } , {.key = MTP_OP_GET_OBJECT_PROPLIST , .data = "GetObjectPropList" } , {.key = MTP_OP_GET_OBJECT_PROP_REFERENCES , .data = "GetObjectPropReferences" } , {.key = MTP_OP_GET_SERVICE_IDS , .data = "GetServiceIDs" } , {.key = MTP_OP_GET_SERVICE_INFO , .data = "GetServiceInfo" } , {.key = MTP_OP_GET_SERVICE_CAPABILITIES , .data = "GetServiceCapabilities" } , {.key = MTP_OP_GET_SERVICE_PROP_DESC , .data = "GetServicePropDesc" } , {.key = MTP_OP_GET_OBJECT_PROP_LIST , .data = "GetObjectPropList" } , {.key = MTP_OP_SET_OBJECT_PROP_LIST , .data = "SetObjectPropList" } , {.key = MTP_OP_GET_INTERDEPENDENT_PROP_DESC , .data = "GetInterdependentPropDesc" } , {.key = MTP_OP_SEND_OBJECT_PROP_LIST , .data = "SendObjectPropList" } }; TU_ATTR_UNUSED static tu_lookup_table_t const _mtp_op_table = { .count = TU_ARRAY_SIZE(_mpt_op_lookup), .items = _mpt_op_lookup }; TU_ATTR_UNUSED static const char* _mtp_phase_str[] = { "Command", "Data", "Response", "Error" }; #endif //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ static bool prepare_new_command(mtpd_interface_t* p_mtp) { p_mtp->phase = MTP_PHASE_COMMAND; return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, CFG_TUD_MTP_EP_BUFSIZE, false); } bool tud_mtp_data_send(mtp_container_info_t *p_container) { mtpd_interface_t *p_mtp = &_mtpd_itf; if (p_mtp->phase == MTP_PHASE_COMMAND) { // 1st data block: header + payload p_mtp->phase = MTP_PHASE_DATA; p_mtp->xferred_len = 0; p_mtp->total_len = p_container->header->len; p_container->header->type = MTP_CONTAINER_TYPE_DATA_BLOCK; p_container->header->transaction_id = p_mtp->command.header.transaction_id; p_mtp->io_header = *p_container->header; // save header for subsequent data } const uint16_t xact_len = (uint16_t)tu_min32(p_mtp->total_len - p_mtp->xferred_len, CFG_TUD_MTP_EP_BUFSIZE); TU_LOG_DRV(" MTP Data IN: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", p_mtp->xferred_len, p_mtp->total_len, xact_len); if (xact_len) { TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_in)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_in, _mtpd_epbuf.buf, xact_len, false)); } return true; } bool tud_mtp_data_receive(mtp_container_info_t *p_container) { mtpd_interface_t *p_mtp = &_mtpd_itf; if (p_mtp->phase == MTP_PHASE_COMMAND) { // 1st data block: header + payload p_mtp->phase = MTP_PHASE_DATA; p_mtp->xferred_len = 0; p_mtp->total_len = p_container->header->len; } // up to buffer size since 1st packet (with header) may also contain payload const uint16_t xact_len = CFG_TUD_MTP_EP_BUFSIZE; TU_LOG_DRV(" MTP Data OUT: xferred_len/total_len=%lu/%lu, xact_len=%u\r\n", p_mtp->xferred_len, p_mtp->total_len, xact_len); TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_out)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, xact_len, false)); return true; } bool tud_mtp_response_send(mtp_container_info_t* p_container) { mtpd_interface_t* p_mtp = &_mtpd_itf; p_mtp->phase = MTP_PHASE_RESPONSE; p_container->header->type = MTP_CONTAINER_TYPE_RESPONSE_BLOCK; p_container->header->transaction_id = p_mtp->command.header.transaction_id; TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_in)); return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_in, _mtpd_epbuf.buf, (uint16_t) p_container->header->len, false); } bool tud_mtp_mounted(void) { mtpd_interface_t* p_mtp = &_mtpd_itf; return p_mtp->ep_out != 0 && p_mtp->ep_in != 0; } bool tud_mtp_event_send(mtp_event_t* event) { mtpd_interface_t* p_mtp = &_mtpd_itf; TU_VERIFY(p_mtp->ep_event != 0); _mtpd_epbuf.buf_event = *event; TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_event)); // Claim the endpoint return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_event, (uint8_t*) &_mtpd_epbuf.buf_event, sizeof(mtp_event_t), false); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void mtpd_init(void) { tu_memclr(&_mtpd_itf, sizeof(mtpd_interface_t)); } bool mtpd_deinit(void) { return true; // nothing to do } void mtpd_reset(uint8_t rhport) { (void) rhport; tu_memclr(&_mtpd_itf, sizeof(mtpd_interface_t)); } uint16_t mtpd_open(uint8_t rhport, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { // only support PIMA 15470 protocol TU_VERIFY(TUSB_CLASS_IMAGE == itf_desc->bInterfaceClass && MTP_SUBCLASS_STILL_IMAGE == itf_desc->bInterfaceSubClass && MTP_PROTOCOL_PIMA_15470 == itf_desc->bInterfaceProtocol, 0); // mtp driver length is fixed const uint16_t mtpd_itf_size = sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t); // Max length must be at least 1 interface + 3 endpoints TU_ASSERT(itf_desc->bNumEndpoints == 3 && max_len >= mtpd_itf_size); mtpd_interface_t* p_mtp = &_mtpd_itf; tu_memclr(p_mtp, sizeof(mtpd_interface_t)); p_mtp->rhport = rhport; p_mtp->itf_num = itf_desc->bInterfaceNumber; // Open interrupt IN endpoint const tusb_desc_endpoint_t* ep_desc_int = (const tusb_desc_endpoint_t*) tu_desc_next(itf_desc); TU_ASSERT(ep_desc_int->bDescriptorType == TUSB_DESC_ENDPOINT && ep_desc_int->bmAttributes.xfer == TUSB_XFER_INTERRUPT, 0); TU_ASSERT(usbd_edpt_open(rhport, ep_desc_int), 0); p_mtp->ep_event = ep_desc_int->bEndpointAddress; // Open endpoint pair const tusb_desc_endpoint_t* ep_desc_bulk = (const tusb_desc_endpoint_t*) tu_desc_next(ep_desc_int); TU_ASSERT(usbd_open_edpt_pair(rhport, (const uint8_t*)ep_desc_bulk, 2, TUSB_XFER_BULK, &p_mtp->ep_out, &p_mtp->ep_in), 0); TU_ASSERT(prepare_new_command(p_mtp), 0); if (tud_speed_get() == TUSB_SPEED_FULL) { p_mtp->ep_sz_fs = (uint8_t)tu_edpt_packet_size(ep_desc_bulk); } return mtpd_itf_size; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool mtpd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { mtpd_interface_t* p_mtp = &_mtpd_itf; tud_mtp_request_cb_data_t cb_data = { .idx = 0, .stage = stage, .session_id = p_mtp->session_id, .request = request, .buf = p_mtp->control_buf, .bufsize = tu_le16toh(request->wLength), }; switch (request->bRequest) { case MTP_REQ_CANCEL: TU_LOG_DRV(" MTP request: Cancel\n"); if (stage == CONTROL_STAGE_SETUP) { return tud_control_xfer(rhport, request, p_mtp->control_buf, CFG_TUD_MTP_EP_CONTROL_BUFSIZE); } else if (stage == CONTROL_STAGE_ACK) { return tud_mtp_request_cancel_cb(&cb_data); } break; case MTP_REQ_GET_EXT_EVENT_DATA: TU_LOG_DRV(" MTP request: Get Extended Event Data\n"); if (stage == CONTROL_STAGE_SETUP) { const int32_t len = tud_mtp_request_get_extended_event_cb(&cb_data); TU_VERIFY(len > 0); return tud_control_xfer(rhport,request, p_mtp->control_buf, (uint16_t) len); } break; case MTP_REQ_RESET: TU_LOG_DRV(" MTP request: Device Reset\n"); // used by the host to return the Still Image Capture Device to the Idle state after the Bulk-pipe has stalled if (stage == CONTROL_STAGE_SETUP) { // clear stalled if (usbd_edpt_stalled(rhport, p_mtp->ep_out)) { usbd_edpt_clear_stall(rhport, p_mtp->ep_out); } if (usbd_edpt_stalled(rhport, p_mtp->ep_in)) { usbd_edpt_clear_stall(rhport, p_mtp->ep_in); } } else if (stage == CONTROL_STAGE_ACK) { prepare_new_command(p_mtp); return tud_mtp_request_device_reset_cb(&cb_data); } break; case MTP_REQ_GET_DEVICE_STATUS: { TU_LOG_DRV(" MTP request: Get Device Status\n"); if (stage == CONTROL_STAGE_SETUP) { const int32_t len = tud_mtp_request_get_device_status_cb(&cb_data); TU_VERIFY(len > 0); return tud_control_xfer(rhport, request, p_mtp->control_buf, (uint16_t) len); } break; } default: return tud_mtp_request_vendor_cb(&cb_data); } return true; } // Transfer on bulk endpoints bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { if (ep_addr == _mtpd_itf.ep_event) { // nothing to do return true; } mtpd_interface_t* p_mtp = &_mtpd_itf; mtp_generic_container_t* p_container = (mtp_generic_container_t*) _mtpd_epbuf.buf; #if CFG_TUSB_DEBUG >= CFG_TUD_MTP_LOG_LEVEL const uint16_t code = (p_mtp->phase == MTP_PHASE_COMMAND) ? p_container->header.code : p_mtp->command.header.code; TU_LOG_DRV(" MTP %s: %s phase\r\n", (const char *) tu_lookup_find(&_mtp_op_table, code), _mtp_phase_str[p_mtp->phase]); #endif const mtp_container_info_t headered_packet = { .header = &p_container->header, .payload = p_container->payload, .payload_bytes = CFG_TUD_MTP_EP_BUFSIZE - sizeof(mtp_container_header_t) }; const mtp_container_info_t headerless_packet = { .header = &p_mtp->io_header, .payload = _mtpd_epbuf.buf, .payload_bytes = CFG_TUD_MTP_EP_BUFSIZE }; tud_mtp_cb_data_t cb_data; cb_data.idx = 0; cb_data.phase = p_mtp->phase; cb_data.session_id = p_mtp->session_id; cb_data.command_container = &p_mtp->command; cb_data.io_container = headered_packet; cb_data.total_xferred_bytes = 0; cb_data.xfer_result = event; switch (p_mtp->phase) { case MTP_PHASE_COMMAND: { // received new command TU_VERIFY(ep_addr == p_mtp->ep_out && p_container->header.type == MTP_CONTAINER_TYPE_COMMAND_BLOCK); memcpy(&p_mtp->command, p_container, sizeof(mtp_container_command_t)); // save new command p_container->header.len = sizeof(mtp_container_header_t); // default container to header only preprocess_cmd(p_mtp, &cb_data); if (tud_mtp_command_received_cb(&cb_data) < 0) { p_mtp->phase = MTP_PHASE_ERROR; } break; } case MTP_PHASE_DATA: { p_mtp->xferred_len += xferred_bytes; cb_data.total_xferred_bytes = p_mtp->xferred_len; const bool is_data_in = (ep_addr == p_mtp->ep_in); // For IN endpoint, threshold is bulk max packet size // For OUT endpoint, threshold is endpoint buffer size, since we always queue fixed size uint16_t threshold; if (is_data_in) { threshold = (p_mtp->ep_sz_fs > 0) ? p_mtp->ep_sz_fs : 512; // full speed bulk if set } else { threshold = CFG_TUD_MTP_EP_BUFSIZE; } // Check completion: ZLP, short packet, or total length reached const bool is_complete = (xferred_bytes == 0 || xferred_bytes < threshold || p_mtp->xferred_len >= p_mtp->total_len); TU_LOG_DRV(" MTP Data %s CB: xferred_bytes=%lu, xferred_len/total_len=%lu/%lu, is_complete=%d\r\n", is_data_in ? "IN" : "OUT", xferred_bytes, p_mtp->xferred_len, p_mtp->total_len, is_complete ? 1 : 0); // Send/queue ZLP if packet is full-sized but transfer is complete if (is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1))) { TU_LOG_DRV(" queue ZLP\r\n"); TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false)); return true; } if (is_data_in) { // Data In if (is_complete) { cb_data.io_container.header->len = sizeof(mtp_container_header_t); tud_mtp_data_complete_cb(&cb_data); } else { // 2nd+ packet: payload only cb_data.io_container = headerless_packet; tud_mtp_data_xfer_cb(&cb_data); } } else { // Data Out if (p_mtp->xferred_len == xferred_bytes) { // 1st OUT packet: header + payload p_mtp->io_header = p_container->header; // save header for subsequent transaction cb_data.io_container.payload_bytes = xferred_bytes - sizeof(mtp_container_header_t); } else { // 2nd+ packet: payload only cb_data.io_container = headerless_packet; cb_data.io_container.payload_bytes = xferred_bytes; } tud_mtp_data_xfer_cb(&cb_data); if (is_complete) { // back to header + payload for response cb_data.io_container = headered_packet; cb_data.io_container.header->len = sizeof(mtp_container_header_t); tud_mtp_data_complete_cb(&cb_data); } } break; } case MTP_PHASE_RESPONSE: // response phase is complete -> prepare for new command TU_ASSERT(ep_addr == p_mtp->ep_in); tud_mtp_response_complete_cb(&cb_data); prepare_new_command(p_mtp); break; case MTP_PHASE_ERROR: // handled after switch, supposedly to be empty break; default: return false; } if (p_mtp->phase == MTP_PHASE_ERROR) { // stall both IN & OUT endpoints usbd_edpt_stall(rhport, p_mtp->ep_out); usbd_edpt_stall(rhport, p_mtp->ep_in); } return true; } //--------------------------------------------------------------------+ // MTPD Internal functionality //--------------------------------------------------------------------+ // pre-processed commands void preprocess_cmd(mtpd_interface_t* p_mtp, tud_mtp_cb_data_t* cb_data) { switch (p_mtp->command.header.code) { case MTP_OP_GET_DEVICE_INFO: { tud_mtp_device_info_t dev_info = { .standard_version = 100, .mtp_vendor_extension_id = 6, // MTP specs say 0xFFFFFFFF but libMTP check for value 6 .mtp_version = 100, .mtp_extensions = { .count = sizeof(CFG_TUD_MTP_DEVICEINFO_EXTENSIONS), .utf16 = { 0 } }, .functional_mode = 0x0000, .supported_operations = { .count = TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS), .arr = { CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS } }, .supported_events = { .count = TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS), .arr = { CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS } }, .supported_device_properties = { .count = TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES), .arr = { CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES } }, .capture_formats = { .count = TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS), .arr = { CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS } }, .playback_formats = { .count = TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS), .arr = { CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS } } }; for (uint8_t i=0; i < dev_info.mtp_extensions.count; i++) { dev_info.mtp_extensions.utf16[i] = (uint16_t)CFG_TUD_MTP_DEVICEINFO_EXTENSIONS[i]; } mtp_container_add_raw(&cb_data->io_container, &dev_info, sizeof(tud_mtp_device_info_t)); break; } default: break; } } #endif ================================================ FILE: src/class/mtp/mtp_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MTP_DEVICE_H_ #define TUSB_MTP_DEVICE_H_ #include "common/tusb_common.h" #include "mtp.h" #if (CFG_TUD_ENABLED && CFG_TUD_MTP) #ifdef __cplusplus extern "C" { #endif // callback data for Bulk Only Transfer (BOT) protocol typedef struct { uint8_t idx; // mtp instance uint8_t phase; // current phase uint32_t session_id; const mtp_container_command_t* command_container; mtp_container_info_t io_container; tusb_xfer_result_t xfer_result; uint32_t total_xferred_bytes; // number of bytes transferred so far in this phase } tud_mtp_cb_data_t; // callback data for Control requests typedef struct { uint8_t idx; uint8_t stage; // control stage // buffer for data stage uint16_t bufsize; uint8_t* buf; const tusb_control_request_t* request; uint32_t session_id; } tud_mtp_request_cb_data_t; // Number of supported operations, events, device properties, capture formats, playback formats // and max number of characters for strings manufacturer, model, device_version, serial_number #define MTP_DEVICE_INFO_STRUCT(_extension_nchars, _op_count, _event_count, _devprop_count, _capture_count, _playback_count) \ struct TU_ATTR_PACKED { \ uint16_t standard_version; \ uint32_t mtp_vendor_extension_id; \ uint16_t mtp_version; \ mtp_string_t(_extension_nchars) mtp_extensions; \ uint16_t functional_mode; \ mtp_auint16_t(_op_count) supported_operations; \ mtp_auint16_t(_event_count) supported_events; \ mtp_auint16_t(_devprop_count) supported_device_properties; \ mtp_auint16_t(_capture_count) capture_formats; \ mtp_auint16_t(_playback_count) playback_formats; \ /* string fields will be added using append function */ \ } typedef MTP_DEVICE_INFO_STRUCT( //-V2586 [MISRA-C-18.7] Flexible array members should not be declared sizeof(CFG_TUD_MTP_DEVICEINFO_EXTENSIONS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS) ) tud_mtp_device_info_t; //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // check if mtp interface is mounted bool tud_mtp_mounted(void); // send data phase bool tud_mtp_data_send(mtp_container_info_t* p_container); // receive data phase bool tud_mtp_data_receive(mtp_container_info_t* p_container); // send response bool tud_mtp_response_send(mtp_container_info_t* p_container); // send event notification on event endpoint bool tud_mtp_event_send(mtp_event_t* event); //--------------------------------------------------------------------+ // Control request Callbacks //--------------------------------------------------------------------+ // Invoked when received Cancel request. Data is available in callback data's buffer // return false to stall the request bool tud_mtp_request_cancel_cb(tud_mtp_request_cb_data_t* cb_data); // Invoked when received Device Reset request // return false to stall the request bool tud_mtp_request_device_reset_cb(tud_mtp_request_cb_data_t* cb_data); // Invoked when received Get Extended Event request. Application fill callback data's buffer for response // return negative to stall the request int32_t tud_mtp_request_get_extended_event_cb(tud_mtp_request_cb_data_t* cb_data); // Invoked when received Get DeviceStatus request. Application fill callback data's buffer for response // return negative to stall the request int32_t tud_mtp_request_get_device_status_cb(tud_mtp_request_cb_data_t* cb_data); // Invoked when received vendor-specific request not in the above standard MTP requests // return false to stall the request bool tud_mtp_request_vendor_cb(tud_mtp_request_cb_data_t* cb_data); //--------------------------------------------------------------------+ // Bulk only protocol Callbacks //--------------------------------------------------------------------+ // Invoked when new command is received. Application fill the cb_data->io_container and call tud_mtp_data_send() or // tud_mtp_response_send() for Data or Response phase. // Return negative to stall the endpoints int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t * cb_data); // Invoked when a data packet is transferred. If data spans over multiple packets, application can use // total_xferred_bytes and io_container's payload_bytes to determine the offset and remaining bytes to be transferred. // Return negative to stall the endpoints int32_t tud_mtp_data_xfer_cb(tud_mtp_cb_data_t* cb_data); // Invoked when all bytes in DATA phase is complete. A response packet is expected // Return negative to stall the endpoints int32_t tud_mtp_data_complete_cb(tud_mtp_cb_data_t* cb_data); // Invoked when response phase is complete // Return negative to stall the endpoints int32_t tud_mtp_response_complete_cb(tud_mtp_cb_data_t* cb_data); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void mtpd_init (void); bool mtpd_deinit (void); void mtpd_reset (uint8_t rhport); uint16_t mtpd_open (uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool mtpd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *p_request); bool mtpd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif #endif ================================================ FILE: src/class/net/ecm_rndis_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if ( CFG_TUD_ENABLED && CFG_TUD_ECM_RNDIS ) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "net_device.h" #include "rndis_protocol.h" #define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t) #define CFG_TUD_NET_PACKET_SUFFIX_LEN 0 #define NETD_PACKET_SIZE (CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN) #define NETD_CONTROL_SIZE 120 //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active uint8_t ep_notif; uint8_t ep_in; uint8_t ep_out; bool ecm_mode; // Endpoint descriptor use to open/close when receiving SetInterface // TODO since configuration descriptor may not be long-lived memory, we should // keep a copy of endpoint attribute instead uint8_t const * ecm_desc_epdata; } netd_interface_t; typedef struct ecm_notify_struct { tusb_control_request_t header; uint32_t downlink, uplink; } ecm_notify_t; typedef struct { TUD_EPBUF_DEF(rx, NETD_PACKET_SIZE); TUD_EPBUF_DEF(tx, NETD_PACKET_SIZE); TUD_EPBUF_DEF(notify, sizeof(ecm_notify_t)); TUD_EPBUF_DEF(ctrl, NETD_CONTROL_SIZE); } netd_epbuf_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static netd_interface_t _netd_itf; CFG_TUD_MEM_SECTION static netd_epbuf_t _netd_epbuf; static bool can_xmit; static bool ecm_link_is_up = true; // Store link state for ECM mode void tud_network_recv_renew(void) { usbd_edpt_xfer(0, _netd_itf.ep_out, _netd_epbuf.rx, NETD_PACKET_SIZE, false); } static void do_in_xfer(uint8_t *buf, uint16_t len) { can_xmit = false; usbd_edpt_xfer(0, _netd_itf.ep_in, buf, len, false); } void netd_report(uint8_t *buf, uint16_t len) { const uint8_t rhport = 0; len = tu_min16(len, sizeof(ecm_notify_t)); if (!usbd_edpt_claim(rhport, _netd_itf.ep_notif)) { TU_LOG1("ECM: Failed to claim notification endpoint\n"); return; } memcpy(_netd_epbuf.notify, buf, len); usbd_edpt_xfer(rhport, _netd_itf.ep_notif, _netd_epbuf.notify, len, false); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void netd_init(void) { tu_memclr(&_netd_itf, sizeof(_netd_itf)); } bool netd_deinit(void) { return true; } void netd_reset(uint8_t rhport) { (void) rhport; netd_init(); } uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { bool const is_rndis = (TUD_RNDIS_ITF_CLASS == itf_desc->bInterfaceClass && TUD_RNDIS_ITF_SUBCLASS == itf_desc->bInterfaceSubClass && TUD_RNDIS_ITF_PROTOCOL == itf_desc->bInterfaceProtocol); bool const is_ecm = (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL == itf_desc->bInterfaceSubClass && 0x00 == itf_desc->bInterfaceProtocol); TU_VERIFY(is_rndis || is_ecm, 0); // confirm interface hasn't already been allocated TU_ASSERT(0 == _netd_itf.ep_notif, 0); // sanity check the descriptor _netd_itf.ecm_mode = is_ecm; //------------- Management Interface -------------// _netd_itf.itf_num = itf_desc->bInterfaceNumber; uint16_t drv_len = sizeof(tusb_desc_interface_t); uint8_t const * p_desc = tu_desc_next( itf_desc ); // Communication Functional Descriptors while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } // notification endpoint (if any) if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0); _netd_itf.ep_notif = ((tusb_desc_endpoint_t const*)p_desc)->bEndpointAddress; drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } //------------- Data Interface -------------// // - RNDIS Data followed immediately by a pair of endpoints // - CDC-ECM data interface has 2 alternate settings // - 0 : zero endpoints for inactive (default) // - 1 : IN & OUT endpoints for active networking TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); do { tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } while (_netd_itf.ecm_mode && (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); // Pair of endpoints TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); if (_netd_itf.ecm_mode) { // ECM by default is in-active, save the endpoint attribute // to open later when received setInterface _netd_itf.ecm_desc_epdata = p_desc; } else { // Open endpoint pair for RNDIS TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in), 0); // we are ready to transmit a packet can_xmit = true; // prepare for incoming packets tud_network_recv_renew(); } drv_len += 2*sizeof(tusb_desc_endpoint_t); return drv_len; } static void ecm_report(bool nc) { ecm_notify_t ecm_notify_nc = { .header = { .bmRequestType = 0xA1, .bRequest = 0, /* NETWORK_CONNECTION aka NetworkConnection */ .wValue = ecm_link_is_up ? 1 : 0, /* Use current link state */ .wLength = 0, }, }; const ecm_notify_t ecm_notify_csc = { .header = { .bmRequestType = 0xA1, .bRequest = 0x2A, /* CONNECTION_SPEED_CHANGE aka ConnectionSpeedChange */ .wLength = 8, }, .downlink = 9728000, .uplink = 9728000, }; ecm_notify_t notify = (nc) ? ecm_notify_nc : ecm_notify_csc; notify.header.wIndex = _netd_itf.itf_num; netd_report((uint8_t *)¬ify, (nc) ? sizeof(notify.header) : sizeof(notify)); } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { if (stage == CONTROL_STAGE_SETUP) { switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { uint8_t const req_itfnum = (uint8_t)request->wIndex; TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum); tud_control_xfer(rhport, request, &_netd_itf.itf_data_alt, 1); } break; case TUSB_REQ_SET_INTERFACE: { uint8_t const req_itfnum = (uint8_t)request->wIndex; uint8_t const req_alt = (uint8_t)request->wValue; // Only valid for Data Interface with Alternate is either 0 or 1 TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum && req_alt < 2); // ACM-ECM only: qequest to enable/disable network activities TU_VERIFY(_netd_itf.ecm_mode); _netd_itf.itf_data_alt = req_alt; if (_netd_itf.itf_data_alt) { // TODO since we don't actually close endpoint // hack here to not re-open it if (_netd_itf.ep_in == 0 && _netd_itf.ep_out == 0) { TU_ASSERT(_netd_itf.ecm_desc_epdata); TU_ASSERT( usbd_open_edpt_pair(rhport, _netd_itf.ecm_desc_epdata, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, & _netd_itf.ep_in)); // TODO should be merge with RNDIS's after endpoint opened // Also should have opposite callback for application to disable network !! can_xmit = true; // we are ready to transmit a packet tud_network_recv_renew(); // prepare for incoming packets } } else { // TODO close the endpoint pair // For now pretend that we did, this should have no harm since host won't try to // communicate with the endpoints again // _netd_itf.ep_in = _netd_itf.ep_out = 0 } tud_control_status(rhport, request); } break; // unsupported request default: return false; } break; case TUSB_REQ_TYPE_CLASS: TU_VERIFY(_netd_itf.itf_num == request->wIndex); if (_netd_itf.ecm_mode) { /* the only required CDC-ECM Management Element Request is SetEthernetPacketFilter */ if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == request->bRequest) { tud_control_xfer(rhport, request, NULL, 0); // Only send connection notification if link is up if (ecm_link_is_up) { ecm_report(true); } } } else { if (request->bmRequestType_bit.direction == TUSB_DIR_IN) { rndis_generic_msg_t* rndis_msg = (rndis_generic_msg_t*)((void*)_netd_epbuf.ctrl); uint32_t msglen = tu_le32toh(rndis_msg->MessageLength); TU_ASSERT(msglen <= NETD_CONTROL_SIZE); tud_control_xfer(rhport, request, _netd_epbuf.ctrl, (uint16_t)msglen); } else { tud_control_xfer(rhport, request, _netd_epbuf.ctrl, NETD_CONTROL_SIZE); } } break; // unsupported request default: return false; } } else if (stage == CONTROL_STAGE_DATA) { // Handle RNDIS class control OUT only if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && request->bmRequestType_bit.direction == TUSB_DIR_OUT && _netd_itf.itf_num == request->wIndex) { if (!_netd_itf.ecm_mode) { rndis_class_set_handler(_netd_epbuf.ctrl, request->wLength); } } } return true; } static void handle_incoming_packet(uint32_t len) { uint8_t* pnt = _netd_epbuf.rx; uint32_t size = 0; if (_netd_itf.ecm_mode) { size = len; } else { rndis_data_packet_t* r = (rndis_data_packet_t*)((void*)pnt); if (len >= sizeof(rndis_data_packet_t)) { if ((r->MessageType == REMOTE_NDIS_PACKET_MSG) && (r->MessageLength <= len)) { if ((r->DataOffset + offsetof(rndis_data_packet_t, DataOffset) + r->DataLength) <= len) { pnt = &_netd_epbuf.rx[r->DataOffset + offsetof(rndis_data_packet_t, DataOffset)]; size = r->DataLength; } } } } if (!tud_network_recv_cb(pnt, (uint16_t)size)) { /* if a buffer was never handled by user code, we must renew on the user's behalf */ tud_network_recv_renew(); } } bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; /* new packet received */ if (ep_addr == _netd_itf.ep_out) { handle_incoming_packet(xferred_bytes); } /* data transmission finished */ if (ep_addr == _netd_itf.ep_in) { /* TinyUSB requires the class driver to implement ZLP (since ZLP usage is class-specific) */ if (xferred_bytes && (0 == (xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE))) { do_in_xfer(NULL, 0); /* a ZLP is needed */ } else { /* we're finally finished */ can_xmit = true; } } if (_netd_itf.ecm_mode && (ep_addr == _netd_itf.ep_notif)) { // Notification transfer complete - endpoint is now free // Don't automatically send speed change notification after link state changes } return true; } bool tud_network_can_xmit(uint16_t size) { (void)size; return can_xmit; } void tud_network_xmit(void *ref, uint16_t arg) { if (!can_xmit) { return; } uint16_t len = (_netd_itf.ecm_mode) ? 0 : CFG_TUD_NET_PACKET_PREFIX_LEN; uint8_t* data = _netd_epbuf.tx + len; len += tud_network_xmit_cb(data, ref, arg); if (!_netd_itf.ecm_mode) { rndis_data_packet_t *hdr = (rndis_data_packet_t *) ((void*) _netd_epbuf.tx); memset(hdr, 0, sizeof(rndis_data_packet_t)); hdr->MessageType = REMOTE_NDIS_PACKET_MSG; hdr->MessageLength = len; hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset); hdr->DataLength = len - sizeof(rndis_data_packet_t); } do_in_xfer(_netd_epbuf.tx, len); } // Set the network link state (up/down) and notify the host void tud_network_link_state(uint8_t rhport, bool is_up) { (void)rhport; if (_netd_itf.ecm_mode) { ecm_link_is_up = is_up; // For ECM mode, send network connection notification only // Don't trigger speed change notification for link state changes ecm_notify_t notify = { .header = { .bmRequestType = 0xA1, .bRequest = 0, /* NETWORK_CONNECTION */ .wValue = is_up ? 1 : 0, /* 0 = disconnected, 1 = connected */ .wLength = 0, }, }; notify.header.wIndex = _netd_itf.itf_num; netd_report((uint8_t *)¬ify, sizeof(notify.header)); } else { // For RNDIS mode, we would need to implement RNDIS status indication // This is more complex and requires RNDIS_INDICATE_STATUS_MSG // For now, RNDIS doesn't support dynamic link state changes (void)is_up; } } #endif ================================================ FILE: src/class/net/ncm.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * Copyright (c) 2024, Hardy Griech * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_NCM_H_ #define TUSB_NCM_H_ #include "common/tusb_common.h" // NTB buffers size for reception side, must be >> MTU to avoid TCP retransmission (driver issue ?) // Linux use 2048 as minimal size #ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 #endif // NTB buffers size for reception side, must be > MTU // Linux use 2048 as minimal size #ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 #endif // Number of NTB buffers for reception side // Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements // On Full-Speed (RP2040) : // 1 - good performance // 2 - up to 30% more performance with iperf with small packets // >2 - no performance gain // On High-Speed (STM32F7) : // No performance gain #ifndef CFG_TUD_NCM_OUT_NTB_N #define CFG_TUD_NCM_OUT_NTB_N 1 #endif // Number of NTB buffers for transmission side // Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements // On Full-Speed (RP2040) : // 1 - good performance but SystemView shows lost events (on load test) // 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" // happens from time to time with SystemView // 3 - "tud_network_can_xmit: request blocked" never happens // >3 - no performance gain // On High-Speed (STM32F7) : // No performance gain #ifndef CFG_TUD_NCM_IN_NTB_N #define CFG_TUD_NCM_IN_NTB_N 1 #endif // How many datagrams it is allowed to put into an NTB for transmission side #ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 #endif // This tells the host how many datagrams it is allowed to put into an NTB #ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 #endif // Table 6.2 Class-Specific Request Codes for Network Control Model subclass typedef enum { NCM_SET_ETHERNET_MULTICAST_FILTERS = 0x40, NCM_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41, NCM_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42, NCM_SET_ETHERNET_PACKET_FILTER = 0x43, NCM_GET_ETHERNET_STATISTIC = 0x44, NCM_GET_NTB_PARAMETERS = 0x80, NCM_GET_NET_ADDRESS = 0x81, NCM_SET_NET_ADDRESS = 0x82, NCM_GET_NTB_FORMAT = 0x83, NCM_SET_NTB_FORMAT = 0x84, NCM_GET_NTB_INPUT_SIZE = 0x85, NCM_SET_NTB_INPUT_SIZE = 0x86, NCM_GET_MAX_DATAGRAM_SIZE = 0x87, NCM_SET_MAX_DATAGRAM_SIZE = 0x88, NCM_GET_CRC_MODE = 0x89, NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; #define NTH16_SIGNATURE 0x484D434E #define NDP16_SIGNATURE_NCM0 0x304D434E #define NDP16_SIGNATURE_NCM1 0x314D434E typedef struct TU_ATTR_PACKED { uint16_t wLength; uint16_t bmNtbFormatsSupported; uint32_t dwNtbInMaxSize; uint16_t wNdbInDivisor; uint16_t wNdbInPayloadRemainder; uint16_t wNdbInAlignment; uint16_t wReserved; uint32_t dwNtbOutMaxSize; uint16_t wNdbOutDivisor; uint16_t wNdbOutPayloadRemainder; uint16_t wNdbOutAlignment; uint16_t wNtbOutMaxDatagrams; } ntb_parameters_t; typedef struct TU_ATTR_PACKED { uint32_t dwSignature; uint16_t wHeaderLength; uint16_t wSequence; uint16_t wBlockLength; uint16_t wNdpIndex; } nth16_t; typedef struct TU_ATTR_PACKED { uint16_t wDatagramIndex; uint16_t wDatagramLength; } ndp16_datagram_t; typedef struct TU_ATTR_PACKED { uint32_t dwSignature; uint16_t wLength; uint16_t wNextNdpIndex; //ndp16_datagram_t datagram[]; } ndp16_t; typedef union TU_ATTR_PACKED { struct { nth16_t nth; ndp16_t ndp; ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; }; uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; } xmit_ntb_t; typedef union TU_ATTR_PACKED { struct { nth16_t nth; // only the header is at a guaranteed position }; uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; } recv_ntb_t; typedef struct { tusb_control_request_t header; uint32_t downlink; uint32_t uplink; } ncm_notify_t; #endif ================================================ FILE: src/class/net/ncm_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech * Copyright (c) 2020 Jacob Berg Potter * Copyright (c) 2020 Peter Lawrence * * 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. * * This file is part of the TinyUSB stack. */ /** * Small Glossary (from the spec) * -------------- * Datagram - A collection of bytes forming a single item of information, passed as a unit from source to destination. * NCM - Network Control Model * NDP - NCM Datagram Pointer: NTB structure that delineates Datagrams (typically Ethernet frames) within an NTB * NTB - NCM Transfer Block: a data structure for efficient USB encapsulation of one or more datagrams * Each NTB is designed to be a single USB transfer * NTH - NTB Header: a data structure at the front of each NTB, which provides the information needed to validate * the NTB and begin decoding * * Some explanations * ----------------- * - rhport is the USB port of the device, in most cases "0" * - itf_data_alt if != 0 -> data xmit/recv are allowed (see spec) * - ep_in IN endpoints take data from the device intended to go in to the host (the device transmits) * - ep_out OUT endpoints send data out of the host to the device (the device receives) */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_NCM) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "ncm.h" #include "net_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_NCM_LOG_LEVEL #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) // Alignment must be 4 #define TUD_NCM_ALIGNMENT 4 // calculate alignment of xmit datagrams within an NTB #define XMIT_ALIGN_OFFSET(x) ((TUD_NCM_ALIGNMENT - ((x) & (TUD_NCM_ALIGNMENT - 1))) & (TUD_NCM_ALIGNMENT - 1)) //----------------------------------------------------------------------------- // // Module global things // #define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N #define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N typedef struct { // general uint8_t ep_in; // endpoint for outgoing datagrams (naming is a little bit confusing) uint8_t ep_out; // endpoint for incoming datagrams (naming is a little bit confusing) uint8_t ep_notif; // endpoint for notifications uint8_t itf_num; // interface number uint8_t itf_data_alt; // ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) uint8_t rhport; // storage of \a rhport because some callbacks are done without it // recv handling recv_ntb_t *recv_free_ntb[RECV_NTB_N]; // free list of recv NTBs recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; // NTBs waiting for transmission to glue logic (circular buffer) #if RECV_NTB_N > 1 uint8_t recv_ready_head; // head index for recv_ready_ntb circular buffer uint8_t recv_ready_tail; // tail index for recv_ready_ntb circular buffer uint8_t recv_ready_count; // number of elements in recv_ready_ntb circular buffer #endif recv_ntb_t *recv_tinyusb_ntb; // buffer for the running transfer TinyUSB -> driver recv_ntb_t *recv_glue_ntb; // buffer for the running transfer driver -> glue logic uint16_t recv_glue_ntb_datagram_ndx; // index into \a recv_glue_ntb_datagram // xmit handling xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; // free list of xmit NTBs xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; // NTBs waiting for transmission to TinyUSB (circular buffer) #if XMIT_NTB_N > 1 uint8_t xmit_ready_head; // head index for xmit_ready_ntb circular buffer uint8_t xmit_ready_tail; // tail index for xmit_ready_ntb circular buffer uint8_t xmit_ready_count; // number of elements in xmit_ready_ntb circular buffer #endif xmit_ntb_t *xmit_tinyusb_ntb; // buffer for the running transfer driver -> TinyUSB xmit_ntb_t *xmit_glue_ntb; // buffer for the running transfer glue logic -> driver uint16_t xmit_sequence; // NTB sequence counter uint16_t xmit_glue_ntb_datagram_ndx; // index into \a xmit_glue_ntb_datagram // notification handling enum { NOTIFICATION_SPEED, NOTIFICATION_CONNECTED, NOTIFICATION_DONE } notification_xmit_state; // state of notification transmission bool notification_xmit_is_running; // notification is currently transmitted bool link_is_up; // current link state // misc bool tud_network_recv_renew_active; // tud_network_recv_renew() is active (avoid recursive invocations) bool tud_network_recv_renew_process_again; // tud_network_recv_renew() should process again } ncm_interface_t; typedef struct { struct { TUD_EPBUF_TYPE_DEF(recv_ntb_t, ntb); } recv[RECV_NTB_N]; struct { TUD_EPBUF_TYPE_DEF(xmit_ntb_t, ntb); } xmit[XMIT_NTB_N]; TUD_EPBUF_TYPE_DEF(ncm_notify_t, epnotif); } ncm_epbuf_t; static ncm_interface_t ncm_interface; CFG_TUD_MEM_SECTION static ncm_epbuf_t ncm_epbuf; /** * This is the NTB parameter structure * * \attention * We are lucky, that byte order is correct */ TU_ATTR_ALIGNED(4) static const ntb_parameters_t ntb_parameters = { .wLength = sizeof(ntb_parameters_t), .bmNtbFormatsSupported = 0x01,// 16-bit NTB supported .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, .wNdbInDivisor = 1, .wNdbInPayloadRemainder = 0, .wNdbInAlignment = TUD_NCM_ALIGNMENT, .wReserved = 0, .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, .wNdbOutDivisor = 1, .wNdbOutPayloadRemainder = 0, .wNdbOutAlignment = TUD_NCM_ALIGNMENT, .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; // Some confusing remarks about wNtbOutMaxDatagrams... // ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup // ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error // ==6 -> SystemView runs fine, iperf also // >6 -> iperf starts to show errors // -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? // // iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done // sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 // //----------------------------------------------------------------------------- // // everything about notifications // /** * Transmit next notification to the host (if appropriate). * Notifications are transferred to the host once during connection setup. */ static void notification_xmit(uint8_t rhport, bool force_next) { TU_LOG_DRV("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); if (!force_next && ncm_interface.notification_xmit_is_running) { return; } if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { TU_LOG_DRV(" NOTIFICATION_SPEED\n"); ncm_notify_t notify_speed_change = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wValue = 0, .wIndex = ncm_interface.itf_num, .wLength = 8 } }; if (tud_speed_get() == TUSB_SPEED_HIGH) { notify_speed_change.downlink = 480000000; notify_speed_change.uplink = 480000000; } else { notify_speed_change.downlink = 12000000; notify_speed_change.uplink = 12000000; } uint16_t notif_len = sizeof(notify_speed_change.header) + notify_speed_change.header.wLength; ncm_epbuf.epnotif = notify_speed_change; usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_epbuf.epnotif, notif_len, false); ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; ncm_interface.notification_xmit_is_running = true; } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { TU_LOG_DRV(" NOTIFICATION_CONNECTED\n"); ncm_notify_t notify_connected = { .header = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_NETWORK_CONNECTION, .wValue = ncm_interface.link_is_up ? 1 : 0, /* Dynamic link state */ .wIndex = ncm_interface.itf_num, .wLength = 0, }, }; uint16_t notif_len = sizeof(notify_connected.header) + notify_connected.header.wLength; ncm_epbuf.epnotif = notify_connected; usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_epbuf.epnotif, notif_len, false); ncm_interface.notification_xmit_state = NOTIFICATION_DONE; ncm_interface.notification_xmit_is_running = true; } else { TU_LOG_DRV(" NOTIFICATION_FINISHED\n"); ncm_interface.notification_xmit_is_running = false; } } // notification_xmit //----------------------------------------------------------------------------- // // everything about packet transmission (driver -> TinyUSB) // /** * Put NTB into the transmitter free list. */ static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) { TU_LOG_DRV("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); if (free_ntb == NULL) { // can happen due to ZLPs return; } for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_free_ntb[i] == NULL) { ncm_interface.xmit_free_ntb[i] = free_ntb; return; } } TU_LOG_DRV("(EE) xmit_put_ntb_into_free_list - no entry in free list\n");// this should not happen } // xmit_put_ntb_into_free_list /** * Get an NTB from the free list */ static xmit_ntb_t *xmit_get_free_ntb(void) { TU_LOG_DRV("xmit_get_free_ntb()\n"); for (int i = 0; i < XMIT_NTB_N; ++i) { if (ncm_interface.xmit_free_ntb[i] != NULL) { xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; ncm_interface.xmit_free_ntb[i] = NULL; return free; } } return NULL; } // xmit_get_free_ntb /** * Put a filled NTB into the ready list */ static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) { TU_LOG_DRV("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); #if XMIT_NTB_N == 1 ncm_interface.xmit_ready_ntb[0] = ready_ntb; #else if (ncm_interface.xmit_ready_count >= XMIT_NTB_N) { TU_LOG_DRV("(EE) xmit_put_ntb_into_ready_list: ready list full\n");// this should not happen return; } ncm_interface.xmit_ready_ntb[ncm_interface.xmit_ready_head] = ready_ntb; ncm_interface.xmit_ready_head = (ncm_interface.xmit_ready_head + 1) % XMIT_NTB_N; ncm_interface.xmit_ready_count++; #endif } // xmit_put_ntb_into_ready_list /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ static xmit_ntb_t *xmit_get_next_ready_ntb(void) { #if XMIT_NTB_N == 1 xmit_ntb_t *r = ncm_interface.xmit_ready_ntb[0]; ncm_interface.xmit_ready_ntb[0] = NULL; TU_LOG_DRV("xmit_get_next_ready_ntb: %p\n", r); return r; #else if (ncm_interface.xmit_ready_count == 0) { return NULL; // empty } xmit_ntb_t *r = ncm_interface.xmit_ready_ntb[ncm_interface.xmit_ready_tail]; ncm_interface.xmit_ready_tail = (ncm_interface.xmit_ready_tail + 1) % XMIT_NTB_N; ncm_interface.xmit_ready_count--; TU_LOG_DRV("xmit_get_next_ready_ntb: %p\n", r); return r; #endif } // xmit_get_next_ready_ntb /** * Transmit a ZLP if required * * \note * Insertion of the ZLPs is a little bit different then described in the spec. * But the below implementation actually works. Don't know if this is a spec * or TinyUSB issue. * * \pre * This must be called from netd_xfer_cb() so that ep_in is ready */ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { TU_LOG_DRV("xmit_insert_required_zlp(%d,%ld)\n", rhport, xferred_bytes); if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { return false; } TU_ASSERT(ncm_interface.itf_data_alt == 1, false); TU_ASSERT(!usbd_edpt_busy(rhport, ncm_interface.ep_in), false); TU_LOG_DRV("xmit_insert_required_zlp! (%u)\n", (unsigned) xferred_bytes); // start transmission of the ZLP usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0, false); return true; } // xmit_insert_required_zlp /** * Start transmission if it there is a waiting packet and if can be done from interface side. */ static void xmit_start_if_possible(uint8_t rhport) { TU_LOG_DRV("xmit_start_if_possible()\n"); if (ncm_interface.xmit_tinyusb_ntb != NULL) { TU_LOG_DRV(" !xmit_start_if_possible 1\n"); return; } if (ncm_interface.itf_data_alt != 1) { TU_LOG_DRV("(EE) !xmit_start_if_possible 2\n"); return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { TU_LOG_DRV(" !xmit_start_if_possible 3\n"); return; } ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); if (ncm_interface.xmit_tinyusb_ntb == NULL) { if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { // -> really nothing is waiting return; } ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; ncm_interface.xmit_glue_ntb = NULL; } #if CFG_TUD_NCM_LOG_LEVEL >= 3 { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data[i], len); } #endif if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { TU_LOG_DRV(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); } // Kick off an endpoint transfer usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, false); } // xmit_start_if_possible /** * check if a new datagram fits into the current NTB */ static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) { TU_LOG_DRV("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb == NULL) { return false; } if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { return false; } if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_IN_NTB_MAX_SIZE) { return false; } return true; } // xmit_requested_datagram_fits_into_current_ntb /** * Setup an NTB for the glue logic */ static bool xmit_setup_next_glue_ntb(void) { TU_LOG_DRV("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); if (ncm_interface.xmit_glue_ntb != NULL) { // put NTB into waiting list (the new datagram did not fit in) xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); } ncm_interface.xmit_glue_ntb = xmit_get_free_ntb();// get next buffer (if any) if (ncm_interface.xmit_glue_ntb == NULL) { TU_LOG_DRV(" xmit_setup_next_glue_ntb - nothing free\n");// should happen rarely return false; } ncm_interface.xmit_glue_ntb_datagram_ndx = 0; xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; // Fill in NTB header ntb->nth.dwSignature = NTH16_SIGNATURE; ntb->nth.wHeaderLength = sizeof(ntb->nth); ntb->nth.wSequence = ncm_interface.xmit_sequence++; ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); ntb->nth.wNdpIndex = sizeof(ntb->nth); // Fill in NDP16 header and terminator ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); ntb->ndp.wNextNdpIndex = 0; memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); return true; } // xmit_setup_next_glue_ntb //----------------------------------------------------------------------------- // // all the recv_*() stuff (TinyUSB -> driver -> glue logic) // /** * Return pointer to an available receive buffer or NULL. * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. */ static recv_ntb_t *recv_get_free_ntb(void) { TU_LOG_DRV("recv_get_free_ntb()\n"); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] != NULL) { recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; ncm_interface.recv_free_ntb[i] = NULL; return free; } } return NULL; } // recv_get_free_ntb /** * Get the next NTB from the ready list (and remove it from the list). * If the ready list is empty, return NULL. */ static recv_ntb_t *recv_get_next_ready_ntb(void) { #if RECV_NTB_N == 1 recv_ntb_t *r = ncm_interface.recv_ready_ntb[0]; ncm_interface.recv_ready_ntb[0] = NULL; TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); return r; #else if (ncm_interface.recv_ready_count == 0) { return NULL; // empty } recv_ntb_t *r = ncm_interface.recv_ready_ntb[ncm_interface.recv_ready_tail]; ncm_interface.recv_ready_tail = (ncm_interface.recv_ready_tail + 1) % RECV_NTB_N; ncm_interface.recv_ready_count--; TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); return r; #endif } // recv_get_next_ready_ntb /** * Put NTB into the receiver free list. */ static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) { TU_LOG_DRV("recv_put_ntb_into_free_list(%p)\n", free_ntb); for (int i = 0; i < RECV_NTB_N; ++i) { if (ncm_interface.recv_free_ntb[i] == NULL) { ncm_interface.recv_free_ntb[i] = free_ntb; return; } } TU_LOG_DRV("(EE) recv_put_ntb_into_free_list - no entry in free list\n");// this should not happen } // recv_put_ntb_into_free_list /** * \a ready_ntb holds a validated NTB, * put this buffer into the waiting list. */ static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) { TU_LOG_DRV("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); #if RECV_NTB_N == 1 ncm_interface.recv_ready_ntb[0] = ready_ntb; #else if (ncm_interface.recv_ready_count >= RECV_NTB_N) { TU_LOG_DRV("(EE) recv_put_ntb_into_ready_list: ready list full\n");// this should not happen return; } ncm_interface.recv_ready_ntb[ncm_interface.recv_ready_head] = ready_ntb; ncm_interface.recv_ready_head = (ncm_interface.recv_ready_head + 1) % RECV_NTB_N; ncm_interface.recv_ready_count++; #endif } // recv_put_ntb_into_ready_list /** * If possible, start a new reception TinyUSB -> driver. */ static void recv_try_to_start_new_reception(uint8_t rhport) { TU_LOG_DRV("recv_try_to_start_new_reception(%d)\n", rhport); if (ncm_interface.itf_data_alt != 1) { return; } if (ncm_interface.recv_tinyusb_ntb != NULL) { return; } if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { return; } ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); if (ncm_interface.recv_tinyusb_ntb == NULL) { return; } // initiate transfer TU_LOG_DRV(" start reception\n"); bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE, false); if (!r) { recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); ncm_interface.recv_tinyusb_ntb = NULL; } } // recv_try_to_start_new_reception /** * Validate incoming datagram. * \return true if valid * * \note * \a ndp16->wNextNdpIndex != 0 is not supported */ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { const nth16_t *nth16 = &(ntb->nth); TU_LOG_DRV("recv_validate_datagram(%p, %d)\n", ntb, (int) len); // check header if (nth16->wHeaderLength != sizeof(nth16_t)) { TU_LOG_DRV("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); return false; } if (nth16->dwSignature != NTH16_SIGNATURE) { TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) nth16->dwSignature); return false; } if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { TU_LOG_DRV("(EE) ill min len: %lu\n", len); return false; } if (nth16->wBlockLength > len) { TU_LOG_DRV("(EE) ill block length: %d > %lu\n", nth16->wBlockLength, len); return false; } if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { TU_LOG_DRV("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); return false; } if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { TU_LOG_DRV("(EE) ill position of first ndp: %d (%lu)\n", nth16->wNdpIndex, len); return false; } // check (first) NDP(16) const ndp16_t *ndp16 = (const ndp16_t *) (ntb->data + nth16->wNdpIndex); if (ndp16->wLength < sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { TU_LOG_DRV("(EE) ill ndp16 length: %d\n", ndp16->wLength); return false; } if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) ndp16->dwSignature); return false; } if (ndp16->wNextNdpIndex != 0) { TU_LOG_DRV("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); return false; } const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *) (ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); int ndx = 0; uint16_t max_ndx = (uint16_t) ((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); if (max_ndx > 2) { // number of datagrams in NTB > 1 TU_LOG_DRV("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); } if (ndp16_datagram[max_ndx - 1].wDatagramIndex != 0 || ndp16_datagram[max_ndx - 1].wDatagramLength != 0) { TU_LOG_DRV(" max_ndx != 0\n"); return false; } while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); if (ndp16_datagram[ndx].wDatagramIndex > len) { TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); return false; } if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%lu)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); return false; } ++ndx; } #if CFG_TUD_NCM_LOG_LEVEL >= 3 TU_LOG_BUF(3, ntb->data[i], len); #endif // -> ntb contains a valid packet structure // ok... I did not check for garbage within the datagram indices... return true; } // recv_validate_datagram /** * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. */ static void recv_transfer_datagram_to_glue_logic(void) { TU_LOG_DRV("recv_transfer_datagram_to_glue_logic()\n"); if (ncm_interface.recv_glue_ntb == NULL) { ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); TU_LOG_DRV(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); ncm_interface.recv_glue_ntb_datagram_ndx = 0; } if (ncm_interface.recv_glue_ntb != NULL) { const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *) (ncm_interface.recv_glue_ntb->data + ncm_interface.recv_glue_ntb->nth.wNdpIndex + sizeof(ndp16_t)); if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { TU_LOG_DRV("(EE) SOMETHING WENT WRONG 1\n"); } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { TU_LOG_DRV("(EE) SOMETHING WENT WRONG 2\n"); } else { uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; TU_LOG_DRV(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { // send datagram successfully to glue logic TU_LOG_DRV(" OK\n"); datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; if (datagramIndex != 0 && datagramLength != 0) { // -> next datagram ++ncm_interface.recv_glue_ntb_datagram_ndx; } else { // end of datagrams reached recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); ncm_interface.recv_glue_ntb = NULL; } } } } } // recv_transfer_datagram_to_glue_logic //----------------------------------------------------------------------------- // // all the tud_network_*() stuff (glue logic -> driver) // /** * Check if the glue logic is allowed to call tud_network_xmit(). * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy * and transmission operation. */ bool tud_network_can_xmit(uint16_t size) { TU_LOG_DRV("tud_network_can_xmit(%d)\n", size); TU_ASSERT(size <= CFG_TUD_NCM_IN_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)), false); if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { // -> everything is fine return true; } xmit_start_if_possible(ncm_interface.rhport); TU_LOG_DRV("(II) tud_network_can_xmit: request blocked\n");// could happen if all xmit buffers are full (but should happen rarely) return false; } // tud_network_can_xmit /** * Put a datagram into a waiting NTB. * If currently no transmission is started, then initiate transmission. */ void tud_network_xmit(void *ref, uint16_t arg) { TU_LOG_DRV("tud_network_xmit(%p, %d)\n", ref, arg); if (ncm_interface.xmit_glue_ntb == NULL) { TU_LOG_DRV("(EE) tud_network_xmit: no buffer\n");// must not happen (really) return; } xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; // copy new datagram to the end of the current NTB uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); // correct NTB internals ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; ncm_interface.xmit_glue_ntb_datagram_ndx += 1; ntb->nth.wBlockLength += (uint16_t) (size + XMIT_ALIGN_OFFSET(size)); if (ntb->nth.wBlockLength > CFG_TUD_NCM_IN_NTB_MAX_SIZE) { TU_LOG_DRV("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) return; } xmit_start_if_possible(ncm_interface.rhport); } // tud_network_xmit /** * Keep the receive logic busy and transfer pending packets to the glue logic. * Avoid recursive calls due to wrong expectations of the net glue logic, * see https://github.com/hathach/tinyusb/issues/2711 */ void tud_network_recv_renew(void) { TU_LOG_DRV("tud_network_recv_renew()\n"); ncm_interface.tud_network_recv_renew_process_again = true; if (ncm_interface.tud_network_recv_renew_active) { TU_LOG_DRV("Re-entrant into tud_network_recv_renew, will process later\n"); return; } while (ncm_interface.tud_network_recv_renew_process_again) { ncm_interface.tud_network_recv_renew_process_again = false; // If the current function is called within recv_transfer_datagram_to_glue_logic, // tud_network_recv_renew_process_again will become true, and the loop will run again // Otherwise the loop will not run again ncm_interface.tud_network_recv_renew_active = true; recv_transfer_datagram_to_glue_logic(); ncm_interface.tud_network_recv_renew_active = false; } recv_try_to_start_new_reception(ncm_interface.rhport); } // tud_network_recv_renew /** * Same as tud_network_recv_renew() but knows \a rhport */ static void tud_network_recv_renew_r(uint8_t rhport) { TU_LOG_DRV("tud_network_recv_renew_r(%d)\n", rhport); ncm_interface.rhport = rhport; tud_network_recv_renew(); } // tud_network_recv_renew /** * Set the link state and send notification to host */ void tud_network_link_state(uint8_t rhport, bool is_up) { TU_LOG_DRV("tud_network_link_state(%d, %d)\n", rhport, is_up); if (ncm_interface.link_is_up == is_up) { // No change in link state return; } ncm_interface.link_is_up = is_up; // Only send notification if we have an active data interface if (ncm_interface.itf_data_alt != 1) { TU_LOG_DRV(" link state notification skipped (interface not active)\n"); return; } // Reset notification state to send speed change notification first, then link state notification ncm_interface.notification_xmit_state = NOTIFICATION_SPEED; // Trigger notification transmission notification_xmit(rhport, false); } //----------------------------------------------------------------------------- // // all the netd_*() stuff (interface TinyUSB -> driver) // /** * Initialize the driver data structures. * Might be called several times. */ void netd_init(void) { TU_LOG_DRV("netd_init()\n"); memset(&ncm_interface, 0, sizeof(ncm_interface)); for (int i = 0; i < XMIT_NTB_N; ++i) { ncm_interface.xmit_free_ntb[i] = &ncm_epbuf.xmit[i].ntb; } for (int i = 0; i < RECV_NTB_N; ++i) { ncm_interface.recv_free_ntb[i] = &ncm_epbuf.recv[i].ntb; } // Default link state - can be configured via CFG_TUD_NCM_DEFAULT_LINK_UP #ifdef CFG_TUD_NCM_DEFAULT_LINK_UP ncm_interface.link_is_up = CFG_TUD_NCM_DEFAULT_LINK_UP; #else ncm_interface.link_is_up = true; // Default to link up if not set. #endif } // netd_init /** * Deinit driver */ bool netd_deinit(void) { return true; } /** * Resets the port. * In this driver this is the same as netd_init() */ void netd_reset(uint8_t rhport) { (void) rhport; netd_init(); } // netd_reset /** * Open the USB interface. * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints * - a specific order of elements in the descriptor is tested. * * \note * Actually all of the information could be read directly from \a itf_desc, because the * structure and the values are well known. But we do it this way. * * \post * - \a itf_num set * - \a ep_notif, \a ep_in and \a ep_out are set * - USB interface is open */ uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { TU_ASSERT(ncm_interface.ep_notif == 0, 0);// assure that the interface is only opened once ncm_interface.itf_num = itf_desc->bInterfaceNumber;// management interface // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries uint16_t drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = tu_desc_next(itf_desc); while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } // get notification endpoint TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0); ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const *) p_desc; TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); drv_len += 2 * sizeof(tusb_desc_endpoint_t); return drv_len; } // netd_open /** * Handle TinyUSB requests to process transfer events. */ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; if (ep_addr == ncm_interface.ep_out) { // new NTB received // - make the NTB valid // - if ready transfer datagrams to the glue logic for further processing // - if there is a free receive buffer, initiate reception if (!recv_validate_datagram(ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { // verification failed: ignore NTB and return it to free TU_LOG_DRV("Invalid datatagram. Ignoring NTB\n"); recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); } else { // packet ok -> put it into ready list recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); } ncm_interface.recv_tinyusb_ntb = NULL; tud_network_recv_renew_r(rhport); } else if (ep_addr == ncm_interface.ep_in) { // transmission of an NTB finished // - free the transmitted NTB buffer // - insert ZLPs when necessary // - if there is another transmit NTB waiting, try to start transmission xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); ncm_interface.xmit_tinyusb_ntb = NULL; if (!xmit_insert_required_zlp(rhport, xferred_bytes)) { xmit_start_if_possible(rhport); } } else if (ep_addr == ncm_interface.ep_notif) { // next transfer on notification channel notification_xmit(rhport, true); } return true; } // netd_xfer_cb /** * Respond to TinyUSB control requests. * At startup transmission of notification packets are done here. */ bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { if (stage != CONTROL_STAGE_SETUP) { return true; } switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); } break; case TUSB_REQ_SET_INTERFACE: { TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); ncm_interface.itf_data_alt = (uint8_t) request->wValue; if (ncm_interface.itf_data_alt == 1) { tud_network_recv_renew_r(rhport); notification_xmit(rhport, false); } else { // Reset notification state to send link state update when interface is re-activated ncm_interface.notification_xmit_state = NOTIFICATION_SPEED; } tud_control_status(rhport, request); } break; // unsupported request default: return false; } break; case TUSB_REQ_TYPE_CLASS: TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); switch (request->bRequest) { case NCM_GET_NTB_PARAMETERS: { // transfer NTB parameters to host. tud_control_xfer(rhport, request, (void *) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); } break; // unsupported request default: return false; } break; // unsupported request default: return false; } return true; } // netd_control_xfer_cb #endif // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) ================================================ FILE: src/class/net/net_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_NET_DEVICE_H_ #define TUSB_NET_DEVICE_H_ #include #include "class/cdc/cdc.h" #if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM #error "Cannot enable both ECM_RNDIS and NCM network drivers" #endif /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) /* Maximum Transmission Unit (in bytes) of the network, including Ethernet header */ #ifndef CFG_TUD_NET_MTU #define CFG_TUD_NET_MTU 1514 #endif // Table 4.3 Data Class Interface Protocol Codes typedef enum { NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 } ncm_data_interface_protocol_code_t; #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Implemented by Application //--------------------------------------------------------------------+ #if CFG_TUD_ECM_RNDIS extern void rndis_class_set_handler(uint8_t *data, int size); #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // indicate to network driver that client has finished with the packet provided to network_recv_cb() void tud_network_recv_renew(void); // poll network driver for its ability to accept another packet to transmit bool tud_network_can_xmit(uint16_t size); // if network_can_xmit() returns true, network_xmit() can be called once void tud_network_xmit(void *ref, uint16_t arg); //--------------------------------------------------------------------+ // Application Callbacks (WEAK is optional) //--------------------------------------------------------------------+ // client must provide this: return false if the packet buffer was not accepted bool tud_network_recv_cb(const uint8_t *src, uint16_t size); // client must provide this: copy from network stack packet pointer to dst uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg); //------------- ECM/RNDIS -------------// // client must provide this: initialize any network state back to the beginning void tud_network_init_cb(void); // client must provide this: 48-bit MAC address // TODO removed later since it is not part of tinyusb stack extern uint8_t tud_network_mac_address[6]; //------------- NCM -------------// // Set the network link state (up/down) and notify the host void tud_network_link_state(uint8_t rhport, bool is_up); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void netd_init (void); bool netd_deinit (void); void netd_reset (uint8_t rhport); uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void netd_report (uint8_t *buf, uint16_t len); #ifdef __cplusplus } #endif #endif /* TUSB_NET_DEVICE_H_ */ ================================================ FILE: src/class/printer/printer.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_PRINTER_H_ #define TUSB_PRINTER_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif /// Printer Class Specific Control Request typedef enum { TUSB_PRINTER_REQUEST_GET_DEVICE_ID = 0x00, ///< Get device ID TUSB_PRINTER_REQUEST_GET_PORT_STATUS = 0x01, ///< Get port status TUSB_PRINTER_REQUEST_SOFT_RESET = 0x02, ///< Soft reset } tusb_printer_request_type_t; /// Printer Port Status (returned by GET_PORT_STATUS request) /// USB Printer Class spec 1.1, Section 4.2 typedef union TU_ATTR_PACKED { uint8_t status; struct TU_ATTR_PACKED { uint8_t reserved0 : 3; ///< Reserved (bits 0-2) uint8_t not_error : 1; ///< 1 = no error, 0 = error uint8_t selected : 1; ///< 1 = selected (online), 0 = not selected uint8_t paper_empty : 1; ///< 1 = paper empty, 0 = paper not empty uint8_t reserved6 : 2; ///< Reserved (bits 6-7) } status_bm; } tusb_printer_port_status_t; TU_VERIFY_STATIC(sizeof(tusb_printer_port_status_t) == 1, "size is not correct"); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/printer/printer_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "printer_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t itf_num; /*------------- From this point, data is not cleared by bus reset -------------*/ tu_edpt_stream_t rx_stream; tu_edpt_stream_t tx_stream; uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; } printer_interface_t; #define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_stream) #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_RX_EPSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_TX_EPSIZE); } printer_epbuf_t; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; #endif static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; //--------------------------------------------------------------------+ // INTERNAL HELPERS //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint8_t _find_itf(uint8_t ep_addr) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { const printer_interface_t *p = &_printer_itf[i]; if (ep_addr == p->rx_stream.ep_addr || ep_addr == p->tx_stream.ep_addr) { return i; } } return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf) { (void)itf; } TU_ATTR_WEAK void tud_printer_tx_complete_cb(uint8_t itf) { (void)itf; } TU_ATTR_WEAK void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request) { (void)itf; (void)request; } TU_ATTR_WEAK uint8_t const *tud_printer_get_device_id_cb(uint8_t itf) { (void)itf; return NULL; } TU_ATTR_WEAK uint8_t tud_printer_get_port_status_cb(uint8_t itf) { (void)itf; return 0x18; // not error, selected, paper not empty } TU_ATTR_WEAK void tud_printer_soft_reset_cb(uint8_t itf) { (void)itf; } //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ uint32_t tud_printer_n_read_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_PRINTER, 0); return tu_edpt_stream_read_available(&_printer_itf[itf].rx_stream); } uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_PRINTER, 0); return tu_edpt_stream_read(&_printer_itf[itf].rx_stream, buffer, bufsize); } bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { TU_VERIFY(itf < CFG_TUD_PRINTER); return tu_edpt_stream_peek(&_printer_itf[itf].rx_stream, chr); } void tud_printer_n_read_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_PRINTER, ); printer_interface_t *p = &_printer_itf[itf]; tu_edpt_stream_clear(&p->rx_stream); tu_edpt_stream_read_xfer(&p->rx_stream); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_PRINTER, 0); return tu_edpt_stream_write(&_printer_itf[itf].tx_stream, buffer, bufsize); } uint32_t tud_printer_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_PRINTER, 0); return tu_edpt_stream_write_xfer(&_printer_itf[itf].tx_stream); } uint32_t tud_printer_n_write_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_PRINTER, 0); return tu_edpt_stream_write_available(&_printer_itf[itf].tx_stream); } bool tud_printer_n_write_clear(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_PRINTER); tu_edpt_stream_clear(&_printer_itf[itf].tx_stream); return true; } //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ void printerd_init(void) { tu_memclr(_printer_itf, sizeof(_printer_itf)); for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p = &_printer_itf[i]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *epout_buf = NULL; uint8_t *epin_buf = NULL; #else uint8_t *epout_buf = _printer_epbuf[i].epout; uint8_t *epin_buf = _printer_epbuf[i].epin; #endif tu_edpt_stream_init(&p->rx_stream, false, false, false, p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p->tx_stream, false, true, true, p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, epin_buf); } } bool printerd_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p = &_printer_itf[i]; tu_edpt_stream_deinit(&p->rx_stream); tu_edpt_stream_deinit(&p->tx_stream); } return true; } void printerd_reset(uint8_t rhport) { (void)rhport; for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { printer_interface_t *p = &_printer_itf[i]; tu_memclr(p, ITF_MEM_RESET_SIZE); tu_edpt_stream_close(&p->rx_stream); tu_edpt_stream_close(&p->tx_stream); } } uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); // Find available interface slot uint8_t const printer_id = _find_itf(0); TU_ASSERT(printer_id < CFG_TUD_PRINTER, 0); printer_interface_t *p = &_printer_itf[printer_id]; p->itf_num = itf_desc->bInterfaceNumber; //------------- Endpoints -------------// const uint8_t *p_desc = (const uint8_t *)itf_desc; const uint8_t *desc_end = p_desc + max_len; uint16_t drv_len = sizeof(tusb_desc_interface_t); p_desc = tu_desc_next(itf_desc); for (uint8_t e = 0; e < itf_desc->bNumEndpoints; e++) { TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p->tx_stream; tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_PRINTER_TX_EPSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p->rx_stream; tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream_rx); TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); } drv_len += sizeof(tusb_desc_endpoint_t); p_desc = tu_desc_next(p_desc); } return drv_len; } bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); // GET_DEVICE_ID: wIndex = (interface_number << 8) | alt_setting // GET_PORT_STATUS / SOFT_RESET: wIndex = interface_number uint8_t itf_num; if (TUSB_PRINTER_REQUEST_GET_DEVICE_ID == request->bRequest) { itf_num = tu_u16_high(request->wIndex); } else { itf_num = tu_u16_low(request->wIndex); } // Find the printer instance index from the USB interface number uint8_t itf = TUSB_INDEX_INVALID_8; for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { if (_printer_itf[i].itf_num == itf_num) { itf = i; break; } } TU_VERIFY(itf < CFG_TUD_PRINTER); // https://www.usb.org/sites/default/files/usbprint11a021811.pdf if (stage == CONTROL_STAGE_SETUP) { switch (request->bRequest) { case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { const uint8_t *device_id = tud_printer_get_device_id_cb(itf); TU_VERIFY(device_id); const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); return tud_control_xfer(rhport, request, (void *)(uintptr_t)device_id, total_len); } case TUSB_PRINTER_REQUEST_GET_PORT_STATUS: { static uint8_t port_status; port_status = tud_printer_get_port_status_cb(itf); return tud_control_xfer(rhport, request, &port_status, sizeof(port_status)); } case TUSB_PRINTER_REQUEST_SOFT_RESET: tud_printer_soft_reset_cb(itf); tud_control_status(rhport, request); return true; default: return false; } } else if (stage == CONTROL_STAGE_ACK) { tud_printer_request_complete_cb(itf, request); } return true; } bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; uint8_t const itf = _find_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_PRINTER); printer_interface_t *p = &_printer_itf[itf]; // Received new data if (ep_addr == p->rx_stream.ep_addr) { tu_edpt_stream_read_xfer_complete(&p->rx_stream, xferred_bytes); if (!tu_edpt_stream_empty(&p->rx_stream)) { tud_printer_rx_cb(itf); } tu_edpt_stream_read_xfer(&p->rx_stream); } // Data sent to host if (ep_addr == p->tx_stream.ep_addr) { tud_printer_tx_complete_cb(itf); if (0 == tu_edpt_stream_write_xfer(&p->tx_stream)) { tu_edpt_stream_write_zlp_if_needed(&p->tx_stream, xferred_bytes); } } return true; } #endif ================================================ FILE: src/class/printer/printer_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2026 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_PRINTER_DEVICE_H_ #define TUSB_PRINTER_DEVICE_H_ #ifdef __cplusplus extern "C" { #endif #include "printer.h" //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_PRINTER_RX_EPSIZE #define CFG_TUD_PRINTER_RX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #ifndef CFG_TUD_PRINTER_TX_EPSIZE #define CFG_TUD_PRINTER_TX_EPSIZE TUD_EPSIZE_BULK_MAX #endif //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_PRINTER > 1 //--------------------------------------------------------------------+ // Get the number of bytes available for reading uint32_t tud_printer_n_read_available(uint8_t itf); // Read received bytes uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize); // Get the number of bytes available for writing uint32_t tud_printer_n_write_available(uint8_t itf); // Clear the received FIFO void tud_printer_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it bool tud_printer_n_peek(uint8_t itf, uint8_t *ui8); // Write data to host uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize); // Force sending data in the TX FIFO uint32_t tud_printer_n_write_flush(uint8_t itf); // Clear the transmit FIFO bool tud_printer_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read_available(void) { return tud_printer_n_read_available(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_available(void) { return tud_printer_n_write_available(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read(void *buffer, uint32_t bufsize) { return tud_printer_n_read(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline void tud_printer_read_flush(void) { tud_printer_n_read_flush(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_peek(uint8_t *ui8) { return tud_printer_n_peek(0, ui8); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write(const void *buffer, uint32_t bufsize) { return tud_printer_n_write(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_flush(void) { return tud_printer_n_write_flush(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_write_clear(void) { return tud_printer_n_write_clear(0); } //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data void tud_printer_rx_cb(uint8_t itf); // Invoked when last write transfer is completed void tud_printer_tx_complete_cb(uint8_t itf); // Invoked when host requests device ID string (IEEE 1284). // Application returns pointer to device ID buffer (must remain valid until transfer completes). // First 2 bytes of returned buffer must contain big-endian length (including the 2 length bytes). const uint8_t *tud_printer_get_device_id_cb(uint8_t itf); // Invoked when host requests port status. uint8_t tud_printer_get_port_status_cb(uint8_t itf); // Invoked when host requests soft reset. void tud_printer_soft_reset_cb(uint8_t itf); // Invoked when a control request is completed (GET_DEVICE_ID, GET_PORT_STATUS, etc.) void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void printerd_init(void); bool printerd_deinit(void); void printerd_reset(uint8_t rhport); uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request); bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/class/usbtmc/usbtmc.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 N Conrad * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_USBTMC_H__ #define TUSB_USBTMC_H__ #include "common/tusb_common.h" /* Implements USBTMC Revision 1.0, April 14, 2003 String descriptors must have a "LANGID=0x409"/US English string. Characters must be 0x20 (' ') to 0x7E ('~') ASCII, But MUST not contain: "/:?\* Also must not have leading or trailing space (' ') Device descriptor must state USB version 0x0200 or greater If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint. */ #define USBTMC_VERSION 0x0100 #define USBTMC_488_VERSION 0x0100 typedef enum { USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u, USBTMC_MSGID_DEV_DEP_MSG_IN = 2u, USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u, USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u, USBTMC_MSGID_USB488_TRIGGER = 128u, } usbtmc_msgid_enum; /// \brief Message header (For BULK OUT and BULK IN); 4 bytes typedef struct TU_ATTR_PACKED { uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum) uint8_t bTag ; ///< Transfer ID 1<=bTag<=255 uint8_t bTagInverse ; ///< Complement of the tag uint8_t _reserved ; ///< Must be 0x00 } usbtmc_msg_header_t; typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header; uint8_t data[8]; } usbtmc_msg_generic_t; /* Uses on the bulk-out endpoint: */ // Next 8 bytes are message-specific typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first struct TU_ATTR_PACKED { unsigned int EOM : 1 ; ///< EOM set on last byte } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_request_dev_dep_out; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length"); // Next 8 bytes are message-specific typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first struct TU_ATTR_PACKED { unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar } bmTransferAttributes; uint8_t TermChar; uint8_t _reserved[2]; } usbtmc_msg_request_dev_dep_in; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length"); /* Bulk-in headers */ typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header; uint32_t TransferSize; struct TU_ATTR_PACKED { uint8_t EOM: 1; ///< Last byte of transfer is the end of the message uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_dev_dep_msg_in_header_t; TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length"); /* Unsupported vendor things.... Are these ever used?*/ typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_out; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length"); typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_in; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length"); // Control request type should use tusb_control_request_t /* typedef struct TU_ATTR_PACKED { struct { unsigned int Recipient : 5 ; ///< EOM set on last byte unsigned int Type : 2 ; ///< EOM set on last byte unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN } bmRequestType; uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum uint16_t wValue ; uint16_t wIndex ; uint16_t wLength ; // Number of bytes in data stage } usbtmc_class_specific_control_req; */ // bulk-in protocol errors enum { USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u, USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u, USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u, USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u, USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u, }; // built-in halt errors enum { USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a /// Bulk-IN transfer is in progress }; typedef enum { USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u, USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u, USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u, USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u, USBTMC_bREQUEST_INITIATE_CLEAR = 5u, USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u, USBTMC_bREQUEST_GET_CAPABILITIES = 7u, USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional /****** USBTMC 488 *************/ USB488_bREQUEST_READ_STATUS_BYTE = 128u, USB488_bREQUEST_REN_CONTROL = 160u, USB488_bREQUEST_GO_TO_LOCAL = 161u, USB488_bREQUEST_LOCAL_LOCKOUT = 162u, } usmtmc_request_type_enum; typedef enum { // The last and first valid bNotify1 for use by the USBTMC class specification. USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00, USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F, // The last and first valid bNotify1 for use by vendors. USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40, USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F, // The last and first valid bNotify1 for use by USBTMC subclass specifications. USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80, USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF, // From the USB488 Subclass Specification, Section 3.4. USB488_bNOTIFY1_SRQ = 0x81, } usbtmc_int_in_payload_format; typedef enum { USBTMC_STATUS_SUCCESS = 0x01, USBTMC_STATUS_PENDING = 0x02, USBTMC_STATUS_FAILED = 0x80, USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83, /****** USBTMC 488 *************/ USB488_STATUS_INTERRUPT_IN_BUSY = 0x20 } usbtmc_status_enum; /************************************************************ * Control Responses */ typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION struct TU_ATTR_PACKED { unsigned int listenOnly :1; unsigned int talkOnly :1; unsigned int supportsIndicatorPulse :1; } bmIntfcCapabilities; struct TU_ATTR_PACKED { unsigned int canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint8_t _reserved3[12]; } usbtmc_response_capabilities_t; TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; struct TU_ATTR_PACKED { unsigned int BulkInFifoBytes :1; } bmClear; } usbtmc_get_clear_status_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); // Used for both abort bulk IN and bulk OUT typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; uint8_t bTag; } usbtmc_initiate_abort_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); // Used for both check_abort_bulk_in_status and check_abort_bulk_out_status typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; struct TU_ATTR_PACKED { unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued } bmAbortBulkIn; uint8_t _reserved[2]; ///< Must be zero uint32_t NBYTES_RXD_TXD; } usbtmc_check_abort_bulk_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION struct TU_ATTR_PACKED { uint8_t listenOnly :1; uint8_t talkOnly :1; uint8_t supportsIndicatorPulse :1; } bmIntfcCapabilities; struct TU_ATTR_PACKED { uint8_t canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint16_t bcdUSB488; struct TU_ATTR_PACKED { uint8_t supportsTrigger :1; uint8_t supportsREN_GTL_LLO :1; uint8_t is488_2 :1; } bmIntfcCapabilities488; struct TU_ATTR_PACKED { uint8_t DT1 :1; uint8_t RL1 :1; uint8_t SR1 :1; uint8_t SCPI :1; } bmDevCapabilities488; uint8_t _reserved3[8]; } usbtmc_response_capabilities_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; uint8_t bTag; uint8_t statusByte; } usbtmc_read_stb_rsp_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ uint8_t StatusByte; } usbtmc_srq_interrupt_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length"); typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED { unsigned int bTag : 7; unsigned int one : 1; } bNotify1; uint8_t StatusByte; } usbtmc_read_stb_interrupt_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length"); #endif ================================================ FILE: src/class/usbtmc/usbtmc_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Nathan Conrad * * 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. * * This file is part of the TinyUSB stack. */ /* * This library is not fully reentrant, though it is reentrant from the view * of either the application layer or the USB stack. Due to its locking, * it is not safe to call its functions from interrupts. * * The one exception is that its functions may not be called from the application * until the USB stack is initialized. This should not be a problem since the * device shouldn't be sending messages until it receives a request from the * host. */ /* * In the case of single-CPU "no OS", this task is never preempted other than by * interrupts, and the USBTMC code isn't called by interrupts, so all is OK. For "no OS", * the mutex structure's main effect is to disable the USB interrupts. * With an OS, this class driver uses the OSAL to perform locking. The code uses a single lock * and does not call outside of this class with a lock held, so deadlocks won't happen. */ //Limitations: // "vendor-specific" commands are handled similar to normal messages, except that the MsgID is changed to "vendor-specific". // Dealing with "termchar" must be handled by the application layer, // though additional error checking is does in this module. // talkOnly and listenOnly are NOT supported. They're not permitted // in USB488, anyway. /* Supported: * * Notification pulse * Trigger * Read status byte (both by interrupt endpoint and control message) * */ // TODO: // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. // Clear message available status byte at the correct time? (488 4.3.1.3) // Ability to defer status byte transmission // Transmission of status byte in response to USB488 SRQ condition #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_USBTMC) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "usbtmc_device.h" // Buffer size must be an exact multiple of the max packet size for both // bulk (up to 64 bytes for FS, 512 bytes for HS). In addation, this driver // imposes a minimum buffer size of 32 bytes. #define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Interrupt endpoint buffer size, default to 2 bytes as USB488 specification. #ifndef CFG_TUD_USBTMC_INT_EP_SIZE #define CFG_TUD_USBTMC_INT_EP_SIZE 2 #endif /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. */ typedef enum { STATE_CLOSED,// Endpoints have not yet been opened since USB reset STATE_NAK, // Bulk-out endpoint is in NAK state. STATE_IDLE, // Bulk-out endpoint is waiting for CMD. STATE_RCV, // Bulk-out is receiving DEV_DEP message STATE_TX_REQUESTED, STATE_TX_INITIATED, STATE_TX_SHORTED, STATE_CLEARING, STATE_ABORTING_BULK_IN, STATE_ABORTING_BULK_IN_SHORTED,// aborting, and short packet has been queued for transmission STATE_ABORTING_BULK_IN_ABORTED,// aborting, and short packet has been transmitted STATE_ABORTING_BULK_OUT, STATE_NUM_STATES } usbtmcd_state_enum; #if (CFG_TUD_USBTMC_ENABLE_488) typedef usbtmc_response_capabilities_488_t usbtmc_capabilities_specific_t; #else typedef usbtmc_response_capabilities_t usbtmc_capabilities_specific_t; #endif typedef struct { volatile usbtmcd_state_enum state; uint8_t itf_id; uint8_t rhport; uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; uint32_t ep_bulk_in_wMaxPacketSize; uint32_t ep_bulk_out_wMaxPacketSize; uint32_t transfer_size_remaining;// also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) uint8_t lastBulkOutTag;// used for aborts (mostly) uint8_t lastBulkInTag; // used for aborts (mostly) uint8_t const *devInBuffer;// pointer to application-layer used for transmissions usbtmc_capabilities_specific_t const *capabilities; } usbtmc_interface_state_t; typedef struct { // IN buffer is only used for first packet, not the remainder in order to deal with prepending header TUD_EPBUF_DEF(epin, USBTMCD_BUFFER_SIZE); // OUT buffer receives one packet at a time TUD_EPBUF_DEF(epout, USBTMCD_BUFFER_SIZE); // Buffer int msg TUD_EPBUF_DEF(epnotif, CFG_TUD_USBTMC_INT_EP_SIZE); } usbtmc_epbuf_t; static usbtmc_interface_state_t usbtmc_state = { .itf_id = 0xFF, }; CFG_TUD_MEM_SECTION static usbtmc_epbuf_t usbtmc_epbuf; // We need all headers to fit in a single packet in this implementation, 32 bytes will fit all standard USBTMC headers TU_VERIFY_STATIC(USBTMCD_BUFFER_SIZE >= 32u, "USBTMC dev buffer size too small"); static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); // USBTMC Device Callbacks weak implementations TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void) { return true; } TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult) { (void) msg; (void) tmcResult; return true; } #if (CFG_TUD_USBTMC_ENABLE_488) TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg) { (void) msg; return true; } #endif #ifndef NDEBUG tu_static uint8_t termChar; #endif tu_static uint8_t termCharRequested = false; tu_static bool usbtmcVendorSpecificRequested = false; #if OSAL_MUTEX_REQUIRED static OSAL_MUTEX_DEF(usbtmcLockBuffer); #endif osal_mutex_t usbtmcLock; // Our own private lock, mostly for the state variable. #define criticalEnter() \ do { (void) osal_mutex_lock(usbtmcLock, OSAL_TIMEOUT_WAIT_FOREVER); } while (0) #define criticalLeave() \ do { (void) osal_mutex_unlock(usbtmcLock); } while (0) static bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newState) { bool ret = true; criticalEnter(); usbtmcd_state_enum oldState = usbtmc_state.state; if (oldState == expectedState) { usbtmc_state.state = newState; } else { ret = false; } criticalLeave(); return ret; } // called from app // We keep a reference to the buffer, so it MUST not change until the app is // notified that the transfer is complete. // length of data is specified in the hdr. // We can't just send the whole thing at once because we need to concatanate the // header with the data. bool tud_usbtmc_transmit_dev_msg_data( const void *data, size_t len, bool endOfMessage, bool usingTermChar) { const unsigned int txBufLen = USBTMCD_BUFFER_SIZE; #ifndef NDEBUG TU_ASSERT(len > 0u); TU_ASSERT(len <= usbtmc_state.transfer_size_remaining); TU_ASSERT(usbtmc_state.transfer_size_sent == 0u); if (usingTermChar) { TU_ASSERT(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); TU_ASSERT(((uint8_t const *) data)[len - 1u] == termChar); } #endif TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); usbtmc_msg_dev_dep_msg_in_header_t *hdr = (usbtmc_msg_dev_dep_msg_in_header_t *) usbtmc_epbuf.epin; tu_varclr(hdr); if (usbtmcVendorSpecificRequested) { hdr->header.MsgID = USBTMC_MSGID_VENDOR_SPECIFIC_IN; } else { hdr->header.MsgID = USBTMC_MSGID_DEV_DEP_MSG_IN; } hdr->header.bTag = usbtmc_state.lastBulkInTag; hdr->header.bTagInverse = (uint8_t) ~(usbtmc_state.lastBulkInTag); hdr->TransferSize = len; hdr->bmTransferAttributes.EOM = endOfMessage; hdr->bmTransferAttributes.UsingTermChar = usingTermChar; // Copy in the header const size_t headerLen = sizeof(*hdr); const size_t dataLen = ((headerLen + hdr->TransferSize) <= txBufLen) ? len : (txBufLen - headerLen); const size_t packetLen = headerLen + dataLen; memcpy((uint8_t *) (usbtmc_epbuf.epin) + headerLen, data, dataLen); usbtmc_state.transfer_size_remaining = len - dataLen; usbtmc_state.transfer_size_sent = dataLen; usbtmc_state.devInBuffer = (uint8_t const *) data + (dataLen); bool stateChanged = atomicChangeState(STATE_TX_REQUESTED, (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED); TU_VERIFY(stateChanged); TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen, false)); return true; } bool tud_usbtmc_transmit_notification_data(const void *data, size_t len) { #ifndef NDEBUG TU_ASSERT(len > 0); TU_ASSERT(usbtmc_state.ep_int_in != 0); #endif TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); TU_VERIFY(tu_memcpy_s(usbtmc_epbuf.epnotif, CFG_TUD_USBTMC_INT_EP_SIZE, data, len) == 0); TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_epbuf.epnotif, (uint16_t) len, false)); return true; } void usbtmcd_init_cb(void) { usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); #ifndef NDEBUG #if CFG_TUD_USBTMC_ENABLE_488 // Per USB488 spec: table 8 TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly, ); TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly, ); #endif #endif usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } bool usbtmcd_deinit(void) { #if OSAL_MUTEX_REQUIRED osal_mutex_delete(usbtmcLock); #endif return true; } uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; uint16_t drv_len; uint8_t const *p_desc; uint8_t found_endpoints = 0; TU_VERIFY(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS, 0); TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS, 0); #ifndef NDEBUG // Only 2 or 3 endpoints are allowed for USBTMC. TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints == 3), 0); #endif TU_ASSERT(usbtmc_state.state == STATE_CLOSED, 0); // Interface drv_len = 0u; p_desc = (uint8_t const *) itf_desc; usbtmc_state.itf_id = itf_desc->bInterfaceNumber; usbtmc_state.rhport = rhport; while (found_endpoints < itf_desc->bNumEndpoints && drv_len <= max_len) { if (TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) { tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *) p_desc; switch (ep_desc->bmAttributes.xfer) { case TUSB_XFER_BULK: // Ensure buffer is an exact multiple of the maxPacketSize TU_ASSERT((USBTMCD_BUFFER_SIZE % tu_edpt_packet_size(ep_desc)) == 0, 0); if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) { usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; usbtmc_state.ep_bulk_in_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } else { usbtmc_state.ep_bulk_out = ep_desc->bEndpointAddress; usbtmc_state.ep_bulk_out_wMaxPacketSize = tu_edpt_packet_size(ep_desc); } break; case TUSB_XFER_INTERRUPT: #ifndef NDEBUG TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN, 0); TU_ASSERT(usbtmc_state.ep_int_in == 0, 0); #endif usbtmc_state.ep_int_in = ep_desc->bEndpointAddress; break; default: TU_ASSERT(false, 0); } TU_ASSERT(usbd_edpt_open(rhport, ep_desc), 0); found_endpoints++; } drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } // bulk endpoints are required, but interrupt IN is optional #ifndef NDEBUG TU_ASSERT(usbtmc_state.ep_bulk_in != 0, 0); TU_ASSERT(usbtmc_state.ep_bulk_out != 0, 0); if (itf_desc->bNumEndpoints == 2) { TU_ASSERT(usbtmc_state.ep_int_in == 0, 0); } else if (itf_desc->bNumEndpoints == 3) { TU_ASSERT(usbtmc_state.ep_int_in != 0, 0); } #if (CFG_TUD_USBTMC_ENABLE_488) if (usbtmc_state.capabilities->bmIntfcCapabilities488.is488_2 || usbtmc_state.capabilities->bmDevCapabilities488.SR1) { TU_ASSERT(usbtmc_state.ep_int_in != 0, 0); } #endif #endif atomicChangeState(STATE_CLOSED, STATE_NAK); tud_usbtmc_open_cb(itf_desc->iInterface); return drv_len; } // Tell USBTMC class to set its bulk-in EP to ACK so that it can // receive USBTMC commands. // Returns false if it was already in an ACK state or is busy // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. bool tud_usbtmc_start_bus_read(void) { usbtmcd_state_enum oldState = usbtmc_state.state; switch (oldState) { // These may transition to IDLE case STATE_NAK: case STATE_ABORTING_BULK_IN_ABORTED: TU_VERIFY(atomicChangeState(oldState, STATE_IDLE)); break; // When receiving, let it remain receiving case STATE_RCV: break; default: return false; } TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_epbuf.epout, (uint16_t) usbtmc_state.ep_bulk_out_wMaxPacketSize, false)); return true; } void usbtmcd_reset_cb(uint8_t rhport) { (void) rhport; usbtmc_capabilities_specific_t const *capabilities = tud_usbtmc_get_capabilities_cb(); criticalEnter(); tu_varclr(&usbtmc_state); usbtmc_state.capabilities = capabilities; usbtmc_state.itf_id = 0xFFu; criticalLeave(); } static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) { (void) rhport; // return true upon failure, as we can assume error is being handled elsewhere. TU_VERIFY(atomicChangeState(STATE_IDLE, STATE_RCV), true); usbtmc_state.transfer_size_sent = 0u; // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out *) data; usbtmc_state.transfer_size_remaining = msg->TransferSize; TU_VERIFY(tud_usbtmc_msgBulkOut_start_cb(msg)); TU_VERIFY(handle_devMsgOut(rhport, (uint8_t *) data + sizeof(*msg), len - sizeof(*msg), len)); usbtmc_state.lastBulkOutTag = msg->header.bTag; return true; } static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen) { (void) rhport; // return true upon failure, as we can assume error is being handled elsewhere. TU_VERIFY(usbtmc_state.state == STATE_RCV, true); bool shortPacket = (packetLen < usbtmc_state.ep_bulk_out_wMaxPacketSize); // Packet is to be considered complete when we get enough data or at a short packet. bool atEnd = false; if (len >= usbtmc_state.transfer_size_remaining || shortPacket) { atEnd = true; TU_VERIFY(atomicChangeState(STATE_RCV, STATE_NAK)); } len = tu_min32(len, usbtmc_state.transfer_size_remaining); usbtmc_state.transfer_size_remaining -= len; usbtmc_state.transfer_size_sent += len; // App may (should?) call the wait_for_bus() command at this point if (!tud_usbtmc_msg_data_cb(data, len, atEnd)) { // TODO: Go to an error state upon failure other than just stalling the EP? return false; } return true; } static bool handle_devMsgIn(void *data, size_t len) { TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in *) data; bool stateChanged = atomicChangeState(STATE_IDLE, STATE_TX_REQUESTED); TU_VERIFY(stateChanged); usbtmc_state.lastBulkInTag = msg->header.bTag; usbtmc_state.transfer_size_remaining = msg->TransferSize; usbtmc_state.transfer_size_sent = 0u; termCharRequested = msg->bmTransferAttributes.TermCharEnabled; #ifndef NDEBUG termChar = msg->TermChar; #endif if (termCharRequested) TU_VERIFY(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); TU_VERIFY(tud_usbtmc_msgBulkIn_request_cb(msg)); return true; } bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { TU_VERIFY(result == XFER_RESULT_SUCCESS); //uart_tx_str_sync("TMC XFER CB\r\n"); if (usbtmc_state.state == STATE_CLEARING) { return true; /* I think we can ignore everything here */ } if (ep_addr == usbtmc_state.ep_bulk_out) { usbtmc_msg_generic_t *msg = NULL; switch (usbtmc_state.state) { case STATE_IDLE: { TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); msg = (usbtmc_msg_generic_t *) (usbtmc_epbuf.epout); uint8_t invInvTag = (uint8_t) ~(msg->header.bTagInverse); TU_VERIFY(msg->header.bTag == invInvTag); TU_VERIFY(msg->header.bTag != 0x00); switch (msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: usbtmcVendorSpecificRequested = false; if (!handle_devMsgOutStart(rhport, msg, xferred_bytes)) { usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); return false; } break; case USBTMC_MSGID_DEV_DEP_MSG_IN: usbtmcVendorSpecificRequested = false; TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); break; #if (CFG_TUD_USBTMC_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg)); break; #endif case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: usbtmcVendorSpecificRequested = true; if (!handle_devMsgOutStart(rhport, msg, xferred_bytes)) { usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); return false; } break; case USBTMC_MSGID_VENDOR_SPECIFIC_IN: usbtmcVendorSpecificRequested = true; TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); break; default: usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); return false; } return true; } case STATE_RCV: if (!handle_devMsgOut(rhport, usbtmc_epbuf.epout, xferred_bytes, xferred_bytes)) { usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); return false; } return true; case STATE_ABORTING_BULK_OUT: // Should be stalled by now, shouldn't have received a packet. return false; case STATE_TX_REQUESTED: case STATE_TX_INITIATED: case STATE_ABORTING_BULK_IN: case STATE_ABORTING_BULK_IN_SHORTED: case STATE_ABORTING_BULK_IN_ABORTED: default: return false; } } else if (ep_addr == usbtmc_state.ep_bulk_in) { switch (usbtmc_state.state) { case STATE_TX_SHORTED: TU_VERIFY(atomicChangeState(STATE_TX_SHORTED, STATE_NAK)); TU_VERIFY(tud_usbtmc_msgBulkIn_complete_cb()); break; case STATE_TX_INITIATED: if (usbtmc_state.transfer_size_remaining >= USBTMCD_BUFFER_SIZE) { // Copy buffer to ensure alignment correctness memcpy(usbtmc_epbuf.epin, usbtmc_state.devInBuffer, USBTMCD_BUFFER_SIZE); TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, USBTMCD_BUFFER_SIZE, false)); usbtmc_state.devInBuffer += USBTMCD_BUFFER_SIZE; usbtmc_state.transfer_size_remaining -= USBTMCD_BUFFER_SIZE; usbtmc_state.transfer_size_sent += USBTMCD_BUFFER_SIZE; } else// last packet { size_t packetLen = usbtmc_state.transfer_size_remaining; memcpy(usbtmc_epbuf.epin, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); usbtmc_state.transfer_size_sent += packetLen; usbtmc_state.transfer_size_remaining = 0; usbtmc_state.devInBuffer = NULL; TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen, false)); if (((packetLen % usbtmc_state.ep_bulk_in_wMaxPacketSize) != 0) || (packetLen == 0)) { usbtmc_state.state = STATE_TX_SHORTED; } } return true; case STATE_ABORTING_BULK_IN: // need to send short packet (ZLP?) TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u, false)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; return true; case STATE_ABORTING_BULK_IN_SHORTED: /* Done. :)*/ usbtmc_state.state = STATE_ABORTING_BULK_IN_ABORTED; return true; default: TU_ASSERT(false); } } else if (ep_addr == usbtmc_state.ep_int_in) { TU_VERIFY(tud_usbtmc_notification_complete_cb()); return true; } return false; } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { // nothing to do with DATA and ACK stage if (stage != CONTROL_STAGE_SETUP) return true; uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; #if (CFG_TUD_USBTMC_ENABLE_488) uint8_t bTag; #endif if ((request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) && (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_ENDPOINT) && (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) { uint32_t ep_addr = (request->wIndex); // At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT, // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if // the EP is not halted. The only USBD API interface to do this is to stall and then un-stall the EP. if (ep_addr == usbtmc_state.ep_bulk_out) { criticalEnter(); usbd_edpt_stall(rhport, (uint8_t) ep_addr); usbd_edpt_clear_stall(rhport, (uint8_t) ep_addr); usbtmc_state.state = STATE_NAK;// USBD core has placed EP in NAK state for us criticalLeave(); tud_usbtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { usbd_edpt_stall(rhport, (uint8_t) ep_addr); usbd_edpt_clear_stall(rhport, (uint8_t) ep_addr); tud_usbtmc_bulkIn_clearFeature_cb(); } else if ((usbtmc_state.ep_int_in != 0) && (ep_addr == usbtmc_state.ep_int_in)) { // Clearing interrupt in EP usbd_edpt_stall(rhport, (uint8_t) ep_addr); usbd_edpt_clear_stall(rhport, (uint8_t) ep_addr); } else { return false; } return true; } // Otherwise, we only handle class requests. if (request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) { return false; } // Verification that we own the interface is unneeded since it's been routed to us specifically. switch (request->bRequest) { // USBTMC required requests case USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT: { usbtmc_initiate_abort_rsp_t rsp = { .bTag = usbtmc_state.lastBulkOutTag, }; TU_VERIFY(request->bmRequestType == 0xA2);// in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); // wValue is the requested bTag to abort if (usbtmc_state.state != STATE_RCV) { rsp.USBTMC_status = USBTMC_STATUS_FAILED; } else if (usbtmc_state.lastBulkOutTag == (request->wValue & 0x7Fu)) { rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; } else { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; // Check if we've queued a short packet criticalEnter(); usbtmc_state.state = STATE_ABORTING_BULK_OUT; criticalLeave(); TU_VERIFY(tud_usbtmc_initiate_abort_bulk_out_cb(&(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); } TU_VERIFY(tud_control_xfer(rhport, request, (void *) &rsp, sizeof(rsp))); return true; } case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: { usbtmc_check_abort_bulk_rsp_t rsp = { .USBTMC_status = USBTMC_STATUS_SUCCESS, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent}; TU_VERIFY(request->bmRequestType == 0xA2);// in,class,EP TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); TU_VERIFY(tud_usbtmc_check_abort_bulk_out_cb(&rsp)); TU_VERIFY(tud_control_xfer(rhport, request, (void *) &rsp, sizeof(rsp))); return true; } case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: { usbtmc_initiate_abort_rsp_t rsp = { .bTag = usbtmc_state.lastBulkInTag, }; TU_VERIFY(request->bmRequestType == 0xA2);// in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_in); // wValue is the requested bTag to abort if ((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED) && usbtmc_state.lastBulkInTag == (request->wValue & 0x7Fu)) { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; usbtmc_state.transfer_size_remaining = 0u; // Check if we've queued a short packet criticalEnter(); usbtmc_state.state = ((usbtmc_state.transfer_size_sent % usbtmc_state.ep_bulk_in_wMaxPacketSize) == 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; criticalLeave(); if (usbtmc_state.transfer_size_sent == 0) { // Send short packet, nothing is in the buffer yet TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u, false)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; } TU_VERIFY(tud_usbtmc_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); } else if ((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) {// FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; } else { rsp.USBTMC_status = USBTMC_STATUS_FAILED; } TU_VERIFY(tud_control_xfer(rhport, request, (void *) &rsp, sizeof(rsp))); return true; } case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: { TU_VERIFY(request->bmRequestType == 0xA2);// in,class,EP TU_VERIFY(request->wLength == 8u); usbtmc_check_abort_bulk_rsp_t rsp = { .USBTMC_status = USBTMC_STATUS_FAILED, .bmAbortBulkIn = { .BulkInFifoBytes = (usbtmc_state.state != STATE_ABORTING_BULK_IN_ABORTED)}, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; TU_VERIFY(tud_usbtmc_check_abort_bulk_in_cb(&rsp)); criticalEnter(); switch (usbtmc_state.state) { case STATE_ABORTING_BULK_IN_ABORTED: rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; usbtmc_state.state = STATE_IDLE; break; case STATE_ABORTING_BULK_IN: case STATE_ABORTING_BULK_OUT: rsp.USBTMC_status = USBTMC_STATUS_PENDING; break; default: break; } criticalLeave(); TU_VERIFY(tud_control_xfer(rhport, request, (void *) &rsp, sizeof(rsp))); return true; } case USBTMC_bREQUEST_INITIATE_CLEAR: { TU_VERIFY(request->bmRequestType == 0xA1);// in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the // control endpoint response shown in Table 31, and clear all input buffers and output buffers. usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); usbtmc_state.transfer_size_remaining = 0; criticalEnter(); usbtmc_state.state = STATE_CLEARING; criticalLeave(); TU_VERIFY(tud_usbtmc_initiate_clear_cb(&tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void *) &tmcStatusCode, sizeof(tmcStatusCode))); return true; } case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: { TU_VERIFY(request->bmRequestType == 0xA1);// in,class,interface usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); if (usbd_edpt_busy(rhport, usbtmc_state.ep_bulk_in)) { // Stuff stuck in TX buffer? clearStatusRsp.bmClear.BulkInFifoBytes = 1; clearStatusRsp.USBTMC_status = USBTMC_STATUS_PENDING; } else { // Let app check if it's clear TU_VERIFY(tud_usbtmc_check_clear_cb(&clearStatusRsp)); } if (clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) { criticalEnter(); usbtmc_state.state = STATE_IDLE; criticalLeave(); } TU_VERIFY(tud_control_xfer(rhport, request, (void *) &clearStatusRsp, sizeof(clearStatusRsp))); return true; } case USBTMC_bREQUEST_GET_CAPABILITIES: { TU_VERIFY(request->bmRequestType == 0xA1);// in,class,interface TU_VERIFY(request->wLength == sizeof(*(usbtmc_state.capabilities))); TU_VERIFY(tud_control_xfer(rhport, request, (void *) (uintptr_t) usbtmc_state.capabilities, sizeof(*usbtmc_state.capabilities))); return true; } // USBTMC Optional Requests case USBTMC_bREQUEST_INDICATOR_PULSE:// Optional { TU_VERIFY(request->bmRequestType == 0xA1);// in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse); TU_VERIFY(tud_usbtmc_indicator_pulse_cb(request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void *) &tmcStatusCode, sizeof(tmcStatusCode))); return true; } #if (CFG_TUD_USBTMC_ENABLE_488) // USB488 required requests case USB488_bREQUEST_READ_STATUS_BYTE: { usbtmc_read_stb_rsp_488_t rsp; TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp));// in,class,interface bTag = request->wValue & 0x7F; TU_VERIFY(request->bmRequestType == 0xA1); TU_VERIFY((request->wValue & (~0x7F)) == 0u);// Other bits are required to be zero (USB488v1.0 Table 11) TU_VERIFY(bTag >= 0x02 && bTag <= 127); TU_VERIFY(request->wIndex == usbtmc_state.itf_id); TU_VERIFY(request->wLength == 0x0003); rsp.bTag = (uint8_t) bTag; if (usbtmc_state.ep_int_in != 0) { rsp.statusByte = 0x00;// Use interrupt endpoint, instead. Must be 0x00 (USB488v1.0 4.3.1.2) if (usbd_edpt_busy(rhport, usbtmc_state.ep_int_in)) { rsp.USBTMC_status = USB488_STATUS_INTERRUPT_IN_BUSY; } else { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; usbtmc_read_stb_interrupt_488_t intMsg = { .bNotify1 = { .one = 1, .bTag = bTag & 0x7Fu, }, .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status))}; // Must be queued before control request response sent (USB488v1.0 4.3.1.2) usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void *) &intMsg, sizeof(intMsg), false); } } else { rsp.statusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)); } TU_VERIFY(tud_control_xfer(rhport, request, (void *) &rsp, sizeof(rsp))); return true; } // USB488 optional requests case USB488_bREQUEST_REN_CONTROL: case USB488_bREQUEST_GO_TO_LOCAL: case USB488_bREQUEST_LOCAL_LOCKOUT: { TU_VERIFY(request->bmRequestType == 0xA1);// in,class,interface return false; } #endif default: return false; } } #endif /* CFG_TUD_TSMC */ ================================================ FILE: src/class/usbtmc/usbtmc_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 N Conrad * * 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. * * This file is part of the TinyUSB stack. */ #ifndef CLASS_USBTMC_USBTMC_DEVICE_H_ #define CLASS_USBTMC_USBTMC_DEVICE_H_ #include "usbtmc.h" // Enable 488 mode by default #if !defined(CFG_TUD_USBTMC_ENABLE_488) #define CFG_TUD_USBTMC_ENABLE_488 (1) #endif /*********************************************** * Functions to be implemented by the class implementation */ // In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after: // * tud_usbtmc_open_cb // * tud_usbtmc_msg_data_cb // * tud_usbtmc_msgBulkIn_complete_cb // * tud_usbtmc_msg_trigger_cb // * (successful) tud_usbtmc_check_abort_bulk_out_cb // * (successful) tud_usbtmc_check_abort_bulk_in_cb // * (successful) tud_usmtmc_bulkOut_clearFeature_cb #if (CFG_TUD_USBTMC_ENABLE_488) usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void); #else usbtmc_response_capabilities_t const * tud_usbtmc_get_capabilities_cb(void); #endif void tud_usbtmc_open_cb(uint8_t interface_id); bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. bool tud_usbtmc_msg_data_cb( void *data, size_t len, bool transfer_complete); void tud_usbtmc_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); bool tud_usbtmc_msgBulkIn_complete_cb(void); void tud_usbtmc_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult); bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult); bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult); bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); // The interrupt-IN endpoint buffer was transmitted to the host. Use // tud_usbtmc_transmit_notification_data to send another notification. bool tud_usbtmc_notification_complete_cb(void); // Indicator pulse should be 0.5 to 1.0 seconds long bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); #if (CFG_TUD_USBTMC_ENABLE_488) uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult); bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); #endif // Called from app // // We keep a reference to the buffer, so it MUST not change until the app is // notified that the transfer is complete. bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); // Buffers a notification to be sent to the host. The data starts // with the bNotify1 field, see the USBTMC Specification, Table 13. // // If the previous notification data has not yet been sent, this // returns false. // // Requires an interrupt endpoint in the interface. bool tud_usbtmc_transmit_notification_data(const void * data, size_t len); bool tud_usbtmc_start_bus_read(void); /* "callbacks" from USB device core */ void usbtmcd_init_cb(void); bool usbtmcd_deinit(void); uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); void usbtmcd_reset_cb(uint8_t rhport); bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); #endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ ================================================ FILE: src/class/vendor/vendor_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_VENDOR) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "vendor_device.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t rhport; uint8_t itf_num; #if CFG_TUD_VENDOR_TXRX_BUFFERED /*------------- From this point, data is not cleared by bus reset -------------*/ tu_edpt_stream_t tx_stream; tu_edpt_stream_t rx_stream; uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; #else uint8_t ep_in; uint8_t ep_out; uint16_t rx_xfer_len; #endif } vendord_interface_t; #if CFG_TUD_VENDOR_TXRX_BUFFERED #define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + TU_FIELD_SIZE(vendord_interface_t, itf_num)) #else #define ITF_MEM_RESET_SIZE sizeof(vendord_interface_t) #endif static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; // Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_RX_EPSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_TX_EPSIZE); } vendord_epbuf_t; CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) { (void)idx; (void)buffer; (void)bufsize; } TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { (void)idx; (void) sent_bytes; } bool tud_vendor_n_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; #if CFG_TUD_VENDOR_TXRX_BUFFERED return (p_itf->rx_stream.ep_addr != 0) || (p_itf->tx_stream.ep_addr != 0); #else return (p_itf->ep_out != 0) || (p_itf->ep_in != 0); #endif } //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ #if CFG_TUD_VENDOR_TXRX_BUFFERED uint32_t tud_vendor_n_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; return tu_edpt_stream_read_available(&p_itf->rx_stream); } bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; return tu_edpt_stream_peek(&p_itf->rx_stream, u8); } uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; return tu_edpt_stream_read(&p_itf->rx_stream, buffer, bufsize); } void tud_vendor_n_read_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, ); vendord_interface_t *p_itf = &_vendord_itf[idx]; tu_edpt_stream_clear(&p_itf->rx_stream); tu_edpt_stream_read_xfer(&p_itf->rx_stream); } #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER bool tud_vendor_n_read_xfer(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; #if CFG_TUD_VENDOR_TXRX_BUFFERED return tu_edpt_stream_read_xfer(&p_itf->rx_stream); #else // Non-FIFO mode TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_out)); return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, p_itf->rx_xfer_len, false); #endif } #endif //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; #if CFG_TUD_VENDOR_TXRX_BUFFERED return tu_edpt_stream_write(&p_itf->tx_stream, buffer, (uint16_t)bufsize); #else // non-fifo mode: direct transfer TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_in), 0); const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_TX_EPSIZE); memcpy(_vendord_epbuf[idx].epin, buffer, xact_len); TU_ASSERT(usbd_edpt_xfer(p_itf->rhport, p_itf->ep_in, _vendord_epbuf[idx].epin, (uint16_t)xact_len, false), 0); return xact_len; #endif } uint32_t tud_vendor_n_write_available(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; #if CFG_TUD_VENDOR_TXRX_BUFFERED return tu_edpt_stream_write_available(&p_itf->tx_stream); #else // Non-FIFO mode TU_VERIFY(p_itf->ep_in > 0, 0); // must be opened return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_TX_EPSIZE; #endif } #if CFG_TUD_VENDOR_TXRX_BUFFERED uint32_t tud_vendor_n_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; return tu_edpt_stream_write_xfer(&p_itf->tx_stream); } bool tud_vendor_n_write_clear(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_itf = &_vendord_itf[idx]; tu_edpt_stream_clear(&p_itf->tx_stream); return true; } #endif //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); #if CFG_TUD_VENDOR_TXRX_BUFFERED for (uint8_t i = 0; i < CFG_TUD_VENDOR; i++) { vendord_interface_t *p_itf = &_vendord_itf[i]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO uint8_t *epout_buf = NULL; uint8_t *epin_buf = NULL; #else uint8_t *epout_buf = _vendord_epbuf[i].epout; uint8_t *epin_buf = _vendord_epbuf[i].epin; #endif uint8_t *rx_ff_buf = p_itf->rx_ff_buf; tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf); uint8_t *tx_ff_buf = p_itf->tx_ff_buf; tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf); } #endif } bool vendord_deinit(void) { #if CFG_TUD_VENDOR_TXRX_BUFFERED for (uint8_t i = 0; i < CFG_TUD_VENDOR; i++) { vendord_interface_t *p_itf = &_vendord_itf[i]; tu_edpt_stream_deinit(&p_itf->rx_stream); tu_edpt_stream_deinit(&p_itf->tx_stream); } #endif return true; } void vendord_reset(uint8_t rhport) { (void) rhport; for(uint8_t i=0; irx_stream); tu_edpt_stream_close(&p_itf->rx_stream); tu_edpt_stream_clear(&p_itf->tx_stream); tu_edpt_stream_close(&p_itf->tx_stream); #endif } } // Find vendor interface by endpoint address static uint8_t find_vendor_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_VENDOR; idx++) { const vendord_interface_t *p_vendor = &_vendord_itf[idx]; if (ep_addr == 0) { // find unused: require both ep == 0 #if CFG_TUD_VENDOR_TXRX_BUFFERED if (p_vendor->rx_stream.ep_addr == 0 && p_vendor->tx_stream.ep_addr == 0) { return idx; } #else if (p_vendor->ep_out == 0 && p_vendor->ep_in == 0) { return idx; } #endif } else { #if CFG_TUD_VENDOR_TXRX_BUFFERED if (ep_addr == p_vendor->rx_stream.ep_addr || ep_addr == p_vendor->tx_stream.ep_addr) { return idx; } #else if (ep_addr == p_vendor->ep_out || ep_addr == p_vendor->ep_in) { return idx; } #endif } } return 0xff; } uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0); const uint8_t* desc_end = (const uint8_t*)desc_itf + max_len; const uint8_t* p_desc = tu_desc_next(desc_itf); // Find available interface const uint8_t idx = find_vendor_itf(0); TU_ASSERT(idx < CFG_TUD_VENDOR, 0); vendord_interface_t *p_vendor = &_vendord_itf[idx]; p_vendor->rhport = rhport; p_vendor->itf_num = desc_itf->bInterfaceNumber; while (tu_desc_in_bounds(p_desc, desc_end)) { const uint8_t desc_type = tu_desc_type(p_desc); if (desc_type == TUSB_DESC_INTERFACE || desc_type == TUSB_DESC_INTERFACE_ASSOCIATION) { break; // end of this interface } else if (desc_type == TUSB_DESC_ENDPOINT) { const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); uint16_t rx_xfer_len = CFG_TUD_VENDOR_RX_NEED_ZLP ? CFG_TUD_VENDOR_RX_EPSIZE : tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_TX_EPSIZE); tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; tu_edpt_stream_open(rx_stream, rhport, desc_ep, rx_xfer_len); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 TU_ASSERT(tu_edpt_stream_read_xfer(rx_stream) > 0, 0); // prepare for incoming data #endif } #else p_vendor->rx_xfer_len = rx_xfer_len; // Non-FIFO mode: store endpoint info if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_vendor->ep_in = desc_ep->bEndpointAddress; } else { p_vendor->ep_out = desc_ep->bEndpointAddress; #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 // Prepare for incoming data TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, rx_xfer_len, false), 0); #endif } #endif } p_desc = tu_desc_next(p_desc); } return (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_itf); } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; const uint8_t idx = find_vendor_itf(ep_addr); TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_vendor = &_vendord_itf[idx]; #if CFG_TUD_VENDOR_TXRX_BUFFERED if (ep_addr == p_vendor->rx_stream.ep_addr) { // Put received data to FIFO tu_edpt_stream_read_xfer_complete(&p_vendor->rx_stream, xferred_bytes); tud_vendor_rx_cb(idx, NULL, 0); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 tu_edpt_stream_read_xfer(&p_vendor->rx_stream); // prepare next data #endif } else if (ep_addr == p_vendor->tx_stream.ep_addr) { // Send complete tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); // try to send more if possible if (0 == tu_edpt_stream_write_xfer(&p_vendor->tx_stream)) { // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero tu_edpt_stream_write_zlp_if_needed(&p_vendor->tx_stream, xferred_bytes); } } #else if (ep_addr == p_vendor->ep_out) { // Non-FIFO mode: invoke callback with buffer tud_vendor_rx_cb(idx, _vendord_epbuf[idx].epout, xferred_bytes); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, p_vendor->rx_xfer_len, false); #endif } else if (ep_addr == p_vendor->ep_in) { // Send complete tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); } #endif return true; } #endif ================================================ FILE: src/class/vendor/vendor_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_VENDOR_DEVICE_H_ #define TUSB_VENDOR_DEVICE_H_ #ifdef __cplusplus extern "C" { #endif #include "common/tusb_common.h" //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_VENDOR_RX_EPSIZE #ifdef CFG_TUD_VENDOR_EPSIZE #define CFG_TUD_VENDOR_RX_EPSIZE CFG_TUD_VENDOR_EPSIZE #else #define CFG_TUD_VENDOR_RX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif #ifndef CFG_TUD_VENDOR_TX_EPSIZE #ifdef CFG_TUD_VENDOR_EPSIZE #define CFG_TUD_VENDOR_TX_EPSIZE CFG_TUD_VENDOR_EPSIZE #else #define CFG_TUD_VENDOR_TX_EPSIZE TUD_EPSIZE_BULK_MAX #endif #endif // RX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_RX_BUFSIZE #define CFG_TUD_VENDOR_RX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif // TX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_TX_BUFSIZE #define CFG_TUD_VENDOR_TX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif // Vendor is buffered (FIFO mode) if both TX and RX buffers are configured // If either is 0, vendor operates in non-buffered (direct transfer) mode #ifndef CFG_TUD_VENDOR_TXRX_BUFFERED #define CFG_TUD_VENDOR_TXRX_BUFFERED ((CFG_TUD_VENDOR_RX_BUFSIZE > 0) && (CFG_TUD_VENDOR_TX_BUFSIZE > 0)) #endif // Application will manually schedule RX transfer. This can be useful when using with non-fifo (buffered) mode // i.e. CFG_TUD_VENDOR_TXRX_BUFFERED = 0 #ifndef CFG_TUD_VENDOR_RX_MANUAL_XFER #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif // Enable multi-packet RX transfer with ZLP termination for better throughput. Requires host support for ZLP. #ifndef CFG_TUD_VENDOR_RX_NEED_ZLP #define CFG_TUD_VENDOR_RX_NEED_ZLP 0 #endif //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ // Return whether the vendor interface is mounted bool tud_vendor_n_mounted(uint8_t idx); //------------- RX -------------// #if CFG_TUD_VENDOR_TXRX_BUFFERED // Return number of available bytes for reading uint32_t tud_vendor_n_available(uint8_t idx); // Peek a byte from RX buffer bool tud_vendor_n_peek(uint8_t idx, uint8_t *ui8); // Read from RX FIFO uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize); // Flush (clear) RX FIFO void tud_vendor_n_read_flush(uint8_t idx); #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER // Start a new RX transfer to fill the RX FIFO, return false if previous transfer is still ongoing bool tud_vendor_n_read_xfer(uint8_t idx); #endif //------------- TX -------------// // Write to TX FIFO. This can be buffered and not sent immediately unless buffered bytes >= USB endpoint size uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize); // Return number of bytes available for writing in TX FIFO (or endpoint if non-buffered) uint32_t tud_vendor_n_write_available(uint8_t idx); #if CFG_TUD_VENDOR_TXRX_BUFFERED // Force sending buffered data, return number of bytes sent uint32_t tud_vendor_n_write_flush(uint8_t idx); // Clear the transmit FIFO bool tud_vendor_n_write_clear(uint8_t idx); #endif // Write a null-terminated string to TX FIFO TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str(uint8_t idx, const char *str) { return tud_vendor_n_write(idx, str, strlen(str)); } // backward compatible #define tud_vendor_n_flush(idx) tud_vendor_n_write_flush(idx) //--------------------------------------------------------------------+ // Application API (Single Port) i.e CFG_TUD_VENDOR = 1 //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_mounted(void) { return tud_vendor_n_mounted(0); } #if CFG_TUD_VENDOR_TXRX_BUFFERED TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { return tud_vendor_n_available(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_peek(uint8_t *ui8) { return tud_vendor_n_peek(0, ui8); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void *buffer, uint32_t bufsize) { return tud_vendor_n_read(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { tud_vendor_n_read_flush(0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { return tud_vendor_n_write_flush(0); } TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_write_clear(void) { return tud_vendor_n_write_clear(0); } #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_read_xfer(void) { return tud_vendor_n_read_xfer(0); } #endif TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write(const void *buffer, uint32_t bufsize) { return tud_vendor_n_write(0, buffer, bufsize); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(const char *str) { return tud_vendor_n_write_str(0, str); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { return tud_vendor_n_write_available(0); } // backward compatible #define tud_vendor_flush() tud_vendor_write_flush() //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data. // - CFG_TUD_VENDOR_TXRX_BUFFERED = 1: buffer and bufsize must not be used (both NULL,0) since data is in RX FIFO // - CFG_TUD_VENDOR_TXRX_BUFFERED = 0: Buffer and bufsize are valid void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize); // Invoked when tx transfer is finished void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void vendord_init(void); bool vendord_deinit(void); void vendord_reset(uint8_t rhport); uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *idx_desc, uint16_t max_len); bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif /* TUSB_VENDOR_DEVICE_H_ */ ================================================ FILE: src/class/vendor/vendor_host.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUH_ENABLED && CFG_TUH_VENDOR) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "host/usbh.h" #include "vendor_host.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ custom_interface_info_t custom_interface[CFG_TUH_DEVICE_MAX]; static tusb_error_t cush_validate_paras(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length) { if ( !tusbh_custom_is_mounted(dev_addr, vendor_id, product_id) ) { return TUSB_ERROR_DEVICE_NOT_READY; } TU_ASSERT( p_buffer != NULL && length != 0, TUSB_ERROR_INVALID_PARA); return TUSB_ERROR_NONE; } //--------------------------------------------------------------------+ // APPLICATION API (need to check parameters) //--------------------------------------------------------------------+ tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length) { TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_buffer, length) ); if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_in) ) { return TUSB_ERROR_INTERFACE_IS_BUSY; } (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_in, p_buffer, length); return TUSB_ERROR_NONE; } tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length) { TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_data, length) ); if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_out) ) { return TUSB_ERROR_INTERFACE_IS_BUSY; } (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_out, p_data, length); return TUSB_ERROR_NONE; } //--------------------------------------------------------------------+ // USBH-CLASS API //--------------------------------------------------------------------+ void cush_init(void) { tu_memclr(&custom_interface, sizeof(custom_interface_info_t) * CFG_TUH_DEVICE_MAX); } tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) { // FIXME quick hack to test lpc1k custom class with 2 bulk endpoints uint8_t const *p_desc = (uint8_t const *) p_interface_desc; p_desc = tu_desc_next(p_desc); //------------- Bulk Endpoints Descriptor -------------// for(uint32_t i=0; i<2; i++) { tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_INVALID_PARA); pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ? &custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out; *p_pipe_hdl = usbh_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC); TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED ); p_desc = tu_desc_next(p_desc); } (*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); return TUSB_ERROR_NONE; } void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event) { } void cush_close(uint8_t dev_addr) { tusb_error_t err1, err2; custom_interface_info_t * p_interface = &custom_interface[dev_addr-1]; // TODO re-consider to check pipe valid before calling pipe_close if( pipehandle_is_valid( p_interface->pipe_in ) ) { err1 = hcd_pipe_close( p_interface->pipe_in ); } if ( pipehandle_is_valid( p_interface->pipe_out ) ) { err2 = hcd_pipe_close( p_interface->pipe_out ); } tu_memclr(p_interface, sizeof(custom_interface_info_t)); TU_ASSERT(err1 == TUSB_ERROR_NONE && err2 == TUSB_ERROR_NONE, (void) 0 ); } #endif ================================================ FILE: src/class/vendor/vendor_host.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_VENDOR_HOST_H_ #define TUSB_VENDOR_HOST_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif typedef struct { pipe_handle_t pipe_in; pipe_handle_t pipe_out; }custom_interface_info_t; //--------------------------------------------------------------------+ // USBH-CLASS DRIVER API //--------------------------------------------------------------------+ static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id) { (void) vendor_id; // TODO check this later (void) product_id; // return (tusbh_device_get_mounted_class_flag(dev_addr) & TU_BIT(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0; return false; } bool tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length); bool tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void cush_init(void); bool cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length); void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event); void cush_close(uint8_t dev_addr); #ifdef __cplusplus } #endif #endif /* TUSB_VENDOR_HOST_H_ */ ================================================ FILE: src/class/video/video.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_VIDEO_H_ #define TUSB_VIDEO_H_ #include "common/tusb_common.h" enum { VIDEO_BCD_1_50 = 0x0150, }; // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, VIDEO_COLOR_PRIMARIES_BT709, // sRGB (default) VIDEO_COLOR_PRIMARIES_BT470_2M, VIDEO_COLOR_PRIMARIES_BT470_2BG, VIDEO_COLOR_PRIMARIES_SMPTE170M, VIDEO_COLOR_PRIMARIES_SMPTE240M, } video_color_primaries_t; // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_XFER_CH_UNDEFINED = 0x00, VIDEO_COLOR_XFER_CH_BT709, // default VIDEO_COLOR_XFER_CH_BT470_2M, VIDEO_COLOR_XFER_CH_BT470_2BG, VIDEO_COLOR_XFER_CH_SMPTE170M, VIDEO_COLOR_XFER_CH_SMPTE240M, VIDEO_COLOR_XFER_CH_LINEAR, VIDEO_COLOR_XFER_CH_SRGB, } video_color_transfer_characteristics_t; // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_COEF_UNDEFINED = 0x00, VIDEO_COLOR_COEF_BT709, VIDEO_COLOR_COEF_FCC, VIDEO_COLOR_COEF_BT470_2BG, VIDEO_COLOR_COEF_SMPTE170M, // BT.601 default VIDEO_COLOR_COEF_SMPTE240M, } video_color_matrix_coefficients_t; /* 4.2.1.2 Request Error Code Control */ typedef enum { VIDEO_ERROR_NONE = 0, /* The request succeeded. */ VIDEO_ERROR_NOT_READY, VIDEO_ERROR_WRONG_STATE, VIDEO_ERROR_POWER, VIDEO_ERROR_OUT_OF_RANGE, VIDEO_ERROR_INVALID_UNIT, VIDEO_ERROR_INVALID_CONTROL, VIDEO_ERROR_INVALID_REQUEST, VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE, VIDEO_ERROR_UNKNOWN = 0xFF, } video_error_code_t; /* A.2 Interface Subclass */ typedef enum { VIDEO_SUBCLASS_UNDEFINED = 0x00, VIDEO_SUBCLASS_CONTROL, VIDEO_SUBCLASS_STREAMING, VIDEO_SUBCLASS_INTERFACE_COLLECTION, } video_subclass_type_t; /* A.3 Interface Protocol */ typedef enum { VIDEO_ITF_PROTOCOL_UNDEFINED = 0x00, VIDEO_ITF_PROTOCOL_15, } video_interface_protocol_code_t; /* A.5 Class-Specific VideoControl Interface Descriptor Subtypes */ typedef enum { VIDEO_CS_ITF_VC_UNDEFINED = 0x00, VIDEO_CS_ITF_VC_HEADER, VIDEO_CS_ITF_VC_INPUT_TERMINAL, VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, VIDEO_CS_ITF_VC_SELECTOR_UNIT, VIDEO_CS_ITF_VC_PROCESSING_UNIT, VIDEO_CS_ITF_VC_EXTENSION_UNIT, VIDEO_CS_ITF_VC_ENCODING_UNIT, VIDEO_CS_ITF_VC_MAX, } video_cs_vc_interface_subtype_t; /* A.6 Class-Specific VideoStreaming Interface Descriptor Subtypes */ typedef enum { VIDEO_CS_ITF_VS_UNDEFINED = 0x00, VIDEO_CS_ITF_VS_INPUT_HEADER = 0x01, VIDEO_CS_ITF_VS_OUTPUT_HEADER = 0x02, VIDEO_CS_ITF_VS_STILL_IMAGE_FRAME = 0x03, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED = 0x04, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED = 0x05, VIDEO_CS_ITF_VS_FORMAT_MJPEG = 0x06, VIDEO_CS_ITF_VS_FRAME_MJPEG = 0x07, VIDEO_CS_ITF_VS_FORMAT_MPEG2TS = 0x0A, VIDEO_CS_ITF_VS_FORMAT_DV = 0x0C, VIDEO_CS_ITF_VS_COLORFORMAT = 0x0D, VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED = 0x10, VIDEO_CS_ITF_VS_FRAME_FRAME_BASED = 0x11, VIDEO_CS_ITF_VS_FORMAT_STREAM_BASED = 0x12, VIDEO_CS_ITF_VS_FORMAT_H264 = 0x13, VIDEO_CS_ITF_VS_FRAME_H264 = 0x14, VIDEO_CS_ITF_VS_FORMAT_H264_SIMULCAST = 0x15, VIDEO_CS_ITF_VS_FORMAT_VP8 = 0x16, VIDEO_CS_ITF_VS_FRAME_VP8 = 0x17, VIDEO_CS_ITF_VS_FORMAT_VP8_SIMULCAST = 0x18, } video_cs_vs_interface_subtype_t; /* A.7. Class-Specific Endpoint Descriptor Subtypes */ typedef enum { VIDEO_CS_EP_UNDEFINED = 0x00, VIDEO_CS_EP_GENERAL, VIDEO_CS_EP_ENDPOINT, VIDEO_CS_EP_INTERRUPT } video_cs_ep_subtype_t; /* A.8 Class-Specific Request Codes */ typedef enum { VIDEO_REQUEST_UNDEFINED = 0x00, VIDEO_REQUEST_SET_CUR = 0x01, VIDEO_REQUEST_SET_CUR_ALL = 0x11, VIDEO_REQUEST_GET_CUR = 0x81, VIDEO_REQUEST_GET_MIN = 0x82, VIDEO_REQUEST_GET_MAX = 0x83, VIDEO_REQUEST_GET_RES = 0x84, VIDEO_REQUEST_GET_LEN = 0x85, VIDEO_REQUEST_GET_INFO = 0x86, VIDEO_REQUEST_GET_DEF = 0x87, VIDEO_REQUEST_GET_CUR_ALL = 0x91, VIDEO_REQUEST_GET_MIN_ALL = 0x92, VIDEO_REQUEST_GET_MAX_ALL = 0x93, VIDEO_REQUEST_GET_RES_ALL = 0x94, VIDEO_REQUEST_GET_DEF_ALL = 0x97 } video_control_request_t; /* A.9.1 VideoControl Interface Control Selectors */ typedef enum { VIDEO_VC_CTL_UNDEFINED = 0x00, VIDEO_VC_CTL_VIDEO_POWER_MODE, // 0x01 VIDEO_VC_CTL_REQUEST_ERROR_CODE, // 0x02 } video_interface_control_selector_t; /* A.9.8 VideoStreaming Interface Control Selectors */ typedef enum { VIDEO_VS_CTL_UNDEFINED = 0x00, VIDEO_VS_CTL_PROBE, // 0x01 VIDEO_VS_CTL_COMMIT, // 0x02 VIDEO_VS_CTL_STILL_PROBE, // 0x03 VIDEO_VS_CTL_STILL_COMMIT, // 0x04 VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, // 0x05 VIDEO_VS_CTL_STREAM_ERROR_CODE, // 0x06 VIDEO_VS_CTL_GENERATE_KEY_FRAME, // 0x07 VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, // 0x08 VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, // 0x09 } video_interface_streaming_selector_t; /* B. Terminal Types */ typedef enum { // Terminal VIDEO_TT_VENDOR_SPECIFIC = 0x0100, VIDEO_TT_STREAMING = 0x0101, // Input VIDEO_ITT_VENDOR_SPECIFIC = 0x0200, VIDEO_ITT_CAMERA = 0x0201, VIDEO_ITT_MEDIA_TRANSPORT_INPUT = 0x0202, // Output VIDEO_OTT_VENDOR_SPECIFIC = 0x0300, VIDEO_OTT_DISPLAY = 0x0301, VIDEO_OTT_MEDIA_TRANSPORT_OUTPUT = 0x0302, // External VIDEO_ETT_VENDOR_SPEIFIC = 0x0400, VIDEO_ETT_COMPOSITE_CONNECTOR = 0x0401, VIDEO_ETT_SVIDEO_CONNECTOR = 0x0402, VIDEO_ETT_COMPONENT_CONNECTOR = 0x0403, } video_terminal_type_t; //--------------------------------------------------------------------+ // Video Control (VC) Descriptors //--------------------------------------------------------------------+ /* 2.3.4.2 */ #define tusb_desc_video_control_header_nitf_t(_nitf) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint16_t bcdUVC; \ uint16_t wTotalLength; \ uint32_t dwClockFrequency; /* deprecated */ \ uint8_t bInCollection; \ uint8_t baInterfaceNr[_nitf]; \ } typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; //-V2586 incorrectly detected as flexible array typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; //-V2586 incorrectly detected as flexible array typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; //-V2586 incorrectly detected as flexible array typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; //-V2586 incorrectly detected as flexible array typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; //-V2586 incorrectly detected as flexible array typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bTerminalID; uint16_t wTerminalType; uint8_t bAssocTerminal; uint8_t iTerminal; } tusb_desc_video_control_input_terminal_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_input_terminal_t) == 8, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bTerminalID; uint16_t wTerminalType; uint8_t bAssocTerminal; uint8_t bSourceID; uint8_t iTerminal; } tusb_desc_video_control_output_terminal_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_output_terminal_t) == 9, "size is not correct"); typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bTerminalID; uint16_t wTerminalType; uint8_t bAssocTerminal; uint8_t iTerminal; uint16_t wObjectiveFocalLengthMin; uint16_t wObjectiveFocalLengthMax; uint16_t wOcularFocalLength; uint8_t bControlSize; uint8_t bmControls[3]; } tusb_desc_video_control_camera_terminal_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_camera_terminal_t) == 18, "size is not correct"); //--------------------------------------------------------------------+ // Video Streaming (VS) Descriptors //--------------------------------------------------------------------+ /* 3.9.2.1 */ #define tusb_desc_video_streaming_input_header_nbyte_t(_nb) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bNumFormats; /* Number of video payload Format descriptors for this interface */ \ uint16_t wTotalLength; \ uint8_t bEndpointAddress; \ uint8_t bmInfo; /* Bit 0: dynamic format change supported */ \ uint8_t bTerminalLink; \ uint8_t bStillCaptureMethod; \ uint8_t bTriggerSupport; /* Hardware trigger supported */ \ uint8_t bTriggerUsage; \ uint8_t bControlSize; /* sizeof of each control item */ \ uint8_t bmaControls[_nb]; \ } typedef tusb_desc_video_streaming_input_header_nbyte_t() tusb_desc_video_streaming_input_header_t; typedef tusb_desc_video_streaming_input_header_nbyte_t(1) tusb_desc_video_streaming_input_header_1byte_t; typedef tusb_desc_video_streaming_input_header_nbyte_t(2) tusb_desc_video_streaming_input_header_2byte_t; typedef tusb_desc_video_streaming_input_header_nbyte_t(3) tusb_desc_video_streaming_input_header_3byte_t; typedef tusb_desc_video_streaming_input_header_nbyte_t(4) tusb_desc_video_streaming_input_header_4byte_t; /* 3.9.2.2 */ typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bNumFormats; uint16_t wTotalLength; uint8_t bEndpointAddress; uint8_t bTerminalLink; uint8_t bControlSize; uint8_t bmaControls[]; } tusb_desc_video_streaming_output_header_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bNumFormats; uint16_t wTotalLength; uint8_t bEndpointAddress; union { struct { uint8_t bmInfo; uint8_t bTerminalLink; uint8_t bStillCaptureMethod; uint8_t bTriggerSupport; uint8_t bTriggerUsage; uint8_t bControlSize; uint8_t bmaControls[]; } input; struct { uint8_t bEndpointAddress; uint8_t bTerminalLink; uint8_t bControlSize; uint8_t bmaControls[]; } output; }; } tusb_desc_video_streaming_inout_header_t; // 3.9.2.6 Color Matching Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bColorPrimaries; uint8_t bTransferCharacteristics; uint8_t bMatrixCoefficients; } tusb_desc_video_streaming_color_matching_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_streaming_color_matching_t) == 6, "size is not correct"); //--------------------------------------------------------------------+ // Format and Frame Descriptor // Note: bFormatIndex & bFrameIndex are 1-based index //--------------------------------------------------------------------+ //------------- Uncompressed -------------// // Uncompressed payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; // Number of frame descriptors for this format uint8_t guidFormat[16]; uint8_t bBitsPerPixel; uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; } tusb_desc_video_format_uncompressed_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is not correct"); // Uncompressed payload specs: 3.1.2 frame descriptor #define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ struct TU_ATTR_PACKED { \ uint8_t bLength; \ uint8_t bDescriptorType; \ uint8_t bDescriptorSubType; \ uint8_t bFrameIndex; \ uint8_t bmCapabilities; \ uint16_t wWidth; \ uint16_t wHeight; \ uint32_t dwMinBitRate; \ uint32_t dwMaxBitRate; \ uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ uint32_t dwDefaultFrameInterval; /* 100ns unit */\ uint8_t bFrameIntervalType; \ uint32_t dwFrameInterval[_nint]; \ } typedef tusb_desc_video_frame_uncompressed_nint_t() tusb_desc_video_frame_uncompressed_t; typedef tusb_desc_video_frame_uncompressed_nint_t(1) tusb_desc_video_frame_uncompressed_1int_t; typedef tusb_desc_video_frame_uncompressed_nint_t(2) tusb_desc_video_frame_uncompressed_2int_t; typedef tusb_desc_video_frame_uncompressed_nint_t(3) tusb_desc_video_frame_uncompressed_3int_t; typedef tusb_desc_video_frame_uncompressed_nint_t(4) tusb_desc_video_frame_uncompressed_4int_t; // continuous = 3 intervals: min, max, step typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_uncompressed_continuous_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_frame_uncompressed_continuous_t) == 38, "size is not correct"); //------------- MJPEG -------------// // MJPEG payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; uint8_t bmFlags; // Bit 0: fixed size samples (1 = yes) uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; } tusb_desc_video_format_mjpeg_t; TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_mjpeg_t) == 11, "size is not correct"); // MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; typedef tusb_desc_video_frame_uncompressed_2int_t tusb_desc_video_frame_mjpeg_2int_t; typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_mjpeg_3int_t; typedef tusb_desc_video_frame_uncompressed_4int_t tusb_desc_video_frame_mjpeg_4int_t; // continuous = 3 intervals: min, max, step typedef tusb_desc_video_frame_mjpeg_3int_t tusb_desc_video_frame_mjpeg_continuous_t; //------------- DV -------------// // DV payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ uint8_t bFormatType; } tusb_desc_video_format_dv_t; // Frame Based payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; uint8_t guidFormat[16]; uint8_t bBitsPerPixel; uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; uint8_t bVaribaleSize; } tusb_desc_video_format_framebased_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFrameIndex; uint8_t bmCapabilities; uint16_t wWidth; uint16_t wHeight; uint32_t dwMinBitRate; uint32_t dwMaxBitRate; uint32_t dwDefaultFrameInterval; uint8_t bFrameIntervalType; uint32_t dwBytesPerLine; uint32_t dwFrameInterval[]; } tusb_desc_video_frame_framebased_t; //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ /* 2.4.3.3 */ typedef struct TU_ATTR_PACKED { uint8_t bHeaderLength; union { uint8_t bmHeaderInfo; struct { uint8_t FrameID: 1; uint8_t EndOfFrame: 1; uint8_t PresentationTime: 1; uint8_t SourceClockReference: 1; uint8_t PayloadSpecific: 1; uint8_t StillImage: 1; uint8_t Error: 1; uint8_t EndOfHeader: 1; }; }; } tusb_video_payload_header_t; /* 4.3.1.1 */ typedef struct TU_ATTR_PACKED { union { uint8_t bmHint; struct TU_ATTR_PACKED { uint16_t dwFrameInterval: 1; uint16_t wKeyFrameRatel : 1; uint16_t wPFrameRate : 1; uint16_t wCompQuality : 1; uint16_t wCompWindowSize: 1; uint16_t : 0; } Hint; }; uint8_t bFormatIndex; uint8_t bFrameIndex; uint32_t dwFrameInterval; uint16_t wKeyFrameRate; uint16_t wPFrameRate; uint16_t wCompQuality; uint16_t wCompWindowSize; uint16_t wDelay; uint32_t dwMaxVideoFrameSize; uint32_t dwMaxPayloadTransferSize; uint32_t dwClockFrequency; union { uint8_t bmFramingInfo; struct TU_ATTR_PACKED { uint8_t FrameID : 1; uint8_t EndOfFrame: 1; uint8_t EndOfSlice: 1; uint8_t : 0; } FramingInfo; }; uint8_t bPreferedVersion; uint8_t bMinVersion; uint8_t bMaxVersion; uint8_t bUsage; uint8_t bBitDepthLuma; uint8_t bmSettings; uint8_t bMaxNumberOfRefFramesPlus1; uint16_t bmRateControlModes; uint64_t bmLayoutPerStream; } video_probe_and_commit_control_t; TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not correct"); #define TUD_VIDEO_DESC_IAD_LEN 8 #define TUD_VIDEO_DESC_STD_VC_LEN 9 #define TUD_VIDEO_DESC_CS_VC_LEN 12 #define TUD_VIDEO_DESC_INPUT_TERM_LEN 8 #define TUD_VIDEO_DESC_OUTPUT_TERM_LEN 9 #define TUD_VIDEO_DESC_CAMERA_TERM_LEN 18 #define TUD_VIDEO_DESC_STD_VS_LEN 9 #define TUD_VIDEO_DESC_CS_VS_IN_LEN 13 #define TUD_VIDEO_DESC_CS_VS_OUT_LEN 9 #define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN 27 #define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN 11 #define TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN 28 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN 38 #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN 26 #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN 38 #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN 26 #define TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN 38 #define TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_DISC_LEN 26 #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN 6 /* 2.2 compression formats */ #define TUD_VIDEO_GUID_YUY2 0x59,0x55,0x59,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_GUID_NV12 0x4E,0x56,0x31,0x32,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_GUID_M420 0x4D,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_GUID_I420 0x49,0x34,0x32,0x30,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_GUID_H264 0x48,0x32,0x36,0x34,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71 #define TUD_VIDEO_DESC_IAD(_firstitf, _nitfs, _stridx) \ TUD_VIDEO_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, \ _firstitf, _nitfs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_INTERFACE_COLLECTION, \ VIDEO_ITF_PROTOCOL_UNDEFINED, _stridx #define TUD_VIDEO_DESC_STD_VC(_itfnum, _nEPs, _stridx) \ TUD_VIDEO_DESC_STD_VC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, \ _nEPs, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_CONTROL, VIDEO_ITF_PROTOCOL_15, _stridx /* 3.7.2 */ #define TUD_VIDEO_DESC_CS_VC(_bcdUVC, _totallen, _clkfreq, ...) \ TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_HEADER, \ U16_TO_U8S_LE(_bcdUVC), U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VC_LEN + (TU_ARGS_NUM(__VA_ARGS__))), \ U32_TO_U8S_LE(_clkfreq), TU_ARGS_NUM(__VA_ARGS__), __VA_ARGS__ /* 3.7.2.1 */ #define TUD_VIDEO_DESC_INPUT_TERM(_tid, _tt, _at, _stridx) \ TUD_VIDEO_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ _tid, U16_TO_U8S_LE(_tt), _at, _stridx /* 3.7.2.2 */ #define TUD_VIDEO_DESC_OUTPUT_TERM(_tid, _tt, _at, _srcid, _stridx) \ TUD_VIDEO_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, \ _tid, U16_TO_U8S_LE(_tt), _at, _srcid, _stridx /* 3.7.2.3 */ #define TUD_VIDEO_DESC_CAMERA_TERM(_tid, _at, _stridx, _focal_min, _focal_max, _focal, _ctls) \ TUD_VIDEO_DESC_CAMERA_TERM_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VC_INPUT_TERMINAL, \ _tid, U16_TO_U8S_LE(VIDEO_ITT_CAMERA), _at, _stridx, \ U16_TO_U8S_LE(_focal_min), U16_TO_U8S_LE(_focal_max), U16_TO_U8S_LE(_focal), 3, \ TU_U32_BYTE0(_ctls), TU_U32_BYTE1(_ctls), TU_U32_BYTE2(_ctls) /* 3.9.1 */ #define TUD_VIDEO_DESC_STD_VS(_itfnum, _alt, _epn, _stridx) \ TUD_VIDEO_DESC_STD_VS_LEN, TUSB_DESC_INTERFACE, _itfnum, _alt, \ _epn, TUSB_CLASS_VIDEO, VIDEO_SUBCLASS_STREAMING, VIDEO_ITF_PROTOCOL_15, _stridx /* 3.9.2.1 */ #define TUD_VIDEO_DESC_CS_VS_INPUT(_numfmt, _totallen, _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, ...) \ TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ VIDEO_CS_ITF_VS_INPUT_HEADER, _numfmt, \ U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_IN_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ _ep, _inf, _termlnk, _sticaptmeth, _trgspt, _trgusg, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ /* 3.9.2.2 */ #define TUD_VIDEO_DESC_CS_VS_OUTPUT(_numfmt, _totallen, _ep, _inf, _termlnk, ...) \ TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, \ VIDEO_CS_ITF_VS_OUTPUT_HEADER, _numfmt, \ U16_TO_U8S_LE((_totallen) + TUD_VIDEO_DESC_CS_VS_OUT_LEN + (_numfmt) * (TU_ARGS_NUM(__VA_ARGS__))), \ _ep, _inf, _termlnk, (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ /* Uncompressed 3.1.1 */ #define TUD_VIDEO_GUID(_g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15) _g0,_g1,_g2,_g3,_g4,_g5,_g6,_g7,_g8,_g9,_g10,_g11,_g12,_g13,_g14,_g15 #define TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfrmdesc, \ _guid, _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, \ _fmtidx, _numfrmdesc, TUD_VIDEO_GUID(_guid), \ _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp /* Uncompressed 3.1.2 Table 3-3 */ #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) /* Uncompressed 3.1.2 Table 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ /* Motion-JPEG 3.1.1 Table 3-1 */ #define TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(_fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp) \ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_MJPEG, \ _fmtidx, _numfrmdesc, _fixed_sz, _frmidx, _asrx, _asry, _interlace, _cp /* Motion-JPEG 3.1.1 Table 3-2 and 3-3 */ #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, _minfrminterval, _maxfrminterval, _frmintervalstep) \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), 0, \ U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) /* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ /* Motion-Frame-Based 3.1.1 Table 3-1 */ #define TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(_fmtidx, _numfrmdesc, _guid, _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp, _variablesize) \ TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED, \ _fmtidx, _numfrmdesc, TUD_VIDEO_GUID(_guid), _bitsperpix, _frmidx, _asrx, _asry, _interlace, _cp, _variablesize /* Motion-Frame-Based 3.1.1 Table 3-2 and 3-3 */ #define TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(_frmidx, _cap, _width, _height, _minbr, _maxbr, _frminterval, _bytesperline, _minfrminterval, _maxfrminterval, _frmintervalstep) \ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN, TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_frminterval), 0, U32_TO_U8S_LE(_bytesperline), \ U32_TO_U8S_LE(_minfrminterval), U32_TO_U8S_LE(_maxfrminterval), U32_TO_U8S_LE(_frmintervalstep) /* Motion-Frame-Based 3.1.1 Table 3-2 and 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _frminterval, _bytesperline, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_FRAME_BASED, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_frminterval), U32_TO_U8S_LE(_bytesperline), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ /* 3.9.2.6 */ #define TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(_color, _trns, _mat) \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN, \ TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_COLORFORMAT, \ _color, _trns, _mat /* 3.10.1.1 */ #define TUD_VIDEO_DESC_EP_ISO(_ep, _epsize, _ep_interval) \ 7, TUSB_DESC_ENDPOINT, _ep, (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS),\ U16_TO_U8S_LE(_epsize), _ep_interval /* 3.10.1.2 */ #define TUD_VIDEO_DESC_EP_BULK(_ep, _epsize, _ep_interval) \ 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), _ep_interval #endif ================================================ FILE: src/class/video/video_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUD_ENABLED && CFG_TUD_VIDEO && CFG_TUD_VIDEO_STREAMING) #include "device/usbd.h" #include "device/usbd_pvt.h" #include "video_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_VIDEO_LOG_LEVEL #define CFG_TUD_VIDEO_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_VIDEO_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ #define VS_STATE_PROBING 0 /* Configuration in progress */ #define VS_STATE_COMMITTED 1 /* Ready for streaming or Streaming via bulk endpoint */ #define VS_STATE_STREAMING 2 /* Streaming via isochronous endpoint */ typedef struct { tusb_desc_interface_t std; tusb_desc_video_control_header_t ctl; } tusb_desc_vc_itf_t; typedef struct { tusb_desc_interface_t std; tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_vs_itf_t; typedef union { tusb_desc_video_control_header_t ctl; tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_video_itf_hdr_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubtype; uint8_t bEntityId; } tusb_desc_cs_video_entity_itf_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubtype; uint16_t wMaxTransferSize; } tusb_desc_cs_video_vc_ep_t; typedef union { struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; }; tusb_desc_video_format_uncompressed_t uncompressed; tusb_desc_video_format_mjpeg_t mjpeg; tusb_desc_video_format_framebased_t frame_based; } tusb_desc_cs_video_fmt_t; typedef union { struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFrameIndex; uint8_t bmCapabilities; uint16_t wWidth; uint16_t wHeight; }; tusb_desc_video_frame_uncompressed_t uncompressed; tusb_desc_video_frame_mjpeg_t mjpeg; tusb_desc_video_frame_framebased_t frame_based; } tusb_desc_cs_video_frm_t; /* video streaming interface */ typedef struct TU_ATTR_PACKED { uint8_t index_vc; /* index of bound video control interface */ uint8_t index_vs; /* index from the video control interface */ struct { uint16_t beg; /* Offset of the beginning of video streaming interface descriptor */ uint16_t end; /* Offset of the end of video streaming interface descriptor */ uint16_t cur; /* Offset of the current settings */ uint16_t ep[2]; /* Offset of endpoint descriptors. 0: streaming, 1: still capture */ } desc; uint8_t *buffer; /* frame buffer. assume linear buffer. no support for stride access */ uint32_t bufsize; /* frame buffer size */ uint32_t offset; /* offset for the next payload transfer */ uint32_t max_payload_transfer_size; uint8_t error_code;/* error code */ uint8_t state; /* 0:probing 1:committed 2:streaming */ video_probe_and_commit_control_t probe_commit_payload; /* Probe and Commit control */ } videod_streaming_interface_t; typedef struct { TUD_EPBUF_DEF(buf, CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE); } videod_streaming_epbuf_t; /* video control interface */ typedef struct TU_ATTR_PACKED { const uint8_t*beg; /* The head of the first video control interface descriptor */ uint16_t len; /* Byte length of the descriptors */ uint16_t cur; /* offset for current video control interface */ uint8_t stm[CFG_TUD_VIDEO_STREAMING]; /* Indices of streaming interface */ uint8_t error_code; /* error code */ uint8_t power_mode; } videod_interface_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static videod_interface_t _videod_itf[CFG_TUD_VIDEO]; static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING]; CFG_TUD_MEM_SECTION static videod_streaming_epbuf_t _videod_streaming_epbuf[CFG_TUD_VIDEO_STREAMING]; static uint8_t const _cap_get = 0x1u; /* support for GET */ static uint8_t const _cap_get_set = 0x3u; /* support for GET and SET */ //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_VIDEO_LOG_LEVEL static tu_lookup_entry_t const tu_lookup_video_request[] = { {.key = VIDEO_REQUEST_UNDEFINED, .data = "Undefined"}, {.key = VIDEO_REQUEST_SET_CUR, .data = "SetCur"}, {.key = VIDEO_REQUEST_SET_CUR_ALL, .data = "SetCurAll"}, {.key = VIDEO_REQUEST_GET_CUR, .data = "GetCur"}, {.key = VIDEO_REQUEST_GET_MIN, .data = "GetMin"}, {.key = VIDEO_REQUEST_GET_MAX, .data = "GetMax"}, {.key = VIDEO_REQUEST_GET_RES, .data = "GetRes"}, {.key = VIDEO_REQUEST_GET_LEN, .data = "GetLen"}, {.key = VIDEO_REQUEST_GET_INFO, .data = "GetInfo"}, {.key = VIDEO_REQUEST_GET_DEF, .data = "GetDef"}, {.key = VIDEO_REQUEST_GET_CUR_ALL, .data = "GetCurAll"}, {.key = VIDEO_REQUEST_GET_MIN_ALL, .data = "GetMinAll"}, {.key = VIDEO_REQUEST_GET_MAX_ALL, .data = "GetMaxAll"}, {.key = VIDEO_REQUEST_GET_RES_ALL, .data = "GetResAll"}, {.key = VIDEO_REQUEST_GET_DEF_ALL, .data = "GetDefAll"}, }; static tu_lookup_table_t const tu_table_video_request = { .count = TU_ARRAY_SIZE(tu_lookup_video_request), .items = tu_lookup_video_request }; static char const* const tu_str_video_vc_control_selector[] = { "Undefined", "Video Power Mode", "Request Error Code", }; static char const* const tu_str_video_vs_control_selector[] = { "Undefined", "Probe", "Commit", "Still Probe", "Still Commit", "Still Image Trigger", "Stream Error Code", "Generate Key Frame", "Update Frame Segment", "Sync Delay", }; #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { (void) ctl_idx; (void) stm_idx; } TU_ATTR_WEAK int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod) { (void) ctl_idx; (void) power_mod; return VIDEO_ERROR_NONE; } TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const *parameters) { (void) ctl_idx; (void) stm_idx; (void) parameters; return VIDEO_ERROR_NONE; } TU_ATTR_WEAK void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request) { (void) ctl_idx; (void) stm_idx; (void) request; } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ /** Get interface number from the interface descriptor * * @param[in] desc interface descriptor * * @return bInterfaceNumber */ static inline uint8_t _desc_itfnum(void const *desc) { return ((uint8_t const*)desc)[2]; } /** Get endpoint address from the endpoint descriptor * * @param[in] desc endpoint descriptor * * @return bEndpointAddress */ static inline uint8_t _desc_ep_addr(void const *desc) { return ((uint8_t const*)desc)[2]; } /** Get instance of streaming interface * * @param[in] ctl_idx instance number of video control * @param[in] stm_idx index number of streaming interface * * @return instance */ static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { videod_interface_t *ctl = &_videod_itf[ctl_idx]; if (!ctl->beg) { return NULL; } videod_streaming_interface_t *stm = &_videod_streaming_itf[ctl->stm[stm_idx]]; if (!stm->desc.beg) { return NULL; } return stm; } static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) { return (tusb_desc_vc_itf_t const *)(self->beg + self->cur); } static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) { if (!self->desc.cur) { return NULL; } uint8_t const *desc = _videod_itf[self->index_vc].beg; return (tusb_desc_vs_itf_t const*)(desc + self->desc.cur); } /** Find the first descriptor of a given type * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * @param[in] desc_type The target descriptor type. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) { void const *cur = beg; while ((cur < end) && (desc_type != tu_desc_type(cur))) { cur = tu_desc_next(cur); } return cur; } /** Find the first descriptor of two given types * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * @param[in] desc_type_0 The first target descriptor type. * @param[in] desc_type_1 The second target descriptor type. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static void const* _find_desc_2_type(void const *beg, void const *end, uint_fast8_t desc_type_0, uint_fast8_t desc_type_1) { void const *cur = beg; while ((cur < end) && (desc_type_0 != tu_desc_type(cur)) && (desc_type_1 != tu_desc_type(cur))) { cur = tu_desc_next(cur); } return cur; } /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * @param[in] desc_type The target descriptor type * @param[in] element_0 The target element following the desc_type * @param[in] element_1 The target element following the element_0 * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static void const* _find_desc_3(void const *beg, void const *end, uint_fast8_t desc_type, uint_fast8_t element_0, uint_fast8_t element_1) { for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { uint8_t const *p = (uint8_t const *)cur; if ((p[2] == element_0) && (p[3] == element_1)) { return cur; } cur = tu_desc_next(cur); } return end; } /** Return the next interface descriptor which has another interface number. * If there are multiple VC interfaces, there will be an IAD descriptor before * the next interface descriptor. Check both the IAD descriptor and the interface * descriptor. * 3.1 Descriptor Layout Overview * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static void const* _next_desc_itf(void const *beg, void const *end) { void const *cur = beg; uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber; while ((cur < end) && (itfnum == ((tusb_desc_interface_t const*)cur)->bInterfaceNumber)) { cur = _find_desc_2_type(tu_desc_next(cur), end, TUSB_DESC_INTERFACE, TUSB_DESC_INTERFACE_ASSOCIATION); } return cur; } /** Find the first interface descriptor with the specified interface number and alternate setting number. * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * @param[in] itfnum The target interface number. * @param[in] altnum The target alternate setting number. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static inline uint8_t const* _find_desc_itf(void const *beg, void const *end, uint_fast8_t itfnum, uint_fast8_t altnum) { return (uint8_t const*) _find_desc_3(beg, end, TUSB_DESC_INTERFACE, itfnum, altnum); } /** Find the first endpoint descriptor belonging to the current interface descriptor. * * The search range is from `beg` to `end` or the next interface descriptor. * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * * @return The pointer for endpoint descriptor. * @retval end did not found endpoint descriptor */ static void const* _find_desc_ep(void const *beg, void const *end) { for (void const *cur = beg; cur < end; cur = tu_desc_next(cur)) { uint_fast8_t desc_type = tu_desc_type(cur); if (TUSB_DESC_ENDPOINT == desc_type) { return cur; } if (TUSB_DESC_INTERFACE == desc_type) { break; } } return end; } /** Return the end of the video control descriptor. */ static inline void const* _end_of_control_descriptor(void const *desc) { tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)desc; return ((uint8_t const*) desc) + vc->std.bLength + tu_le16toh(vc->ctl.wTotalLength); } /** Find the first entity descriptor with the entity ID * specified by the argument belonging to the current video control descriptor. * * @param[in] desc The video control interface descriptor. * @param[in] entityid The target entity id. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ static void const* _find_desc_entity(void const *desc, uint_fast8_t entityid) { void const *end = _end_of_control_descriptor(desc); for (void const *cur = desc; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { tusb_desc_cs_video_entity_itf_t const *itf = (tusb_desc_cs_video_entity_itf_t const *)cur; if ((VIDEO_CS_ITF_VC_INPUT_TERMINAL <= itf->bDescriptorSubtype && itf->bDescriptorSubtype < VIDEO_CS_ITF_VC_MAX) && itf->bEntityId == entityid) { return itf; } cur = tu_desc_next(cur); } return end; } /** Return the end of the video streaming descriptor. */ static inline void const* _end_of_streaming_descriptor(void const *desc) { tusb_desc_vs_itf_t const *vs = (tusb_desc_vs_itf_t const *)desc; return ((uint8_t const*) desc) + vs->std.bLength + tu_le16toh(vs->stm.wTotalLength); } /** Find the first format descriptor with the specified format number. */ static inline void const *_find_desc_format(void const *beg, void const *end, uint_fast8_t fmtnum) { for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { uint8_t const *p = (uint8_t const *)cur; uint_fast8_t fmt = p[2]; if ((fmt == VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED || fmt == VIDEO_CS_ITF_VS_FORMAT_MJPEG || fmt == VIDEO_CS_ITF_VS_FORMAT_DV || fmt == VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED) && fmtnum == p[3]) { return cur; } cur = tu_desc_next(cur); } return end; } /** Find the first frame descriptor with the specified format number. */ static inline void const *_find_desc_frame(void const *beg, void const *end, uint_fast8_t frmnum) { for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, TUSB_DESC_CS_INTERFACE)) { uint8_t const *p = (uint8_t const *)cur; uint_fast8_t frm = p[2]; if ((frm == VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED || frm == VIDEO_CS_ITF_VS_FRAME_MJPEG || frm == VIDEO_CS_ITF_VS_FRAME_FRAME_BASED) && frmnum == p[3]) { return cur; } cur = tu_desc_next(cur); } return end; } /** Set uniquely determined values to variables that have not been set * * @param[in,out] param Target */ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm, video_probe_and_commit_control_t *param) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); uint_fast8_t fmtnum = param->bFormatIndex; TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats); if (0 == fmtnum) { if (1 < vs->stm.bNumFormats) { return true; /* Need to negotiate all variables. */ } fmtnum = 1; param->bFormatIndex = 1; } /* Set the parameters determined by the format */ param->wKeyFrameRate = 1; param->wPFrameRate = 0; param->wCompWindowSize = 1; /* GOP size? */ param->wDelay = 0; /* milliseconds */ param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ param->bmFramingInfo = 0x3; /* enables FrameID and EndOfFrame */ param->bPreferedVersion = 1; param->bMinVersion = 1; param->bMaxVersion = 1; param->bUsage = 0; param->bBitDepthLuma = 8; void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); TU_ASSERT(fmt != end); switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: param->wCompQuality = 1; /* 1 to 10000 */ break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: break; case VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED: break; default: return false; } uint_fast8_t frmnum = param->bFrameIndex; TU_ASSERT(frmnum <= fmt->bNumFrameDescriptors); if (0 == frmnum) { if (1 < fmt->bNumFrameDescriptors) { return true; } frmnum = 1; param->bFrameIndex = 1; } tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); TU_ASSERT(frm != end); /* Set the parameters determined by the frame */ uint_fast32_t frame_size = param->dwMaxVideoFrameSize; if (0 == frame_size) { switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; case VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; default: break; } param->dwMaxVideoFrameSize = frame_size; } uint_fast32_t interval = param->dwFrameInterval; if (0 == interval) { if ((1 < frm->uncompressed.bFrameIntervalType) || ((0 == frm->uncompressed.bFrameIntervalType) && (frm->uncompressed.dwFrameInterval[1] != frm->uncompressed.dwFrameInterval[0]))) { return true; } interval = frm->uncompressed.dwFrameInterval[0]; param->dwFrameInterval = interval; } uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms != 0); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; } param->dwMaxPayloadTransferSize = payload_size; return true; } /** Set the minimum, maximum, default values or resolutions to variables which need to negotiate with the host * * @param[in] request GET_MAX, GET_MIN, GET_RES or GET_DEF * @param[in,out] param Target */ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const *stm, uint_fast8_t request, video_probe_and_commit_control_t *param) { uint_fast8_t const fmtnum = param->bFormatIndex; if (0 == fmtnum) { switch (request) { case VIDEO_REQUEST_GET_MAX: if (_get_desc_vs(stm)) param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; break; case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_DEF: param->bFormatIndex = 1; break; default: return false; } /* Set the parameters determined by the format */ param->wKeyFrameRate = 1; param->wPFrameRate = 0; param->wCompQuality = 1; /* 1 to 10000 */ param->wCompWindowSize = 1; /* GOP size? */ param->wDelay = 0; /* milliseconds */ param->dwClockFrequency = 27000000; /* same as MPEG-2 system time clock */ param->bmFramingInfo = 0x3; /* enables FrameID and EndOfFrame */ param->bPreferedVersion = 1; param->bMinVersion = 1; param->bMaxVersion = 1; param->bUsage = 0; param->bBitDepthLuma = 8; return true; } uint_fast8_t frmnum = param->bFrameIndex; if (0 == frmnum) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); switch (request) { case VIDEO_REQUEST_GET_MAX: frmnum = fmt->bNumFrameDescriptors; break; case VIDEO_REQUEST_GET_MIN: frmnum = 1; break; case VIDEO_REQUEST_GET_DEF: switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frmnum = fmt->uncompressed.bDefaultFrameIndex; break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frmnum = fmt->mjpeg.bDefaultFrameIndex; break; case VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED: frmnum = fmt->frame_based.bDefaultFrameIndex; break; default: return false; } break; default: return false; } param->bFrameIndex = (uint8_t)frmnum; /* Set the parameters determined by the frame */ tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); uint_fast32_t frame_size; switch (fmt->bDescriptorSubType) { case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; case VIDEO_CS_ITF_VS_FORMAT_FRAME_BASED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; default: return false; } param->dwMaxVideoFrameSize = frame_size; return true; } if (0 == param->dwFrameInterval) { tusb_desc_vs_itf_t const *vs = _get_desc_vs(stm); TU_ASSERT(vs); void const *end = _end_of_streaming_descriptor(vs); tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; min_interval = frm->uncompressed.dwFrameInterval[0]; interval = max_interval; interval_ms = min_interval / 10000; break; } case VIDEO_REQUEST_GET_MIN: { uint_fast32_t min_interval, max_interval; uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; min_interval = frm->uncompressed.dwFrameInterval[0]; interval = min_interval; interval_ms = max_interval / 10000; break; } case VIDEO_REQUEST_GET_DEF: interval = frm->uncompressed.dwDefaultFrameInterval; interval_ms = interval / 10000; break; case VIDEO_REQUEST_GET_RES: { uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; if (num_intervals) { interval = 0; interval_ms = 0; } else { interval = frm->uncompressed.dwFrameInterval[2]; interval_ms = interval / 10000; } break; } default: return false; } param->dwFrameInterval = interval; if (0 == interval) { param->dwMaxPayloadTransferSize = 0; } else { uint_fast32_t frame_size = param->dwMaxVideoFrameSize; uint_fast32_t payload_size; if (0 == interval_ms) { payload_size = frame_size + 2; } else { payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; } param->dwMaxPayloadTransferSize = payload_size; } return true; } return true; } /** Close current video control interface. * * @param[in,out] self Video control interface context. * @param[in] altnum The target alternate setting number. */ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) { tusb_desc_vc_itf_t const *vc = _get_desc_vc(self); /* The next descriptor after the class-specific VC interface header descriptor. */ void const *cur = (uint8_t const*)vc + vc->std.bLength + vc->ctl.bLength; /* The end of the video control interface descriptor. */ void const *end = _end_of_control_descriptor(vc); if (vc->std.bNumEndpoints != 0) { /* Extend end to cover the standard endpoint and class-specific endpoint descriptors * that follow wTotalLength */ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t); /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); TU_ASSERT(cur < end); tusb_desc_endpoint_t const *notif = (tusb_desc_endpoint_t const *)cur; usbd_edpt_close(rhport, notif->bEndpointAddress); } self->cur = 0; return true; } /** Set the alternate setting to own video control interface. * * @param[in,out] self Video control interface context. * @param[in] altnum The target alternate setting number. */ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t altnum) { TU_LOG_DRV(" open VC %d\r\n", altnum); uint8_t const *beg = self->beg; uint8_t const *end = beg + self->len; /* The first descriptor is a video control interface descriptor. */ uint8_t const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); TU_LOG_DRV(" cur %" PRId32 "\r\n", (int32_t) (cur - beg)); TU_VERIFY(cur < end); tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)cur; TU_LOG_DRV(" bInCollection %d\r\n", vc->ctl.bInCollection); /* Support for up to 2 streaming interfaces only. */ TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); /* Update to point the end of the video control interface descriptor. */ end = _end_of_control_descriptor(cur); /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; TU_LOG_DRV(" bNumEndpoints %d\r\n", vc->std.bNumEndpoints); /* Open the notification endpoint if it exist. */ if (vc->std.bNumEndpoints != 0) { /* Support for 1 endpoint only. */ TU_VERIFY(1 == vc->std.bNumEndpoints); /* Extend end to cover the standard endpoint and class-specific endpoint descriptors * that follow wTotalLength */ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t); /* Find the notification endpoint descriptor. */ cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT); TU_VERIFY(cur < end); tusb_desc_endpoint_t const *notif = (tusb_desc_endpoint_t const *)cur; /* Open the notification endpoint */ TU_ASSERT(usbd_edpt_open(rhport, notif)); } self->cur = (uint16_t) ((uint8_t const*)vc - beg); return true; } static bool _init_vs_configuration(videod_streaming_interface_t *stm) { /* initialize streaming settings */ stm->state = VS_STATE_PROBING; stm->max_payload_transfer_size = 0; video_probe_and_commit_control_t *param = &stm->probe_commit_payload; tu_memclr(param, sizeof(*param)); return _update_streaming_parameters(stm, param); } /** Set the alternate setting to own video streaming interface. * * @param[in,out] stm Streaming interface context. * @param[in] altnum The target alternate setting number. */ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint_fast8_t altnum) { uint_fast8_t i; TU_LOG_DRV(" reopen VS %d\r\n", altnum); uint8_t const *desc = _videod_itf[stm->index_vc].beg; #ifndef TUP_DCD_EDPT_ISO_ALLOC /* Close endpoints of previous settings. */ for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); /* Only ISO endpoints needs to be closed */ if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { stm->desc.ep[i] = 0; usbd_edpt_close(rhport, ep->bEndpointAddress); TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); } } #endif /* clear transfer management information */ stm->buffer = NULL; stm->bufsize = 0; stm->offset = 0; /* Find a alternate interface */ uint8_t const *beg = desc + stm->desc.beg; uint8_t const *end = desc + stm->desc.end; uint8_t const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); TU_VERIFY(cur < end); uint_fast8_t numeps = ((tusb_desc_interface_t const *)cur)->bNumEndpoints; TU_ASSERT(numeps <= TU_ARRAY_SIZE(stm->desc.ep)); stm->desc.cur = (uint16_t)(cur - desc); /* Save the offset of the new settings */ if (!altnum && (VS_STATE_COMMITTED != stm->state)) { TU_VERIFY(_init_vs_configuration(stm)); } /* Open bulk or isochronous endpoints of the new settings. */ for (i = 0, cur = tu_desc_next(cur); i < numeps; ++i, cur = tu_desc_next(cur)) { cur = _find_desc_ep(cur, end); TU_ASSERT(cur < end); tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur; uint_fast32_t max_size = stm->max_payload_transfer_size; if (altnum && (TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer)) { /* FS must be less than or equal to max packet size */ TU_VERIFY (tu_edpt_packet_size(ep) >= max_size); #ifdef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_iso_activate(rhport, ep); #else TU_ASSERT(usbd_edpt_open(rhport, ep)); #endif } else { TU_VERIFY(TUSB_XFER_BULK == ep->bmAttributes.xfer); TU_ASSERT(usbd_edpt_open(rhport, ep)); } stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur)); } if (altnum != 0) { stm->state = VS_STATE_STREAMING; } TU_LOG_DRV(" done\r\n"); return true; } /** Prepare the next packet payload. */ static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm, uint8_t* ep_buf) { uint_fast16_t remaining = stm->bufsize - stm->offset; uint_fast16_t hdr_len = ep_buf[0]; uint_fast16_t pkt_len = stm->max_payload_transfer_size; if (hdr_len + remaining < pkt_len) { pkt_len = hdr_len + remaining; } TU_ASSERT(pkt_len >= hdr_len); uint_fast16_t data_len = pkt_len - hdr_len; if (stm->buffer) { memcpy(&ep_buf[hdr_len], stm->buffer + stm->offset, data_len); } else { tud_video_payload_request_t rqst = { .buf = &ep_buf[hdr_len], .length = data_len, .offset = stm->offset }; tud_video_prepare_payload_cb(stm->index_vc, stm->index_vs, &rqst); } stm->offset += data_len; remaining -= data_len; if (!remaining) { tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*) ep_buf; hdr->EndOfFrame = 1; } return hdr_len + data_len; } /** Handle a standard request to the video control interface. */ static int handle_video_ctl_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { TU_LOG_DRV("\r\n"); switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); tusb_desc_vc_itf_t const *vc = _get_desc_vc(&_videod_itf[ctl_idx]); TU_VERIFY(vc, VIDEO_ERROR_UNKNOWN); uint8_t alt_num = vc->std.bAlternateSetting; TU_VERIFY(tud_control_xfer(rhport, request, &alt_num, sizeof(alt_num)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case TUSB_REQ_SET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(0 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(_close_vc_itf(rhport, &_videod_itf[ctl_idx]), VIDEO_ERROR_UNKNOWN); TU_VERIFY(_open_vc_itf(rhport, &_videod_itf[ctl_idx], request->wValue), VIDEO_ERROR_UNKNOWN); tud_control_status(rhport, request); } return VIDEO_ERROR_NONE; default: /* Unknown/Unsupported request */ TU_BREAKPOINT(); return VIDEO_ERROR_INVALID_REQUEST; } } static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { videod_interface_t *self = &_videod_itf[ctl_idx]; /* 4.2.1 Interface Control Request */ uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vc_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); switch (ctrl_sel) { case VIDEO_VC_CTL_VIDEO_POWER_MODE: switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { return tud_video_power_mode_cb(ctl_idx, self->power_mode); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &self->power_mode, sizeof(self->power_mode)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; default: break; } break; case VIDEO_VC_CTL_REQUEST_ERROR_CODE: switch (request->bRequest) { case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; default: break; } break; default: break; } /* Unknown/Unsupported request */ TU_BREAKPOINT(); return VIDEO_ERROR_INVALID_REQUEST; } static int handle_video_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: return handle_video_ctl_std_req(rhport, stage, request, ctl_idx); case TUSB_REQ_TYPE_CLASS: { uint_fast8_t entity_id = TU_U16_HIGH(request->wIndex); if (0 == entity_id) { return handle_video_ctl_cs_req(rhport, stage, request, ctl_idx); } else { TU_VERIFY(_find_desc_entity(_get_desc_vc(&_videod_itf[ctl_idx]), entity_id), VIDEO_ERROR_INVALID_REQUEST); return VIDEO_ERROR_NONE; } } default: return VIDEO_ERROR_INVALID_REQUEST; } } static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t stm_idx) { TU_LOG_DRV("\r\n"); videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); tusb_desc_vs_itf_t const *vs = _get_desc_vs(self); TU_VERIFY(vs, VIDEO_ERROR_UNKNOWN); uint8_t alt_num = vs->std.bAlternateSetting; TU_VERIFY(tud_control_xfer(rhport, request, &alt_num, sizeof(alt_num)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case TUSB_REQ_SET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(_open_vs_itf(rhport, self, request->wValue), VIDEO_ERROR_UNKNOWN); tud_control_status(rhport, request); } return VIDEO_ERROR_NONE; default: /* Unknown/Unsupported request */ TU_BREAKPOINT(); return VIDEO_ERROR_INVALID_REQUEST; } } static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t stm_idx) { (void)rhport; videod_streaming_interface_t *stm = &_videod_streaming_itf[stm_idx]; videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[stm_idx]; uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vs_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); /* 4.2.1 Interface Control Request */ switch (ctrl_sel) { case VIDEO_VS_CTL_STREAM_ERROR_CODE: switch (request->bRequest) { case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { /* TODO */ TU_VERIFY(tud_control_xfer(rhport, request, &stm->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; default: break; } break; case VIDEO_VS_CTL_PROBE: if (stm->state != VS_STATE_PROBING) { stm->state = VS_STATE_PROBING; } switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { TU_VERIFY(_update_streaming_parameters(stm, &stm->probe_commit_payload), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); } else { // nothing to do } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_MAX: case VIDEO_REQUEST_GET_RES: case VIDEO_REQUEST_GET_DEF: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN); video_probe_and_commit_control_t tmp = stm->probe_commit_payload; TU_VERIFY(_negotiate_streaming_parameters(stm, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; default: break; } break; case VIDEO_VS_CTL_COMMIT: switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { video_probe_and_commit_control_t *param = &stm->probe_commit_payload; TU_VERIFY(_update_streaming_parameters(stm, param), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); /* Set the negotiated value */ stm->max_payload_transfer_size = param->dwMaxPayloadTransferSize; int ret = tud_video_commit_cb(stm->index_vc, stm->index_vs, param); if (VIDEO_ERROR_NONE == ret) { stm->state = VS_STATE_COMMITTED; stm->buffer = NULL; stm->bufsize = 0; stm->offset = 0; /* initialize payload header */ tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm_epbuf->buf; hdr->bHeaderLength = sizeof(*hdr); hdr->bmHeaderInfo = 0; } } else { // nothing to do } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength != 0, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, &stm->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; default: break; } break; case VIDEO_VS_CTL_STILL_PROBE: case VIDEO_VS_CTL_STILL_COMMIT: case VIDEO_VS_CTL_STILL_IMAGE_TRIGGER: case VIDEO_VS_CTL_GENERATE_KEY_FRAME: case VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT: case VIDEO_VS_CTL_SYNCH_DELAY_CONTROL: /* TODO */ break; default: break; } /* Unknown/Unsupported request */ TU_BREAKPOINT(); return VIDEO_ERROR_INVALID_REQUEST; } static int handle_video_stm_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t stm_idx) { switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: return handle_video_stm_std_req(rhport, stage, request, stm_idx); case TUSB_REQ_TYPE_CLASS: if (0 != TU_U16_HIGH(request->wIndex)) { return VIDEO_ERROR_INVALID_REQUEST; } return handle_video_stm_cs_req(rhport, stage, request, stm_idx); default: return VIDEO_ERROR_INVALID_REQUEST; } } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_video_n_connected(uint_fast8_t ctl_idx) { TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, 0); if (stm != NULL) { return true; } return false; } bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING); videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); if (NULL == stm || 0 == stm->desc.ep[0]) { return false; } if (stm->state == VS_STATE_PROBING) { return false; } #ifdef TUP_DCD_EDPT_ISO_ALLOC uint8_t const *desc = _videod_itf[stm->index_vc].beg; uint_fast16_t ofs_ep = stm->desc.ep[0]; tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); if (ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { if (stm->state == VS_STATE_COMMITTED) { return false; } } #endif return true; } bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize) { TU_ASSERT(ctl_idx < CFG_TUD_VIDEO); TU_ASSERT(stm_idx < CFG_TUD_VIDEO_STREAMING); if (0 == bufsize) { return false; } videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[ctl_idx]; if (NULL == stm || 0 == stm->desc.ep[0] || stm->bufsize) { return false; } if (stm->state == VS_STATE_PROBING) { return false; } /* Find EP address */ uint8_t const *desc = _videod_itf[stm->index_vc].beg; uint8_t ep_addr = 0; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (0 == ofs_ep) { continue; } ep_addr = _desc_ep_addr(desc + ofs_ep); break; } if (0 == ep_addr) { return false; } TU_VERIFY(usbd_edpt_claim(0, ep_addr)); /* update the packet header */ tusb_video_payload_header_t *hdr = (tusb_video_payload_header_t*)stm_epbuf->buf; hdr->FrameID ^= 1; hdr->EndOfFrame = 0; /* update the packet data */ stm->buffer = (uint8_t*)buffer; stm->bufsize = bufsize; uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf); TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0); return true; } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ void videod_init(void) { for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; tu_memclr(ctl, sizeof(*ctl)); } for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { videod_streaming_interface_t *stm = &_videod_streaming_itf[i]; tu_memclr(stm, sizeof(videod_streaming_interface_t)); } } bool videod_deinit(void) { return true; } void videod_reset(uint8_t rhport) { (void) rhport; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; tu_memclr(ctl, sizeof(*ctl)); } for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { videod_streaming_interface_t *stm = &_videod_streaming_itf[i]; tu_memclr(stm, sizeof(videod_streaming_interface_t)); } } uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { TU_VERIFY((TUSB_CLASS_VIDEO == itf_desc->bInterfaceClass) && (VIDEO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass) && (VIDEO_ITF_PROTOCOL_15 == itf_desc->bInterfaceProtocol), 0); /* Find available interface */ videod_interface_t *self = NULL; uint8_t ctl_idx; for (ctl_idx = 0; ctl_idx < CFG_TUD_VIDEO; ++ctl_idx) { if (NULL != _videod_itf[ctl_idx].beg) { continue; } self = &_videod_itf[ctl_idx]; break; } TU_ASSERT(ctl_idx < CFG_TUD_VIDEO, 0); uint8_t const *end = (uint8_t const*)itf_desc + max_len; self->beg = (uint8_t const*) itf_desc; self->len = max_len; /*------------- Video Control Interface -------------*/ TU_VERIFY(_open_vc_itf(rhport, self, 0), 0); tusb_desc_vc_itf_t const *vc = _get_desc_vc(self); uint_fast8_t bInCollection = vc->ctl.bInCollection; /* Find the end of the video interface descriptor */ void const *cur = _next_desc_itf(itf_desc, end); for (uint8_t stm_idx = 0; stm_idx < bInCollection; ++stm_idx) { videod_streaming_interface_t *stm = NULL; /* find free streaming interface handle */ for (uint8_t i = 0; i < CFG_TUD_VIDEO_STREAMING; ++i) { if (0 != _videod_streaming_itf[i].desc.beg) { continue; } stm = &_videod_streaming_itf[i]; self->stm[stm_idx] = i; break; } TU_ASSERT(stm, 0); stm->index_vc = ctl_idx; stm->index_vs = stm_idx; stm->desc.beg = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); cur = _next_desc_itf(cur, end); stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); stm->state = VS_STATE_PROBING; #ifdef TUP_DCD_EDPT_ISO_ALLOC /* Allocate ISO endpoints */ uint16_t ep_size = 0; uint8_t ep_addr = 0; uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg; uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end; while (p_desc < p_desc_end) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { ep_addr = desc_ep->bEndpointAddress; ep_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_size); } } p_desc = tu_desc_next(p_desc); } if(ep_addr > 0 && ep_size > 0) { usbd_edpt_iso_alloc(rhport, ep_addr, ep_size); } #endif if (0 == stm_idx && 1 == bInCollection) { /* If there is only one streaming interface and no alternate settings, * host may not issue set_interface so open the streaming interface here. */ uint8_t const *sbeg = (uint8_t const*)itf_desc + stm->desc.beg; uint8_t const *send = (uint8_t const*)itf_desc + stm->desc.end; if (send == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) { TU_VERIFY(_open_vs_itf(rhport, stm, 0), 0); } } } self->len = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); return (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); } // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { int err; TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint_fast8_t itfnum = tu_u16_low(request->wIndex); /* Identify which control interface to use */ uint_fast8_t itf; for (itf = 0; itf < CFG_TUD_VIDEO; ++itf) { void const *desc = _videod_itf[itf].beg; if (!desc) { continue; } if (itfnum == _desc_itfnum(desc)) { break; } } if (itf < CFG_TUD_VIDEO) { TU_LOG_DRV(" VC[%d]: ", itf); err = handle_video_ctl_req(rhport, stage, request, itf); _videod_itf[itf].error_code = (uint8_t)err; if (0 != err) { return false; } return true; } /* Identify which streaming interface to use */ for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) { videod_streaming_interface_t *stm = &_videod_streaming_itf[itf]; if (0 == stm->desc.beg) { continue; } uint8_t const *desc = _videod_itf[stm->index_vc].beg; if (itfnum == _desc_itfnum(desc + stm->desc.beg)) { break; } } if (itf < CFG_TUD_VIDEO_STREAMING) { TU_LOG_DRV(" VS[%d]: ", itf); err = handle_video_stm_req(rhport, stage, request, itf); _videod_streaming_itf[itf].error_code = (uint8_t)err; if (err != 0) { return false; } return true; } return false; } bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)result; (void)xferred_bytes; /* find streaming handle */ uint_fast8_t itf; videod_interface_t *ctl; videod_streaming_interface_t *stm; for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) { stm = &_videod_streaming_itf[itf]; uint_fast16_t const ep_ofs = stm->desc.ep[0]; if (0 == ep_ofs) { continue; } ctl = &_videod_itf[stm->index_vc]; uint8_t const *desc = ctl->beg; if (ep_addr == _desc_ep_addr(desc + ep_ofs)) { break; } } TU_ASSERT(itf < CFG_TUD_VIDEO_STREAMING); videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[itf]; if (stm->offset < stm->bufsize) { /* Claim the endpoint */ TU_VERIFY(usbd_edpt_claim(rhport, ep_addr), 0); uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf); TU_ASSERT(usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0); } else { stm->buffer = NULL; stm->bufsize = 0; stm->offset = 0; tud_video_frame_xfer_complete_cb(stm->index_vc, stm->index_vs); } return true; } #endif ================================================ FILE: src/class/video/video_device.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2021 Koji KITAYAMA * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_VIDEO_DEVICE_H_ #define TUSB_VIDEO_DEVICE_H_ #include "common/tusb_common.h" #include "video.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Payload request //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { void* buf; /* Payload buffer to be filled */ size_t length; /* Length of the requested data in bytes */ size_t offset; /* Offset within the frame (in bytes) */ } tud_video_payload_request_t; //--------------------------------------------------------------------+ // Application API (Multiple Ports) // CFG_TUD_VIDEO > 1 //--------------------------------------------------------------------+ bool tud_video_n_connected(uint_fast8_t ctl_idx); /** Return true if streaming * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index */ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); /** Transfer a frame * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index * @param[in] buffer Frame buffer. The caller must not use this buffer until the operation is completed. * @param[in] bufsize Byte size of the frame buffer */ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *buffer, size_t bufsize); /*------------- Optional callbacks -------------*/ /** Invoked when compeletion of a frame transfer * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index */ void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ /** Invoked when SET_POWER_MODE request received * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index * @return video_error_code_t */ int tud_video_power_mode_cb(uint_fast8_t ctl_idx, uint8_t power_mod); /** Invoked when VS_COMMIT_CONTROL(SET_CUR) request received * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index * @param[in] parameters Video streaming parameters * @return video_error_code_t */ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, video_probe_and_commit_control_t const *parameters); /** Invoked if buffer is set to NULL (allows bufferless on the fly data generation) * * @param[in] ctl_idx Destination control interface index * @param[in] stm_idx Destination streaming interface index * @param[out] payload_buf Payload storage buffer (target buffer for requested data) * @param[in] payload_size Size of payload_buf (requested data size) * @param[in] offset Current byte offset relative to given bufsize from tud_video_n_frame_xfer (framesize) */ void tud_video_prepare_payload_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, tud_video_payload_request_t* request); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void videod_init (void); bool videod_deinit (void); void videod_reset (uint8_t rhport); uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool videod_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/common/tusb_common.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_COMMON_H_ #define TUSB_COMMON_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Macros Helper //--------------------------------------------------------------------+ #define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_FIELD_SIZE(_type, _field) (sizeof(((_type *)0)->_field)) #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) #define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d)) #define TU_DIV_ROUND_NEAREST(v, d) (((v) + (d)/2) / (d) ) // round to nearest integer #define TU_U16(_high, _low) ((uint16_t) ((((uint16_t) (_high)) << 8) | ((uint16_t) (_low)))) #define TU_U16_HIGH(_u16) ((uint8_t) (((uint16_t) (_u16) >> 8) & 0x00ffu)) #define TU_U16_LOW(_u16) ((uint8_t) ((uint16_t) (_u16) & 0x00ffu)) #define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16) #define U16_TO_U8S_LE(_u16) TU_U16_LOW(_u16), TU_U16_HIGH(_u16) #define TU_U24(_high, _mid, _low) ((uint32_t) ((((uint32_t) (_high)) << 16) | (((uint32_t) (_mid)) << 8) | ((uint32_t) (_low)))) #define TU_U24_HIGH(_u24) ((uint8_t) (((uint32_t) (_u24) >> 16) & 0x0000ffu)) #define TU_U24_MID(_u24) ((uint8_t) (((uint32_t) (_u24) >> 8) & 0x0000ffu)) #define TU_U24_LOW(_u24) ((uint8_t) ((uint32_t) (_u24) & 0x0000ffu)) #define U24_TO_U8S_BE(_u24) TU_U24_HIGH(_u24), TU_U24_MID(_u24), TU_U24_LOW(_u24) #define U24_TO_U8S_LE(_u24) TU_U24_LOW(_u24), TU_U24_MID(_u24), TU_U24_HIGH(_u24) #define TU_U32_BYTE3(_u32) ((uint8_t) ((((uint32_t) _u32) >> 24) & 0x000000ff)) // MSB #define TU_U32_BYTE2(_u32) ((uint8_t) ((((uint32_t) _u32) >> 16) & 0x000000ff)) #define TU_U32_BYTE1(_u32) ((uint8_t) ((((uint32_t) _u32) >> 8) & 0x000000ff)) #define TU_U32_BYTE0(_u32) ((uint8_t) (((uint32_t) _u32) & 0x000000ff)) // LSB #define U32_TO_U8S_BE(_u32) TU_U32_BYTE3(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE0(_u32) #define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32) #define TU_BIT(n) (1UL << (n)) // Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111 #define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) ) //--------------------------------------------------------------------+ // Includes //--------------------------------------------------------------------+ // Standard Headers #include #include #include #include #include // Tinyusb Common Headers #include "tusb_option.h" #include "tusb_compiler.h" #include "tusb_verify.h" #include "tusb_types.h" #include "tusb_debug.h" //--------------------------------------------------------------------+ // API implemented by application if needed // TODO move to a more obvious place/file //--------------------------------------------------------------------+ // Get current milliseconds, required by some port/configuration without RTOS extern uint32_t tusb_time_millis_api(void); // Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS extern void tusb_time_delay_ms_api(uint32_t ms); // flush data cache extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size); // invalidate data cache extern void tusb_app_dcache_invalidate(uintptr_t addr, uint32_t data_size); // Optional physical <-> virtual address translation extern void* tusb_app_virt_to_phys(void *virt_addr); extern void* tusb_app_phys_to_virt(void *phys_addr); //--------------------------------------------------------------------+ // Internal Inline Functions //--------------------------------------------------------------------+ //------------- Mem -------------// #define tu_memclr(buffer, size) (void) memset((buffer), 0, (size)) #define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) // This is a backport of memset_s from c11 TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) { // Validate parameters if (dest == NULL) { return -1; } if (count == 0u) { return 0; } if (count > destsz) { return -1; } (void) memset(dest, ch, count); return 0; } // This is a backport of memcpy_s from c11 TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) { if (dest == NULL) { return -1; } if (count == 0u) { return 0; } if (src == NULL) { return -1; } if (count > destsz) { return -1; } (void) memcpy(dest, src, count); return 0; } TU_ATTR_ALWAYS_INLINE static inline bool tu_mem_is_zero(const void *buffer, size_t size) { const uint8_t* buf8 = (const uint8_t*) buffer; for (size_t i = 0; i < size; i++) { if (buf8[i] != 0) { return false; } } return true; } TU_ATTR_ALWAYS_INLINE static inline bool tu_mem_is_ff(const void *buffer, size_t size) { const uint8_t* buf8 = (const uint8_t*) buffer; for (size_t i = 0; i < size; i++) { if (buf8[i] != 0xff) { return false; } } return true; } //------------- Bytes -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) { return (((uint32_t)b3) << 24) | (((uint32_t)b2) << 16) | (((uint32_t)b1) << 8) | b0; } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32_from_u16(uint16_t high, uint16_t low) { return (((uint32_t)high) << 16) | low; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) { return (uint16_t)((((uint16_t)high) << 8) | low); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t ui32) { return TU_U32_BYTE3(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_U32_BYTE2(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } //------------- Bits -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); } TU_ATTR_ALWAYS_INLINE static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; } //------------- Min -------------// TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_min8 (uint8_t x, uint8_t y ) { return (x < y) ? x : y; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_min16 (uint16_t x, uint16_t y) { return (x < y) ? x : y; } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_min32 (uint32_t x, uint32_t y) { return (x < y) ? x : y; } //------------- Max -------------// TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_max8 (uint8_t x, uint8_t y ) { return (x > y) ? x : y; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { return (x > y) ? x : y; } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; } //------------- Align -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) { return value & ((uint32_t) ~(alignment-1)); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4 (uint32_t value) { return (value & 0xFFFFFFFCUL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align8 (uint32_t value) { return (value & 0xFFFFFFF8UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); } TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; } TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; } //------------- Mathematics -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return TU_DIV_CEIL(v, d); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_round_nearest(uint32_t v, uint32_t d) { return TU_DIV_ROUND_NEAREST(v, d); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_round_up(uint32_t v, uint32_t f) { return tu_div_ceil(v, f) * f; } // log2 of a value is its MSB's position // TODO use clz TODO remove TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_log2(uint32_t value) { uint8_t result = 0; while ((value >>= 1u) != 0u) { result++; } return result; } //static inline uint8_t tu_log2(uint32_t value) //{ // return sizeof(uint32_t) * CHAR_BIT - __builtin_clz(x) - 1; //} TU_ATTR_ALWAYS_INLINE static inline bool tu_is_power_of_two(uint32_t value) { return (value != 0) && ((value & (value - 1)) == 0); } //------------- Unaligned Access -------------// #if TUP_ARCH_STRICT_ALIGN // Rely on compiler to generate correct code for unaligned access typedef struct { uint16_t val; } TU_ATTR_PACKED tu_unaligned_uint16_t; typedef struct { uint32_t val; } TU_ATTR_PACKED tu_unaligned_uint32_t; TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) { tu_unaligned_uint32_t const *ua32 = (tu_unaligned_uint32_t const *) mem; return ua32->val; } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) { tu_unaligned_uint32_t *ua32 = (tu_unaligned_uint32_t *) mem; ua32->val = value; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) { tu_unaligned_uint16_t const *ua16 = (tu_unaligned_uint16_t const *) mem; return ua16->val; } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) { tu_unaligned_uint16_t *ua16 = (tu_unaligned_uint16_t *) mem; ua16->val = value; } #elif TUP_MCU_STRICT_ALIGN // MCU such as LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM although it is ARM M4. // We have to manually pick up bytes since tu_unaligned_uint32_t will still generate unaligned code // NOTE: volatile cast to memory to prevent compiler to optimize and generate unaligned code // TODO Big Endian may need minor changes TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem) { volatile uint8_t const* buf8 = (uint8_t const*) mem; return tu_u32(buf8[3], buf8[2], buf8[1], buf8[0]); } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value) { volatile uint8_t* buf8 = (uint8_t*) mem; buf8[0] = tu_u32_byte0(value); buf8[1] = tu_u32_byte1(value); buf8[2] = tu_u32_byte2(value); buf8[3] = tu_u32_byte3(value); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem) { volatile uint8_t const* buf8 = (uint8_t const*) mem; return tu_u16(buf8[1], buf8[0]); } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value) { volatile uint8_t* buf8 = (uint8_t*) mem; buf8[0] = tu_u16_low(value); buf8[1] = tu_u16_high(value); } #else // MCU that could access unaligned memory natively TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) { return *((uint32_t const *) mem); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) { return *((uint16_t const *) mem); } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) { *((uint32_t *) mem) = value; } TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) { *((uint16_t *) mem) = value; } #endif // scatter read 4 bytes from two buffers (LE). Parameter are not checked TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_scatter_read32(const uint8_t *buf1, uint8_t len1, const uint8_t *buf2, uint8_t len2) { uint32_t result = 0; uint8_t shift = 0; for (uint8_t i = 0; i < len1; ++i) { result |= ((uint32_t)buf1[i]) << shift; shift += 8; } for (uint8_t i = 0; i < len2; ++i) { result |= ((uint32_t)buf2[i]) << shift; shift += 8; } return result; } // scatter write 4 bytes (LE) to two buffers. Parameter are not checked TU_ATTR_ALWAYS_INLINE static inline void tu_scatter_write32(uint32_t value, uint8_t *buf1, uint8_t len1, uint8_t *buf2, uint8_t len2) { for (uint8_t i = 0; i < len1; ++i) { buf1[i] = (uint8_t)(value & 0xFF); value >>= 8; } for (uint8_t i = 0; i < len2; ++i) { buf2[i] = (uint8_t)(value & 0xFF); value >>= 8; } } //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ // return next descriptor TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) { uint8_t const* desc8 = (uint8_t const*) desc; return desc8 + desc8[DESC_OFFSET_LEN]; } // get descriptor length TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } // get descriptor type TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; } // get descriptor subtype TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE]; } TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) { return p_desc < desc_end && tu_desc_next(p_desc) <= desc_end; } // find descriptor that match byte1 (type) uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1); // find descriptor that match byte1 (type) and byte2 uint8_t const * tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2); // find descriptor that match byte1 (type) and byte2 uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3); #ifdef __cplusplus } #endif #endif /* TUSB_COMMON_H_ */ ================================================ FILE: src/common/tusb_compiler.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #pragma once #define TU_TOKEN(x) x #define TU_STRING(x) #x ///< stringify without expand #define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify #define TU_STRCAT(a, b) a##b ///< concat without expand #define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand #define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat #define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens #define TU_INCLUDE_PATH(_dir,_file) TU_XSTRING( TU_TOKEN(_dir)TU_TOKEN(_file) ) #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ #define TU_COUNTER __COUNTER__ #else #define TU_COUNTER __LINE__ #endif // Compile-time Assert #if defined (__cplusplus) && __cplusplus >= 201103L #define TU_VERIFY_STATIC static_assert #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, TU_COUNTER)[(const_expr) ? 1 : 0]; #else #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, TU_COUNTER) = 1/(!!(const_expr)) } #endif /* --------------------- Fuzzing types -------------------------------------- */ #ifdef _FUZZ #define tu_static static __thread #else #define tu_static static #endif // for declaration of reserved field, make use of TU_COUNTER #define TU_RESERVED TU_XSTRCAT(reserved, TU_COUNTER) #define TU_LITTLE_ENDIAN (0x12u) #define TU_BIG_ENDIAN (0x21u) /*------------------------------------------------------------------*/ /* Count number of arguments of __VA_ARGS__ * - reference www.stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments * - TU_GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) * - TU_NARG_RSEQ_N() is reverse sequential to N to add padding to have * Nth position is the same as the number of arguments * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) *------------------------------------------------------------------*/ #if defined(__CCRX__) #define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, __VA_ARGS__, TU_NARG_RSEQ_N()) #else #define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, ##__VA_ARGS__, TU_NARG_RSEQ_N()) #endif #define TU_NARG_IMPL(...) TU_GET_NTH_ARG(__VA_ARGS__) #define TU_GET_NTH_ARG( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _61,_62,_63,N,...) N #define TU_NARG_RSEQ_N() \ 62,61,60, \ 59,58,57,56,55,54,53,52,51,50, \ 49,48,47,46,45,44,43,42,41,40, \ 39,38,37,36,35,34,33,32,31,30, \ 29,28,27,26,25,24,23,22,21,20, \ 19,18,17,16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0 // Apply a macro X to each of the arguments with a separation/delimiter #define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__) #define TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1) #define TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2) #define TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s TU_ARGS_APPLY_2(_X, _s, _a2, _a3) #define TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4) #define TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5) #define TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6) #define TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7) #define TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8) // Apply a macro X to each of the arguments and expand the result with comma #define TU_ARGS_APPLY_EXPAND(_X, ...) TU_XSTRCAT(TU_ARGS_APPLY_EXPAND_, TU_ARGS_NUM(__VA_ARGS__))(_X, __VA_ARGS__) #define TU_ARGS_APPLY_EXPAND_1(_X, _a1) _X(_a1) #define TU_ARGS_APPLY_EXPAND_2(_X, _a1, _a2) _X(_a1), _X(_a2) #define TU_ARGS_APPLY_EXPAND_3(_X, _a1, _a2, _a3) _X(_a1), TU_ARGS_APPLY_EXPAND_2(_X, _a2, _a3) #define TU_ARGS_APPLY_EXPAND_4(_X, _a1, _a2, _a3, _a4) _X(_a1), TU_ARGS_APPLY_EXPAND_3(_X, _a2, _a3, _a4) #define TU_ARGS_APPLY_EXPAND_5(_X, _a1, _a2, _a3, _a4, _a5) _X(_a1), TU_ARGS_APPLY_EXPAND_4(_X, _a2, _a3, _a4, _a5) #define TU_ARGS_APPLY_EXPAND_6(_X, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1), TU_ARGS_APPLY_EXPAND_5(_X, _a2, _a3, _a4, _a5, _a6) #define TU_ARGS_APPLY_EXPAND_7(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1), TU_ARGS_APPLY_EXPAND_6(_X, _a2, _a3, _a4, _a5, _a6, _a7) #define TU_ARGS_APPLY_EXPAND_8(_X, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1), TU_ARGS_APPLY_EXPAND_7(_X, _a2, _a3, _a4, _a5, _a6, _a7, _a8) //--------------------------------------------------------------------+ // Macro for function default arguments //--------------------------------------------------------------------+ #define TU_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 // function expand with number of arguments #define TU_FUNC_OPTIONAL_ARG(func, ...) TU_XSTRCAT(func##_arg, TU_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__) //--------------------------------------------------------------------+ // Compiler Attribute Abstraction //--------------------------------------------------------------------+ #if defined(__GNUC__) || defined(__ICCARM__) || defined(__TI_COMPILER_VERSION__) #if defined(__ICCARM__) #include // for builtin functions #endif #define TU_ATTR_ALIGNED(Bytes) __attribute__((aligned(Bytes))) #define TU_ATTR_SECTION(sec_name) __attribute__((section(#sec_name))) #define TU_ATTR_PACKED __attribute__((packed)) #define TU_ATTR_WEAK __attribute__((weak)) // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f))) #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug #define TU_ATTR_ALWAYS_INLINE __attribute__((always_inline)) #endif #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END #define TU_ATTR_BIT_FIELD_ORDER_BEGIN #define TU_ATTR_BIT_FIELD_ORDER_END #if (defined(__has_attribute) && __has_attribute(__fallthrough__)) || defined(__TI_COMPILER_VERSION__) #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough)) #else #define TU_ATTR_FALLTHROUGH \ do { \ } while (0) /* fallthrough */ #endif // Endian conversion use well-known host to network (big endian) naming // For TI ARM compiler, __BYTE_ORDER__ is not defined for MSP430 but still LE #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__MSP430__) #define TU_BYTE_ORDER TU_LITTLE_ENDIAN #else #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif // Unfortunately XC16 doesn't provide builtins for 32bit endian conversion #if defined(__XC16) #define TU_BSWAP16(u16) (__builtin_swap(u16)) #define TU_BSWAP32(u32) ((((u32) & 0xff000000) >> 24) | \ (((u32) & 0x00ff0000) >> 8) | \ (((u32) & 0x0000ff00) << 8) | \ (((u32) & 0x000000ff) << 24)) #else #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) #endif // List of obsolete callback function that is renamed and should not be defined. // Put it here since only gcc support this pragma #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) #pragma GCC poison tud_vendor_control_request_cb #endif #elif defined(__ICCARM__) #include #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) #define TU_ATTR_PACKED __attribute__ ((packed)) #define TU_ATTR_WEAK __attribute__ ((weak)) // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f))) #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) #endif #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */ #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END #define TU_ATTR_BIT_FIELD_ORDER_BEGIN #define TU_ATTR_BIT_FIELD_ORDER_END // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define TU_BYTE_ORDER TU_LITTLE_ENDIAN #else #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif #define TU_BSWAP16(u16) (__iar_builtin_REV16(u16)) #define TU_BSWAP32(u32) (__iar_builtin_REV(u32)) #elif defined(__CCRX__) #define TU_ATTR_ALIGNED(Bytes) #define TU_ATTR_SECTION(sec_name) #define TU_ATTR_PACKED #define TU_ATTR_WEAK // #define TU_ATTR_WEAK_ALIAS(f) #define TU_ATTR_ALWAYS_INLINE #define TU_ATTR_DEPRECATED(mess) #define TU_ATTR_UNUSED #define TU_ATTR_USED #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */ #define TU_ATTR_PACKED_BEGIN _Pragma("pack") #define TU_ATTR_PACKED_END _Pragma("packoption") #define TU_ATTR_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") #define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order") // Endian conversion use well-known host to network (big endian) naming #if defined(__LIT) #define TU_BYTE_ORDER TU_LITTLE_ENDIAN #else #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif #define TU_BSWAP16(u16) ((unsigned short)_builtin_revw((unsigned long)u16)) #define TU_BSWAP32(u32) (_builtin_revl(u32)) #else #error "Compiler attribute porting is required" #endif #if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) #define tu_htons(u16) (TU_BSWAP16(u16)) #define tu_ntohs(u16) (TU_BSWAP16(u16)) #define tu_htonl(u32) (TU_BSWAP32(u32)) #define tu_ntohl(u32) (TU_BSWAP32(u32)) #define tu_htole16(u16) (u16) #define tu_le16toh(u16) (u16) #define tu_htole32(u32) (u32) #define tu_le32toh(u32) (u32) #elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) #define tu_htons(u16) (u16) #define tu_ntohs(u16) (u16) #define tu_htonl(u32) (u32) #define tu_ntohl(u32) (u32) #define tu_htole16(u16) (TU_BSWAP16(u16)) #define tu_le16toh(u16) (TU_BSWAP16(u16)) #define tu_htole32(u32) (TU_BSWAP32(u32)) #define tu_le32toh(u32) (TU_BSWAP32(u32)) #else #error Byte order is undefined #endif ================================================ FILE: src/common/tusb_debug.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DEBUG_H_ #define TUSB_DEBUG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ // CFG_TUSB_DEBUG for debugging // 0 : no debug // 1 : print error // 2 : print warning // 3 : print info #if CFG_TUSB_DEBUG // Enum to String for debugging purposes #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL extern char const* const tu_str_speed[]; extern char const* const tu_str_std_request[]; extern char const* const tu_str_xfer_result[]; #endif void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); #ifdef CFG_TUSB_DEBUG_PRINTF extern int CFG_TUSB_DEBUG_PRINTF(const char *format, ...); #define tu_printf CFG_TUSB_DEBUG_PRINTF #else #include #define tu_printf(...) (void) printf(__VA_ARGS__) #endif TU_ATTR_ALWAYS_INLINE static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM #define TU_LOG2_BUF TU_LOG1_BUF #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX #endif // Log Level 3: Info #if CFG_TUSB_DEBUG >= 3 #define TU_LOG3 TU_LOG1 #define TU_LOG3_MEM TU_LOG1_MEM #define TU_LOG3_BUF TU_LOG1_BUF #define TU_LOG3_INT TU_LOG1_INT #define TU_LOG3_HEX TU_LOG1_HEX #endif typedef struct { uint32_t key; const char* data; } tu_lookup_entry_t; typedef struct { uint16_t count; tu_lookup_entry_t const* items; } tu_lookup_table_t; static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) { for(uint16_t i=0; icount; i++) { if (p_table->items[i].key == key) { return p_table->items[i].data; } } #ifndef CFG_TUSB_DEBUG_PRINTF // not found return the key value in hex if no custom printf is defined static char not_found[11]; if (snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long)key) <= 0) { not_found[0] = 0; } return not_found; #else return "NotFound"; #endif } #endif // CFG_TUSB_DEBUG #ifndef TU_LOG #define TU_LOG(n, ...) #define TU_LOG_MEM(n, ...) #define TU_LOG_BUF(n, ...) #define TU_LOG_INT(n, ...) #define TU_LOG_HEX(n, ...) #define TU_LOG_LOCATION() #define TU_LOG_FAILED() #endif #define TU_LOG0(...) #define TU_LOG0_MEM(...) #define TU_LOG0_BUF(...) #define TU_LOG0_INT(...) #define TU_LOG0_HEX(...) #ifndef TU_LOG1 #define TU_LOG1(...) #define TU_LOG1_MEM(...) #define TU_LOG1_BUF(...) #define TU_LOG1_INT(...) #define TU_LOG1_HEX(...) #endif #ifndef TU_LOG2 #define TU_LOG2(...) #define TU_LOG2_MEM(...) #define TU_LOG2_BUF(...) #define TU_LOG2_INT(...) #define TU_LOG2_HEX(...) #endif #ifndef TU_LOG3 #define TU_LOG3(...) #define TU_LOG3_MEM(...) #define TU_LOG3_BUF(...) #define TU_LOG3_INT(...) #define TU_LOG3_HEX(...) #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: src/common/tusb_fifo.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2020 Reinhard Panhuber - rework to unmasked pointers * * 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. * * This file is part of the TinyUSB stack. */ #include "osal/osal.h" #include "tusb_fifo.h" #define TU_FIFO_DBG 0 #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline void ff_lock(osal_mutex_t mutex) { if (mutex != NULL) { osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); } } TU_ATTR_ALWAYS_INLINE static inline void ff_unlock(osal_mutex_t mutex) { if (mutex != NULL) { osal_mutex_unlock(mutex); } } #else #define ff_lock(_mutex) #define ff_unlock(_mutex) #endif //--------------------------------------------------------------------+ // Setup API //--------------------------------------------------------------------+ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable) { // Limit index space to 2*depth - this allows for a fast "modulo" calculation // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) if (depth > 0x8000) { return false; } ff_lock(f->mutex_wr); ff_lock(f->mutex_rd); f->buffer = (uint8_t *)buffer; f->depth = depth; f->overwritable = overwritable; f->rd_idx = 0u; f->wr_idx = 0u; ff_unlock(f->mutex_wr); ff_unlock(f->mutex_rd); return true; } // clear fifo by resetting read and write indices void tu_fifo_clear(tu_fifo_t *f) { ff_lock(f->mutex_wr); ff_lock(f->mutex_rd); f->rd_idx = 0; f->wr_idx = 0; ff_unlock(f->mutex_wr); ff_unlock(f->mutex_rd); } // Change the fifo overwritable mode void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { if (f->overwritable == overwritable) { return; } ff_lock(f->mutex_wr); ff_lock(f->mutex_rd); f->overwritable = overwritable; ff_unlock(f->mutex_wr); ff_unlock(f->mutex_rd); } //--------------------------------------------------------------------+ // Hardware FIFO API // Support different data access width and address increment scheme // Can support multiple i.e both 16 and 32-bit data access if needed //--------------------------------------------------------------------+ #if CFG_TUSB_FIFO_HWFIFO_API #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE > 0 #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) _hwfifo = (_const volatile void *)((uintptr_t)(_hwfifo) + _n) #else #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) #endif #define HWFIFO_ADDR_NEXT(_hwfifo, _const) HWFIFO_ADDR_NEXT_N(_hwfifo, _const, CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE) // the fixed ratio works since in the only case of dynamic/multiple data_stride (rusb2): addr_stride is 0 #define HWFIFO_ADDR_DATA_RATIO (CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE / CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE) //------------- Write -------------// #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE TU_ATTR_ALWAYS_INLINE static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) { (void)data_stride; // possible unused #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4 #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4 if (data_stride == 4) #endif { *((volatile uint32_t *)hwfifo) = tu_unaligned_read32(src); } #endif #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2 #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 2 if (data_stride == 2) #endif { *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src); } #endif #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 *((volatile uint8_t *)hwfifo) = *(const uint8_t *)src; #endif } // Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) { // Write full available 16/32 bit words to dest const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE; while (len >= data_stride) { stride_write(hwfifo, src, data_stride); src += data_stride; len -= data_stride; HWFIFO_ADDR_NEXT(hwfifo, ); } #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE > 1 #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // 16-bit access is allowed for odd bytes if (len >= 2) { *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src); src += 2; len -= 2; HWFIFO_ADDR_NEXT_N(hwfifo, , 2); } #endif #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // 8-bit access is allowed for odd bytes while (len > 0) { *((volatile uint8_t *)hwfifo) = *src++; len--; HWFIFO_ADDR_NEXT_N(hwfifo, , 1); } #else // Write odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit if (len > 0) { uint32_t tmp = 0u; memcpy(&tmp, src, len); stride_write(hwfifo, &tmp, data_stride); HWFIFO_ADDR_NEXT(hwfifo, ); } #endif #endif } #endif //------------- Read -------------// #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ TU_ATTR_ALWAYS_INLINE static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_stride) { (void)data_stride; // possible unused #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4 #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4 if (data_stride == 4) #endif { tu_unaligned_write32(dest, *((const volatile uint32_t *)hwfifo)); } #endif #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2 #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 2 if (data_stride == 2) #endif { tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo)); } #endif #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 *(uint8_t *)dest = *((const volatile uint8_t *)hwfifo); #endif } void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) { // Reading full available 16/32-bit hwfifo and write to fifo const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE; while (len >= data_stride) { stride_read(hwfifo, dest, data_stride); dest += data_stride; len -= data_stride; HWFIFO_ADDR_NEXT(hwfifo, const); } #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE > 1 #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // 16-bit access is allowed for odd bytes if (len >= 2) { tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo)); dest += 2; len -= 2; HWFIFO_ADDR_NEXT_N(hwfifo, const, 2); } #endif #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // 8-bit access is allowed for odd bytes while (len > 0) { *dest++ = *((const volatile uint8_t *)hwfifo); len--; HWFIFO_ADDR_NEXT_N(hwfifo, const, 1); } #else // Read odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit if (len > 0) { uint32_t tmp; stride_read(hwfifo, &tmp, data_stride); memcpy(dest, &tmp, len); HWFIFO_ADDR_NEXT(hwfifo, const); } #endif #endif } #endif // push to sw fifo from hwfifo static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr, const tu_hwfifo_access_t *access_mode) { uint16_t lin_bytes = f->depth - wr_ptr; uint16_t wrap_bytes = n - lin_bytes; uint8_t *ff_buf = f->buffer + wr_ptr; const volatile void *hwfifo = (const volatile void *)app_buf; if (n <= lin_bytes) { // Linear only case tu_hwfifo_read(hwfifo, ff_buf, n, access_mode); } else { // Wrap around case #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 tu_hwfifo_read(hwfifo, ff_buf, lin_bytes, access_mode); // linear part HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_bytes); tu_hwfifo_read(hwfifo, f->buffer, wrap_bytes, access_mode); // wrapped part #else // Write full words to the linear part of the buffer const uint8_t data_stride = access_mode->data_stride; const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode); HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even * HWFIFO_ADDR_DATA_RATIO); ff_buf += lin_even; // There could be an odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary // combine it with the wrapped part to form a full word for data stride const uint8_t lin_odd = lin_bytes & odd_mask; if (lin_odd > 0) { const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd); uint8_t buf_temp[4]; tu_hwfifo_read(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode); HWFIFO_ADDR_NEXT(hwfifo, const); for (uint8_t i = 0; i < lin_odd; ++i) { ff_buf[i] = buf_temp[i]; } for (uint8_t i = 0; i < wrap_odd; ++i) { f->buffer[i] = buf_temp[lin_odd + i]; } wrap_bytes -= wrap_odd; ff_buf = f->buffer + wrap_odd; // wrap around } else { ff_buf = f->buffer; // wrap around to beginning } // Write data wrapped part if (wrap_bytes > 0) { tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, access_mode); } #endif } } // pull from sw fifo to hwfifo static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, const tu_hwfifo_access_t *access_mode) { uint16_t lin_bytes = f->depth - rd_ptr; uint16_t wrap_bytes = n - lin_bytes; // only used if wrapped const uint8_t *ff_buf = f->buffer + rd_ptr; volatile void *hwfifo = (volatile void *)app_buf; if (n <= lin_bytes) { // Linear only case tu_hwfifo_write(hwfifo, ff_buf, n, access_mode); } else { // Wrap around case #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE == 1 tu_hwfifo_write(hwfifo, ff_buf, lin_bytes, access_mode); // linear part HWFIFO_ADDR_NEXT_N(hwfifo, , lin_bytes); tu_hwfifo_write(hwfifo, f->buffer, wrap_bytes, access_mode); // wrapped part #else // Read full words from linear part const uint8_t data_stride = access_mode->data_stride; const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode); HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even * HWFIFO_ADDR_DATA_RATIO); ff_buf += lin_even; // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary const uint8_t lin_odd = lin_bytes & odd_mask; if (lin_odd > 0) { const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd); uint8_t buf_temp[4]; for (uint8_t i = 0; i < lin_odd; ++i) { buf_temp[i] = ff_buf[i]; } for (uint8_t i = 0; i < wrap_odd; ++i) { buf_temp[lin_odd + i] = f->buffer[i]; } tu_hwfifo_write(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode); HWFIFO_ADDR_NEXT(hwfifo, ); wrap_bytes -= wrap_odd; ff_buf = f->buffer + wrap_odd; // wrap around } else { ff_buf = f->buffer; // wrap around to beginning } // Read data wrapped part if (wrap_bytes > 0) { tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, access_mode); } #endif } } #endif //--------------------------------------------------------------------+ // Pull & Push // copy data to/from fifo without updating read/write pointers //--------------------------------------------------------------------+ // send n items to fifo WITHOUT updating write pointer static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr) { uint16_t lin_bytes = f->depth - wr_ptr; uint16_t wrap_bytes = n - lin_bytes; uint8_t *ff_buf = f->buffer + wr_ptr; if (n <= lin_bytes) { // Linear only case memcpy(ff_buf, app_buf, n); } else { // Wrap around case memcpy(ff_buf, app_buf, lin_bytes); // linear part memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part } } // get n items from fifo WITHOUT updating read pointer static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr) { uint16_t lin_bytes = f->depth - rd_ptr; uint16_t wrap_bytes = n - lin_bytes; // only used if wrapped const uint8_t *ff_buf = f->buffer + rd_ptr; // single byte access if (n <= lin_bytes) { // Linear only memcpy(app_buf, ff_buf, n); } else { // Wrap around memcpy(app_buf, ff_buf, lin_bytes); // linear part memcpy((uint8_t *)app_buf + lin_bytes, f->buffer, wrap_bytes); // wrapped part } } //--------------------------------------------------------------------+ // Index Helper //--------------------------------------------------------------------+ // Advance an absolute index // "absolute" index is only in the range of [0..2*depth) static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index uint16_t new_idx = (uint16_t)(idx + offset); if ((idx > new_idx) || (new_idx >= 2 * depth)) { const uint16_t non_used_index_space = (uint16_t)(UINT16_MAX - (2 * depth - 1)); new_idx = (uint16_t)(new_idx + non_used_index_space); } return new_idx; } // index to pointer (0..depth-1), simply a modulo with minus. TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t idx) { // Only run at most 3 times since index is limit in the range of [0..2*depth) while (idx >= depth) { idx -= depth; } return idx; } // Works on local copies of w // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; if (wr_idx >= f->depth) { rd_idx = wr_idx - f->depth; } else { rd_idx = wr_idx + f->depth; } f->rd_idx = rd_idx; return rd_idx; } //--------------------------------------------------------------------+ // n-API //--------------------------------------------------------------------+ // Works on local copies of w and r // Must be protected by read mutex since in case of an overflow read pointer gets modified uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, const tu_hwfifo_access_t *access_mode) { uint16_t count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); if (count == 0) { return 0; // nothing to peek } // Check overflow and correct if required if (count > f->depth) { rd_idx = correct_read_index(f, wr_idx); count = f->depth; } if (count < n) { n = count; // limit to available count } const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); #if CFG_TUSB_FIFO_HWFIFO_API if (access_mode != NULL) { hwff_pull_n(f, p_buffer, n, rd_ptr, access_mode); } else #endif { (void)access_mode; ff_pull_n(f, p_buffer, n, rd_ptr); } return n; } // Read n items without removing it from the FIFO, correct read pointer if overflowed uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) { ff_lock(f->mutex_rd); const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, wr_idx, rd_idx, NULL); ff_unlock(f->mutex_rd); return ret; } // Read n items from fifo with access mode uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode) { ff_lock(f->mutex_rd); // Peek the data: f->rd_idx might get modified in case of an overflow so we can not use a local variable const uint16_t wr_idx = f->wr_idx; n = tu_fifo_peek_n_access_mode(f, buffer, n, wr_idx, f->rd_idx, access_mode); f->rd_idx = advance_index(f->depth, f->rd_idx, n); ff_unlock(f->mutex_rd); return n; } // Write n items to fifo with access mode uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, const tu_hwfifo_access_t *access_mode) { if (n == 0) { return 0; } ff_lock(f->mutex_wr); uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; const uint8_t *buf8 = (const uint8_t *)data; TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", rd_idx, wr_idx, tu_ff_overflow_count(f->depth, wr_idx, rd_idx), tu_ff_remaining_local(f->depth, wr_idx, rd_idx), n); if (!f->overwritable) { // limit up to full const uint16_t remain = tu_ff_remaining_local(f->depth, wr_idx, rd_idx); n = tu_min16(n, remain); } else { // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case, // oldest data in fifo i.e. at read pointer data will be overwritten // Note: we can modify read buffer contents however we must not modify the read index itself within a write // function! Since it would end up in a race condition with read functions! if (n >= f->depth) { // Only copy last part if (access_mode == NULL) { buf8 += (n - f->depth); } else { // TODO should read from hw fifo to discard data, however reading an odd number could // accidentally discard data. } n = f->depth; // We start writing at the read pointer's position since we fill the whole buffer wr_idx = rd_idx; } else { const uint16_t overflowable_count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); if (overflowable_count + n >= 2 * f->depth) { // Double overflowed // Index is bigger than the allowed range [0,2*depth) // re-position write index to have a full fifo after pushed wr_idx = advance_index(f->depth, rd_idx, f->depth - n); // TODO we should also shift out n bytes from read index since we avoid changing rd index !! // However memmove() is expensive due to actual copying + wrapping consideration. // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory // currently deliberately not implemented --> result in incorrect data read back } else { // normal + single overflowed: // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() // Therefore we just increase write index // we will correct (re-position) read index later on in fifo_read() function } } } if (n) { const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); #if CFG_TUSB_FIFO_HWFIFO_API if (access_mode != NULL) { hwff_push_n(f, buf8, n, wr_ptr, access_mode); } else #endif { ff_push_n(f, buf8, n, wr_ptr); } f->wr_idx = advance_index(f->depth, wr_idx, n); TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx); } ff_unlock(f->mutex_wr); return n; } uint16_t tu_fifo_discard_n(tu_fifo_t *f, uint16_t n) { const uint16_t count = tu_min16(n, tu_fifo_count(f)); // limit to available count ff_lock(f->mutex_rd); f->rd_idx = advance_index(f->depth, f->rd_idx, count); ff_unlock(f->mutex_rd); return count; } //--------------------------------------------------------------------+ // One API //--------------------------------------------------------------------+ // peek() using local write/read index, correct read index if overflowed // Be careful, caller must not lock mutex, since this Will also try to lock mutex static bool ff_peek_local(tu_fifo_t *f, void *buf, uint16_t wr_idx, uint16_t rd_idx) { const uint16_t ovf_count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); if (ovf_count == 0) { return false; // nothing to peek } // Correct read index if overflow if (ovf_count > f->depth) { ff_lock(f->mutex_rd); rd_idx = correct_read_index(f, wr_idx); ff_unlock(f->mutex_rd); } const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); memcpy(buf, f->buffer + rd_ptr, 1); return true; } // Read one element out of the buffer, correct read index if overflowed bool tu_fifo_read(tu_fifo_t *f, void *buffer) { // Peek the data // f->rd_idx might get modified in case of an overflow so we can not use a local variable const uint16_t wr_idx = f->wr_idx; const bool ret = ff_peek_local(f, buffer, wr_idx, f->rd_idx); if (ret) { ff_lock(f->mutex_rd); f->rd_idx = advance_index(f->depth, f->rd_idx, 1); ff_unlock(f->mutex_rd); } return ret; } // Read one item without removing it from the FIFO, correct read index if overflowed bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) { const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; return ff_peek_local(f, p_buffer, wr_idx, rd_idx); } // Write one element into the buffer bool tu_fifo_write(tu_fifo_t *f, const void *data) { bool ret; ff_lock(f->mutex_wr); const uint16_t wr_idx = f->wr_idx; if (tu_fifo_full(f) && !f->overwritable) { ret = false; } else { const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); memcpy(f->buffer + wr_ptr, data, 1); f->wr_idx = advance_index(f->depth, wr_idx, 1); ret = true; } ff_unlock(f->mutex_wr); return ret; } //--------------------------------------------------------------------+ // Index API //--------------------------------------------------------------------+ /******************************************************************************/ /*! @brief Advance write pointer - intended to be used in combination with DMA. It is possible to fill the FIFO by use of a DMA in circular mode. Within DMA ISRs you may update the write pointer to be able to read from the FIFO. As long as the DMA is the only process writing into the FIFO this is safe to use. USE WITH CARE - WE DO NOT CONDUCT SAFETY CHECKS HERE! @param[in] f Pointer to the FIFO buffer to manipulate @param[in] n Number of items the write pointer moves forward */ /******************************************************************************/ void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) { f->wr_idx = advance_index(f->depth, f->wr_idx, n); } // Correct the read index in case tu_fifo_overflow() returned true! void tu_fifo_correct_read_pointer(tu_fifo_t *f) { ff_lock(f->mutex_rd); correct_read_index(f, f->wr_idx); ff_unlock(f->mutex_rd); } /******************************************************************************/ /*! @brief Advance read pointer - intended to be used in combination with DMA. It is possible to read from the FIFO by use of a DMA in linear mode. Within DMA ISRs you may update the read pointer to be able to again write into the FIFO. As long as the DMA is the only process reading from the FIFO this is safe to use. USE WITH CARE - WE DO NOT CONDUCT SAFETY CHECKS HERE! @param[in] f Pointer to the FIFO buffer to manipulate @param[in] n Number of items the read pointer moves forward */ /******************************************************************************/ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) { f->rd_idx = advance_index(f->depth, f->rd_idx, n); } /******************************************************************************/ /*! @brief Get read info Returns the length and pointer from which bytes can be read in a linear manner. This is of major interest for DMA transmissions. If returned length is zero the corresponding pointer is invalid. The read pointer does NOT get advanced, use tu_fifo_advance_read_pointer() to do so! @param[in] f Pointer to FIFO @param[out] *info Pointer to struct which holds the desired infos */ /******************************************************************************/ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Operate on temporary values in case they change in between uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; uint16_t cnt = tu_ff_overflow_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) { ff_lock(f->mutex_rd); rd_idx = correct_read_index(f, wr_idx); ff_unlock(f->mutex_rd); cnt = f->depth; } // Check if fifo is empty if (cnt == 0) { info->linear.len = 0; info->wrapped.len = 0; info->linear.ptr = NULL; info->wrapped.ptr = NULL; return; } // Get relative pointers uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start reading from info->linear.ptr = &f->buffer[rd_ptr]; // Check if there is a wrap around necessary if (wr_ptr > rd_ptr) { // Non wrapping case info->linear.len = cnt; info->wrapped.len = 0; info->wrapped.ptr = NULL; } else { info->linear.len = f->depth - rd_ptr; // Also the case if FIFO was full info->wrapped.len = cnt - info->linear.len; info->wrapped.ptr = f->buffer; } } /******************************************************************************/ /*! @brief Get linear write info Returns the length and pointer to which bytes can be written into FIFO in a linear manner. This is of major interest for DMA transmissions not using circular mode. If a returned length is zero the corresponding pointer is invalid. The returned lengths summed up are the currently free space in the FIFO. The write pointer does NOT get advanced, use tu_fifo_advance_write_pointer() to do so! TAKE CARE TO NOT OVERFLOW THE BUFFER MORE THAN TWO TIMES THE FIFO DEPTH - IT CAN NOT RECOVERE OTHERWISE! @param[in] f Pointer to FIFO @param[out] *info Pointer to struct which holds the desired infos */ /******************************************************************************/ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; uint16_t remain = tu_ff_remaining_local(f->depth, wr_idx, rd_idx); if (remain == 0) { info->linear.len = 0; info->wrapped.len = 0; info->linear.ptr = NULL; info->wrapped.ptr = NULL; return; } // Get relative pointers uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start writing to info->linear.ptr = &f->buffer[wr_ptr]; if (wr_ptr < rd_ptr) { // Non wrapping case info->linear.len = rd_ptr - wr_ptr; info->wrapped.len = 0; info->wrapped.ptr = NULL; } else { info->linear.len = f->depth - wr_ptr; info->wrapped.len = remain - info->linear.len; // Remaining length - n already was limited to remain or FIFO depth info->wrapped.ptr = f->buffer; // Always start of buffer } } ================================================ FILE: src/common/tusb_fifo.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2020 Reinhard Panhuber - rework to unmasked pointers * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_FIFO_H_ #define TUSB_FIFO_H_ #ifdef __cplusplus extern "C" { #endif #include "common/tusb_common.h" #include "osal/osal.h" //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ // mutex is only needed for RTOS. For OS None, we don't get preempted #define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED #define CFG_TUSB_FIFO_HWFIFO_API (CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO) #ifndef CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 0 #endif #ifndef CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 #endif // Due to the use of unmasked pointers, this FIFO does not suffer from losing // one item slice. Furthermore, write and read operations are completely // decoupled as write and read functions do not modify a common state. Henceforth, // writing or reading from the FIFO within an ISR is safe as long as no other // process (thread or ISR) interferes. // Also, this FIFO is ready to be used in combination with a DMA as the write and // read pointers can be updated from within a DMA ISR. Overflows are detectable // within a certain number (see tu_fifo_overflow()). /* Write/Read "pointer" is in the range of: 0 .. depth - 1, and is used to get the fifo data. * Write/Read "index" is always in the range of: 0 .. 2*depth-1 * * The extra window allow us to determine the fifo state of empty or full with only 2 indices * Following are examples with depth = 3 * * - empty: W = R * | * ------------------------- * | 0 | RW| 2 | 3 | 4 | 5 | * * - full 1: W > R * | * ------------------------- * | 0 | R | 2 | 3 | W | 5 | * * - full 2: W < R * | * ------------------------- * | 0 | 1 | W | 3 | 4 | R | * * - Number of items in the fifo can be determined in either cases: * - case W >= R: Count = W - R * - case W < R: Count = 2*depth - (R - W) * * In non-overwritable mode, computed Count (in above 2 cases) is at most equal to depth. * However, in over-writable mode, write index can be repeatedly increased and count can be * temporarily larger than depth (overflowed condition) e.g * * - Overflowed 1: write(3), write(1) * In this case we will adjust Read index when read()/peek() is called so that count = depth. * | * ------------------------- * | R | 1 | 2 | 3 | W | 5 | * * - Double Overflowed i.e index is out of allowed range [0,2*depth) * This occurs when we continue to write after 1st overflowed to 2nd overflowed. e.g: * write(3), write(1), write(2) * This must be prevented since it will cause unrecoverable state, in above example * if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify * read index in write() function, which cause race condition. We will re-position write index so that * after data is written it is a full fifo i.e W = depth - R * * re-position W = 1 before write(2) * Note: we should also move data from mem[3] to read index as well, but deliberately skipped here * since it is an expensive operation !!! * | * ------------------------- * | R | W | 2 | 3 | 4 | 5 | * * perform write(2), result is still a full fifo. * * | * ------------------------- * | R | 1 | 2 | W | 4 | 5 | */ typedef struct { uint8_t *buffer; // buffer pointer uint16_t depth; // max items bool overwritable; // overwritable when full // 1 byte padding here volatile uint16_t wr_idx; // write index volatile uint16_t rd_idx; // read index #if OSAL_MUTEX_REQUIRED osal_mutex_t mutex_wr; osal_mutex_t mutex_rd; #endif } tu_fifo_t; typedef struct { struct { uint16_t len; // length uint8_t *ptr; // buffer pointer } linear, wrapped; } tu_fifo_buffer_info_t; // Access mode for hardware fifo read/write typedef struct { uint8_t data_stride; uintptr_t param; } tu_hwfifo_access_t; #define TU_FIFO_INIT(_buffer, _depth, _overwritable) \ { \ .buffer = _buffer, \ .depth = _depth, \ .overwritable = _overwritable, \ } #define TU_FIFO_DEF(_name, _depth, _overwritable) \ uint8_t _name##_buf[_depth]; \ tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _overwritable) // Moving data from tusb_fifo <-> USB hardware FIFOs e.g. STM32s need to use a special stride mode which reads/writes // data in 2/4 byte chunks from/to a fixed address (USB FIFO register) instead of incrementing the address. For this use // read/write access_mode with stride_mode = true. The STRIDE DATA and ADDR stride must be configured with // CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE and CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE //--------------------------------------------------------------------+ // Setup API //--------------------------------------------------------------------+ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable); void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); void tu_fifo_clear(tu_fifo_t *f); #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) { f->mutex_wr = wr_mutex; f->mutex_rd = rd_mutex; } #else #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) #endif //--------------------------------------------------------------------+ // Index API //--------------------------------------------------------------------+ void tu_fifo_correct_read_pointer(tu_fifo_t *f); // Pointer modifications intended to be used in combinations with DMAs. // USE WITH CARE - NO SAFETY CHECKS CONDUCTED HERE! NOT MUTEX PROTECTED! void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n); void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n); // If you want to read/write from/to the FIFO by use of a DMA, you may need to conduct two copies // to handle a possible wrapping part. These functions deliver a pointer to start // reading/writing from/to and a valid linear length along which no wrap occurs. void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); //--------------------------------------------------------------------+ // Peek API // peek() will correct/re-index read pointer in case of an overflowed fifo to form a full fifo //--------------------------------------------------------------------+ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, const tu_hwfifo_access_t *access_mode); bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer); uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n); //--------------------------------------------------------------------+ // Read API // peek() + advance read index //--------------------------------------------------------------------+ uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode); bool tu_fifo_read(tu_fifo_t *f, void *buffer); TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n) { return tu_fifo_read_n_access_mode(f, buffer, n, NULL); } // discard first n items from fifo i.e advance read pointer by n with mutex // return number of discarded items uint16_t tu_fifo_discard_n(tu_fifo_t *f, uint16_t n); //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, const tu_hwfifo_access_t *access_mode); bool tu_fifo_write(tu_fifo_t *f, const void *data); TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n) { return tu_fifo_write_n_access_mode(f, data, n, NULL); } //--------------------------------------------------------------------+ // Hardware FIFO API // Special hardware FIFO/Buffer to hold USB data, usually requires certain access method these can be configured with // CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (data width) and CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE (address increment) // Note: these usually has opposite direction (read/write) to/from our software FIFO (tu_fifo_t) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_write_from_fifo(volatile void *hwfifo, tu_fifo_t *f, uint16_t n, const tu_hwfifo_access_t *access_mode) { const tu_hwfifo_access_t default_access = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE, .param = 0}; return tu_fifo_read_n_access_mode(f, (void *)(uintptr_t)hwfifo, n, (access_mode != NULL) ? access_mode : &default_access); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_read_to_fifo(const volatile void *hwfifo, tu_fifo_t *f, uint16_t n, const tu_hwfifo_access_t *access_mode) { const tu_hwfifo_access_t default_access = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE, .param = 0}; return tu_fifo_write_n_access_mode(f, (const void *)(uintptr_t)hwfifo, n, (access_mode != NULL) ? access_mode : &default_access); } #if CFG_TUSB_FIFO_HWFIFO_API // read from hwfifo to buffer void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode); // write to hwfifo from buffer with access mode void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode); #endif //--------------------------------------------------------------------+ // Internal Helper Local // work on local copies of read/write indices in order to only access them once for re-entrancy //--------------------------------------------------------------------+ // return overflowable count (index difference), which can be used to determine both fifo count and an overflow state TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_ff_overflow_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { const int32_t diff = (int32_t)wr_idx - (int32_t)rd_idx; if (diff >= 0) { return (uint16_t)diff; } else { return (uint16_t)(2 * depth + diff); } } // return remaining slot in fifo TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_ff_remaining_local(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { const uint16_t ovf_count = tu_ff_overflow_count(depth, wr_idx, rd_idx); return (depth > ovf_count) ? (depth - ovf_count) : 0; } //--------------------------------------------------------------------+ // State API // Following functions are reentrant since they only access read/write indices once, therefore can be used in thread and // ISRs context without the need of mutexes //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_depth(const tu_fifo_t *f) { return f->depth; } TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) { const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; return wr_idx == rd_idx; } // return number of items in fifo, capped to fifo's depth TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_count(const tu_fifo_t *f) { const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; return tu_min16(tu_ff_overflow_count(f->depth, wr_idx, rd_idx), f->depth); } // check if fifo is full TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_full(const tu_fifo_t *f) { const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; return tu_ff_overflow_count(f->depth, wr_idx, rd_idx) >= f->depth; } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_remaining(const tu_fifo_t *f) { const uint16_t wr_idx = f->wr_idx; const uint16_t rd_idx = f->rd_idx; return tu_ff_remaining_local(f->depth, wr_idx, rd_idx); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/common/tusb_mcu.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #pragma once //--------------------------------------------------------------------+ // Port/Platform Specific // TUP stand for TinyUSB Port/Platform (can be renamed) //--------------------------------------------------------------------+ //------------- Unaligned Memory Access -------------// #ifdef __ARM_ARCH // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1 #define TUP_ARCH_STRICT_ALIGN 0 #else #define TUP_ARCH_STRICT_ALIGN 1 #endif #else // TODO default to strict align for others // Should investigate other architecture such as risv, xtensa, mips for optimal setting #define TUP_ARCH_STRICT_ALIGN 1 #endif /* USB Controller Attributes for Device, Host or MCU (both) * - ENDPOINT_MAX: max (logical) number of endpoint * - ENDPOINT_EXCLUSIVE_NUMBER: endpoint number with different direction IN and OUT aren't allowed, * e.g EP1 OUT & EP1 IN cannot exist together * - RHPORT_HIGHSPEED: support highspeed with on-chip PHY */ //--------------------------------------------------------------------+ // NXP //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP #define TUP_OHCI_RHPORTS 2 #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC54) #include "fsl_device_registers.h" // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 #if !defined(LPC54114_cm4_SERIES) && !defined(LPC54114_cm0plus_SERIES) #define TUP_USBIP_IP3516 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP #define TUP_OHCI_RHPORTS 1 // 1 downstream port #endif #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55) // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 #define TUP_USBIP_IP3516 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP #define TUP_OHCI_RHPORTS 1 // 1 downstream port #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // USB0 has 6 with HS PHY, USB1 has 4 only FS #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 6 #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_MCXN9) // USB0 is chipidea FS #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_MCX // USB1 is chipidea HS #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_MCXA15) // USB0 is chipidea FS #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_MCX #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_RW61X) // USB0 is chipidea HS #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX) #include "fsl_device_registers.h" #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 #if __CORTEX_M == 7 #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT 1 #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT 1 #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #endif #elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_MM32F327X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // Nordic //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // 8 CBI + 1 ISO #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_DCD_EDPT_CLOSE_API #elif TU_CHECK_MCU(OPT_MCU_NRF54) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_NRF #define TUP_DCD_ENDPOINT_MAX 16 #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 //--------------------------------------------------------------------+ // Microchip //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML2X, OPT_MCU_SAMD21) || TU_CHECK_MCU(OPT_MCU_SAMD51, OPT_MCU_SAME5X) #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_SAMG) #define TUP_DCD_ENDPOINT_MAX 6 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define TUP_DCD_ENDPOINT_MAX 10 #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_SAMX7X_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) #define TUP_DCD_ENDPOINT_MAX 8 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) #define TUP_DCD_ENDPOINT_MAX 16 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // ST //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_STM32C0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #elif TU_CHECK_MCU(OPT_MCU_STM32F1) // - F102, F103 use fsdev // - F105, F107 use dwc2 #if defined(STM32F105x8) || defined(STM32F105xB) || defined(STM32F105xC) || defined(STM32F107xB) || \ defined(STM32F107xC) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 #define TUP_DCD_ENDPOINT_MAX 4 #elif defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || \ defined(STM32F103xE) || defined(STM32F103xG) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 512u #else #error "Unsupported STM32F1 mcu" #endif #elif TU_CHECK_MCU(OPT_MCU_STM32F2) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 4 ep, HS has 5 ep #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #if defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \ defined(STM32F373xC) // xB, and xC: 512 #define CFG_TUSB_FSDEV_PMA_SIZE 512u #elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \ defined(STM32F303xD) || defined(STM32F303xE) // x6, x8, xD, and xE: 1024 + LPM Support #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #else #error "Unsupported STM32F3 mcu" #endif #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #elif TU_CHECK_MCU(OPT_MCU_STM32G0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32G4) // Device controller #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u // TypeC controller #define TUP_USBIP_TYPEC_STM32 #define TUP_TYPEC_RHPORTS_NUM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32H5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32H7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define TUP_DCD_ENDPOINT_MAX 9 #ifndef CORE_CM4 // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7RS, OPT_MCU_STM32N6) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 // MCU with on-chip HS Phy #define TUP_RHPORT_HIGHSPEED 1 // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #elif TU_CHECK_MCU(OPT_MCU_STM32L0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #elif TU_CHECK_MCU(OPT_MCU_STM32L1) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 512u #elif TU_CHECK_MCU(OPT_MCU_STM32L4) // - L4x2, L4x3 use fsdev // - L4x4, L4x6, L4x7, L4x9 use dwc2 #if defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \ defined(STM32L496xx) || defined(STM32L4A6xx) || defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || \ defined(STM32L4S7xx) || defined(STM32L4S9xx) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define TUP_DCD_ENDPOINT_MAX 6 #elif defined(STM32L412xx) || defined(STM32L422xx) || defined(STM32L432xx) || defined(STM32L433xx) || \ defined(STM32L442xx) || defined(STM32L443xx) || defined(STM32L452xx) || defined(STM32L462xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #else #error "Unsupported STM32L4 mcu" #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE (1024u) #elif TU_CHECK_MCU(OPT_MCU_STM32U0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #elif TU_CHECK_MCU(OPT_MCU_STM32U3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #elif TU_CHECK_MCU(OPT_MCU_STM32U5) // U535/545 use fsdev #if defined(STM32U535xx) || defined(STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u #else #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 #else #define TUP_DCD_ENDPOINT_MAX 6 #endif #endif #elif TU_CHECK_MCU(OPT_MCU_STM32WB) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define CFG_TUSB_FSDEV_PMA_SIZE 1024u #elif TU_CHECK_MCU(OPT_MCU_STM32WBA) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 //--------------------------------------------------------------------+ // Sony //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_CXD56) #define TUP_DCD_ENDPOINT_MAX 7 #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // TI //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #define TUP_USBIP_MUSB #define TUP_USBIP_MUSB_TI #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ // ValentyUSB (Litex) //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) #define TUP_DCD_ENDPOINT_MAX 16 //--------------------------------------------------------------------+ // Nuvoton //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_NUC120) #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_NUC505) #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 //--------------------------------------------------------------------+ // Espressif //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN // clang-format off #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ // clang-format on #if CFG_TUSB_MCU == OPT_MCU_ESP32S3 #define TUP_MCU_MULTIPLE_CORE 1 #endif #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 #define TUP_RHPORT_HIGHSPEED 1 // port0 FS, port1 HS #define TUP_DCD_ENDPOINT_MAX 16 // FS 7 ep, HS 16 ep // clang-format off #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ // clang-format on #define TUP_MCU_MULTIPLE_CORE 1 // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 64 #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C5, OPT_MCU_ESP32C6, \ OPT_MCU_ESP32C61, OPT_MCU_ESP32H2) #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" #endif #define TUP_DCD_ENDPOINT_MAX 0 // clang-format off #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ // clang-format on //--------------------------------------------------------------------+ // Dialog //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_DA1469X) #define TUP_DCD_ENDPOINT_MAX 4 #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // Raspberry Pi //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RP2040) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_MCU_MULTIPLE_CORE 1 #define TU_ATTR_FAST_FUNC __not_in_flash("tinyusb") //--------------------------------------------------------------------+ // Silabs //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 7 //--------------------------------------------------------------------+ // Renesas //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N, OPT_MCU_RAXXX) #define TUP_USBIP_RUSB2 #define TUP_DCD_ENDPOINT_MAX 10 //--------------------------------------------------------------------+ // GigaDevice //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 4 //--------------------------------------------------------------------+ // Broadcom //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 //--------------------------------------------------------------------+ // Infineon //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_XMC4000) #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ // BridgeTek //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_FT90X) #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_FT93X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // Allwinner //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define TUP_DCD_ENDPOINT_MAX 4 #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // WCH //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_USBIP_WCH_USBHS #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_USBHS) #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) #if CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_EDPT_CLOSE_API #endif #elif TU_CHECK_MCU(OPT_MCU_CH32V103) #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) #define CFG_TUD_WCH_USBIP_USBFS 1 #endif #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both port0 FSDEV (USBD) and port1 USBFS #define TUP_USBIP_WCH_USBFS #ifndef CFG_TUH_WCH_USBIP_USBFS #define CFG_TUH_WCH_USBIP_USBFS 1 #endif #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_CH32 #define CFG_TUSB_FSDEV_PMA_SIZE 512u // default to FSDEV for device #if !defined(CFG_TUD_WCH_USBIP_USBFS) #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_FSDEV) #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_CH32V307) // v307 support both FS and HS, default to HS #define TUP_USBIP_WCH_USBHS #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_USBHS) #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) #if CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_EDPT_CLOSE_API #endif //--------------------------------------------------------------------+ // Analog Devices //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) #define TUP_USBIP_MUSB #define TUP_USBIP_MUSB_ADI #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // ArteryTek //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_AT32F403A_407, OPT_MCU_AT32F413) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_AT32 #define CFG_TUSB_FSDEV_PMA_SIZE 512u #elif TU_CHECK_MCU(OPT_MCU_AT32F415) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 4 #elif TU_CHECK_MCU(OPT_MCU_AT32F402_405, OPT_MCU_AT32F423, OPT_MCU_AT32F425, OPT_MCU_AT32F435_437, OPT_MCU_AT32F45X) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 8 // AT32F405xx has on-chip HS PHY #if defined(AT32F405CBT7) || defined(AT32F405CBU7) || defined(AT32F405CCT7) || defined(AT32F405CCU7) || \ defined(AT32F405KBU7_4) || defined(AT32F405KCU7_4) || defined(AT32F405RBT7_7) || defined(AT32F405RBT7) || \ defined(AT32F405RCT7_7) || defined(AT32F405RCT7) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif //--------------------------------------------------------------------+ // HPMicro //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_HPM) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 #define TU_ATTR_FAST_FUNC __attribute__((section(".fast"))) #endif // External USB controller #if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 #ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4 * (CFG_TUH_DEVICE_MAX - 1)) #endif #endif //--------------------------------------------------------------------+ // Default Values //--------------------------------------------------------------------+ #if defined(TUP_USBIP_FSDEV) #define TUP_DCD_ENDPOINT_MAX 8 #endif #ifndef TUP_MCU_MULTIPLE_CORE #define TUP_MCU_MULTIPLE_CORE 0 #endif #if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif // Default to fullspeed if not defined #ifndef TUP_RHPORT_HIGHSPEED #define TUP_RHPORT_HIGHSPEED 0 #endif // fast function, normally mean placing function in SRAM #ifndef TU_ATTR_FAST_FUNC #define TU_ATTR_FAST_FUNC #endif #if defined(TUP_USBIP_IP3511) || defined(TUP_USBIP_RUSB2) #define TUP_DCD_EDPT_CLOSE_API #endif // USBIP implement dcd_edpt_close() and does not support ISO alloc & activate API #ifndef TUP_DCD_EDPT_CLOSE_API #define TUP_DCD_EDPT_ISO_ALLOC #endif ================================================ FILE: src/common/tusb_private.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_PRIVATE_H #define TUSB_PRIVATE_H // Internal Helper used by Host and Device Stack #ifdef __cplusplus extern "C" { #endif typedef void (*tusb_defer_func_t)(uintptr_t param); //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ #define TUP_USBIP_CONTROLLER_NUM 2 extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM]; //--------------------------------------------------------------------+ // Endpoint //--------------------------------------------------------------------+ enum { TU_EDPT_STATE_BUSY = 0x01, TU_EDPT_STATE_STALLED = 0x02, TU_EDPT_STATE_CLAIMED = 0x04, }; typedef struct TU_ATTR_PACKED { volatile uint8_t busy : 1; volatile uint8_t stalled : 1; volatile uint8_t claimed : 1; } tu_edpt_state_t; typedef struct { uint8_t hwid; // device: rhport, host: daddr bool is_host; // 1: host, 0: device uint8_t ep_addr; // 1 byte padding uint16_t mps; uint16_t xfer_len; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; // mutex: read if rx, otherwise write OSAL_MUTEX_DEF(ff_mutexdef); }tu_edpt_stream_t; //--------------------------------------------------------------------+ // Endpoint //--------------------------------------------------------------------+ // Check if endpoint descriptor is valid per USB specs if debug is enabled #if CFG_TUSB_DEBUG bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed); #else TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { (void)speed; return tu_edpt_packet_size(desc_ep) > 0; } #endif // Bind drivers to all interfaces and endpoints in the provided configuration descriptor bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max, const uint8_t *p_desc, uint16_t desc_len); // Claim an endpoint with provided mutex bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Release an endpoint with provided mutex bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); //--------------------------------------------------------------------+ // Endpoint Stream //--------------------------------------------------------------------+ // Init an endpoint stream bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, uint16_t ff_bufsize, uint8_t *ep_buf); // Deinit an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { (void)s; #if OSAL_MUTEX_REQUIRED if (s->ff.mutex_wr) { osal_mutex_delete(s->ff.mutex_wr); } if (s->ff.mutex_rd) { osal_mutex_delete(s->ff.mutex_rd); } #endif } // Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid, const tusb_desc_endpoint_t *desc_ep, uint16_t xfer_len) { s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->mps = tu_edpt_packet_size(desc_ep); s->xfer_len = xfer_len; } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) { return s->ep_addr != 0; } TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) { s->ep_addr = 0; } TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_clear(tu_edpt_stream_t *s) { tu_fifo_clear(&s->ff); } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) { return tu_fifo_empty(&s->ff); } //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ // Write to stream uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy. Return number of queued bytes uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s); // Start an zero-length packet if needed bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes); // Get the number of bytes available for writing to FIFO // Note: if no fifo, return endpoint size if not busy, 0 otherwise uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s); //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ // Read from stream uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s); // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { if (s->ep_buf != NULL) { tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t)xferred_bytes); } } // Complete read transfer with provided buffer TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t *s, const void *buf, uint32_t xferred_bytes) { tu_fifo_write_n(&s->ff, buf, (uint16_t)xferred_bytes); } // Get the number of bytes available for reading TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_read_available(const tu_edpt_stream_t *s) { return (uint32_t) tu_fifo_count(&s->ff); } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_peek(tu_edpt_stream_t *s, uint8_t *ch) { return tu_fifo_peek(&s->ff, ch); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/common/tusb_types.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_TYPES_H_ #define TUSB_TYPES_H_ #include #include #include "tusb_compiler.h" #ifdef __cplusplus extern "C" { #endif //------------- Device DCache declaration -------------// #define TUD_EPBUF_DCACHE_SIZE(_size) (CFG_TUD_MEM_DCACHE_ENABLE ? \ (TU_DIV_CEIL(_size, CFG_TUD_MEM_DCACHE_LINE_SIZE) * CFG_TUD_MEM_DCACHE_LINE_SIZE) : (_size)) // Declare an endpoint buffer with uint8_t[size] #define TUD_EPBUF_DEF(_name, _size) \ union { \ CFG_TUD_MEM_ALIGN uint8_t _name[_size]; \ TU_ATTR_ALIGNED(CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1) uint8_t _name##_dcache_padding[TUD_EPBUF_DCACHE_SIZE(_size)]; \ } // Declare an endpoint buffer with a type #define TUD_EPBUF_TYPE_DEF(_type, _name) \ union { \ CFG_TUD_MEM_ALIGN _type _name; \ TU_ATTR_ALIGNED(CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1) uint8_t _name##_dcache_padding[TUD_EPBUF_DCACHE_SIZE(sizeof(_type))]; \ } //------------- Host DCache declaration -------------// #define TUH_EPBUF_DCACHE_SIZE(_size) (CFG_TUH_MEM_DCACHE_ENABLE ? \ (TU_DIV_CEIL(_size, CFG_TUH_MEM_DCACHE_LINE_SIZE) * CFG_TUH_MEM_DCACHE_LINE_SIZE) : (_size)) // Declare an endpoint buffer with uint8_t[size] #define TUH_EPBUF_DEF(_name, _size) \ union { \ CFG_TUH_MEM_ALIGN uint8_t _name[_size]; \ TU_ATTR_ALIGNED(CFG_TUH_MEM_DCACHE_ENABLE ? CFG_TUH_MEM_DCACHE_LINE_SIZE : 1) uint8_t _name##_dcache_padding[TUH_EPBUF_DCACHE_SIZE(_size)]; \ } // Declare an endpoint buffer with a type #define TUH_EPBUF_TYPE_DEF(_type, _name) \ union { \ CFG_TUH_MEM_ALIGN _type _name; \ TU_ATTR_ALIGNED(CFG_TUH_MEM_DCACHE_ENABLE ? CFG_TUH_MEM_DCACHE_LINE_SIZE : 1) uint8_t _name##_dcache_padding[TUH_EPBUF_DCACHE_SIZE(sizeof(_type))]; \ } /*------------------------------------------------------------------*/ /* CONSTANTS *------------------------------------------------------------------*/ typedef enum { TUSB_ROLE_INVALID = 0u, TUSB_ROLE_DEVICE = 0x1, TUSB_ROLE_HOST = 0x2, } tusb_role_t; /// defined base on EHCI specs value for Endpoint Speed typedef enum { TUSB_SPEED_FULL = 0, TUSB_SPEED_LOW = 1, TUSB_SPEED_HIGH = 2, TUSB_SPEED_AUTO = 0xaa, TUSB_SPEED_INVALID = 0xff, } tusb_speed_t; /// defined base on USB Specs Endpoint's bmAttributes typedef enum { TUSB_XFER_CONTROL = 0, TUSB_XFER_ISOCHRONOUS = 1, TUSB_XFER_BULK = 2, TUSB_XFER_INTERRUPT = 3 } tusb_xfer_type_t; typedef enum { TUSB_DIR_OUT = 0, TUSB_DIR_IN = 1, TUSB_EPNUM_MASK = 0x0F, TUSB_DIR_IN_MASK = 0x80 } tusb_dir_t; enum { TUSB_EPSIZE_BULK_FS = 64, TUSB_EPSIZE_BULK_HS = 512, TUSB_EPSIZE_ISO_FS_MAX = 1023, TUSB_EPSIZE_ISO_HS_MAX = 1024, }; // Endpoint Bulk size depending on host/device max speed #define TUD_EPSIZE_BULK_MAX (TUD_OPT_HIGH_SPEED ? 512 : 64) #define TUH_EPSIZE_BULK_MAX (TUH_OPT_HIGH_SPEED ? 512 : 64) /// Isochronous Endpoint Attributes typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback } tusb_iso_ep_attribute_t; /// USB Descriptor Types typedef enum { TUSB_DESC_DEVICE = 0x01, TUSB_DESC_CONFIGURATION = 0x02, TUSB_DESC_STRING = 0x03, TUSB_DESC_INTERFACE = 0x04, TUSB_DESC_ENDPOINT = 0x05, TUSB_DESC_DEVICE_QUALIFIER = 0x06, TUSB_DESC_OTHER_SPEED_CONFIG = 0x07, TUSB_DESC_INTERFACE_POWER = 0x08, TUSB_DESC_OTG = 0x09, TUSB_DESC_DEBUG = 0x0A, TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B, TUSB_DESC_BOS = 0x0F, TUSB_DESC_DEVICE_CAPABILITY = 0x10, TUSB_DESC_FUNCTIONAL = 0x21, // Class Specific Descriptor TUSB_DESC_CS_DEVICE = 0x21, TUSB_DESC_CS_CONFIGURATION = 0x22, TUSB_DESC_CS_STRING = 0x23, TUSB_DESC_CS_INTERFACE = 0x24, TUSB_DESC_CS_ENDPOINT = 0x25, TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 } tusb_desc_type_t; typedef enum { TUSB_REQ_GET_STATUS = 0 , TUSB_REQ_CLEAR_FEATURE = 1 , TUSB_REQ_RESERVED = 2 , TUSB_REQ_SET_FEATURE = 3 , TUSB_REQ_RESERVED2 = 4 , TUSB_REQ_SET_ADDRESS = 5 , TUSB_REQ_GET_DESCRIPTOR = 6 , TUSB_REQ_SET_DESCRIPTOR = 7 , TUSB_REQ_GET_CONFIGURATION = 8 , TUSB_REQ_SET_CONFIGURATION = 9 , TUSB_REQ_GET_INTERFACE = 10 , TUSB_REQ_SET_INTERFACE = 11 , TUSB_REQ_SYNCH_FRAME = 12 } tusb_request_code_t; typedef enum { TUSB_REQ_FEATURE_EDPT_HALT = 0, TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, TUSB_REQ_FEATURE_TEST_MODE = 2 } tusb_request_feature_selector_t; typedef enum { TUSB_REQ_TYPE_STANDARD = 0u, TUSB_REQ_TYPE_CLASS, TUSB_REQ_TYPE_VENDOR, TUSB_REQ_TYPE_INVALID } tusb_request_type_t; typedef enum { TUSB_REQ_RCPT_DEVICE =0, TUSB_REQ_RCPT_INTERFACE, TUSB_REQ_RCPT_ENDPOINT, TUSB_REQ_RCPT_OTHER } tusb_request_recipient_t; // https://www.usb.org/defined-class-codes typedef enum { TUSB_CLASS_UNSPECIFIED = 0 , TUSB_CLASS_AUDIO = 1 , TUSB_CLASS_CDC = 2 , TUSB_CLASS_HID = 3 , TUSB_CLASS_RESERVED_4 = 4 , TUSB_CLASS_PHYSICAL = 5 , TUSB_CLASS_IMAGE = 6 , TUSB_CLASS_PRINTER = 7 , TUSB_CLASS_MSC = 8 , TUSB_CLASS_HUB = 9 , TUSB_CLASS_CDC_DATA = 10 , TUSB_CLASS_SMART_CARD = 11 , TUSB_CLASS_RESERVED_12 = 12 , TUSB_CLASS_CONTENT_SECURITY = 13 , TUSB_CLASS_VIDEO = 14 , TUSB_CLASS_PERSONAL_HEALTHCARE = 15 , TUSB_CLASS_AUDIO_VIDEO = 16 , TUSB_CLASS_DIAGNOSTIC = 0xDC , TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0 , TUSB_CLASS_MISC = 0xEF , TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE , TUSB_CLASS_VENDOR_SPECIFIC = 0xFF } tusb_class_code_t; typedef enum { MISC_SUBCLASS_COMMON = 2 }misc_subclass_type_t; typedef enum { MISC_PROTOCOL_IAD = 1 } misc_protocol_type_t; typedef enum { APP_SUBCLASS_USBTMC = 0x03, APP_SUBCLASS_DFU_RUNTIME = 0x01 } app_subclass_type_t; typedef enum { DEVICE_CAPABILITY_WIRELESS_USB = 0x01, DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, DEVICE_CAPABILITY_CONTAINER_id = 0x04, DEVICE_CAPABILITY_PLATFORM = 0x05, DEVICE_CAPABILITY_POWER_DELIVERY = 0x06, DEVICE_CAPABILITY_BATTERY_INFO = 0x07, DEVICE_CAPABILITY_PD_CONSUMER_PORT = 0x08, DEVICE_CAPABILITY_PD_PROVIDER_PORT = 0x09, DEVICE_CAPABILITY_SUPERSPEED_PLUS = 0x0A, DEVICE_CAPABILITY_PRECESION_TIME_MEASUREMENT = 0x0B, DEVICE_CAPABILITY_WIRELESS_USB_EXT = 0x0C, DEVICE_CAPABILITY_BILLBOARD = 0x0D, DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 } device_capability_type_t; enum { TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = 1 << 5, TUSB_DESC_CONFIG_ATT_SELF_POWERED = 1 << 6, }; #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) // USB 2.0 Spec Table 9-7: Test Mode Selectors typedef enum { TUSB_FEATURE_TEST_J = 1, TUSB_FEATURE_TEST_K = 2, TUSB_FEATURE_TEST_SE0_NAK = 3, TUSB_FEATURE_TEST_PACKET = 4, TUSB_FEATURE_TEST_FORCE_ENABLE = 5, } tusb_feature_test_mode_t; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef enum { XFER_RESULT_SUCCESS = 0, XFER_RESULT_FAILED, XFER_RESULT_STALLED, XFER_RESULT_TIMEOUT, XFER_RESULT_INVALID } xfer_result_t; #define tusb_xfer_result_t xfer_result_t // TODO remove enum { DESC_OFFSET_LEN = 0, DESC_OFFSET_TYPE = 1, DESC_OFFSET_SUBTYPE = 2 }; enum { INTERFACE_INVALID_NUMBER = 0xff }; typedef enum { MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, MS_OS_20_FEATURE_COMPATBLE_ID = 0x03, MS_OS_20_FEATURE_REG_PROPERTY = 0x04, MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05, MS_OS_20_FEATURE_MODEL_ID = 0x06, MS_OS_20_FEATURE_CCGP_DEVICE = 0x07, MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 } microsoft_os_20_type_t; enum { CONTROL_STAGE_IDLE = 0, CONTROL_STAGE_SETUP, // 1 CONTROL_STAGE_DATA, // 2 CONTROL_STAGE_ACK // 3 }; enum { TUSB_INDEX_INVALID_8 = 0xFF }; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef struct { tusb_role_t role; tusb_speed_t speed; } tusb_rhport_init_t; typedef struct { uint16_t len; uint8_t *buffer; } tusb_buffer_t; //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ // Start of all packed definitions for compiler without per-type packed TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN /// USB Device Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF). uint16_t idProduct ; ///< Product ID (assigned by the manufacturer). uint16_t bcdDevice ; ///< Device release number in binary-coded decimal. uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer. uint8_t iProduct ; ///< Index of string descriptor describing product. uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number. uint8_t bNumConfigurations ; ///< Number of possible configurations. } tusb_desc_device_t; TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18u, "size is not correct"); // USB Binary Device Object Store (BOS) Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this descriptor uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS } tusb_desc_bos_t; TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5u, "size is not correct"); /// USB Configuration Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. uint8_t bNumInterfaces ; ///< Number of interfaces supported by this configuration uint8_t bConfigurationValue ; ///< Value to use as an argument to the SetConfiguration() request to select this configuration. uint8_t iConfiguration ; ///< Index of string descriptor describing this configuration uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one. uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA). } tusb_desc_configuration_t; TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9u, "size is not correct"); /// USB Interface Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type uint8_t bInterfaceNumber ; ///< Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration. uint8_t bAlternateSetting ; ///< Value used to select this alternate setting for the interface identified in the prior field uint8_t bNumEndpoints ; ///< Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe. uint8_t bInterfaceClass ; ///< Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF. uint8_t bInterfaceSubClass ; ///< Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface. uint8_t iInterface ; ///< Index of string descriptor describing this interface } tusb_desc_interface_t; TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9u, "size is not correct"); /// USB Endpoint Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; // Size of this descriptor in bytes uint8_t bDescriptorType ; // ENDPOINT Descriptor Type uint8_t bEndpointAddress ; // The address of the endpoint struct TU_ATTR_PACKED { uint8_t xfer : 2; // Control, ISO, Bulk, Interrupt uint8_t sync : 2; // None, Asynchronous, Adaptive, Synchronous uint8_t usage : 2; // Data, Feedback, Implicit feedback uint8_t : 2; } bmAttributes; uint16_t wMaxPacketSize ; // Bit 10..0 : max packet size, bit 12..11 additional transaction per highspeed micro-frame uint8_t bInterval ; // Polling interval, in frames or microframes depending on the operating speed } tusb_desc_endpoint_t; TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7u, "size is not correct"); /// USB Other Speed Configuration Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint16_t wTotalLength ; ///< Total length of data returned uint8_t bNumInterfaces ; ///< Number of interfaces supported by this speed configuration uint8_t bConfigurationValue ; ///< Value to use to select configuration uint8_t iConfiguration ; ///< Index of string descriptor uint8_t bmAttributes ; ///< Same as Configuration descriptor uint8_t bMaxPower ; ///< Same as Configuration descriptor } tusb_desc_other_speed_t; /// USB Device Qualifier Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Device Qualifier Type uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00) uint8_t bDeviceClass ; ///< Class Code uint8_t bDeviceSubClass ; ///< SubClass Code uint8_t bDeviceProtocol ; ///< Protocol Code uint8_t bMaxPacketSize0 ; ///< Maximum packet size for other speed uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations uint8_t bReserved ; ///< Reserved for future use, must be zero } tusb_desc_device_qualifier_t; TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10u, "size is not correct"); /// USB Interface Association Descriptor (IAD ECN) typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint8_t bFirstInterface ; ///< Index of the first associated interface. uint8_t bInterfaceCount ; ///< Total number of associated interfaces. uint8_t bFunctionClass ; ///< Interface class ID. uint8_t bFunctionSubClass ; ///< Interface subclass ID. uint8_t bFunctionProtocol ; ///< Interface protocol ID. uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. } tusb_desc_interface_assoc_t; TU_VERIFY_STATIC( sizeof(tusb_desc_interface_assoc_t) == 8u, "size is not correct"); // USB String Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< Descriptor Type uint16_t utf16le[]; } tusb_desc_string_t; // USB Binary Device Object Store (BOS) typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType ; uint8_t bDevCapabilityType; uint8_t bReserved; uint8_t PlatformCapabilityUUID[16]; uint8_t CapabilityData[]; } tusb_desc_bos_platform_t; // USB WebUSB URL Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bScheme; char url[]; } tusb_desc_webusb_url_t; // DFU Functional Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; union { struct TU_ATTR_PACKED { uint8_t bitCanDnload : 1; uint8_t bitCanUpload : 1; uint8_t bitManifestationTolerant : 1; uint8_t bitWillDetach : 1; uint8_t reserved : 4; } bmAttributes; uint8_t bAttributes; }; uint16_t wDetachTimeOut; uint16_t wTransferSize; uint16_t bcdDFUVersion; } tusb_desc_dfu_functional_t; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. uint8_t type : 2; ///< Request type tusb_request_type_t. uint8_t direction : 1; ///< Direction type. tusb_dir_t } bmRequestType_bit; uint8_t bmRequestType; }; uint8_t bRequest; uint16_t wValue; uint16_t wIndex; uint16_t wLength; } tusb_control_request_t; TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8u, "size is not correct"); TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Endpoint helper //--------------------------------------------------------------------+ // Get direction from Endpoint address TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) { return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; } // Get Endpoint number from address TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { return (uint8_t) (addr & TUSB_EPNUM_MASK); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) { return (uint8_t) (num | (dir == (uint8_t)TUSB_DIR_IN ? (uint8_t)TUSB_DIR_IN_MASK : 0u)); } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { return tu_le16toh(desc_ep->wMaxPacketSize) & 0x7FF; } #if CFG_TUSB_DEBUG TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; } #endif #ifdef __cplusplus } #endif #endif // TUSB_TYPES_H_ ================================================ FILE: src/common/tusb_verify.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_VERIFY_H_ #define TUSB_VERIFY_H_ #include #include #include "tusb_option.h" #include "tusb_compiler.h" /*------------------------------------------------------------------*/ /* This file use an advanced macro technique to mimic the default parameter * as C++ for the sake of code simplicity. Beware of a headache macro * manipulation that you are told to stay away. * * This contains macros for both VERIFY and ASSERT: * * VERIFY: Used when there is an error condition which is not the * fault of the MCU. For example, bounds checking on data * sent to the micro over USB should use this function. * Another example is checking for buffer overflows, where * returning from the active function causes a NAK. * * ASSERT: Used for error conditions that are caused by MCU firmware * bugs. This is used to discover bugs in the code more * quickly. One example would be adding assertions in library * function calls to confirm a function's (untainted) * parameters are valid. * * The difference in behavior is that ASSERT triggers a breakpoint while * verify does not. * * #define TU_VERIFY(cond) if (!cond) return false; * #define TU_VERIFY(cond,ret) if (!cond) return ret; * * #define TU_ASSERT(cond) if (!cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if (!cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return ret;} *------------------------------------------------------------------*/ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TU_VERIFY Helper //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG #define TU_MESS_FAILED() TU_LOG1("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) #else #define TU_MESS_FAILED() do {} while (0) #endif // Custom defined application function #ifdef CFG_TUSB_DEBUG_BREAKPOINT extern void CFG_TUSB_DEBUG_BREAKPOINT(void); #define TU_BREAKPOINT() CFG_TUSB_DEBUG_BREAKPOINT() // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 #elif defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) #define TU_BREAKPOINT() do { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if (0u != ((*ARM_CM_DHCSR) & 1UL)) { __asm("BKPT #0\n"); } /* Only halt mcu if debugger is attached */ \ } while(0) #elif defined(__riscv) && !defined(ESP_PLATFORM) #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) #elif defined(_mips) #define TU_BREAKPOINT() do { __asm("sdbbp 0"); } while (0) #else #define TU_BREAKPOINT() do {} while (0) #endif /*------------------------------------------------------------------*/ /* TU_VERIFY * - TU_VERIFY_1ARGS : return false if failed * - TU_VERIFY_2ARGS : return provided value if failed *------------------------------------------------------------------*/ #define TU_VERIFY_DEFINE(_cond, _ret) \ do { \ if (!(_cond)) { \ return _ret; \ } \ } while (0) #define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false) #define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret) #define TU_VERIFY(...) TU_GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, _dummy)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT * basically TU_VERIFY with TU_BREAKPOINT() as handler * - 1 arg : return false if failed * - 2 arg : return error if failed *------------------------------------------------------------------*/ #define TU_ASSERT_DEFINE(_cond, _ret) \ do { \ if ( !(_cond) ) { TU_MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ } while(0) #define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) #define TU_ASSERT_2ARGS(_cond, _ret) TU_ASSERT_DEFINE(_cond, _ret) #ifndef TU_ASSERT #define TU_ASSERT(...) TU_GET_3RD_ARG(__VA_ARGS__, TU_ASSERT_2ARGS, TU_ASSERT_1ARGS, _dummy)(__VA_ARGS__) #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: src/device/dcd.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DCD_H_ #define TUSB_DCD_H_ #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ typedef enum { DCD_EVENT_INVALID = 0, // 0 DCD_EVENT_BUS_RESET, // 1 DCD_EVENT_UNPLUGGED, // 2 DCD_EVENT_SOF, // 3 DCD_EVENT_SUSPEND, // 4 TODO LPM Sleep L1 support DCD_EVENT_RESUME, // 5 DCD_EVENT_SETUP_RECEIVED, // 6 DCD_EVENT_XFER_COMPLETE, // 7 USBD_EVENT_FUNC_CALL, // 8 Not an DCD event, just a convenient way to defer ISR function DCD_EVENT_COUNT } dcd_eventid_t; typedef struct TU_ATTR_ALIGNED(4) { uint8_t rhport; uint8_t event_id; union { // BUS RESET struct { tusb_speed_t speed; } bus_reset; // SOF struct { uint32_t frame_count; }sof; // SETUP_RECEIVED tusb_control_request_t setup_received; // XFER_COMPLETE struct { uint8_t ep_addr; uint8_t result; uint32_t len; }xfer_complete; // FUNC_CALL struct { void (*func) (void* param); void* param; }func_call; }; } dcd_event_t; //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ // Memory API //--------------------------------------------------------------------+ // clean/flush data cache: write cache -> memory. // Required before an DMA TX transfer to make sure data is in memory bool dcd_dcache_clean(const void* addr, uint32_t data_size); // invalidate data cache: mark cache as invalid, next read will read from memory // Required BOTH before and after an DMA RX transfer bool dcd_dcache_invalidate(const void* addr, uint32_t data_size); // clean and invalidate data cache // Required before an DMA transfer where memory is both read/write by DMA bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size); //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // optional dcd configuration, called by tud_configure() bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Deinitialize controller, unset device mode. bool dcd_deinit(uint8_t rhport); // Interrupt Handler void dcd_int_handler(uint8_t rhport); // Enable device interrupt void dcd_int_enable (uint8_t rhport); // Disable device interrupt void dcd_int_disable(uint8_t rhport); // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr); // Wake up host void dcd_remote_wakeup(uint8_t rhport); // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport); // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport); // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); #if CFG_TUD_TEST_MODE // Put device into a test mode (needs power cycle to quit) void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector); #endif //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request); // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); // Close all non-control endpoints, cancel all pending transfers if any. // Invoked when switching from a non-zero Configuration by SET_CONFIGURE therefore // required for multiple configuration support. void dcd_edpt_close_all (uint8_t rhport); // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr); // Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack // This API is optional, may be useful for register-based for transferring data. bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr); // Stall endpoint, any queuing transfer should be removed from endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // clear stall, data toggle is also reset to DATA0 // This API never calls with control endpoints, since it is auto cleared when receiving setup packet void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); #ifdef TUP_DCD_EDPT_CLOSE_API // Close an endpoint. void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); #else // Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); #endif //--------------------------------------------------------------------+ // Event API (implemented by stack) //--------------------------------------------------------------------+ // Called by DCD to notify device stack extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) { dcd_event_t event; event.rhport = rhport; event.event_id = eid; dcd_event_handler(&event, in_isr); } // helper to send bus reset event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) { dcd_event_t event; event.rhport = rhport; event.event_id = DCD_EVENT_BUS_RESET; event.bus_reset.speed = speed; dcd_event_handler(&event, in_isr); } // helper to send setup received TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) { dcd_event_t event; event.rhport = rhport; event.event_id = DCD_EVENT_SETUP_RECEIVED; (void) memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t)); dcd_event_handler(&event, in_isr); } // helper to send transfer complete event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) { dcd_event_t event; event.rhport = rhport; event.event_id = DCD_EVENT_XFER_COMPLETE; event.xfer_complete.ep_addr = ep_addr; event.xfer_complete.len = xferred_bytes; event.xfer_complete.result = result; dcd_event_handler(&event, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) { dcd_event_t event; event.rhport = rhport; event.event_id = DCD_EVENT_SOF; event.sof.frame_count = frame_count; dcd_event_handler(&event, in_isr); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/device/usbd.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED #include "device/dcd.h" #include "tusb.h" #include "common/tusb_private.h" #include "device/usbd.h" #include "device/usbd_pvt.h" //--------------------------------------------------------------------+ // USBD Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; (void) in_isr; } TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { (void) frame_count; } TU_ATTR_WEAK uint8_t const* tud_descriptor_bos_cb(void) { return NULL; } TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void) { return NULL; } TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void) index; return NULL; } TU_ATTR_WEAK void tud_mount_cb(void) { } TU_ATTR_WEAK void tud_umount_cb(void) { } TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; } TU_ATTR_WEAK void tud_resume_cb(void) { } TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { (void) rhport; (void) stage; (void) request; return false; } TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { (void) rhport; return false; } TU_ATTR_WEAK void dcd_connect(uint8_t rhport) { (void) rhport; } TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) { (void) rhport; } TU_ATTR_WEAK bool dcd_dcache_clean(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_WEAK bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_WEAK bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ typedef struct { // Note: these may share an enum state volatile uint8_t connected; volatile uint8_t addressed; volatile uint8_t suspended; union { struct TU_ATTR_PACKED { uint8_t self_powered : 1; // configuration descriptor's attribute; uint8_t remote_wakeup_en : 1; // enable/disable by host }; uint8_t dev_state_bm; }; uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; volatile uint8_t sof_consumer; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2]; } usbd_device_t; static usbd_device_t _usbd_dev; static volatile uint8_t _usbd_queued_setup; //--------------------------------------------------------------------+ // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL #define DRIVER_NAME(_name) _name #else #define DRIVER_NAME(_name) NULL #endif // Built-in class drivers static const usbd_class_driver_t _usbd_driver[] = { #if CFG_TUD_CDC { .name = DRIVER_NAME("CDC"), .init = cdcd_init, .deinit = cdcd_deinit, .reset = cdcd_reset, .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, .xfer_cb = cdcd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_MSC { .name = DRIVER_NAME("MSC"), .init = mscd_init, .deinit = NULL, .reset = mscd_reset, .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, .xfer_cb = mscd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_HID { .name = DRIVER_NAME("HID"), .init = hidd_init, .deinit = hidd_deinit, .reset = hidd_reset, .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_AUDIO { .name = DRIVER_NAME("AUDIO"), .init = audiod_init, .deinit = audiod_deinit, .reset = audiod_reset, .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, .xfer_isr = audiod_xfer_isr, .sof = audiod_sof_isr }, #endif #if CFG_TUD_VIDEO { .name = DRIVER_NAME("VIDEO"), .init = videod_init, .deinit = videod_deinit, .reset = videod_reset, .open = videod_open, .control_xfer_cb = videod_control_xfer_cb, .xfer_cb = videod_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_MIDI { .name = DRIVER_NAME("MIDI"), .init = midid_init, .deinit = midid_deinit, .open = midid_open, .reset = midid_reset, .control_xfer_cb = midid_control_xfer_cb, .xfer_cb = midid_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_VENDOR { .name = DRIVER_NAME("VENDOR"), .init = vendord_init, .deinit = vendord_deinit, .reset = vendord_reset, .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_USBTMC { .name = DRIVER_NAME("TMC"), .init = usbtmcd_init_cb, .deinit = usbtmcd_deinit, .reset = usbtmcd_reset_cb, .open = usbtmcd_open_cb, .control_xfer_cb = usbtmcd_control_xfer_cb, .xfer_cb = usbtmcd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_DFU_RUNTIME { .name = DRIVER_NAME("DFU-RUNTIME"), .init = dfu_rtd_init, .deinit = dfu_rtd_deinit, .reset = dfu_rtd_reset, .open = dfu_rtd_open, .control_xfer_cb = dfu_rtd_control_xfer_cb, .xfer_cb = NULL, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_DFU { .name = DRIVER_NAME("DFU"), .init = dfu_moded_init, .deinit = dfu_moded_deinit, .reset = dfu_moded_reset, .open = dfu_moded_open, .control_xfer_cb = dfu_moded_control_xfer_cb, .xfer_cb = NULL, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM { .name = DRIVER_NAME("NET"), .init = netd_init, .deinit = netd_deinit, .reset = netd_reset, .open = netd_open, .control_xfer_cb = netd_control_xfer_cb, .xfer_cb = netd_xfer_cb, .xfer_isr = NULL, .sof = NULL, }, #endif #if CFG_TUD_BTH { .name = DRIVER_NAME("BTH"), .init = btd_init, .deinit = btd_deinit, .reset = btd_reset, .open = btd_open, .control_xfer_cb = btd_control_xfer_cb, .xfer_cb = btd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_MTP { .name = DRIVER_NAME("MTP"), .init = mtpd_init, .deinit = mtpd_deinit, .reset = mtpd_reset, .open = mtpd_open, .control_xfer_cb = mtpd_control_xfer_cb, .xfer_cb = mtpd_xfer_cb, .xfer_isr = NULL, .sof = NULL }, #endif #if CFG_TUD_PRINTER { .name = DRIVER_NAME("PRINTER"), .init = printerd_init, .deinit = printerd_deinit, .reset = printerd_reset, .open = printerd_open, .control_xfer_cb = printerd_control_xfer_cb, .xfer_cb = printerd_xfer_cb, .sof = NULL }, #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; // Additional class drivers implemented by application static const usbd_class_driver_t *_app_driver = NULL; static uint8_t _app_driver_count = 0; #define TOTAL_DRIVER_COUNT ((uint8_t) (_app_driver_count + BUILTIN_DRIVER_COUNT)) // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { usbd_class_driver_t const *driver = NULL; if (drvid < _app_driver_count) { // Application drivers driver = &_app_driver[drvid]; } else{ drvid -= _app_driver_count; if (drvid < BUILTIN_DRIVER_COUNT) { driver = &_usbd_driver[drvid]; } } return driver; } //--------------------------------------------------------------------+ // DCD Event //--------------------------------------------------------------------+ enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; static OSAL_SPINLOCK_DEF(_usbd_spin, usbd_int_set); // Event queue: usbd_int_set() is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); static osal_queue_t _usbd_q; // Mutex for claiming endpoint #if OSAL_MUTEX_REQUIRED static osal_mutex_def_t _ubsd_mutexdef; static osal_mutex_t _usbd_mutex; #else #define _usbd_mutex NULL #endif TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr)); tud_event_hook_cb(event->rhport, event->event_id, in_isr); return true; } //--------------------------------------------------------------------+ // Prototypes //--------------------------------------------------------------------+ static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); #if CFG_TUD_TEST_MODE static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { TU_VERIFY(CONTROL_STAGE_ACK == stage); uint8_t const selector = tu_u16_high(request->wIndex); TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); dcd_enter_test_mode(rhport, (tusb_feature_test_mode_t) selector); return true; } #endif // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) { *driver_count = 0; return NULL; } TU_ATTR_WEAK bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) rhport; (void) ep_addr; (void) ff; (void) total_bytes; (void) is_isr; return false; } TU_ATTR_WEAK bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; (void) cfg_id; (void) cfg_param; return false; } //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL static char const *const _usbd_event_str[DCD_EVENT_COUNT] = { "Invalid", "Bus Reset", "Unplugged", "SOF", "Suspend", "Resume", "Setup Received", "Xfer Complete", "Func Call" }; // for usbd_control to print the name of control complete driver void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); if (driver && driver->control_xfer_cb == callback) { TU_LOG_USBD("%s control complete\r\n", driver->name); return; } } } #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ tusb_speed_t tud_speed_get(void) { return (tusb_speed_t) _usbd_dev.speed; } bool tud_connected(void) { return _usbd_dev.connected; } bool tud_mounted(void) { return _usbd_dev.cfg_num ? true : false; } bool tud_suspended(void) { return _usbd_dev.suspended; } bool tud_remote_wakeup(void) { // only wake up host if this feature is enabled and we are suspended TU_VERIFY(_usbd_dev.suspended && _usbd_dev.remote_wakeup_en); dcd_remote_wakeup(_usbd_rhport); return true; } bool tud_disconnect(void) { dcd_disconnect(_usbd_rhport); return true; } bool tud_connect(void) { dcd_connect(_usbd_rhport); return true; } void tud_sof_cb_enable(bool en) { usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); } bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { return dcd_configure(rhport, cfg_id, cfg_param); } bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { if (tud_inited()) { return true; // skip if already initialized } TU_ASSERT(rh_init); #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* speed_str = 0; switch (rh_init->speed) { case TUSB_SPEED_HIGH: speed_str = "High"; break; case TUSB_SPEED_FULL: speed_str = "Full"; break; case TUSB_SPEED_LOW: speed_str = "Low"; break; case TUSB_SPEED_AUTO: speed_str = "Auto"; break; default: break; } TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, speed_str); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t)); #endif tu_varclr(&_usbd_dev); _usbd_queued_setup = 0; osal_spin_init(&_usbd_spin); #if OSAL_MUTEX_REQUIRED // Init device mutex _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef); TU_ASSERT(_usbd_mutex); #endif // Init device queue & task _usbd_q = osal_queue_create(&_usbd_qdef); TU_ASSERT(_usbd_q); // Get application driver if available _app_driver = usbd_app_driver_get_cb(&_app_driver_count); TU_ASSERT(_app_driver_count + BUILTIN_DRIVER_COUNT <= UINT8_MAX); // Init class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver && driver->init); TU_LOG_USBD("%s init\r\n", driver->name); driver->init(); } _usbd_rhport = rhport; // Init device controller driver TU_ASSERT(dcd_init(rhport, rh_init)); dcd_int_enable(rhport); return true; } bool tud_deinit(uint8_t rhport) { if (!tud_inited()) { return true; // skip if not initialized } TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport); const uint8_t cfg_num = _usbd_dev.cfg_num; // Deinit device controller driver dcd_int_disable(rhport); dcd_disconnect(rhport); TU_ASSERT(dcd_deinit(rhport)); // Deinit class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); if(driver && driver->deinit) { TU_LOG_USBD("%s deinit\r\n", driver->name); driver->deinit(); } } // Clear device data tu_varclr(&_usbd_dev); usbd_control_reset(); // Deinit device queue & task osal_queue_delete(_usbd_q); _usbd_q = NULL; #if OSAL_MUTEX_REQUIRED // TODO make sure there is no task waiting on this mutex osal_mutex_delete(_usbd_mutex); _usbd_mutex = NULL; #endif _usbd_rhport = RHPORT_INVALID; if (cfg_num > 0) { tud_umount_cb(); } return true; } static void configuration_reset(uint8_t rhport) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } tu_varclr(&_usbd_dev); (void)memset(_usbd_dev.itf2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.itf2drv)); // invalid mapping (void)memset(_usbd_dev.ep2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { configuration_reset(rhport); usbd_control_reset(); } bool tud_task_event_ready(void) { TU_VERIFY(tud_inited()); // Skip if stack is not initialized return !osal_queue_empty(_usbd_q); } //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ /* USB Device Driver task * This top level thread manages all device controller event and delegates events to class-specific drivers. * This should be called periodically within the mainloop or rtos thread. * int main(void) { application_init(); tusb_init(0, TUSB_ROLE_DEVICE); while(1) { // the mainloop application_code(); tud_task(); // tinyusb device task } } */ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized if (!tud_inited()) { return; } // Loop until there are no more events in the queue or CFG_TUD_TASK_EVENTS_PER_RUN is reached for (unsigned epr = 0;; epr++) { #if CFG_TUD_TASK_EVENTS_PER_RUN > 0 if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) { TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n"); break; } #endif dcd_event_t event; if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) { return; } #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL if (event.event_id == DCD_EVENT_SETUP_RECEIVED) { TU_LOG_USBD("\r\n"); // extra line for setup } TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); #endif switch (event.event_id) { case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; break; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); usbd_reset(event.rhport); tud_umount_cb(); break; case DCD_EVENT_SETUP_RECEIVED: TU_ASSERT(_usbd_queued_setup > 0,); _usbd_queued_setup--; TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); if (_usbd_queued_setup != 0) { TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n"); break; } // Mark as connected after receiving 1st setup packet. // But it is easier to set it every time instead of wasting time to check then set _usbd_dev.connected = 1; // mark both in & out control as free _usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = 0; _usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0; _usbd_dev.ep_status[0][TUSB_DIR_IN].busy = 0; _usbd_dev.ep_status[0][TUSB_DIR_IN].claimed = 0; // Process control request if (!process_control_request(event.rhport, &event.setup_received)) { TU_LOG_USBD(" Stall EP0\r\n"); // Failed -> stall both control endpoint IN and OUT dcd_edpt_stall(event.rhport, 0); dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK); } break; case DCD_EVENT_XFER_COMPLETE: { // Invoke the class callback associated with the endpoint address uint8_t const ep_addr = event.xfer_complete.ep_addr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); _usbd_dev.ep_status[epnum][ep_dir].busy = 0; _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; if (0 == epnum) { usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); TU_ASSERT(driver,); TU_LOG_USBD(" %s xfer callback\r\n", driver->name); driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } break; } case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected if (_usbd_dev.connected) { TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); tud_suspend_cb(_usbd_dev.remote_wakeup_en); } else { TU_LOG_USBD(" Skipped\r\n"); } break; case DCD_EVENT_RESUME: if (_usbd_dev.connected) { TU_LOG_USBD("\r\n"); tud_resume_cb(); } else { TU_LOG_USBD(" Skipped\r\n"); } break; case USBD_EVENT_FUNC_CALL: TU_LOG_USBD("\r\n"); if (event.func_call.func != NULL) { event.func_call.func(event.func_call.param); } break; case DCD_EVENT_SOF: if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) { TU_LOG_USBD("\r\n"); tud_sof_cb(event.sof.frame_count); } break; default: TU_BREAKPOINT(); break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO // return if there is no more events, for application to run other background if (osal_queue_empty(_usbd_q)) { return; } #endif } } //--------------------------------------------------------------------+ // Control Request Parser & Handling //--------------------------------------------------------------------+ // Helper to invoke class driver control request handler static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) { usbd_control_set_complete_callback(driver->control_xfer_cb); TU_LOG_USBD(" %s control request\r\n", driver->name); return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); } // This handles the actual request and its response. // Returns false if unable to complete the request, causing caller to stall control endpoints. static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { usbd_control_set_complete_callback(NULL); TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); } #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]); if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) { TU_LOG_USBD("\r\n"); } } #endif switch (p_request->bmRequestType_bit.recipient) { //-V2520 //------------- Device Requests e.g in enumeration -------------// case TUSB_REQ_RCPT_DEVICE: if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) { uint8_t const itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]); TU_VERIFY(driver); // forward to class driver: "non-STD request to Interface" return invoke_class_control(rhport, driver, p_request); } if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) { // Non-standard request is not supported TU_BREAKPOINT(); return false; } switch (p_request->bRequest) { //-V2520 case TUSB_REQ_SET_ADDRESS: // Depending on mcu, status phase could be sent either before or after changing device address, // or even require stack to not response with status at all // Therefore DCD must take full responsibility to response and include zlp status packet if needed. usbd_control_set_request(p_request); // set request since DCD has no access to tud_control_status() API dcd_set_address(rhport, (uint8_t) p_request->wValue); // skip tud_control_status() _usbd_dev.addressed = 1; break; case TUSB_REQ_GET_CONFIGURATION: { uint8_t cfg_num = _usbd_dev.cfg_num; tud_control_xfer(rhport, p_request, &cfg_num, 1); } break; case TUSB_REQ_SET_CONFIGURATION: { uint8_t const cfg_num = (uint8_t) p_request->wValue; // Only process if new configure is different if (_usbd_dev.cfg_num != cfg_num) { if (_usbd_dev.cfg_num != 0) { // already configured: need to clear all endpoints and driver first TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); dcd_sof_enable(rhport, false); dcd_edpt_close_all(rhport); // close all drivers and current configured state except bus speed const uint8_t speed = _usbd_dev.speed; configuration_reset(rhport); _usbd_dev.speed = speed; // restore speed } _usbd_dev.cfg_num = cfg_num; // Handle the new configuration if (cfg_num == 0) { tud_umount_cb(); } else { if (!process_set_config(rhport, cfg_num)) { _usbd_dev.cfg_num = 0; TU_ASSERT(false); } tud_mount_cb(); } } tud_control_status(rhport, p_request); } break; case TUSB_REQ_GET_DESCRIPTOR: TU_VERIFY(process_get_descriptor(rhport, p_request)); break; case TUSB_REQ_SET_FEATURE: switch(p_request->wValue) { //-V2520 case TUSB_REQ_FEATURE_REMOTE_WAKEUP: TU_LOG_USBD(" Enable Remote Wakeup\r\n"); // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = 1; tud_control_status(rhport, p_request); break; #if CFG_TUD_TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid TU_VERIFY(0 == tu_u16_low(p_request->wIndex)); uint8_t const selector = tu_u16_high(p_request->wIndex); TU_VERIFY(TUSB_FEATURE_TEST_J <= selector && selector <= TUSB_FEATURE_TEST_FORCE_ENABLE); usbd_control_set_complete_callback(process_test_mode_cb); tud_control_status(rhport, p_request); break; } #endif // Stall unsupported feature selector default: return false; } break; case TUSB_REQ_CLEAR_FEATURE: // Only support remote wakeup for device feature TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); TU_LOG_USBD(" Disable Remote Wakeup\r\n"); // Host may disable remote wake up after resuming _usbd_dev.remote_wakeup_en = 0; tud_control_status(rhport, p_request); break; case TUSB_REQ_GET_STATUS: { // Device status bit mask // - Bit 0: Self Powered TODO must invoke callback to get actual status // - Bit 1: Remote Wakeup enabled uint16_t status = (uint16_t)_usbd_dev.dev_state_bm; tud_control_xfer(rhport, p_request, &status, 2); break; } // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } break; //------------- Class/Interface Specific Request -------------// case TUSB_REQ_RCPT_INTERFACE: { uint8_t itf; #if CFG_TUD_PRINTER // Printer GET_DEVICE_ID has a weird wIndex = interface (high) | alt (low) // attempt to interpret this as a printer request if matched if (TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type && TUSB_DIR_IN == p_request->bmRequestType_bit.direction && TUSB_PRINTER_REQUEST_GET_DEVICE_ID == p_request->bRequest) { itf = tu_u16_high(p_request->wIndex); if (itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)) { const usbd_class_driver_t * driver = get_driver(_usbd_dev.itf2drv[itf]); if (driver != NULL && driver->control_xfer_cb == printerd_control_xfer_cb) { if (invoke_class_control(rhport, driver, p_request)) { return true; } } } } #endif itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]); TU_VERIFY(driver); // all requests to Interface (STD or Class) is forwarded to class driver. // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE if (!invoke_class_control(rhport, driver, p_request)) { // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class // driver doesn't use alternate settings or implement this TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); // Clear complete callback if driver set since it can also stall the request. usbd_control_set_complete_callback(NULL); switch (p_request->bRequest) { //-V2520 case TUSB_REQ_GET_INTERFACE: { uint8_t alternate = 0; tud_control_xfer(rhport, p_request, &alternate, 1); break; } case TUSB_REQ_SET_INTERFACE: tud_control_status(rhport, p_request); break; default: return false; } } break; } //------------- Endpoint Request -------------// case TUSB_REQ_RCPT_ENDPOINT: { uint8_t const ep_addr = tu_u16_low(p_request->wIndex); uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]); if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) { // Forward class request to its driver TU_VERIFY(driver); return invoke_class_control(rhport, driver, p_request); } else { // Handle STD request to endpoint switch (p_request->bRequest) { //-V2520 case TUSB_REQ_GET_STATUS: { uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001u : 0x0000u; tud_control_xfer(rhport, p_request, &status, 2); } break; case TUSB_REQ_CLEAR_FEATURE: case TUSB_REQ_SET_FEATURE: { if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) { if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) { usbd_edpt_clear_stall(rhport, ep_addr); }else { usbd_edpt_stall(rhport, ep_addr); } } if (driver != NULL) { // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request // We will also forward std request targeted endpoint to class drivers as well // STD request must always be ACKed regardless of driver returned value // Also clear complete callback if driver set since it can also stall the request. (void) invoke_class_control(rhport, driver, p_request); usbd_control_set_complete_callback(NULL); // skip ZLP status if driver already did that if (!_usbd_dev.ep_status[0][TUSB_DIR_IN].busy) { tud_control_status(rhport, p_request); } } } break; // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } } break; } // Unknown recipient default: TU_BREAKPOINT(); return false; } return true; } // Process Set Configure Request // This function parse configuration descriptor & open drivers accordingly static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { // index is cfg_num-1 const tusb_desc_configuration_t *desc_cfg = (const tusb_desc_configuration_t *)tud_descriptor_configuration_cb(cfg_num - 1); TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION); // Parse configuration descriptor _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED) ? 1u : 0u; // Parse interface descriptor const uint8_t *p_desc = ((const uint8_t *)desc_cfg) + sizeof(tusb_desc_configuration_t); const uint8_t *desc_end = ((const uint8_t *)desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); while (tu_desc_in_bounds(p_desc, desc_end)) { // Class will always start with Interface Association (if any) and then Interface descriptor if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); // next to Interface continue; } TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc)); const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc; // Find driver for this interface const uint16_t remaining_len = (uint16_t)(desc_end - p_desc); uint8_t drv_id; for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { const usbd_class_driver_t *driver = get_driver(drv_id); TU_ASSERT(driver); const uint16_t drv_len = driver->open(rhport, desc_itf, remaining_len); if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) { // Open successfully TU_LOG_USBD(" %s opened\r\n", driver->name); // bind found driver to all interfaces and endpoint within drv_len TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, _usbd_dev.ep2drv, _usbd_dev.itf2drv, CFG_TUD_INTERFACE_MAX, p_desc, drv_len)); p_desc += drv_len; // next Interface break; // exit driver find loop } } // Failed if there is no supported drivers TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT); } return true; } // return descriptor's buffer and update desc_len static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request) { tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue); uint8_t const desc_index = tu_u16_low( p_request->wValue ); switch(desc_type) { //-V2520 case TUSB_DESC_DEVICE: { TU_LOG_USBD(" Device\r\n"); void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb(); TU_ASSERT(desc_device); // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has. // This only happens with the very first get device descriptor and EP0 size = 8 or 16. if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed && ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) { // Hack here: we modify the request length to prevent usbd_control response with zlp // since we are responding with 1 packet & less data than wLength. tusb_control_request_t mod_request = *p_request; mod_request.wLength = CFG_TUD_ENDPOINT0_SIZE; return tud_control_xfer(rhport, &mod_request, desc_device, CFG_TUD_ENDPOINT0_SIZE); }else { return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t)); } } // break; // unreachable case TUSB_DESC_BOS: { TU_LOG_USBD(" BOS\r\n"); // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb(); TU_VERIFY(desc_bos != 0); // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) ); return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len); } // break; // unreachable case TUSB_DESC_CONFIGURATION: case TUSB_DESC_OTHER_SPEED_CONFIG: { uintptr_t desc_config; if ( desc_type == TUSB_DESC_CONFIGURATION ) { TU_LOG_USBD(" Configuration[%u]\r\n", desc_index); desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); TU_ASSERT(desc_config != 0); }else { // Host only request this after getting Device Qualifier descriptor TU_LOG_USBD(" Other Speed Configuration\r\n"); desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); TU_VERIFY(desc_config != 0); } // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) ); return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len); } // break; // unreachable case TUSB_DESC_STRING: { TU_LOG_USBD(" String[%u]\r\n", desc_index); // String Descriptor always uses the desc set from user uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex)); TU_VERIFY(desc_str); // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_str, tu_desc_len(desc_str)); } // break; // unreachable case TUSB_DESC_DEVICE_QUALIFIER: { TU_LOG_USBD(" Device Qualifier\r\n"); uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb(); TU_VERIFY(desc_qualifier); return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier)); } // break; // unreachable default: return false; } } //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) { bool send = false; switch (event->event_id) { case DCD_EVENT_UNPLUGGED: _usbd_dev.connected = 0; _usbd_dev.addressed = 0; _usbd_dev.cfg_num = 0; _usbd_dev.suspended = 0; send = true; break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected if (_usbd_dev.connected) { _usbd_dev.suspended = 1; send = true; } break; case DCD_EVENT_RESUME: // skip event if not connected (especially required for SAMD) if (_usbd_dev.connected) { _usbd_dev.suspended = 0; send = true; } break; case DCD_EVENT_SOF: // SOF driver handler in ISR context for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); if (driver && driver->sof) { driver->sof(event->rhport, event->sof.frame_count); } } // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational if (_usbd_dev.suspended) { _usbd_dev.suspended = 0; dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME}; queue_event(&event_resume, in_isr); } if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) { dcd_event_t const event_sof = {.rhport = event->rhport, .event_id = DCD_EVENT_SOF, .sof.frame_count = event->sof.frame_count}; queue_event(&event_sof, in_isr); } break; case DCD_EVENT_SETUP_RECEIVED: _usbd_queued_setup++; send = true; break; case DCD_EVENT_XFER_COMPLETE: { // Invoke the class callback associated with the endpoint address uint8_t const ep_addr = event->xfer_complete.ep_addr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); send = true; if(epnum > 0) { usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); if (driver && driver->xfer_isr) { _usbd_dev.ep_status[epnum][ep_dir].busy = 0; _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; send = !driver->xfer_isr(event->rhport, ep_addr, (xfer_result_t) event->xfer_complete.result, event->xfer_complete.len); // xfer_isr() is deferred to xfer_cb(), revert busy/claimed status if (send) { _usbd_dev.ep_status[epnum][ep_dir].busy = 1; _usbd_dev.ep_status[epnum][ep_dir].claimed = 1; } } } break; } default: send = true; break; } if (send) { queue_event(event, in_isr); } } //--------------------------------------------------------------------+ // USBD API For Class Driver //--------------------------------------------------------------------+ void usbd_int_set(bool enabled) { if (enabled) { dcd_int_enable(_usbd_rhport); } else { dcd_int_disable(_usbd_rhport); } } void usbd_spin_lock(bool in_isr) { osal_spin_lock(&_usbd_spin, in_isr); } void usbd_spin_unlock(bool in_isr) { osal_spin_unlock(&_usbd_spin, in_isr); } // Parse consecutive endpoint descriptors (IN & OUT) bool usbd_open_edpt_pair(uint8_t rhport, const uint8_t *p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t *ep_out, uint8_t *ep_in) { for (int i = 0; i < ep_count; i++) { const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer); TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { (*ep_in) = desc_ep->bEndpointAddress; } else { (*ep_out) = desc_ep->bEndpointAddress; } p_desc = tu_desc_next(p_desc); } return true; } // Helper to defer an isr function void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { dcd_event_t event = { .rhport = 0, .event_id = USBD_EVENT_FUNC_CALL, }; event.func_call.func = func; event.func_call.param = param; queue_event(&event, in_isr); } //--------------------------------------------------------------------+ // USBD Endpoint API //--------------------------------------------------------------------+ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed)); return dcd_edpt_open(rhport, desc_ep); } bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) { (void) rhport; // TODO add this check later, also make sure we don't starve an out endpoint while suspending // TU_VERIFY(tud_ready()); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_claim(ep_state, _usbd_mutex); } bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_release(ep_state, _usbd_mutex); } bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); // TODO skip ready() check for now since enumeration also use this API // TU_VERIFY(tud_ready()); TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); #if CFG_TUD_LOG_LEVEL >= 3 if(dir == TUSB_DIR_IN) { TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2); } #endif // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() // could return and USBD task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes, is_isr)) { return true; } else { // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; TU_LOG_USBD("FAILED\r\n"); TU_BREAKPOINT(); return false; } } // The number of bytes has to be given explicitly to allow more flexible control of how many // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) { #if CFG_TUD_EDPT_DEDICATED_HWFIFO rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_LOG_USBD(" Queue FIFO EP %02X with %u bytes ... ", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like a race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return // and usbd task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes, is_isr)) { TU_LOG_USBD("OK\r\n"); return true; } else { // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; TU_LOG_USBD("failed\r\n"); TU_BREAKPOINT(); return false; } #else (void)rhport; (void)ep_addr; (void)ff; (void)total_bytes; (void)is_isr; return false; #endif } bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].busy; } void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); // only stalled if currently cleared TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr); dcd_edpt_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 1; _usbd_dev.ep_status[epnum][dir].busy = 1; } void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); // only clear if currently stalled TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr); dcd_edpt_clear_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; } bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].stalled; } /** * usbd_edpt_close will disable an endpoint. * In progress transfers on this EP may be delivered after this call. */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { #ifdef TUP_DCD_EDPT_ISO_ALLOC (void) rhport; (void) ep_addr; // ISO alloc/activate Should be used instead #else rhport = _usbd_rhport; TU_LOG_USBD(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); dcd_edpt_close(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; #endif return; } void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { rhport = _usbd_rhport; uint8_t consumer_old = _usbd_dev.sof_consumer; // Keep track how many class instances need the SOF interrupt if (en) { _usbd_dev.sof_consumer |= (uint8_t)(1 << consumer); } else { _usbd_dev.sof_consumer &= (uint8_t)(~(1 << consumer)); } // Test logically unequal if(!_usbd_dev.sof_consumer != !consumer_old) { dcd_sof_enable(rhport, _usbd_dev.sof_consumer); } } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { #ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX); return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size); #else (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; #endif } bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { #ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed)); _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; return dcd_edpt_iso_activate(rhport, desc_ep); #else (void) rhport; (void) desc_ep; return false; #endif } #endif ================================================ FILE: src/device/usbd.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_USBD_H_ #define TUSB_USBD_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif // ConfigID for tud_configure() enum { TUD_CFGID_INVALID = 0, TUD_CFGID_DWC2 = 100, }; typedef struct { uint16_t bm_double_buffered; // bitmap of IN endpoints to be double buffered, only effective for bulk endpoints bool vbus_sensing; // Vbus pin is used for device connection detection, mandatory for tud_umount_cb() } tud_configure_dwc2_t; #ifndef CFG_TUD_CONFIGURE_DWC2_DEFAULT #define CFG_TUD_CONFIGURE_DWC2_DEFAULT {.bm_double_buffered = 0, .vbus_sensing = CFG_TUD_VBUS_DETECT_HW} #endif typedef union { tud_configure_dwc2_t dwc2; } tud_configure_param_t; //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Configure device stack behavior with dynamic or port-specific parameters. // Should be called before initialization of the device stack // - cfg_id : configure ID from TUD_CFGID_* enum values // - cfg_param: configure data, structure depends on the ID bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // New API to replace tud_init() to init device stack on specific roothub port // Must be called in the same task/context as tud_task() if RTOS is used bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Init device stack on roothub port #if TUSB_VERSION_NUMBER > 2000 // 0.20.0 TU_ATTR_DEPRECATED("Please use tusb_init(rhport, rh_init) instead") #endif TU_ATTR_ALWAYS_INLINE static inline bool tud_init (uint8_t rhport) { const tusb_rhport_init_t rh_init = { .role = TUSB_ROLE_DEVICE, .speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; return tud_rhport_init(rhport, &rh_init); } // Deinit device stack on roothub port // Must be called in the same task/context as tud_task() if RTOS is used bool tud_deinit(uint8_t rhport); // Check if device stack is already initialized bool tud_inited(void); // Task function should be called in main/rtos loop, extended version of tud_task() // - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever // - in_isr: if function is called in ISR void tud_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline void tud_task (void) { tud_task_ext(UINT32_MAX, false); } // Check if there is pending events need processing by tud_task() bool tud_task_event_ready(void); #ifndef TUSB_DCD_H_ extern void dcd_int_handler(uint8_t rhport); #endif // Interrupt handler, name alias to DCD #define tud_int_handler dcd_int_handler // Get current bus speed tusb_speed_t tud_speed_get(void); // Check if device is connected (may not mounted/configured yet) // True if just got out of Bus Reset and received the very first data from host bool tud_connected(void); // Check if device is connected and configured bool tud_mounted(void); // Check if device is suspended bool tud_suspended(void); // Check if device is ready to transfer TU_ATTR_ALWAYS_INLINE static inline bool tud_ready(void) { const bool is_mounted = tud_mounted(); const bool is_suspended = tud_suspended(); return is_mounted && !is_suspended; } // Remote wake up host, only if suspended and enabled by host bool tud_remote_wakeup(void); // Enable pull-up resistor on D+ D- // Return false on unsupported MCUs bool tud_disconnect(void); // Disable pull-up resistor on D+ D- // Return false on unsupported MCUs bool tud_connect(void); // Enable or disable the Start Of Frame callback support void tud_sof_cb_enable(bool en); // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len); // Send STATUS (zero length) packet bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request); //--------------------------------------------------------------------+ // Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR request // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void); // Invoked when received GET CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index); // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid); // Invoked when received GET BOS DESCRIPTOR request // Application return pointer to descriptor uint8_t const * tud_descriptor_bos_cb(void); // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. uint8_t const* tud_descriptor_device_qualifier_cb(void); // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); // Invoked when device is mounted (configured) void tud_mount_cb(void); // Invoked when device is unmounted void tud_umount_cb(void); // Invoked when usb bus is suspended // Within 7ms, device must draw an average of current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed void tud_resume_cb(void); // Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); // Invoked when a new (micro) frame started void tud_sof_cb(uint32_t frame_count); // Invoked when received control request with VENDOR TYPE bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); //--------------------------------------------------------------------+ // Binary Device Object Store (BOS) Descriptor Templates //--------------------------------------------------------------------+ #define TUD_BOS_DESC_LEN 5 // total length, number of device caps #define TUD_BOS_DESCRIPTOR(_total_len, _caps_num) \ 5, TUSB_DESC_BOS, U16_TO_U8S_LE(_total_len), _caps_num // Device Capability Platform 128-bit UUID + Data #define TUD_BOS_PLATFORM_DESCRIPTOR(...) \ 4+TU_ARGS_NUM(__VA_ARGS__), TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_PLATFORM, 0x00, __VA_ARGS__ //------------- WebUSB BOS Platform -------------// // Descriptor Length #define TUD_BOS_WEBUSB_DESC_LEN 24 // Vendor Code, iLandingPage #define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \ TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_WEBUSB_UUID, U16_TO_U8S_LE(0x0100), _vendor_code, _ipage) #define TUD_BOS_WEBUSB_UUID \ 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \ 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65 //------------- Microsoft OS 2.0 Platform -------------// #define TUD_BOS_MICROSOFT_OS_DESC_LEN 28 // Total Length of descriptor set, vendor code #define TUD_BOS_MS_OS_20_DESCRIPTOR(_desc_set_len, _vendor_code) \ TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_MS_OS_20_UUID, U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(_desc_set_len), _vendor_code, 0) #define TUD_BOS_MS_OS_20_UUID \ 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \ 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F //--------------------------------------------------------------------+ // Configuration Descriptor Templates //--------------------------------------------------------------------+ #define TUD_CONFIG_DESC_LEN (9) // Config number, interface count, string index, total length, attribute, power in mA #define TUD_CONFIG_DESCRIPTOR(config_num, _itfcount, _stridx, _total_len, _attribute, _power_ma) \ 9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2 //--------------------------------------------------------------------+ // CDC Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 66 bytes #define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7) // CDC Descriptor Template // Interface number, string index, EP notification address and size, EP data address (out, in) and size. #define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ /* Interface Associate */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, 0,\ /* CDC Control Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, _stridx,\ /* CDC Header */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC Call */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ /* CDC ACM: support line request + send break */\ 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 6,\ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ /* CDC Data Interface */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // MSC Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 23 bytes #define TUD_MSC_DESC_LEN (9 + 7 + 7) // Interface number, string index, EP Out & EP In address, EP size #define TUD_MSC_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_MSC, MSC_SUBCLASS_SCSI, MSC_PROTOCOL_BOT, _stridx,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // Printer Descriptor Templates //--------------------------------------------------------------------+ #define TUD_PRINTER_DESC_LEN (9 + 7 + 7) // one interface, two endpoints #define TUD_PRINTER_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_PRINTER, 1, 2, _stridx,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // MTP Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 30 bytes #define TUD_MTP_DESC_LEN (9 + 7 + 7 + 7) // Interface number, string index, EP event, EP event size, EP event polling, EP Out & EP In address, EP size #define TUD_MTP_DESCRIPTOR(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_polling_interval, _epout, _epin, _epsize) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 3, TUSB_CLASS_IMAGE, MTP_SUBCLASS_STILL_IMAGE, MTP_PROTOCOL_PIMA_15470, _stridx,\ /* Endpoint Interrupt */\ 7, TUSB_DESC_ENDPOINT, _ep_evt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_evt_size), _ep_evt_polling_interval,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // HID Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 25 bytes #define TUD_HID_DESC_LEN (9 + 9 + 7) // HID Input only descriptor // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval #define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (uint8_t)((_boot_protocol != HID_ITF_PROTOCOL_NONE) ? (uint8_t)HID_SUBCLASS_BOOT : 0u), _boot_protocol, _stridx,\ /* HID descriptor */\ 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval // Length of template descriptor: 32 bytes #define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7) // HID Input & Output descriptor // Interface number, string index, protocol, report descriptor len, EP OUT & IN address, size & polling interval #define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epout, _epin, _epsize, _ep_interval) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (uint8_t)((_boot_protocol != HID_ITF_PROTOCOL_NONE) ? (uint8_t)HID_SUBCLASS_BOOT : 0u), _boot_protocol, _stridx,\ /* HID descriptor */\ 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval, \ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval //--------------------------------------------------------------------+ // MIDI Descriptor Templates // Note: MIDI v1.0 is based on Audio v1.0 //--------------------------------------------------------------------+ #define TUD_MIDI_DESC_HEAD_LEN (9 + 9 + 9 + 7) #define TUD_MIDI_DESC_HEAD(_itfnum, _stridx, _numcables) \ /* Audio Control (AC) Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, _stridx,\ /* AC Header */\ 9, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0009), 1, (uint8_t)((_itfnum) + 1),\ /* MIDI Streaming (MS) Interface */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ /* MS Header */\ 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(7 + (_numcables) * TUD_MIDI_DESC_JACK_LEN + 2 * TUD_MIDI_DESC_EP_LEN(_numcables)) #define TUD_MIDI_JACKID_IN_EMB(_cablenum) \ (uint8_t)(((_cablenum) - 1) * 4 + 1) #define TUD_MIDI_JACKID_IN_EXT(_cablenum) \ (uint8_t)(((_cablenum) - 1) * 4 + 2) #define TUD_MIDI_JACKID_OUT_EMB(_cablenum) \ (uint8_t)(((_cablenum) - 1) * 4 + 3) #define TUD_MIDI_JACKID_OUT_EXT(_cablenum) \ (uint8_t)(((_cablenum) - 1) * 4 + 4) #define TUD_MIDI_DESC_JACK_LEN (6 + 6 + 9 + 9) #define TUD_MIDI_DESC_JACK_DESC(_cablenum, _stridx) \ /* MS In Jack (Embedded) */\ 6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EMBEDDED, TUD_MIDI_JACKID_IN_EMB(_cablenum), _stridx,\ /* MS In Jack (External) */\ 6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_IN_EXT(_cablenum), _stridx,\ /* MS Out Jack (Embedded), connected to In Jack External */\ 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, TUD_MIDI_JACKID_OUT_EMB(_cablenum), 1, TUD_MIDI_JACKID_IN_EXT(_cablenum), 1, _stridx,\ /* MS Out Jack (External), connected to In Jack Embedded */\ 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, TUD_MIDI_JACKID_OUT_EXT(_cablenum), 1, TUD_MIDI_JACKID_IN_EMB(_cablenum), 1, _stridx #define TUD_MIDI_DESC_JACK(_cablenum) TUD_MIDI_DESC_JACK_DESC(_cablenum, 0) #define TUD_MIDI_DESC_EP_LEN(_numcables) (9 + 4 + (_numcables)) #define TUD_MIDI_DESC_EP(_epout, _epsize, _numcables) \ /* Endpoint: Note Audio v1.0's endpoint has 9 bytes instead of 7 */\ 9, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, 0, 0, \ /* MS Endpoint (connected to embedded jack) */\ (uint8_t)(4 + (_numcables)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, _numcables // Length of template descriptor (88 bytes) #define TUD_MIDI_DESC_LEN (TUD_MIDI_DESC_HEAD_LEN + TUD_MIDI_DESC_JACK_LEN + TUD_MIDI_DESC_EP_LEN(1) * 2) // MIDI simple descriptor // - 1 Embedded Jack In connected to 1 External Jack Out // - 1 Embedded Jack out connected to 1 External Jack In #define TUD_MIDI_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ TUD_MIDI_DESC_HEAD(_itfnum, _stridx, 1),\ TUD_MIDI_DESC_JACK_DESC(1, 0),\ TUD_MIDI_DESC_EP(_epout, _epsize, 1),\ TUD_MIDI_JACKID_IN_EMB(1),\ TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1) //--------------------------------------------------------------------+ // Audio Descriptor Templates //--------------------------------------------------------------------+ /* Audio v1.0 Descriptor Templates */ /* Standard AC Interface Descriptor UAC1 (4.3.1) */ #define TUD_AUDIO10_DESC_STD_AC_LEN 9 #define TUD_AUDIO10_DESC_STD_AC(_itfnum, _nEPs, _stridx) \ TUD_AUDIO10_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V1, _stridx /* Class-Specific AC Interface Header Descriptor UAC1 (4.3.2) */ #define TUD_AUDIO10_DESC_CS_AC_LEN(_nintfs) (8 + (_nintfs)) // Class-Specific AC Interface Header descriptor, take list of streaming interface numbers as variable arguments #define TUD_AUDIO10_DESC_CS_AC(_bcdADC, _totallen, ...) \ TUD_AUDIO10_DESC_CS_AC_LEN(TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), U16_TO_U8S_LE(_totallen + TUD_AUDIO10_DESC_CS_AC_LEN(TU_ARGS_NUM(__VA_ARGS__))), TU_ARGS_NUM(__VA_ARGS__), __VA_ARGS__ /* Input Terminal Descriptor UAC1 (4.3.2.1) */ #define TUD_AUDIO10_DESC_INPUT_TERM_LEN 12 #define TUD_AUDIO10_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _nchannels, _channelcfg, _idxchannelnames, _stridx) \ TUD_AUDIO10_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _nchannels, U16_TO_U8S_LE(_channelcfg), _idxchannelnames, _stridx /* Output Terminal Descriptor UAC1 (4.3.2.2) */ #define TUD_AUDIO10_DESC_OUTPUT_TERM_LEN 9 #define TUD_AUDIO10_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _stridx) \ TUD_AUDIO10_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _stridx /* Mixer Unit Descriptor UAC1 (4.3.2.3) - One Input Pin */ #define TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN_LEN(_ctrlsize) (11 + (_ctrlsize)) #define TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN(_unitid, _srcid, _nrchannels, _channelcfg, _idxchannelnames, _ctrlsize, _stridx, ...) \ TUD_AUDIO10_DESC_MIXER_UNIT_ONE_PIN_LEN(_ctrlsize), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_MIXER_UNIT, _unitid, 1, _srcid, _nrchannels, U16_TO_U8S_LE(_channelcfg), _idxchannelnames, __VA_ARGS__, _stridx /* Selector Unit Descriptor UAC1 (4.3.2.4) - One Input Pin */ #define TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN 7 #define TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN(_unitid, _srcid, _stridx) \ TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT, _unitid, 1, _srcid, _stridx /* Feature Unit Descriptor UAC1 (4.3.2.5) - Variable Channels */ #define TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(_nchannels) (7 + ((_nchannels) + 1) * 2) // Feature Unit descriptor, take list of control bitmaps for master channel + each channel as variable arguments #define TUD_AUDIO10_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, 2, TU_ARGS_APPLY_EXPAND(U16_TO_U8S_LE, __VA_ARGS__), _stridx /* Standard AS Interface Descriptor UAC1 (4.5.1) */ #define TUD_AUDIO10_DESC_STD_AS_LEN 9 #define TUD_AUDIO10_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ TUD_AUDIO10_DESC_STD_AS_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V1, _stridx /* Class-Specific AS Interface Descriptor UAC1 (4.5.2) */ #define TUD_AUDIO10_DESC_CS_AS_INT_LEN 7 #define TUD_AUDIO10_DESC_CS_AS_INT(_termid, _delay, _formattype) \ TUD_AUDIO10_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AS_INTERFACE_AS_GENERAL, _termid, _delay, U16_TO_U8S_LE(_formattype) /* Type I Format Type Descriptor UAC1 (2.2.5) */ #define TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs) (8 + (_nfreqs)*3) // Type I Format descriptor, take list of sample rates in Hz as variable arguments #define TUD_AUDIO10_DESC_TYPE_I_FORMAT(_nrchannels, _subframesize, _bitresolution, ...) \ TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(TU_ARGS_NUM(__VA_ARGS__)), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO10_FORMAT_TYPE_I, _nrchannels, _subframesize, _bitresolution, TU_ARGS_NUM(__VA_ARGS__), TU_ARGS_APPLY_EXPAND(U24_TO_U8S_LE, __VA_ARGS__) /* Standard AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.1) */ #define TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN 9 #define TUD_AUDIO10_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval, _sync_ep) \ TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval, 0x00, _sync_ep /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor UAC1 (4.6.1.2) */ #define TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN 7 #define TUD_AUDIO10_DESC_CS_AS_ISO_EP(_attr, _lockdelayunits, _lockdelay) \ TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO10_CS_EP_SUBTYPE_GENERAL, _attr, _lockdelayunits, U16_TO_U8S_LE(_lockdelay) /* Standard AS Isochronous Synch Endpoint Descriptor UAC1 (4.6.2.1) */ #define TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP_LEN 9 #define TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP(_ep, _bRefresh) \ TUD_AUDIO10_DESC_STD_AS_ISO_SYNC_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_ISOCHRONOUS, U16_TO_U8S_LE(3), 1, _bRefresh, 0x00 /* Standard AC Interrupt Endpoint Descriptor UAC1 (4.4.2) */ #define TUD_AUDIO10_DESC_STD_AC_INT_EP_LEN 9 #define TUD_AUDIO10_DESC_STD_AC_INT_EP(_ep, _interval) \ TUD_AUDIO10_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(2), _interval, 0x00, 0x00 // AUDIO simple descriptor templates for UAC1 // AUDIO simple descriptor (UAC1) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal #define TUD_AUDIO10_MIC_ONE_CH_DESC_LEN(_nfreqs) (\ + TUD_AUDIO10_DESC_STD_AC_LEN\ + TUD_AUDIO10_DESC_CS_AC_LEN(1)\ + TUD_AUDIO10_DESC_INPUT_TERM_LEN\ + TUD_AUDIO10_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1)\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_STD_AS_LEN\ + TUD_AUDIO10_DESC_CS_AS_INT_LEN\ + TUD_AUDIO10_DESC_TYPE_I_FORMAT_LEN(_nfreqs)\ + TUD_AUDIO10_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO10_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO10_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize, ...) \ /* Standard AC Interface Descriptor(4.3.1) */\ TUD_AUDIO10_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.3.2) */\ TUD_AUDIO10_DESC_CS_AC(/*_bcdADC*/ 0x0100, /*_totallen*/ (TUD_AUDIO10_DESC_INPUT_TERM_LEN+TUD_AUDIO10_DESC_OUTPUT_TERM_LEN+TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(1)), /*_itf*/ ((_itfnum)+1)),\ /* Input Terminal Descriptor(4.3.2.1) */\ TUD_AUDIO10_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_nchannels*/ 0x01, /*_channelcfg*/ AUDIO10_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.3.2.2) */\ TUD_AUDIO10_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.3.2.5) */\ TUD_AUDIO10_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlmaster*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME), /*_ctrlch1*/ (AUDIO10_FU_CONTROL_BM_MUTE | AUDIO10_FU_CONTROL_BM_VOLUME)),\ /* Standard AS Interface Descriptor(4.5.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.5.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO10_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.5.2) */\ TUD_AUDIO10_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_delay*/ 0x01, /*_formattype*/ AUDIO10_DATA_FORMAT_TYPE_I_PCM),\ /* Type I Format Type Descriptor(2.2.5) */\ TUD_AUDIO10_DESC_TYPE_I_FORMAT(/*_nrchannels*/ 0x01, /*_subframesize*/ _nBytesPerSample, /*_bitresolution*/ _nBitsUsedPerSample, /*_freq*/ __VA_ARGS__),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.6.1.1) */\ TUD_AUDIO10_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01, /* _sync_ep */ 0x00),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.6.1.2) */\ TUD_AUDIO10_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO10_CS_AS_ISO_DATA_EP_ATT_SAMPLING_FRQ, /*_lockdelayunits*/ AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001) /* Audio v2.0 Descriptor Templates */ /* Standard Interface Association Descriptor (IAD) */ #define TUD_AUDIO20_DESC_IAD_LEN 8 #define TUD_AUDIO20_DESC_IAD(_firstitf, _nitfs, _stridx) \ TUD_AUDIO20_DESC_IAD_LEN, TUSB_DESC_INTERFACE_ASSOCIATION, _firstitf, _nitfs, TUSB_CLASS_AUDIO, AUDIO_FUNCTION_SUBCLASS_UNDEFINED, AUDIO_FUNC_PROTOCOL_CODE_V2, _stridx /* Standard AC Interface Descriptor(4.7.1) */ #define TUD_AUDIO20_DESC_STD_AC_LEN 9 #define TUD_AUDIO20_DESC_STD_AC(_itfnum, _nEPs, _stridx) /* _nEPs is 0 or 1 */\ TUD_AUDIO20_DESC_STD_AC_LEN, TUSB_DESC_INTERFACE, _itfnum, /* fixed to zero */ 0x00, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_INT_PROTOCOL_CODE_V2, _stridx /* Class-Specific AC Interface Header Descriptor(4.7.2) */ #define TUD_AUDIO20_DESC_CS_AC_LEN 9 #define TUD_AUDIO20_DESC_CS_AC(_bcdADC, _category, _totallen, _ctrl) /* _bcdADC : Audio Device Class Specification Release Number in Binary-Coded Decimal, _category : see audio20_function_t, _totallen : Total number of bytes returned for the class-specific AudioControl interface i.e. Clock Source, Unit and Terminal descriptors - Do not include TUD_AUDIO20_DESC_CS_AC_LEN, we already do this here*/ \ TUD_AUDIO20_DESC_CS_AC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_HEADER, U16_TO_U8S_LE(_bcdADC), _category, U16_TO_U8S_LE(_totallen + TUD_AUDIO20_DESC_CS_AC_LEN), _ctrl /* Clock Source Descriptor(4.7.2.1) */ #define TUD_AUDIO20_DESC_CLK_SRC_LEN 8 #define TUD_AUDIO20_DESC_CLK_SRC(_clkid, _attr, _ctrl, _assocTerm, _stridx) \ TUD_AUDIO20_DESC_CLK_SRC_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE, _clkid, _attr, _ctrl, _assocTerm, _stridx /* Input Terminal Descriptor(4.7.2.4) */ #define TUD_AUDIO20_DESC_INPUT_TERM_LEN 17 #define TUD_AUDIO20_DESC_INPUT_TERM(_termid, _termtype, _assocTerm, _clkid, _nchannelslogical, _channelcfg, _idxchannelnames, _ctrl, _stridx) \ TUD_AUDIO20_DESC_INPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _clkid, _nchannelslogical, U32_TO_U8S_LE(_channelcfg), _idxchannelnames, U16_TO_U8S_LE(_ctrl), _stridx /* Output Terminal Descriptor(4.7.2.5) */ #define TUD_AUDIO20_DESC_OUTPUT_TERM_LEN 12 #define TUD_AUDIO20_DESC_OUTPUT_TERM(_termid, _termtype, _assocTerm, _srcid, _clkid, _ctrl, _stridx) \ TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx /* Feature Unit Descriptor(4.7.2.8) */ #define TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(_nchannels) (6 + ((_nchannels) + 1) * 4) #define TUD_AUDIO20_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, TU_ARGS_APPLY_EXPAND(U32_TO_U8S_LE, __VA_ARGS__), _stridx /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */ #define TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN 7 #define TUD_AUDIO20_DESC_STD_AC_INT_EP(_ep, _interval) \ TUD_AUDIO20_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval /* Standard AS Interface Descriptor(4.9.1) */ #define TUD_AUDIO20_DESC_STD_AS_LEN 9 #define TUD_AUDIO20_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ TUD_AUDIO20_DESC_STD_AS_LEN, TUSB_DESC_INTERFACE, _itfnum, _altset, _nEPs, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_STREAMING, AUDIO_INT_PROTOCOL_CODE_V2, _stridx /* Class-Specific AS Interface Descriptor(4.9.2) */ #define TUD_AUDIO20_DESC_CS_AS_INT_LEN 16 #define TUD_AUDIO20_DESC_CS_AS_INT(_termid, _ctrl, _formattype, _formats, _nchannelsphysical, _channelcfg, _stridx) \ TUD_AUDIO20_DESC_CS_AS_INT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_AS_GENERAL, _termid, _ctrl, _formattype, U32_TO_U8S_LE(_formats), _nchannelsphysical, U32_TO_U8S_LE(_channelcfg), _stridx /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ #define TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN 6 #define TUD_AUDIO20_DESC_TYPE_I_FORMAT(_subslotsize, _bitresolution) /* _subslotsize is number of bytes per sample (i.e. subslot) and can be 1,2,3, or 4 */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO20_FORMAT_TYPE_I, _subslotsize, _bitresolution /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ #define TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN 7 #define TUD_AUDIO20_DESC_STD_AS_ISO_EP(_ep, _attr, _maxEPsize, _interval) \ TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN, TUSB_DESC_ENDPOINT, _ep, _attr, U16_TO_U8S_LE(_maxEPsize), _interval /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ #define TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN 8 #define TUD_AUDIO20_DESC_CS_AS_ISO_EP(_attr, _ctrl, _lockdelayunit, _lockdelay) \ TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN, TUSB_DESC_CS_ENDPOINT, AUDIO20_CS_EP_SUBTYPE_GENERAL, _attr, _ctrl, _lockdelayunit, U16_TO_U8S_LE(_lockdelay) /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ #define TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN 7 #define TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(_ep, _epsize, _interval) \ TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(_epsize), _interval // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source #define TUD_AUDIO20_MIC_ONE_CH_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO20_MIC_ONE_CH_DESC_N_AS_INT 1 // Number of AS interfaces #define TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) // AUDIO simple descriptor (UAC2) for 4 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source #define TUD_AUDIO20_MIC_FOUR_CH_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(4)\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) #define TUD_AUDIO20_MIC_FOUR_CH_DESC_N_AS_INT 1 // Number of AS interfaces #define TUD_AUDIO20_MIC_FOUR_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(4), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch3*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch4*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x04, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) // AUDIO simple descriptor (UAC2) for mono speaker // - 1 Input Terminal, 2 Feature Unit (Mute and Volume Control), 3 Output Terminal, 4 Clock Source #define TUD_AUDIO20_SPEAKER_MONO_FB_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN\ + TUD_AUDIO20_DESC_STD_AC_LEN\ + TUD_AUDIO20_DESC_CS_AC_LEN\ + TUD_AUDIO20_DESC_CLK_SRC_LEN\ + TUD_AUDIO20_DESC_INPUT_TERM_LEN\ + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1)\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_STD_AS_LEN\ + TUD_AUDIO20_DESC_CS_AS_INT_LEN\ + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN\ + TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP_LEN) #define TUD_AUDIO20_SPEAKER_MONO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN+TUD_AUDIO20_DESC_INPUT_TERM_LEN+TUD_AUDIO20_DESC_OUTPUT_TERM_LEN+TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(1), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ TUD_AUDIO20_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ 1) // Calculate wMaxPacketSize of Endpoints #define TUD_AUDIO_EP_SIZE(_is_highspeed, _maxFrequency, _nBytesPerSample, _nChannels) \ (((((_maxFrequency) + ((_is_highspeed) ? 7999 : 999)) / ((_is_highspeed) ? 8000 : 1000)) + 1) * (_nBytesPerSample) * (_nChannels)) //--------------------------------------------------------------------+ // USBTMC/USB488 Descriptor Templates //--------------------------------------------------------------------+ #define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) #define TUD_USBTMC_APP_SUBCLASS 0x03u #define TUD_USBTMC_PROTOCOL_STD 0x00u #define TUD_USBTMC_PROTOCOL_USB488 0x01u // Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, // bulk-in endpoint ID #define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ /* Interface */ \ 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx #define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u #define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \ /* Endpoint Out */ \ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \ /* Endpoint In */ \ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u #define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) /* optional interrupt endpoint */ \ // _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? #define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), _int_pollingInterval #define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) //--------------------------------------------------------------------+ // Vendor Descriptor Templates //--------------------------------------------------------------------+ #define TUD_VENDOR_DESC_LEN (9+7+7) // Interface number, string index, EP Out & IN address, EP size #define TUD_VENDOR_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, 0x00, 0x00, _stridx,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // DFU Runtime Descriptor Templates //--------------------------------------------------------------------+ #define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) #define TUD_DFU_APP_SUBCLASS (APP_SUBCLASS_DFU_RUNTIME) // Length of template descriptr: 18 bytes #define TUD_DFU_RT_DESC_LEN (9 + 9) // DFU runtime descriptor // Interface number, string index, attributes, detach timeout, transfer size #define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \ /* Interface */ \ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \ /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110) //--------------------------------------------------------------------+ // DFU Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 9 bytes + number of alternatives * 9 #define TUD_DFU_DESC_LEN(_alt_count) (9 + (_alt_count) * 9) // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size // Note: Alternate count must be numeric or macro, string index is increased by one for each Alt interface #define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \ TU_XSTRCAT(TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \ /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110) #define TUD_DFU_ALT(_itfnum, _alt, _stridx) \ /* Interface */ \ 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx #define TUD_DFU_ALT_1(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx) #define TUD_DFU_ALT_2(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_1(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_3(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_2(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_4(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_3(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_5(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_4(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_6(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_5(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_7(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_6(_itfnum, _alt_count+1, _stridx+1) #define TUD_DFU_ALT_8(_itfnum, _alt_count, _stridx) \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT_7(_itfnum, _alt_count+1, _stridx+1) //--------------------------------------------------------------------+ // CDC-ECM Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor: 71 bytes #define TUD_CDC_ECM_DESC_LEN (8+9+5+5+13+7+9+9+7+7) // CDC-ECM Descriptor Template // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. #define TUD_CDC_ECM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \ /* Interface Association */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL, 0, 0,\ /* CDC Control Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL, 0, _desc_stridx,\ /* CDC-ECM Header */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC-ECM Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* CDC-ECM Functional Descriptor */\ 13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0,\ /* Endpoint Notification */\ 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ /* CDC Data Interface (default inactive) */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ /* CDC Data Interface (alternative active) */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // RNDIS Descriptor Templates //--------------------------------------------------------------------+ #if 0 /* Windows XP */ #define TUD_RNDIS_ITF_CLASS TUSB_CLASS_CDC #define TUD_RNDIS_ITF_SUBCLASS CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL #define TUD_RNDIS_ITF_PROTOCOL 0xFF /* CDC_COMM_PROTOCOL_MICROSOFT_RNDIS */ #else /* Windows 7+ */ #define TUD_RNDIS_ITF_CLASS TUSB_CLASS_WIRELESS_CONTROLLER #define TUD_RNDIS_ITF_SUBCLASS 0x01 #define TUD_RNDIS_ITF_PROTOCOL 0x03 #endif // Length of template descriptor: 66 bytes #define TUD_RNDIS_DESC_LEN (8+9+5+5+4+5+7+9+7+7) // RNDIS Descriptor Template // Interface number, string index, EP notification address and size, EP data address (out, in) and size. #define TUD_RNDIS_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ /* Interface Association */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, 0,\ /* CDC Control Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUD_RNDIS_ITF_CLASS, TUD_RNDIS_ITF_SUBCLASS, TUD_RNDIS_ITF_PROTOCOL, _stridx,\ /* CDC-ACM Header */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\ /* CDC Call Management */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ /* ACM */\ 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 0,\ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ /* CDC Data Interface */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 //--------------------------------------------------------------------+ // Bluetooth Radio Descriptor Templates //--------------------------------------------------------------------+ #define TUD_BT_APP_CLASS (TUSB_CLASS_WIRELESS_CONTROLLER) #define TUD_BT_APP_SUBCLASS 0x01 #define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01 #define TUD_BT_PROTOCOL_AMP_CONTROLLER 0x02 // Length of template descriptor: 38 bytes + number of ISO alternatives * 23 #define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7)) /* Primary Interface */ #define TUD_BTH_PRI_ITF(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size) \ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 3, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, _stridx, \ /* Endpoint In for events */ \ 7, TUSB_DESC_ENDPOINT, _ep_evt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_evt_size), _ep_evt_interval, \ /* Endpoint In for ACL data */ \ 7, TUSB_DESC_ENDPOINT, _ep_in, TUSB_XFER_BULK, U16_TO_U8S_LE(_ep_size), 1, \ /* Endpoint Out for ACL data */ \ 7, TUSB_DESC_ENDPOINT, _ep_out, TUSB_XFER_BULK, U16_TO_U8S_LE(_ep_size), 1 #define TUD_BTH_ISO_ITF(_itfnum, _alt, _ep_in, _ep_out, _n) ,\ /* Interface with 2 endpoints */ \ 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 2, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, 0, \ /* Isochronous endpoints */ \ 7, TUSB_DESC_ENDPOINT, _ep_in, TUSB_XFER_ISOCHRONOUS, U16_TO_U8S_LE(_n), 1, \ 7, TUSB_DESC_ENDPOINT, _ep_out, TUSB_XFER_ISOCHRONOUS, U16_TO_U8S_LE(_n), 1 #define _FIRST(a, ...) a #define _REST(a, ...) __VA_ARGS__ #define TUD_BTH_ISO_ITF_0(_itfnum, ...) #define TUD_BTH_ISO_ITF_1(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 1, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) #define TUD_BTH_ISO_ITF_2(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 2, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ TUD_BTH_ISO_ITF_1(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) #define TUD_BTH_ISO_ITF_3(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 3, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ TUD_BTH_ISO_ITF_2(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) #define TUD_BTH_ISO_ITF_4(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 4, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ TUD_BTH_ISO_ITF_3(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) #define TUD_BTH_ISO_ITF_5(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 5, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ TUD_BTH_ISO_ITF_4(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) #define TUD_BTH_ISO_ITF_6(_itfnum, _ep_in, _ep_out, ...) TUD_BTH_ISO_ITF(_itfnum, (CFG_TUD_BTH_ISO_ALT_COUNT) - 6, _ep_in, _ep_out, _FIRST(__VA_ARGS__)) \ TUD_BTH_ISO_ITF_5(_itfnum, _ep_in, _ep_out, _REST(__VA_ARGS__)) #define TUD_BTH_ISO_ITFS(_itfnum, _ep_in, _ep_out, ...) \ TU_XSTRCAT(TUD_BTH_ISO_ITF_, CFG_TUD_BTH_ISO_ALT_COUNT)(_itfnum, _ep_in, _ep_out, __VA_ARGS__) // BT Primary controller descriptor // Interface number, string index, attributes, event endpoint, event endpoint size, interval, data in, data out, data endpoint size, iso endpoint sizes // TODO BTH should also use IAD like CDC for composite device #define TUD_BTH_DESCRIPTOR(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size,...) \ /* Interface Associate */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUD_BT_APP_CLASS, TUD_BT_APP_SUBCLASS, TUD_BT_PROTOCOL_PRIMARY_CONTROLLER, 0,\ TUD_BTH_PRI_ITF(_itfnum, _stridx, _ep_evt, _ep_evt_size, _ep_evt_interval, _ep_in, _ep_out, _ep_size) \ TUD_BTH_ISO_ITFS(_itfnum + 1, _ep_in + 1, _ep_out + 1, __VA_ARGS__) //--------------------------------------------------------------------+ // CDC-NCM Descriptor Templates //--------------------------------------------------------------------+ // Length of template descriptor #define TUD_CDC_NCM_DESC_LEN (8+9+5+5+13+6+7+9+9+7+7) // CDC-ECM Descriptor Template // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. #define TUD_CDC_NCM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \ /* Interface Association */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, 0,\ /* CDC Control Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_NETWORK_CONTROL_MODEL, 0, _desc_stridx,\ /* CDC-NCM Header */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0110),\ /* CDC-NCM Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* CDC-NCM Functional Descriptor */\ 13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0, \ /* CDC-NCM Functional Descriptor */\ 6, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_NCM, U16_TO_U8S_LE(0x0100), 0, \ /* Endpoint Notification */\ 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 50,\ /* CDC Data Interface (default inactive) */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ /* CDC Data Interface (alternative active) */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK, 0,\ /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 #ifdef __cplusplus } #endif #endif /* TUSB_USBD_H_ */ /** @} */ ================================================ FILE: src/device/usbd_control.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED #include "dcd.h" #include "tusb.h" #include "device/usbd_pvt.h" //--------------------------------------------------------------------+ // Callback weak stubs (called if application does not provide) //--------------------------------------------------------------------+ TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t* request) { (void) rhport; (void) request; } //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ enum { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80 }; typedef struct { tusb_control_request_t request; uint8_t* buffer; uint16_t data_len; uint16_t total_xferred; usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; static usbd_control_xfer_t _ctrl_xfer; CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(buf, CFG_TUD_ENDPOINT0_BUFSIZE); } _ctrl_epbuf; uint8_t* usbd_get_ctrl_buf(void) { return _ctrl_epbuf.buf; } //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Queue ZLP status transaction static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { // Opposite to endpoint in Data Phase const uint8_t ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; return usbd_edpt_xfer(rhport, ep_addr, NULL, 0, false); } // Status phase bool tud_control_status(uint8_t rhport, const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; _ctrl_xfer.data_len = 0; return status_stage_xact(rhport, request); } // Queue a transaction in Data Stage // Each transaction has up to Endpoint0's max packet size. // This function can also transfer an zero-length packet static bool data_stage_xact(uint8_t rhport) { const uint16_t xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_BUFSIZE); uint8_t ep_addr = EDPT_CTRL_OUT; if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) { ep_addr = EDPT_CTRL_IN; if (0u != xact_len && _ctrl_xfer.buffer != _ctrl_epbuf.buf) { TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_BUFSIZE, _ctrl_xfer.buffer, xact_len)); } } return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len, false); } // Transmit data to/from the control endpoint. // If the request's wLength is zero, a status packet is sent instead. bool tud_control_xfer(uint8_t rhport, const tusb_control_request_t* request, void* buffer, uint16_t len) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = (uint8_t*) buffer; _ctrl_xfer.total_xferred = 0U; _ctrl_xfer.data_len = tu_min16(len, request->wLength); if (request->wLength > 0U) { if (_ctrl_xfer.data_len > 0U) { TU_ASSERT(buffer); } TU_ASSERT(data_stage_xact(rhport)); } else { TU_ASSERT(status_stage_xact(rhport, request)); } return true; } //--------------------------------------------------------------------+ // USBD API //--------------------------------------------------------------------+ void usbd_control_reset(void); void usbd_control_set_request(const tusb_control_request_t* request); void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp); bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void usbd_control_reset(void) { tu_varclr(&_ctrl_xfer); } // Set complete callback void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) { _ctrl_xfer.complete_cb = fp; } // for dcd_set_address where DCD is responsible for status response void usbd_control_set_request(const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; _ctrl_xfer.data_len = 0; } // callback when a transaction complete on // - DATA stage of control endpoint or // - Status stage bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; // Endpoint Address is opposite to direction bit, this is Status Stage complete event if (tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction) { TU_ASSERT(0 == xferred_bytes); // invoke optional dcd hook if available dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); if (NULL != _ctrl_xfer.complete_cb) { // TODO refactor with usbd_driver_print_control_complete_name _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request); } return true; } if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) { TU_VERIFY(_ctrl_xfer.buffer); if (_ctrl_xfer.buffer != _ctrl_epbuf.buf) { memcpy(_ctrl_xfer.buffer, _ctrl_epbuf.buf, xferred_bytes); } TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.total_xferred += (uint16_t) xferred_bytes; _ctrl_xfer.buffer += xferred_bytes; // Data Stage is complete when all request's length are transferred or // a short packet is sent including zero-length packet. if ((_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_BUFSIZE)) { // DATA stage is complete bool is_ok = true; // invoke complete callback if set // callback can still stall control in status phase e.g out data does not make sense if (NULL != _ctrl_xfer.complete_cb) { #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb); #endif is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request); } if (is_ok) { TU_ASSERT(status_stage_xact(rhport, &_ctrl_xfer.request)); } else { // Stall both IN and OUT control endpoint dcd_edpt_stall(rhport, EDPT_CTRL_OUT); dcd_edpt_stall(rhport, EDPT_CTRL_IN); } } else { // More data to transfer TU_ASSERT(data_stage_xact(rhport)); } return true; } #endif ================================================ FILE: src/device/usbd_pvt.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_USBD_PVT_H_ #define TUSB_USBD_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" #include "common/tusb_private.h" #ifdef __cplusplus extern "C" { #endif #define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ typedef enum { SOF_CONSUMER_USER = 0, SOF_CONSUMER_AUDIO, } sof_consumer_t; //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ typedef struct { char const* name; void (* init ) (void); bool (* deinit ) (void); void (* reset ) (uint8_t rhport); uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool (* xfer_isr ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); // optional, return false to defer to xfer_cb() void (* sof ) (uint8_t rhport, uint32_t frame_count); // optional } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. // Can be implemented by application to extend/overwrite class driver support. // Note: The drivers array must be accessible at all time when stack is active usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count); typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); void usbd_int_set(bool enabled); void usbd_spin_lock(bool in_isr); void usbd_spin_unlock(bool in_isr); uint8_t* usbd_get_ctrl_buf(void); //--------------------------------------------------------------------+ // USBD Endpoint API // Note: rhport should be 0 since device stack only support 1 rhport for now //--------------------------------------------------------------------+ // Open an endpoint bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); // Close an endpoint void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr); // Submit a usb transfer bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr); // Submit a usb ISO transfer by use of a FIFO (ring buffer) - all bytes in FIFO get transmitted bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr); // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr); // Release claimed endpoint without submitting a transfer bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr); // Check if endpoint is busy transferring bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr); // Stall endpoint void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr); // Clear stalled endpoint void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr); // Check if endpoint is stalled bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr); // Allocate packet buffer used by ISO endpoints bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); // Check if endpoint is ready (not busy and not stalled) TU_ATTR_ALWAYS_INLINE static inline bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { const bool is_busy = usbd_edpt_busy(rhport, ep_addr); const bool is_stalled = usbd_edpt_stalled(rhport, ep_addr); return !is_busy && !is_stalled; } // Enable SOF interrupt void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: src/host/hcd.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HCD_H_ #define TUSB_HCD_H_ #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ // Max number of endpoints pair per device // TODO optimize memory usage #ifndef CFG_TUH_ENDPOINT_MAX #define CFG_TUH_ENDPOINT_MAX 16 // #ifdef TUP_HCD_ENDPOINT_MAX // #define CFG_TUH_ENDPPOINT_MAX TUP_HCD_ENDPOINT_MAX // #else // #define // #endif #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef enum { HCD_EVENT_DEVICE_ATTACH, HCD_EVENT_DEVICE_REMOVE, HCD_EVENT_XFER_COMPLETE, USBH_EVENT_FUNC_CALL, // Not an HCD event HCD_EVENT_INVALID } hcd_eventid_t; typedef struct { uint8_t rhport; uint8_t event_id; uint8_t dev_addr; union { // Attach, Remove struct { uint8_t hub_addr; uint8_t hub_port; } connection; // XFER_COMPLETE struct { uint8_t ep_addr; uint8_t result; uint32_t len; } xfer_complete; // FUNC_CALL struct { void (*func) (void* param); void* param; }func_call; }; } hcd_event_t; //--------------------------------------------------------------------+ // Memory API //--------------------------------------------------------------------+ // clean/flush data cache: write cache -> memory. // Required before an DMA TX transfer to make sure data is in memory bool hcd_dcache_clean(void const* addr, uint32_t data_size); // invalidate data cache: mark cache as invalid, next read will read from memory // Required BOTH before and after an DMA RX transfer bool hcd_dcache_invalidate(void const* addr, uint32_t data_size); // clean and invalidate data cache // Required before an DMA transfer where memory is both read/write by DMA bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size); //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // De-initialize controller bool hcd_deinit(uint8_t rhport); // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr); // Enable USB interrupt void hcd_int_enable (uint8_t rhport); // Disable USB interrupt void hcd_int_disable(uint8_t rhport); // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport); //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport); // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport); // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport); // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport); // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr); //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint // return true if successfully opened or endpoint is currently opened bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc); // Close an endpoint bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr); // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]); // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); //--------------------------------------------------------------------+ // USBH implemented API //--------------------------------------------------------------------+ // Called by HCD to notify stack extern void hcd_event_handler(hcd_event_t const* event, bool in_isr); // Helper to send device attach event TU_ATTR_ALWAYS_INLINE static inline void hcd_event_device_attach(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_ATTACH; event.connection.hub_addr = 0; event.connection.hub_port = 0; hcd_event_handler(&event, in_isr); } // Helper to send device removal event TU_ATTR_ALWAYS_INLINE static inline void hcd_event_device_remove(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_REMOVE; event.connection.hub_addr = 0; event.connection.hub_port = 0; hcd_event_handler(&event, in_isr); } // Helper to send USB transfer event TU_ATTR_ALWAYS_INLINE static inline void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) { hcd_event_t event = { .rhport = 0, // TODO correct rhport .event_id = HCD_EVENT_XFER_COMPLETE, .dev_addr = dev_addr, }; event.xfer_complete.ep_addr = ep_addr; event.xfer_complete.result = result; event.xfer_complete.len = xferred_bytes; hcd_event_handler(&event, in_isr); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/host/hub.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if (CFG_TUH_ENABLED && CFG_TUH_HUB) #include "hcd.h" #include "usbh.h" #include "usbh_pvt.h" #include "hub.h" // Debug level, TUSB_CFG_DEBUG must be at least this level for debug message #define HUB_DEBUG 2 #define TU_LOG_DRV(...) TU_LOG(HUB_DEBUG, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ typedef struct { uint8_t itf_num; uint8_t ep_in; // from hub descriptor uint8_t bNbrPorts; uint8_t bPwrOn2PwrGood_2ms; // port power on to good, in 2ms unit // uint16_t wHubCharacteristics; bool mtt; hub_port_status_response_t port_status; } hub_interface_t; typedef struct { TUH_EPBUF_DEF(status_change, 4); // interrupt endpoint TUH_EPBUF_DEF(ctrl_buf, CFG_TUH_HUB_BUFSIZE); } hub_epbuf_t; static tuh_xfer_cb_t user_complete_cb = NULL; static hub_interface_t hub_itfs[CFG_TUH_HUB]; CFG_TUH_MEM_SECTION static hub_epbuf_t hub_epbufs[CFG_TUH_HUB]; TU_ATTR_ALWAYS_INLINE static inline hub_interface_t* get_hub_itf(uint8_t daddr) { return &hub_itfs[daddr-1-CFG_TUH_DEVICE_MAX]; } TU_ATTR_ALWAYS_INLINE static inline hub_epbuf_t* get_hub_epbuf(uint8_t daddr) { return &hub_epbufs[daddr-1-CFG_TUH_DEVICE_MAX]; } #if CFG_TUSB_DEBUG >= HUB_DEBUG static char const* const _hub_feature_str[] = { [HUB_FEATURE_PORT_CONNECTION ] = "PORT_CONNECTION", [HUB_FEATURE_PORT_ENABLE ] = "PORT_ENABLE", [HUB_FEATURE_PORT_SUSPEND ] = "PORT_SUSPEND", [HUB_FEATURE_PORT_OVER_CURRENT ] = "PORT_OVER_CURRENT", [HUB_FEATURE_PORT_RESET ] = "PORT_RESET", [HUB_FEATURE_PORT_POWER ] = "PORT_POWER", [HUB_FEATURE_PORT_LOW_SPEED ] = "PORT_LOW_SPEED", [HUB_FEATURE_PORT_CONNECTION_CHANGE ] = "PORT_CONNECTION_CHANGE", [HUB_FEATURE_PORT_ENABLE_CHANGE ] = "PORT_ENABLE_CHANGE", [HUB_FEATURE_PORT_SUSPEND_CHANGE ] = "PORT_SUSPEND_CHANGE", [HUB_FEATURE_PORT_OVER_CURRENT_CHANGE ] = "PORT_OVER_CURRENT_CHANGE", [HUB_FEATURE_PORT_RESET_CHANGE ] = "PORT_RESET_CHANGE", [HUB_FEATURE_PORT_TEST ] = "PORT_TEST", [HUB_FEATURE_PORT_INDICATOR ] = "PORT_INDICATOR", }; #endif //--------------------------------------------------------------------+ // HUB //--------------------------------------------------------------------+ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = HUB_REQUEST_CLEAR_FEATURE, .wValue = feature, .wIndex = hub_port, .wLength = 0 }; tuh_xfer_t xfer = { .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; TU_LOG_DRV("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); TU_ASSERT(tuh_control_xfer(&xfer)); return true; } bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT }, .bRequest = HUB_REQUEST_SET_FEATURE, .wValue = feature, .wIndex = hub_port, .wLength = 0 }; tuh_xfer_t xfer = { .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; TU_LOG_DRV("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); TU_ASSERT(tuh_control_xfer(&xfer)); return true; } static void port_get_status_complete (tuh_xfer_t* xfer) { if (xfer->result == XFER_RESULT_SUCCESS) { hub_interface_t* p_hub = get_hub_itf(xfer->daddr); p_hub->port_status = *((const hub_port_status_response_t *) (uintptr_t) xfer->buffer); } xfer->complete_cb = user_complete_cb; user_complete_cb = NULL; if (xfer->complete_cb) { xfer->complete_cb(xfer); } } bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = HUB_REQUEST_GET_STATUS, .wValue = 0, .wIndex = hub_port, .wLength = tu_htole16(4) }; tuh_xfer_t xfer = { .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = resp, .complete_cb = complete_cb, .user_data = user_data }; if (hub_port != 0) { // intercept complete callback to save port status, ignore resp hub_epbuf_t* p_epbuf = get_hub_epbuf(hub_addr); xfer.complete_cb = port_get_status_complete; xfer.buffer = p_epbuf->ctrl_buf; user_complete_cb = complete_cb; } else { user_complete_cb = NULL; } TU_LOG_DRV("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); TU_VERIFY(tuh_control_xfer(&xfer)); return true; } bool hub_port_get_status_local(uint8_t hub_addr, uint8_t hub_port, hub_port_status_response_t* resp) { (void) hub_port; hub_interface_t* p_hub = get_hub_itf(hub_addr); *resp = p_hub->port_status; return true; } //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ bool hub_init(void) { tu_memclr(hub_itfs, sizeof(hub_itfs)); return true; } bool hub_deinit(void) { return true; } uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { (void)rhport; TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && 0 == itf_desc->bInterfaceSubClass, 0); const uint16_t itf_ep_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); uint16_t drv_len = itf_ep_len; TU_ASSERT(drv_len <= max_len, 0); hub_interface_t *p_hub = get_hub_itf(dev_addr); const tusb_desc_interface_t *desc_itf_use = itf_desc; // interface to use for endpoint open // Check device descriptor for MTT hub (bDeviceProtocol == 2) // MTT hub has 2 alt settings: alt 0 is STT (protocol 1), alt 1 is MTT (protocol 2) // Consume both alt settings and use alt setting 1 for endpoint tusb_desc_device_t desc_dev; if (tuh_descriptor_get_device_local(dev_addr, &desc_dev) && desc_dev.bDeviceProtocol == HUB_PROTOCOL_HIGH_SPEED_MTT) { drv_len += itf_ep_len; TU_ASSERT(drv_len <= max_len, 0); const tusb_desc_interface_t *desc_alt1 = (const tusb_desc_interface_t *)((const uint8_t *)itf_desc + itf_ep_len); TU_ASSERT(desc_alt1->bDescriptorType == TUSB_DESC_INTERFACE && desc_alt1->bInterfaceClass == TUSB_CLASS_HUB && desc_alt1->bInterfaceProtocol == HUB_PROTOCOL_HIGH_SPEED_MTT, 0); p_hub->mtt = true; desc_itf_use = desc_alt1; } // Interrupt Status endpoint const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_itf_use); TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep), 0); p_hub->itf_num = itf_desc->bInterfaceNumber; p_hub->ep_in = desc_ep->bEndpointAddress; return drv_len; } void hub_close(uint8_t dev_addr) { TU_VERIFY(dev_addr > CFG_TUH_DEVICE_MAX, ); hub_interface_t* p_hub = get_hub_itf(dev_addr); if (p_hub->ep_in) { TU_LOG_DRV(" HUB close addr = %d\r\n", dev_addr); tu_memclr(p_hub, sizeof( hub_interface_t)); } } bool hub_edpt_status_xfer(uint8_t daddr) { hub_interface_t* p_hub = get_hub_itf(daddr); hub_epbuf_t* p_epbuf = get_hub_epbuf(daddr); TU_VERIFY(usbh_edpt_claim(daddr, p_hub->ep_in)); if (!usbh_edpt_xfer(daddr, p_hub->ep_in, p_epbuf->status_change, 1)) { usbh_edpt_release(daddr, p_hub->ep_in); return false; } return true; } //--------------------------------------------------------------------+ // Set Configure //--------------------------------------------------------------------+ static void config_set_port_power (tuh_xfer_t* xfer); static void config_port_power_complete (tuh_xfer_t* xfer); static void config_get_hub_descriptor(tuh_xfer_t* xfer); bool hub_set_config(uint8_t daddr, uint8_t itf_num) { hub_interface_t* p_hub = get_hub_itf(daddr); TU_ASSERT(itf_num == p_hub->itf_num); if (p_hub->mtt) { // Set Alternate Setting 1 for MTT hub TU_ASSERT(tuh_interface_set(daddr, itf_num, 1, config_get_hub_descriptor, 0)); } else { tuh_xfer_t xfer; xfer.daddr = daddr; xfer.ep_addr = 0; xfer.user_data = 0; config_get_hub_descriptor(&xfer); } return true; } static void config_get_hub_descriptor(tuh_xfer_t* xfer) { // Get Hub Descriptor tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN }, .bRequest = HUB_REQUEST_GET_DESCRIPTOR, .wValue = 0, .wIndex = 0, .wLength = sizeof(hub_desc_cs_t) }; xfer->setup = &request; xfer->buffer = get_hub_epbuf(xfer->daddr)->ctrl_buf; xfer->complete_cb = config_set_port_power; TU_ASSERT(tuh_control_xfer(xfer), ); } static void config_set_port_power (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); uint8_t const daddr = xfer->daddr; hub_interface_t* p_hub = get_hub_itf(daddr); hub_epbuf_t* p_epbuf = get_hub_epbuf(daddr); // only use the number of ports in the hub descriptor hub_desc_cs_t const* desc_hub = (hub_desc_cs_t const*) p_epbuf->ctrl_buf; p_hub->bNbrPorts = desc_hub->bNbrPorts; p_hub->bPwrOn2PwrGood_2ms = desc_hub->bPwrOn2PwrGood; // May need to GET_STATUS // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } static void config_port_power_complete (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); uint8_t const daddr = xfer->daddr; hub_interface_t* p_hub = get_hub_itf(daddr); if (xfer->setup->wIndex == p_hub->bNbrPorts) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION if (!hub_edpt_status_xfer(daddr)) { TU_MESS_FAILED(); TU_BREAKPOINT(); } usbh_driver_set_config_complete(daddr, p_hub->itf_num); } else { // power next port uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } } //--------------------------------------------------------------------+ // Connection Changes //--------------------------------------------------------------------+ enum { STATE_IDLE = 0, STATE_HUB_STATUS, STATE_CLEAR_CHANGE, STATE_CHECK_CONN, STATE_COMPLETE }; static void process_new_status(tuh_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) xferred_bytes; (void) ep_addr; bool processed = false; // true if new status is processed if (result == XFER_RESULT_SUCCESS) { hub_interface_t* p_hub = get_hub_itf(daddr); hub_epbuf_t *p_epbuf = get_hub_epbuf(daddr); const uint8_t status_change = p_epbuf->status_change[0]; TU_LOG_DRV(" Hub Status Change = 0x%02X\r\n", status_change); if (status_change == 0) { // The status change event was neither for the hub, nor for any of its ports. // This shouldn't happen, but it does with some devices. Re-Initiate the interrupt poll. processed = false; } else if (tu_bit_test(status_change, 0)) { // Hub bit 0 is for the hub device events processed = hub_get_status(daddr, p_epbuf->ctrl_buf, process_new_status, STATE_HUB_STATUS); } else { // Hub bits 1 to n are hub port events for (uint8_t port=1; port <= p_hub->bNbrPorts; port++) { if (tu_bit_test(status_change, port)) { processed = hub_port_get_status(daddr, port, NULL, process_new_status, STATE_CLEAR_CHANGE); break; // after completely processed one port, we will re-queue the status poll and handle next one } } } } // If new status event is processed: next status pool is queued by usbh.c after handled this request // Otherwise re-queue the status poll here if (!processed) { TU_ASSERT(hub_edpt_status_xfer(daddr)); } return true; } static void process_new_status(tuh_xfer_t* xfer) { const uint8_t daddr = xfer->daddr; if (xfer->result != XFER_RESULT_SUCCESS) { TU_ASSERT(hub_edpt_status_xfer(daddr),); return; } const uint8_t port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); hub_interface_t *p_hub = get_hub_itf(daddr); const uintptr_t state = xfer->user_data; bool processed = false; // true if new status is processed switch (state) { case STATE_HUB_STATUS: { hub_status_response_t hub_status = *((const hub_status_response_t *) (uintptr_t) xfer->buffer); TU_LOG_DRV("HUB Got hub status, addr = %u, status = %04x\r\n", daddr, hub_status.change.value); if (hub_status.change.local_power_source) { TU_LOG_DRV(" Local Power Change\r\n"); processed = hub_clear_feature(daddr, HUB_FEATURE_HUB_LOCAL_POWER_CHANGE, process_new_status, STATE_COMPLETE); } else if (hub_status.change.over_current) { TU_LOG_DRV(" Over Current\r\n"); processed = hub_clear_feature(daddr, HUB_FEATURE_HUB_OVER_CURRENT_CHANGE, process_new_status, STATE_COMPLETE); } break; } case STATE_CLEAR_CHANGE: // Get port status complete --> clear change if (p_hub->port_status.change.connection) { // Connection change // Port is powered and enabled //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); // Acknowledge Port Connection Change processed = hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, process_new_status, STATE_CHECK_CONN); } else if (p_hub->port_status.change.port_enable) { processed = hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_ENABLE_CHANGE, process_new_status, STATE_COMPLETE); } else if (p_hub->port_status.change.suspend) { processed = hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_SUSPEND_CHANGE, process_new_status, STATE_COMPLETE); } else if (p_hub->port_status.change.over_current) { processed = hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_OVER_CURRENT_CHANGE, process_new_status, STATE_COMPLETE); } else if (p_hub->port_status.change.reset) { processed = hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_RESET_CHANGE, process_new_status, STATE_COMPLETE); } break; case STATE_CHECK_CONN: { const hcd_event_t event = { .rhport = usbh_get_rhport(daddr), .event_id = p_hub->port_status.status.connection ? HCD_EVENT_DEVICE_ATTACH : HCD_EVENT_DEVICE_REMOVE, .connection = { .hub_addr = daddr, .hub_port = port_num } }; hcd_event_handler(&event, false); // skip status for attach event, usbh will do it after handled this enumeration processed = (event.event_id == HCD_EVENT_DEVICE_ATTACH); break; } case STATE_COMPLETE: default: processed = false; // complete this status, queue next status break; } if (!processed) { TU_ASSERT(hub_edpt_status_xfer(daddr),); } } #endif ================================================ FILE: src/host/hub.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HUB_H_ #define TUSB_HUB_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_HUB_BUFSIZE #define CFG_TUH_HUB_BUFSIZE 12 #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ enum { HUB_REQUEST_GET_STATUS = 0 , HUB_REQUEST_CLEAR_FEATURE = 1 , // 2 is reserved HUB_REQUEST_SET_FEATURE = 3 , // 4-5 are reserved HUB_REQUEST_GET_DESCRIPTOR = 6 , HUB_REQUEST_SET_DESCRIPTOR = 7 , HUB_REQUEST_CLEAR_TT_BUFFER = 8 , HUB_REQUEST_RESET_TT = 9 , HUB_REQUEST_GET_TT_STATE = 10 , HUB_REQUEST_STOP_TT = 11 }; enum { HUB_FEATURE_HUB_LOCAL_POWER_CHANGE = 0, HUB_FEATURE_HUB_OVER_CURRENT_CHANGE }; enum{ HUB_FEATURE_PORT_CONNECTION = 0, HUB_FEATURE_PORT_ENABLE = 1, HUB_FEATURE_PORT_SUSPEND = 2, HUB_FEATURE_PORT_OVER_CURRENT = 3, HUB_FEATURE_PORT_RESET = 4, // 5-7 are reserved HUB_FEATURE_PORT_POWER = 8, HUB_FEATURE_PORT_LOW_SPEED = 9, // 10-15 are reserved HUB_FEATURE_PORT_CONNECTION_CHANGE = 16, HUB_FEATURE_PORT_ENABLE_CHANGE = 17, HUB_FEATURE_PORT_SUSPEND_CHANGE = 18, HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19, HUB_FEATURE_PORT_RESET_CHANGE = 20, HUB_FEATURE_PORT_TEST = 21, HUB_FEATURE_PORT_INDICATOR = 22 }; enum { HUB_CHARS_POWER_GANGED_SWITCHING = 0, HUB_CHARS_POWER_INDIVIDUAL_SWITCHING = 1, }; enum { HUB_CHARS_OVER_CURRENT_GLOBAL = 0, HUB_CHARS_OVER_CURRENT_INDIVIDUAL = 1, }; // Hub Interface Protocol (USB 2.0 spec Table 11-16) typedef enum { HUB_PROTOCOL_FULL_SPEED = 0, // Full speed hub HUB_PROTOCOL_HIGH_SPEED_STT = 1, // Hi-speed hub with single TT HUB_PROTOCOL_HIGH_SPEED_MTT = 2, // Hi-speed hub with multiple TTs } hub_protocol_t; typedef struct TU_ATTR_PACKED{ uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint8_t bNbrPorts; uint16_t wHubCharacteristics; uint8_t bPwrOn2PwrGood; uint8_t bHubContrCurrent; uint8_t DeviceRemovable; // bitmap each bit for a port (from bit1) uint8_t PortPwrCtrlMask; // just for compatibility, should be 0xff } hub_desc_cs_t; TU_VERIFY_STATIC(sizeof(hub_desc_cs_t) == 9, "size is not correct"); TU_VERIFY_STATIC(CFG_TUH_HUB_BUFSIZE >= sizeof(hub_desc_cs_t), "buffer is not big enough"); typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED { uint8_t logical_power_switching_mode : 2; // [0..1] gannged or individual power switching uint8_t compound_device : 1; // [2] hub is part of compound device uint8_t over_current_protect_mode : 2; // [3..4] global or individual port over-current protection uint8_t tt_think_time : 2; // [5..6] TT think time uint8_t port_indicator_supported : 1; // [7] port indicator supported }; uint8_t rsv1; } hub_characteristics_t; TU_VERIFY_STATIC(sizeof(hub_characteristics_t) == 2, "size is not correct"); // data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub) typedef struct { union{ struct TU_ATTR_PACKED { uint16_t local_power_source : 1; uint16_t over_current : 1; uint16_t : 14; }; uint16_t value; } status, change; } hub_status_response_t; TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct"); // data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num typedef struct { union TU_ATTR_PACKED { struct TU_ATTR_PACKED { // Bit 0-4 are for change & status uint16_t connection : 1; // [0] 0 = no device, 1 = device connected uint16_t port_enable : 1; // [1] port is enabled uint16_t suspend : 1; // [2] uint16_t over_current : 1; // [3] over-current exists uint16_t reset : 1; // [4] 0 = no reset, 1 = resetting // From Bit 5 are for status only uint16_t rsv5_7 : 3; // [5..7] reserved uint16_t port_power : 1; // [8] 0 = port is off, 1 = port is on uint16_t low_speed : 1; // [9] low speed device attached uint16_t high_speed : 1; // [10] high speed device attached uint16_t port_test_mode : 1; // [11] port in test mode uint16_t port_indicator_control : 1; // [12] 0: default color, 1: indicator is software controlled uint16_t TU_RESERVED : 3; // [13..15] reserved }; uint16_t value; } status, change; } hub_port_status_response_t; TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); //--------------------------------------------------------------------+ // HUB API //--------------------------------------------------------------------+ // Clear port feature bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Set port feature bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get port status // If hub_port != 0, resp is ignored. hub_port_get_status_local() can be used to retrieve the status bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void *resp, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get port status from local cache. This does not send a request to the device bool hub_port_get_status_local(uint8_t hub_addr, uint8_t hub_port, hub_port_status_response_t* resp); // Get status from Interrupt endpoint bool hub_edpt_status_xfer(uint8_t daddr); // Reset a port TU_ATTR_ALWAYS_INLINE static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); } // Clear Port Reset Change TU_ATTR_ALWAYS_INLINE static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); } // Get Hub status (port = 0) TU_ATTR_ALWAYS_INLINE static inline bool hub_get_status(uint8_t hub_addr, void* resp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_get_status(hub_addr, 0, resp, complete_cb, user_data); } // Clear Hub feature TU_ATTR_ALWAYS_INLINE static inline bool hub_clear_feature(uint8_t hub_addr, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_clear_feature(hub_addr, 0, feature, complete_cb, user_data); } //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ bool hub_init(void); bool hub_deinit(void); uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool hub_set_config(uint8_t daddr, uint8_t itf_num); bool hub_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); void hub_close(uint8_t dev_addr); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/host/usbh.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED #include "hcd.h" #include "tusb.h" #include "usbh_pvt.h" #include "hub.h" //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_TASK_QUEUE_SZ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif #ifndef CFG_TUH_INTERFACE_MAX #define CFG_TUH_INTERFACE_MAX 8 #endif enum { USBH_CONTROL_RETRY_MAX = 3, }; //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { (void) rhport; return false; } TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; (void) cfg_id; (void) cfg_param; return false; } TU_ATTR_WEAK void tuh_enum_descriptor_device_cb(uint8_t daddr, const tusb_desc_device_t *desc_device) { (void) daddr; (void) desc_device; } TU_ATTR_WEAK bool tuh_enum_descriptor_configuration_cb(uint8_t daddr, uint8_t cfg_index, const tusb_desc_configuration_t *desc_config) { (void) daddr; (void) cfg_index; (void) desc_config; return true; } TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; (void) in_isr; } TU_ATTR_WEAK bool hcd_dcache_clean(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return false; } TU_ATTR_WEAK bool hcd_dcache_invalidate(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return false; } TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { (void) addr; (void) data_size; return false; } TU_ATTR_WEAK usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) { *driver_count = 0; return NULL; } TU_ATTR_WEAK void tuh_mount_cb(uint8_t daddr) { (void) daddr; } TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr) { (void) daddr; } //--------------------------------------------------------------------+ // Data Structure //--------------------------------------------------------------------+ // Device Descriptor (without bLength and bDescriptorType header) typedef struct TU_ATTR_PACKED { uint16_t bcdUSB; uint8_t bDeviceClass; uint8_t bDeviceSubClass; uint8_t bDeviceProtocol; uint8_t bMaxPacketSize0; uint16_t idVendor; uint16_t idProduct; uint16_t bcdDevice; uint8_t iManufacturer; uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; } desc_device_noheader_t; TU_VERIFY_STATIC( sizeof(desc_device_noheader_t) == 16u, "size is not correct"); typedef struct { tuh_bus_info_t bus_info; desc_device_noheader_t desc_device; // Device State struct TU_ATTR_PACKED { volatile uint8_t connected : 1; // After 1st transfer volatile uint8_t addressed : 1; // After SET_ADDR volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured volatile uint8_t suspended : 1; // Bus suspended // volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh }; // Endpoint & Interface uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUH_ENDPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; #if CFG_TUH_API_EDPT_XFER // TODO array can be CFG_TUH_ENDPOINT_MAX-1 struct { tuh_xfer_cb_t complete_cb; uintptr_t user_data; }ep_callback[CFG_TUH_ENDPOINT_MAX][2]; #endif } usbh_device_t; // sum of end device + hub #define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) // all devices excluding zero-address // hub address start from CFG_TUH_DEVICE_MAX+1 // TODO: hub can has its own simpler struct to save memory static usbh_device_t _usbh_devices[TOTAL_DEVICES]; // Mutex for claiming endpoint #if OSAL_MUTEX_REQUIRED static osal_mutex_def_t _usbh_mutexdef; static osal_mutex_t _usbh_mutex; #else #define _usbh_mutex NULL #endif // Spinlock for interrupt handler static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set); // Event queue: usbh_int_set() is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; #if CFG_TUH_HUB // Deferred attachment queue, only needed when using hub OSAL_QUEUE_DEF(usbh_int_set, _usbh_daqdef, CFG_TUH_HUB, hcd_event_t); static osal_queue_t _usbh_daq; #endif // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. typedef struct { uint8_t* buffer; tuh_xfer_cb_t complete_cb; uintptr_t user_data; volatile uint8_t stage; uint8_t daddr; volatile uint16_t actual_len; uint8_t failed_count; } usbh_ctrl_xfer_info_t; typedef struct { tusb_defer_func_t func; uintptr_t arg; uint32_t at_ms; } usbh_call_after_t; typedef struct { uint8_t controller_id; // controller ID uint8_t enumerating_daddr; // device address of the device being enumerated uint8_t attach_debouncing_bm; // bitmask for roothub port attach debouncing tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer usbh_call_after_t call_after; } usbh_data_t; static usbh_data_t _usbh_data = { .controller_id = TUSB_INDEX_INVALID_8, }; typedef struct { TUH_EPBUF_TYPE_DEF(tusb_control_request_t, request); TUH_EPBUF_DEF(ctrl, CFG_TUH_ENUMERATION_BUFSIZE); } usbh_epbuf_t; CFG_TUH_MEM_SECTION static usbh_epbuf_t _usbh_epbuf; //--------------------------------------------------------------------+ // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL #define DRIVER_NAME(_name) _name #else #define DRIVER_NAME(_name) NULL #endif static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_CDC { .name = DRIVER_NAME("CDC"), .init = cdch_init, .deinit = cdch_deinit, .open = cdch_open, .set_config = cdch_set_config, .xfer_cb = cdch_xfer_cb, .close = cdch_close }, #endif #if CFG_TUH_MSC { .name = DRIVER_NAME("MSC"), .init = msch_init, .deinit = msch_deinit, .open = msch_open, .set_config = msch_set_config, .xfer_cb = msch_xfer_cb, .close = msch_close }, #endif #if CFG_TUH_HID { .name = DRIVER_NAME("HID"), .init = hidh_init, .deinit = hidh_deinit, .open = hidh_open, .set_config = hidh_set_config, .xfer_cb = hidh_xfer_cb, .close = hidh_close }, #endif #if CFG_TUH_MIDI { .name = DRIVER_NAME("MIDI"), .init = midih_init, .deinit = midih_deinit, .open = midih_open, .set_config = midih_set_config, .xfer_cb = midih_xfer_cb, .close = midih_close }, #endif #if CFG_TUH_HUB { .name = DRIVER_NAME("HUB"), .init = hub_init, .deinit = hub_deinit, .open = hub_open, .set_config = hub_set_config, .xfer_cb = hub_xfer_cb, .close = hub_close }, #endif #if CFG_TUH_VENDOR { .name = DRIVER_NAME("VENDOR"), .init = cush_init, .deinit = cush_deinit, .open = cush_open, .set_config = cush_set_config, .xfer_cb = cush_isr, .close = cush_close } #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; // Additional class drivers implemented by application static usbh_class_driver_t const * _app_driver = NULL; static uint8_t _app_driver_count = 0; #define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. TU_ATTR_ALWAYS_INLINE static inline usbh_class_driver_t const *get_driver(uint8_t drv_id) { usbh_class_driver_t const *driver = NULL; if (drv_id < _app_driver_count) { driver = &_app_driver[drv_id]; } else { drv_id -= _app_driver_count; if (drv_id < BUILTIN_DRIVER_COUNT) { driver = &usbh_class_drivers[drv_id]; } } return driver; } //--------------------------------------------------------------------+ // Function Inline and Prototypes //--------------------------------------------------------------------+ static void enum_new_device(hcd_event_t* event); static void enum_delay_async(uintptr_t state); static void process_remove_event(hcd_event_t *event); static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); return &_usbh_devices[dev_addr-1]; } TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); //-V560 } TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { TU_ASSERT(osal_queue_send(_usbh_q, event, in_isr)); tuh_event_hook_cb(event->rhport, event->event_id, in_isr); return true; } TU_ATTR_ALWAYS_INLINE static inline void _control_set_xfer_stage(uint8_t stage) { if (_usbh_data.ctrl_xfer_info.stage != stage) { (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _usbh_data.ctrl_xfer_info.stage = stage; (void) osal_mutex_unlock(_usbh_mutex); } } TU_ATTR_ALWAYS_INLINE static inline bool usbh_setup_send(uint8_t daddr, const uint8_t setup_packet[8]) { const uint8_t rhport = usbh_get_rhport(daddr); const bool ret = hcd_setup_send(rhport, daddr, setup_packet); if (!ret) { _control_set_xfer_stage(CONTROL_STAGE_IDLE); } return ret; } bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param) { TU_ASSERT(_usbh_data.call_after.func == NULL); TU_LOG_USBH("USBH schedule function after %u ms\r\n", (unsigned int)ms); _usbh_data.call_after.func = func; _usbh_data.call_after.arg = param; _usbh_data.call_after.at_ms = tusb_time_millis_api() + ms; return true; } TU_ATTR_ALWAYS_INLINE static inline void usbh_device_close(uint8_t rhport, uint8_t daddr) { hcd_device_close(rhport, daddr); // abort any ongoing control transfer if (daddr == _usbh_data.ctrl_xfer_info.daddr) { _control_set_xfer_stage(CONTROL_STAGE_IDLE); } // invalidate if enumerating if (daddr == _usbh_data.enumerating_daddr) { _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // clear enum delay function of the device being removed if (_usbh_data.call_after.func == enum_delay_async) { _usbh_data.call_after.func = NULL; } } } //--------------------------------------------------------------------+ // Device API //--------------------------------------------------------------------+ bool tuh_mounted(uint8_t dev_addr) { usbh_device_t *dev = get_device(dev_addr); TU_VERIFY(dev); return dev->configured; } bool tuh_connected(uint8_t daddr) { if (daddr == 0) { return _usbh_data.enumerating_daddr == 0; } else { const usbh_device_t* dev = get_device(daddr); TU_VERIFY(dev != NULL); return dev->connected; } } bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = *pid = 0; usbh_device_t const *dev = get_device(dev_addr); TU_VERIFY(dev && dev->addressed && dev->desc_device.idVendor != 0); *vid = dev->desc_device.idVendor; *pid = dev->desc_device.idProduct; return true; } bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device) { usbh_device_t *dev = get_device(daddr); TU_VERIFY(dev && desc_device); desc_device->bLength = sizeof(tusb_desc_device_t); desc_device->bDescriptorType = TUSB_DESC_DEVICE; memcpy((uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), &dev->desc_device, sizeof(desc_device_noheader_t)); return true; } tusb_speed_t tuh_speed_get(uint8_t daddr) { tuh_bus_info_t bus_info; tuh_bus_info_get(daddr, &bus_info); return (tusb_speed_t)bus_info.speed; } bool tuh_rhport_is_active(uint8_t rhport) { return _usbh_data.controller_id == rhport; } bool tuh_rhport_reset_bus(uint8_t rhport, bool active) { TU_VERIFY(tuh_rhport_is_active(rhport)); if (active) { hcd_port_reset(rhport); } else { hcd_port_reset_end(rhport); } return true; } //--------------------------------------------------------------------+ // PUBLIC API (Parameter Verification is required) //--------------------------------------------------------------------+ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { return hcd_configure(rhport, cfg_id, cfg_param); } static void clear_device(usbh_device_t* dev) { tu_memclr(dev, sizeof(usbh_device_t)); (void) memset(dev->itf2drv, TUSB_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping (void) memset(dev->ep2drv , TUSB_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping } bool tuh_inited(void) { return _usbh_data.controller_id != TUSB_INDEX_INVALID_8; } bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { if (tuh_rhport_is_active(rhport)) { return true; // skip if already initialized } #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL char const* speed_str = 0; switch (rh_init->speed) { case TUSB_SPEED_HIGH: speed_str = "High"; break; case TUSB_SPEED_FULL: speed_str = "Full"; break; case TUSB_SPEED_LOW: speed_str = "Low"; break; case TUSB_SPEED_AUTO: speed_str = "Auto"; break; default: break; } TU_LOG_USBH("USBH init on controller %u, speed = %s\r\n", rhport, speed_str); #endif // Init host stack if not already if (!tuh_inited()) { TU_LOG_INT_USBH(sizeof(usbh_data_t)); TU_LOG_INT_USBH(sizeof(usbh_device_t)); TU_LOG_INT_USBH(sizeof(hcd_event_t)); TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); TU_LOG_INT_USBH(sizeof(tu_fifo_t)); TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); osal_spin_init(&_usbh_spin); // Event queue _usbh_q = osal_queue_create(&_usbh_qdef); TU_ASSERT(_usbh_q != NULL); #if CFG_TUH_HUB // Deferred attachment queue _usbh_daq = osal_queue_create(&_usbh_daqdef); TU_ASSERT(_usbh_daq != NULL); #endif #if OSAL_MUTEX_REQUIRED // Init mutex _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); TU_ASSERT(_usbh_mutex); #endif // Get application driver if available _app_driver = usbh_app_driver_get_cb(&_app_driver_count); // Device tu_memclr(_usbh_devices, sizeof(_usbh_devices)); tu_memclr(&_usbh_data, sizeof(_usbh_data)); _usbh_data.controller_id = TUSB_INDEX_INVALID_8; _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; for (uint8_t i = 0; i < TOTAL_DEVICES; i++) { clear_device(&_usbh_devices[i]); } // Class drivers for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); if (driver != NULL) { TU_LOG_USBH("%s init\r\n", driver->name); driver->init(); } } } // Init host controller _usbh_data.controller_id = rhport; TU_ASSERT(hcd_init(rhport, rh_init)); hcd_int_enable(rhport); return true; } bool tuh_deinit(uint8_t rhport) { if (!tuh_rhport_is_active(rhport)) { return true; } // deinit host controller hcd_int_disable(rhport); TU_ASSERT(hcd_deinit(rhport)); _usbh_data.controller_id = TUSB_INDEX_INVALID_8; // remove all devices on this rhport (hub_addr = 0, hub_port = 0) remove_device_tree(rhport, 0, 0); // deinit host stack if no controller is active if (!tuh_inited()) { // Class drivers for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); if (driver && driver->deinit) { TU_LOG_USBH("%s deinit\r\n", driver->name); driver->deinit(); } } osal_queue_delete(_usbh_q); _usbh_q = NULL; #if CFG_TUH_HUB osal_queue_delete(_usbh_daq); _usbh_daq = NULL; #endif #if OSAL_MUTEX_REQUIRED // TODO make sure there is no task waiting on this mutex osal_mutex_delete(_usbh_mutex); _usbh_mutex = NULL; #endif } return true; } bool tuh_task_event_ready(void) { if (!tuh_inited()) { return false; // Skip if tusb stack is not initialized } if (!osal_queue_empty(_usbh_q)) { return true; } #if CFG_TUH_HUB if (!osal_queue_empty(_usbh_daq)) { return true; } #endif return false; } /* USB Host Driver task * This top level thread manages all host controller event and delegates events to class-specific drivers. * This should be called periodically within the mainloop or rtos thread. * @code int main(void) { application_init(); tusb_init(0, TUSB_ROLE_HOST); while(1) { // the mainloop application_code(); tuh_task(); // tinyusb host task } } @endcode */ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Skip if stack is not initialized if (!tuh_inited()) { return; } (void) in_isr; // not implemented yet // Loop until there are no more events in the queue or CFG_TUH_TASK_EVENTS_PER_RUN is reached for (unsigned epr = 0;; epr++) { #if CFG_TUH_TASK_EVENTS_PER_RUN > 0 if (epr >= CFG_TUH_TASK_EVENTS_PER_RUN) { TU_LOG_USBH("USBH event limit (" TU_XSTRING(CFG_TUH_TASK_EVENTS_PER_RUN) ") reached\r\n"); break; } #endif // Process call_after_ms function if ms is reached tusb_defer_func_t after_cb = _usbh_data.call_after.func; if (after_cb) { int32_t remain_ms = (int32_t)(_usbh_data.call_after.at_ms - tusb_time_millis_api()); if (remain_ms <= 0) { // delay expired, run callback now TU_LOG_USBH("USBH invoke scheduled function\r\n"); _usbh_data.call_after.func = NULL; after_cb(_usbh_data.call_after.arg); } // above after_cb() can re-schedule another function, we need to re-check and reduce timeout of // the main event timeout to make sure we aren't blocking more than call_after remaining ms. if (_usbh_data.call_after.func != NULL) { remain_ms = (int32_t) (_usbh_data.call_after.at_ms - tusb_time_millis_api()); if (remain_ms <= 0) { timeout_ms = 0; // expired already } else if (timeout_ms > (uint32_t)remain_ms) { timeout_ms = (uint32_t)remain_ms; } } } hcd_event_t event; #if CFG_TUH_HUB // Get deferred device attachments if none is enumerating bool has_deferred_attach = false; if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { // zero wait to avoid blocking the main event queue has_deferred_attach = osal_queue_receive(_usbh_daq, &event, 0); } if (!has_deferred_attach) // skip event queue to process deferred attach #endif { if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) { return; } } switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: // Should we miss the hub detach event due to high traffic, Or due to physical debouncing, some devices can // cause multiple attaches (actually reset) without a detached event. // Force remove currently mounted with the same bus info (rhport, hub addr, hub port) if exists process_remove_event(&event); // due to the shared control buffer, we must fully complete enumerating one device first. if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) { // New device attached and we are ready TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport); _usbh_data.enumerating_daddr = 0; // enumerate new device with address 0 enum_new_device(&event); } #if CFG_TUH_HUB else { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); TU_ASSERT(osal_queue_send(_usbh_daq, &event, in_isr), ); } #endif break; case HCD_EVENT_DEVICE_REMOVE: TU_LOG_USBH("[%u:%u:%u] USBH Device Removed\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); process_remove_event(&event); break; case HCD_EVENT_XFER_COMPLETE: { uint8_t const ep_addr = event.xfer_complete.ep_addr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); TU_LOG_USBH("[:%u] on EP %02X with %u bytes: %s\r\n", event.dev_addr, ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]); if (event.dev_addr == 0) { // device 0 only has control endpoint TU_ASSERT(epnum == 0,); usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { usbh_device_t* dev = get_device(event.dev_addr); TU_VERIFY(dev && dev->connected,); dev->ep_status[epnum][ep_dir].busy = 0; dev->ep_status[epnum][ep_dir].claimed = 0; if (0 == epnum) { usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { // Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used // with enabled driver e.g HID endpoint #if CFG_TUH_API_EDPT_XFER tuh_xfer_cb_t const complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb; if (complete_cb != NULL) { // re-construct xfer info tuh_xfer_t xfer = { .daddr = event.dev_addr, .ep_addr = ep_addr, .result = (xfer_result_t)event.xfer_complete.result, .actual_len = event.xfer_complete.len, .buflen = 0, // not available .buffer = NULL, // not available .complete_cb = complete_cb, .user_data = dev->ep_callback[epnum][ep_dir].user_data }; complete_cb(&xfer); }else #endif { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; usbh_class_driver_t const* driver = get_driver(drv_id); if (driver != NULL) { TU_LOG_USBH(" %s xfer callback\r\n", driver->name); driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { // no driver/callback responsible for this transfer TU_ASSERT(false,); } } } } break; } case USBH_EVENT_FUNC_CALL: if (event.func_call.func != NULL) { event.func_call.func(event.func_call.param); } break; default: // unknown event break; } // allow to exit tuh_task() if there is no event in the next run timeout_ms = 0; } } //--------------------------------------------------------------------+ // Control transfer //--------------------------------------------------------------------+ static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } // TODO timeout_ms is not supported yet bool tuh_control_xfer (tuh_xfer_t* xfer) { TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); // EP0 with setup packet const uint8_t daddr = xfer->daddr; TU_VERIFY(tuh_connected(daddr)); usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info; TU_VERIFY(ctrl_info->stage == CONTROL_STAGE_IDLE); // pre-check to help reducing mutex lock (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); bool const is_idle = (ctrl_info->stage == CONTROL_STAGE_IDLE); if (is_idle) { ctrl_info->stage = CONTROL_STAGE_SETUP; ctrl_info->daddr = daddr; ctrl_info->actual_len = 0; ctrl_info->failed_count = 0; ctrl_info->buffer = xfer->buffer; ctrl_info->complete_cb = xfer->complete_cb; ctrl_info->user_data = xfer->user_data; _usbh_epbuf.request = (*xfer->setup); } (void) osal_mutex_unlock(_usbh_mutex); TU_VERIFY(is_idle); TU_LOG_USBH("[%u:%u] %s: ", usbh_get_rhport(daddr), daddr, (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); TU_LOG_BUF_USBH(xfer->setup, 8); if (xfer->complete_cb != NULL) { TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) &_usbh_epbuf.request)); }else { // blocking if complete callback is not provided // change callback to internal blocking, and result as user argument volatile xfer_result_t result = XFER_RESULT_INVALID; // use user_data to point to xfer_result_t ctrl_info->user_data = (uintptr_t) &result; ctrl_info->complete_cb = _control_blocking_complete_cb; TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) &_usbh_epbuf.request)); while (result == XFER_RESULT_INVALID) { // Note: this can be called within an callback ie. part of tuh_task() // therefore even with RTOS tuh_task_ext() still need to be invoked tuh_task_ext(0, false); // TODO probably some timeout to prevent hanged } // update transfer result, user_data is expected to point to xfer_result_t if (xfer->user_data != 0) { *((xfer_result_t*) xfer->user_data) = result; } xfer->result = result; xfer->actual_len = ctrl_info->actual_len; } return true; } static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info; // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _usbh_epbuf.request; tuh_xfer_t xfer_temp = { .daddr = daddr, .ep_addr = 0, .result = result, .setup = &request, .actual_len = (uint32_t) ctrl_info->actual_len, .buffer = ctrl_info->buffer, .complete_cb = ctrl_info->complete_cb, .user_data = ctrl_info->user_data }; _control_set_xfer_stage(CONTROL_STAGE_IDLE); if (xfer_temp.complete_cb != NULL) { xfer_temp.complete_cb(&xfer_temp); } } static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; const uint8_t rhport = usbh_get_rhport(daddr); tusb_control_request_t const * request = &_usbh_epbuf.request; usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info; switch (result) { case XFER_RESULT_STALLED: TU_LOG_USBH("[%u:%u] Control STALLED, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, xferred_bytes); TU_LOG_BUF_USBH(request, 8); _control_xfer_complete(daddr, result); break; case XFER_RESULT_FAILED: if (tuh_connected(daddr) && ctrl_info->failed_count < USBH_CONTROL_RETRY_MAX) { TU_LOG_USBH("[%u:%u] Control FAILED %u/%u, retrying\r\n", rhport, daddr, ctrl_info->failed_count+1, USBH_CONTROL_RETRY_MAX); (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); ctrl_info->stage = CONTROL_STAGE_SETUP; ctrl_info->failed_count++; ctrl_info->actual_len = 0; // reset actual_len (void) osal_mutex_unlock(_usbh_mutex); TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) request)); } else { TU_LOG_USBH("[%u:%u] Control FAILED, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, xferred_bytes); TU_LOG_BUF_USBH(request, 8); _control_xfer_complete(daddr, result); } break; case XFER_RESULT_SUCCESS: switch(ctrl_info->stage) { case CONTROL_STAGE_SETUP: if (request->wLength > 0) { // DATA stage: initial data toggle is always 1 _control_set_xfer_stage(CONTROL_STAGE_DATA); const uint8_t ep_data = tu_edpt_addr(0, request->bmRequestType_bit.direction); TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_data, ctrl_info->buffer, request->wLength)); return true; } TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: { if (request->wLength > 0) { TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2); } ctrl_info->actual_len = (uint16_t) xferred_bytes; // ACK stage: toggle is always 1 _control_set_xfer_stage(CONTROL_STAGE_ACK); const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction); TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0)); break; } case CONTROL_STAGE_ACK: { // Abort all pending transfers if SET_CONFIGURATION request // NOTE: should we force closing all non-control endpoints in the future? if (request->bRequest == TUSB_REQ_SET_CONFIGURATION && request->bmRequestType == 0x00) { for(uint8_t epnum=1; epnumdaddr; uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data)) { usbh_edpt_release(daddr, ep_addr); return false; } return true; } bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr); const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); if (epnum == 0) { // Also include dev0 for aborting enumerating const uint8_t rhport = usbh_get_rhport(daddr); // control transfer: only 1 control at a time, check if we are aborting the current one const usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info; TU_VERIFY(daddr == ctrl_info->daddr && ctrl_info->stage != CONTROL_STAGE_IDLE); hcd_edpt_abort_xfer(rhport, daddr, ep_addr); _control_set_xfer_stage(CONTROL_STAGE_IDLE); // reset control transfer state to idle } else { usbh_device_t* dev = get_device(daddr); TU_VERIFY(dev); TU_VERIFY(dev->ep_status[epnum][dir].busy); // non-control skip if not busy // abort then mark as ready and release endpoint hcd_edpt_abort_xfer(dev->bus_info.rhport, daddr, ep_addr); dev->ep_status[epnum][dir].busy = false; tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); } return true; } //--------------------------------------------------------------------+ // USBH API For Class Driver //--------------------------------------------------------------------+ uint8_t usbh_get_rhport(uint8_t daddr) { tuh_bus_info_t bus_info; tuh_bus_info_get(daddr, &bus_info); return bus_info.rhport; } uint8_t *usbh_get_enum_buf(void) { return _usbh_epbuf.ctrl; } void usbh_int_set(bool enabled) { // TODO all host controller if multiple are used since they shared the same event queue if (enabled) { hcd_int_enable(_usbh_data.controller_id); } else { hcd_int_disable(_usbh_data.controller_id); } } void usbh_spin_lock(bool in_isr) { osal_spin_lock(&_usbh_spin, in_isr); } void usbh_spin_unlock(bool in_isr) { osal_spin_unlock(&_usbh_spin, in_isr); } void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { hcd_event_t event = { 0 }; event.event_id = USBH_EVENT_FUNC_CALL; event.func_call.func = func; event.func_call.param = param; queue_event(&event, in_isr); } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Claim an endpoint for transfer bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_ASSERT(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Claimed EP 0x%02x\r\n", dev_addr, ep_addr); return true; } // Release an claimed endpoint due to failed transfer attempt bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Released EP 0x%02x\r\n", dev_addr, ep_addr); return true; } // Submit an transfer bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { (void) complete_cb; (void) user_data; usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; TU_LOG_USBH(" Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(ep_state->busy == 0); // Set busy first since the actual transfer can be complete before hcd_edpt_xfer() // could return and USBH task can preempt and clear the busy ep_state->busy = 1; #if CFG_TUH_API_EDPT_XFER dev->ep_callback[epnum][dir].complete_cb = complete_cb; dev->ep_callback[epnum][dir].user_data = user_data; #endif if (hcd_edpt_xfer(dev->bus_info.rhport, dev_addr, ep_addr, buffer, total_bytes)) { TU_LOG_USBH("OK\r\n"); return true; } else { // HCD error, mark endpoint as ready to allow next transfer ep_state->busy = 0; ep_state->claimed = 0; TU_LOG1("Failed\r\n"); // TU_BREAKPOINT(); return false; } } static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, .wMaxPacketSize = max_packet_size, .bInterval = 0 }; return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) { // HACK: some device incorrectly always reports 512 bulk regardless of link speed, overwrite descriptor to force 64 if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 && tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) { TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n"); tusb_desc_endpoint_t *hacked_ep = (tusb_desc_endpoint_t *)(uintptr_t)desc_ep; hacked_ep->wMaxPacketSize = tu_htole16(64); } TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr))); return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep); } bool tuh_edpt_close(uint8_t daddr, uint8_t ep_addr) { TU_VERIFY(0 != tu_edpt_number(ep_addr)); // cannot close EP0 tuh_edpt_abort_xfer(daddr, ep_addr); // abort any pending transfer return hcd_edpt_close(usbh_get_rhport(daddr), daddr, ep_addr); } bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); return dev->ep_status[epnum][dir].busy; } //--------------------------------------------------------------------+ // HCD Event Handler //--------------------------------------------------------------------+ bool tuh_bus_info_get(uint8_t daddr, tuh_bus_info_t* bus_info) { usbh_device_t const* dev = get_device(daddr); if (dev != NULL) { *bus_info = dev->bus_info; } else { *bus_info = _usbh_data.dev0_bus; } return true; } TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) { switch (event->event_id) { case HCD_EVENT_DEVICE_ATTACH: case HCD_EVENT_DEVICE_REMOVE: // Attach debouncing on roothub: skip attach/remove while debouncing delay if (event->connection.hub_addr == 0) { if (tu_bit_test(_usbh_data.attach_debouncing_bm, event->rhport)) { return; } if (event->event_id == HCD_EVENT_DEVICE_ATTACH) { // No debouncing, set flag if attach event _usbh_data.attach_debouncing_bm |= TU_BIT(event->rhport); } } break; default: // nothing to do break; } queue_event(event, in_isr); } //--------------------------------------------------------------------+ // Descriptors Async //--------------------------------------------------------------------+ // generic helper to get a descriptor // if blocking, user_data is pointed to xfer_result TU_ATTR_ALWAYS_INLINE static inline bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN }, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = tu_htole16( TU_U16(type, index) ), .wIndex = tu_htole16(language_id), .wLength = tu_htole16(len) }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data); } //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data); } // Get manufacturer string descriptor bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->desc_device.iManufacturer); return tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, language_id, buffer, len, complete_cb, user_data); } // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->desc_device.iProduct); return tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, language_id, buffer, len, complete_cb, user_data); } // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->desc_device.iSerialNumber); return tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, language_id, buffer, len, complete_cb, user_data); } // Get HID report descriptor // if blocking, user_data is pointed to xfer_result bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN }, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = tu_htole16(TU_U16(desc_type, index)), .wIndex = tu_htole16((uint16_t) itf_num), .wLength = len }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_address_set(uint8_t daddr, uint8_t new_addr, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Address = %d\r\n", new_addr); const tusb_control_request_t request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, .bRequest = TUSB_REQ_SET_ADDRESS, .wValue = tu_htole16(new_addr), .wIndex = 0, .wLength = 0 }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; TU_ASSERT(tuh_control_xfer(&xfer)); return true; } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Configuration = %d\r\n", config_num); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, .bRequest = TUSB_REQ_SET_CONFIGURATION, .wValue = tu_htole16(config_num), .wIndex = 0, .wLength = 0 }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt); tusb_control_request_t const request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, .bRequest = TUSB_REQ_SET_INTERFACE, .wValue = tu_htole16(itf_alt), .wIndex = tu_htole16(itf_num), .wLength = 0 }; tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_data = user_data }; return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ // Detaching //--------------------------------------------------------------------+ // process detach event from rhport:hub_addr:hub_port static void process_remove_event(hcd_event_t *event) { if (_usbh_data.enumerating_daddr == 0 && event->rhport == _usbh_data.dev0_bus.rhport && event->connection.hub_addr == _usbh_data.dev0_bus.hub_addr && event->connection.hub_port == _usbh_data.dev0_bus.hub_port) { // dev0 is unplugged while enumerating (not yet assigned an address) usbh_device_close(_usbh_data.dev0_bus.rhport, 0); } else { remove_device_tree(event->rhport, event->connection.hub_addr, event->connection.hub_port); } } // remove a device at rhport:hub_addr:hub_port and all of its downstream static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { // Find the all devices (star-network) under port that is unplugged #if CFG_TUH_HUB uint8_t removing_hubs[CFG_TUH_HUB] = { 0 }; #endif do { for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { usbh_device_t* dev = &_usbh_devices[dev_id]; uint8_t const daddr = dev_id + 1u; // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub if (dev->bus_info.rhport == rhport && dev->connected && (hub_addr == 0 || dev->bus_info.hub_addr == hub_addr) && (hub_port == 0 || dev->bus_info.hub_port == hub_port)) { TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr); #if CFG_TUH_HUB if (is_hub_addr(daddr)) { TU_LOG_USBH(" is a HUB device %u\r\n", daddr); removing_hubs[dev_id - CFG_TUH_DEVICE_MAX] = 1; } else #endif { // Invoke callback before closing driver (maybe call it later ?) tuh_umount_cb(daddr); } // Close class driver for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); if (driver != NULL) { driver->close(daddr); } } usbh_device_close(rhport, daddr); clear_device(dev); } } #if CFG_TUH_HUB // if a hub is removed, we need to remove all of its downstream devices if (tu_mem_is_zero(removing_hubs, CFG_TUH_HUB)) { break; } // find a marked hub to process for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { if (0 != removing_hubs[h_id]) { removing_hubs[h_id] = 0; // update hub_addr and hub_port for next loop hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX; hub_port = 0; break; } } #else break; #endif } while(1); } //--------------------------------------------------------------------+ // Enumeration Process // is a lengthy process with a series of control transfer to configure newly attached device. // NOTE: due to the shared control buffer, we must complete enumerating // one device before enumerating another one. //--------------------------------------------------------------------+ enum { // USB 2.0 specs 7.1.7 for timing ENUM_DEBOUNCING_DELAY_MS = 150, // T(ATTDB) minimum 100 ms for stable connection ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port ENUM_RESET_ROOT_POST_DELAY_MS = 2, // 2 ms delay after root port reset before getting speed/status ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms }; enum { ENUM_IDLE, ENUM_HUB_RERSET, ENUM_HUB_RESET_COMPLETE, ENUM_HUB_CLEAR_RESET, ENUM_HUB_CLEAR_RESET_RETRY, // 2nd attempt waiting for hub reset ENUM_HUB_CLEAR_RESET_COMPLETE, ENUM_ADDR0_DEVICE_DESC, ENUM_SET_ADDR, ENUM_GET_DEVICE_DESC, ENUM_GET_STRING_LANGUAGE_ID_LEN, ENUM_GET_STRING_LANGUAGE_ID, ENUM_GET_STRING_MANUFACTURER_LEN, ENUM_GET_STRING_MANUFACTURER, ENUM_GET_STRING_PRODUCT_LEN, ENUM_GET_STRING_PRODUCT, ENUM_GET_STRING_SERIAL_LEN, ENUM_GET_STRING_SERIAL, ENUM_GET_9BYTE_CONFIG_DESC, ENUM_GET_FULL_CONFIG_DESC, ENUM_SET_CONFIG, ENUM_CONFIG_DRIVER }; static uint8_t enum_get_new_address(bool is_hub); static bool enum_parse_configuration_desc(uint8_t dev_addr, const tusb_desc_configuration_t *desc_cfg); static void enum_full_complete(bool success); static void process_enumeration(tuh_xfer_t *xfer); enum { ENUM_AFTER_DEBOUNCING_DELAY, ENUM_AFTER_RESET_ROOT_DELAY, ENUM_AFTER_RESET_ROOT_POST_DELAY, ENUM_AFTER_RESET_HUB_DELAY, ENUM_AFTER_RESET_HUB_DELAY_RETRY, ENUM_AFTER_RESET_RECOVERY_DELAY, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY, }; // process async delay in enumeration static void enum_delay_async(uintptr_t state) { tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; switch (state) { case ENUM_AFTER_DEBOUNCING_DELAY: #if CFG_TUH_HUB if (dev0_bus->hub_addr != 0) { // connected via hub TU_VERIFY(dev0_bus->hub_port != 0, ); TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, ENUM_HUB_RERSET), ); } else #endif { // connected directly to roothub _usbh_data.attach_debouncing_bm &= (uint8_t)~TU_BIT(dev0_bus->rhport); // clear roothub debouncing delay if (!hcd_port_connect_status(dev0_bus->rhport)) { TU_LOG_USBH("Device unplugged while debouncing\r\n"); enum_full_complete(false); return; } hcd_port_reset(dev0_bus->rhport); // reset port usbh_defer_func_ms_async(ENUM_RESET_ROOT_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_DELAY); } break; case ENUM_AFTER_RESET_ROOT_DELAY: hcd_port_reset_end(dev0_bus->rhport); usbh_defer_func_ms_async(ENUM_RESET_ROOT_POST_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_ROOT_POST_DELAY); break; case ENUM_AFTER_RESET_ROOT_POST_DELAY: if (!hcd_port_connect_status(dev0_bus->rhport)) { // device unplugged while delaying enum_full_complete(false); return; } dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport); TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]); // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; xfer.daddr = 0; xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; process_enumeration(&xfer); break; #if CFG_TUH_HUB case ENUM_AFTER_RESET_HUB_DELAY: case ENUM_AFTER_RESET_HUB_DELAY_RETRY: // get status after reset complete to check for reset change TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, NULL, process_enumeration, state == ENUM_AFTER_RESET_HUB_DELAY ? ENUM_HUB_CLEAR_RESET : ENUM_HUB_CLEAR_RESET_RETRY), ); break; #endif case ENUM_AFTER_RESET_RECOVERY_DELAY: // TODO probably doesn't need to open/close each enumeration if (!usbh_edpt_control_open(0, 8)) { TU_LOG_USBH("Failed to open dev0's control endpoint\r\n"); enum_full_complete(false); // Stop enumeration gracefully return; } // Get first 8 bytes of device descriptor for control endpoint size TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); TU_ASSERT(tuh_descriptor_get_device(0, _usbh_epbuf.ctrl, 8, process_enumeration, ENUM_SET_ADDR), ); break; case ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY: { const uint8_t new_addr = _usbh_data.enumerating_daddr; usbh_device_t *new_dev = get_device(new_addr); TU_ASSERT(new_dev, ); if (!usbh_edpt_control_open(new_addr, new_dev->desc_device.bMaxPacketSize0)) { TU_LOG_USBH("Failed to open new device's control endpoint\r\n"); clear_device(new_dev); enum_full_complete(false); return; } TU_LOG_USBH("Get Device Descriptor\r\n"); TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_STRING_LANGUAGE_ID_LEN), ); break; } default: break; } } // start a new enumeration process static void enum_new_device(hcd_event_t *event) { tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; dev0_bus->rhport = event->rhport; dev0_bus->hub_addr = event->connection.hub_addr; dev0_bus->hub_port = event->connection.hub_port; usbh_defer_func_ms_async(ENUM_DEBOUNCING_DELAY_MS, enum_delay_async, ENUM_AFTER_DEBOUNCING_DELAY); } // process device enumeration static void process_enumeration(tuh_xfer_t *xfer) { if (XFER_RESULT_FAILED == xfer->result) { enum_full_complete(false); // failed to enum return; } const uint8_t daddr = xfer->daddr; const uintptr_t state = xfer->user_data; usbh_device_t *dev = get_device(daddr); tuh_bus_info_t *dev0_bus = &_usbh_data.dev0_bus; if (daddr > 0) { TU_ASSERT(dev != NULL,); } uint16_t langid = 0x0409; // default is English bool is_enum_failed = false; switch (state) { #if CFG_TUH_HUB case ENUM_HUB_RERSET: { hub_port_status_response_t port_status; hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status); if (0 == port_status.status.connection) { TU_LOG_USBH("Device unplugged from hub while debouncing\r\n"); is_enum_failed = true; } else { TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_RESET_COMPLETE), ); } break; } case ENUM_HUB_RESET_COMPLETE: // wait for reset to take effect usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY); break; case ENUM_HUB_CLEAR_RESET: case ENUM_HUB_CLEAR_RESET_RETRY: { hub_port_status_response_t port_status; hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status); if (1 == port_status.change.reset) { // Acknowledge Port Reset Change TU_ASSERT(hub_port_clear_reset_change(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_CLEAR_RESET_COMPLETE), ); } else if (state == ENUM_HUB_CLEAR_RESET) { // retry one more time if reset change not set yet usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY); } else { // retry but still not set --> failed is_enum_failed = true; } break; } case ENUM_HUB_CLEAR_RESET_COMPLETE: { hub_port_status_response_t port_status; hub_port_get_status_local(dev0_bus->hub_addr, dev0_bus->hub_port, &port_status); if (0 == port_status.status.connection) { TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n"); is_enum_failed = true; break; } dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; TU_ATTR_FALLTHROUGH; } #endif case ENUM_ADDR0_DEVICE_DESC: usbh_defer_func_ms_async(ENUM_RESET_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_RECOVERY_DELAY); break; case ENUM_SET_ADDR: { const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl; if (!(desc_device->bDescriptorType == TUSB_DESC_DEVICE && desc_device->bMaxPacketSize0 >= 8)) { TU_LOG_USBH("Invalid Device descriptor\r\n"); is_enum_failed = true; break; } const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0,); usbh_device_t* new_dev = get_device(new_addr); new_dev->bus_info = *dev0_bus; new_dev->connected = 1; new_dev->desc_device.bMaxPacketSize0 = desc_device->bMaxPacketSize0; TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC), ); break; } case ENUM_GET_DEVICE_DESC: { const uint8_t new_addr = (uint8_t)tu_le16toh(xfer->setup->wValue); usbh_device_t *new_dev = get_device(new_addr); TU_ASSERT(new_dev, ); new_dev->addressed = 1; _usbh_data.enumerating_daddr = new_addr; usbh_device_close(dev0_bus->rhport, 0); // close dev0 usbh_defer_func_ms_async(ENUM_SET_ADDRESS_RECOVERY_DELAY_MS, enum_delay_async, ENUM_AFTER_SET_ADDRESS_RECOVERY_DELAY); break; } // For string descriptor (langid, manufacturer, product, serila): always get the first 2 bytes // to determine the length first. otherwise, some device may have buffer overflow. case ENUM_GET_STRING_LANGUAGE_ID_LEN: { // save the received device descriptor tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl; memcpy(&dev->desc_device, (const uint8_t*) desc_device + offsetof(tusb_desc_device_t, bcdUSB), sizeof(desc_device_noheader_t)); tuh_enum_descriptor_device_cb(daddr, desc_device); // callback tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_LANGUAGE_ID); break; } case ENUM_GET_STRING_LANGUAGE_ID: { const uint8_t str_len = xfer->buffer[0]; tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_STRING_MANUFACTURER_LEN); break; } case ENUM_GET_STRING_MANUFACTURER_LEN: { const tusb_desc_string_t* desc_langid = (const tusb_desc_string_t *) _usbh_epbuf.ctrl; if (desc_langid->bLength >= 4) { langid = tu_le16toh(desc_langid->utf16le[0]); // previous request is langid } if (dev->desc_device.iManufacturer != 0) { tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_MANUFACTURER); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_MANUFACTURER: { if (dev->desc_device.iManufacturer != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; tuh_descriptor_get_string(daddr, dev->desc_device.iManufacturer, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_STRING_PRODUCT_LEN); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_PRODUCT_LEN: { if (dev->desc_device.iProduct != 0) { if (state == ENUM_GET_STRING_PRODUCT_LEN) { langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through } tuh_descriptor_get_string( daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_PRODUCT); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_PRODUCT: { if (dev->desc_device.iProduct != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; tuh_descriptor_get_string(daddr, dev->desc_device.iProduct, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_STRING_SERIAL_LEN); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_SERIAL_LEN: { if (dev->desc_device.iSerialNumber != 0) { if (state == ENUM_GET_STRING_SERIAL_LEN) { langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through } tuh_descriptor_get_string( daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, 2, process_enumeration, ENUM_GET_STRING_SERIAL); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_STRING_SERIAL: { if (dev->desc_device.iSerialNumber != 0) { langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request const uint8_t str_len = xfer->buffer[0]; tuh_descriptor_get_string(daddr, dev->desc_device.iSerialNumber, langid, _usbh_epbuf.ctrl, str_len, process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC); break; } TU_ATTR_FALLTHROUGH; } case ENUM_GET_9BYTE_CONFIG_DESC: { // Get 9-byte for total length uint8_t const config_idx = 0; TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx); TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); break; } case ENUM_GET_FULL_CONFIG_DESC: { uint8_t const* desc_config = _usbh_epbuf.ctrl; // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh(tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))); // TODO not enough buffer to hold configuration descriptor TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE,); // Get full configuration descriptor uint8_t const config_idx = (uint8_t) tu_le16toh(xfer->setup->wIndex); TU_LOG_USBH("Get Configuration[%u] Descriptor\r\n", config_idx); TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, total_len, process_enumeration, ENUM_SET_CONFIG),); break; } case ENUM_SET_CONFIG: { uint8_t config_idx = (uint8_t) tu_le16toh(xfer->setup->wIndex); if (tuh_enum_descriptor_configuration_cb(daddr, config_idx, (const tusb_desc_configuration_t*) _usbh_epbuf.ctrl)) { TU_ASSERT(tuh_configuration_set(daddr, config_idx+1u, process_enumeration, ENUM_CONFIG_DRIVER),); } else { config_idx++; TU_ASSERT(config_idx < dev->desc_device.bNumConfigurations,); TU_LOG_USBH("Get Configuration[%u] Descriptor (9 bytes)\r\n", config_idx); TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_epbuf.ctrl, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); } break; } case ENUM_CONFIG_DRIVER: { TU_LOG_USBH("Device configured\r\n"); dev->configured = 1; #if CFG_TUH_HUB // get next hub status now since device can be unplugged before set_configure() is complete if (_usbh_data.dev0_bus.hub_addr != 0) { hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); } #endif // Parse configuration & set up drivers // driver_open() must not make any usb transfer TU_ASSERT(enum_parse_configuration_desc(daddr, (tusb_desc_configuration_t*) _usbh_epbuf.ctrl),); // Start the Set Configuration process for interfaces (itf = TUSB_INDEX_INVALID_8) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using TUSB_INDEX_INVALID_8 usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8); break; } default: is_enum_failed = true; break; } if (is_enum_failed) { enum_full_complete(false); } } static uint8_t enum_get_new_address(bool is_hub) { uint8_t start; uint8_t end; if ( is_hub ) { start = CFG_TUH_DEVICE_MAX; end = start + CFG_TUH_HUB; }else { start = 0; end = start + CFG_TUH_DEVICE_MAX; } for (uint8_t idx = start; idx < end; idx++) { if (0 == _usbh_devices[idx].connected) { return (idx + 1); } } #if CFG_TUH_HUB if ( is_hub ) { TU_LOG1("All addresses are occupied, try to increase CFG_TUH_HUB value.\r\n"); } #endif // CFG_TUH_HUB return 0; // invalid address } static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength); uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len; uint8_t const* p_desc = tu_desc_next(desc_cfg); TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); // parse all interfaces while (tu_desc_in_bounds(p_desc, desc_end)) { if (0 == tu_desc_len(p_desc)) { // A zero-length descriptor indicates that the device is off spec (e.g. wrong wTotalLength). // Parsed interfaces should still be usable TU_LOG_USBH("Encountered a zero-length descriptor after %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg); break; } // skip if not interface if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); continue; } const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc; // uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) // (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find a driver for this interface const uint16_t remaining_len = (uint16_t)(desc_end - p_desc); uint8_t drv_id; for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { const usbh_class_driver_t *driver = get_driver(drv_id); if (driver) { const uint16_t drv_len = driver->open(dev->bus_info.rhport, dev_addr, desc_itf, remaining_len); if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) { // open successfully TU_LOG_USBH(" %s opened\r\n", driver->name); // bind found driver to all interfaces and endpoint within drv_len tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, p_desc, drv_len); p_desc += drv_len; // next Interface break; // exit driver find loop } } } // no driver found if (drv_id == TOTAL_DRIVER_COUNT) { p_desc = tu_desc_next(p_desc); // skip this interface TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } } return true; } void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { usbh_device_t* dev = get_device(dev_addr); for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) { // continue with next valid interface // IAD binding interface such as CDCs should return itf_num + 1 when complete // with usbh_driver_set_config_complete() uint8_t const drv_id = dev->itf2drv[itf_num]; usbh_class_driver_t const * driver = get_driver(drv_id); if (driver != NULL) { TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; } } // all interfaces are configured if (itf_num == CFG_TUH_INTERFACE_MAX) { enum_full_complete(true); if (is_hub_addr(dev_addr)) { TU_LOG_USBH("HUB address = %u is mounted\r\n", dev_addr); }else { // Invoke callback if available tuh_mount_cb(dev_addr); } } } static void enum_full_complete(bool success) { (void)success; TU_LOG_USBH("Enumeration complete: success = %u\r\n", success); _usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8; // mark enumeration as complete _usbh_data.call_after.func = NULL; #if CFG_TUH_HUB // Hub status is already requested in case of successful enumeration if (!success && _usbh_data.dev0_bus.hub_addr != 0) { hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); } #endif } #endif ================================================ FILE: src/host/usbh.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_USBH_H_ #define TUSB_USBH_H_ #ifdef __cplusplus extern "C" { #endif #include "common/tusb_common.h" #if CFG_TUH_MAX3421 #include "portable/analog/max3421/hcd_max3421.h" #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // forward declaration struct tuh_xfer_s; typedef struct tuh_xfer_s tuh_xfer_t; typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); // Note1: layout and order of this will be changed in near future // it is advised to initialize it using member name // Note2: not all field is available/meaningful in callback, // some info is not saved by usbh to save SRAM struct tuh_xfer_s { uint8_t daddr; uint8_t ep_addr; uint8_t TU_RESERVED; // reserved xfer_result_t result; uint32_t actual_len; // excluding setup packet union { tusb_control_request_t const* setup; // setup packet pointer if control transfer uint32_t buflen; // expected length if not control transfer (not available in callback) }; uint8_t* buffer; // not available in callback if not control transfer tuh_xfer_cb_t complete_cb; uintptr_t user_data; // uint32_t timeout_ms; // place holder, not supported yet }; // Subject to change typedef struct { uint8_t daddr; tusb_desc_interface_t desc; } tuh_itf_info_t; typedef struct { uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; uint8_t speed; } tuh_bus_info_t; // backward compatibility for hcd_devtree_info_t, maybe removed in the future #define hcd_devtree_info_t tuh_bus_info_t #define hcd_devtree_get_info(_daddr, _bus_info) tuh_bus_info_get(_daddr, _bus_info) // ConfigID for tuh_configure() enum { TUH_CFGID_INVALID = 0, TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t TUH_CFGID_MAX3421 = 200, TUH_CFGID_FSDEV = 300, TUH_CFGID_DWC2 = 400 }; typedef struct { uint8_t max_nak; // max NAK per endpoint per frame to save CPU/SPI bus usage (0=unlimited) uint8_t cpuctl; // R16: CPU Control Register uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored } tuh_configure_max3421_t; typedef struct { uint8_t max_nak; // max NAK per endpoint per frame to save CPU usage (0=unlimited) } tuh_configure_fsdev_t; typedef struct { bool use_hs_phy; // Always use high-speed ULPI/UTMI phy even when working at full-speed } tuh_configure_dwc2_t; typedef union { // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t tuh_configure_max3421_t max3421; tuh_configure_fsdev_t fsdev; tuh_configure_dwc2_t dwc2; } tuh_configure_param_t; //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ // Invoked when enumeration get device descriptor // Device is not ready to communicate yet, application can copy the descriptor if needed void tuh_enum_descriptor_device_cb(uint8_t daddr, const tusb_desc_device_t *desc_device); // Invoked when enumeration get configuration descriptor // For multi-configuration device return false to skip, true to proceed with this configuration (may not be implemented yet) // Device is not ready to communicate yet, application can copy the descriptor if needed bool tuh_enum_descriptor_configuration_cb(uint8_t daddr, uint8_t cfg_index, const tusb_desc_configuration_t *desc_config); // Invoked when a device is mounted (configured) void tuh_mount_cb (uint8_t daddr); // Invoked when a device failed to mount during enumeration process // void tuh_mount_failed_cb (uint8_t daddr); // Invoked when a device is unmounted (detached) void tuh_umount_cb(uint8_t daddr); // Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ // Configure host stack behavior with dynamic or port-specific parameters. // Should be called before tuh_init() // - cfg_id : configure ID (TBD) // - cfg_param: configure data, structure depends on the ID bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // New API to replace tuh_init() to init host stack on specific roothub port // Must be called in the same task/context as tuh_task() if RTOS is used bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Init host stack #if TUSB_VERSION_NUMBER > 2000 // 0.20.0 TU_ATTR_DEPRECATED("Please use tusb_init(rhport, rh_init) instead") #endif TU_ATTR_ALWAYS_INLINE static inline bool tuh_init(uint8_t rhport) { const tusb_rhport_init_t rh_init = { .role = TUSB_ROLE_HOST, .speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, }; return tuh_rhport_init(rhport, &rh_init); } // Deinit host stack on rhport // Must be called in the same task/context as tuh_task() if RTOS is used bool tuh_deinit(uint8_t rhport); // Check if host stack is already initialized with any roothub ports // To check if an rhport is initialized, use tuh_rhport_is_active() bool tuh_inited(void); // Task function should be called in main/rtos loop, extended version of tuh_task() // - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever // - in_isr: if function is called in ISR void tuh_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline void tuh_task(void) { tuh_task_ext(UINT32_MAX, false); } // Check if there is pending events need processing by tuh_task() bool tuh_task_event_ready(void); #ifndef TUSB_HCD_H_ extern void hcd_int_handler(uint8_t rhport, bool in_isr); #endif // Interrupt handler alias to HCD with in_isr as optional parameter #define _tuh_int_handler_arg0() TU_VERIFY_STATIC(false, "tuh_int_handler() must have 1 or 2 arguments") #define _tuh_int_handler_arg1(_rhport) hcd_int_handler(_rhport, true) #define _tuh_int_handler_arg2(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr) // 1st argument is rhport (mandatory), 2nd argument in_isr (optional) #define tuh_int_handler(...) TU_FUNC_OPTIONAL_ARG(_tuh_int_handler, __VA_ARGS__) // Check if roothub port is initialized and active as a host bool tuh_rhport_is_active(uint8_t rhport); // Assert/de-assert Bus Reset signal to roothub port. USB specs: it should last 10-50ms bool tuh_rhport_reset_bus(uint8_t rhport, bool active); //--------------------------------------------------------------------+ // Device API //--------------------------------------------------------------------+ // Get VID/PID of device bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); // Get local (cached) device descriptor once device is enumerated bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device); // Get speed of device tusb_speed_t tuh_speed_get(uint8_t daddr); // Check if device is connected and configured bool tuh_mounted(uint8_t daddr); // Check if device is connected which mean device has at least 1 successful transfer // Note: It may not be addressed/configured/mounted yet bool tuh_connected(uint8_t daddr); // Check if device is suspended TU_ATTR_ALWAYS_INLINE static inline bool tuh_suspended(uint8_t daddr) { // TODO implement suspend & resume on host (void) daddr; return false; } // Check if device is ready to communicate with TU_ATTR_ALWAYS_INLINE static inline bool tuh_ready(uint8_t daddr) { return tuh_mounted(daddr) && !tuh_suspended(daddr); } // Get bus information of device bool tuh_bus_info_get(uint8_t daddr, tuh_bus_info_t* bus_info); //--------------------------------------------------------------------+ // Transfer API // Each Function will make a USB transfer request to device. If // - complete_cb != NULL, the function will return immediately and invoke the callback when request is complete. // - complete_cb == NULL, the function will block until request is complete. // In this case, user_data should be tusb_xfer_result_t* to hold the transfer result. //--------------------------------------------------------------------+ // Helper to make Sync API from async one #define TU_API_SYNC(_async_api, ...) \ xfer_result_t result = XFER_RESULT_INVALID;\ TU_VERIFY(_async_api(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ return result // Submit a control transfer // - async: complete callback invoked when finished. // - sync : blocking if complete callback is NULL. bool tuh_control_xfer(tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer // - async: complete callback invoked when finished. // - sync : blocking if complete callback is NULL. bool tuh_edpt_xfer(tuh_xfer_t* xfer); // Open a non-control endpoint bool tuh_edpt_open(uint8_t daddr, tusb_desc_endpoint_t const * desc_ep); // Close a non-control endpoint, it will abort any pending transfer bool tuh_edpt_close(uint8_t daddr, uint8_t ep_addr); // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr); // Set Address (control transfer) bool tuh_address_set(uint8_t daddr, uint8_t new_addr, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // true on success, false if there is on-going control transfer or incorrect parameters // if complete_cb == NULL i.e blocking, user_data should be pointed to xfer_reuslt_t* bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Set Interface (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters // if complete_cb == NULL i.e blocking, user_data should be pointed to xfer_reuslt_t* bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) //--------------------------------------------------------------------+ // Get an descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get device descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get configuration descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get HID report descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters // Blocking if complete callback is NULL, in this case 'user_data' must contain xfer_result_t variable bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get language id string descriptor (control transfer) TU_ATTR_ALWAYS_INLINE static inline bool tuh_descriptor_get_string_langid(uint8_t daddr, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_descriptor_get_string(daddr, 0, 0, buffer, len, complete_cb, user_data); } // Get manufacturer string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get product string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Get serial string descriptor (control transfer) // true on success, false if there is on-going control transfer or incorrect parameters bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //--------------------------------------------------------------------+ // Descriptors Synchronous (blocking) // Sync API which is blocking until transfer is complete. // return transfer result //--------------------------------------------------------------------+ // Sync version of tuh_descriptor_get() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get, daddr, type, index, buffer, len); } // Sync version of tuh_descriptor_get_device() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_device, daddr, buffer, len); } // Sync version of tuh_descriptor_get_configuration() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_configuration, daddr, index, buffer, len); } // Sync version of tuh_descriptor_get_hid_report() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len); } // Sync version of tuh_descriptor_get_string() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_string, daddr, index, language_id, buffer, len); } // Sync version of tuh_descriptor_get_string_langid() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_string_langid_sync(uint8_t daddr, void* buffer, uint16_t len) { return tuh_descriptor_get_string_sync(daddr, 0, 0, buffer, len); } // Sync version of tuh_descriptor_get_manufacturer_string() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len); } // Sync version of tuh_descriptor_get_product_string() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_product_string, daddr, language_id, buffer, len); } // Sync version of tuh_descriptor_get_serial_string() TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) { TU_API_SYNC(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/host/usbh_pvt.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_USBH_PVT_H_ #define TUSB_USBH_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" #include "common/tusb_private.h" #ifdef __cplusplus extern "C" { #endif #define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) #define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) #define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) #define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) #define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // Class Driver API //--------------------------------------------------------------------+ typedef struct { const char *name; bool (*const init)(void); bool (*const deinit)(void); uint16_t (*const open)(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); bool (*const set_config)(uint8_t dev_addr, uint8_t itf_num); bool (*const xfer_cb)(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void (*const close)(uint8_t dev_addr); } usbh_class_driver_t; // Invoked when initializing host stack to get additional class drivers. // Can be implemented by application to extend/overwrite class driver support. // Note: The drivers array must be accessible at all time when stack is active usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count); // Call by class driver to tell USBH that it has complete the enumeration void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num); uint8_t usbh_get_rhport(uint8_t daddr); uint8_t* usbh_get_enum_buf(void); void usbh_int_set(bool enabled); // Invoke this function later in tuh_task() by putting it into task queue void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); // Schedules a function to be called after certain time asynchronously bool usbh_defer_func_ms_async(uint32_t ms, tusb_defer_func_t func, uintptr_t param); void usbh_spin_lock(bool in_isr); void usbh_spin_unlock(bool in_isr); //--------------------------------------------------------------------+ // USBH Endpoint API //--------------------------------------------------------------------+ // Submit a usb transfer with callback support, require CFG_TUH_API_EDPT_XFER bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, tuh_xfer_cb_t complete_cb, uintptr_t user_data); TU_ATTR_ALWAYS_INLINE static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); } // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); // Release claimed endpoint without submitting a transfer bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); // Check if endpoint transferring is complete bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_H_ #define TUSB_OSAL_H_ #ifdef __cplusplus extern "C" { #endif #include "common/tusb_common.h" typedef void (*osal_task_func_t)(void* param); // Timeout #define OSAL_TIMEOUT_NOTIMEOUT (0) // Return immediately #define OSAL_TIMEOUT_NORMAL (10) // Default timeout #define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) // Wait forever #define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER // Mutex is required when using a preempted RTOS or MCU has multiple cores #if (CFG_TUSB_OS == OPT_OS_NONE) && !TUP_MCU_MULTIPLE_CORE #define OSAL_MUTEX_REQUIRED 0 #define OSAL_MUTEX_DEF(_name) uint8_t :0 #else #define OSAL_MUTEX_REQUIRED 1 #define OSAL_MUTEX_DEF(_name) osal_mutex_def_t _name #endif // OS thin implementation #if CFG_TUSB_OS == OPT_OS_NONE #include "osal_none.h" #elif CFG_TUSB_OS == OPT_OS_FREERTOS #include "osal_freertos.h" #elif CFG_TUSB_OS == OPT_OS_MYNEWT #include "osal_mynewt.h" #elif CFG_TUSB_OS == OPT_OS_PICO #include "osal_pico.h" #elif CFG_TUSB_OS == OPT_OS_RTTHREAD #include "osal_rtthread.h" #elif CFG_TUSB_OS == OPT_OS_RTX4 #include "osal_rtx4.h" #elif CFG_TUSB_OS == OPT_OS_ZEPHYR #include "osal_zephyr.h" #elif CFG_TUSB_OS == OPT_OS_THREADX #include "osal_threadx.h" #elif CFG_TUSB_OS == OPT_OS_CUSTOM #include "tusb_os_custom.h" // implemented by application #else #error OS is not supported yet #endif /*-------------------------------------------------------------------- OSAL Porting API Should be implemented as static inline function in osal_port.h header uint32_t osal_time_millis(void); void osal_spin_init(osal_spinlock_t *ctx); void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr); osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); bool osal_semaphore_delete(osal_semaphore_t semd_hdl); bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); void osal_semaphore_reset(osal_semaphore_t sem_hdl); osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); bool osal_mutex_delete(osal_mutex_t mutex_hdl) bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); bool osal_mutex_unlock(osal_mutex_t mutex_hdl); osal_queue_t osal_queue_create(osal_queue_def_t* qdef); bool osal_queue_delete(osal_queue_t qhdl); bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec); bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); bool osal_queue_empty(osal_queue_t qhdl); --------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_freertos.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_FREERTOS_H_ #define TUSB_OSAL_FREERTOS_H_ // FreeRTOS Headers #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h) #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,semphr.h) #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,queue.h) #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,task.h) #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ #if configSUPPORT_STATIC_ALLOCATION typedef StaticSemaphore_t osal_semaphore_def_t; typedef StaticSemaphore_t osal_mutex_def_t; #else // not used therefore defined to the smallest possible type to save space typedef uint8_t osal_semaphore_def_t; typedef uint8_t osal_mutex_def_t; #endif typedef SemaphoreHandle_t osal_semaphore_t; typedef SemaphoreHandle_t osal_mutex_t; typedef QueueHandle_t osal_queue_t; typedef struct { uint16_t depth; uint16_t item_sz; void* buf; #if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) char const* name; #endif #if configSUPPORT_STATIC_ALLOCATION StaticQueue_t sq; #endif } osal_queue_def_t; #if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) #define OSAL_Q_NAME(_name) .name = #_name #else #define OSAL_Q_NAME(_name) #endif // _int_set is not used with an RTOS #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, OSAL_Q_NAME(_name) } //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { if (msec == OSAL_TIMEOUT_WAIT_FOREVER) { return portMAX_DELAY; } if (msec == 0) { return 0; } uint32_t ticks = pdMS_TO_TICKS(msec); // If configTICK_RATE_HZ is less than 1000 and 1 tick > 1 ms, we still need to delay at least 1 tick if (ticks == 0) { ticks = 1; } return ticks; } TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { vTaskDelay(pdMS_TO_TICKS(msec)); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return pdTICKS_TO_MS(xTaskGetTickCount()); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name #ifdef ESP_PLATFORM // Espressif critical take spinlock as argument and does not use in_isr typedef portMUX_TYPE osal_spinlock_t; TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { spinlock_initialize(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } portENTER_CRITICAL(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } portEXIT_CRITICAL(ctx); } #else typedef UBaseType_t osal_spinlock_t; TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (in_isr) { #if TUP_MCU_MULTIPLE_CORE *ctx = taskENTER_CRITICAL_FROM_ISR(); #else (void) ctx; return; // single core MCU does not need to lock in ISR #endif } else { taskENTER_CRITICAL(); } } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (in_isr) { #if TUP_MCU_MULTIPLE_CORE taskEXIT_CRITICAL_FROM_ISR(*ctx); #else (void) ctx; return; // single core MCU does not need to lock in ISR #endif } else { taskEXIT_CRITICAL(); } } #endif //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { #if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateBinaryStatic((StaticSemaphore_t*) semdef); #else (void) semdef; return xSemaphoreCreateBinary(); #endif } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { vSemaphoreDelete((SemaphoreHandle_t) semd_hdl); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if (!in_isr) { return xSemaphoreGive(sem_hdl) != 0; } else { BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); return res != 0; } } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { xQueueReset(sem_hdl); } //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { #if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateMutexStatic(mdef); #else (void) mdef; return xSemaphoreCreateMutex(); #endif } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { vSemaphoreDelete(mutex_hdl); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return xSemaphoreGive(mutex_hdl); } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { osal_queue_t q; #if configSUPPORT_STATIC_ALLOCATION q = xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); #else q = xQueueCreate(qdef->depth, qdef->item_sz); #endif #if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) vQueueAddToRegistry(q, qdef->name); #endif return q; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { vQueueDelete(qhdl); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { if (!in_isr) { return xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER) != 0; } else { BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); return res != 0; } } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return uxQueueMessagesWaiting(qhdl) == 0; } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_mynewt.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef OSAL_MYNEWT_H_ #define OSAL_MYNEWT_H_ #include "os/os.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_time_delay( os_time_ms_to_ticks32(msec) ); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return os_time_ticks_to_ms32(os_time_get()); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ typedef os_sr_t osal_spinlock_t; #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } OS_ENTER_CRITICAL(*ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } OS_EXIT_CRITICAL(*ctx); } //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ typedef struct os_sem osal_semaphore_def_t; typedef struct os_sem* osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { (void) semd_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return os_sem_release(sem_hdl) == OS_OK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_sem_pend(sem_hdl, ticks) == OS_OK; } static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { // TODO implement later } //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ typedef struct os_mutex osal_mutex_def_t; typedef struct os_mutex* osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void) mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_mutex_pend(mutex_hdl, ticks) == OS_OK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mutex_release(mutex_hdl) == OS_OK; } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ static struct os_event _name##_##evbuf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ typedef struct { uint16_t depth; uint16_t item_sz; void* buf; void* evbuf; struct os_mempool mpool; struct os_mempool epool; struct os_eventq evq; }osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usb queue") ) return NULL; if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usb evqueue") ) return NULL; os_eventq_init(&qdef->evq); return (osal_queue_t) qdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { (void) qhdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER struct os_event* ev; ev = os_eventq_get(&qhdl->evq); memcpy(data, ev->ev_arg, qhdl->item_sz); // copy message os_memblock_put(&qhdl->mpool, ev->ev_arg); // put back mem block os_memblock_put(&qhdl->epool, ev); // put back ev block return true; } static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { (void) in_isr; // get a block from mem pool for data void* ptr = os_memblock_get(&qhdl->mpool); if (!ptr) return false; memcpy(ptr, data, qhdl->item_sz); // get a block from event pool to put into queue struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool); if (!ev) { os_memblock_put(&qhdl->mpool, ptr); return false; } tu_memclr(ev, sizeof(struct os_event)); ev->ev_arg = ptr; os_eventq_put(&qhdl->evq, ev); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return STAILQ_EMPTY(&qhdl->evq.evq_list); } #ifdef __cplusplus } #endif #endif /* OSAL_MYNEWT_H_ */ ================================================ FILE: src/osal/osal_none.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_NONE_H_ #define TUSB_OSAL_NONE_H_ #ifdef __cplusplus extern "C" { #endif // osal_time_millis() is not provided, tusb_time_millis_api() must be implemented by user application //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ // Note: This implementation is designed for bare-metal single-core systems without RTOS. // - Supports nested locking within the same execution context // - NOT suitable for true SMP (Symmetric Multi-Processing) systems // - NOT thread-safe for multi-threaded environments // - Primarily manages interrupt enable/disable state for critical sections typedef struct { void (* interrupt_set)(bool enabled); uint32_t nested_count; } osal_spinlock_t; // For SMP, spinlock must be locked by hardware, cannot just use interrupt #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name = { .interrupt_set = _int_set, .nested_count = 0 } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { // Disable interrupts first to make nested_count increment atomic if (!in_isr && ctx->nested_count == 0) { ctx->interrupt_set(false); } ctx->nested_count++; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (ctx->nested_count == 0) { return; // spin is not locked to begin with } ctx->nested_count--; // Only re-enable interrupts when fully unlocked if (!in_isr && ctx->nested_count == 0) { ctx->interrupt_set(true); } } //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ typedef struct { volatile uint16_t count; } osal_semaphore_def_t; typedef osal_semaphore_def_t* osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { semdef->count = 0; return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { (void) semd_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_hdl->count++; return true; } // TODO blocking for now TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { (void) msec; while (sem_hdl->count == 0) {} sem_hdl->count--; return true; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_hdl->count = 0; } //--------------------------------------------------------------------+ // MUTEX API // Within tinyusb, mutex is never used in ISR context //--------------------------------------------------------------------+ typedef osal_semaphore_def_t osal_mutex_def_t; typedef osal_semaphore_t osal_mutex_t; #if OSAL_MUTEX_REQUIRED // Note: multiple cores MCUs usually do provide IPC API for mutex // or we can use std atomic function TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mdef->count = 1; return mdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void) mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return osal_semaphore_post(mutex_hdl, false); } #else #define osal_mutex_create(_mdef) (NULL) #define osal_mutex_lock(_mutex_hdl, _ms) (true) #define osal_mutex_unlock(_mutex_hdl) (true) #endif //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" typedef struct { void (* interrupt_set)(bool enabled); uint16_t item_size; tu_fifo_t ff; } osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; // _int_set is used as mutex in OS NONE (disable/enable USB ISR) #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth * sizeof(_type)]; \ osal_queue_def_t _name = {.interrupt_set = _int_set, \ .item_size = sizeof(_type), \ .ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)} TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { (void) qhdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // not used, always behave as msec = 0 qhdl->interrupt_set(false); const bool success = (tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size) > 0); qhdl->interrupt_set(true); return success; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) { if (!in_isr) { qhdl->interrupt_set(false); } const bool success = (tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size) > 0); if (!in_isr) { qhdl->interrupt_set(true); } return success; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // Skip queue lock/unlock since this function is primarily called // with interrupt disabled before going into low power mode return tu_fifo_empty(&qhdl->ff); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_pico.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_PICO_H_ #define TUSB_OSAL_PICO_H_ #include "pico/time.h" #include "pico/sem.h" #include "pico/mutex.h" #include "pico/critical_section.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { sleep_ms(msec); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return to_ms_since_boot(get_absolute_time()); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ typedef critical_section_t osal_spinlock_t; // pico implement critical section with spinlock #define OSAL_SPINLOCK_DEF(_name, _int_set) osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { critical_section_init(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { (void)in_isr; critical_section_enter_blocking(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { (void)in_isr; critical_section_exit(ctx); } //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { sem_init(semdef, 0, 255); return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { (void)semd_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void)in_isr; return sem_release(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return sem_acquire_timeout_ms(sem_hdl, msec); } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_reset(sem_hdl, 0); } //--------------------------------------------------------------------+ // MUTEX API // Within tinyusb, mutex is never used in ISR context //--------------------------------------------------------------------+ typedef struct mutex osal_mutex_def_t, *osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { mutex_init(mdef); return mdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void)mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return mutex_enter_timeout_ms(mutex_hdl, msec); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { mutex_exit(mutex_hdl); return true; } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" typedef struct { uint16_t item_size; tu_fifo_t ff; struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section } osal_queue_def_t; typedef osal_queue_def_t *osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth * sizeof(_type)]; \ osal_queue_def_t _name = {.item_size = sizeof(_type), .ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)} TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { critical_section_init(&qdef->critsec); tu_fifo_clear(&qdef->ff); return (osal_queue_t)qdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { osal_queue_def_t *qdef = (osal_queue_def_t *)qhdl; critical_section_deinit(&qdef->critsec); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { (void)msec; // not used, always behave as msec = 0 critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size); critical_section_exit(&qhdl->critsec); return success; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, const void *data, bool in_isr) { (void)in_isr; critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size); critical_section_exit(&qhdl->critsec); return success; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single // volatile read. // Skip queue lock/unlock since this function is primarily called // with interrupt disabled before going into low power mode return tu_fifo_empty(&qhdl->ff); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_rtthread.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 tfx2001 (2479727366@qq.com) * Copyright (c) 2020 yekai (2857693944@qq.com) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_RTTHREAD_H_ #define TUSB_OSAL_RTTHREAD_H_ // RT-Thread Headers #include "rtthread.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { rt_thread_mdelay(msec); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return (uint32_t)((((uint64_t)rt_tick_get()) * 1000) / RT_TICK_PER_SECOND); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ typedef struct rt_spinlock osal_spinlock_t; #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { rt_spin_lock_init(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } rt_spin_lock(ctx); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } rt_spin_unlock(ctx); } //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ typedef struct rt_semaphore osal_semaphore_def_t; typedef rt_sem_t osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { return RT_EOK == rt_sem_detach(semd_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return rt_sem_release(sem_hdl) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); } //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ typedef struct rt_mutex osal_mutex_def_t; typedef rt_mutex_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); return mdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { return RT_EOK == rt_mutex_detach(mutex_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return rt_mutex_release(mutex_hdl) == RT_EOK; } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth]; \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; typedef struct { uint16_t depth; uint16_t item_sz; void *buf; struct rt_messagequeue sq; } osal_queue_def_t; typedef rt_mq_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); return &(qdef->sq); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { return RT_EOK == rt_mq_detach(qhdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); #if RT_VERSION_MAJOR >= 5 return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) > 0; #else return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; #endif /* RT_VERSION_MAJOR >= 5 */ } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { (void) in_isr; return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return (qhdl->entry) == 0; } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_rtx4.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_RTX4_H_ #define TUSB_OSAL_RTX4_H_ #include #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { uint16_t hi = msec >> 16; uint16_t lo = msec; while (hi--) { os_dly_wait(0xFFFE); } os_dly_wait(lo); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return os_time_get(); } TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { if (msec == OSAL_TIMEOUT_WAIT_FOREVER) { return 0xFFFF; } else if (msec >= 0xFFFE) { return 0xFFFE; } else { return msec; } } //--------------------------------------------------------------------+ // Spinlock API, stub not implemented //--------------------------------------------------------------------+ typedef uint8_t osal_spinlock_t; #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { (void) ctx; (void) in_isr; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { (void) ctx; (void) in_isr; } //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ typedef OS_SEM osal_semaphore_def_t; typedef OS_ID osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) { os_sem_init(semdef, 0); return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { (void) semd_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { os_sem_send(sem_hdl); } else { isr_sem_send(sem_hdl); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { // TODO: implement } //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ typedef OS_MUT osal_mutex_def_t; typedef OS_ID osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { os_mut_init(mdef); return mdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void) mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mut_release(mutex_hdl) == OS_R_OK; } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ // role device/host is used by OS NONE for mutex (disable usb isr) only #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ os_mbx_declare(_name##__mbox, _depth); \ _declare_box(_name##__pool, sizeof(_type), _depth); \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; typedef struct { uint16_t depth; uint16_t item_sz; U32* pool; U32* mbox; }osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); return qdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { void* buf; os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec)); memcpy(data, buf, qhdl->item_sz); _free_box(qhdl->pool, buf); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { (void) qhdl; return true; // nothing to do ? } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { void* buf = _alloc_box(qhdl->pool); memcpy(buf, data, qhdl->item_sz); if ( !in_isr ) { os_mbx_send(qhdl->mbox, buf, 0xFFFF); } else { isr_mbx_send(qhdl->mbox, buf); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return os_mbx_check(qhdl->mbox) == qhdl->depth; } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_threadx.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_THREADX_H_ #define TUSB_OSAL_THREADX_H_ // ThreadX Headers #include "tx_api.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { if ( msec == TX_WAIT_FOREVER ) { return TX_WAIT_FOREVER; } if ( msec == 0 ) { return 0; } uint32_t ticks = msec * TX_TIMER_TICKS_PER_SECOND / 1000; // TX_TIMER_TICKS_PER_SECOND is less than 1000 and 1 tick > 1 ms // we still need to delay at least 1 tick if ( ticks == 0 ) { ticks = 1; } return ticks; } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return (uint32_t)((uint64_t) tx_time_get() * 1000u / TX_TIMER_TICKS_PER_SECOND); } TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { tx_thread_sleep(_osal_ms2tick(msec)); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ typedef struct { void (* interrupt_set)(bool); } osal_spinlock_t; // For SMP, spinlock must be locked by hardware, cannot just use interrupt #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name = { .interrupt_set = _int_set } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!in_isr) { ctx->interrupt_set(false); } } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!in_isr) { ctx->interrupt_set(true); } } //--------------------------------------------------------------------+ // Binary Semaphore API (act) //--------------------------------------------------------------------+ // Note: semaphores are not used in tinyusb for now, and their API has not been tested typedef TX_SEMAPHORE osal_semaphore_def_t, * osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { tx_semaphore_create(semdef, TX_NULL, 0); return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t sem_hdl) { (void) sem_hdl; return TX_SUCCESS == tx_semaphore_delete(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return TX_SUCCESS == tx_semaphore_put(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return TX_SUCCESS == tx_semaphore_get(sem_hdl, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { (void) sem_hdl; } //--------------------------------------------------------------------+ // MUTEX API //--------------------------------------------------------------------+ typedef TX_MUTEX osal_mutex_def_t, *osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { if (TX_SUCCESS == tx_mutex_create(mdef, mdef->tx_mutex_name, TX_NO_INHERIT)) { return mdef; } else { return NULL; } } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void) mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return TX_SUCCESS == tx_mutex_get(mutex_hdl, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return TX_SUCCESS == tx_mutex_put(mutex_hdl); } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ typedef TX_QUEUE osal_queue_def_t, * osal_queue_t; // _int_set is not used with an RTOS _usbd_qdef #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_buf[_depth]; \ osal_queue_def_t _name = { \ .tx_queue_name = (CHAR*)(uintptr_t)#_name, \ .tx_queue_message_size = (sizeof(_type) + 3) / 4, \ .tx_queue_capacity = _depth, \ .tx_queue_start = (ULONG *) _name##_buf } TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { return TX_SUCCESS == tx_queue_create(qdef, qdef->tx_queue_name, qdef->tx_queue_message_size, qdef->tx_queue_start, qdef->tx_queue_capacity * qdef->tx_queue_message_size * 4) ? qdef : 0; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { (void) qhdl; return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return 0 == tx_queue_receive(qhdl, data, _osal_ms2tick(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { return 0 == tx_queue_send(qhdl, (VOID *)(uintptr_t) data, in_isr ? TX_NO_WAIT : TX_WAIT_FOREVER); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { ULONG enqueued; tx_queue_info_get(qhdl, 0, &enqueued, 0, 0, 0, 0); return enqueued == 0; } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/osal/osal_zephyr.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OSAL_ZEPHYR_H #define TUSB_OSAL_ZEPHYR_H #include //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { k_msleep(msec); } TU_ATTR_ALWAYS_INLINE static inline uint32_t osal_time_millis(void) { return k_uptime_get_32(); } //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ typedef struct { struct k_spinlock lock; k_spinlock_key_t key; } osal_spinlock_t; #define OSAL_SPINLOCK_DEF(_name, _int_set) \ osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { (void) ctx; } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } ctx->key = k_spin_lock(&ctx->lock); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } k_spin_unlock(&ctx->lock, ctx->key); } //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ typedef struct k_sem osal_semaphore_def_t, * osal_semaphore_t; TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { k_sem_init(semdef, 0, 255); return semdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { (void) semd_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; k_sem_give(sem_hdl); return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return 0 == k_sem_take(sem_hdl, K_MSEC(msec)); } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { k_sem_reset(sem_hdl); } //--------------------------------------------------------------------+ // MUTEX API //--------------------------------------------------------------------+ typedef struct k_mutex osal_mutex_def_t, *osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { if ( 0 == k_mutex_init(mdef) ) { return mdef; } else { return NULL; } } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { (void) mutex_hdl; return true; // nothing to do } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return 0 == k_mutex_lock(mutex_hdl, K_MSEC(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return 0 == k_mutex_unlock(mutex_hdl); } //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ typedef struct k_msgq osal_queue_def_t, * osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) K_MSGQ_DEFINE(_name, sizeof(_type), _depth, 4) TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { // K_MSGQ_DEFINE already initializes the queue return (osal_queue_t) qdef; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { (void) qhdl; return true; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return 0 == k_msgq_get(qhdl, data, K_MSEC(msec)); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) { return 0 == k_msgq_put(qhdl, data, in_isr ? K_NO_WAIT : K_FOREVER); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return 0 == k_msgq_num_used_get(qhdl); } #endif ================================================ FILE: src/portable/analog/max3421/hcd_max3421.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 #include "host/hcd.h" #include "host/usbh.h" #include "host/usbh_pvt.h" //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Command format is // Reg [7:3] | 0 [2] | Dir [1] | Ack [0] enum { CMDBYTE_WRITE = 0x02, }; enum { RCVVFIFO_ADDR = 1u << 3, // 0x08 SNDFIFO_ADDR = 2u << 3, // 0x10 SUDFIFO_ADDR = 4u << 3, // 0x20 RCVBC_ADDR = 6u << 3, // 0x30 SNDBC_ADDR = 7u << 3, // 0x38 USBIRQ_ADDR = 13u << 3, // 0x68 USBIEN_ADDR = 14u << 3, // 0x70 USBCTL_ADDR = 15u << 3, // 0x78 CPUCTL_ADDR = 16u << 3, // 0x80 PINCTL_ADDR = 17u << 3, // 0x88 REVISION_ADDR = 18u << 3, // 0x90 // 19 is not used IOPINS1_ADDR = 20u << 3, // 0xA0 IOPINS2_ADDR = 21u << 3, // 0xA8 GPINIRQ_ADDR = 22u << 3, // 0xB0 GPINIEN_ADDR = 23u << 3, // 0xB8 GPINPOL_ADDR = 24u << 3, // 0xC0 HIRQ_ADDR = 25u << 3, // 0xC8 HIEN_ADDR = 26u << 3, // 0xD0 MODE_ADDR = 27u << 3, // 0xD8 PERADDR_ADDR = 28u << 3, // 0xE0 HCTL_ADDR = 29u << 3, // 0xE8 HXFR_ADDR = 30u << 3, // 0xF0 HRSL_ADDR = 31u << 3, // 0xF8 }; enum { USBIRQ_OSCOK_IRQ = 1u << 0, USBIRQ_NOVBUS_IRQ = 1u << 5, USBIRQ_VBUS_IRQ = 1u << 6, }; enum { USBCTL_PWRDOWN = 1u << 4, USBCTL_CHIPRES = 1u << 5, }; enum { CPUCTL_IE = 1u << 0, CPUCTL_PULSEWID0 = 1u << 6, CPUCTL_PULSEWID1 = 1u << 7, }; enum { PINCTL_GPXA = 1u << 0, PINCTL_GPXB = 1u << 1, PINCTL_POSINT = 1u << 2, PINCTL_INTLEVEL = 1u << 3, PINCTL_FDUPSPI = 1u << 4, }; enum { HIRQ_BUSEVENT_IRQ = 1u << 0, HIRQ_RWU_IRQ = 1u << 1, HIRQ_RCVDAV_IRQ = 1u << 2, HIRQ_SNDBAV_IRQ = 1u << 3, HIRQ_SUSDN_IRQ = 1u << 4, HIRQ_CONDET_IRQ = 1u << 5, HIRQ_FRAME_IRQ = 1u << 6, HIRQ_HXFRDN_IRQ = 1u << 7, }; enum { MODE_HOST = 1u << 0, MODE_LOWSPEED = 1u << 1, MODE_HUBPRE = 1u << 2, MODE_SOFKAENAB = 1u << 3, MODE_SEPIRQ = 1u << 4, MODE_DELAYISO = 1u << 5, MODE_DMPULLDN = 1u << 6, MODE_DPPULLDN = 1u << 7, }; enum { HCTL_BUSRST = 1u << 0, HCTL_FRMRST = 1u << 1, HCTL_SAMPLEBUS = 1u << 2, HCTL_SIGRSM = 1u << 3, HCTL_RCVTOG0 = 1u << 4, HCTL_RCVTOG1 = 1u << 5, HCTL_SNDTOG0 = 1u << 6, HCTL_SNDTOG1 = 1u << 7, }; enum { HXFR_EPNUM_MASK = 0x0f, HXFR_SETUP = 1u << 4, HXFR_OUT_NIN = 1u << 5, HXFR_ISO = 1u << 6, HXFR_HS = 1u << 7, }; enum { HRSL_RESULT_MASK = 0x0f, HRSL_RCVTOGRD = 1u << 4, HRSL_SNDTOGRD = 1u << 5, HRSL_KSTATUS = 1u << 6, HRSL_JSTATUS = 1u << 7, }; enum { HRSL_SUCCESS = 0, HRSL_BUSY, HRSL_BAD_REQ, HRSL_UNDEF, HRSL_NAK, HRSL_STALL, HRSL_TOG_ERR, HRSL_WRONG_PID, HRSL_BAD_BYTECOUNT, HRSL_PID_ERR, HRSL_PKT_ERR, HRSL_CRC_ERR, HRSL_K_ERR, HRSL_J_ERR, HRSL_TIMEOUT, HRSL_BABBLE, }; enum { DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ | HIRQ_RCVDAV_IRQ }; enum { MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame to save CPU/SPI bus usage }; enum { EP_STATE_IDLE = 0, EP_STATE_COMPLETE = 1, EP_STATE_ABORTING = 2, EP_STATE_ATTEMPT_1 = 3, // Number of attempts to transfer in a frame. Incremented after each NAK EP_STATE_ATTEMPT_MAX = 15 }; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { uint8_t ep_num : 4; uint8_t is_setup : 1; uint8_t is_out : 1; uint8_t is_iso : 1; } hxfr_bm_t; TU_VERIFY_STATIC(sizeof(hxfr_bm_t) == 1, "size is not correct"); typedef struct { uint8_t daddr; union { hxfr_bm_t hxfr_bm; uint8_t hxfr; }; struct TU_ATTR_PACKED { uint8_t state : 4; uint8_t data_toggle : 1; uint16_t packet_size : 11; }; uint16_t total_len; uint16_t xferred_len; uint8_t* buf; } max3421_ep_t; TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); typedef struct { volatile uint16_t frame_count; // cached register uint8_t sndbc; uint8_t hirq; uint8_t hien; uint8_t mode; uint8_t peraddr; union { hxfr_bm_t hxfr_bm; uint8_t hxfr; }; // owner of data in SNDFIFO, for retrying NAKed without re-writing to FIFO struct { uint8_t daddr; uint8_t hxfr; }sndfifo_owner; bool busy_lock; // busy transferring #if OSAL_MUTEX_REQUIRED OSAL_MUTEX_DEF(spi_mutexdef); osal_mutex_t spi_mutex; #endif max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0 } max3421_data_t; static max3421_data_t _hcd_data; // max NAK before giving up in a frame. 0 means infinite NAKs static tuh_configure_max3421_t _tuh_cfg = { .max_nak = MAX_NAK_DEFAULT, .cpuctl = 0, // default: INT pulse width = 10.6 us .pinctl = 0, // default: negative edge interrupt }; //--------------------------------------------------------------------+ // SPI Commands and Helper //--------------------------------------------------------------------+ #define reg_read tuh_max3421_reg_read #define reg_write tuh_max3421_reg_write static void max3421_spi_lock(uint8_t rhport, bool in_isr) { // disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr if (!in_isr) { (void) osal_mutex_lock(_hcd_data.spi_mutex, OSAL_TIMEOUT_WAIT_FOREVER); tuh_max3421_int_api(rhport, false); } // assert CS tuh_max3421_spi_cs_api(rhport, true); } static void max3421_spi_unlock(uint8_t rhport, bool in_isr) { // de-assert CS tuh_max3421_spi_cs_api(rhport, false); // mutex unlock and re-enable interrupt if (!in_isr) { tuh_max3421_int_api(rhport, true); (void) osal_mutex_unlock(_hcd_data.spi_mutex); } } uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr) { uint8_t tx_buf[2] = {reg, 0}; uint8_t rx_buf[2] = {0, 0}; max3421_spi_lock(rhport, in_isr); bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2); max3421_spi_unlock(rhport, in_isr); _hcd_data.hirq = rx_buf[0]; return ret ? rx_buf[1] : 0; } bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr) { uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data}; uint8_t rx_buf[2] = {0, 0}; max3421_spi_lock(rhport, in_isr); bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2); max3421_spi_unlock(rhport, in_isr); // HIRQ register since we are in full-duplex mode _hcd_data.hirq = rx_buf[0]; return ret; } //-------------------------------------------------------------------- // Register helper //-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) { reg_write(rhport, HIRQ_ADDR, data, in_isr); // HIRQ write 1 is clear _hcd_data.hirq &= (uint8_t) ~data; } TU_ATTR_ALWAYS_INLINE static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.hien = data; reg_write(rhport, HIEN_ADDR, data, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.mode = data; reg_write(rhport, MODE_ADDR, data, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) { if (_hcd_data.peraddr == data) { return; // no need to change address } _hcd_data.peraddr = data; reg_write(rhport, PERADDR_ADDR, data, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.hxfr = data; reg_write(rhport, HXFR_ADDR, data, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.sndbc = data; reg_write(rhport, SNDBC_ADDR, data, in_isr); } //-------------------------------------------------------------------- // FIFO access (receive, send, setup) //-------------------------------------------------------------------- static void hwfifo_write(uint8_t rhport, uint8_t reg, const uint8_t* buffer, uint8_t len, bool in_isr) { uint8_t hirq; reg |= CMDBYTE_WRITE; max3421_spi_lock(rhport, in_isr); tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); _hcd_data.hirq = hirq; tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); max3421_spi_unlock(rhport, in_isr); } // Write to SNDFIFO if len > 0 and update SNDBC TU_ATTR_ALWAYS_INLINE static inline void hwfifo_send(uint8_t rhport, const uint8_t* buffer, uint8_t len, bool in_isr) { if (len) { hwfifo_write(rhport, SNDFIFO_ADDR, buffer, len, in_isr); } sndbc_write(rhport, len, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void hwfifo_setup(uint8_t rhport, const uint8_t* buffer, bool in_isr) { hwfifo_write(rhport, SUDFIFO_ADDR, buffer, 8, in_isr); } static void hwfifo_receive(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { uint8_t hirq; const uint8_t reg = RCVVFIFO_ADDR; max3421_spi_lock(rhport, in_isr); tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); _hcd_data.hirq = hirq; tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); max3421_spi_unlock(rhport, in_isr); } //--------------------------------------------------------------------+ // Endpoint helper //--------------------------------------------------------------------+ static max3421_ep_t* find_ep_not_addr0(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) { const uint8_t is_out = 1-ep_dir; for(size_t i=1; idaddr && ep_num == ep->hxfr_bm.ep_num && (ep_num == 0 || is_out == ep->hxfr_bm.is_out)) { return ep; } } return NULL; } // daddr = 0 and ep_num = 0 means find a free (allocate) endpoint TU_ATTR_ALWAYS_INLINE static inline max3421_ep_t * allocate_ep(void) { return find_ep_not_addr0(0, 0, 0); } TU_ATTR_ALWAYS_INLINE static inline max3421_ep_t * find_opened_ep(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) { if (daddr == 0 && ep_num == 0) { return &_hcd_data.ep[0]; }else{ return find_ep_not_addr0(daddr, ep_num, ep_dir); } } // free all endpoints belong to device address static void free_ep(uint8_t daddr) { for (size_t i=1; idaddr == daddr) { tu_memclr(ep, sizeof(max3421_ep_t)); } } } // Check if endpoint has a queued transfer and not reach max NAK in this frame TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { uint8_t const state = ep->state; return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && (_tuh_cfg.max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _tuh_cfg.max_nak); } // Find the next pending endpoint using round-robin scheduling, starting from next endpoint. // return NULL if not found // TODO respect interrupt endpoint's interval static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { size_t const idx = (size_t) (cur_ep - _hcd_data.ep); // starting from next endpoint for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; if (is_ep_pending(ep)) { return ep; } } // wrap around including current endpoint for (size_t i = 0; i <= idx; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; if (is_ep_pending(ep)) { return ep; } } return NULL; } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _tuh_cfg = cfg->max3421; _tuh_cfg.max_nak = tu_min8(_tuh_cfg.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); return true; } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; tuh_max3421_int_api(rhport, false); TU_LOG2_INT(sizeof(max3421_ep_t)); TU_LOG2_INT(sizeof(max3421_data_t)); TU_LOG2_INT(offsetof(max3421_data_t, ep)); tu_memclr(&_hcd_data, sizeof(_hcd_data)); _hcd_data.peraddr = 0xff; // invalid #if OSAL_MUTEX_REQUIRED _hcd_data.spi_mutex = osal_mutex_create(&_hcd_data.spi_mutexdef); #endif // NOTE: driver does not seem to work without nRST pin signal // full duplex, interrupt negative edge reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); // v1 is 0x01, v2 is 0x12, v3 is 0x13 // Note: v1 and v2 has host OUT errata whose workaround is not implemented in this driver uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); TU_LOG2_HEX(revision); TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); reg_write(rhport, USBCTL_ADDR, 0, false); while( !(reg_read(rhport, USBIRQ_ADDR, false) & USBIRQ_OSCOK_IRQ) ) { // wait for oscillator to stabilize } // Mode: Host and DP/DM pull down mode_write(rhport, MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST, false); // frame reset & bus reset, this will trigger CONDET IRQ if device is already connected reg_write(rhport, HCTL_ADDR, HCTL_BUSRST | HCTL_FRMRST, false); // clear all previously pending IRQ hirq_write(rhport, 0xff, false); // Enable IRQ hien_write(rhport, DEFAULT_HIEN, false); tuh_max3421_int_api(rhport, true); // Enable Interrupt pin reg_write(rhport, CPUCTL_ADDR, _tuh_cfg.cpuctl | CPUCTL_IE, false); return true; } bool hcd_deinit(uint8_t rhport) { (void) rhport; // disable interrupt tuh_max3421_int_api(rhport, false); // reset max3421 and power down reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); reg_write(rhport, USBCTL_ADDR, USBCTL_PWRDOWN, false); #if OSAL_MUTEX_REQUIRED osal_mutex_delete(_hcd_data.spi_mutex); _hcd_data.spi_mutex = NULL; #endif return true; } // Enable USB interrupt // Not actually enable GPIO interrupt, just set variable to prevent handler to process void hcd_int_enable (uint8_t rhport) { tuh_max3421_int_api(rhport, true); } // Disable USB interrupt // Not actually disable GPIO interrupt, just set variable to prevent handler to process void hcd_int_disable(uint8_t rhport) { tuh_max3421_int_api(rhport, false); } // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return (uint32_t ) _hcd_data.frame_count; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; return (_hcd_data.mode & MODE_SOFKAENAB) ? true : false; } // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport) { reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, false); } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { reg_write(rhport, HCTL_ADDR, 0, false); } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; return (_hcd_data.mode & MODE_LOWSPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; } // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_desc->bEndpointAddress); tusb_dir_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); max3421_ep_t * ep; if (daddr == 0 && ep_num == 0) { ep = &_hcd_data.ep[0]; }else { if (NULL != find_ep_not_addr0(daddr, ep_num, ep_dir)) { return true; // already opened } ep = allocate_ep(); TU_ASSERT(ep); ep->daddr = daddr; ep->hxfr_bm.ep_num = (uint8_t) (ep_num & 0x0f); ep->hxfr_bm.is_out = (ep_dir == TUSB_DIR_OUT) ? 1 : 0; ep->hxfr_bm.is_iso = (TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer) ? 1 : 0; } ep->packet_size = (uint16_t) (tu_edpt_packet_size(ep_desc) & 0x7ff); return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); max3421_ep_t * ep = find_ep_not_addr0(daddr, ep_num, ep_dir); if (!ep) { return false; // not opened } tu_memclr(ep, sizeof(max3421_ep_t)); return true; } /* The microcontroller repeatedly writes the SNDFIFO register R2 to load the FIFO with up to 64 data bytes. * Then the microcontroller writes the SNDBC register, which this does three things: * 1. Tells the MAX3421E SIE (Serial Interface Engine) how many bytes in the FIFO to send. * 2. Connects the SNDFIFO and SNDBC register to the USB logic for USB transmission. * 3. Clears the SNDBAVIRQ interrupt flag. If the second FIFO is available for µC loading, the SNDBAVIRQ immediately re-asserts. +-----------+ --->| SNDBC-A | / | SNDFIFO-A | / +-----------+ +------+ +-------------+ / +----------+ | MCU |------>| R2: SNDFIFO |---- << Write R7 Flip >> ---| MAX3241E | |(hcd) | | R7: SNDBC | / | SIE | +------+ +-------------+ / +----------+ +-----------+ / | SNDBC-B | / | SNDFIFO-B |<--- +-----------+ Note: xact_out() is called when starting a new transfer, continue a transfer (isr) or retry a transfer (NAK) For NAK retry, we do not need to write to FIFO or SNDBC register again. */ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { // Page 12: Programming BULK-OUT Transfers // TODO: double buffering for ISO transfer if (switch_ep) { peraddr_write(rhport, ep->daddr, in_isr); const uint8_t hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); reg_write(rhport, HCTL_ADDR, hctl, in_isr); } // Only write to sndfifo and sdnbc register if it is not a NAKed retry if (!(ep->daddr == _hcd_data.sndfifo_owner.daddr && ep->hxfr == _hcd_data.sndfifo_owner.hxfr)) { // skip SNDBAV IRQ check, overwrite sndfifo if needed const uint8_t xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); hwfifo_send(rhport, ep->buf, xact_len, in_isr); } _hcd_data.sndfifo_owner.daddr = ep->daddr; _hcd_data.sndfifo_owner.hxfr = ep->hxfr; hxfr_write(rhport, ep->hxfr, in_isr); } static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { // Page 13: Programming BULK-IN Transfers if (switch_ep) { peraddr_write(rhport, ep->daddr, in_isr); uint8_t const hctl = (ep->data_toggle ? HCTL_RCVTOG1 : HCTL_RCVTOG0); reg_write(rhport, HCTL_ADDR, hctl, in_isr); } hxfr_write(rhport, ep->hxfr, in_isr); } static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) { peraddr_write(rhport, ep->daddr, in_isr); hwfifo_setup(rhport, ep->buf, in_isr); hxfr_write(rhport, HXFR_SETUP, in_isr); } static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { if (ep->hxfr_bm.ep_num == 0 ) { // setup if (ep->hxfr_bm.is_setup) { xact_setup(rhport, ep, in_isr); return; } // status if (ep->buf == NULL || ep->total_len == 0) { const uint8_t hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); peraddr_write(rhport, ep->daddr, in_isr); hxfr_write(rhport, hxfr, in_isr); return; } } if (ep->hxfr_bm.is_out) { xact_out(rhport, ep, switch_ep, in_isr); }else { xact_in(rhport, ep, switch_ep, in_isr); } } // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = (uint8_t) tu_edpt_dir(ep_addr); max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_VERIFY(ep); if (ep_num == 0) { // control transfer can switch direction ep->hxfr_bm.is_out = ep_dir ? 0 : 1; ep->hxfr_bm.is_setup = 0; ep->data_toggle = 1; } ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; ep->state = EP_STATE_ATTEMPT_1; bool has_xfer = false; usbh_spin_lock(false); if (!_hcd_data.busy_lock) { _hcd_data.busy_lock = true; has_xfer = true; } usbh_spin_unlock(false); // carry out transfer if not busy if (has_xfer) { xact_generic(rhport, ep, true, false); } return true; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_VERIFY(ep); if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { hcd_int_disable(rhport); ep->state = EP_STATE_ABORTING; hcd_int_enable(rhport); } return true; } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]) { (void) rhport; max3421_ep_t* ep = find_opened_ep(daddr, 0, 0); TU_ASSERT(ep); ep->hxfr_bm.is_out = 1; ep->hxfr_bm.is_setup = 1; ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; ep->state = EP_STATE_ATTEMPT_1; bool has_xfer = false; usbh_spin_lock(false); if (!_hcd_data.busy_lock) { _hcd_data.busy_lock = true; has_xfer = true; } usbh_spin_unlock(false); // carry out transfer if not busy if (has_xfer) { xact_setup(rhport, ep, false); } return true; } // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; return false; } //--------------------------------------------------------------------+ // Interrupt Handler //--------------------------------------------------------------------+ static void handle_connect_irq(uint8_t rhport, bool in_isr) { uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); uint8_t const jk = hrsl & (HRSL_JSTATUS | HRSL_KSTATUS); uint8_t new_mode = MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST; TU_LOG2_HEX(jk); switch(jk) { case 0x00: // SEO is disconnected case (HRSL_JSTATUS | HRSL_KSTATUS): // SE1 is illegal mode_write(rhport, new_mode, in_isr); // port reset anyway, this will help to stable bus signal for next connection reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, in_isr); hcd_event_device_remove(rhport, in_isr); reg_write(rhport, HCTL_ADDR, 0, in_isr); break; default: { // Bus Reset also cause CONDET IRQ, skip if we are already connected and doing bus reset if ((_hcd_data.hirq & HIRQ_BUSEVENT_IRQ) && (_hcd_data.mode & MODE_SOFKAENAB)) { break; } // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) // However, since we are always in full speed mode, we can just check J-state if (jk == HRSL_KSTATUS) { new_mode |= MODE_LOWSPEED; TU_LOG3("Low speed\r\n"); }else { TU_LOG3("Full speed\r\n"); } new_mode |= MODE_SOFKAENAB; mode_write(rhport, new_mode, in_isr); // FIXME multiple MAX3421 rootdevice address is not 1 uint8_t const daddr = 1; free_ep(daddr); hcd_event_device_attach(rhport, in_isr); break; } } } static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) { const uint8_t ep_dir = 1 - ep->hxfr_bm.is_out; const uint8_t ep_addr = tu_edpt_addr(ep->hxfr_bm.ep_num, ep_dir); // save data toggle if (ep_dir) { ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1u : 0u; }else { ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1u : 0u; } ep->state = EP_STATE_IDLE; hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); // Find next pending endpoint max3421_ep_t * next_ep = find_next_pending_ep(ep); if (next_ep) { xact_generic(rhport, next_ep, true, in_isr); }else { // no more pending usbh_spin_lock(in_isr); _hcd_data.busy_lock = false; usbh_spin_unlock(in_isr); } } static void handle_xfer_done(uint8_t rhport, bool in_isr) { const uint8_t hrsl = reg_read(rhport, HRSL_ADDR, in_isr); const uint8_t hresult = hrsl & HRSL_RESULT_MASK; const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; const uint8_t hxfr_type = _hcd_data.hxfr & 0xf0; const uint8_t ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, ep_dir); TU_VERIFY(ep, ); xfer_result_t xfer_result; switch(hresult) { case HRSL_NAK: if (ep->state == EP_STATE_ABORTING) { ep->state = EP_STATE_IDLE; } else { if (ep_num == 0) { // control endpoint -> retry immediately and return hxfr_write(rhport, _hcd_data.hxfr, in_isr); return; } if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; } } max3421_ep_t * next_ep = find_next_pending_ep(ep); if (ep == next_ep) { // this endpoint is only one pending -> retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else if (next_ep) { // switch to next pending endpoint xact_generic(rhport, next_ep, true, in_isr); } else { // no more pending in this frame -> clear busy usbh_spin_lock(in_isr); _hcd_data.busy_lock = false; usbh_spin_unlock(in_isr); } return; case HRSL_BAD_REQ: // occurred when initialized without any pending transfer. Skip for now return; case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; break; case HRSL_STALL: xfer_result = XFER_RESULT_STALLED; break; default: TU_LOG3("HRSL: %02X\r\n", hrsl); xfer_result = XFER_RESULT_FAILED; break; } if (xfer_result != XFER_RESULT_SUCCESS) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); return; } if (ep_dir) { // IN transfer: fifo data is already received in RCVDAV IRQ // mark control handshake as complete if (hxfr_type & HXFR_HS) { ep->state = EP_STATE_COMPLETE; } // short packet or all bytes transferred if (ep->state == EP_STATE_COMPLETE) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { hxfr_write(rhport, _hcd_data.hxfr, in_isr); // more to transfer } } else { // SETUP or OUT transfer // clear sndfifo owner since data is sent _hcd_data.sndfifo_owner.daddr = 0xff; _hcd_data.sndfifo_owner.hxfr = 0xff; uint8_t xact_len; if (hxfr_type & HXFR_SETUP) { xact_len = 8; } else if (hxfr_type & HXFR_HS) { xact_len = 0; } else { xact_len = _hcd_data.sndbc; } ep->xferred_len += xact_len; ep->buf += xact_len; if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); } else { xact_out(rhport, ep, false, in_isr); // more to transfer } } } #if CFG_TUSB_DEBUG >= 3 void print_hirq(uint8_t hirq) { TU_LOG3_HEX(hirq); if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN"); if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME"); if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET"); if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN"); if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV"); if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV"); if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU"); if (hirq & HIRQ_BUSEVENT_IRQ) TU_LOG3(" BUSEVENT"); TU_LOG3("\r\n"); } #else #define print_hirq(hirq) #endif // Interrupt handler void hcd_int_handler(uint8_t rhport, bool in_isr) { uint8_t hirq = reg_read(rhport, HIRQ_ADDR, in_isr) & _hcd_data.hien; if (!hirq) { return; } // print_hirq(hirq); if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; // reset all endpoints nak counter, retry with 1st pending ep. max3421_ep_t* ep_retry = NULL; for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) { ep->state = EP_STATE_ATTEMPT_1; if (ep_retry == NULL) { ep_retry = ep; } } } // start usb transfer if not busy if (ep_retry != NULL) { bool has_xfer = false; usbh_spin_lock(in_isr); if (!_hcd_data.busy_lock) { _hcd_data.busy_lock = true; has_xfer = true; } usbh_spin_unlock(in_isr); if (has_xfer) { xact_generic(rhport, ep_retry, true, in_isr); } } } if (hirq & HIRQ_CONDET_IRQ) { handle_connect_irq(rhport, in_isr); } // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or // not call this handler again. So we need to loop until all IRQ are cleared while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) { if (hirq & HIRQ_RCVDAV_IRQ) { const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); uint8_t xact_len = 0; // RCVDAV_IRQ can trigger 2 times (dual buffered) while (hirq & HIRQ_RCVDAV_IRQ) { const uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); if (xact_len) { hwfifo_receive(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; } // ack RCVDVAV IRQ hirq_write(rhport, HIRQ_RCVDAV_IRQ, in_isr); hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { ep->state = EP_STATE_COMPLETE; } } if (hirq & HIRQ_HXFRDN_IRQ) { hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr); handle_xfer_done(rhport, in_isr); } hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing hirq &= (uint8_t) ~HIRQ_SNDBAV_IRQ; if (hirq) { hirq_write(rhport, hirq, in_isr); } } #endif ================================================ FILE: src/portable/analog/max3421/hcd_max3421.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HCD_MAX3421_H #define TUSB_HCD_MAX3421_H #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // SPI transfer API with MAX3421E are implemented by application // - spi_cs_api(), spi_xfer_api(), int_api() //--------------------------------------------------------------------+ // API to control MAX3421 SPI CS extern void tuh_max3421_spi_cs_api(uint8_t rhport, bool active); // API to transfer data with MAX3421 SPI // Either tx_buf or rx_buf can be NULL, which means transfer is write or read only extern bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes); // API to enable/disable MAX3421 INTR pin interrupt extern void tuh_max3421_int_api(uint8_t rhport, bool enabled); //--------------------------------------------------------------------+ // API for read/write MAX3421 registers // are implemented by this driver, can be used by application //--------------------------------------------------------------------+ // API to read MAX3421's register. Implemented by TinyUSB uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr); // API to write MAX3421's register. Implemented by TinyUSB bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/bridgetek/ft9xx/dcd_ft9xx.c ================================================ /* * The MIT License (MIT) * * Copyright 2021 Bridgetek Pte Ltd * * 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. * * This file is part of the TinyUSB stack. */ /* * Contains code adapted from Bridgetek Pte Ltd via license terms stated * in https://brtchip.com/BRTSourceCodeLicenseAgreement */ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X) #include #include #include #define USBD_USE_STREAMS #include "device/dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // Board code will determine the state of VBUS from USB host. extern int8_t board_ft9xx_vbus(void); extern int board_uart_write(void const *buf, int len); // Static array to store an incoming SETUP request for processing by tinyusb. CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _ft9xx_setup_packet[8]; struct ft9xx_xfer_state { volatile uint8_t ready; // OUT Transfer has been received and waiting for transfer. volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. int16_t total_size; // Total transfer size in bytes for this transfer. int16_t remain_size; // Total remaining in transfer. uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. uint8_t type; // Endpoint type. Of type USBD_ENDPOINT_TYPE from endpoint descriptor. uint8_t dir; // Endpoint direction. TUSB_DIR_OUT or TUSB_DIR_IN. For control endpoint this is the current direction. uint16_t buff_size; // Actual size of buffer RAM used by endpoint. uint16_t size; // Max packet size for endpoint from endpoint descriptor. }; // Endpoint description array for each endpoint. static struct ft9xx_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]; // USB speed. static tusb_speed_t _speed; // Interrupt handlers. void _ft9xx_usbd_ISR(void); // Interrupt handler for USB device. void ft9xx_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board). // Internal functions forward declarations. static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); static void _ft9xx_reset_edpts(void); static inline void _ft9xx_phy_enable(bool en); static void _ft9xx_usb_speed(void); static void _dcd_ft9xx_attach(void); static void _dcd_ft9xx_detach(void) __attribute__((unused)); static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); // Internal functions. // Manage an OUT transfer from the host. // This can be up-to the maximum packet size of the endpoint. // Continuation of a transfer beyond the maximum packet size is performed // by the interrupt handler. static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) { //Note: this is called from only the interrupt handler when an OUT transfer is called. uint16_t ep_size = ep_xfer[ep_number].size; (void)ep_size; if (xfer_bytes > ep_size) { xfer_bytes = ep_size; } // Wait until the endpoint has finished - it should be complete! //while (!(USBD_EP_SR_REG(ep_number) & MASK_USBD_EPxSR_OPRDY)) //; // Send the first packet of max packet size xfer_bytes = _ft9xx_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); if (ep_number == USBD_EP_0) { // Set flags to indicate data ready. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); } else { USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_OPRDY); } return xfer_bytes; } // Manage an IN transfer to the host. // This can be up-to the maximum packet size of the endpoint. // Continuation of a transfer beyond the maximum packet size is performed // by the interrupt handler. static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) { //Note: this may be called from the interrupt handler or from normal code. uint8_t end = 0; uint16_t ep_size = ep_xfer[ep_number].size; (void)ep_size; if ((xfer_bytes == 0) || (xfer_bytes < ep_size)) { end = 1; } else { xfer_bytes = ep_size; } if (ep_number == USBD_EP_0) { // An IN direction SETUP can be interrupted by an OUT packet. // This will result in a STALL generated by the silicon. while (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_STALL) { // Clear the STALL and finish the transaction. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_STALL); } } else { // If there is data to transmit then wait until the IN buffer // for the endpoint is empty. // This does not apply to interrupt endpoints. if (ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT) { uint8_t sr_reg; do { sr_reg = USBD_EP_SR_REG(ep_number); } while (sr_reg & MASK_USBD_EPxSR_INPRDY); } } // Do not send a ZLP for interrupt endpoints. if ((ep_xfer[ep_number].type != TUSB_XFER_INTERRUPT) || (xfer_bytes > 0)) { xfer_bytes = _ft9xx_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); } if (ep_number == USBD_EP_0) { if (end) { // Set flags to indicate data ready and transfer complete. USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_INPRDY | MASK_USBD_EP0SR_DATAEND; } else { // Set flags to indicate data ready. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_INPRDY); } } else { // Set flags to indicate data ready. USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_INPRDY); } return xfer_bytes; } // Reset all non-control endpoints to a default state. // Control endpoint is always enabled and ready. All others disabled. static void _ft9xx_reset_edpts(void) { // Disable all endpoints and remove configuration values. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { // Clear settings. tu_memclr(&ep_xfer[i], sizeof(struct ft9xx_xfer_state)); // Disable hardware. USBD_EP_CR_REG(i) = 0; } // Enable interrupts from USB device control. USBD_REG(cmie) = MASK_USBD_CMIE_ALL; } // Enable or disable the USB PHY. static inline void _ft9xx_phy_enable(bool en) { if (en) SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN; else SYS->PMCFG_L &= ~MASK_SYS_PMCFG_DEV_PHY_EN; } // Safely connect to the USB. static void _dcd_ft9xx_attach(void) { uint8_t reg; CRITICAL_SECTION_BEGIN // Disable device responses. USBD_REG(faddr) = 0; // Reset USB Device. SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; // Disable device connect/disconnect/host reset detection. SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_DIS_DEV; SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_CONN_DEV; SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); // Enable Chip USB device clock/PM configuration. sys_enable(sys_device_usb_device); CRITICAL_SECTION_END; // Wait a short time to get started. delayms(1); CRITICAL_SECTION_BEGIN // Turn off the device enable bit. #if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED USBD_REG(fctrl) = 0; #else // BOARD_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED //Set the full speed only bit if required. USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY; #endif // BOARD_TUD_MAX_SPEED // Clear first reset and suspend interrupts. do { reg = USBD_REG(cmif); USBD_REG(cmif) = reg; } while (reg); // Clear any endpoint interrupts. reg = USBD_REG(epif); USBD_REG(epif) = reg; // Disable all interrupts from USB device control before attaching interrupt. USBD_REG(cmie) = 0; CRITICAL_SECTION_END; // Enable device connect/disconnect/host reset detection. // Set device detect and remote wakeup enable interrupt enables. SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; #if defined(__FT930__) // Setup VBUS detect SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; #endif } // Gracefully disconnect from the USB. static void _dcd_ft9xx_detach(void) { // Disable device connect/disconnect/host reset detection. SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); #if defined(__FT930__) // Disable VBUS detection. SYS->MSC0CFG = SYS->MSC0CFG & (~MASK_SYS_MSC0CFG_USB_VBUS_EN); #endif CRITICAL_SECTION_BEGIN // Disable interrupts from USB. USBD_REG(epie) = 0; USBD_REG(cmie) = 0; // Turn off the device enable bit. USBD_REG(fctrl) = 0; CRITICAL_SECTION_END; delayms(1); // Disable USB PHY dcd_disconnect(BOARD_TUD_RHPORT); delayms(1); // Disable Chip USB device clock/PM configuration. sys_disable(sys_device_usb_device); // Reset USB Device... Needed for Back voltage D+ to be <400mV SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL; delayms(1); // Set device detect and remote wakeup enable interrupt enables. SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN; #if defined(__FT930__) // Setup VBUS detect SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN; #endif } // Determine the speed of the USB to which we are connected. // Set the speed of the PHY accordingly. // High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings. static void _ft9xx_usb_speed(void) { uint8_t fctrl_val; // If USB device function is already enabled then disable it. if (USBD_REG(fctrl) & MASK_USBD_FCTRL_USB_DEV_EN) { USBD_REG(fctrl) = (USBD_REG(fctrl) & (~MASK_USBD_FCTRL_USB_DEV_EN)); delayus(200); } #if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED /* Detect high or full speed */ fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN; #if defined(__FT900__) if (!sys_check_ft900_revB())//if 90x series is rev C { fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; } #endif USBD_REG(fctrl) = fctrl_val; #if defined(__FT930__) delayus(200); _speed = (SYS->MSC0CFG & MASK_SYS_MSC0CFG_HIGH_SPED_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; #else /* __FT930__ */ /* Detection by SOF */ while (!(USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ)); USBD_REG(cmif) = MASK_USBD_CMIF_SOFIRQ; delayus(125 + 5); _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); #endif /* !__FT930__ */ #else // BOARD_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED /* User force set to full speed */ _speed = TUSB_SPEED_FULL; fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN | MASK_USBD_FCTRL_MODE_FS_ONLY; #if defined(__FT900__) if (!sys_check_ft900_revB())//if 90x series is rev C { fctrl_val |= MASK_USBD_FCTRL_IMP_PERF; } #endif USBD_REG(fctrl) = fctrl_val; dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); return; #endif // BOARD_TUD_MAX_SPEED } // Send a buffer to the USB IN FIFO. // When the macro USBD_USE_STREAMS is defined this will stream a buffer of data // to the FIFO using the most efficient MCU streamout combination. // If streaming is disabled then it will send each byte of the buffer in turn // to the FIFO. The is no reason to not stream. // The total number of bytes sent to the FIFO is returned. static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) { uint16_t bytes_read = 0; uint16_t buff_size = length; #ifdef USBD_USE_STREAMS volatile uint8_t *data_reg; data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); if (buff_size) { if (((uint32_t)buffer) % 4 == 0) { uint16_t aligned = buff_size & (~3); uint16_t left = buff_size & 3; if (aligned) { __asm__ volatile("streamout.l %0,%1,%2" : : "r"(data_reg), "r"(buffer), "r"(aligned)); buffer += aligned; } if (left) { __asm__ volatile("streamout.b %0,%1,%2" : : "r"(data_reg), "r"(buffer), "r"(left)); } } else { __asm__ volatile("streamout.b %0,%1,%2" : : "r"(data_reg), "r"(buffer), "r"(buff_size)); } bytes_read = buff_size; } #else // USBD_USE_STREAMS bytes_read = buff_size; while (buff_size--) { USBD_EP_FIFO_REG(ep_number) = *buffer++; }; #endif // USBD_USE_STREAMS return bytes_read; } // Receive a buffer from the USB OUT FIFO. // When the macro USBD_USE_STREAMS is defined this will stream from the FIFO // to a buffer of data using the most efficient MCU streamin combination. // If streaming is disabled then it will receive each byte from the FIFO in turn // to the buffer. The is no reason to not stream. // The total number of bytes received from the FIFO is returned. static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) { #ifdef USBD_USE_STREAMS volatile uint8_t *data_reg; #endif // USBD_USE_STREAMS uint16_t bytes_read = 0; uint16_t buff_size = length; if (length > 0) { if (ep_number == USBD_EP_0) { buff_size = USBD_EP_CNT_REG(USBD_EP_0); } else { if (USBD_EP_SR_REG(ep_number) & (MASK_USBD_EPxSR_OPRDY)) { buff_size = USBD_EP_CNT_REG(ep_number); } } } // Only read as many bytes as we have space for. if (buff_size > length) buff_size = length; #ifdef USBD_USE_STREAMS data_reg = (volatile uint8_t *)&(USBD->ep[ep_number].epxfifo); if (buff_size) { if ((uint32_t)buffer % 4 == 0) { uint16_t aligned = buff_size & (~3); uint16_t left = buff_size & 3; if (aligned) { __asm__ volatile("streamin.l %0,%1,%2" : : "r"(buffer), "r"(data_reg), "r"(aligned)); buffer += aligned; } if (left) { __asm__ volatile("streamin.b %0,%1,%2" : : "r"(buffer), "r"(data_reg), "r"(left)); } } else { __asm__ volatile("streamin.b %0,%1,%2" : : "r"(buffer), "r"(data_reg), "r"(buff_size)); } bytes_read = buff_size; } #else // USBD_USE_STREAMS bytes_read = buff_size; while (buff_size--) { *buffer++ = USBD_EP_FIFO_REG(ep_number); } #endif // USBD_USE_STREAMS return bytes_read; } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; TU_LOG2("FT9xx initialisation\r\n"); _dcd_ft9xx_attach(); interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft9xx_usbd_ISR); dcd_connect(rhport); return true; } // Enable device interrupt void dcd_int_enable(uint8_t rhport) { (void)rhport; TU_LOG3("FT9xx int enable\r\n"); // Peripheral devices interrupt enable. interrupt_enable_globally(); } // Disable device interrupt void dcd_int_disable(uint8_t rhport) { (void)rhport; TU_LOG3("FT9xx int disable\r\n"); // Peripheral devices interrupt disable. interrupt_disable_globally(); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)rhport; (void)dev_addr; // Respond with status. There is no checking that the address is in range. dcd_edpt_xfer(rhport, tu_edpt_addr(USBD_EP_0, TUSB_DIR_IN), NULL, 0, false); // Set the update bit for the address register. dev_addr |= 0x80; // Modify the address register within a critical section. CRITICAL_SECTION_BEGIN { USBD_REG(faddr) = dev_addr; } CRITICAL_SECTION_END; } // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. #if 0 // never called void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { if (request->bRequest == TUSB_REQ_SET_ADDRESS) { } else if (request->bRequest == TUSB_REQ_SET_CONFIGURATION) { } } } #endif // 0 // Wake up host void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP; // At least 2 ms of delay needed for RESUME Data K state. delayms(2); SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP; // Enable USB PHY and determine current bus speed. dcd_connect(rhport); } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void)rhport; TU_LOG2("FT9xx connect\r\n"); CRITICAL_SECTION_BEGIN // Is device connected? if (board_ft9xx_vbus()) { // Clear/disable address register. USBD_REG(faddr) = 0; _ft9xx_phy_enable(true); // Determine bus speed and signal speed to tusb. _ft9xx_usb_speed(); } // Setup the control endpoint only. #if CFG_TUD_ENDPOINT0_SIZE == 64 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE); #elif CFG_TUD_ENDPOINT0_SIZE == 32 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE); #elif CFG_TUD_ENDPOINT0_SIZE == 16 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE); #elif CFG_TUD_ENDPOINT0_SIZE == 8 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE); #else #error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64." #endif CRITICAL_SECTION_END; // Configure the control endpoint. ep_xfer[USBD_EP_0].size = CFG_TUD_ENDPOINT0_SIZE; ep_xfer[USBD_EP_0].type = TUSB_XFER_CONTROL; // Enable interrupts on EP0. USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); // Restore default endpoint state. _ft9xx_reset_edpts(); } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void)rhport; TU_LOG2("FT9xx disconnect\r\n"); // Disable the USB PHY. _ft9xx_phy_enable(false); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) { (void)rhport; uint8_t const ep_number = tu_edpt_number(ep_desc->bEndpointAddress); uint8_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); uint8_t const ep_type = ep_desc->bmAttributes.xfer; uint16_t const ep_size = tu_edpt_packet_size(ep_desc); // Mask size per packet, bits 10..0. uint16_t ep_buff_size; uint8_t ep_reg_size = USBD_EP_MAX_SIZE_8; uint8_t ep_reg_data = 0; int16_t total_ram; TU_LOG2("FT9xx endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O'); // Check that the requested endpoint number is allowable. if (ep_number >= USBD_MAX_ENDPOINT_COUNT) { TU_LOG1("FT9xx endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); return false; } // Calculate the physical size of the endpoint as a power of 2. This may be more than // the requested size. while (ep_size > (8 * (1 << ep_reg_size))) { ep_reg_size++; } if (ep_reg_size > USBD_EP_MAX_SIZE_1024) { TU_LOG1("FT9xx endpoint size not valid: requested %d max 1024\r\n", ep_size); return false; } // Calculate actual amount of buffer RAM used by this endpoint. This may be more than the // requested size. ep_buff_size = 8 << ep_reg_size; if (ep_number > 0) { // Set EP cmd parameters... ep_reg_data |= (ep_reg_size << BIT_USBD_EP_MAX_SIZE); if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED) { // This could be because an endpoint has been assigned with the same number. // On FT9xx, IN and OUT endpoints may not have the same number. e.g. There // cannot been an 0x81 and 0x01 endpoint. TU_LOG1("FT9xx endpoint %d already assigned\r\n", ep_number); return false; } // Check that there is enough buffer RAM to allocate to this new endpoint. // Available buffer RAM depends on the device revision. // The IN and OUT buffer RAM should be the same size. if (ep_dir == USBD_DIR_IN) total_ram = USBD_RAMTOTAL_IN; else total_ram = USBD_RAMTOTAL_OUT; // Work out how much has been allocated to existing endpoints. // The total RAM allocated should always be a positive number as this // algorithm should not let it go below zero. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { if (ep_xfer[i].type != USBD_EP_TYPE_DISABLED) { if (ep_xfer[i].dir == ep_dir) { total_ram -= ep_xfer[i].buff_size; } } } if (sys_check_ft900_revB()) { // The control endpoint is taken into account as well on RevB silicon. total_ram -= ep_xfer[0].buff_size; } // Make sure we have enough space. The corner case is having zero bytes // free which means that total_ram must be signed as zero bytes free is // allowable. if (total_ram < ep_buff_size) { TU_LOG1("FT9xx insufficient buffer RAM for endpoint %d\r\n", ep_number); return false; } // Set the type of this endpoint in the control register. if (ep_type == TUSB_XFER_BULK) ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS); else if (ep_type == TUSB_XFER_INTERRUPT) ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS); else if (ep_type == TUSB_XFER_ISOCHRONOUS) ep_reg_data |= (USBD_EP_DIS_ISO << BIT_USBD_EP_CONTROL_DIS); // Set the direction of this endpoint in the control register. if (ep_dir == USBD_DIR_IN) ep_reg_data |= MASK_USBD_EPxCR_DIR; // Do not perform double buffering. //if ( != USBD_DB_OFF) //ep_reg_data |= MASK_USBD_EPxCR_DB; // Set the control register for this endpoint. USBD_EP_CR_REG(ep_number) = ep_reg_data; TU_LOG2("FT9xx endpoint setting %x\r\n", ep_reg_data); } else { // Set the control register for endpoint zero. USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE); } CRITICAL_SECTION_BEGIN // Store the endpoint characteristics for later reference. ep_xfer[ep_number].dir = ep_dir; ep_xfer[ep_number].type = ep_type; ep_xfer[ep_number].size = ep_size; ep_xfer[ep_number].buff_size = ep_buff_size; // Clear register transaction continuation and signalling state. ep_xfer[ep_number].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].buff_ptr = NULL; ep_xfer[ep_number].total_size = 0; ep_xfer[ep_number].remain_size = 0; CRITICAL_SECTION_END return true; } // Close all endpoints. void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; // Reset the endpoint configurations. _ft9xx_reset_edpts(); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; uint8_t ep_number = tu_edpt_number(ep_addr); uint8_t ep_dir = tu_edpt_dir(ep_addr); uint16_t xfer_bytes; bool status = false; // We will attempt to transfer the buffer. If it is less than or equal to the endpoint // maximum packet size then the whole buffer will be transferred. If it is larger then // the interrupt handler will transfer the remainder. // ep_xfer is used to tell the interrupt handler what to do. // ep_xfer can be used at interrupt level to continue transfers. CRITICAL_SECTION_BEGIN // Transfer currently in progress. if (ep_xfer[ep_number].valid == 0) { ep_xfer[ep_number].total_size = total_bytes; ep_xfer[ep_number].remain_size = total_bytes; ep_xfer[ep_number].buff_ptr = buffer; if (ep_number == USBD_EP_0) { ep_xfer[USBD_EP_0].dir = ep_dir; } else { // Enable the interrupt for this endpoint allowing the interrupt handler to report // continue the transfer and signal completion. USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number); } if (ep_dir == TUSB_DIR_IN) { // For IN transfers send the first packet as a starter. Interrupt handler to complete // this if it is larger than one packet. xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, buffer, total_bytes); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; // Tell the interrupt handler to signal dcd_event_xfer_complete on completion. ep_xfer[ep_number].valid = 1; } else // (dir == TUSB_DIR_OUT) { // For OUT transfers on the control endpoint. // The host may already have performed the first data transfer after the SETUP packet // before the transfer is setup for it. if (ep_xfer[ep_number].ready) { // We have received a data packet on the endpoint without a transfer // being initialised. This can be because the host has sent this packet before // a new transfer has been initiated on the endpoint. // We will now stream the data from the FIFO. ep_xfer[ep_number].ready = 0; // Transfer incoming data from an OUT packet to the buffer. xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, buffer, total_bytes); // Report completion of the transfer. dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number /*| TUSB_DIR_OUT_MASK */, xfer_bytes, XFER_RESULT_SUCCESS, false); } else { // Tell the interrupt handler to wait for the packet to be received and // then report the transfer complete with dcd_event_xfer_complete. ep_xfer[ep_number].valid = 1; } } status = true; } else { // Note: should not arrive here. } CRITICAL_SECTION_END return status; } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; (void)ep_addr; (void)ff; (void)total_bytes; bool status = false; return status; } // Stall endpoint (non-control endpoint) void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t ep_number = tu_edpt_number(ep_addr); (void)rhport; CRITICAL_SECTION_BEGIN if (ep_number == USBD_EP_0) { USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) | MASK_USBD_EP0CR_SDSTL; } else { USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) | MASK_USBD_EPxCR_SDSTL; USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE | MASK_USBD_EPxSR_FIFO_FLUSH; } CRITICAL_SECTION_END } // Clear stall (non-control endpoint), data toggle is also reset to DATA0 void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t ep_number = tu_edpt_number(ep_addr); (void)rhport; if (ep_number > USBD_EP_0) { CRITICAL_SECTION_BEGIN USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) & (~MASK_USBD_EPxCR_SDSTL); USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE; // Allow transfers to restart. ep_xfer[ep_number].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].remain_size = 0; CRITICAL_SECTION_END } } // Interrupt handling. void _ft9xx_usbd_ISR(void) { dcd_int_handler(BOARD_TUD_RHPORT); } void dcd_int_handler(uint8_t rhport) { (void)rhport; // Read the Common Interrupt Flag Register. uint8_t cmif = USBD_REG(cmif); // Read the Endpoint Interrupt Flag Register. #if defined(__FT930__) // This is 16 bits on FT93x. uint16_t epif = USBD_REG(epif); #else // This is 8 bits on FT90x. uint8_t epif = USBD_REG(epif); #endif if (cmif & MASK_USBD_CMIF_ALL) { // Clear all CMIF bits. USBD_REG(cmif) = MASK_USBD_CMIF_ALL; if (cmif & MASK_USBD_CMIF_PHYIRQ) //Handle PHY interrupt { } if (cmif & MASK_USBD_CMIF_PIDIRQ) //Handle PIDIRQ interrupt { } if (cmif & MASK_USBD_CMIF_CRC16IRQ) //Handle CRC16IRQ interrupt { } if (cmif & MASK_USBD_CMIF_CRC5IRQ) //Handle CRC5 interrupt { } if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt { // Reset endpoints to default state. _ft9xx_reset_edpts(); dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); } if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt { dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_SUSPEND, true); } if (cmif & MASK_USBD_CMIF_RESIRQ) //Handle Resume interrupt { dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } if (cmif & MASK_USBD_CMIF_SOFIRQ) //Handle SOF interrupt { dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_SOF, true); } } // Handle endpoint interrupts. if (epif) { uint16_t xfer_bytes; // Check for EP0 interrupts pending. if (epif & MASK_USBD_EPIF_EP0IRQ) { // Clear interrupt register. USBD_REG(epif) = MASK_USBD_EPIF_EP0IRQ; // Test for an incoming SETUP request on the control endpoint. if (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_SETUP) { // If protocol STALL, End the STALL signalling. if (USBD_EP_CR_REG(USBD_EP_0) & MASK_USBD_EP0CR_SDSTL) { // STALL end. USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) & (~MASK_USBD_EP0CR_SDSTL); // Clear STALL send. USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL; } // Host has sent a SETUP packet. Receive this into the SETUP packet store. _ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. dcd_event_setup_received(BOARD_TUD_RHPORT, _ft9xx_setup_packet, true); // Clear the interrupt that signals a SETUP packet is received. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); // Any SETUP packet will clear the incoming FIFO. ep_xfer[USBD_EP_0].ready = 0; // Allow new DATA and ACK transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; return; } else { // Check for a complete or partially complete transfers on EP0. if (ep_xfer[USBD_EP_0].valid) { xfer_bytes = (uint16_t)ep_xfer[USBD_EP_0].total_size; // Transfer incoming data from an OUT packet to the buffer supplied. if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT) { xfer_bytes = _ft9xx_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); } // Now signal completion of data packet. dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); // Incoming FIFO has been cleared. ep_xfer[USBD_EP_0].ready = 0; // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; } // No transfer is in flight for EP0. else { // We have received a data packet on the control endpoint without a transfer // being initialised. This can be because the host has sent this packet before // a new transfer has been initiated on the control endpoint. // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain // once the transfer is initiated. ep_xfer[USBD_EP_0].ready = 1; } } } else // !(epif & MASK_USBD_EPIF_EP0IRQ) { // Mask out currently disabled endpoints. epif &= USBD_REG(epie); // Handle complete and partially complete transfers for each endpoint. for (uint8_t ep_number = 1; ep_number < USBD_MAX_ENDPOINT_COUNT; ep_number++) { if ((epif & MASK_USBD_EPIF_IRQ(ep_number)) == 0) { // No pending interrupt for this endpoint. continue; } if (ep_xfer[ep_number].valid) { xfer_bytes = 0; // Clear interrupt register for this endpoint. USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number); // Start or continue an OUT transfer. if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) { xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); // Report each OUT packet received to the stack. dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number /* | TUSB_DIR_OUT_MASK */, xfer_bytes, XFER_RESULT_SUCCESS, true); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; } // continue an IN transfer else // if (ep_xfer[ep_number].dir == TUSB_DIR_IN) { if (ep_xfer[ep_number].remain_size > 0) { xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; } if (ep_xfer[ep_number].remain_size == 0) { dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number | TUSB_DIR_IN_MASK, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); } } // When the transfer is complete... if (ep_xfer[ep_number].remain_size == 0) { // Finish this transfer and allow new transfers on this endpoint. ep_xfer[ep_number].valid = 0; // Disable the interrupt for this endpoint now it is complete. USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number)); } ep_xfer[ep_number].ready = 0; } // No OUT transfer is in flight for this endpoint. else { if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) { // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain // once the transfer is initiated. // Strictly this should not happen for a non-control endpoint. Interrupts // are disabled when there are no transfers setup for an endpoint. ep_xfer[ep_number].ready = 1; } } } } } } // Power management interrupt handler. // This handles USB device related power management interrupts only. void ft9xx_usbd_pm_ISR(void) { uint16_t pmcfg = SYS->PMCFG_H; // Main interrupt handler is responible for if (pmcfg & MASK_SYS_PMCFG_DEV_CONN_DEV) { // Signal connection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV) { // Signal disconnection interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_UNPLUGGED, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV) { // Signal Host Reset interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_BUS_RESET, true); } if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV) { // Signal Host Resume interrupt SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; if (!(SYS->MSC0CFG & MASK_SYS_MSC0CFG_DEV_RMWAKEUP)) { // If we are driving K-state on Device USB port; // We must maintain the 1ms requirement before resuming the phy dcd_event_bus_signal(BOARD_TUD_RHPORT, DCD_EVENT_RESUME, true); } } } #endif ================================================ FILE: src/portable/chipidea/ci_fs/ci_fs_kinetis.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_FS_KINETIS_H #define _CI_FS_KINETIS_H #include "fsl_device_registers.h" //static const ci_fs_controller_t _ci_controller[] = { // {.reg_base = USB0_BASE, .irqnum = USB0_IRQn} //}; #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) #define CI_REG CI_FS_REG(0) void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB0_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB0_IRQn); } #endif ================================================ FILE: src/portable/chipidea/ci_fs/ci_fs_mcx.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_FS_MCX_H #define _CI_FS_MCX_H #include "fsl_device_registers.h" #if CFG_TUSB_MCU == OPT_MCU_MCXN9 #define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE) #define CIFS_IRQN USB0_FS_IRQn #elif CFG_TUSB_MCU == OPT_MCU_MCXA15 #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) #define CIFS_IRQN USB0_IRQn #else #error "MCU is not supported" #endif #define CI_REG CI_FS_REG(0) void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(CIFS_IRQN); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(CIFS_IRQN); } #endif ================================================ FILE: src/portable/chipidea/ci_fs/ci_fs_type.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_FS_TYPE_H #define _CI_FS_TYPE_H #include #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Note: some MCUs can only access these registers in 8-bit mode // align 4 is used to get rid of reserved fields #define _va32 volatile TU_ATTR_ALIGNED(4) typedef struct { _va32 uint8_t PER_ID; // [00] Peripheral ID register _va32 uint8_t ID_COMP; // [04] Peripheral ID complement register _va32 uint8_t REV; // [08] Peripheral revision register _va32 uint8_t ADD_INFO; // [0C] Peripheral additional info register _va32 uint8_t OTG_ISTAT; // [10] OTG Interrupt Status Register _va32 uint8_t OTG_ICTRL; // [14] OTG Interrupt Control Register _va32 uint8_t OTG_STAT; // [18] OTG Status Register _va32 uint8_t OTG_CTRL; // [1C] OTG Control register uint32_t reserved_20[24]; // [20] _va32 uint8_t INT_STAT; // [80] Interrupt status register _va32 uint8_t INT_EN; // [84] Interrupt enable register _va32 uint8_t ERR_STAT; // [88] Error interrupt status register _va32 uint8_t ERR_ENB; // [8C] Error interrupt enable register _va32 uint8_t STAT; // [90] Status register _va32 uint8_t CTL; // [94] Control register _va32 uint8_t ADDR; // [98] Address register _va32 uint8_t BDT_PAGE1; // [9C] BDT page register 1 _va32 uint8_t FRM_NUML; // [A0] Frame number register _va32 uint8_t FRM_NUMH; // [A4] Frame number register _va32 uint8_t TOKEN; // [A8] Token register _va32 uint8_t SOF_THLD; // [AC] SOF threshold register _va32 uint8_t BDT_PAGE2; // [B0] BDT page register 2 _va32 uint8_t BDT_PAGE3; // [B4] BDT page register 3 uint32_t reserved_b8; // [B8] uint32_t reserved_bc; // [BC] struct { _va32 uint8_t CTL; }EP[16]; // [C0] Endpoint control register //----- Following is only found available in NXP Kinetis _va32 uint8_t USBCTRL; // [100] USB Control register, _va32 uint8_t OBSERVE; // [104] USB OTG Observe register, _va32 uint8_t CONTROL; // [108] USB OTG Control register, _va32 uint8_t USBTRC0; // [10C] USB Transceiver Control Register 0, uint32_t reserved_110; // [110] _va32 uint8_t USBFRMADJUST; // [114] Frame Adjust Register, //----- Following is only found available in NXP MCX uint32_t reserved_118[3]; // [118] _va32 uint8_t KEEP_ALIVE_CTRL; // [124] Keep Alive Mode Control, _va32 uint8_t KEEP_ALIVE_WKCTRL; // [128] Keep Alive Mode Wakeup Control, _va32 uint8_t MISCCTRL; // [12C] Miscellaneous Control, _va32 uint8_t STALL_IL_DIS; // [130] Peripheral Mode Stall Disable for Endpoints[ 7..0] IN _va32 uint8_t STALL_IH_DIS; // [134] Peripheral Mode Stall Disable for Endpoints[15..8] IN _va32 uint8_t STALL_OL_DIS; // [138] Peripheral Mode Stall Disable for Endpoints[ 7..0] OUT _va32 uint8_t STALL_OH_DIS; // [13C] Peripheral Mode Stall Disable for Endpoints[15..8] OUT _va32 uint8_t CLK_RECOVER_CTRL; // [140] USB Clock Recovery Control, _va32 uint8_t CLK_RECOVER_IRC_EN; // [144] FIRC Oscillator Enable, uint32_t reserved_148[3]; // [148] _va32 uint8_t CLK_RECOVER_INT_EN; // [154] Clock Recovery Combined Interrupt Enable, uint32_t reserved_158; // [158] _va32 uint8_t CLK_RECOVER_INT_STATUS; // [15C] Clock Recovery Separated Interrupt Status, } ci_fs_regs_t; TU_VERIFY_STATIC(sizeof(ci_fs_regs_t) == 0x160, "Size is not correct"); typedef struct { uint32_t reg_base; uint32_t irqnum; } ci_fs_controller_t; #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/chipidea/ci_fs/dcd_ci_fs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS) #include "device/dcd.h" #include "ci_fs_type.h" #if defined(TUP_USBIP_CHIPIDEA_FS_KINETIS) #include "ci_fs_kinetis.h" #elif defined(TUP_USBIP_CHIPIDEA_FS_MCX) #include "ci_fs_mcx.h" #else #error "MCU is not supported" #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { TOK_PID_OUT = 0x1u, TOK_PID_IN = 0x9u, TOK_PID_SETUP = 0xDu, }; typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { uint16_t : 2; __IO uint16_t tok_pid : 4; uint16_t data : 1; __IO uint16_t own : 1; uint16_t : 8; }; struct { uint16_t : 2; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; uint16_t : 10; }; }; __IO uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; }buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { uint32_t max_packet_size :11; uint32_t : 5; uint32_t odd : 1; uint32_t :15; }; }; uint16_t length; uint16_t remaining; }endpoint_state_t; TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); typedef struct { union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; uint16_t bda[512]; }; TU_ATTR_ALIGNED(4) union { endpoint_state_t endpoint[16][2]; endpoint_state_t endpoint_unified[16 * 2]; }; uint8_t setup_packet[8]; uint8_t addr; }dcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); static void prepare_next_setup_packet(uint8_t rhport) { const unsigned out_odd = _dcd.endpoint[0][0].odd; const unsigned in_odd = _dcd.endpoint[0][1].odd; TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, ); _dcd.bdt[0][0][out_odd].data = 0; _dcd.bdt[0][0][out_odd ^ 1].data = 1; _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) { for (int i = 0; i < 16; ++i) { uint32_t const ep_ctl = CI_REG->EP[i].CTL; if (ep_ctl & USB_ENDPT_EPSTALL_MASK) { // prepare next setup if endpoint0 if ( i == 0 ) prepare_next_setup_packet(rhport); // clear stall bit CI_REG->EP[i].CTL = ep_ctl & ~USB_ENDPT_EPSTALL_MASK; } } } static void process_tokdne(uint8_t rhport) { const unsigned s = CI_REG->STAT; CI_REG->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); uint8_t const dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT; unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; /* fetch pid before discarded by the next steps */ const unsigned pid = bd->tok_pid; /* reset values for a next transfer */ bd->bdt_stall = 0; bd->dts = 1; bd->ninc = 0; bd->keep = 0; /* update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, bd->addr, true); CI_REG->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; return; } const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; if (remaining && bc == ep->max_packet_size) { /* continue the transferring consecutive data */ ep->remaining = remaining; const int next_remaining = remaining - ep->max_packet_size; if (next_remaining > 0) { /* prepare to the after next transfer */ bd->addr += ep->max_packet_size * 2; bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; __DSB(); bd->own = 1; /* the own bit must set after addr */ } return; } const unsigned length = ep->length; dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), length - remaining, XFER_RESULT_SUCCESS, true); if (0 == epnum && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ if (_dcd.addr) { /* When the transfer was the SetAddress, * the device address should be updated here. */ CI_REG->ADDR = _dcd.addr; _dcd.addr = 0; } prepare_next_setup_packet(rhport); } } static void process_bus_reset(uint8_t rhport) { CI_REG->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; CI_REG->CTL |= USB_CTL_ODDRST_MASK; CI_REG->ADDR = 0; CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; CI_REG->EP[0].CTL = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; for (unsigned i = 1; i < 16; ++i) { CI_REG->EP[i].CTL = 0; } buffer_descriptor_t *bd = _dcd.bdt[0][0]; for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } const endpoint_state_t ep0 = { .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, .odd = 0, .length = 0, .remaining = 0, }; _dcd.endpoint[0][0] = ep0; _dcd.endpoint[0][1] = ep0; tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); _dcd.addr = 0; prepare_next_setup_packet(rhport); CI_REG->CTL &= ~USB_CTL_ODDRST_MASK; dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } static void process_bus_sleep(uint8_t rhport) { // Enable resume & disable suspend interrupt const unsigned inten = CI_REG->INT_EN; CI_REG->INT_EN = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; CI_REG->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; CI_REG->USBCTRL |= USB_USBCTRL_SUSP_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } static void process_bus_resume(uint8_t rhport) { // Enable suspend & disable resume interrupt const unsigned inten = CI_REG->INT_EN; CI_REG->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; // will also clear USB_USBTRC0_USB_RESUME_INT_MASK CI_REG->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; CI_REG->INT_EN = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; // save crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 uint32_t clk_recover_irc_en = CI_REG->CLK_RECOVER_IRC_EN; uint32_t clk_recover_ctrl = CI_REG->CLK_RECOVER_CTRL; #endif CI_REG->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (CI_REG->USBTRC0 & USB_USBTRC0_USBRESET_MASK); // restore crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 CI_REG->CLK_RECOVER_IRC_EN = clk_recover_irc_en; CI_REG->CLK_RECOVER_CTRL |= clk_recover_ctrl; #endif tu_memclr(&_dcd, sizeof(_dcd)); CI_REG->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ CI_REG->BDT_PAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); CI_REG->BDT_PAGE2 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); CI_REG->BDT_PAGE3 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK; dcd_connect(rhport); // NVIC_ClearPendingIRQ(CIFS_IRQN); return true; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { _dcd.addr = dev_addr & 0x7F; /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; CI_REG->CTL |= USB_CTL_RESUME_MASK; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); CI_REG->CTL &= ~USB_CTL_RESUME_MASK; } void dcd_connect(uint8_t rhport) { (void) rhport; CI_REG->USBCTRL = 0; CI_REG->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; CI_REG->CTL |= USB_CTL_USBENSOFEN_MASK; } void dcd_disconnect(uint8_t rhport) { (void) rhport; CI_REG->CTL = 0; CI_REG->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ static bool edpt_open(uint8_t rhport, uint8_t ep_addr, uint16_t max_packet_size, tusb_xfer_type_t xfer) { (void)rhport; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; const unsigned odd = ep->odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; /* No support for control transfer */ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); ep->max_packet_size = max_packet_size; unsigned val = USB_ENDPT_EPCTLDIS_MASK; val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0; val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; CI_REG->EP[epn].CTL |= val; if (xfer != TUSB_XFER_ISOCHRONOUS) { bd[odd].dts = 1; bd[odd].data = 0; bd[odd ^ 1].dts = 1; bd[odd ^ 1].data = 1; } return true; } bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { return edpt_open(rhport, ep_desc->bEndpointAddress, tu_edpt_packet_size(ep_desc), ep_desc->bmAttributes.xfer); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { return edpt_open(rhport, ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS); } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { const unsigned epn = tu_edpt_number(ep_desc->bEndpointAddress); const unsigned dir = tu_edpt_dir(ep_desc->bEndpointAddress); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; dcd_int_disable(rhport); ep->max_packet_size = tu_edpt_packet_size(ep_desc); dcd_int_enable(rhport); return true; } void dcd_edpt_close_all(uint8_t rhport) { dcd_int_disable(rhport); for (unsigned i = 1; i < 16; ++i) { CI_REG->EP[i].CTL = 0; } dcd_int_enable(rhport); buffer_descriptor_t *bd = _dcd.bdt[1][0]; for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } endpoint_state_t *ep = &_dcd.endpoint[1][0]; for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) { /* Clear except the odd */ ep->max_packet_size = 0; ep->length = 0; ep->remaining = 0; } } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; TU_ASSERT(0 == bd->own); dcd_int_disable(rhport); ep->length = total_bytes; ep->remaining = total_bytes; const unsigned mps = ep->max_packet_size; if (total_bytes > mps) { buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; next->addr = buffer + mps; next->own = 1; } bd->bc = total_bytes >= mps ? mps: total_bytes; bd->addr = buffer; __DSB(); bd->own = 1; /* This bit must be set last */ dcd_int_enable(rhport); return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { CI_REG->EP[epn].CTL |= USB_ENDPT_EPSTALL_MASK; } else { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd]; TU_ASSERT(0 == bd->own,); dcd_int_disable(rhport); bd->bdt_stall = 1; __DSB(); bd->own = 1; /* This bit must be set last */ dcd_int_enable(rhport); } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { const unsigned epn = tu_edpt_number(ep_addr); TU_VERIFY(epn,); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; TU_VERIFY(bd[odd].own,); dcd_int_disable(rhport); bd[odd].own = 0; __DSB(); // clear stall bd[odd].bdt_stall = 0; // Reset data toggle bd[odd ].data = 0; bd[odd ^ 1].data = 1; // We already cleared this in ISR, but just clear it here to be safe const uint32_t ep_ctl = CI_REG->EP[epn].CTL; if (ep_ctl & USB_ENDPT_EPSTALL_MASK) { CI_REG->EP[epn].CTL = ep_ctl & ~USB_ENDPT_EPSTALL_MASK; } dcd_int_enable(rhport); } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { uint32_t is = CI_REG->INT_STAT; uint32_t msk = CI_REG->INT_EN; // clear non-enabled interrupts CI_REG->INT_STAT = is & ~msk; is &= msk; if (is & USB_ISTAT_ERROR_MASK) { /* TODO: */ uint32_t es = CI_REG->ERR_STAT; CI_REG->ERR_STAT = es; CI_REG->INT_STAT = is; /* discard any pending events */ } if (is & USB_ISTAT_USBRST_MASK) { CI_REG->INT_STAT = is; /* discard any pending events */ process_bus_reset(rhport); } if (is & USB_ISTAT_SLEEP_MASK) { // TU_LOG2("Suspend: "); TU_LOG2_HEX(is); // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good CI_REG->INT_STAT = USB_ISTAT_SLEEP_MASK; process_bus_sleep(rhport); } #if 0 // ISTAT_RESUME never trigger, probably for host mode ? if (is & USB_ISTAT_RESUME_MASK) { // TU_LOG2("ISTAT Resume: "); TU_LOG2_HEX(is); KHCI->ISTAT = USB_ISTAT_RESUME_MASK; process_bus_resume(rhport); } #endif if (CI_REG->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) { // TU_LOG2("USBTRC0 Resume: "); TU_LOG2_HEX(is); TU_LOG2_HEX(KHCI->USBTRC0); process_bus_resume(rhport); } if (is & USB_ISTAT_SOFTOK_MASK) { CI_REG->INT_STAT = USB_ISTAT_SOFTOK_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } if (is & USB_ISTAT_STALL_MASK) { CI_REG->INT_STAT = USB_ISTAT_STALL_MASK; process_stall(rhport); } if (is & USB_ISTAT_TOKDNE_MASK) { process_tokdne(rhport); } } #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_hpm.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_HS_HPM_H_ #define _CI_HS_HPM_H_ #include "ci_hs_type.h" #include "hpm_soc.h" #include "hpm_interrupt.h" #include "hpm_usb_drv.h" static const ci_hs_controller_t _ci_controller[] = { { .reg_base = HPM_USB0_BASE, .irqnum = IRQn_USB0}, #ifdef HPM_USB1_BASE { .reg_base = HPM_USB1_BASE, .irqnum = IRQn_USB1}, #endif }; #define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) //------------- DCD -------------// #define CI_DCD_INT_ENABLE(_p) intc_m_enable_irq (_ci_controller[_p].irqnum) #define CI_DCD_INT_DISABLE(_p) intc_m_disable_irq(_ci_controller[_p].irqnum) //------------- HCD -------------// #define CI_HCD_INT_ENABLE(_p) intc_m_enable_irq (_ci_controller[_p].irqnum) #define CI_HCD_INT_DISABLE(_p) intc_m_disable_irq(_ci_controller[_p].irqnum) #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_imxrt.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_HS_IMXRT_H_ #define _CI_HS_IMXRT_H_ #include "fsl_device_registers.h" #if !defined(USB1_BASE) && defined(USB_OTG1_BASE) #define USB1_BASE USB_OTG1_BASE #endif #if !defined(USB2_BASE) && defined(USB_OTG2_BASE) #define USB2_BASE USB_OTG2_BASE #endif // RT1040 calls its only USB USB_OTG (no 1) #if defined(MIMXRT1042_SERIES) #define USB_OTG1_IRQn USB_OTG_IRQn #endif static const ci_hs_controller_t _ci_controller[] = { // RT1010 and RT1020 only has 1 USB controller #if FSL_FEATURE_SOC_USBHS_COUNT == 1 { .reg_base = USB_BASE , .irqnum = USB_OTG1_IRQn } #else { .reg_base = USB1_BASE, .irqnum = USB_OTG1_IRQn}, { .reg_base = USB2_BASE, .irqnum = USB_OTG2_IRQn} #endif }; #define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) //------------- DCD -------------// #define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) #define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) //------------- HCD -------------// #define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) #define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) //------------- DCache -------------// #if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE #if __CORTEX_M == 7 TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) { if (size & (CFG_TUD_MEM_DCACHE_LINE_SIZE-1)) { size = (size & ~(CFG_TUD_MEM_DCACHE_LINE_SIZE-1)) + CFG_TUD_MEM_DCACHE_LINE_SIZE; } return size; } TU_ATTR_ALWAYS_INLINE static inline bool imxrt_is_cache_mem(uintptr_t addr) { return !(0x20000000 <= addr && addr < 0x20100000); } TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { TU_ASSERT(tu_is_aligned32(addr32)); data_size = round_up_to_cache_line_size(data_size); SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { // Invalidating does not push cached changes back to RAM so we need to be // *very* careful when we do it. If we're not aligned, then we risk resetting // values back to their RAM state. TU_ASSERT(tu_is_aligned32(addr32)); data_size = round_up_to_cache_line_size(data_size); SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { TU_ASSERT(tu_is_aligned32(addr32)); data_size = round_up_to_cache_line_size(data_size); SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } #elif __CORTEX_M == 4 #error "Secondary M4 core's cache controller is not supported yet." #endif #endif #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_HS_LPC18_43_H_ #define _CI_HS_LPC18_43_H_ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // LPCOpen for 18xx & 43xx #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif static const ci_hs_controller_t _ci_controller[] = { { .reg_base = LPC_USB0_BASE, .irqnum = USB0_IRQn }, { .reg_base = LPC_USB1_BASE, .irqnum = USB1_IRQn } }; #define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base) #define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) #define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) #define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum) #define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum) #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_mcx.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_HS_MCX_H_ #define _CI_HS_MCX_H_ #include "fsl_device_registers.h" // NOTE: MCX N9 has 2 different USB Controller // - USB0 is KHCI FullSpeed // - USB1 is ChipIdea HighSpeed, therefore rhport = 1 is actually index 0 static const ci_hs_controller_t _ci_controller[] = { {.reg_base = USBHS1__USBC_BASE, .irqnum = USB1_HS_IRQn} }; TU_ATTR_ALWAYS_INLINE static inline ci_hs_regs_t* CI_HS_REG(uint8_t port) { (void) port; return ((ci_hs_regs_t*) _ci_controller[0].reg_base); } #define CI_DCD_INT_ENABLE(_p) do { (void) _p; NVIC_EnableIRQ (_ci_controller[0].irqnum); } while (0) #define CI_DCD_INT_DISABLE(_p) do { (void) _p; NVIC_DisableIRQ(_ci_controller[0].irqnum); } while (0) #define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) #define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_rw61x.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _CI_HS_RW61X_H_ #define _CI_HS_RW61X_H_ #include "fsl_device_registers.h" static const ci_hs_controller_t _ci_controller[] = { {.reg_base = USBOTG_BASE, .irqnum = USB_IRQn} }; TU_ATTR_ALWAYS_INLINE static inline ci_hs_regs_t* CI_HS_REG(uint8_t port) { (void) port; return ((ci_hs_regs_t*) _ci_controller[0].reg_base); } #define CI_DCD_INT_ENABLE(_p) do { (void) _p; NVIC_EnableIRQ (_ci_controller[0].irqnum); } while (0) #define CI_DCD_INT_DISABLE(_p) do { (void) _p; NVIC_DisableIRQ(_ci_controller[0].irqnum); } while (0) #define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) #define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) #endif ================================================ FILE: src/portable/chipidea/ci_hs/ci_hs_type.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef CI_HS_TYPE_H_ #define CI_HS_TYPE_H_ #ifdef __cplusplus extern "C" { #endif // DCCPARAMS enum { DCCPARAMS_DEN_MASK = 0x1Fu, ///< DEN bit 4:0 }; // USBCMD enum { USBCMD_RUN_STOP = TU_BIT(0), USBCMD_RESET = TU_BIT(1), USBCMD_SETUP_TRIPWIRE = TU_BIT(13), USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14), // This bit is used as a semaphore to ensure the to proper addition of a // new dTD to an active (primed) endpoint’s linked list. This bit is set and // cleared by software during the process of adding a new dTD USBCMD_INTR_THRESHOLD_MASK = 0x00FF0000u, // Interrupt Threshold bit 23:16 }; // PORTSC1 #define PORTSC1_PORT_SPEED_POS 26 enum { PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), PORTSC1_SUSPEND = TU_BIT(7), PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27) }; // OTGSC enum { OTGSC_VBUS_DISCHARGE = TU_BIT(0), OTGSC_VBUS_CHARGE = TU_BIT(1), // OTGSC_HWASSIST_AUTORESET = TU_BIT(2), OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode OTGSC_DATA_PULSING = TU_BIT(4), OTGSC_ID_PULLUP = TU_BIT(5), // OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), // OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device OTGSC_A_VBUS_VALID = TU_BIT(9), OTGSC_A_SESSION_VALID = TU_BIT(10), OTGSC_B_SESSION_VALID = TU_BIT(11), OTGSC_B_SESSION_END = TU_BIT(12), OTGSC_1MS_TOGGLE = TU_BIT(13), OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), }; // USBMode enum { USBMOD_CM_MASK = TU_BIT(0) | TU_BIT(1), USBMODE_CM_DEVICE = 2, USBMODE_CM_HOST = 3, USBMODE_SLOM = TU_BIT(3), USBMODE_SDIS = TU_BIT(4), USBMODE_VBUS_POWER_SELECT = TU_BIT(5), // Need to be enabled for LPC18XX/43XX in host mode }; // Device Registers typedef struct { //------------- ID + HW Parameter Registers-------------// volatile uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX //------------- Capability Registers-------------// volatile uint8_t CAPLENGTH; ///< Capability Registers Length volatile uint8_t TU_RESERVED[1]; volatile uint16_t HCIVERSION; ///< Host Controller Interface Version volatile uint32_t HCSPARAMS; ///< Host Controller Structural Parameters volatile uint32_t HCCPARAMS; ///< Host Controller Capability Parameters volatile uint32_t TU_RESERVED[5]; volatile uint16_t DCIVERSION; ///< Device Controller Interface Version volatile uint8_t TU_RESERVED[2]; volatile uint32_t DCCPARAMS; ///< Device Controller Capability Parameters volatile uint32_t TU_RESERVED[6]; //------------- Operational Registers -------------// volatile uint32_t USBCMD; ///< USB Command Register volatile uint32_t USBSTS; ///< USB Status Register volatile uint32_t USBINTR; ///< Interrupt Enable Register volatile uint32_t FRINDEX; ///< USB Frame Index volatile uint32_t TU_RESERVED; volatile uint32_t DEVICEADDR; ///< Device Address volatile uint32_t ENDPTLISTADDR; ///< Endpoint List Address volatile uint32_t TU_RESERVED; volatile uint32_t BURSTSIZE; ///< Programmable Burst Size volatile uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning uint32_t TU_RESERVED[4]; volatile uint32_t ENDPTNAK; ///< Endpoint NAK volatile uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable volatile uint32_t TU_RESERVED; volatile uint32_t PORTSC1; ///< Port Status & Control volatile uint32_t TU_RESERVED[7]; volatile uint32_t OTGSC; ///< On-The-Go Status & control volatile uint32_t USBMODE; ///< USB Device Mode volatile uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status volatile uint32_t ENDPTPRIME; ///< Endpoint Prime volatile uint32_t ENDPTFLUSH; ///< Endpoint Flush volatile uint32_t ENDPTSTAT; ///< Endpoint Status volatile uint32_t ENDPTCOMPLETE; ///< Endpoint Complete volatile uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 } ci_hs_regs_t; typedef struct { uint32_t reg_base; uint32_t irqnum; }ci_hs_controller_t; #ifdef __cplusplus } #endif #endif /* CI_HS_TYPE_H_ */ ================================================ FILE: src/portable/chipidea/ci_hs/dcd_ci_hs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_HS) #include "device/dcd.h" #include "ci_hs_type.h" #if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX #include "ci_hs_imxrt.h" #if CFG_TUD_MEM_DCACHE_ENABLE bool dcd_dcache_clean(const void *addr, uint32_t data_size) { return imxrt_dcache_clean(addr, data_size); } bool dcd_dcache_invalidate(const void *addr, uint32_t data_size) { return imxrt_dcache_invalidate(addr, data_size); } bool dcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) { return imxrt_dcache_clean_invalidate(addr, data_size); } #endif #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" #elif TU_CHECK_MCU(OPT_MCU_MCXN9) // MCX N9 only port 1 use this controller #include "ci_hs_mcx.h" #elif TU_CHECK_MCU(OPT_MCU_HPM) #include "ci_hs_hpm.h" #elif TU_CHECK_MCU(OPT_MCU_RW61X) #include "ci_hs_rw61x.h" #else #error "Unsupported MCUs" #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // ENDPTCTRL enum { ENDPTCTRL_TYPE_POS = 2, // Endpoint type is 2-bit field }; enum { ENDPTCTRL_STALL = TU_BIT(0), ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), // used for test only ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), ENDPTCTRL_ENABLE = TU_BIT(7), }; #define ENDPTCTRL_TYPE(_type) ((_type) << ENDPTCTRL_TYPE_POS) #define ENDPTCTRL_RESET_MASK (ENDPTCTRL_TYPE(TUSB_XFER_BULK) | (ENDPTCTRL_TYPE(TUSB_XFER_BULK) << 16u)) // USBSTS, USBINTR enum { INTR_USB = TU_BIT(0), INTR_ERROR = TU_BIT(1), INTR_PORT_CHANGE = TU_BIT(2), INTR_RESET = TU_BIT(6), INTR_SOF = TU_BIT(7), INTR_SUSPEND = TU_BIT(8), INTR_NAK = TU_BIT(16) }; // Queue Transfer Descriptor typedef struct { // Word 0: Next QTD Pointer uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed // Word 1: qTQ Token uint32_t : 3; volatile uint32_t xact_err : 1; uint32_t : 1; volatile uint32_t buffer_err : 1; volatile uint32_t halted : 1; volatile uint32_t active : 1; uint32_t : 2; uint32_t iso_mult_override : 2; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. ///< This field must be zero for all packet types that are not transmit-ISO. uint32_t : 3; uint32_t int_on_complete : 1; volatile uint32_t total_bytes : 15; uint32_t : 1; // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The // lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the // start of a 4K page uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous //--------------------------------------------------------------------+ // TD is 32 bytes aligned but occupies only 28 bytes // Therefore there are 4 bytes padding that we can use. //--------------------------------------------------------------------+ uint16_t expected_bytes; uint8_t reserved[2]; } dcd_qtd_t; TU_VERIFY_STATIC(sizeof(dcd_qtd_t) == 32, "size is not correct"); // Queue Head typedef struct { // Word 0: Capabilities and Characteristics uint32_t : 15; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated ///< by the USB variable length protocol where N is computed using Max_packet_length and the ///< Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - ///< Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: ///< Isochronous endpoints must set MULT = 01, 10, or 11 as needed. uint32_t int_on_setup : 1; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is ///< set in response to a setup being received. uint32_t max_packet_size : 11; ///< Endpoint's wMaxPacketSize uint32_t : 2; uint32_t zero_length_termination : 1; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to ///< terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to ///< terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on ///< transfers that are equal in length to a multiple Max_packet_length. uint32_t iso_mult : 2; ///< // Word 1: Current qTD Pointer volatile uint32_t qtd_addr; // Word 2-9: Transfer Overlay volatile dcd_qtd_t qtd_overlay; // Word 10-11: Setup request (control OUT only) volatile tusb_control_request_t setup_request; //--------------------------------------------------------------------+ // QHD is 64 bytes aligned but occupies only 48 bytes // Therefore there are 16 bytes padding that we can use. //--------------------------------------------------------------------+ tu_fifo_t *ff; uint8_t reserved[12]; } dcd_qhd_t; TU_VERIFY_STATIC(sizeof(dcd_qhd_t) == 64, "size is not correct"); //--------------------------------------------------------------------+ // Variables //--------------------------------------------------------------------+ #define QTD_NEXT_INVALID 0x01 typedef struct { // Must be at 2K alignment // Each endpoint with direction (IN/OUT) occupies a queue head // for portability, TinyUSB only queue 1 TD for each Qhd dcd_qhd_t qhd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64); dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32); } dcd_data_t; CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t _dcd_data; //--------------------------------------------------------------------+ // Prototypes and Helper Functions //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint8_t ci_ep_count(const ci_hs_regs_t *dcd_reg) { return dcd_reg->DCCPARAMS & DCCPARAMS_DEN_MASK; } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ /// follows LPC43xx User Manual 23.10.3 static void bus_reset(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); // The reset value for all endpoint types is the control endpoint. If one endpoint // direction is enabled and the paired endpoint of opposite direction is disabled, then the // endpoint type of the unused direction must be changed from the control type to any other // type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior // for the data PID tracking on the active endpoint. const uint8_t ep_count = ci_ep_count(dcd_reg); for (uint8_t i = 1; i < ep_count; i++) { dcd_reg->ENDPTCTRL[i] = ENDPTCTRL_RESET_MASK; } //------------- Clear All Registers -------------// dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; dcd_reg->ENDPTNAKEN = 0; dcd_reg->USBSTS = dcd_reg->USBSTS; dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; while (dcd_reg->ENDPTPRIME) {} dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; while (dcd_reg->ENDPTFLUSH) {} // read reset bit in portsc //------------- Queue Head & Queue TD -------------// tu_memclr(&_dcd_data, sizeof(dcd_data_t)); //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// _dcd_data.qhd[0][0].zero_length_termination = _dcd_data.qhd[0][1].zero_length_termination = 1; _dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; _dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID; _dcd_data.qhd[0][0].int_on_setup = 1; // OUT only dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rh_init; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX); #if TU_CHECK_MCU(OPT_MCU_HPM) usb_phy_init((USB_Type *)dcd_reg, false); #endif // Reset controller dcd_reg->USBCMD |= USBCMD_RESET; while (dcd_reg->USBCMD & USBCMD_RESET) {} // Set mode to device, must be set immediately after reset uint32_t usbmode = dcd_reg->USBMODE & ~USBMOD_CM_MASK; usbmode |= USBMODE_CM_DEVICE; dcd_reg->USBMODE = usbmode; #ifdef CFG_TUD_CI_HS_VBUS_CHARGE dcd_reg->OTGSC = OTGSC_VBUS_CHARGE | OTGSC_OTG_TERMINATION; #else dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; #endif #if !TUD_OPT_HIGH_SPEED dcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; #endif #if TU_CHECK_MCU(OPT_MCU_HPM) dcd_reg->PORTSC1 &= ~USB_PORTSC1_STS_MASK; #endif dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); dcd_reg->ENDPTLISTADDR = (uint32_t)_dcd_data.qhd; // Endpoint List Address has to be 2K alignment dcd_reg->USBSTS = dcd_reg->USBSTS; dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND; uint32_t usbcmd = dcd_reg->USBCMD; usbcmd &= ~USBCMD_INTR_THRESHOLD_MASK; // Interrupt Threshold Interval = 0 usbcmd |= USBCMD_RUN_STOP; // run dcd_reg->USBCMD = usbcmd; return true; } bool dcd_deinit(uint8_t rhport) { ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); // disable all interrupt dcd_reg->USBINTR = 0; // unattach from bus dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; // flush all endpoints while (dcd_reg->ENDPTPRIME) {} dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; while (dcd_reg->ENDPTFLUSH) {} return true; } void dcd_int_enable(uint8_t rhport) { CI_DCD_INT_ENABLE(rhport); } void dcd_int_disable(uint8_t rhport) { CI_DCD_INT_DISABLE(rhport); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); } void dcd_remote_wakeup(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME; } void dcd_connect(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->USBCMD |= USBCMD_RUN_STOP; } void dcd_disconnect(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; } void dcd_sof_enable(uint8_t rhport, bool en) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); if (en) { dcd_reg->USBINTR |= INTR_SOF; } else { dcd_reg->USBINTR &= ~INTR_SOF; } } //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ static void qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes) { dcd_dcache_clean_invalidate((uint32_t *)tu_align((uint32_t)data_ptr, 4), total_bytes); tu_memclr(p_qtd, sizeof(dcd_qtd_t)); p_qtd->next = QTD_NEXT_INVALID; p_qtd->active = 1; p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; p_qtd->int_on_complete = true; if (data_ptr != NULL) { p_qtd->buffer[0] = (uint32_t)data_ptr; const uint32_t bufend = p_qtd->buffer[0] + total_bytes; for (uint8_t i = 1; i < 5; i++) { const uint32_t next_page = tu_align4k(p_qtd->buffer[i - 1]) + 4096; if (bufend <= next_page) { break; } p_qtd->buffer[i] = next_page; // TODO page[1] FRAME_N for ISO transfer } } } //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_write(volatile uint32_t *epctrl, uint8_t dir, uint32_t value) { if (dir == TUSB_DIR_OUT) { *epctrl = (*epctrl & 0xFFFF0000u) | value; } else { *epctrl = (*epctrl & 0x0000FFFFu) | (value << 16); } } TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_mask(volatile uint32_t *epctrl, uint8_t dir, uint32_t and_mask, uint32_t or_mask) { uint32_t value = *epctrl; if (and_mask != 0) { value &= (dir == TUSB_DIR_OUT) ? (and_mask | 0xFFFF0000u) : ((and_mask << 16u) | 0x0000FFFFu); } if (or_mask != 0) { value |= (dir == TUSB_DIR_OUT) ? or_mask : (or_mask << 16u); } *epctrl = value; } TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_set(volatile uint32_t *epctrl, uint8_t dir, uint32_t mask) { ep_ctrl_mask(epctrl, dir, 0, mask); } TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_clear(volatile uint32_t *epctrl, uint8_t dir, uint32_t mask) { ep_ctrl_mask(epctrl, dir, ~mask, 0); } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); // flush to abort any primed buffer dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0); dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0)); } static void qhd_init(dcd_qhd_t *p_qhd, uint16_t max_packet_size, uint8_t iso_mult) { tu_memclr(p_qhd, sizeof(dcd_qhd_t)); p_qhd->zero_length_termination = 1; p_qhd->max_packet_size = max_packet_size; p_qhd->iso_mult = iso_mult; p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); } bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *endpoint_desc) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); const uint8_t epnum = tu_edpt_number(endpoint_desc->bEndpointAddress); const uint8_t dir = tu_edpt_dir(endpoint_desc->bEndpointAddress); const uint8_t xfer_type = endpoint_desc->bmAttributes.xfer; TU_ASSERT(epnum < ci_ep_count(dcd_reg)); dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; qhd_init(p_qhd, tu_edpt_packet_size(endpoint_desc), 0u); // EP Control const uint32_t epctrl = ENDPTCTRL_TYPE(xfer_type) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; ep_ctrl_write(&dcd_reg->ENDPTCTRL[epnum], dir, epctrl); return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ci_ep_count(dcd_reg)); // EP Control: set type but not enabled yet const uint32_t epctrl = ENDPTCTRL_TYPE(TUSB_XFER_ISOCHRONOUS) | ENDPTCTRL_TOGGLE_RESET; ep_ctrl_write(&dcd_reg->ENDPTCTRL[epnum], dir, epctrl); return true; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { const uint8_t epnum = tu_edpt_number(desc_ep->bEndpointAddress); const uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); TU_ASSERT(epnum < ci_ep_count(dcd_reg)); dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; volatile uint32_t *endptctrl = &dcd_reg->ENDPTCTRL[epnum]; // _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; // dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); // Flush EP const uint32_t flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); dcd_reg->ENDPTFLUSH = flush_mask; while (dcd_reg->ENDPTFLUSH & flush_mask) {} // disable to change max packet size ep_ctrl_clear(endptctrl, dir, ENDPTCTRL_ENABLE); qhd_init(p_qhd, tu_edpt_packet_size(desc_ep), 1u); ep_ctrl_set(endptctrl, dir, ENDPTCTRL_ENABLE); return true; } void dcd_edpt_close_all(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); // Disable all non-control endpoints const uint8_t ep_count = ci_ep_count(dcd_reg); for (uint8_t epnum = 1; epnum < ep_count; epnum++) { _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; _dcd_data.qhd[epnum][TUSB_DIR_IN].qtd_overlay.halted = 1; dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum + 16); dcd_reg->ENDPTCTRL[epnum] = ENDPTCTRL_RESET_MASK; } } static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir]; p_qhd->qtd_overlay.halted = false; // clear any previous error p_qhd->qtd_overlay.next = (uint32_t)p_qtd; // link qtd to qhd // flush cache dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); if (epnum == 0) { // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out while (dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {} } // start transfer dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0)); } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { (void)is_isr; const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir]; // Prepare qtd qtd_init(p_qtd, buffer, total_bytes); // Start qhd transfer p_qhd->ff = NULL; qhd_start_xfer(rhport, epnum, dir); return true; } #if !CFG_TUD_MEM_DCACHE_ENABLE // fifo has to be aligned to 4k boundary // It's incompatible with dcache enabled transfer, since neither address nor size is aligned to cache line bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { (void)is_isr; const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir]; tu_fifo_buffer_info_t fifo_info; if (dir) { tu_fifo_get_read_info(ff, &fifo_info); } else { tu_fifo_get_write_info(ff, &fifo_info); } if (fifo_info.linear.len >= total_bytes) { // Linear length is enough for this transfer qtd_init(p_qtd, fifo_info.linear.ptr, total_bytes); } else { // linear part is not enough // prepare TD up to linear length qtd_init(p_qtd, fifo_info.linear.ptr, fifo_info.linear.len); if (!tu_offset4k((uint32_t)fifo_info.wrapped.ptr) && !tu_offset4k(tu_fifo_depth(ff))) { // If buffer is aligned to 4K & buffer size is multiple of 4K // We can make use of buffer page array to also combine the linear + wrapped length p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; for (uint8_t i = 1, page = 0; i < 5; i++) { // pick up buffer array where linear ends if (p_qtd->buffer[i] == 0) { p_qtd->buffer[i] = (uint32_t)fifo_info.wrapped.ptr + 4096 * page; page++; } } } else { // TODO we may need to carry the wrapped length after the linear part complete // for now only transfer up to linear part } } // Start qhd transfer p_qhd->ff = ff; qhd_start_xfer(rhport, epnum, dir); return true; } #endif //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir) { dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir]; uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : (p_qtd->xact_err || p_qtd->buffer_err) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; if (result != XFER_RESULT_SUCCESS) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); // flush to abort error buffer dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0)); } const uint16_t xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes; if (p_qhd->ff) { if (dir == TUSB_DIR_IN) { tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes); } else { tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes); } } // only number of bytes in the IOC qtd dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true); } void dcd_int_handler(uint8_t rhport) { ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); const uint32_t int_enable = dcd_reg->USBINTR; const uint32_t int_status = dcd_reg->USBSTS & int_enable; dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt // disabled interrupt sources if (int_status == 0) { return; } // Set if the port controller enters the full or high-speed operational state. // either from Bus Reset or Suspended state if (int_status & INTR_PORT_CHANGE) { // TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1); // Reset interrupt is not enabled, we manually check if Port Change is due // to connection / disconnection if (dcd_reg->USBSTS & INTR_RESET) { dcd_reg->USBSTS = INTR_RESET; if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) { const uint32_t speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS; bus_reset(rhport); dcd_event_bus_reset(rhport, (tusb_speed_t)speed, true); } else { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } else { // Triggered by resuming from suspended state if (!(dcd_reg->PORTSC1 & PORTSC1_SUSPEND)) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } } } if (int_status & INTR_SUSPEND) { // TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1); if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) { // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. // Skip suspend event if we are not addressed if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } } } if (int_status & INTR_USB) { // Make sure we read the latest version of _dcd_data. dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); const uint32_t edpt_complete = dcd_reg->ENDPTCOMPLETE; dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set // nothing to do, we will submit xfer as error to usbd // if (int_status & INTR_ERROR) { } if (edpt_complete) { for (uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) { if (tu_bit_test(edpt_complete, epnum)) { process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT); } if (tu_bit_test(edpt_complete, epnum + 16)) { process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN); } } } // Set up Received // 23.10.10.2 Operational model for setup transfers // Must be after normal transfer complete since it is possible to have both previous control status + new setup // in the same frame and we should handle previous status first. if (dcd_reg->ENDPTSETUPSTAT) { dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; dcd_event_setup_received(rhport, (uint8_t *)(uintptr_t)&_dcd_data.qhd[0][0].setup_request, true); } } if (int_status & INTR_SOF) { const uint32_t frame = dcd_reg->FRINDEX; dcd_event_sof(rhport, frame, true); } } #endif ================================================ FILE: src/portable/chipidea/ci_hs/hcd_ci_hs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" // Chipidea Highspeed USB IP implement EHCI for host functionality #if CFG_TUH_ENABLED && defined(TUP_USBIP_EHCI) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "common/tusb_common.h" #include "host/hcd.h" #include "host/usbh.h" #include "portable/ehci/ehci_api.h" #include "ci_hs_type.h" #if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX #include "ci_hs_imxrt.h" #if CFG_TUH_MEM_DCACHE_ENABLE bool hcd_dcache_clean(const void *addr, uint32_t data_size) { return imxrt_dcache_clean(addr, data_size); } bool hcd_dcache_invalidate(const void *addr, uint32_t data_size) { return imxrt_dcache_invalidate(addr, data_size); } bool hcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) { return imxrt_dcache_clean_invalidate(addr, data_size); } #endif #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #include "ci_hs_lpc18_43.h" #elif TU_CHECK_MCU(OPT_MCU_HPM) #include "ci_hs_hpm.h" #elif TU_CHECK_MCU(OPT_MCU_RW61X) #include "ci_hs_rw61x.h" #else #error "Unsupported MCUs" #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rh_init; ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport); #if CFG_TUSB_MCU == OPT_MCU_HPM usb_phy_init((USB_Type *)hcd_reg, true); #endif // Reset controller hcd_reg->USBCMD |= USBCMD_RESET; while (hcd_reg->USBCMD & USBCMD_RESET) {} // Set mode to host, must be set immediately after reset #if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX // LPC18XX/43XX need to set VBUS Power Select to HIGH hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; #else hcd_reg->USBMODE = USBMODE_CM_HOST; #endif #if !TUH_OPT_HIGH_SPEED hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; #endif return ehci_init(rhport, (uint32_t)&hcd_reg->CAPLENGTH, (uint32_t)&hcd_reg->USBCMD); } bool hcd_deinit(uint8_t rhport) { return ehci_deinit(rhport); } void hcd_int_enable(uint8_t rhport) { CI_HCD_INT_ENABLE(rhport); } void hcd_int_disable(uint8_t rhport) { CI_HCD_INT_DISABLE(rhport); } #endif ================================================ FILE: src/portable/dialog/da146xx/dcd_da146xx.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X #include "mcu/mcu.h" #include "device/dcd.h" /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ // Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) // We disable SOF for now until needed later on #define USE_SOF 0 // Size of RX or TX FIFO. #define FIFO_SIZE 64 #ifndef TU_DA1469X_FIFO_READ_THRESHOLD // RX FIFO is 64 bytes. When endpoint size is greater then 64, FIFO warning interrupt // is enabled to allow read incoming data during frame reception. // It is possible to stay in interrupt reading whole packet at once, but it may be // more efficient for MCU to read as much data as possible and when FIFO is hardly // filled exit interrupt handler waiting for next FIFO warning level interrupt // or packet end. // When running at 96MHz code that reads FIFO based on number of bytes stored in // USB_RXSx_REG.USB_RXCOUNT takes enough time to fill FIFO with two additional bytes. // Settings this threshold above this allows to leave interrupt handler and wait // for more bytes to before next ISR. This allows reduce overall ISR time to 1/3 // of time that would be needed if ISR read as fast as possible. #define TU_DA1469X_FIFO_READ_THRESHOLD 4 #endif #define EP_MAX 4 // Node functional states #define NFSR_NODE_RESET 0 #define NFSR_NODE_RESUME 1 #define NFSR_NODE_OPERATIONAL 2 #define NFSR_NODE_SUSPEND 3 // Those two following states are added to allow going out of sleep mode // using frame interrupt. On remove wakeup RESUME state must be kept for // at least 1ms. It is accomplished by using FRAME interrupt that goes // through those two fake states before entering OPERATIONAL state. #define NFSR_NODE_WAKING (0x10 | (NFSR_NODE_RESUME)) #define NFSR_NODE_WAKING2 (0x20 | (NFSR_NODE_RESUME)) static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8]; typedef struct { union { __IOM uint32_t epc_in; __IOM uint32_t USB_EPC0_REG; /*!< (@ 0x00000080) Endpoint Control 0 Register */ __IOM uint32_t USB_EPC1_REG; /*!< (@ 0x000000A0) Endpoint Control Register 1 */ __IOM uint32_t USB_EPC3_REG; /*!< (@ 0x000000C0) Endpoint Control Register 3 */ __IOM uint32_t USB_EPC5_REG; /*!< (@ 0x000000E0) Endpoint Control Register 5 */ }; union { __IOM uint32_t txd; __IOM uint32_t USB_TXD0_REG; /*!< (@ 0x00000084) Transmit Data 0 Register */ __IOM uint32_t USB_TXD1_REG; /*!< (@ 0x000000A4) Transmit Data Register 1 */ __IOM uint32_t USB_TXD2_REG; /*!< (@ 0x000000C4) Transmit Data Register 2 */ __IOM uint32_t USB_TXD3_REG; /*!< (@ 0x000000E4) Transmit Data Register 3 */ }; union { __IOM uint32_t txs; __IOM uint32_t USB_TXS0_REG; /*!< (@ 0x00000088) Transmit Status 0 Register */ __IOM uint32_t USB_TXS1_REG; /*!< (@ 0x000000A8) Transmit Status Register 1 */ __IOM uint32_t USB_TXS2_REG; /*!< (@ 0x000000C8) Transmit Status Register 2 */ __IOM uint32_t USB_TXS3_REG; /*!< (@ 0x000000E8) Transmit Status Register 3 */ }; union { __IOM uint32_t txc; __IOM uint32_t USB_TXC0_REG; /*!< (@ 0x0000008C) Transmit command 0 Register */ __IOM uint32_t USB_TXC1_REG; /*!< (@ 0x000000AC) Transmit Command Register 1 */ __IOM uint32_t USB_TXC2_REG; /*!< (@ 0x000000CC) Transmit Command Register 2 */ __IOM uint32_t USB_TXC3_REG; /*!< (@ 0x000000EC) Transmit Command Register 3 */ }; union { __IOM uint32_t epc_out; __IOM uint32_t USB_EP0_NAK_REG; /*!< (@ 0x00000090) EP0 INNAK and OUTNAK Register */ __IOM uint32_t USB_EPC2_REG; /*!< (@ 0x000000B0) Endpoint Control Register 2 */ __IOM uint32_t USB_EPC4_REG; /*!< (@ 0x000000D0) Endpoint Control Register 4 */ __IOM uint32_t USB_EPC6_REG; /*!< (@ 0x000000F0) Endpoint Control Register 6 */ }; union { __IOM uint32_t rxd; __IOM uint32_t USB_RXD0_REG; /*!< (@ 0x00000094) Receive Data 0 Register */ __IOM uint32_t USB_RXD1_REG; /*!< (@ 0x000000B4) Receive Data Register,1 */ __IOM uint32_t USB_RXD2_REG; /*!< (@ 0x000000D4) Receive Data Register 2 */ __IOM uint32_t USB_RXD3_REG; /*!< (@ 0x000000F4) Receive Data Register 3 */ }; union { __IOM uint32_t rxs; __IOM uint32_t USB_RXS0_REG; /*!< (@ 0x00000098) Receive Status 0 Register */ __IOM uint32_t USB_RXS1_REG; /*!< (@ 0x000000B8) Receive Status Register 1 */ __IOM uint32_t USB_RXS2_REG; /*!< (@ 0x000000D8) Receive Status Register 2 */ __IOM uint32_t USB_RXS3_REG; /*!< (@ 0x000000F8) Receive Status Register 3 */ }; union { __IOM uint32_t rxc; __IOM uint32_t USB_RXC0_REG; /*!< (@ 0x0000009C) Receive Command 0 Register */ __IOM uint32_t USB_RXC1_REG; /*!< (@ 0x000000BC) Receive Command Register 1 */ __IOM uint32_t USB_RXC2_REG; /*!< (@ 0x000000DC) Receive Command Register 2 */ __IOM uint32_t USB_RXC3_REG; /*!< (@ 0x000000FC) Receive Command Register 3 */ }; } volatile EPx_REGS; #define EP_REGS(first_ep_reg) (EPx_REGS*)(&USB->first_ep_reg) // DMA channel pair to use, channel 6 will be used for RX channel 7 for TX direction. #ifndef TU_DA146XX_DMA_RX_CHANNEL #define TU_DA146XX_DMA_RX_CHANNEL 6 #endif #define DA146XX_DMA_USB_MUX (0x6 << (TU_DA146XX_DMA_RX_CHANNEL * 2)) #define DA146XX_DMA_USB_MUX_MASK (0xF << (TU_DA146XX_DMA_RX_CHANNEL * 2)) typedef struct { __IOM uint32_t DMAx_A_START_REG; __IOM uint32_t DMAx_B_START_REG; __IOM uint32_t DMAx_INT_REG; __IOM uint32_t DMAx_LEN_REG; __IOM uint32_t DMAx_CTRL_REG; __IOM uint32_t DMAx_IDX_REG; __IM uint32_t RESERVED[2]; // Extend structure size for array like usage, registers for each channel are 0x20 bytes apart. } da146xx_dma_channel_t; #define DMA_CHANNEL_REGS(n) ((da146xx_dma_channel_t *)(DMA) + n) #define RX_DMA_REGS DMA_CHANNEL_REGS(TU_DA146XX_DMA_RX_CHANNEL) #define TX_DMA_REGS DMA_CHANNEL_REGS((TU_DA146XX_DMA_RX_CHANNEL) + 1) #define RX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\ (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \ (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \ (1 << DMA_DMA0_CTRL_REG_BINC_Pos) | \ (0 << DMA_DMA0_CTRL_REG_AINC_Pos) | \ (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \ (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \ (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \ (0 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos)) #define TX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\ (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \ (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_BINC_Pos) | \ (1 << DMA_DMA0_CTRL_REG_AINC_Pos) | \ (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \ (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \ (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \ (1 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \ (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos)) // Dialog register fields and bit mask are very long. Filed masks repeat register names. // Those convenience macros are a way to reduce complexity of register modification lines. #define GET_BIT(val, field) (val & field ## _Msk) >> field ## _Pos #define REG_GET_BIT(reg, field) (USB->reg & USB_ ## reg ## _ ## field ## _Msk) #define REG_SET_BIT(reg, field) USB->reg |= USB_ ## reg ## _ ## field ## _Msk #define REG_CLR_BIT(reg, field) USB->reg &= ~USB_ ## reg ## _ ## field ## _Msk #define REG_SET_VAL(reg, field, val) USB->reg = (USB->reg & ~USB_ ## reg ## _ ## field ## _Msk) | (val << USB_ ## reg ## _ ## field ## _Pos) static EPx_REGS * const ep_regs[EP_MAX] = { EP_REGS(USB_EPC0_REG), EP_REGS(USB_EPC1_REG), EP_REGS(USB_EPC3_REG), EP_REGS(USB_EPC5_REG), }; typedef struct { uint8_t * buffer; // Total length of current transfer uint16_t total_len; // Bytes transferred so far uint16_t transferred; uint16_t max_packet_size; // Packet size sent or received so far. It is used to modify transferred field // after ACK is received or when filling ISO endpoint with size larger then // FIFO size. uint16_t last_packet_size; uint8_t ep_addr; // DATA0/1 toggle bit 1 DATA1 is expected or transmitted uint8_t data1 : 1; // Endpoint is stalled uint8_t stall : 1; // ISO endpoint uint8_t iso : 1; } xfer_ctl_t; static struct { bool vbus_present; bool init_called; uint8_t nfsr; xfer_ctl_t xfer_status[EP_MAX][2]; // Endpoints that use DMA, one for each direction uint8_t dma_ep[2]; } _dcd = { .vbus_present = false, .init_called = false, }; // Converts xfer pointer to epnum (0,1,2,3) regardless of xfer direction #define XFER_EPNUM(xfer) ((xfer - &_dcd.xfer_status[0][0]) >> 1) // Converts xfer pointer to EPx_REGS pointer (returns same pointer for IN and OUT with same endpoint number) #define XFER_REGS(xfer) ep_regs[XFER_EPNUM(xfer)] // Converts epnum (0,1,2,3) to EPx_REGS pointer #define EPNUM_REGS(epnum) ep_regs[epnum] // Two endpoint 0 descriptor definition for unified dcd_edpt_open() static const tusb_desc_endpoint_t ep0OUT_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0x00, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, .bInterval = 0 }; static const tusb_desc_endpoint_t ep0IN_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0x80, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, .bInterval = 0 }; #define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] static void set_nfsr(uint8_t val) { _dcd.nfsr = val; // Write only lower 2 bits to register, higher bits are used // to count down till OPERATIONAL state can be entered when // remote wakeup activated. USB->USB_NFSR_REG = val & 3; } static void fill_tx_fifo(xfer_ctl_t * xfer) { int left_to_send; uint8_t const *src; uint8_t const epnum = tu_edpt_number(xfer->ep_addr); EPx_REGS *regs = EPNUM_REGS(epnum); src = &xfer->buffer[xfer->transferred]; left_to_send = xfer->total_len - xfer->transferred; if (left_to_send > xfer->max_packet_size - xfer->last_packet_size) { left_to_send = xfer->max_packet_size - xfer->last_packet_size; } // Loop checks TCOUNT all the time since this value is saturated to 31 // and can't be read just once before. while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0) { regs->txd = *src++; xfer->last_packet_size++; left_to_send--; } if (epnum != 0) { if (left_to_send > 0) { // Max packet size is set to value greater then FIFO. Enable fifo level warning // to handle larger packets. regs->txc |= (3 << USB_USB_TXC1_REG_USB_TFWL_Pos); USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos); } else { regs->txc &= ~USB_USB_TXC1_REG_USB_TFWL_Msk; USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos)); // Whole packet already in fifo, no need to refill it later. Mark last. regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk; } } } static bool try_allocate_dma(uint8_t epnum, uint8_t dir) { // TODO: Disable interrupts while checking if (_dcd.dma_ep[dir] == 0) { _dcd.dma_ep[dir] = epnum; if (dir == TUSB_DIR_OUT) USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_RX_Msk) | ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_RX_Pos); else USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_TX_Msk) | ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_TX_Pos); USB->USB_DMA_CTRL_REG |= USB_USB_DMA_CTRL_REG_USB_DMA_EN_Msk; } return _dcd.dma_ep[dir] == epnum; } static void start_rx_dma(volatile void *src, void *dst, uint16_t size) { // Setup SRC and DST registers RX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src; RX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst; // Don't need DMA interrupt, read end is determined by RX_LAST or RX_ERR events. RX_DMA_REGS->DMAx_INT_REG = size - 1; RX_DMA_REGS->DMAx_LEN_REG = size - 1; RX_DMA_REGS->DMAx_CTRL_REG = RX_DMA_START; } static void start_rx_packet(xfer_ctl_t *xfer) { uint8_t const epnum = tu_edpt_number(xfer->ep_addr); uint16_t remaining = xfer->total_len - xfer->transferred; uint16_t size = tu_min16(remaining, xfer->max_packet_size); EPx_REGS *regs = XFER_REGS(xfer); xfer->last_packet_size = 0; if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE) { if (try_allocate_dma(epnum, TUSB_DIR_OUT)) { start_rx_dma(®s->rxd, xfer->buffer + xfer->transferred, size); } else { // Other endpoint is using DMA in that direction, fall back to interrupts. // For endpoint size greater than FIFO size enable FIFO level warning interrupt // when FIFO has less than 17 bytes free. regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk; USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos); } } else if (epnum != 0) { // If max_packet_size would fit in FIFO no need for FIFO level warning interrupt. regs->rxc &= ~USB_USB_RXC1_REG_USB_RFWL_Msk; USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos)); } regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; } static void start_tx_dma(void *src, volatile void *dst, uint16_t size) { // Setup SRC and DST registers TX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src; TX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst; // Interrupt not needed TX_DMA_REGS->DMAx_INT_REG = size; TX_DMA_REGS->DMAx_LEN_REG = size - 1; TX_DMA_REGS->DMAx_CTRL_REG = TX_DMA_START; } static void start_tx_packet(xfer_ctl_t *xfer) { uint8_t const epnum = tu_edpt_number(xfer->ep_addr); uint16_t remaining = xfer->total_len - xfer->transferred; uint16_t size = tu_min16(remaining, xfer->max_packet_size); EPx_REGS *regs = EPNUM_REGS(epnum); xfer->last_packet_size = 0; regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk; regs->txc = USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk; if (xfer->data1) regs->txc |= USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk; if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE && try_allocate_dma(epnum, TUSB_DIR_IN)) { // Whole packet will be put in FIFO by DMA. Set LAST bit before start. start_tx_dma(xfer->buffer + xfer->transferred, ®s->txd, size); regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk; } else { fill_tx_fifo(xfer); } regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk; } static uint16_t read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) { EPx_REGS *regs = XFER_REGS(xfer); uint16_t remaining = xfer->total_len - xfer->transferred - xfer->last_packet_size; uint16_t receive_this_time = bytes_in_fifo; if (remaining < bytes_in_fifo) receive_this_time = remaining; uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size; for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd; xfer->last_packet_size += receive_this_time; return bytes_in_fifo - receive_this_time; } static void handle_ep0_rx(void) { int fifo_bytes; uint32_t rxs0 = USB->USB_RXS0_REG; xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); fifo_bytes = GET_BIT(rxs0, USB_USB_RXS0_REG_USB_RCOUNT); if (rxs0 & USB_USB_RXS0_REG_USB_SETUP_Msk) { xfer_ctl_t *xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); // Setup packet is in for (int i = 0; i < fifo_bytes; ++i) _setup_packet[i] = USB->USB_RXD0_REG; xfer->stall = 0; xfer->data1 = 1; xfer_in->stall = 0; xfer_in->data1 = 1; REG_SET_BIT(USB_TXC0_REG, USB_TOGGLE_TX0); REG_CLR_BIT(USB_EPC0_REG, USB_STALL); dcd_event_setup_received(0, _setup_packet,true); } else { if (GET_BIT(rxs0, USB_USB_RXS0_REG_USB_TOGGLE_RX0) != xfer->data1) { // Toggle bit does not match discard packet REG_SET_BIT(USB_RXC0_REG, USB_FLUSH); xfer->last_packet_size = 0; } else { read_rx_fifo(xfer, fifo_bytes); if (rxs0 & USB_USB_RXS0_REG_USB_RX_LAST_Msk) { xfer->transferred += xfer->last_packet_size; xfer->data1 ^= 1; if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size) { dcd_event_xfer_complete(0, 0, xfer->transferred, XFER_RESULT_SUCCESS, true); } else { // Re-enable reception REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); } xfer->last_packet_size = 0; } } } } static void handle_ep0_tx(void) { uint32_t txs0; xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_IN); EPx_REGS *regs = XFER_REGS(xfer); txs0 = regs->USB_TXS0_REG; if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_TX_DONE)) { // ACK received if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_ACK_STAT)) { xfer->transferred += xfer->last_packet_size; xfer->last_packet_size = 0; xfer->data1 ^= 1; REG_SET_VAL(USB_TXC0_REG, USB_TOGGLE_TX0, xfer->data1); if (xfer->transferred == xfer->total_len) { dcd_event_xfer_complete(0, 0 | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); return; } } else { // Start from the beginning xfer->last_packet_size = 0; } fill_tx_fifo(xfer); } } static void handle_epx_rx_ev(uint8_t ep) { uint32_t rxs; int fifo_bytes; xfer_ctl_t *xfer = XFER_CTL_BASE(ep, TUSB_DIR_OUT); EPx_REGS *regs = EPNUM_REGS(ep); do { rxs = regs->rxs; if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_ERR)) { regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; xfer->last_packet_size = 0; if (_dcd.dma_ep[TUSB_DIR_OUT] == ep) { // Stop DMA RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; // Restart DMA since packet was dropped, all parameters should still work. RX_DMA_REGS->DMAx_CTRL_REG |= DMA_DMA0_CTRL_REG_DMA_ON_Msk; } break; } else { if (_dcd.dma_ep[TUSB_DIR_OUT] == ep) { // Disable DMA and update last_packet_size with what DMA reported. RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; xfer->last_packet_size = RX_DMA_REGS->DMAx_IDX_REG; // When DMA did not finished (packet was smaller then MPS), DMAx_IDX_REG holds exact number of bytes transmitted. // When DMA finished value in DMAx_IDX_REG is one less then actual number of transmitted bytes. if (xfer->last_packet_size == RX_DMA_REGS->DMAx_LEN_REG) xfer->last_packet_size++; // Release DMA to use by other endpoints. _dcd.dma_ep[TUSB_DIR_OUT] = 0; } fifo_bytes = GET_BIT(rxs, USB_USB_RXS1_REG_USB_RXCOUNT); // FIFO maybe empty if DMA read it before or it's final iteration and function already read all that was to read. if (fifo_bytes > 0) { fifo_bytes = read_rx_fifo(xfer, fifo_bytes); } if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_LAST)) { if (!xfer->iso && GET_BIT(rxs, USB_USB_RXS1_REG_USB_TOGGLE_RX) != xfer->data1) { // Toggle bit does not match discard packet regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; } else { xfer->data1 ^= 1; xfer->transferred += xfer->last_packet_size; if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size || xfer->iso) { if (fifo_bytes) { // There are extra bytes in the FIFO just flush them regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; fifo_bytes = 0; } dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, XFER_RESULT_SUCCESS, true); } else { // Re-enable reception start_rx_packet(xfer); } } xfer->last_packet_size = 0; } } } while (fifo_bytes > TU_DA1469X_FIFO_READ_THRESHOLD); } static void handle_rx_ev(void) { if (USB->USB_RXEV_REG & 1) handle_epx_rx_ev(1); if (USB->USB_RXEV_REG & 2) handle_epx_rx_ev(2); if (USB->USB_RXEV_REG & 4) handle_epx_rx_ev(3); } static void handle_epx_tx_ev(xfer_ctl_t *xfer) { uint8_t const epnum = tu_edpt_number(xfer->ep_addr); uint32_t txs; EPx_REGS *regs = EPNUM_REGS(epnum); txs = regs->txs; if (GET_BIT(txs, USB_USB_TXS1_REG_USB_TX_DONE)) { if (_dcd.dma_ep[TUSB_DIR_IN] == epnum) { // Disable DMA and update last_packet_size with what DMA reported. TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk; xfer->last_packet_size = TX_DMA_REGS->DMAx_IDX_REG + 1; // Release DMA to used by other endpoints. _dcd.dma_ep[TUSB_DIR_IN] = 0; } if (GET_BIT(txs, USB_USB_TXS1_REG_USB_ACK_STAT)) { // ACK received, update transfer state and DATA0/1 bit xfer->transferred += xfer->last_packet_size; xfer->last_packet_size = 0; xfer->data1 ^= 1; if (xfer->transferred == xfer->total_len) { dcd_event_xfer_complete(0, xfer->ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); return; } } else if (regs->epc_in & USB_USB_EPC1_REG_USB_STALL_Msk) { // TX_DONE also indicates that STALL packet was just sent, there is // no point to put anything into transmit FIFO. It could result in // empty packet being scheduled. return; } } if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk) { TU_LOG1("EP %d FIFO underrun\r\n", epnum); } // Start next or repeated packet. start_tx_packet(xfer); } static void handle_tx_ev(void) { if (USB->USB_TXEV_REG & 1) handle_epx_tx_ev(XFER_CTL_BASE(1, TUSB_DIR_IN)); if (USB->USB_TXEV_REG & 2) handle_epx_tx_ev(XFER_CTL_BASE(2, TUSB_DIR_IN)); if (USB->USB_TXEV_REG & 4) handle_epx_tx_ev(XFER_CTL_BASE(3, TUSB_DIR_IN)); } static uint32_t check_reset_end(uint32_t alt_ev) { if (_dcd.nfsr == NFSR_NODE_RESET) { if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET)) { // Could be still in reset, but since USB_M_RESET is disabled it can // be also old reset state that was not cleared yet. // If (after reading USB_ALTEV_REG register again) bit is cleared // reset state just ended. // Keep non-reset bits combined from two previous ALTEV read and // one from the next line. alt_ev = (alt_ev & ~USB_USB_ALTEV_REG_USB_RESET_Msk) | USB->USB_ALTEV_REG; } if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) == 0) { USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | USB_USB_ALTEV_REG_USB_SD3_Msk; set_nfsr(NFSR_NODE_OPERATIONAL); dcd_edpt_open(0, &ep0OUT_desc); dcd_edpt_open(0, &ep0IN_desc); } } return alt_ev; } static void handle_bus_reset(void) { uint32_t alt_ev; USB->USB_NFSR_REG = 0; USB->USB_FAR_REG = 0x80; USB->USB_ALTMSK_REG = 0; USB->USB_NFSR_REG = NFSR_NODE_RESET; USB->USB_TXMSK_REG = 0; USB->USB_RXMSK_REG = 0; set_nfsr(NFSR_NODE_RESET); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); USB->USB_DMA_CTRL_REG = 0; USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | USB_USB_MAMSK_REG_USB_M_FRAME_Msk | USB_USB_MAMSK_REG_USB_M_WARN_Msk | USB_USB_MAMSK_REG_USB_M_ALT_Msk; USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; alt_ev = USB->USB_ALTEV_REG; check_reset_end(alt_ev); } static void handle_alt_ev(void) { uint32_t alt_ev = USB->USB_ALTEV_REG; alt_ev = check_reset_end(alt_ev); if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) && _dcd.nfsr != NFSR_NODE_RESET) { handle_bus_reset(); } else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESUME)) { if (USB->USB_NFSR_REG == NFSR_NODE_SUSPEND) { set_nfsr(NFSR_NODE_OPERATIONAL); USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | USB_USB_ALTMSK_REG_USB_M_SD3_Msk; // Re-enable reception of endpoint with pending transfer for (int epnum = 1; epnum <= 3; ++epnum) { xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); if (xfer->total_len > xfer->transferred) { start_rx_packet(xfer); } } dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_SD3)) { set_nfsr(NFSR_NODE_SUSPEND); USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } } static void handle_epx_tx_warn_ev(uint8_t ep) { fill_tx_fifo(XFER_CTL_BASE(ep, TUSB_DIR_IN)); } static void handle_fifo_warning(void) { uint32_t fifo_warning = USB->USB_FWEV_REG; if (fifo_warning & 0x01) handle_epx_tx_warn_ev(1); if (fifo_warning & 0x02) handle_epx_tx_warn_ev(2); if (fifo_warning & 0x04) handle_epx_tx_warn_ev(3); if (fifo_warning & 0x10) handle_epx_rx_ev(1); if (fifo_warning & 0x20) handle_epx_rx_ev(2); if (fifo_warning & 0x40) handle_epx_rx_ev(3); } static void handle_ep0_nak(void) { uint32_t ep0_nak = USB->USB_EP0_NAK_REG; if (REG_GET_BIT(USB_EPC0_REG, USB_STALL)) { if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_INNAK)) { // EP0 is stalled and NAK was sent, it means that RX is enabled // Disable RX for now. REG_CLR_BIT(USB_RXC0_REG, USB_RX_EN); REG_SET_BIT(USB_TXC0_REG, USB_TX_EN); } if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK)) { REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); } } else { REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); } } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; _dcd.init_called = true; if (_dcd.vbus_present) { dcd_connect(rhport); } return true; } void dcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB_IRQn); } void dcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)rhport; // Set default address for one ZLP USB->USB_EPC0_REG = USB_USB_EPC0_REG_USB_DEF_Msk; USB->USB_FAR_REG = (dev_addr & USB_USB_FAR_REG_USB_AD_Msk) | USB_USB_FAR_REG_USB_AD_EN_Msk; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; if (_dcd.nfsr == NFSR_NODE_SUSPEND) { // Enter fake state that will use FRAME interrupt to wait before going operational. set_nfsr(NFSR_NODE_WAKING); USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_FRAME_Msk; } } void dcd_connect(uint8_t rhport) { (void)rhport; if (GET_BIT(USB->USB_MCTRL_REG, USB_USB_MCTRL_REG_USB_NAT) == 0) { USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk; USB->USB_NFSR_REG = 0; USB->USB_FAR_REG = 0x80; USB->USB_TXMSK_REG = 0; USB->USB_RXMSK_REG = 0; USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | USB_USB_MAMSK_REG_USB_M_ALT_Msk | USB_USB_MAMSK_REG_USB_M_WARN_Msk; USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk | USB_USB_ALTEV_REG_USB_SD3_Msk; USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk | USB_USB_MCTRL_REG_USB_NAT_Msk; // Select chosen DMA to be triggered by USB. DMA->DMA_REQ_MUX_REG = (DMA->DMA_REQ_MUX_REG & ~DA146XX_DMA_USB_MUX_MASK) | DA146XX_DMA_USB_MUX; } } void dcd_disconnect(uint8_t rhport) { (void)rhport; REG_CLR_BIT(USB_MCTRL_REG, USB_NAT); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; } void tusb_vbus_changed(bool present); void tusb_vbus_changed(bool present) { if (present && !_dcd.vbus_present) { _dcd.vbus_present = true; // If power event happened before USB started, delay dcd_connect // until dcd_init is called. if (_dcd.init_called) { dcd_connect(0); } } else if (!present && _dcd.vbus_present) { _dcd.vbus_present = false; USB->USB_MCTRL_REG = 0; dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); } } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void)rhport; uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); EPx_REGS *regs = EPNUM_REGS(epnum); uint8_t iso_mask = 0; TU_ASSERT(epnum < EP_MAX); xfer->max_packet_size = tu_edpt_packet_size(desc_edpt); xfer->ep_addr = desc_edpt->bEndpointAddress; xfer->data1 = 0; xfer->iso = 0; if (epnum != 0 && desc_edpt->bmAttributes.xfer == 1) { iso_mask = USB_USB_EPC1_REG_USB_ISO_Msk; xfer->iso = 1; } if (epnum == 0) { USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk | USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk; } else { if (dir == TUSB_DIR_OUT) { regs->epc_out = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; USB->USB_RXMSK_REG |= 0x11 << (epnum - 1); REG_SET_BIT(USB_MAMSK_REG, USB_M_RX_EV); } else { regs->epc_in = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; USB->USB_TXMSK_REG |= 0x11 << (epnum - 1); REG_SET_BIT(USB_MAMSK_REG, USB_M_TX_EV); } } return true; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; for (int epnum = 1; epnum < EP_MAX; ++epnum) { dcd_edpt_close(0, epnum | TUSB_DIR_OUT); dcd_edpt_close(0, epnum | TUSB_DIR_IN); } } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); EPx_REGS *regs = EPNUM_REGS(epnum); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); (void)rhport; TU_ASSERT(epnum < EP_MAX,); if (epnum == 0) { USB->USB_MAMSK_REG &= ~(USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk | USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk); } else { if (dir == TUSB_DIR_OUT) { regs->rxc = USB_USB_RXC1_REG_USB_FLUSH_Msk; regs->epc_out = 0; USB->USB_RXMSK_REG &= ~(0x11 << (epnum - 1)); // Release DMA if needed if (_dcd.dma_ep[TUSB_DIR_OUT] == epnum) { RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk; _dcd.dma_ep[TUSB_DIR_OUT] = 0; } } else { regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk; regs->epc_in = 0; USB->USB_TXMSK_REG &= ~(0x11 << (epnum - 1)); // Release DMA if needed if (_dcd.dma_ep[TUSB_DIR_IN] == epnum) { TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk; _dcd.dma_ep[TUSB_DIR_IN] = 0; } } } tu_memclr(xfer, sizeof(*xfer)); } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { (void) rhport; (void) desc_ep; return false; } #endif bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); (void)rhport; xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->last_packet_size = 0; xfer->transferred = 0; if (dir == TUSB_DIR_OUT) { start_rx_packet(xfer); } else // IN { start_tx_packet(xfer); } return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); (void)rhport; xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); EPx_REGS *regs = EPNUM_REGS(epnum); xfer->stall = 1; if (epnum == 0) { // EP0 has just one registers to control stall for IN and OUT REG_SET_BIT(USB_EPC0_REG, USB_STALL); if (dir == TUSB_DIR_OUT) { regs->USB_RXC0_REG = USB_USB_RXC0_REG_USB_RX_EN_Msk; } else { if (regs->USB_RXC0_REG & USB_USB_RXC0_REG_USB_RX_EN_Msk) { // If RX is also enabled TX will not be stalled since RX has // higher priority. Enable NAK interrupt to handle stall. REG_SET_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); } else { regs->USB_TXC0_REG |= USB_USB_TXC0_REG_USB_TX_EN_Msk; } } } else { if (dir == TUSB_DIR_OUT) { regs->epc_out |= USB_USB_EPC1_REG_USB_STALL_Msk; regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; } else { regs->epc_in |= USB_USB_EPC1_REG_USB_STALL_Msk; regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk | USB_USB_TXC1_REG_USB_LAST_Msk; } } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); (void)rhport; xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); EPx_REGS *regs = EPNUM_REGS(epnum); // Clear stall is called in response to Clear Feature ENDPOINT_HALT, reset toggle xfer->data1 = 0; xfer->stall = 0; if (dir == TUSB_DIR_OUT) { regs->epc_out &= ~USB_USB_EPC1_REG_USB_STALL_Msk; } else { regs->epc_in &= ~USB_USB_EPC1_REG_USB_STALL_Msk; } if (epnum == 0) { REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); } } /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ void dcd_int_handler(uint8_t rhport) { uint32_t int_status = USB->USB_MAEV_REG & USB->USB_MAMSK_REG; (void)rhport; if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_WARN)) { handle_fifo_warning(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_CH_EV)) { // TODO: for now just clear interrupt (void)USB->USB_CHARGER_STAT_REG; } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_NAK)) { handle_ep0_nak(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_RX)) { handle_ep0_rx(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_TX)) { handle_ep0_tx(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_RX_EV)) { handle_rx_ev(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_NAK)) { (void)USB->USB_NAKEV_REG; } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_FRAME)) { if (_dcd.nfsr == NFSR_NODE_RESET) { // During reset FRAME interrupt is enabled to periodically // check when reset state ends. // FRAME interrupt is generated every 1ms without host sending // actual SOF. check_reset_end(USB_USB_ALTEV_REG_USB_RESET_Msk); } else if (_dcd.nfsr == NFSR_NODE_WAKING) { // No need to call set_nfsr, just set state _dcd.nfsr = NFSR_NODE_WAKING2; } else if (_dcd.nfsr == NFSR_NODE_WAKING2) { // No need to call set_nfsr, just set state _dcd.nfsr = NFSR_NODE_RESUME; } else if (_dcd.nfsr == NFSR_NODE_RESUME) { set_nfsr(NFSR_NODE_OPERATIONAL); } else { #if USE_SOF dcd_event_bus_signal(0, DCD_EVENT_SOF, true); #else // FRAME interrupt was used to re-enable reset detection or remote // wakeup no need to keep it enabled when USE_SOF is off. USB->USB_MAMSK_REG &= ~USB_USB_MAMSK_REG_USB_M_FRAME_Msk; #endif } } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_TX_EV)) { handle_tx_ev(); } if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_ALT)) { handle_alt_ev(); } } #endif ================================================ FILE: src/portable/ehci/ehci.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_EHCI) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "osal/osal.h" #include "host/hcd.h" #include "host/usbh.h" #include "host/usbh_pvt.h" #include "ehci_api.h" #include "ehci.h" // NXP specific fixes #if TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX, OPT_MCU_LPC55, OPT_MCU_MCXN9, OPT_MCU_RW61X) #include "fsl_device_registers.h" #endif #if TU_CHECK_MCU(OPT_MCU_HPM) #include "ci_hs_hpm.h" #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // Debug level of EHCI #define EHCI_DBG 2 // Framelist size as small as possible to save SRAM #ifdef TUP_USBIP_CHIPIDEA_HS // NXP Transdimension: 8 elements #define FRAMELIST_SIZE_BIT_VALUE 7u #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_FRAMELIST_SIZE_SHIFT) | \ ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT)) #else // STD EHCI: 256 elements #define FRAMELIST_SIZE_BIT_VALUE 2u #define FRAMELIST_SIZE_USBCMD_VALUE ((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) #endif #define FRAMELIST_SIZE (1024 >> FRAMELIST_SIZE_BIT_VALUE) // Total queue head pool. TODO should be user configurable and more optimize memory usage in the future #define QHD_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX + CFG_TUH_HUB) #define QTD_MAX QHD_MAX typedef struct { ehci_link_t period_framelist[FRAMELIST_SIZE]; // TODO only implement 1 ms & 2 ms & 4 ms, 8 ms (framelist) // [0] : 1ms, [1] : 2ms, [2] : 4ms, [3] : 8 ms // TODO better implementation without dummy head to save SRAM ehci_qhd_t period_head_arr[4]; // Note control qhd of dev0 is used as head of async list struct { ehci_qhd_t qhd; ehci_qtd_t qtd; }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; ehci_qhd_t qhd_pool[QHD_MAX]; ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32); ehci_registers_t* regs; // operational register ehci_cap_registers_t* cap_regs; // capability register volatile uint32_t uframe_number; }ehci_data_t; // Periodic frame list must be 4K alignment CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data; //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if 0 && CFG_TUSB_DEBUG >= (EHCI_DBG + 1) static inline void print_portsc(ehci_registers_t* regs) { TU_LOG_HEX(EHCI_DBG, regs->portsc); TU_LOG(EHCI_DBG, " Connect Status : %u\r\n", regs->portsc_bm.current_connect_status); TU_LOG(EHCI_DBG, " Connect Change : %u\r\n", regs->portsc_bm.connect_status_change); TU_LOG(EHCI_DBG, " Enabled : %u\r\n", regs->portsc_bm.port_enabled); TU_LOG(EHCI_DBG, " Enabled Change : %u\r\n", regs->portsc_bm.port_enable_change); TU_LOG(EHCI_DBG, " OverCurr Change: %u\r\n", regs->portsc_bm.over_current_change); TU_LOG(EHCI_DBG, " Force Resume : %u\r\n", regs->portsc_bm.force_port_resume); TU_LOG(EHCI_DBG, " Suspend : %u\r\n", regs->portsc_bm.suspend); TU_LOG(EHCI_DBG, " Reset : %u\r\n", regs->portsc_bm.port_reset); TU_LOG(EHCI_DBG, " Power : %u\r\n", regs->portsc_bm.port_power); } static inline void print_intr(uint32_t intr) { TU_LOG_HEX(EHCI_DBG, intr); TU_LOG(EHCI_DBG, " USB Interrupt : %u\r\n", (intr & EHCI_INT_MASK_USB) ? 1 : 0); TU_LOG(EHCI_DBG, " USB Error : %u\r\n", (intr & EHCI_INT_MASK_ERROR) ? 1 : 0); TU_LOG(EHCI_DBG, " Port Change Detect : %u\r\n", (intr & EHCI_INT_MASK_PORT_CHANGE) ? 1 : 0); TU_LOG(EHCI_DBG, " Frame List Rollover: %u\r\n", (intr & EHCI_INT_MASK_FRAMELIST_ROLLOVER) ? 1 : 0); TU_LOG(EHCI_DBG, " Host System Error : %u\r\n", (intr & EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR) ? 1 : 0); TU_LOG(EHCI_DBG, " Async Advance : %u\r\n", (intr & EHCI_INT_MASK_ASYNC_ADVANCE) ? 1 : 0); // TU_LOG(EHCI_DBG, " Interrupt on Async: %u\r\n", (intr & EHCI_INT_MASK_NXP_ASYNC)); // TU_LOG(EHCI_DBG, " Periodic Schedule : %u\r\n", (intr & EHCI_INT_MASK_NXP_PERIODIC)); } #else #define print_portsc(_reg) #endif //--------------------------------------------------------------------+ // PROTOTYPE //--------------------------------------------------------------------+ // weak dcache for non-cacheable MCU TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr); TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd); TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void); static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr); static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd); static void qhd_remove_qtd(ehci_qhd_t *qhd); TU_ATTR_ALWAYS_INLINE static inline bool qhd_is_periodic(ehci_qhd_t const *qhd) { return qhd->int_smask != 0; } TU_ATTR_ALWAYS_INLINE static inline uint8_t qhd_ep_addr(ehci_qhd_t const *qhd) { return tu_edpt_addr(qhd->ep_number, qhd->pid); } TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr); TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void); static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes); TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms); TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport); TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next (ehci_link_t const *p_link); TU_ATTR_ALWAYS_INLINE static inline void list_insert (ehci_link_t *current, ehci_link_t *entry, uint8_t type); TU_ATTR_ALWAYS_INLINE static inline void list_remove(ehci_link_t* head, ehci_link_t* prev, ehci_qhd_t* qhd); static void list_remove_qhd_by_addr(ehci_link_t *list_head, uint8_t dev_addr, uint8_t ep_addr); static void ehci_disable_schedule(ehci_registers_t* regs, bool is_period) { // maybe have a timeout for status if (is_period) { regs->command_bm.periodic_enable = 0; while(regs->status_bm.periodic_status) {} } else { regs->command_bm.async_enable = 0; while(regs->status_bm.async_status) {} // should have a timeout } } static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) { // maybe have a timeout for status if (is_period) { regs->command_bm.periodic_enable = 1; while ( 0 == regs->status_bm.periodic_status ) {} } else { regs->command_bm.async_enable = 1; while( 0 == regs->status_bm.async_status ) {} } } #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) static void nxp_usbphy_disconn_detector_set(uint8_t port, bool enable) { // unify naming convention #if !defined(USBPHY1) && defined(USBPHY) #define USBPHY1 USBPHY #endif if (port == 0) { if (enable) { USBPHY1->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } else { USBPHY1->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } } #if FSL_FEATURE_SOC_USBPHY_COUNT > 1U else if (port == 1) { if (enable) { USBPHY2->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } else { USBPHY2->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } } #endif #if !defined(USBPHY1) && defined(USBPHY) #undef USBPHY1 #endif } #endif //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; uint32_t uframe = ehci_data.regs->frame_index; return (ehci_data.uframe_number + uframe) >> 3; } void hcd_port_reset(uint8_t rhport) { (void) rhport; ehci_registers_t* regs = ehci_data.regs; // skip if already in reset if (regs->portsc_bm.port_reset) { return; } // mask out Write-1-to-Clear bits uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; #if TU_CHECK_MCU(OPT_MCU_HPM) if (usb_phy_get_line_state((USB_Type *)CI_HS_REG(rhport)) == usb_line_state2) { portsc |= USB_PORTSC1_STS_MASK; } else { portsc &= ~USB_PORTSC1_STS_MASK; } #endif // EHCI Table 2-16 PortSC // when software writes Port Reset bit to a one, it must also write a zero to the Port Enable bit. portsc &= ~(EHCI_PORTSC_MASK_PORT_EANBLED); portsc |= EHCI_PORTSC_MASK_PORT_RESET; regs->portsc = portsc; } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; ehci_registers_t* regs = ehci_data.regs; // stop reset only if is not complete yet if (regs->portsc_bm.port_reset) { // mask out all change bits since they are Write 1 to clear uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; portsc &= ~EHCI_PORTSC_MASK_PORT_RESET; regs->portsc = portsc; } #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) // Enable disconnect detector for highspeed device only if (hcd_port_speed_get(rhport) == TUSB_SPEED_HIGH) { nxp_usbphy_disconn_detector_set(rhport, true); } #endif } bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; return ehci_data.regs->portsc_bm.current_connect_status; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t daddr) { // skip dev0 if (daddr == 0) { return; } // Remove from async list all endpoints of this device list_remove_qhd_by_addr((ehci_link_t *) list_get_async_head(rhport), daddr, TUSB_INDEX_INVALID_8); // Remove from all interval period list of this device for (uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) { list_remove_qhd_by_addr((ehci_link_t *) &ehci_data.period_head_arr[i], daddr, TUSB_INDEX_INVALID_8); } // Async doorbell (EHCI 4.8.2 for operational details) ehci_data.regs->command_bm.async_adv_doorbell = 1; } static void init_periodic_list(uint8_t rhport) { (void) rhport; // Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) { ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive } // TODO EHCI_FRAMELIST_SIZE with other size than 8 // all links --> period_head_arr[0] (1ms) // 0, 2, 4, 6 etc --> period_head_arr[1] (2ms) // 1, 5 --> period_head_arr[2] (4ms) // 3 --> period_head_arr[3] (8ms) ehci_link_t * const framelist = ehci_data.period_framelist; ehci_link_t * const head_1ms = (ehci_link_t *) &ehci_data.period_head_arr[0]; ehci_link_t * const head_2ms = (ehci_link_t *) &ehci_data.period_head_arr[1]; ehci_link_t * const head_4ms = (ehci_link_t *) &ehci_data.period_head_arr[2]; ehci_link_t * const head_8ms = (ehci_link_t *) &ehci_data.period_head_arr[3]; for (uint32_t i = 0; i < FRAMELIST_SIZE; i++) { framelist[i].address = (uint32_t) head_1ms; framelist[i].type = EHCI_QTYPE_QHD; } for (uint32_t i = 0; i < FRAMELIST_SIZE; i += 2) { list_insert(framelist + i, head_2ms, EHCI_QTYPE_QHD); } for (uint32_t i = 1; i < FRAMELIST_SIZE; i += 4) { list_insert(framelist + i, head_4ms, EHCI_QTYPE_QHD); } list_insert(framelist + 3, head_8ms, EHCI_QTYPE_QHD); head_1ms->terminate = 1; } bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg) { tu_memclr(&ehci_data, sizeof(ehci_data_t)); ehci_data.regs = (ehci_registers_t*) operatial_reg; ehci_data.cap_regs = (ehci_cap_registers_t*) capability_reg; ehci_registers_t* regs = ehci_data.regs; // EHCI 4.1 Host Controller Initialization //------------- CTRLDSSEGMENT Register (skip) -------------// //------------- USB INT Register -------------// // disable all the interrupt regs->inten = 0; // clear all status except port change since device maybe connected before this driver is initialized regs->status = (EHCI_INT_MASK_ALL & ~EHCI_INT_MASK_PORT_CHANGE); // Enable interrupts regs->inten = EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_FRAMELIST_ROLLOVER; //------------- Asynchronous List -------------// ehci_qhd_t * const async_head = list_get_async_head(rhport); tu_memclr(async_head, sizeof(ehci_qhd_t)); async_head->next.address = (uint32_t) async_head; // circular list, next is itself async_head->next.type = EHCI_QTYPE_QHD; async_head->head_list_flag = 1; async_head->qtd_overlay.halted = 1; // inactive most of time async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified regs->async_list_addr = (uint32_t) async_head; //------------- Periodic List -------------// init_periodic_list(rhport); regs->periodic_list_base = (uint32_t) ehci_data.period_framelist; hcd_dcache_clean(&ehci_data, sizeof(ehci_data_t)); //------------- TT Control (NXP only) -------------// regs->nxp_tt_control = 0; //------------- USB CMD Register -------------// regs->command |= EHCI_USBCMD_RUN_STOP | EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE | EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE | FRAMELIST_SIZE_USBCMD_VALUE; //------------- ConfigFlag Register (skip) -------------// // enable port power bit in portsc. The function of this bit depends on the value of the Port // Power Control (PPC) field in the HCSPARAMS register. if (ehci_data.cap_regs->hcsparams_bm.port_power_control) { // mask out all change bits since they are Write 1 to clear uint32_t portsc = (regs->portsc & ~EHCI_PORTSC_MASK_W1C); portsc |= EHCI_PORTSC_MASK_PORT_POWER; regs->portsc = portsc; } return true; } bool ehci_deinit(uint8_t rhport) { (void) rhport; ehci_registers_t* regs = ehci_data.regs; // Disable all the interrupt regs->inten = 0; // Disable schedules regs->command_bm.run_stop = 0; // USB Spec: controller has to stop within 16 uframe = 2 frames while( regs->status_bm.hc_halted == 0 ) {} return true; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { // TODO not support ISO yet TU_ASSERT (ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); //------------- Prepare Queue Head -------------// ehci_qhd_t *p_qhd; if (ep_desc->bEndpointAddress == 0) { p_qhd = qhd_control(dev_addr); } else { if (NULL != qhd_get_from_addr(dev_addr, ep_desc->bEndpointAddress)) { return true; // already opened } p_qhd = qhd_find_free(); } TU_ASSERT(p_qhd); qhd_init(p_qhd, dev_addr, ep_desc); // control of dev0 always exists as async head if (dev_addr == 0) { return true; } // Insert to list ehci_link_t * list_head = NULL; switch (ep_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: case TUSB_XFER_BULK: list_head = (ehci_link_t *) list_get_async_head(rhport); break; case TUSB_XFER_INTERRUPT: list_head = list_get_period_head(rhport, p_qhd->interval_ms); break; case TUSB_XFER_ISOCHRONOUS: // TODO iso is not supported break; default: break; } TU_ASSERT(list_head); list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD); hcd_dcache_clean(p_qhd, sizeof(ehci_qhd_t)); hcd_dcache_clean(list_head, sizeof(ehci_qhd_t)); return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { ehci_qhd_t* qhd = qhd_get_from_addr(daddr, ep_addr); TU_VERIFY(qhd != NULL); ehci_link_t * list_head; if (qhd_is_periodic(qhd)) { // interrupt endpoint list_head = list_get_period_head(rhport, qhd->interval_ms);; } else { list_head = (ehci_link_t *) list_get_async_head(rhport); } list_remove_qhd_by_addr(list_head, daddr, ep_addr); return true; } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; ehci_qhd_t* qhd = &ehci_data.control[dev_addr].qhd; ehci_qtd_t* td = &ehci_data.control[dev_addr].qtd; qtd_init(td, setup_packet, 8); td->pid = EHCI_PID_SETUP; hcd_dcache_clean(setup_packet, 8); // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage if (qhd->qtd_overlay.halted) { qhd->qtd_overlay.halted = false; } // attach TD to QHD -> start transferring qhd_attach_qtd(qhd, td); return true; } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr); TU_VERIFY(qhd != NULL); ehci_qtd_t* qtd; if (epnum == 0) { // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage if (qhd->qtd_overlay.halted) { qhd->qtd_overlay.halted = false; } qtd = qtd_control(dev_addr); qtd_init(qtd, buffer, buflen); // first data toggle is always 1 (data & setup stage) qtd->data_toggle = 1; qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT; } else { // skip if endpoint is halted TU_VERIFY(!qhd->qtd_overlay.halted); qtd = qtd_find_free(); TU_ASSERT(qtd); qtd_init(qtd, buffer, buflen); qtd->pid = qhd->pid; } // IN transfer: invalidate buffer, OUT transfer: clean buffer if (dir) { hcd_dcache_invalidate(buffer, buflen); }else { hcd_dcache_clean(buffer, buflen); } // attach TD to QHD -> start transferring qhd_attach_qtd(qhd, qtd); return true; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; // TODO ISO not supported yet ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr); ehci_qtd_t * volatile qtd = qhd->attached_qtd; TU_VERIFY(qtd != NULL); // no queued transfer hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); TU_VERIFY(qtd->active); // transfer is already complete // HC is still processing, disable HC list schedule before making changes bool const is_period = (qhd->interval_ms > 0); ehci_disable_schedule(ehci_data.regs, is_period); // check active bit again just in case HC has just processed the TD bool const still_active = qtd->active; if (still_active) { // remove TD from QH overlay qhd->qtd_overlay.next.terminate = 1; hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); // remove TD from QH software list qhd_remove_qtd(qhd); } ehci_enable_schedule(ehci_data.regs, is_period); return still_active; // true if removed an active transfer } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr); qhd->qtd_overlay.halted = 0; qhd->qtd_overlay.data_toggle = 0; hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t)); return true; } //--------------------------------------------------------------------+ // EHCI Interrupt Handler //--------------------------------------------------------------------+ // async_advance is handshake between usb stack & ehci controller. // This isr mean it is safe to modify previously removed queue head from async list. // In tinyusb, queue head is only removed when device is unplugged. TU_ATTR_ALWAYS_INLINE static inline void async_advance_isr(uint8_t rhport) { (void) rhport; ehci_qhd_t *qhd_pool = ehci_data.qhd_pool; for (uint32_t i = 0; i < QHD_MAX; i++) { if (qhd_pool[i].removing) { qhd_pool[i].removing = 0; qhd_pool[i].used = 0; } } } TU_ATTR_ALWAYS_INLINE static inline void port_connect_status_change_isr(uint8_t rhport) { // NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device if ( ehci_data.regs->portsc_bm.current_connect_status ) { hcd_port_reset(rhport); hcd_event_device_attach(rhport, true); } else // device unplugged { #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) // Disable disconnect detector nxp_usbphy_disconn_detector_set(rhport, false); #endif hcd_event_device_remove(rhport, true); } } // Check queue head for potential transfer complete (successful or error) TU_ATTR_ALWAYS_INLINE static inline void qhd_xfer_complete_isr(ehci_qhd_t * qhd) { hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t)); // HC may have updated the overlay volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay; // process non-active (completed) QHD with attached (scheduled) TD if ( !qtd_overlay->active && qhd->attached_qtd != NULL ) { xfer_result_t xfer_result; if ( qtd_overlay->halted ) { if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) { // Error count = 0 often occurs when device disconnected, or other bus-related error // clear halted bit if not caused by STALL to allow more transfer xfer_result = XFER_RESULT_FAILED; qtd_overlay->halted = false; TU_LOG3(" QHD xfer err count: %d\r\n", qtd_overlay->err_count); // TU_BREAKPOINT(); // TODO skip unplugged device }else { // no error bits are set, endpoint is halted due to STALL xfer_result = XFER_RESULT_STALLED; } } else { xfer_result = XFER_RESULT_SUCCESS; } ehci_qtd_t * volatile qtd = qhd->attached_qtd; hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // HC may have written back TD uint8_t const dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0; uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes; // invalidate dcache if IN transfer with data if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) { hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes); } // remove and free TD before invoking callback qhd_remove_qtd(qhd); // notify usbh uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir); hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true); } } TU_ATTR_ALWAYS_INLINE static inline void proccess_async_xfer_isr(ehci_qhd_t * const list_head) { ehci_qhd_t *qhd = list_head; do { qhd_xfer_complete_isr(qhd); qhd = qhd_next(qhd); } while ( qhd != list_head ); // async list traversal, stop if loop around } TU_ATTR_ALWAYS_INLINE static inline void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms) { uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u); ehci_link_t next_link = *list_get_period_head(rhport, interval_ms); while (!next_link.terminate) { if (interval_ms > 1 && period_1ms_addr == tu_align32(next_link.address)) { // 1ms period list is end of list for all larger interval break; } uintptr_t const entry_addr = tu_align32(next_link.address); switch (next_link.type) { case EHCI_QTYPE_QHD: { ehci_qhd_t *qhd = (ehci_qhd_t *) entry_addr; qhd_xfer_complete_isr(qhd); } break; // TODO support hs/fs ISO case EHCI_QTYPE_ITD: case EHCI_QTYPE_SITD: case EHCI_QTYPE_FSTN: default: break; } next_link = *list_next(&next_link); } } //------------- Host Controller Driver's Interrupt Handler -------------// void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; ehci_registers_t* regs = ehci_data.regs; uint32_t const int_status = regs->status; if (int_status & EHCI_INT_MASK_HC_HALTED) { // something seriously wrong, maybe forget to flush/invalidate cache TU_BREAKPOINT(); TU_LOG1(" HC halted\r\n"); return; } if (int_status & EHCI_INT_MASK_FRAMELIST_ROLLOVER) { ehci_data.uframe_number += (FRAMELIST_SIZE << 3); regs->status = EHCI_INT_MASK_FRAMELIST_ROLLOVER; // Acknowledge } if (int_status & EHCI_INT_MASK_PORT_CHANGE) { // Including: Force port resume, over-current change, enable/disable change and connect status change. uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_W1C; // print_portsc(regs); if (regs->portsc_bm.connect_status_change) { port_connect_status_change_isr(rhport); } regs->portsc |= port_status; // Acknowledge change bits in portsc regs->status = EHCI_INT_MASK_PORT_CHANGE; // Acknowledge } // A USB transfer is completed (OK or error) uint32_t const usb_int = int_status & (EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR); if (usb_int) { proccess_async_xfer_isr(list_get_async_head(rhport)); for ( uint32_t i = 1; i <= FRAMELIST_SIZE; i *= 2 ) { process_period_xfer_isr(rhport, i); } regs->status = usb_int; // Acknowledge } //------------- There is some removed async previously -------------// // need to place after EHCI_INT_MASK_NXP_ASYNC if (int_status & EHCI_INT_MASK_ASYNC_ADVANCE) { async_advance_isr(rhport); regs->status = EHCI_INT_MASK_ASYNC_ADVANCE; // Acknowledge } } //--------------------------------------------------------------------+ // List Managing Helper //--------------------------------------------------------------------+ // Get head of periodic list TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms) { (void) rhport; return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ]; } // Get head of async list TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport) { (void) rhport; return qhd_control(0); // control qhd of dev0 is used as async head } TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next(ehci_link_t const *p_link) { return (ehci_link_t*) tu_align32(p_link->address); } TU_ATTR_ALWAYS_INLINE static inline void list_insert(ehci_link_t *current, ehci_link_t *entry, uint8_t type) { entry->address = current->address; current->address = ((uint32_t) entry) | (type << 1); } // Remove a queue head from the list. // Per EHCI 4.8.2 the removed qhd's next is linked to list head (which always reachable by Host Controller) // TODO support iTD/siTD TU_ATTR_ALWAYS_INLINE static inline void list_remove(ehci_link_t* head, ehci_link_t* prev, ehci_qhd_t* qhd) { // TODO deactivate all TD, wait for QHD to inactive before removal prev->address = qhd->next.address; // link the removed qhd's next to list head qhd->next.address = ((uint32_t) head) | (EHCI_QTYPE_QHD << 1); if (qhd_is_periodic(qhd)) { // period list queue element is guarantee to be free in the next frame (1 ms) qhd->used = 0; } else { // async list use async advance handshake. Mark as removing, will completely re-usable when async advance isr occurs qhd->removing = 1; } hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); hcd_dcache_clean(prev, sizeof(ehci_qhd_t)); } // Remove queue head belong to this device address static void list_remove_qhd_by_addr(ehci_link_t *list_head, uint8_t dev_addr, uint8_t ep_addr) { ehci_link_t *prev = list_head; while (prev && !prev->terminate) { ehci_qhd_t *qhd = (ehci_qhd_t *) (uintptr_t) list_next(prev); // done if loop back to head if ((uintptr_t) qhd == (uintptr_t) list_head) { break; } // ep_addr is 0xff means all endpoints of this device address if (qhd->dev_addr == dev_addr && (ep_addr == TUSB_INDEX_INVALID_8 || qhd_ep_addr(qhd) == ep_addr)) { list_remove(list_head, prev, qhd); } else { prev = list_next(prev); } } } //--------------------------------------------------------------------+ // Queue Header helper //--------------------------------------------------------------------+ // Get queue head for control transfer (always available) TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) { return &ehci_data.control[dev_addr].qhd; } // Find a free queue head TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_find_free(void) { for (uint32_t i = 0; i < QHD_MAX; i++) { if (!ehci_data.qhd_pool[i].used) { return &ehci_data.qhd_pool[i]; } } return NULL; } // Next queue head link TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd) { return (ehci_qhd_t *) tu_align32(p_qhd->next.address); } // Get queue head from device + endpoint address static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) { if ( 0 == tu_edpt_number(ep_addr) ) { return qhd_control(dev_addr); } ehci_qhd_t *qhd_pool = ehci_data.qhd_pool; // protect qhd_pool since 'used' and 'removing' can be changed in isr ehci_qhd_t *result = NULL; usbh_spin_lock(false); for (uint32_t i = 0; i < QHD_MAX; i++) { if ((qhd_pool[i].dev_addr == dev_addr) && ep_addr == qhd_ep_addr(&qhd_pool[i]) && qhd_pool[i].used && !qhd_pool[i].removing) { result = &qhd_pool[i]; break; } } usbh_spin_unlock(false); return result; } // Init queue head with endpoint descriptor static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { // address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise) if (dev_addr != 0) { tu_memclr(p_qhd, sizeof(ehci_qhd_t)); } tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); uint8_t const xfer_type = ep_desc->bmAttributes.xfer; uint8_t const interval = ep_desc->bInterval; p_qhd->dev_addr = dev_addr; p_qhd->fl_inactive_next_xact = 0; p_qhd->ep_number = tu_edpt_number(ep_desc->bEndpointAddress); p_qhd->ep_speed = bus_info.speed; p_qhd->data_toggle_control= (xfer_type == TUSB_XFER_CONTROL) ? 1 : 0; p_qhd->head_list_flag = (dev_addr == 0) ? 1 : 0; // addr0's endpoint is the static async list head p_qhd->max_packet_size = tu_edpt_packet_size(ep_desc); p_qhd->fl_ctrl_ep_flag = ((xfer_type == TUSB_XFER_CONTROL) && (p_qhd->ep_speed != TUSB_SPEED_HIGH)) ? 1 : 0; p_qhd->nak_reload = 0; switch (xfer_type) { case TUSB_XFER_CONTROL: case TUSB_XFER_BULK: p_qhd->int_smask = p_qhd->fl_int_cmask = 0; break; case TUSB_XFER_INTERRUPT: if (TUSB_SPEED_HIGH == p_qhd->ep_speed) { TU_ASSERT(interval <= 16, ); if (interval < 4) { // sub millisecond interval p_qhd->interval_ms = 0; p_qhd->int_smask = (interval == 1) ? 0xff : // 0b11111111 (interval == 2) ? 0xaa /* 0b10101010 */ : 0x44 /* 0b01000100 */; } else { p_qhd->interval_ms = (uint8_t) tu_min16(1 << (interval - 4), 255); p_qhd->int_smask = TU_BIT(interval % 8); } } else { TU_ASSERT(0 != interval, ); // Full/Low: 4.12.2.1 (EHCI) case 1 schedule start split at 1 us & complete split at 2,3,4 uframes p_qhd->int_smask = 0x01; p_qhd->fl_int_cmask = 0x1c; // 0b11100 p_qhd->interval_ms = interval; } break; case TUSB_XFER_ISOCHRONOUS: // TODO not support ISO yet break; default: break; } p_qhd->fl_hub_addr = bus_info.hub_addr; p_qhd->fl_hub_port = bus_info.hub_port; p_qhd->mult = 1; // TODO not use high bandwidth/park mode yet //------------- HCD Management Data -------------// p_qhd->used = 1; p_qhd->removing = 0; p_qhd->attached_qtd = NULL; p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint //------------- active, but no TD list -------------// p_qhd->qtd_overlay.halted = 0; p_qhd->qtd_overlay.next.terminate = 1; p_qhd->qtd_overlay.alternate.terminate = 1; if (TUSB_XFER_BULK == xfer_type && p_qhd->ep_speed == TUSB_SPEED_HIGH && p_qhd->pid == EHCI_PID_OUT) { p_qhd->qtd_overlay.ping_err = 1; // do PING for Highspeed Bulk OUT, EHCI section 4.11 } } // Attach a TD to queue head static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) { qhd->attached_qtd = qtd; qhd->attached_buffer = qtd->buffer[0]; // clean and invalidate cache before physically write hcd_dcache_clean_invalidate(qtd, sizeof(ehci_qtd_t)); qhd->qtd_overlay.next.address = (uint32_t) qtd; hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t)); } // Remove an attached TD from queue head static void qhd_remove_qtd(ehci_qhd_t *qhd) { ehci_qtd_t * volatile qtd = qhd->attached_qtd; qhd->attached_qtd = NULL; qhd->attached_buffer = 0; hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); qtd->used = 0; // free QTD hcd_dcache_clean(qtd, sizeof(ehci_qtd_t)); } //--------------------------------------------------------------------+ // Queue TD helper //--------------------------------------------------------------------+ // Get TD for control transfer (always available) TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) { return &ehci_data.control[dev_addr].qtd; } TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t *qtd_find_free(void) { for (uint32_t i = 0; i < QTD_MAX; i++) { if (!ehci_data.qtd_pool[i].used) return &ehci_data.qtd_pool[i]; } return NULL; } static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes) { tu_memclr(qtd, sizeof(ehci_qtd_t)); qtd->used = 1; qtd->next.terminate = 1; // init to null qtd->alternate.terminate = 1; // not used, always set to terminated qtd->active = 1; qtd->err_count = 3; // TODO 3 consecutive errors tolerance qtd->data_toggle = 0; qtd->int_on_complete = 1; qtd->total_bytes = total_bytes; qtd->expected_bytes = total_bytes; qtd->buffer[0] = (uint32_t) buffer; for(uint8_t i=1; i<5; i++) { qtd->buffer[i] |= tu_align4k(qtd->buffer[i - 1] ) + 4096; } } #endif ================================================ FILE: src/portable/ehci/ehci.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_EHCI_H_ #define TUSB_EHCI_H_ /* Abbreviation * HC: Host Controller * HCD: Host Controller Driver * QHD: Queue Head for non-ISO transfer * QTD: Queue Transfer Descriptor for non-ISO transfer * ITD: Iso Transfer Descriptor for highspeed * SITD: Split ISO Transfer Descriptor for full-speed * SMASK: Start Split mask for Slipt Transaction * CMASK: Complete Split mask for Slipt Transaction */ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // EHCI CONFIGURATION & CONSTANTS //--------------------------------------------------------------------+ // TODO merge OHCI with EHCI enum { EHCI_MAX_ITD = 4, EHCI_MAX_SITD = 16 }; //--------------------------------------------------------------------+ // EHCI Data Structure //--------------------------------------------------------------------+ enum { EHCI_QTYPE_ITD = 0 , EHCI_QTYPE_QHD , EHCI_QTYPE_SITD , EHCI_QTYPE_FSTN }; /// EHCI PID enum { EHCI_PID_OUT = 0 , EHCI_PID_IN , EHCI_PID_SETUP }; /// Link pointer typedef union { uint32_t address; struct { uint32_t terminate : 1; uint32_t type : 2; }; } ehci_link_t; TU_VERIFY_STATIC( sizeof(ehci_link_t) == 4, "size is not correct" ); /// Queue Element Transfer Descriptor /// Qtd is used to declare overlay in ehci_qhd_t -> cannot be declared with TU_ATTR_ALIGNED(32) typedef struct { // Word 0 Next QTD Pointer ehci_link_t next; // Word 1 Alternate Next QTD Pointer (not used) union { ehci_link_t alternate; struct { uint32_t : 5; uint32_t used : 1; uint32_t : 10; uint32_t expected_bytes : 16; }; }; // Word 2 qTQ Token volatile uint32_t ping_err : 1; // For Highspeed: 0 Out, 1 Ping. Full/Slow used as error indicator volatile uint32_t non_hs_split_state : 1; // Used by HC to track the state of split transaction volatile uint32_t non_hs_missed_uframe : 1; // HC misses a complete split transaction volatile uint32_t xact_err : 1; // Error (Timeout, CRC, Bad PID ... ) volatile uint32_t babble_err : 1; // Babble detected, also set Halted bit to 1 volatile uint32_t buffer_err : 1; // Data overrun/underrun error volatile uint32_t halted : 1; // Serious error or STALL received volatile uint32_t active : 1; // Start transfer, clear by HC when complete uint32_t pid : 2; // 0: OUT, 1: IN, 2 Setup volatile uint32_t err_count : 2; // Error Counter of consecutive errors volatile uint32_t current_page : 3; // Index into the qTD buffer pointer list uint32_t int_on_complete : 1; // Interrupt on complete volatile uint32_t total_bytes : 15; // Transfer bytes, decreased during transaction volatile uint32_t data_toggle : 1; // Data Toggle bit // Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. // The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page uint32_t buffer[5]; } ehci_qtd_t; TU_VERIFY_STATIC( sizeof(ehci_qtd_t) == 32, "size is not correct" ); /// Queue Head typedef struct TU_ATTR_ALIGNED(32) { // Word 0 Next QHD ehci_link_t next; // Word 1 Endpoint Characteristics uint32_t dev_addr : 7; // device address uint32_t fl_inactive_next_xact : 1; // Only valid for Periodic with Full/Slow speed uint32_t ep_number : 4; // EP number uint32_t ep_speed : 2; // Full (0), Low (1), High (2) uint32_t data_toggle_control : 1; // 0 use DT in qHD, 1 use DT in qTD uint32_t head_list_flag : 1; // Head of the queue uint32_t max_packet_size : 11; // Max packet size uint32_t fl_ctrl_ep_flag : 1; // 1 if is Full/Low speed control endpoint uint32_t nak_reload : 4; // Used by HC // Word 2 Endpoint Capabilities uint32_t int_smask : 8; // Interrupt Schedule Mask uint32_t fl_int_cmask : 8; // Split Completion Mask for Full/Slow speed uint32_t fl_hub_addr : 7; // Hub Address for Full/Slow speed uint32_t fl_hub_port : 7; // Hub Port for Full/Slow speed uint32_t mult : 2; // Transaction per micro frame // Word 3 Current qTD Pointer volatile uint32_t qtd_addr; // Word 4-11 Transfer Overlay volatile ehci_qtd_t qtd_overlay; //--------------------------------------------------------------------+ /// Due to the fact QHD is 32 bytes aligned but occupies only 48 bytes /// thus there are 16 bytes padding free that we can make use of. //--------------------------------------------------------------------+ uint8_t used; uint8_t removing;// removed from asyn list, waiting for async advance uint8_t pid; uint8_t interval_ms;// polling interval in frames (or millisecond) uint8_t TU_RESERVED[4]; // Attached TD management, note usbh will only queue 1 TD per QHD. // buffer for dcache invalidate since td's buffer is modified by HC and finding initial buffer address is not trivial uint32_t attached_buffer; ehci_qtd_t *volatile attached_qtd; } ehci_qhd_t; TU_VERIFY_STATIC( sizeof(ehci_qhd_t) == 64, "size is not correct" ); /// Highspeed Isochronous Transfer Descriptor (section 3.3) typedef struct TU_ATTR_ALIGNED(32) { // Word 0: Next Link Pointer ehci_link_t next; // Word 1-8: iTD Transaction Status and Control List struct { // iTD Control volatile uint32_t offset : 12; // offset in bytes, from the beginning of a buffer. volatile uint32_t page_select : 3; // buffer page pointers the offset field in this slot should be concatenated to produce the starting memory address for this transaction. The valid range of values for this field is 0 to 6 uint32_t int_on_complete : 1; // If this bit is set to a one, it specifies that when this transaction completes, the Host Controller should issue an interrupt at the next interrupt threshold volatile uint32_t length : 12; // For an OUT, this field is the number of data bytes the host controller will send during the transaction. The host controller is not required to update this field to reflect the actual number of bytes transferred during the transfer // For an IN, the initial value of the field is the number of bytes the host expects the endpoint to deliver. During the status update, the host controller writes back the number of bytes successfully received. The value in this register is the actual byte count // iTD Status volatile uint32_t error : 1; // Set to a one by the Host Controller during status update in the case where the host did not receive a valid response from the device (Timeout, CRC, Bad PID, etc.). This bit may only be set for isochronous IN transactions. volatile uint32_t babble_err : 1; // Set to a 1 by the Host Controller during status update when a babble is detected during the transaction volatile uint32_t buffer_err : 1; // Set to a 1 by the Host Controller during status update to indicate that the Host Controller is unable to keep up with the reception of incoming data (overrun) or is unable to supply data fast enough during transmission (underrun). volatile uint32_t active : 1; // Set to 1 by software to enable the execution of an isochronous transaction by the Host Controller } xact[8]; // Word 9-15 Buffer Page Pointer List (Plus) uint32_t BufferPointer[7]; // FIXME: Store meta data into buffer pointer reserved for saving memory //---------- HCD Area ---------- // uint32_t used; // uint32_t IhdIdx; // uint32_t reserved[6]; } ehci_itd_t; TU_VERIFY_STATIC( sizeof(ehci_itd_t) == 64, "size is not correct" ); /// Split (Full-Speed) Isochronous Transfer Descriptor typedef struct TU_ATTR_ALIGNED(32) { // Word 0: Next Link Pointer ehci_link_t next; // Word 1: siTD Endpoint Characteristics uint32_t dev_addr : 7; ///< This field selects the specific device serving as the data source or sink. uint32_t : 1; ///< reserved uint32_t ep_number : 4; ///< This 4-bit field selects the particular endpoint number on the device serving as the data source or sink. uint32_t : 4; ///< This field is reserved and should be set to zero. uint32_t hub_addr : 7; ///< This field holds the device address of the transaction translators’ hub. uint32_t : 1; ///< reserved uint32_t port_number : 7; ///< This field is the port number of the recipient transaction translator. uint32_t direction : 1; ///< 0 = OUT; 1 = IN. This field encodes whether the full-speed transaction should be an IN or OUT. // Word 2: Micro-frame Schedule Control uint8_t int_smask ; ///< This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine during which micro-frames the host controller should execute complete-split transactions uint8_t fl_int_cmask; ///< This field (along with the Activeand SplitX-statefields in the Statusbyte) are used to determine during which micro-frames the host controller should execute start-split transactions. uint16_t reserved ; ///< reserved // Word 3: siTD Transfer Status and Control // Status [7:0] TODO identical to qTD Token'status --> refactor later volatile uint32_t : 1 ; // reserved volatile uint32_t split_state : 1 ; volatile uint32_t missed_uframe : 1 ; volatile uint32_t xact_err : 1 ; volatile uint32_t babble_err : 1 ; volatile uint32_t buffer_err : 1 ; volatile uint32_t error : 1 ; volatile uint32_t active : 1 ; // Micro-frame Schedule Control volatile uint32_t cmask_progress : 8 ; ///< This field is used by the host controller to record which split-completes have been executed. See Section 4.12.3.3.2 for behavioral requirements. volatile uint32_t total_bytes : 10 ; ///< This field is initialized by software to the total number of bytes expected in this transfer. Maximum value is 1023 volatile uint32_t : 4 ; ///< reserved volatile uint32_t page_select : 1 ; ///< Used to indicate which data page pointer should be concatenated with the CurrentOffsetfield to construct a data buffer pointer uint32_t int_on_complete : 1 ; ///< Do not interrupt when transaction is complete. 1 = Do interrupt when transaction is complete uint32_t : 0 ; // padding to the end of current storage unit /// Word 4-5: Buffer Pointer List uint32_t buffer[2]; // buffer[1] TP: Transaction Position - T-Count: Transaction Count /*---------- Word 6 ----------*/ ehci_link_t back; /// SITD is 32-byte aligned but occupies only 28 --> 4 bytes for storing extra data uint8_t used; uint8_t ihd_idx; uint8_t reserved2[2]; } ehci_sitd_t; TU_VERIFY_STATIC( sizeof(ehci_sitd_t) == 32, "size is not correct" ); //--------------------------------------------------------------------+ // EHCI Operational Register //--------------------------------------------------------------------+ enum { // Bit 0-5 has maskable in interrupt enabled register EHCI_INT_MASK_USB = TU_BIT(0), EHCI_INT_MASK_ERROR = TU_BIT(1), EHCI_INT_MASK_PORT_CHANGE = TU_BIT(2), EHCI_INT_MASK_FRAMELIST_ROLLOVER = TU_BIT(3), EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR = TU_BIT(4), EHCI_INT_MASK_ASYNC_ADVANCE = TU_BIT(5), EHCI_INT_MASK_NXP_SOF = TU_BIT(7), EHCI_INT_MASK_HC_HALTED = TU_BIT(12), EHCI_INT_MASK_RECLAIMATION = TU_BIT(13), EHCI_INT_MASK_PERIODIC_SCHED_STATUS = TU_BIT(14), EHCI_INT_MASK_ASYNC_SCHED_STATUS = TU_BIT(15), EHCI_INT_MASK_ALL = EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR | EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF }; enum { EHCI_USBCMD_FRAMELIST_SIZE_SHIFT = 2, // [2..3] EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15, EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16 }; enum { EHCI_USBCMD_RUN_STOP = TU_BIT(0), // [0..0] 1 = Run, 0 = Stop EHCI_USBCMD_HCRESET = TU_BIT(1), // [1..1] SW write 1 to reset HC, clear by HC when complete EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE = TU_BIT(4), // [4..4] Enable periodic schedule EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE = TU_BIT(5), // [5..5] Enable async schedule EHCI_USBCMD_INTR_ON_ASYNC_ADVANCE_DOORBELL = TU_BIT(6), // [6..6] Tell HC to interrupt next time it advances async list. Clear by HC }; enum { EHCI_PORTSC_MASK_CURRENT_CONNECT_STATUS = TU_BIT(0), EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1), EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2), EHCI_PORTSC_MASK_PORT_ENABLE_CHANGE = TU_BIT(3), EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5), EHCI_PORTSC_MASK_FORCE_RESUME = TU_BIT(6), EHCI_PORTSC_MASK_PORT_SUSPEND = TU_BIT(7), EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8), EHCI_PORTSC_MASK_PORT_POWER = TU_BIT(12), EHCI_PORTSC_MASK_W1C = EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE | EHCI_PORTSC_MASK_PORT_ENABLE_CHANGE | EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE }; typedef volatile struct { union { uint32_t command; // 0x00 struct { uint32_t run_stop : 1 ; ///< 1=Run. 0=Stop uint32_t reset : 1 ; ///< SW write 1 to reset HC, clear by HC when complete uint32_t framelist_size : 2 ; ///< Frame List size 0: 1024, 1: 512, 2: 256 uint32_t periodic_enable : 1 ; ///< This bit controls whether the host controller skips processing the Periodic Schedule. Values mean: 0b Do not process the Periodic Schedule 1b Use the PERIODICLISTBASE register to access the Periodic Schedule. uint32_t async_enable : 1 ; ///< This bit controls whether the host controller skips processing the Asynchronous Schedule. Values mean: 0b Do not process the Asynchronous Schedule 1b Use the ASYNCLISTADDR register to access the Asynchronous Schedule. uint32_t async_adv_doorbell : 1 ; ///< Tell HC to interrupt next time it advances async list. Clear by HC uint32_t light_reset : 1 ; ///< Reset HC without affecting ports state uint32_t async_park_count : 2 ; ///< not used by tinyusb uint32_t : 1 ; uint32_t async_park_enable : 1 ; ///< Enable park mode, not used by tinyusb uint32_t : 3 ; uint32_t nxp_framelist_size_msb : 1 ; ///< NXP customized : Bit 2 of the Frame List Size bits \n 011b: 128 elements \n 100b: 64 elements \n 101b: 32 elements \n 110b: 16 elements \n 111b: 8 elements uint32_t int_threshold : 8 ; ///< Default 08h. Interrupt rate in unit of micro frame }command_bm; }; union { uint32_t status; // 0x04 struct { uint32_t usb : 1 ; ///< qTD with IOC is retired uint32_t usb_error : 1 ; ///< qTD retired due to error uint32_t port_change_detect : 1 ; ///< Set when PortOwner or ForcePortResume change from 0 -> 1 uint32_t framelist_rollover : 1 ; ///< R/WC The Host Controller sets this bit to a one when the Frame List Index(see Section 2.3.4) rolls over from its maximum value to zero. The exact value at which the rollover occurs depends on the frame list size. For example, if the frame list size (as programmed in the Frame List Sizefield of the USBCMD register) is 1024, the Frame Index Registerrolls over every time FRINDEX[13] toggles. Similarly, if the size is 512, the Host Controller sets this bit to a one every time FRINDEX[12] toggles. uint32_t pci_host_system_error : 1 ; ///< R/WC (not used by NXP) The Host Controller sets this bit to 1 when a serious error occurs during a host system access involving the Host Controller module. In a PCI system, conditions that set this bit to 1 include PCI Parity error, PCI Master Abort, and PCI Target Abort. When this error occurs, the Host Controller clears the Run/Stop bit in the Command register to prevent further execution of the scheduled TDs. uint32_t async_adv : 1 ; ///< Async Advance interrupt uint32_t : 1 ; uint32_t nxp_int_sof : 1 ; ///< NXP customized: this bit will be set every 125us and can be used by host controller driver as a time base. uint32_t : 4 ; uint32_t hc_halted : 1 ; ///< Opposite value to run_stop bit. uint32_t reclamation : 1 ; ///< Used to detect empty async shecudle uint32_t periodic_status : 1 ; ///< Periodic schedule status uint32_t async_status : 1 ; ///< Async schedule status uint32_t : 2 ; uint32_t nxp_int_async : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the asynchronous schedule. This bit is also set by the Host when a short packet is detected and the packet is on the asynchronous schedule. uint32_t nxp_int_period : 1 ; ///< NXP customized: This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the periodic schedule. uint32_t : 12 ; }status_bm; }; union{ uint32_t inten; // 0x08 struct { uint32_t usb : 1 ; uint32_t usb_error : 1 ; uint32_t port_change_detect : 1 ; uint32_t framelist_rollover : 1 ; uint32_t pci_host_system_error : 1 ; uint32_t async_adv : 1 ; uint32_t : 1 ; uint32_t nxp_int_sof : 1 ; uint32_t : 10 ; uint32_t nxp_int_async : 1 ; uint32_t nxp_int_period : 1 ; uint32_t : 12 ; }inten_bm; }; uint32_t frame_index ; ///< 0x0C Micro frame counter uint32_t ctrl_ds_seg ; ///< 0x10 Control Data Structure Segment uint32_t periodic_list_base ; ///< 0x14 Beginning address of perodic frame list uint32_t async_list_addr ; ///< 0x18 Address of next async QHD to be executed uint32_t nxp_tt_control ; ///< nxp embedded transaction translator (reserved by EHCI specs) uint32_t reserved[8] ; uint32_t config_flag ; ///< 0x40 not used by NXP union { // mixed with RW and R/WC bits, care should be taken when writing to this register uint32_t portsc ; ///< 0x44 port status and control const struct { uint32_t current_connect_status : 1; ///< 00: 0: No device, 1: Device is present on port uint32_t connect_status_change : 1; ///< 01: [R/WC] Change in Current Connect Status uint32_t port_enabled : 1; ///< 02: Ports can only be enabled by HC as a part of the reset and enable. SW can write 0 to disable uint32_t port_enable_change : 1; ///< 03: [R/WC] Port Enabled has changed uint32_t over_current_active : 1; ///< 04: Port has an over-current condition uint32_t over_current_change : 1; ///< 05: [R/WC] Change to Over-current Active uint32_t force_port_resume : 1; ///< 06: Resume detected/driven on port. This functionality defined for manipulating this bit depends on the value of the Suspend bit. uint32_t suspend : 1; ///< 07: Port in suspend state uint32_t port_reset : 1; ///< 08: 1=Port is in Reset. 0=Port is not in Reset uint32_t nxp_highspeed_status : 1; ///< 09: NXP customized: 0=connected to the port is not in High-speed mode, 1=connected to the port is in High-speed mode uint32_t line_status : 2; ///< 10-11: D+/D- state: 00: SE0, 10: J-state, 01: K-state uint32_t port_power : 1; ///< 12: 0= power off, 1= power on uint32_t port_owner : 1; ///< 13: not used by NXP uint32_t port_indicator_control : 2; ///< 14-15: 00b: off, 01b: Amber, 10b: green, 11b: undefined uint32_t port_test_control : 4; ///< 16-19: Port test mode, not used by tinyusb uint32_t wake_on_connect_enable : 1; ///< 20: Enables device connects as wake-up events uint32_t wake_on_disconnect_enable : 1; ///< 21: Enables device disconnects as wake-up events uint32_t wake_on_over_current_enable : 1; ///< 22: Enables over-current conditions as wake-up events uint32_t nxp_phy_clock_disable : 1; ///< 23: NXP customized: the PHY can be put into Low Power Suspend – Clock Disable when the downstream device has been put into suspend mode or when no downstream device is connected. Low power suspend is completely under the control of software. 0: enable PHY clock, 1: disable PHY clock uint32_t nxp_port_force_fullspeed : 1; ///< 24: NXP customized: Writing this bit to a 1 will force the port to only connect at Full Speed. It disables the chirp sequence that allowsthe port to identify itself as High Speed. This is useful for testing FS configurations with a HS host, hub or device. uint32_t TU_RESERVED : 1; ///< 25 uint32_t nxp_port_speed : 2; ///< 26-27: NXP customized: This register field indicates the speed atwhich the port is operating. For HS mode operation in the host controllerand HS/FS operation in the device controller the port routing steers data to the Protocol engine. For FS and LS mode operation in the host controller, the port routing steers data to the Protocol Engine w/ Embedded Transaction Translator. 0x0: Fullspeed, 0x1: Lowspeed, 0x2: Highspeed uint32_t TU_RESERVED : 4; }portsc_bm; }; } ehci_registers_t; //--------------------------------------------------------------------+ // Capability Registers //--------------------------------------------------------------------+ typedef volatile struct { uint8_t caplength; // 0x00 uint8_t TU_RESERVED; // 0x01 uint16_t hciversion; // 0x02 union { uint32_t hcsparams; // 0x04 struct { uint32_t num_ports : 4; // [00:03] uint32_t port_power_control : 1; // [04] uint32_t TU_RESERVED : 2; // [05:06] uint32_t port_route_rule : 1; // [07] uint32_t n_pcc : 4; // [08:11] Number of Ports per Companion Controller uint32_t n_cc : 4; // [12:15] Number of Companion Controllers uint32_t port_ind : 1; // [16] Port Indicators uint32_t TU_RESERVED : 3; // [17:19] uint32_t n_ptt : 4; // [20:23] ChipIdea: Number of Ports per Transaction Translator uint32_t n_tt : 4; // [24:27] ChipIdea: Number of Transaction Translators uint32_t TU_RESERVED : 4; // [28:31] } hcsparams_bm; }; union { uint32_t hccparams; // 0x08 struct { uint32_t addr_64bit : 1; // [00] 64-bit Addressing Capability uint32_t programmable_frame_list_flag : 1; // [01] Programmable Frame List Flag uint32_t async_park_cap : 1; // [02] Asynchronous Schedule Park Capability uint32_t TU_RESERVED : 1; // [03] uint32_t iso_schedule_threshold : 4; // [4:7] Isochronous Scheduling Threshold uint32_t eecp : 8; // [8:15] EHCI Extended Capabilities Pointer uint32_t TU_RESERVED : 16;// [16:31] } hccparams_bm; }; uint32_t hcsp_portroute; // 0x0C HCSP Port Route Register } ehci_cap_registers_t; TU_VERIFY_STATIC(sizeof(ehci_cap_registers_t) == 16, "size is not correct"); #ifdef __cplusplus } #endif #endif /* TUSB_EHCI_H_ */ ================================================ FILE: src/portable/ehci/ehci_api.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_EHCI_API_H_ #define TUSB_EHCI_API_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // API Implemented by EHCI //--------------------------------------------------------------------+ // Initialize EHCI driver bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg); // De-initialize EHCI driver bool ehci_deinit(uint8_t rhport); #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/mentor/musb/dcd_musb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB) #define MUSB_DEBUG 2 #define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) #include "musb_type.h" #include "device/dcd.h" // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit #if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" #elif defined(TUP_USBIP_MUSB_ADI) #include "musb_max32.h" #else #error "Unsupported MCU" #endif /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ #define REQUEST_TYPE_INVALID (0xFFu) typedef union { volatile uint8_t u8; volatile uint16_t u16; volatile uint32_t u32; } hw_fifo_t; typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ } pipe_state_t; typedef struct { union { tusb_control_request_t setup_packet; uint32_t setup_buffer[2]; }; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX-1]; /* pipe[direction][endpoint number - 1] */ uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; static dcd_data_t _dcd; //-------------------------------------------------------------------- // HW FIFO Helper // Note: Index register is already set by caller //-------------------------------------------------------------------- #if MUSB_CFG_DYNAMIC_FIFO // musb is configured to use dynamic FIFO sizing. // FF Size is encodded: 1 << (fifo_size[3:0] + 3) = 8 << fifo_size[3:0] // FF Address is 8*ff_addr[12:0] // First 64 bytes are reserved for EP0 static uint32_t alloced_fifo_bytes; // ffsize is log2(mps) - 3 (round up) TU_ATTR_ALWAYS_INLINE static inline uint8_t hwfifo_byte2size(uint16_t nbytes) { uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(nbytes)); if ((8u << ffsize) < nbytes) { ++ffsize; } return ffsize; } TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { (void) epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; } TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, bool double_packet) { (void) epnum; uint8_t ffsize = hwfifo_byte2size(mps); mps = 8 << ffsize; // round up to the next power of 2 if (double_packet) { ffsize |= MUSB_FIFOSZ_DOUBLE_PACKET; mps <<= 1; } TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; musb->fifo_size[is_rx] = ffsize; alloced_fifo_bytes += mps; return true; } #else TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { (void) musb; (void) epnum; (void) is_rx; // nothing to do for static FIFO } TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, bool double_packet) { (void) epnum; (void) mps; if (!double_packet) { #if defined(TUP_USBIP_MUSB_ADI) musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); #else if (is_rx) { musb->rx_doulbe_packet_disable |= 1u << epnum; } else { musb->tx_double_packet_disable |= 1u << epnum; } #endif } return true; } #endif // Flush FIFO and clear data toggle TU_ATTR_ALWAYS_INLINE static inline void hwfifo_flush(musb_regs_t* musb, unsigned epnum, unsigned is_rx, bool clear_dtog) { (void) epnum; const uint8_t csrl_dtog = clear_dtog ? MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx) : 0; musb_ep_maxp_csr_t* maxp_csr = &musb->indexed_csr.maxp_csr[is_rx]; // may need to flush twice for double packet for (unsigned i=0; i<2; i++) { if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx) | csrl_dtog; } } } static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); // Read setup packet _dcd.setup_buffer[0] = musb_regs->fifo[0]; _dcd.setup_buffer[1] = musb_regs->fifo[0]; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); const unsigned len = _dcd.setup_packet.wLength; _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) { musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); ep_csr->csr0l = MUSB_CSRL0_RXRDYC; } } static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; if (rem == 0 && pipe->length > 0) { pipe->buf = NULL; return true; } musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); const unsigned mps = ep_csr->tx_maxp; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { tu_hwfifo_write_from_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL); } else { tu_hwfifo_write(fifo_ptr, buf, len, NULL); pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; } ep_csr->tx_csrl = MUSB_TXCSRL1_TXRDY; // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len); return false; } static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); TU_ASSERT(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY); const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; const unsigned vld = ep_csr->rx_count; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { tu_hwfifo_read_to_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL); } else { tu_hwfifo_read(fifo_ptr, buf, len, NULL); pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; } if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } ep_csr->rx_csrl = 0; /* Clear RXRDY bit */ return false; } static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; pipe->buf = buffer; pipe->length = total_bytes; pipe->remaining = total_bytes; if (dir_in) { handle_xfer_in(rhport, ep_addr); } else { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; } return true; } static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { /* STATUS OUT stage. * MUSB controller automatically handles STATUS OUT packets without * software helps. We do not have to do anything. And STATUS stage * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ // TU_LOG1(" STATUS OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); } else { /* The next setup packet has already been received, it aborts * invoking callback function to avoid confusing TUSB stack. */ TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); } return true; } const unsigned dir_in = tu_edpt_dir(ep_addr); if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); volatile void *fifo_ptr = &musb_regs->fifo[0]; if (dir_in) { tu_hwfifo_write(fifo_ptr, buffer, len, NULL); _dcd.pipe0.buf = buffer + len; _dcd.pipe0.length = len; _dcd.pipe0.remaining = 0; _dcd.remaining_ctrl = rem - len; if ((len < 64) || (rem == len)) { _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ ep_csr->csr0l = MUSB_CSRL0_TXRDY | MUSB_CSRL0_DATAEND; } else { ep_csr->csr0l = MUSB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); } else { // TU_LOG1(" OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; ep_csr->csr0l = MUSB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } return true; } static void process_ep0(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); uint_fast8_t csrl = ep_csr->csr0l; // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); // 21.1.5: endpoint 0 service routine as peripheral if (csrl & MUSB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ ep_csr->csr0l = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & MUSB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); ep_csr->csr0l = MUSB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, req & TUSB_DIR_IN_MASK, _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } req = REQUEST_TYPE_INVALID; if (!(csrl & MUSB_CSRL0_RXRDY)) return; /* Received SETUP packet */ } if (csrl & MUSB_CSRL0_RXRDY) { /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->count0,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ const unsigned vld = ep_csr->count0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); volatile void *fifo_ptr = &musb_regs->fifo[0]; tu_hwfifo_read(fifo_ptr, _dcd.pipe0.buf, len, NULL); _dcd.pipe0.remaining = rem - len; _dcd.remaining_ctrl -= len; _dcd.pipe0.buf = NULL; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } return; } /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ musb_regs->faddr = (uint8_t)_dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); return; } if (_dcd.pipe0.buf) { /* DATA IN */ _dcd.pipe0.buf = NULL; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } } static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn_minus1 = epn - 1; musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl); if (ep_csr->tx_csrl & MUSB_TXCSRL1_STALLED) { ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(rhport, ep_addr); } else { // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) { ep_csr->rx_csrl &= ~(MUSB_RXCSRL1_STALLED | MUSB_RXCSRL1_OVER); return; } completed = handle_xfer_out(rhport, ep_addr); } if (completed) { pipe_state_t *pipe = &_dcd.pipe[dir_in][epn_minus1]; dcd_event_xfer_complete(rhport, ep_addr, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); } } // Upon BUS RESET is detected, hardware havs already done: // faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts static void process_bus_reset(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); #if MUSB_CFG_DYNAMIC_FIFO alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; #endif /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; musb->intr_txen = 1; /* Enable only EP0 */ musb->intr_rxen = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb->index = i; hwfifo_reset(musb, i, 0); hwfifo_reset(musb, i, 1); } dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ * Device API *------------------------------------------------------------------*/ #if CFG_TUSB_DEBUG >= MUSB_DEBUG static void print_musb_info(musb_regs_t* musb_regs) { // print version, epinfo, raminfo, config_data0, fifo_size TU_LOG1("musb version = %u.%u\r\n", musb_regs->hwvers_bit.major, musb_regs->hwvers_bit.minor); TU_LOG1("Number of endpoints: %u TX, %u RX\r\n", musb_regs->epinfo_bit.tx_ep_num, musb_regs->epinfo_bit.rx_ep_num); TU_LOG1("RAM Info: %u DMA Channel, %u RAM address width\r\n", musb_regs->raminfo_bit.dma_channel, musb_regs->raminfo_bit.ram_bits); musb_regs->index = 0; TU_LOG1("config_data0 = 0x%x\r\n", musb_regs->indexed_csr.config_data0); #if MUSB_CFG_DYNAMIC_FIFO TU_LOG1("Dynamic FIFO configuration\r\n"); #else for (uint8_t i=1; i <= musb_regs->epinfo_bit.tx_ep_num; i++) { musb_regs->index = i; TU_LOG1("FIFO %u Size: TX %u RX %u\r\n", i, musb_regs->indexed_csr.fifo_size_bit.tx, musb_regs->indexed_csr.fifo_size_bit.rx); } #endif } #endif bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; musb_regs_t* musb_regs = MUSB_REGS(rhport); #if CFG_TUSB_DEBUG >= MUSB_DEBUG print_musb_info(musb_regs); #endif musb_regs->intr_usben |= MUSB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); return true; } void dcd_int_enable(uint8_t rhport) { musb_dcd_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { musb_dcd_int_disable(rhport); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs->power |= MUSB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); musb_regs->power &= ~MUSB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs->power |= TUD_OPT_HIGH_SPEED ? MUSB_POWER_HSENAB : 0; musb_regs->power |= MUSB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs->power &= ~MUSB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // static void edpt_setup(musb_regs_t* musb, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_size){ // const unsigned epn = tu_edpt_number(ep_addr); // const unsigned dir_in = tu_edpt_dir(ep_addr); // } // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned mps = tu_edpt_packet_size(ep_desc); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; pipe->length = 0; pipe->remaining = 0; musb_regs_t* musb = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; maxp_csr->maxp = mps; maxp_csr->csrh = 0; #if MUSB_CFG_SHARED_FIFO if (dir_in) { maxp_csr->csrh |= MUSB_CSRH_TX_MODE; } #endif hwfifo_flush(musb, epn, is_rx, true); TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, false)); musb->intren_ep[is_rx] |= TU_BIT(epn); return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); musb_regs_t* musb = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].csrh = 0; return hwfifo_config(musb, epn, is_rx, largest_packet_size, true); } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned mps = tu_edpt_packet_size(ep_desc); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; pipe->length = 0; pipe->remaining = 0; musb_regs_t* musb = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; maxp_csr->maxp = mps; maxp_csr->csrh |= MUSB_CSRH_ISO; #if MUSB_CFG_SHARED_FIFO if (dir_in) { maxp_csr->csrh |= MUSB_CSRH_TX_MODE; } #endif hwfifo_flush(musb, epn, is_rx, true); #if MUSB_CFG_DYNAMIC_FIFO // fifo space is already allocated, keep the address and just change packet size musb->fifo_size[is_rx] = hwfifo_byte2size(mps) | MUSB_FIFOSZ_DOUBLE_PACKET; #endif musb->intren_ep[is_rx] |= TU_BIT(epn); if (ie) musb_dcd_int_enable(rhport); return true; } void dcd_edpt_close_all(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); musb->intr_txen = 1; /* Enable only EP0 */ musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); for (unsigned d = 0; d < 2; d++) { musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d]; hwfifo_flush(musb, i, d, true); hwfifo_reset(musb, i, d); maxp_csr->maxp = 0; maxp_csr->csrh = 0; } } #if MUSB_CFG_DYNAMIC_FIFO alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; #endif if (ie) musb_dcd_int_enable(rhport); } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; bool ret; // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); } if (ie) musb_dcd_int_enable(rhport); return ret; } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack // - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; bool ret; // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); if (ie) musb_dcd_int_enable(rhport); return ret; } // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (0 == epn) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; ep_csr->csr0l = MUSB_CSRL0_STALL; } } else { const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx); } if (ie) musb_dcd_int_enable(rhport); } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); if (ie) musb_dcd_int_enable(rhport); } /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ void dcd_int_handler(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); const uint8_t saved_index = musb_regs->index; // save endpoint index //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */ if (intr_usb & MUSB_IS_DISCON) { } if (intr_usb & MUSB_IS_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } if (intr_usb & MUSB_IS_RESET) { process_bus_reset(rhport); } if (intr_usb & MUSB_IS_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } if (intr_usb & MUSB_IS_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } intr_tx &= musb_regs->intr_txen; /* Clear disabled interrupts */ if (intr_tx & TU_BIT(0)) { process_ep0(rhport); intr_tx &= ~TU_BIT(0); } while (intr_tx) { unsigned const num = __builtin_ctz(intr_tx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); intr_tx &= ~TU_BIT(num); } intr_rx &= musb_regs->intr_rxen; /* Clear disabled interrupts */ while (intr_rx) { unsigned const num = __builtin_ctz(intr_rx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); intr_rx &= ~TU_BIT(num); } musb_regs->index = saved_index; // restore endpoint index } #endif ================================================ FILE: src/portable/mentor/musb/hcd_musb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && \ TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though * the target CPU has the capability for unaligned memory access. */ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #endif #include "host/hcd.h" #include "host/usbh.h" #include "musb_type.h" #if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #include "musb_ti.h" #else #error "Unsupported MCUs" #endif #ifndef HCD_ATTR_ENDPOINT_MAX # define HCD_ATTR_ENDPOINT_MAX 8 #endif /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ #define REQUEST_TYPE_INVALID (0xFFu) typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ } free_block_t; typedef struct TU_ATTR_PACKED { uint8_t TXFUNCADDR; uint8_t RESERVED0; uint8_t TXHUBADDR; uint8_t TXHUBPORT; uint8_t RXFUNCADDR; uint8_t RESERVED1; uint8_t RXHUBADDR; uint8_t RXHUBPORT; } hw_addr_t; typedef struct TU_ATTR_PACKED { uint16_t TXMAXP; uint8_t TXCSRL; uint8_t TXCSRH; uint16_t RXMAXP; uint8_t RXCSRL; uint8_t RXCSRH; uint16_t RXCOUNT; uint8_t TXTYPE; uint8_t TXINTERVAL; uint8_t RXTYPE; uint8_t RXINTERVAL; uint16_t RESERVED; } hw_endpoint_t; typedef union { uint8_t u8; uint16_t u16; uint32_t u32; } hw_fifo_t; typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ } pipe_state_t; typedef struct TU_ATTR_PACKED { uint8_t dev; uint8_t ep; } pipe_addr_t; typedef struct { bool need_reset; /* The device has not been reset after connection. */ uint8_t bmRequestType; uint8_t ctl_mps[7]; /* EP0 max packet size for each device */ pipe_state_t pipe0; pipe_state_t pipe[7][2]; /* pipe[pipe number - 1][direction 0:RX 1:TX] */ pipe_addr_t addr[7][2]; /* addr[pipe number - 1][direction 0:RX 1:TX] */ } hcd_data_t; /*------------------------------------------------------------------ * INTERNAL OBJECT & FUNCTION DECLARATION *------------------------------------------------------------------*/ static hcd_data_t _hcd; static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { free_block_t *cur = beg; for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; return cur; } static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { free_block_t *p = find_containing_block(blks, blks + num, addr); TU_ASSERT(p != blks + num, -2); if (p->beg == addr) { /* Shrink block */ p->beg = addr + size; if (p->beg != p->end) return 0; /* remove block */ free_block_t *end = blks + num; while (p + 1 < end) { *p = *(p + 1); ++p; } return -1; } else { /* Split into 2 blocks */ free_block_t tmp = { .beg = addr + size, .end = p->end }; p->end = addr; if (p->beg == p->end) { if (tmp.beg != tmp.end) { *p = tmp; return 0; } /* remove block */ free_block_t *end = blks + num; while (p + 1 < end) { *p = *(p + 1); ++p; } return -1; } if (tmp.beg == tmp.end) return 0; blks[num] = tmp; return 1; } } static inline unsigned free_block_size(free_block_t const *blk) { return blk->end - blk->beg; } static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { free_block_t free_blocks[2 * (HCD_ATTR_ENDPOINT_MAX - 1)]; unsigned num_blocks = 1; /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ for (int i = 1; i < HCD_ATTR_ENDPOINT_MAX; ++i) { uint_fast16_t addr; int num; USB0->EPIDX = i; addr = USB0->TXFIFOADD; if (addr) { unsigned sz = USB0->TXFIFOSZ; unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); TU_ASSERT(-2 < num, 0); num_blocks += num; } addr = USB0->RXFIFOADD; if (addr) { unsigned sz = USB0->RXFIFOSZ; unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); TU_ASSERT(-2 < num, 0); num_blocks += num; } } /* Find the best fit memory block */ uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; free_block_t const *min = NULL; uint_fast16_t min_sz = 0xFFFFu; free_block_t const *end = &free_blocks[num_blocks]; for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { uint_fast16_t sz = free_block_size(cur); if (sz < size_in_8byte_unit) continue; if (size_in_8byte_unit == sz) return cur->beg; if (sz < min_sz) min = cur; } TU_ASSERT(min, 0); return min->beg; } static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) { volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); return regs + epnum_minus1; } static unsigned find_pipe(uint_fast8_t dev_addr, uint_fast8_t ep_addr) { unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; pipe_addr_t const *p = &_hcd.addr[0][dir_tx]; for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { if ((dev_addr == p->dev) && (ep_addr == p->ep)) return i + 1; } return 0; } static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; uintptr_t addr = (uintptr_t)buf; while (len >= 4) { reg->u32 = *(uint32_t const *)addr; addr += 4; len -= 4; } if (len >= 2) { reg->u16 = *(uint16_t const *)addr; addr += 2; len -= 2; } if (len) { reg->u8 = *(uint8_t const *)addr; } } static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; uintptr_t addr = (uintptr_t)buf; while (len >= 4) { *(uint32_t *)addr = reg->u32; addr += 4; len -= 4; } if (len >= 2) { *(uint16_t *)addr = reg->u16; addr += 2; len -= 2; } if (len) { *(uint8_t *)addr = reg->u8; } } static bool edpt0_xfer_out(void) { pipe_state_t *pipe = &_hcd.pipe0; unsigned const rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } unsigned const dev_addr = USB0->TXFUNCADDR0; unsigned const mps = _hcd.ctl_mps[dev_addr]; unsigned const len = TU_MIN(rem, mps); void *buf = pipe->buf; if (len) { pipe_write_packet(buf, &USB0->FIFO0_WORD, len); pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; USB0->CSRL0 = USB_CSRL0_TXRDY; return false; } static bool edpt0_xfer_in(void) { pipe_state_t *pipe = &_hcd.pipe0; unsigned const rem = pipe->remaining; unsigned const dev_addr = USB0->TXFUNCADDR0; unsigned const mps = _hcd.ctl_mps[dev_addr]; unsigned const vld = USB0->COUNT0; unsigned const len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { pipe_read_packet(buf, &USB0->FIFO0_WORD, len); pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } USB0->CSRL0 = USB_CSRL0_REQPKT; return false; } static bool edpt0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void)rhport; unsigned const req = _hcd.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID); TU_ASSERT(dev_addr < sizeof(_hcd.ctl_mps)); USB0->TXFUNCADDR0 = dev_addr; const unsigned dir_in = tu_edpt_dir(ep_addr); if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ TU_ASSERT(buffer); _hcd.pipe0.buf = buffer; _hcd.pipe0.length = buflen; _hcd.pipe0.remaining = buflen; if (dir_in) USB0->CSRL0 = USB_CSRL0_REQPKT; else edpt0_xfer_out(); } else { /* STATUS stage */ _hcd.pipe0.buf = NULL; _hcd.pipe0.length = 0; _hcd.pipe0.remaining = 0; USB0->CSRL0 = USB_CSRL0_STATUS | (dir_in ? USB_CSRL0_REQPKT: USB_CSRL0_TXRDY); } return true; } static bool pipe_xfer_out(uint_fast8_t pipenum) { pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; unsigned const rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); unsigned const mps = regs->TXMAXP; unsigned const len = TU_MIN(rem, mps); void *buf = pipe->buf; if (len) { pipe_write_packet(buf, &USB0->FIFO0_WORD + pipenum, len); pipe->buf = (uint8_t*)buf + len; } pipe->remaining = rem - len; regs->TXCSRL = USB_TXCSRL1_TXRDY; return false; } static bool pipe_xfer_in(uint_fast8_t pipenum) { pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); const unsigned mps = regs->RXMAXP; const unsigned rem = pipe->remaining; const unsigned vld = regs->RXCOUNT; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { pipe_read_packet(buf, &USB0->FIFO0_WORD + pipenum, len); pipe->buf = buf + len; pipe->remaining = rem - len; } if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } regs->RXCSRL = USB_RXCSRL1_REQPKT; return false; } static bool edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void)rhport; unsigned const pipenum = find_pipe(dev_addr, ep_addr); unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; pipe->buf = buffer; pipe->length = buflen; pipe->remaining = buflen; if (dir_tx) { pipe_xfer_out(pipenum); } else { volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); regs->RXCSRL = USB_RXCSRL1_REQPKT; } return true; } static void process_ep0(uint8_t rhport) { (void)rhport; uint_fast8_t csrl = USB0->CSRL0; // TU_LOG1(" EP0 CSRL = %x\r\n", csrl); unsigned const dev_addr = USB0->TXFUNCADDR0; unsigned const req = _hcd.bmRequestType; if (csrl & (USB_CSRL0_ERROR | USB_CSRL0_NAKTO | USB_CSRL0_STALLED)) { /* No response / NAK timed out / Stall received */ if (csrl & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) USB0->CSRH0 = USB_CSRH0_FLUSH; USB0->CSRL0 = 0; _hcd.bmRequestType = REQUEST_TYPE_INVALID; uint8_t result = (csrl & USB_CSRL0_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; if (REQUEST_TYPE_INVALID == req) { /* SETUP */ uint8_t const ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); hcd_event_xfer_complete(dev_addr, ep_addr, _hcd.pipe0.length - _hcd.pipe0.remaining, result, true); } else if (csrl & USB_CSRL0_STATUS) { /* STATUS */ uint8_t const ep_addr = tu_edpt_dir(req) ? tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); hcd_event_xfer_complete(dev_addr, ep_addr, _hcd.pipe0.length - _hcd.pipe0.remaining, result, true); } else { /* DATA */ uint8_t const ep_addr = tu_edpt_dir(req) ? tu_edpt_addr(0, TUSB_DIR_IN): tu_edpt_addr(0, TUSB_DIR_OUT); hcd_event_xfer_complete(dev_addr, ep_addr, _hcd.pipe0.length - _hcd.pipe0.remaining, result, true); } return; } if (csrl & USB_CSRL0_STATUS) { /* STATUS IN */ TU_ASSERT(USB_CSRL0_RXRDY == (csrl & USB_CSRL0_RXRDY),); TU_ASSERT(0 == USB0->COUNT0,); USB0->CSRH0 = USB_CSRH0_FLUSH; USB0->CSRL0 = 0; _hcd.bmRequestType = REQUEST_TYPE_INVALID; hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), 0, XFER_RESULT_SUCCESS, true); return; } if (csrl & USB_CSRL0_RXRDY) { /* DATA IN */ TU_ASSERT(REQUEST_TYPE_INVALID != req,); TU_ASSERT(_hcd.pipe0.buf,); if (edpt0_xfer_in()) { hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), _hcd.pipe0.length - _hcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } return; } /* When CSRL0 is zero, it means that completion of sending a any length packet. */ if (!_hcd.pipe0.buf) { /* STATUS OUT */ TU_ASSERT(REQUEST_TYPE_INVALID != req,); _hcd.bmRequestType = REQUEST_TYPE_INVALID; /* EP address is the reverse direction of DATA stage */ uint8_t const ep_addr = tu_edpt_dir(req) ? tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); return; } if (REQUEST_TYPE_INVALID == req) { /* SETUP */ _hcd.bmRequestType = *(uint8_t*)_hcd.pipe0.buf; _hcd.pipe0.buf = NULL; hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); return; } /* DATA OUT */ if (edpt0_xfer_out()) { hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), _hcd.pipe0.length - _hcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } } static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum) { (void)rhport; bool completed; uint8_t result; volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); unsigned const csrl = regs->TXCSRL; // TU_LOG1(" TXCSRL%d = %x\r\n", pipenum, csrl); if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) { if (csrl & USB_TXCSRL1_TXRDY) regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH; else regs->TXCSRL = csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR); completed = true; result = (csrl & USB_TXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; } else { completed = pipe_xfer_out(pipenum); result = XFER_RESULT_SUCCESS; } if (completed) { pipe_addr_t *addr = &_hcd.addr[pipenum - 1][1]; pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; hcd_event_xfer_complete(addr->dev, addr->ep, pipe->length - pipe->remaining, result, true); } } static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) { (void)rhport; bool completed; uint8_t result; volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); unsigned const csrl = regs->RXCSRL; // TU_LOG1(" RXCSRL%d = %x\r\n", pipenum, csrl); if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) { if (csrl & USB_RXCSRL1_RXRDY) regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH; else regs->RXCSRL = csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR); completed = true; result = (csrl & USB_RXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; } else { completed = pipe_xfer_in(pipenum); result = XFER_RESULT_SUCCESS; } if (completed) { pipe_addr_t *addr = &_hcd.addr[pipenum - 1][0]; pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; hcd_event_xfer_complete(addr->dev, addr->ep, pipe->length - pipe->remaining, result, true); } } /*------------------------------------------------------------------ * Host API *------------------------------------------------------------------*/ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; NVIC_ClearPendingIRQ(USB0_IRQn); _hcd.bmRequestType = REQUEST_TYPE_INVALID; USB0->DEVCTL |= USB_DEVCTL_SESSION; USB0->IE = USB_IE_DISCON | USB_IE_CONN | USB_IE_BABBLE | USB_IE_RESUME; return true; } void hcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB0_IRQn); } void hcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB0_IRQn); } uint32_t hcd_frame_number(uint8_t rhport) { (void)rhport; /* The device must be reset at least once after connection * in order to start the frame counter. */ if (_hcd.need_reset) hcd_port_reset(rhport); return USB0->FRAME; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ bool hcd_port_connect_status(uint8_t rhport) { (void)rhport; unsigned devctl = USB0->DEVCTL; if (!(devctl & USB_DEVCTL_HOST)) return false; if (devctl & (USB_DEVCTL_LSDEV | USB_DEVCTL_FSDEV)) return true; return false; } void hcd_port_reset(uint8_t rhport) { (void)rhport; USB0->POWER |= USB_POWER_HSENAB | USB_POWER_RESET; unsigned cnt = SystemCoreClock / 1000 * 20; while (cnt--) __NOP(); USB0->POWER &= ~USB_POWER_RESET; _hcd.need_reset = false; } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; unsigned devctl = USB0->DEVCTL; if (devctl & USB_DEVCTL_LSDEV) return TUSB_SPEED_LOW; if (!(devctl & USB_DEVCTL_FSDEV)) return TUSB_SPEED_INVALID; if (USB0->POWER & USB_POWER_HSMODE) return TUSB_SPEED_HIGH; return TUSB_SPEED_FULL; } void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void)rhport; if (sizeof(_hcd.ctl_mps) <= dev_addr) return; unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); _hcd.ctl_mps[dev_addr] = 0; if (!dev_addr) return; pipe_addr_t *p = &_hcd.addr[0][0]; for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i) { for (unsigned j = 0; j < 2; ++j, ++p) { if (dev_addr != p->dev) continue; hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + i + 1; hw_endpoint_t volatile *regs = edpt_regs(i); USB0->EPIDX = i + 1; if (j) { USB0->TXIE &= ~TU_BIT(i + 1); if (regs->TXCSRL & USB_TXCSRL1_TXRDY) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; regs->TXMAXP = 0; regs->TXTYPE = 0; regs->TXINTERVAL = 0; fadr->TXFUNCADDR = 0; fadr->TXHUBADDR = 0; fadr->TXHUBPORT = 0; USB0->TXFIFOADD = 0; USB0->TXFIFOSZ = 0; } else { USB0->RXIE &= ~TU_BIT(i + 1); if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; regs->RXMAXP = 0; regs->RXTYPE = 0; regs->RXINTERVAL = 0; fadr->RXFUNCADDR = 0; fadr->RXHUBADDR = 0; fadr->RXHUBPORT = 0; USB0->RXFIFOADD = 0; USB0->RXFIFOSZ = 0; } p->dev = 0; p->ep = 0; pipe_state_t *pipe = &_hcd.pipe[i][j]; pipe->buf = NULL; pipe->length = 0; pipe->remaining = 0; } } if (ie) NVIC_EnableIRQ(USB0_IRQn); } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void)rhport; pipe_write_packet((void*)(uintptr_t)setup_packet, &USB0->FIFO0_WORD, 8); _hcd.pipe0.buf = (void*)(uintptr_t)setup_packet; _hcd.pipe0.length = 8; _hcd.pipe0.remaining = 0; tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); switch (bus_info.speed) { default: return false; case TUSB_SPEED_LOW: USB0->TYPE0 = USB_TYPE0_SPEED_LOW; break; case TUSB_SPEED_FULL: USB0->TYPE0 = USB_TYPE0_SPEED_FULL; break; case TUSB_SPEED_HIGH: USB0->TYPE0 = USB_TYPE0_SPEED_HIGH; break; } USB0->TXHUBADDR0 = bus_info.hub_addr; USB0->TXHUBPORT0 = bus_info.hub_port; USB0->TXFUNCADDR0 = dev_addr; USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; if (sizeof(_hcd.ctl_mps) <= dev_addr) return false; unsigned const ep_addr = ep_desc->bEndpointAddress; unsigned const epn = tu_edpt_number(ep_addr); if (0 == epn) { _hcd.ctl_mps[dev_addr] = ep_desc->wMaxPacketSize; return true; } unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; /* Find a free pipe */ unsigned pipenum = 0; pipe_addr_t *p = &_hcd.addr[0][dir_tx]; for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { if (0 == p->ep) { p->dev = dev_addr; p->ep = ep_addr; pipenum = i + 1; break; } } if (!pipenum) return false; unsigned const xfer = ep_desc->bmAttributes.xfer; unsigned const mps = tu_edpt_packet_size(ep_desc); pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; pipe->buf = NULL; pipe->length = 0; pipe->remaining = 0; uint8_t pipe_type = 0; tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); switch (bus_info.speed) { default: return false; case TUSB_SPEED_LOW: pipe_type |= USB_TXTYPE1_SPEED_LOW; break; case TUSB_SPEED_FULL: pipe_type |= USB_TXTYPE1_SPEED_FULL; break; case TUSB_SPEED_HIGH: pipe_type |= USB_TXTYPE1_SPEED_HIGH; break; } switch (xfer) { default: return false; case TUSB_XFER_BULK: pipe_type |= USB_TXTYPE1_PROTO_BULK; break; case TUSB_XFER_INTERRUPT: pipe_type |= USB_TXTYPE1_PROTO_INT; break; case TUSB_XFER_ISOCHRONOUS: pipe_type |= USB_TXTYPE1_PROTO_ISOC; break; } hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + pipenum; hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); if (dir_tx) { fadr->TXFUNCADDR = dev_addr; fadr->TXHUBADDR = bus_info.hub_addr; fadr->TXHUBPORT = bus_info.hub_port; regs->TXMAXP = mps; regs->TXTYPE = pipe_type | epn; regs->TXINTERVAL = ep_desc->bInterval; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; USB0->TXIE |= TU_BIT(pipenum); } else { fadr->RXFUNCADDR = dev_addr; fadr->RXHUBADDR = bus_info.hub_addr; fadr->RXHUBPORT = bus_info.hub_port; regs->RXMAXP = mps; regs->RXTYPE = pipe_type | epn; regs->RXINTERVAL = ep_desc->bInterval; if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; USB0->RXIE |= TU_BIT(pipenum); } /* Setup FIFO */ int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; unsigned addr = find_free_memory(size_in_log2_minus3); TU_ASSERT(addr); USB0->EPIDX = pipenum; if (dir_tx) { USB0->TXFIFOADD = addr; USB0->TXFIFOSZ = size_in_log2_minus3; } else { USB0->RXFIFOADD = addr; USB0->RXFIFOSZ = size_in_log2_minus3; } return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void)rhport; bool ret = false; if (0 == tu_edpt_number(ep_addr)) { ret = edpt0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } else { ret = edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } return ret; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; // TODO not implemented yet return false; } // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; unsigned const pipenum = find_pipe(dev_addr, ep_addr); if (!pipenum) return false; hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; if (dir_tx) regs->TXCSRL = USB_TXCSRL1_CLRDT; else regs->RXCSRL = USB_RXCSRL1_CLRDT; return true; } /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; uint_fast8_t is, txis, rxis; is = USB0->IS; /* read and clear interrupt status */ txis = USB0->TXIS; /* read and clear interrupt status */ rxis = USB0->RXIS; /* read and clear interrupt status */ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); is &= USB0->IE; /* Clear disabled interrupts */ if (is & USB_IS_RESUME) { } if (is & USB_IS_CONN) { _hcd.need_reset = true; hcd_event_device_attach(rhport, true); } if (is & USB_IS_DISCON) { hcd_event_device_remove(rhport, true); } if (is & USB_IS_BABBLE) { } txis &= USB0->TXIE; /* Clear disabled interrupts */ if (txis & USB_TXIE_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); } while (txis) { unsigned const num = __builtin_ctz(txis); process_pipe_tx(rhport, num); txis &= ~TU_BIT(num); } rxis &= USB0->RXIE; /* Clear disabled interrupts */ while (rxis) { unsigned const num = __builtin_ctz(rxis); process_pipe_rx(rhport, num); rxis &= ~TU_BIT(num); } } #endif ================================================ FILE: src/portable/mentor/musb/musb_max32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MUSB_MAX32_H_ #define TUSB_MUSB_MAX32_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "mxc_device.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "usbhs_regs.h" #define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints #define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB_IRQn }; TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 return NVIC_GetEnableIRQ(musb_irqs[rhport]); #else uint32_t IRQn = (uint32_t) musb_irqs[rhport]; return ((NVIC->ISER[IRQn >> 5UL] & (1UL << (IRQn & 0x1FUL))) != 0UL) ? 1UL : 0UL; #endif } TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } static inline void musb_dcd_int_handler_enter(uint8_t rhport) { mxc_usbhs_regs_t* hs_phy = MXC_USBHS; uint32_t mxm_int, mxm_int_en, mxm_is; //Handle PHY specific events mxm_int = hs_phy->mxm_int; mxm_int_en = hs_phy->mxm_int_en; mxm_is = mxm_int & mxm_int_en; hs_phy->mxm_int = mxm_is; if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } static inline void musb_dcd_phy_init(uint8_t rhport) { (void) rhport; mxc_usbhs_regs_t* hs_phy = MXC_USBHS; // Interrupt for VBUS disconnect hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; musb_dcd_int_clear(rhport); // Unsuspend the MAC hs_phy->mxm_suspend = 0; // Configure PHY hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); hs_phy->m31_phy_xcfgi_63_32 = 0; hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); hs_phy->m31_phy_xcfgi_127_96 = 0; #ifdef USBHS_M31_CLOCK_RECOVERY hs_phy->m31_phy_noncry_rstb = 1; hs_phy->m31_phy_noncry_en = 1; hs_phy->m31_phy_outclksel = 0; hs_phy->m31_phy_coreclkin = 0; hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ #else hs_phy->m31_phy_noncry_rstb = 0; hs_phy->m31_phy_noncry_en = 0; hs_phy->m31_phy_outclksel = 1; hs_phy->m31_phy_coreclkin = 1; hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ #endif hs_phy->m31_phy_pll_en = 1; hs_phy->m31_phy_oscouten = 1; /* Reset PHY */ hs_phy->m31_phy_ponrst = 0; hs_phy->m31_phy_ponrst = 1; } // static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { // (void) mps; // // //Most likely the caller has already grabbed the right register block. But // //as a precaution save and restore the register bank anyways // unsigned saved_index = musb_periph_inst[rhport]->index; // // musb_periph_inst[rhport]->index = epnum; // // //Disable double buffering // if (dir_in) { // musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); // } else { // musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); // } // // musb_periph_inst[rhport]->index = saved_index; // } #endif // CFG_TUD_ENABLED #ifdef __cplusplus } #endif #endif // TUSB_MUSB_MAX32_H_ ================================================ FILE: src/portable/mentor/musb/musb_ti.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MUSB_TI_H_ #define TUSB_MUSB_TI_H_ #ifdef __cplusplus extern "C" { #endif #if CFG_TUSB_MCU == OPT_MCU_TM4C123 #include "TM4C123.h" #define FIFO0_WORD FIFO0 #define FIFO1_WORD FIFO1 #elif CFG_TUSB_MCU == OPT_MCU_TM4C129 #include "TM4C129.h" #define FIFO0_WORD FIFOA #define FIFO1_WORD FIFOB #elif CFG_TUSB_MCU == OPT_MCU_MSP432E4 #include "msp.h" #else #error "Unsupported MCUs" #endif #define MUSB_CFG_SHARED_FIFO 0 #define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 const uintptr_t MUSB_BASES[] = { USB0_BASE }; // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB0_IRQn }; static inline void musb_dcd_phy_init(uint8_t rhport){ (void)rhport; //Nothing to do for this part } TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { return NVIC_GetEnableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } static inline void musb_dcd_int_handler_enter(uint8_t rhport) { (void)rhport; //Nothing to do for this part } #endif // CFG_TUD_ENABLED #ifdef __cplusplus } #endif #endif // TUSB_MUSB_TI_H_ ================================================ FILE: src/portable/mentor/musb/musb_type.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ /****************************************************************************** * * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 COPYRIGHT * OWNER OR CONTRIBUTORS 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. * *******************************************************************************/ #ifndef TUSB_MUSB_TYPE_H_ #define TUSB_MUSB_TYPE_H_ #include "stdint.h" #ifdef __cplusplus extern "C" { #endif #ifndef __IO #define __IO volatile #endif #ifndef __I #define __I volatile const #endif #ifndef __O #define __O volatile #endif #ifndef __R #define __R volatile const #endif typedef struct TU_ATTR_PACKED { __IO uint16_t maxp; // 0x00, 0x04: MAXP __IO uint8_t csrl; // 0x02, 0x06: CSRL __IO uint8_t csrh; // 0x03, 0x07: CSRH }musb_ep_maxp_csr_t; // 0: TX (device IN, host OUT) // 1: RX (device OUT, host IN) typedef struct TU_ATTR_PACKED { union { struct { __IO uint16_t tx_maxp; // 0x00: TXMAXP union { __IO uint8_t csr0l; // 0x02: CSR0 __IO uint8_t tx_csrl; // 0x02: TX CSRL }; union { __IO uint8_t csr0h; // 0x03: CSR0H __IO uint8_t tx_csrh; // 0x03: TX CSRH }; __IO uint16_t rx_maxp; // 0x04: RX MAXP __IO uint8_t rx_csrl; // 0x06: RX CSRL __IO uint8_t rx_csrh; // 0x07: RX CSRH }; musb_ep_maxp_csr_t maxp_csr[2]; }; union { __IO uint16_t count0; // 0x08: COUNT0 __IO uint16_t rx_count; // 0x08: RX COUNT }; union { __IO uint8_t type0; // 0x0A: TYPE0 (host only) __IO uint8_t tx_type; // 0x0A: TX TYPE }; __IO uint8_t tx_interval; // 0x0B: TX INTERVAL __IO uint8_t rx_type; // 0x0C: RX TYPE __IO uint8_t rx_interval; // 0x0D: RX INTERVAL __IO uint8_t reserved_0x0e; // 0x0E: Reserved union { __IO uint8_t config_data0; // 0x0F: CONFIG DATA struct { __IO uint8_t utmi_data_width : 1; // [0] UTMI Data Width __IO uint8_t softconn_en : 1; // [1] Soft Connect Enable __IO uint8_t dynamic_fifo : 1; // [2] Dynamic FIFO Sizing __IO uint8_t hb_tx_en : 1; // [3] High Bandwidth TX ISO Enable __IO uint8_t hb_rx_en : 1; // [4] High Bandwidth RX ISO Enable __IO uint8_t big_endian : 1; // [5] Big Endian __IO uint8_t mp_tx_en : 1; // [6] Auto splitting BULK TX Enable __IO uint8_t mp_rx_en : 1; // [7] Auto amalgamation BULK RX Enable } config_data0_bit; __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE struct { __IO uint8_t tx : 4; // [3:0] TX FIFO Size __IO uint8_t rx : 4; // [7:4] RX FIFO Size }fifo_size_bit; }; } musb_ep_csr_t; TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); typedef struct { //------------- Common -------------// __IO uint8_t faddr; // 0x00: FADDR union { __IO uint8_t power; // 0x01: POWER struct { __IO uint8_t suspend_mode_en : 1; // [0] SUSPEND Mode Enable __IO uint8_t suspend_mode : 1; // [1] SUSPEND Mode __IO uint8_t resume_mode : 1; // [2] RESUME __IO uint8_t reset : 1; // [3] RESET __IO uint8_t highspeed_mode : 1; // [4] High Speed Mode __IO uint8_t highspeed_en : 1; // [5] High Speed Enable __IO uint8_t soft_conn : 1; // [6] Soft Connect/Disconnect __IO uint8_t iso_update : 1; // [7] Isochronous Update } power_bit; }; union { struct { __IO uint16_t intr_tx; // 0x02: INTR_TX __IO uint16_t intr_rx; // 0x04: INTR_RX }; __IO uint16_t intr_ep[2]; // 0x02-0x05: INTR_EP0-1 }; union { struct { __IO uint16_t intr_txen; // 0x06: INTR_TXEN __IO uint16_t intr_rxen; // 0x08: INTR_RXEN }; __IO uint16_t intren_ep[2]; // 0x06-0x09: INTREN_EP0-1 }; __IO uint8_t intr_usb; // 0x0A: INTRUSB __IO uint8_t intr_usben; // 0x0B: INTRUSBEN __IO uint16_t frame; // 0x0C: FRAME __IO uint8_t index; // 0x0E: INDEX __IO uint8_t testmode; // 0x0F: TESTMODE //------------- Endpoint CSR (indexed) -------------// musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 //------------- FIFOs -------------// __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 // Common (2) __IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t misc; // 0x61: MISC //------------- Dynammic FIFO (indexed) -------------// union { struct { __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ }; __IO uint8_t fifo_size[2]; }; union { struct { __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR }; __IO uint16_t fifo_addr[2]; }; //------------- Additional Control and Configuration -------------// union { __O uint32_t vcontrol; // 0x68: PHY VCONTROL __IO uint32_t vstatus; // 0x68: PHY VSTATUS }; union { __IO uint16_t hwvers; // 0x6C: HWVERS struct { __IO uint16_t minor : 10; // [9:0] Minor __IO uint16_t major : 5; // [14:10] Major __IO uint16_t rc : 1; // [15] Release Candidate } hwvers_bit; }; __R uint16_t rsv_0x6e_0x77[5]; // 0x6E-0x77: Reserved //------------- Additional Configuration -------------// union { __IO uint8_t epinfo; // 0x78: EPINFO struct { __IO uint8_t tx_ep_num : 4; // [3:0] TX Endpoints __IO uint8_t rx_ep_num : 4; // [7:4] RX Endpoints } epinfo_bit; }; union { __IO uint8_t raminfo; // 0x79: RAMINFO struct { __IO uint8_t ram_bits : 4; // [3:0] RAM Address Bus Width __IO uint8_t dma_channel : 4; // [7:4] DMA Channels }raminfo_bit; }; union { __IO uint8_t link_info; // 0x7A: LINK_INFO __IO uint8_t adi_softreset; // 0x7A: AnalogDevice SOFTRESET }; __IO uint8_t vplen; // 0x7B: VPLEN __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 __IO uint8_t soft_rst; // 0x7F: SOFT_RST //------------- Target Endpoints (multipoint option) -------------// __IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t cthsrtn; // 0x82: CTHSRTN __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR //------------- DMA -------------// __IO uint8_t dma_intr; // 0x200: DMA_INTR __R uint8_t rsv_0x201_0x203[3]; // 0x201-0x203: Reserved struct { __IO uint16_t cntl; // 0x204: DMA_CNTL __IO uint16_t rsv_0x206; // 0x206: Reserved __IO uint32_t addr; // 0x208: DMA_ADDR __IO uint32_t count; // 0x20C: DMA_COUNT __IO uint32_t rsv_0x210; // 0x210: Reserved }dma[8]; __R uint32_t rsv_0x284_0x2FF[31]; // 0x284-0x2FF: Reserved //------------- Extended -------------// __R uint32_t rsv_0x300; // 0x300: Reserved struct { __IO uint16_t count; // 0x304: REQ_PACKET_COUNT __R uint16_t rsv_0x306; // 0x306: Reserved }req_packet[15]; __IO uint16_t rx_doulbe_packet_disable; // 0x340: RX_DOUBLE_PACKET_DISABLE __IO uint16_t tx_double_packet_disable; // 0x342: TX_DOUBLE_PACKET_DISABLE __IO uint16_t chirp_timeout; // 0x344: CHIRP_TIMEOUT __IO uint16_t hs_to_utm; // 0x346: HS_TO_UTM delay __IO uint16_t hs_timeout_adder; // 0x348: HS_TIMEOUT_ADDER __R uint8_t rsv_34A_34f[6]; // 0x34A-0x34F: Reserved } musb_regs_t; TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x350, "size is not correct"); //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) { musb_regs->index = epnum; return &musb_regs->indexed_csr; } //--------------------------------------------------------------------+ // Register Bit Field //--------------------------------------------------------------------+ // 0x01: Power #define MUSB_POWER_ISOUP 0x0080 // Isochronous Update #define MUSB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect #define MUSB_POWER_HSENAB 0x0020 // High Speed Enable #define MUSB_POWER_HSMODE 0x0010 // High Speed Enable #define MUSB_POWER_RESET 0x0008 // RESET Signaling #define MUSB_POWER_RESUME 0x0004 // RESUME Signaling #define MUSB_POWER_SUSPEND 0x0002 // SUSPEND Mode #define MUSB_POWER_PWRDNPHY 0x0001 // Power Down PHY // Interrupt TX/RX Status and Enable: each bit is for an endpoint // 0x6c: HWVERS #define MUSB_HWVERS_RC_SHIFT 15 #define MUSB_HWVERS_RC_MASK 0x8000 #define MUSB_HWVERS_MAJOR_SHIFT 10 #define MUSB_HWVERS_MAJOR_MASK 0x7C00 #define MUSB_HWVERS_MINOR_SHIFT 0 #define MUSB_HWVERS_MINOR_MASK 0x03FF // 0x12, 0x16: TX/RX CSRL #define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) #define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) #define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) #define MUSB_CSRL_STALLED(_rx) (1u << ((_rx) ? 6 : 5)) #define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) #define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO #define MUSB_CSRH_ISO (1u << 6) // 0x62, 0x63: TXFIFO_SZ, RXFIFO_SZ #define MUSB_FIFOSZ_DOUBLE_PACKET (1u << 4) //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_IS register. // //***************************************************************************** #define MUSB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) #define MUSB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) #define MUSB_IS_DISCON 0x0020 // Session Disconnect (OTG only) #define MUSB_IS_CONN 0x0010 // Session Connect #define MUSB_IS_SOF 0x0008 // Start of Frame #define MUSB_IS_BABBLE 0x0004 // Babble Detected #define MUSB_IS_RESET 0x0004 // RESET Signaling Detected #define MUSB_IS_RESUME 0x0002 // RESUME Signaling Detected #define MUSB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_IE register. // //***************************************************************************** #define MUSB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) #define MUSB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) #define MUSB_IE_DISCON 0x0020 // Enable Disconnect Interrupt #define MUSB_IE_CONN 0x0010 // Enable Connect Interrupt #define MUSB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt #define MUSB_IE_BABBLE 0x0004 // Enable Babble Interrupt #define MUSB_IE_RESET 0x0004 // Enable RESET Interrupt #define MUSB_IE_RESUME 0x0002 // Enable RESUME Interrupt #define MUSB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_FRAME register. // //***************************************************************************** #define MUSB_FRAME_M 0x07FF // Frame Number #define MUSB_FRAME_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TEST register. // //***************************************************************************** #define MUSB_TEST_FORCEH 0x0080 // Force Host Mode #define MUSB_TEST_FIFOACC 0x0040 // FIFO Access #define MUSB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode #define MUSB_TEST_FORCEHS 0x0010 // Force High-Speed Mode #define MUSB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable #define MUSB_TEST_TESTK 0x0004 // Test_K Mode Enable #define MUSB_TEST_TESTJ 0x0002 // Test_J Mode Enable #define MUSB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_DEVCTL register. // //***************************************************************************** #define MUSB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) #define MUSB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected #define MUSB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected #define MUSB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) #define MUSB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd #define MUSB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid #define MUSB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid #define MUSB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid #define MUSB_DEVCTL_HOST 0x0004 // Host Mode #define MUSB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) #define MUSB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_CCONF register. // //***************************************************************************** #define MUSB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable #define MUSB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIVBUSCTL // register. // //***************************************************************************** #define MUSB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator #define MUSB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIREGDATA // register. // //***************************************************************************** #define MUSB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data #define MUSB_ULPIREGDATA_REGDATA_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIREGADDR // register. // //***************************************************************************** #define MUSB_ULPIREGADDR_ADDR_M 0x00FF // Register Address #define MUSB_ULPIREGADDR_ADDR_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIREGCTL // register. // //***************************************************************************** #define MUSB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control #define MUSB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete #define MUSB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_EPINFO register. // //***************************************************************************** #define MUSB_EPINFO_RXEP_M 0x00F0 // RX Endpoints #define MUSB_EPINFO_TXEP_M 0x000F // TX Endpoints #define MUSB_EPINFO_RXEP_S 4 #define MUSB_EPINFO_TXEP_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_RAMINFO register. // //***************************************************************************** #define MUSB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels #define MUSB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width #define MUSB_RAMINFO_DMACHAN_S 4 #define MUSB_RAMINFO_RAMBITS_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_CONTIM register. // //***************************************************************************** #define MUSB_CONTIM_WTCON_M 0x00F0 // Connect Wait #define MUSB_CONTIM_WTID_M 0x000F // Wait ID #define MUSB_CONTIM_WTCON_S 4 #define MUSB_CONTIM_WTID_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_VPLEN register. // //***************************************************************************** #define MUSB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length #define MUSB_VPLEN_VPLEN_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_HSEOF register. // //***************************************************************************** #define MUSB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap #define MUSB_HSEOF_HSEOFG_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_FSEOF register. // //***************************************************************************** #define MUSB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap #define MUSB_FSEOF_FSEOFG_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_LSEOF register. // //***************************************************************************** #define MUSB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap #define MUSB_LSEOF_LSEOFG_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_CSRL0 register. // //***************************************************************************** #define MUSB_CSRL0_NAKTO 0x0080 // NAK Timeout #define MUSB_CSRL0_SETENDC 0x0080 // Setup End Clear #define MUSB_CSRL0_STATUS 0x0040 // STATUS Packet #define MUSB_CSRL0_RXRDYC 0x0040 // RXRDY Clear #define MUSB_CSRL0_REQPKT 0x0020 // Request Packet #define MUSB_CSRL0_STALL 0x0020 // Send Stall #define MUSB_CSRL0_SETEND 0x0010 // Setup End #define MUSB_CSRL0_ERROR 0x0010 // Error #define MUSB_CSRL0_DATAEND 0x0008 // Data End #define MUSB_CSRL0_SETUP 0x0008 // Setup Packet #define MUSB_CSRL0_STALLED 0x0004 // Endpoint Stalled #define MUSB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready #define MUSB_CSRL0_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_CSRH0 register. // //***************************************************************************** #define MUSB_CSRH0_DISPING 0x0008 // PING Disable #define MUSB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable #define MUSB_CSRH0_DT 0x0002 // Data Toggle #define MUSB_CSRH0_FLUSH 0x0001 // Flush FIFO //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TYPE0 register. // //***************************************************************************** #define MUSB_TYPE0_SPEED_M 0x00C0 // Operating Speed #define MUSB_TYPE0_SPEED_HIGH 0x0040 // High #define MUSB_TYPE0_SPEED_FULL 0x0080 // Full #define MUSB_TYPE0_SPEED_LOW 0x00C0 // Low //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_NAKLMT register. // //***************************************************************************** #define MUSB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit #define MUSB_NAKLMT_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TXCSRL1 register. // //***************************************************************************** #define MUSB_TXCSRL1_NAKTO 0x0080 // NAK Timeout #define MUSB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle #define MUSB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled #define MUSB_TXCSRL1_STALL 0x0010 // Send STALL #define MUSB_TXCSRL1_SETUP 0x0010 // Setup Packet #define MUSB_TXCSRL1_FLUSH 0x0008 // Flush FIFO #define MUSB_TXCSRL1_ERROR 0x0004 // Error #define MUSB_TXCSRL1_UNDRN 0x0004 // Underrun #define MUSB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty #define MUSB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TXCSRH1 register. // //***************************************************************************** #define MUSB_TXCSRH1_AUTOSET 0x0080 // Auto Set #define MUSB_TXCSRH1_ISO 0x0040 // Isochronous Transfers #define MUSB_TXCSRH1_MODE 0x0020 // Mode #define MUSB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable #define MUSB_TXCSRH1_FDT 0x0008 // Force Data Toggle #define MUSB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode #define MUSB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable #define MUSB_TXCSRH1_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_RXCSRL1 register. // //***************************************************************************** #define MUSB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle #define MUSB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled #define MUSB_RXCSRL1_STALL 0x0020 // Send STALL #define MUSB_RXCSRL1_REQPKT 0x0020 // Request Packet #define MUSB_RXCSRL1_FLUSH 0x0010 // Flush FIFO #define MUSB_RXCSRL1_DATAERR 0x0008 // Data Error #define MUSB_RXCSRL1_NAKTO 0x0008 // NAK Timeout #define MUSB_RXCSRL1_OVER 0x0004 // Overrun #define MUSB_RXCSRL1_ERROR 0x0004 // Error #define MUSB_RXCSRL1_FULL 0x0002 // FIFO Full #define MUSB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_RXCSRH1 register. // //***************************************************************************** #define MUSB_RXCSRH1_AUTOCL 0x0080 // Auto Clear #define MUSB_RXCSRH1_AUTORQ 0x0040 // Auto Request #define MUSB_RXCSRH1_ISO 0x0040 // Isochronous Transfers #define MUSB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable #define MUSB_RXCSRH1_DISNYET 0x0010 // Disable NYET #define MUSB_RXCSRH1_PIDERR 0x0010 // PID Error #define MUSB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode #define MUSB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable #define MUSB_RXCSRH1_DT 0x0002 // Data Toggle #define MUSB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TXTYPE1 register. // //***************************************************************************** #define MUSB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed #define MUSB_TXTYPE1_SPEED_DFLT 0x0000 // Default #define MUSB_TXTYPE1_SPEED_HIGH 0x0040 // High #define MUSB_TXTYPE1_SPEED_FULL 0x0080 // Full #define MUSB_TXTYPE1_SPEED_LOW 0x00C0 // Low #define MUSB_TXTYPE1_PROTO_M 0x0030 // Protocol #define MUSB_TXTYPE1_PROTO_CTRL 0x0000 // Control #define MUSB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous #define MUSB_TXTYPE1_PROTO_BULK 0x0020 // Bulk #define MUSB_TXTYPE1_PROTO_INT 0x0030 // Interrupt #define MUSB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number #define MUSB_TXTYPE1_TEP_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_TXINTERVAL1 // register. // //***************************************************************************** #define MUSB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit #define MUSB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling #define MUSB_TXINTERVAL1_TXPOLL_S 0 #define MUSB_TXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_RXTYPE1 register. // //***************************************************************************** #define MUSB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed #define MUSB_RXTYPE1_SPEED_DFLT 0x0000 // Default #define MUSB_RXTYPE1_SPEED_HIGH 0x0040 // High #define MUSB_RXTYPE1_SPEED_FULL 0x0080 // Full #define MUSB_RXTYPE1_SPEED_LOW 0x00C0 // Low #define MUSB_RXTYPE1_PROTO_M 0x0030 // Protocol #define MUSB_RXTYPE1_PROTO_CTRL 0x0000 // Control #define MUSB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous #define MUSB_RXTYPE1_PROTO_BULK 0x0020 // Bulk #define MUSB_RXTYPE1_PROTO_INT 0x0030 // Interrupt #define MUSB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number #define MUSB_RXTYPE1_TEP_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_RXINTERVAL1 // register. // //***************************************************************************** #define MUSB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling #define MUSB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit #define MUSB_RXINTERVAL1_TXPOLL_S 0 #define MUSB_RXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_DMACTL0 register. // //***************************************************************************** #define MUSB_DMACTL0_BRSTM_M 0x0600 // Burst Mode #define MUSB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length #define MUSB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length #define MUSB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length #define MUSB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length #define MUSB_DMACTL0_ERR 0x0100 // Bus Error Bit #define MUSB_DMACTL0_EP_M 0x00F0 // Endpoint number #define MUSB_DMACTL0_IE 0x0008 // DMA Interrupt Enable #define MUSB_DMACTL0_MODE 0x0004 // DMA Transfer Mode #define MUSB_DMACTL0_DIR 0x0002 // DMA Direction #define MUSB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable #define MUSB_DMACTL0_EP_S 4 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_DMAADDR0 register. // //***************************************************************************** #define MUSB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address #define MUSB_DMAADDR0_ADDR_S 2 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_DMACOUNT0 // register. // //***************************************************************************** #define MUSB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count #define MUSB_DMACOUNT0_COUNT_S 2 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_CTO register. // //***************************************************************************** #define MUSB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value #define MUSB_CTO_CCTV_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_HHSRTN register. // //***************************************************************************** #define MUSB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating // Delay #define MUSB_HHSRTN_HHSRTN_S 0 //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_HSBT register. // //***************************************************************************** #define MUSB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder #define MUSB_HSBT_HSBT_S 0 #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/microchip/pic/README.md ================================================ # Microchip PIC Chipidea FS Driver This driver adds support for Microchip PIC microcontrollers with full-speed Chipidea USB peripheral to the TinyUSB stack. It supports the following families: - PIC32MX (untested) - PIC32MM - PIC32MK (untested) - PIC24FJ - PIC24EP (untested) - dsPIC33EP (untested) Currently only the device mode is supported. ## Important Notes ### Handling of shared VBUS & GPIO pin Some PICs have the USB VBUS pin bonded with a GPIO pin in the chip package. This driver does **NOT** handle the potential conflict between the VBUS and GPIO functionalities. Developers must ensure that the GPIO pin is tristated when the VBUS pin is managed by the USB peripheral in order to prevent damaging the chip. This design choice allows developers the flexibility to use the GPIO functionality for controlling VBUS in device mode if desired. ## TODO ### Handle USB remote wakeup timing correctly The Chipidea FS IP doesn't handle the RESUME signal automatically and it must be managed in software. It needs to be asserted for exactly 10ms, and this is impossible to do without per-device support due to BSP differences. For now, a simple for-based loop is used. ### 8-bit PIC support The 8-bit PICs also uses the Chipidea FS IP. Technically it's possible to support them as well. Possible difficulties: - Memory size constraints (1KB/8KB ballpark) - A third BDT layout (now we have two) - Different compiler-specific directives - Compiler bugs if you use SDCC ## Author [ReimuNotMoe](https://github.com/ReimuNotMoe) at SudoMaker, Ltd. ## Credits This driver is based on: - Microchip's USB driver (usb_device.c) - TinyUSB's NXP KHCI driver (dcd_khci.c) ================================================ FILE: src/portable/microchip/pic/dcd_pic.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022-2024 SudoMaker, Ltd. * Author: Mike Yang (Reimu NotMoe) * * Based on usb_device.c - Copyright (c) 2015 Microchip Technology Inc. * Based on dcd_khci.c - Copyright (c) 2020 Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || \ CFG_TUSB_MCU == OPT_MCU_PIC32MK || CFG_TUSB_MCU == OPT_MCU_PIC24 || \ CFG_TUSB_MCU == OPT_MCU_DSPIC33) #include #include "device/dcd.h" #if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK) #define TU_PIC_INT_SIZE 4 #elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33) #define TU_PIC_INT_SIZE 2 #else #error Unsupportd PIC MCU #endif #if TU_PIC_INT_SIZE == 4 #ifndef KVA_TO_PA #define KVA_TO_PA(kva) ((uint32_t)(kva) & 0x1fffffff) #endif #ifndef PA_TO_KVA1 #define PA_TO_KVA1(pa) ((uint32_t)(pa) | 0xA0000000) #endif #else #ifndef KVA_TO_PA #define KVA_TO_PA(kva) (kva) #endif #ifndef PA_TO_KVA1 #define PA_TO_KVA1(pa) (pa) #endif #endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { TOK_PID_OUT = 0x1u, TOK_PID_IN = 0x9u, TOK_PID_SETUP = 0xDu, }; // The BDT is 8 bytes on 32bit PICs and 4 bytes on 8/16bit PICs #if TU_PIC_INT_SIZE == 4 typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { uint16_t : 2; uint16_t tok_pid : 4; uint16_t data : 1; uint16_t own : 1; uint16_t : 8; }; struct { uint16_t : 2; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; uint16_t : 10; }; }; uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; } buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); #else typedef struct TU_ATTR_PACKED { union { uint16_t head; struct { uint16_t : 10; uint16_t tok_pid : 4; uint16_t data : 1; uint16_t own : 1; }; struct { uint16_t : 10; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; }; struct { uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; } buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 4, "size is not correct" ); #endif typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { uint32_t max_packet_size :11; uint32_t : 5; uint32_t odd : 1; uint32_t :15; }; }; uint16_t length; uint16_t remaining; } endpoint_state_t; TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); typedef struct { union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; #if TU_PIC_INT_SIZE == 4 uint16_t bda[256]; #else uint8_t bda[256]; #endif }; TU_ATTR_ALIGNED(4) union { endpoint_state_t endpoint[16][2]; endpoint_state_t endpoint_unified[16 * 2]; }; uint8_t setup_packet[8]; uint8_t addr; } dcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd; #if TU_PIC_INT_SIZE == 4 TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); #else TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 256, "size is not correct" ); #endif #if TU_PIC_INT_SIZE == 4 typedef uint32_t ep_reg_t; #elif TU_PIC_INT_SIZE == 2 typedef uint16_t ep_reg_t; #endif static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) { #if CFG_TUSB_MCU == OPT_MCU_PIC32MK volatile void *ep_reg_base = rhport ? (&U2EP0) : (&U1EP0); #else volatile void *ep_reg_base = &U1EP0; #endif #if TU_PIC_INT_SIZE == 4 const size_t offset = 0x10; #else const size_t offset = 0x2; #endif return ep_reg_base + offset * ep_num; } static inline ep_reg_t ep_read(uint8_t rhport, uint8_t ep_num) { volatile ep_reg_t *ep = ep_addr(rhport, ep_num); return *ep; } static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { volatile ep_reg_t *ep = ep_addr(rhport, ep_num); *ep = val; } static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { #if TU_PIC_INT_SIZE == 4 volatile ep_reg_t *ep_clr = (ep_addr(rhport, ep_num) + 0x4); *ep_clr = val; #else ep_reg_t v = ep_read(rhport, ep_num); v &= ~val; ep_write(rhport, ep_num, v); #endif } static inline void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val) { #if TU_PIC_INT_SIZE == 4 volatile ep_reg_t *ep_s = (ep_addr(rhport, ep_num) + 0x8); *ep_s = val; #else ep_reg_t v = ep_read(rhport, ep_num); v |= val; ep_write(rhport, ep_num, v); #endif } static inline void intr_enable(uint8_t rhport) { #if CFG_TUSB_MCU == OPT_MCU_PIC32MM IEC0SET = _IEC0_USBIE_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MX IEC1SET = _IEC1_USBIE_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK if (rhport == 0) IEC1SET = _IEC1_USB1IE_MASK; else IEC7SET = _IEC7_USB2IE_MASK; #elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) IEC5bits.USB1IE = 1; #endif } static inline void intr_disable(uint8_t rhport) { #if CFG_TUSB_MCU == OPT_MCU_PIC32MM IEC0CLR = _IEC0_USBIE_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MX IEC1CLR = _IEC1_USBIE_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK if (rhport == 0) IEC1CLR = _IEC1_USB1IE_MASK; else IEC7CLR = _IEC7_USB2IE_MASK; #elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) IEC5bits.USB1IE = 0; #endif } static inline int intr_is_enabled(uint8_t rhport) { #if CFG_TUSB_MCU == OPT_MCU_PIC32MM return IEC0bits.USBIE; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MX return IEC1bits.USBIE; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK if (rhport == 0) return IEC1bits.USB1IE; else return IEC7bits.USB2IE; #elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) return IEC5bits.USB1IE; #endif } static inline void intr_clear(uint8_t rhport) { #if CFG_TUSB_MCU == OPT_MCU_PIC32MM IFS0CLR = _IFS0_USBIF_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MX IFS1CLR = _IFS1_USBIF_MASK; #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK if (rhport == 0) IFS1CLR = _IFS1_USB1IF_MASK; else IFS7CLR = _IFS7_USB2IF_MASK; #elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33) IFS5bits.USB1IF = 0; #endif } static void prepare_next_setup_packet(uint8_t rhport) { const unsigned out_odd = _dcd.endpoint[0][0].odd; const unsigned in_odd = _dcd.endpoint[0][1].odd; // Abandon any previous control transfers that might have been using EP0. // Ordinarily, nothing actually needs abandoning, since the previous control // transfer would have completed successfully prior to the host sending the // next SETUP packet. However, in a timeout error case, or after an EP0 // STALL event, one or more UOWN bits might still be set. If so, we should // clear the UOWN bits, so the EP0 IN/OUT endpoints are in a known inactive // state, ready for re-arming by the `dcd_edpt_xfer' function that will be // called next. _dcd.bdt[0][0][out_odd].data = 0; _dcd.bdt[0][0][out_odd].own = 0; _dcd.bdt[0][0][out_odd ^ 1].data = 1; _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd].own = 0; _dcd.bdt[0][1][in_odd ^ 1].data = 0; _dcd.bdt[0][1][in_odd ^ 1].own = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.setup_packet, sizeof(_dcd.setup_packet)); } static void process_stall(uint8_t rhport) { for (int i = 0; i < 16; ++i) { unsigned const endpt = ep_read(rhport, i); if (endpt & _U1EP0_EPSTALL_MASK) { // prepare next setup if endpoint0 if ( i == 0 ) prepare_next_setup_packet(rhport); // clear stall bit ep_clear(rhport, i, _U1EP0_EPSTALL_MASK); } } } static void process_tokdne(uint8_t rhport) { ep_reg_t s = U1STAT; U1IR = _U1IR_TRNIF_MASK; uint8_t epnum = (s >> _U1STAT_ENDPT0_POSITION); uint8_t dir = (s & _U1STAT_DIR_MASK) >> _U1STAT_DIR_POSITION; unsigned odd = (s & _U1STAT_PPBI_MASK) ? 1 : 0; buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; /* fetch pid before discarded by the next steps */ const unsigned pid = bd->tok_pid; /* reset values for a next transfer */ bd->bdt_stall = 0; bd->dts = 1; bd->ninc = 0; bd->keep = 0; /* update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, (uint8_t *)PA_TO_KVA1(bd->addr), true); #if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK; #else U1CONbits.PKTDIS = 0; #endif return; } const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; if (remaining && bc == ep->max_packet_size) { /* continue the transferring consecutive data */ ep->remaining = remaining; const int next_remaining = remaining - ep->max_packet_size; if (next_remaining > 0) { /* prepare to the after next transfer */ bd->addr += ep->max_packet_size * 2; bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; bd->own = 1; /* the own bit must set after addr */ } return; } const unsigned length = ep->length; dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), length - remaining, XFER_RESULT_SUCCESS, true); if (0 == epnum && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ if (_dcd.addr) { /* When the transfer was the SetAddress, * the device address should be updated here. */ U1ADDR = _dcd.addr; _dcd.addr = 0; } prepare_next_setup_packet(rhport); } } static void process_bus_reset(uint8_t rhport) { #if TU_PIC_INT_SIZE == 4 U1PWRCCLR = _U1PWRC_USUSPEND_MASK; U1CONSET = _U1CON_PPBRST_MASK; #else U1PWRCbits.USUSPND = 0; U1CONbits.PPBRST = 1; #endif U1ADDR = 0; U1IE = _U1IE_URSTIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK | _U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK; U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK; for (unsigned i = 1; i < 16; ++i) { ep_write(rhport, i, 0); } buffer_descriptor_t *bd = _dcd.bdt[0][0]; for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } const endpoint_state_t ep0 = { .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, .odd = 0, .length = 0, .remaining = 0, }; _dcd.endpoint[0][0] = ep0; _dcd.endpoint[0][1] = ep0; tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); _dcd.addr = 0; prepare_next_setup_packet(rhport); #if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_PPBRST_MASK; #else U1CONbits.PPBRST = 0; #endif dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } static void process_bus_sleep(uint8_t rhport) { // Enable resume & disable suspend interrupt dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } static void process_bus_resume(uint8_t rhport) { // Enable suspend & disable resume interrupt #if TU_PIC_INT_SIZE == 4 U1PWRCCLR = _U1PWRC_USUSPEND_MASK; U1IECLR = _U1IE_RESUMEIE_MASK; U1IESET = _U1IE_IDLEIE_MASK; #else U1PWRCbits.USUSPND = 0; U1IEbits.RESUMEIE = 0; U1IEbits.IDLEIE = 1; #endif dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; intr_disable(rhport); intr_clear(rhport); tu_memclr(&_dcd, sizeof(_dcd)); #if TU_PIC_INT_SIZE == 4 // The USBBUSY bit is present on PIC32s and we're required to check it // prior to powering on the USB peripheral (see DS61126F page 27) while (U1PWRCbits.USBBUSY); U1PWRCSET = _U1PWRC_USBPWR_MASK; #else U1PWRCbits.USBPWR = 1; #endif #if TU_PIC_INT_SIZE == 4 uint32_t bdt_phys = KVA_TO_PA((uintptr_t)_dcd.bdt); U1BDTP1 = (uint8_t)(bdt_phys >> 8); U1BDTP2 = (uint8_t)(bdt_phys >> 16); U1BDTP3 = (uint8_t)(bdt_phys >> 24); #else U1BDTP1 = (uint8_t)((uint16_t)(void *)_dcd.bdt >> 8); U1CNFG1bits.PPB = 2; #endif U1IE = _U1IE_URSTIE_MASK; dcd_connect(rhport); return true; } bool dcd_deinit(uint8_t rhport) { U1CON = 0; U1IE = 0; U1OTGIE = 0; #if TU_PIC_INT_SIZE == 4 U1PWRCCLR = _U1PWRC_USUSPEND_MASK | _U1PWRC_USBPWR_MASK; #else U1PWRC &= ~(_U1PWRC_USUSPEND_MASK | _U1PWRC_USBPWR_MASK); #endif return true; } void dcd_int_enable(uint8_t rhport) { intr_enable(rhport); } void dcd_int_disable(uint8_t rhport) { intr_disable(rhport); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { _dcd.addr = dev_addr & 0x7F; /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { #if TU_PIC_INT_SIZE == 4 U1CONSET = _U1CON_RESUME_MASK; #else U1CONbits.RESUME = 1; #endif // FIXME: Assert RESUME signal correctly, requires device-specific handling // For now we use a hardcoded cycle-based delay which attempts to delay 10ms // at the most common CPU frequencies. On PIC32s we assume the loop body // takes 3 cycles. On 16-bit PICs we assume the XC16 compiler is in use and // use its `__delay_ms' function. #if CFG_TUSB_MCU == OPT_MCU_PIC32MM uint32_t cnt = 24000000 / 1000 / 3; while (cnt--) asm volatile("nop"); #elif CFG_TUSB_MCU == OPT_MCU_PIC32MX uint32_t cnt = 40000000 / 1000 / 3; while (cnt--) asm volatile("nop"); #elif CFG_TUSB_MCU == OPT_MCU_PIC32MK uint32_t cnt = 120000000 / 1000 / 3; while (cnt--) asm volatile("nop"); #else __delay_ms(10); #endif #if TU_PIC_INT_SIZE == 4 U1CONCLR = _U1CON_RESUME_MASK; #else U1CONbits.RESUME = 0; #endif } void dcd_connect(uint8_t rhport) { while (!U1CONbits.USBEN) { #if TU_PIC_INT_SIZE == 4 U1CONSET = _U1CON_USBEN_SOFEN_MASK; #else U1CONbits.USBEN = 1; #endif } } void dcd_disconnect(uint8_t rhport) { U1CON = 0; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; const unsigned odd = ep->odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; /* No support for control transfer */ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); ep->max_packet_size = tu_edpt_packet_size(ep_desc); unsigned val = _U1EP0_EPCONDIS_MASK; val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? _U1EP0_EPHSHK_MASK : 0; val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK; ep_reg_t tmp = ep_read(rhport, epn); tmp |= val; ep_write(rhport, epn, tmp); if (xfer != TUSB_XFER_ISOCHRONOUS) { bd[odd].dts = 1; bd[odd].data = 0; bd[odd ^ 1].dts = 1; bd[odd ^ 1].data = 1; } return true; } void dcd_edpt_close_all(uint8_t rhport) { const unsigned ie = intr_is_enabled(rhport); intr_disable(rhport); for (unsigned i = 1; i < 16; ++i) { ep_write(rhport, i, 0); } if (ie) intr_enable(rhport); buffer_descriptor_t *bd = _dcd.bdt[1][0]; for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } endpoint_state_t *ep = &_dcd.endpoint[1][0]; for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) { /* Clear except the odd */ ep->max_packet_size = 0; ep->length = 0; ep->remaining = 0; } } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; const unsigned msk = dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK; const unsigned ie = intr_is_enabled(rhport); intr_disable(rhport); ep_clear(rhport, epn, msk); ep->max_packet_size = 0; ep->length = 0; ep->remaining = 0; bd[0].head = 0; bd[1].head = 0; if (ie) intr_enable(rhport); } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { (void) rhport; (void) desc_ep; return false; } #endif bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; TU_ASSERT(0 == bd->own); const unsigned ie = intr_is_enabled(rhport); intr_disable(rhport); ep->length = total_bytes; ep->remaining = total_bytes; const unsigned mps = ep->max_packet_size; if (total_bytes > mps) { buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; next->addr = (uint8_t *)KVA_TO_PA(buffer + mps); next->own = 1; } bd->bc = total_bytes >= mps ? mps: total_bytes; bd->addr = (uint8_t *)KVA_TO_PA(buffer); bd->own = 1; /* This bit must be set last */ if (ie) intr_enable(rhport); return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { ep_set(rhport, epn, _U1EP0_EPSTALL_MASK); } else { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd]; TU_ASSERT(0 == bd->own,); const unsigned ie = intr_is_enabled(rhport); intr_disable(rhport); bd->bdt_stall = 1; bd->own = 1; /* This bit must be set last */ if (ie) intr_enable(rhport); } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { const unsigned epn = tu_edpt_number(ep_addr); TU_VERIFY(epn,); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; TU_VERIFY(bd[odd].own,); const unsigned ie = intr_is_enabled(rhport); intr_disable(rhport); bd[odd].own = 0; // clear stall bd[odd].bdt_stall = 0; // Reset data toggle bd[odd ].data = 0; bd[odd ^ 1].data = 1; // We already cleared this in ISR, but just clear it here to be safe const unsigned endpt = ep_read(rhport, epn); if (endpt & _U1EP0_EPSTALL_MASK) { ep_clear(rhport, endpt, _U1EP0_EPSTALL_MASK); } if (ie) intr_enable(rhport); } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { uint32_t is, msk; // Part 1 - "USB interrupts" is = U1IR; msk = U1IE; U1IR = is & ~msk; is &= msk; if (is & _U1IR_UERRIF_MASK) { uint32_t es = U1EIR; U1EIR = es; U1IR = is; /* discard any pending events */ } if (is & _U1IR_URSTIF_MASK) { U1IR = is; /* discard any pending events */ process_bus_reset(rhport); } if (is & _U1IR_IDLEIF_MASK) { // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good /* * NOTE: Do not clear U1OTGIRbits.ACTVIF here! * Reason: * ACTVIF is only generated once an IDLEIF has been generated. * This is a 1:1 ratio interrupt generation. * For every IDLEIF, there will be only one ACTVIF regardless of * the number of subsequent bus transitions. * * If the ACTIF is cleared here, a problem could occur when: * [ IDLE ][bus activity -> * <--- 3 ms -----> ^ * ^ ACTVIF=1 * IDLEIF=1 * # # # # (#=Program polling flags) * ^ * This polling loop will see both * IDLEIF=1 and ACTVIF=1. * However, the program services IDLEIF first * because ACTIVIE=0. * If this routine clears the only ACTIVIF, * then it can never get out of the suspend * mode. */ U1OTGIESET = _U1OTGIE_ACTVIE_MASK; U1IR = _U1IR_IDLEIF_MASK; process_bus_sleep(rhport); } if (is & _U1IR_SOFIF_MASK) { U1IR = _U1IR_SOFIF_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } if (is & _U1IR_STALLIF_MASK) { process_stall(rhport); U1IR = _U1IR_STALLIF_MASK; } if (is & _U1IR_TRNIF_MASK) { process_tokdne(rhport); } // Part 2 - "USB OTG interrupts" is = U1OTGIR; msk = U1OTGIE; U1OTGIR = is & ~msk; is &= msk; if (is & _U1OTGIR_ACTVIF_MASK) { #if TU_PIC_INT_SIZE == 4 U1OTGIECLR = _U1OTGIE_ACTVIE_MASK; #else U1OTGIE &= ~_U1OTGIE_ACTVIE_MASK; #endif U1OTGIR = _U1OTGIR_ACTVIF_MASK; process_bus_resume(rhport); } intr_clear(rhport); } #endif ================================================ FILE: src/portable/microchip/pic32mz/dcd_pic32mz.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Jerzy Kasenberg * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ #include #include #include #include "usbhs_registers.h" #define USB_REGS ((usbhs_registers_t *) (_USB_BASE_ADDRESS)) // Maximum number of endpoints, could be trimmed down in tusb_config to reduce RAM usage. #ifndef EP_MAX #define EP_MAX 8 #endif typedef enum { EP0_STAGE_NONE, EP0_STAGE_SETUP_IN_DATA, EP0_STAGE_SETUP_OUT_NO_DATA, EP0_STAGE_SETUP_OUT_DATA, EP0_STAGE_DATA_IN, EP0_STAGE_DATA_IN_LAST_PACKET_FILLED, EP0_STAGE_DATA_IN_SENT, EP0_STAGE_DATA_OUT, EP0_STAGE_DATA_OUT_COMPLETE, EP0_STAGE_STATUS_IN, EP0_STAGE_ADDRESS_CHANGE, } ep0_stage_t; typedef struct { uint8_t * buffer; // Total length of current transfer uint16_t total_len; // Bytes transferred so far uint16_t transferred; uint16_t max_packet_size; uint16_t fifo_size; // Packet size sent or received so far. It is used to modify transferred field // after ACK is received or when filling ISO endpoint with size larger then // FIFO size. uint16_t last_packet_size; uint8_t ep_addr; } xfer_ctl_t; static struct { // Current FIFO RAM address used for FIFO allocation uint16_t fifo_addr_top; // EP0 transfer stage ep0_stage_t ep0_stage; // Device address uint8_t dev_addr; xfer_ctl_t xfer_status[EP_MAX][2]; } _dcd; // Two endpoint 0 descriptor definition for unified dcd_edpt_open() static tusb_desc_endpoint_t const ep0OUT_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0x00, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, .bInterval = 0 }; static tusb_desc_endpoint_t const ep0IN_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0x80, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, .bInterval = 0 }; #define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] static void ep0_set_stage(ep0_stage_t stage) { _dcd.ep0_stage = stage; } static ep0_stage_t ep0_get_stage(void) { return _dcd.ep0_stage; } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; // Disable endpoint interrupts for now USB_REGS->INTRRXEbits.w = 0; USB_REGS->INTRTXEbits.w = 0; // Enable Reset/Suspend/Resume interrupts only USB_REGS->INTRUSBEbits.w = 7; dcd_connect(rhport); return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; USBCRCONbits.USBIE = 1; } void dcd_int_disable(uint8_t rhport) { (void) rhport; USBCRCONbits.USBIE = 0; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; ep0_set_stage(EP0_STAGE_ADDRESS_CHANGE); // Store address it will be used later after status stage is done _dcd.dev_addr = dev_addr; // Confirm packet now, address will be set when status stage is detected USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; USB_REGS->POWERbits.RESUME = 1; tusb_time_delay_ms_api(10); USB_REGS->POWERbits.RESUME = 0; } void dcd_connect(uint8_t rhport) { (void) rhport; USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0; USB_REGS->POWERbits.SOFTCONN = 1; } void dcd_disconnect(uint8_t rhport) { (void) rhport; USB_REGS->POWERbits.SOFTCONN = 1; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0; } static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType) { uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; // Select endpoint register set (same register address is used for all endpoints. USB_REGS->INDEXbits.ENDPOINT = endpoint; // Configure the Endpoint size USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize; // Set up the fifo address. USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress; // Resets the endpoint data toggle to 0 USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1; // Set up the FIFO size USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize; USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0; // Disable NYET Handshakes for interrupt endpoints USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0; // Restore the index register. USB_REGS->INDEXbits.ENDPOINT = old_index; // Enable the endpoint interrupt. USB_REGS->INTRRXEbits.w |= (1 << endpoint); } static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType) { uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; // Select endpoint register set (same register address is used for all endpoints. USB_REGS->INDEXbits.ENDPOINT = endpoint; // Configure the Endpoint size USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize; // Set up the fifo address USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress; // Resets the endpoint data toggle to 0 USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1; // Set up the FIFO size USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize; USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0; // Restore the index register USB_REGS->INDEXbits.ENDPOINT = old_index; // Enable the interrupt USB_REGS->INTRTXEbits.w |= (1 << endpoint); } static void tx_fifo_write(uint8_t endpoint, uint8_t const * buffer, size_t count) { size_t i; volatile uint8_t * fifo_reg; fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[endpoint]); for (i = 0; i < count; i++) { *fifo_reg = buffer[i]; } } static int rx_fifo_read(uint8_t epnum, uint8_t * buffer) { uint32_t i; uint32_t count; volatile uint8_t * fifo_reg; fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[epnum]); count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT; for (i = 0; i < count; i++) { buffer[i] = fifo_reg[i & 3]; } return count; } static void xfer_complete(xfer_ctl_t * xfer, uint8_t result, bool in_isr) { dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, result, in_isr); } static void ep0_fill_tx(xfer_ctl_t * xfer_in) { uint16_t left = xfer_in->total_len - xfer_in->transferred; if (left) { xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); tx_fifo_write(0, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); xfer_in->transferred += xfer_in->last_packet_size; left = xfer_in->total_len - xfer_in->transferred; } if (xfer_in->last_packet_size < xfer_in->max_packet_size || left == 0) { switch (ep0_get_stage()) { case EP0_STAGE_SETUP_IN_DATA: case EP0_STAGE_DATA_IN: case EP0_STAGE_DATA_IN_SENT: ep0_set_stage(EP0_STAGE_DATA_IN_LAST_PACKET_FILLED); USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; break; case EP0_STAGE_SETUP_OUT_NO_DATA: ep0_set_stage(EP0_STAGE_STATUS_IN); USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); break; case EP0_STAGE_DATA_OUT_COMPLETE: ep0_set_stage(EP0_STAGE_STATUS_IN); USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND); break; default: break; } } else { switch (ep0_get_stage()) { case EP0_STAGE_SETUP_IN_DATA: ep0_set_stage(EP0_STAGE_DATA_IN); // fall through case EP0_STAGE_DATA_IN: USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1; break; default: break; } } } static void epn_fill_tx(xfer_ctl_t * xfer_in, uint8_t epnum) { uint16_t left = xfer_in->total_len - xfer_in->transferred; if (left) { xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left); tx_fifo_write(epnum, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size); } USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1; } static bool ep0_xfer(xfer_ctl_t * xfer, int dir) { if (dir == TUSB_DIR_OUT) { if (xfer->total_len) { switch (_dcd.ep0_stage) { case EP0_STAGE_DATA_OUT_COMPLETE: case EP0_STAGE_SETUP_OUT_DATA: ep0_set_stage(EP0_STAGE_DATA_OUT); USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; break; default: TU_ASSERT(0); } } else { switch (_dcd.ep0_stage) { case EP0_STAGE_DATA_IN_SENT: ep0_set_stage(EP0_STAGE_NONE); // fall through case EP0_STAGE_NONE: xfer_complete(xfer, XFER_RESULT_SUCCESS, true); break; default: break; } } } else // IN { ep0_fill_tx(xfer); } return true; } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void) rhport; uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); TU_ASSERT(epnum < EP_MAX); xfer->max_packet_size = tu_edpt_packet_size(desc_edpt); xfer->fifo_size = xfer->max_packet_size; xfer->ep_addr = desc_edpt->bEndpointAddress; if (epnum != 0) { if (dir == TUSB_DIR_OUT) { epn_rx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; } else { epn_tx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer); _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3; } } return true; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // Reserve EP0 FIFO address _dcd.fifo_addr_top = 64 >> 3; for (int i = 1; i < EP_MAX; ++i) { tu_memclr(&_dcd.xfer_status[i], sizeof(_dcd.xfer_status[i])); } } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); (void) rhport; xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->last_packet_size = 0; xfer->transferred = 0; if (epnum == 0) { return ep0_xfer(xfer, dir); } if (dir == TUSB_DIR_OUT) { USB_REGS->INTRRXEbits.w |= (1u << epnum); } else // IN { epn_fill_tx(xfer, epnum); } return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); (void) rhport; if (epnum == 0) { USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1; } else { if (dir == TUSB_DIR_OUT) { USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1; } else { USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1; } } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); (void) rhport; if (epnum == 0) { USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0; } else { if (dir == TUSB_DIR_OUT) { USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL); USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1; } else { USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL); USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1; } } } /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ static void ep0_handle_rx(void) { int transferred; xfer_ctl_t * xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); TU_ASSERT(xfer->buffer,); transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred); xfer->transferred += transferred; TU_ASSERT(xfer->transferred <= xfer->total_len,); if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) { ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE); xfer_complete(xfer, XFER_RESULT_SUCCESS, true); } else { USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; } } static void epn_handle_rx_int(uint8_t epnum) { uint8_t ep_status; int transferred; xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w; if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL) { USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL; } if (ep_status & USBHS_EP0_HOST_RXPKTRDY) { TU_ASSERT(xfer->buffer != NULL,); transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred); USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0; xfer->transferred += transferred; TU_ASSERT(xfer->transferred <= xfer->total_len,); if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len) { USB_REGS->INTRRXEbits.w &= ~(1u << epnum); xfer_complete(xfer, XFER_RESULT_SUCCESS, true); } } } static void epn_handle_tx_int(uint8_t epnum) { uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w; xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL) { USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL; } else { xfer->transferred += xfer->last_packet_size; TU_ASSERT(xfer->transferred <= xfer->total_len,); if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len) { xfer->last_packet_size = 0; xfer_complete(xfer, XFER_RESULT_SUCCESS, true); } else { epn_fill_tx(xfer, epnum); } } } static void ep0_handle_int(void) { __USBHS_CSR0L_DEVICE_t ep0_status; union { tusb_control_request_t request; uint32_t setup_buffer[2]; } setup_packet; xfer_ctl_t * xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT; // Select EP0 registers USB_REGS->INDEXbits.ENDPOINT = 0; ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits; if (ep0_status.SENTSTALL) { // Stall was sent. Reset the endpoint 0 state. // Clear the sent stall bit. ep0_set_stage(EP0_STAGE_NONE); USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0; } if (ep0_status.SETUPEND) { // This means the current control transfer end prematurely. We don't // need to end any transfers. The device layer will manage the // premature transfer end. We clear the SetupEnd bit and reset the // driver control transfer state machine to waiting for next setup // packet from host. USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1; ep0_set_stage(EP0_STAGE_NONE); } if (ep0_status.RXPKTRDY) { switch (ep0_get_stage()) { default: // Data arrived at unexpected state, this must be setup stage packet after all. // Fall through case EP0_STAGE_NONE: // This means we were expecting a SETUP packet and we got one. setup_packet.setup_buffer[0] = USB_REGS->FIFO[0]; setup_packet.setup_buffer[1] = USB_REGS->FIFO[0]; if (setup_packet.request.bmRequestType_bit.direction == TUSB_DIR_OUT) { // SVCRPR is not set yet, it will be set later when out xfer is started // Till then NAKs will hold incommint data ep0_set_stage(setup_packet.request.wLength == 0 ? EP0_STAGE_SETUP_OUT_NO_DATA : EP0_STAGE_SETUP_OUT_DATA); } else { USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1; ep0_set_stage(EP0_STAGE_SETUP_IN_DATA); } dcd_event_setup_received(0, &setup_packet.request.bmRequestType, true); break; case EP0_STAGE_DATA_OUT: ep0_handle_rx(); break; } } else { switch (ep0_get_stage()) { case EP0_STAGE_STATUS_IN: // Status was just sent, this concludes request, notify client ep0_set_stage(EP0_STAGE_NONE); xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); break; case EP0_STAGE_DATA_IN: // Packet sent, fill more data ep0_fill_tx(xfer_in); break; case EP0_STAGE_DATA_IN_LAST_PACKET_FILLED: ep0_set_stage(EP0_STAGE_DATA_IN_SENT); xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true); break; case EP0_STAGE_ADDRESS_CHANGE: // Status stage after set address request finished, address can be changed USB_REGS->FADDRbits.FUNC = _dcd.dev_addr; ep0_set_stage(EP0_STAGE_NONE); break; default: break; } } // Restore register index USB_REGS->INDEXbits.ENDPOINT = old_index; } void dcd_int_handler(uint8_t rhport) { int i; uint8_t mask; __USBCSR2bits_t csr2_bits; uint16_t rxints = USB_REGS->INTRRX & USB_REGS->INTRRXEbits.w; uint16_t txints = USB_REGS->INTRTX; csr2_bits = USBCSR2bits; (void) rhport; IFS4CLR = _IFS4_USBIF_MASK; if (csr2_bits.SOFIF && csr2_bits.SOFIE) { dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } if (csr2_bits.RESETIF) { dcd_edpt_open(0, &ep0OUT_desc); dcd_edpt_open(0, &ep0IN_desc); dcd_event_bus_reset(0, USB_REGS->POWERbits.HSMODE ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } if (csr2_bits.SUSPIF) { dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (csr2_bits.RESUMEIF) { dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } // INTRTX has bit for EP0 if (txints & 1) { txints ^= 1; ep0_handle_int(); } for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i) { if (rxints & mask) { rxints ^= mask; epn_handle_rx_int(i); } } for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i) { if (txints & mask) { txints ^= mask; epn_handle_tx_int(i); } } } #endif ================================================ FILE: src/portable/microchip/pic32mz/usbhs_registers.h ================================================ /******************************************************************************* * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries. * * Subject to your compliance with these terms, you may use Microchip software * and any derivatives exclusively with Microchip products. It is your * responsibility to comply with third party license terms applicable to your * use of third party software (including open source software) that may * accompany Microchip software. * * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A * PARTICULAR PURPOSE. * * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. *******************************************************************************/ /******************************************************************************* USBHS Peripheral Library Register Definitions File Name: usbhs_registers.h Summary: USBHS PLIB Register Definitions Description: This file contains the constants and definitions which are required by the the USBHS library. *******************************************************************************/ #ifndef __USBHS_REGISTERS_H__ #define __USBHS_REGISTERS_H__ #include #include /***************************************** * Module Register Offsets. *****************************************/ #define USBHS_REG_FADDR 0x000 #define USBHS_REG_POWER 0x001 #define USBHS_REG_INTRTX 0x002 #define USBHS_REG_INTRRX 0x004 #define USBHS_REG_INTRTXE 0x006 #define USBHS_REG_INTRRXE 0x008 #define USBHS_REG_INTRUSB 0x00A #define USBHS_REG_INTRUSBE 0x00B #define USBHS_REG_FRAME 0x00C #define USBHS_REG_INDEX 0x00E #define USBHS_REG_TESTMODE 0x00F /******************************************************* * Endpoint Control Status Registers (CSR). These values * should be added to either the 0x10 to access the * register through Indexed CSR. To access the actual * CSR, see ahead in this header file. ******************************************************/ #define USBHS_REG_EP_TXMAXP 0x000 #define USBHS_REG_EP_CSR0L 0x002 #define USBHS_REG_EP_CSR0H 0x003 #define USBHS_REG_EP_TXCSRL 0x002 #define USBHS_REG_EP_TXCSRH 0x003 #define USBHS_REG_EP_RXMAXP 0x004 #define USBHS_REG_EP_RXCSRL 0x006 #define USBHS_REG_EP_RXCSRH 0x007 #define USBHS_REG_EP_COUNT0 0x008 #define USBHS_REG_EP_RXCOUNT 0x008 #define USBHS_REG_EP_TYPE0 0x01A #define USBHS_REG_EP_TXTYPE 0x01A #define USBHS_REG_EP_NAKLIMIT0 0x01B #define USBHS_REG_EP_TXINTERVAL 0x01B #define USBHS_REG_EP_RXTYPE 0x01C #define USBHS_REG_EP_RXINTERVAL 0x01D #define USBHS_REG_EP_CONFIGDATA 0x01F #define USBHS_REG_EP_FIFOSIZE 0x01F #define USBHS_HOST_EP0_SETUPKT_SET 0x8 #define USBHS_HOST_EP0_TXPKTRDY_SET 0x2 #define USBHS_SOFT_RST_NRST_SET 0x1 #define USBHS_SOFT_RST_NRSTX_SET 0x2 #define USBHS_EP0_DEVICE_SERVICED_RXPKTRDY 0x40 #define USBHS_EP0_DEVICE_DATAEND 0x08 #define USBHS_EP0_DEVICE_TXPKTRDY 0x02 #define USBHS_EP0_HOST_STATUS_STAGE_START 0x40 #define USBHS_EP0_HOST_REQPKT 0x20 #define USBHS_EP0_HOST_TXPKTRDY 0x02 #define USBHS_EP0_HOST_RXPKTRDY 0x01 #define USBHS_EP_DEVICE_TX_SENT_STALL 0x20 #define USBHS_EP_DEVICE_TX_SEND_STALL 0x10 #define USBHS_EP_DEVICE_RX_SENT_STALL 0x40 #define USBHS_EP_DEVICE_RX_SEND_STALL 0x20 /* FADDR - Device Function Address */ typedef union { struct __attribute__((packed)) { unsigned FUNC:7; unsigned :1; }; uint8_t w; } __USBHS_FADDR_t; /* POWER - Control Resume and Suspend signalling */ typedef union { struct __attribute__((packed)) { unsigned SUSPEN:1; unsigned SUSPMODE:1; unsigned RESUME:1; unsigned RESET:1; unsigned HSMODE:1; unsigned HSEN:1; unsigned SOFTCONN:1; unsigned ISOUPD:1; }; struct { uint8_t w; }; } __USBHS_POWER_t; /* INTRTXE - Transmit endpoint interrupt enable */ typedef union { struct __attribute__((packed)) { unsigned EP0IE:1; unsigned EP1TXIE:1; unsigned EP2TXIE:1; unsigned EP3TXIE:1; unsigned EP4TXIE:1; unsigned EP5TXIE:1; unsigned EP6TXIE:1; unsigned EP7TXIE:1; unsigned :8; }; struct { uint16_t w; }; } __USBHS_INTRTXE_t; /* INTRRXE - Receive endpoint interrupt enable */ typedef union { struct __attribute__((packed)) { unsigned :1; unsigned EP1RXIE:1; unsigned EP2RXIE:1; unsigned EP3RXIE:1; unsigned EP4RXIE:1; unsigned EP5RXIE:1; unsigned EP6RXIE:1; unsigned EP7RXIE:1; unsigned :8; }; struct { uint16_t w; }; } __USBHS_INTRRXE_t; /* INTRUSBE - General USB Interrupt enable */ typedef union { struct __attribute__((packed)) { unsigned SUSPIE:1; unsigned RESUMEIE:1; unsigned RESETIE:1; unsigned SOFIE:1; unsigned CONNIE:1; unsigned DISCONIE:1; unsigned SESSRQIE:1; unsigned VBUSERRIE:1; }; struct { uint8_t w; }; } __USBHS_INTRUSBE_t; /* FRAME - Frame number */ typedef union { struct __attribute__((packed)) { unsigned RFRMNUM:11; unsigned :5; }; struct { uint16_t w; }; } __USBHS_FRAME_t; /* INDEX - Endpoint index */ typedef union { struct __attribute__((packed)) { unsigned ENDPOINT:4; unsigned :4; }; struct { uint8_t w; }; } __USBHS_INDEX_t; /* TESTMODE - Test mode register */ typedef union { struct __attribute__((packed)) { unsigned NAK:1; unsigned TESTJ:1; unsigned TESTK:1; unsigned PACKET:1; unsigned FORCEHS:1; unsigned FORCEFS:1; unsigned FIFOACC:1; unsigned FORCEHST:1; }; struct { uint8_t w; }; } __USBHS_TESTMODE_t; /* COUNT0 - Indicates the amount of data received in endpoint 0 */ typedef union { struct __attribute__((packed)) { unsigned RXCNT:7; unsigned :1; }; struct { uint8_t w; }; } __USBHS_COUNT0_t; /* TYPE0 - Operating speed of target device */ typedef union { struct __attribute__((packed)) { unsigned :6; unsigned SPEED:2; }; struct { uint8_t w; }; } __USBHS_TYPE0_t; /* DEVCTL - Module control register */ typedef union { struct __attribute__((packed)) { unsigned SESSION:1; unsigned HOSTREQ:1; unsigned HOSTMODE:1; unsigned VBUS:2; unsigned LSDEV:1; unsigned FSDEV:1; unsigned BDEV:1; }; struct { uint8_t w; }; } __USBHS_DEVCTL_t; /* CSR0L Device - Endpoint Device Mode Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned RXPKTRDY:1; unsigned TXPKTRDY:1; unsigned SENTSTALL:1; unsigned DATAEND:1; unsigned SETUPEND:1; unsigned SENDSTALL:1; unsigned SVCRPR:1; unsigned SVSSETEND:1; }; struct { uint8_t w; }; } __USBHS_CSR0L_DEVICE_t; /* CSR0L Host - Endpoint Host Mode Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned RXPKTRDY:1; unsigned TXPKTRDY:1; unsigned RXSTALL:1; unsigned SETUPPKT:1; unsigned ERROR:1; unsigned REQPKT:1; unsigned STATPKT:1; unsigned NAKTMOUT:1; }; struct { uint8_t w; }; } __USBHS_CSR0L_HOST_t; /* TXCSRL Device - Endpoint Transmit Control Status Register Low */ typedef union { struct __attribute__((packed)) { unsigned TXPKTRDY:1; unsigned FIFOONE:1; unsigned UNDERRUN:1; unsigned FLUSH:1; unsigned SENDSTALL:1; unsigned SENTSTALL:1; unsigned CLRDT:1; unsigned INCOMPTX:1; }; struct { uint8_t w; }; } __USBHS_TXCSRL_DEVICE_t; /* TXCSRL Host - Endpoint Transmit Control Status Register Low */ typedef union { struct __attribute__((packed)) { unsigned TXPKTRDY:1; unsigned FIFONE:1; unsigned ERROR:1; unsigned FLUSH:1; unsigned SETUPPKT:1; unsigned RXSTALL:1; unsigned CLRDT:1; unsigned INCOMPTX:1; }; struct { uint8_t w; }; } __USBHS_TXCSRL_HOST_t; /* TXCSRH Device - Endpoint Transmit Control Status Register High */ typedef union { struct __attribute__((packed)) { unsigned :2; unsigned DMAREQMD:1; unsigned FRCDATTG:1; unsigned DMAREQENL:1; unsigned MODE:1; unsigned ISO:1; unsigned AUTOSET:1; }; struct { uint8_t w; }; } __USBHS_TXCSRH_DEVICE_t; /* TXCSRH Host - Endpoint Transmit Control Status Register High */ typedef union { struct __attribute__((packed)) { unsigned DATATGGL:1; unsigned DTWREN:1; unsigned DMAREQMD:1; unsigned FRCDATTG:1; unsigned DMAREQEN:1; unsigned MODE:1; unsigned :1; unsigned AUOTSET:1; }; struct { uint8_t w; }; } __USBHS_TXCSRH_HOST_t; /* CSR0H Device - Endpoint 0 Control Status Register High */ typedef union { struct __attribute__((packed)) { unsigned FLSHFIFO:1; unsigned :7; }; struct { uint8_t w; }; } __USBHS_CSR0H_DEVICE_t; /* CSR0H Host - Endpoint 0 Control Status Register High */ typedef union { struct __attribute__((packed)) { unsigned FLSHFIFO:1; unsigned DATATGGL:1; unsigned DTWREN:1; unsigned DISPING:1; unsigned :4; }; struct { uint8_t w; }; } __USBHS_CSR0H_HOST_t; /* RXMAXP - Receive Endpoint Max packet size. */ typedef union { struct __attribute__((packed)) { unsigned RXMAXP:11; unsigned MULT:5; }; struct { uint16_t w; }; } __USBHS_RXMAXP_t; /* RXCSRL Device - Receive endpoint Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned RXPKTRDY:1; unsigned FIFOFULL:1; unsigned OVERRUN:1; unsigned DATAERR:1; unsigned FLUSH:1; unsigned SENDSTALL:1; unsigned SENTSTALL:1; unsigned CLRDT:1; }; struct { uint8_t w; }; } __USBHS_RXCSRL_DEVICE_t; /* RXCSRL Host - Receive endpoint Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned RXPKTRDY:1; unsigned FIFOFULL:1; unsigned ERROR:1; unsigned DERRNAKT:1; unsigned FLUSH:1; unsigned REQPKT:1; unsigned RXSTALL:1; unsigned CLRDT:1; }; struct { uint8_t w; }; } __USBHS_RXCSRL_HOST_t; /* RXCSRH Device - Receive endpoint Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned INCOMPRX:1; unsigned :2; unsigned DMAREQMODE:1; unsigned DISNYET:1; unsigned DMAREQEN:1; unsigned ISO:1; unsigned AUTOCLR:1; }; struct { uint8_t w; }; } __USBHS_RXCSRH_DEVICE_t; /* RXCSRH Host - Receive endpoint Control Status Register */ typedef union { struct __attribute__((packed)) { unsigned INCOMPRX:1; unsigned DATATGGL:1; unsigned DATATWEN:1; unsigned DMAREQMD:1; unsigned PIDERR:1; unsigned DMAREQEN:1; unsigned AUTORQ:1; unsigned AUOTCLR:1; }; struct { uint8_t w; }; } __USBHS_RXCSRH_HOST_t; /* RXCOUNT - Amount of data pending in RX FIFO */ typedef union { struct __attribute__((packed)) { unsigned RXCNT:14; unsigned :2; }; struct { uint16_t w; }; } __USBHS_RXCOUNT_t; /* TXTYPE - Specifies the target transmit endpoint */ typedef union { struct __attribute__((packed)) { unsigned TEP:4; unsigned PROTOCOL:2; unsigned SPEED:2; }; struct { uint8_t w; }; } __USBHS_TXTYPE_t; /* RXTYPE - Specifies the target receive endpoint */ typedef union { struct __attribute__((packed)) { unsigned TEP:4; unsigned PROTOCOL:2; unsigned SPEED:2; }; struct { uint8_t w; }; } __USBHS_RXTYPE_t; /* TXINTERVAL - Defines the polling interval */ typedef struct { uint8_t TXINTERV; } __USBHS_TXINTERVAL_t; /* RXINTERVAL - Defines the polling interval */ typedef struct { uint8_t RXINTERV; } __USBHS_RXINTERVAL_t; /* TXMAXP - Maximum amount of data that can be transferred through a TX endpoint * */ typedef union { struct __attribute__((packed)) { unsigned TXMAXP:11; unsigned MULT:5; }; uint16_t w; } __USBHS_TXMAXP_t; /* TXFIFOSZ - Size of the transmit endpoint FIFO */ typedef struct __attribute__((packed)) { unsigned TXFIFOSZ:4; unsigned TXDPB:1; unsigned :3; } __USBHS_TXFIFOSZ_t; /* RXFIFOSZ - Size of the receive endpoint FIFO */ typedef struct __attribute__((packed)) { unsigned RXFIFOSZ:4; unsigned RXDPB:1; unsigned :3; } __USBHS_RXFIFOSZ_t; /* TXFIFOADD - Start address of the transmit endpoint FIFO */ typedef union { struct __attribute__((packed)) { unsigned TXFIFOAD:13; unsigned :3; }; uint16_t w; } __USBHS_TXFIFOADD_t; /* RXFIFOADD - Start address of the receive endpoint FIFO */ typedef union { struct __attribute__((packed)) { unsigned RXFIFOAD:13; unsigned :3; }; uint16_t w; } __USBHS_RXFIFOADD_t; /* SOFTRST - Asserts NRSTO and NRSTOX */ typedef union { struct __attribute__((packed)) { unsigned NRST:1; unsigned NRSTX:1; unsigned :6; }; uint8_t w; } __USBHS_SOFTRST_t; /* TXFUNCADDR - Target address of transmit endpoint */ typedef union { struct __attribute__((packed)) { unsigned TXFADDR:7; unsigned :1; }; uint8_t w; } __USBHS_TXFUNCADDR_t; /* RXFUNCADDR - Target address of receive endpoint */ typedef union { struct __attribute__((packed)) { unsigned RXFADDR:7; unsigned :1; }; uint8_t w; } __USBHS_RXFUNCADDR_t; /* TXHUBADDR - Address of the hub to which the target transmit device endpoint * is connected */ typedef union { struct __attribute__((packed)) { unsigned TXHUBADDR:7; unsigned MULTTRAN:1; }; uint8_t w; } __USBHS_TXHUBADDR_t; /* RXHUBADDR - Address of the hub to which the target receive device endpoint is * connected */ typedef union { struct __attribute__((packed)) { unsigned RXHUBADDR:7; unsigned MULTTRAN:1; }; uint8_t w; } __USBHS_RXHUBADDR_t; /* TXHUBPORT - Address of the hub to which the target transmit device endpoint * is connected. */ typedef union { struct __attribute__((packed)) { unsigned TXHUBPRT:7; unsigned :1; }; uint8_t w; } __USBHS_TXHUBPORT_t; /* RXHUBPORT - Address of the hub to which the target receive device endpoint * is connected. */ typedef union { struct __attribute__((packed)) { unsigned RXHUBPRT:7; unsigned :1; }; uint8_t w; } __USBHS_RXHUBPORT_t; /* DMACONTROL - Configures a DMA channel */ typedef union { struct __attribute__((packed)) { unsigned DMAEN:1; unsigned DMADIR:1; unsigned DMAMODE:1; unsigned DMAIE:1; unsigned DMAEP:4; unsigned DMAERR:1; unsigned DMABRSTM:2; unsigned:21; }; uint32_t w; } __USBHS_DMACNTL_t; /* Endpoint Control and Status Register Set */ typedef struct __attribute__((packed)) { volatile __USBHS_TXMAXP_t TXMAXPbits; union { struct { union { volatile __USBHS_CSR0L_DEVICE_t CSR0L_DEVICEbits; volatile __USBHS_CSR0L_HOST_t CSR0L_HOSTbits; }; union { volatile __USBHS_CSR0H_DEVICE_t CSR0H_DEVICEbits; volatile __USBHS_CSR0H_HOST_t CSR0H_HOSTbits; }; }; struct { union { volatile __USBHS_TXCSRL_DEVICE_t TXCSRL_DEVICEbits; volatile __USBHS_TXCSRL_HOST_t TXCSRL_HOSTbits; }; union { volatile __USBHS_TXCSRH_DEVICE_t TXCSRH_DEVICEbits; volatile __USBHS_TXCSRH_HOST_t TXCSRH_HOSTbits; }; }; }; volatile __USBHS_RXMAXP_t RXMAXPbits; union { volatile __USBHS_RXCSRL_DEVICE_t RXCSRL_DEVICEbits; volatile __USBHS_RXCSRL_HOST_t RXCSRL_HOSTbits; }; union { volatile __USBHS_RXCSRH_DEVICE_t RXCSRH_DEVICEbits; volatile __USBHS_RXCSRH_HOST_t RXCSRH_HOSTbits; }; union { volatile __USBHS_COUNT0_t COUNT0bits; volatile __USBHS_RXCOUNT_t RXCOUNTbits; }; union { volatile __USBHS_TYPE0_t TYPE0bits; volatile __USBHS_TXTYPE_t TXTYPEbits; }; union { volatile uint8_t NAKLIMIT0; volatile __USBHS_TXINTERVAL_t TXINTERVALbits; }; volatile __USBHS_RXTYPE_t RXTYPEbits; volatile __USBHS_RXINTERVAL_t RXINTERVALbits; unsigned :8; union { volatile uint8_t CONFIGDATA; volatile uint8_t FIFOSIZE; }; } __USBHS_EPCSR_t; /* Set of registers that configure the multi-point option */ typedef struct __attribute__((packed)) { volatile __USBHS_TXFUNCADDR_t TXFUNCADDRbits; unsigned :8; volatile __USBHS_TXHUBADDR_t TXHUBADDRbits; volatile __USBHS_TXHUBPORT_t TXHUBPORTbits; volatile __USBHS_RXFUNCADDR_t RXFUNCADDRbits; unsigned :8; volatile __USBHS_RXHUBADDR_t RXHUBADDRbits; volatile __USBHS_RXHUBPORT_t RXHUBPORTbits; } __USBHS_TARGET_ADDR_t; /* Set of registers that configure the DMA channel */ typedef struct __attribute__((packed)) { volatile __USBHS_DMACNTL_t DMACNTLbits; volatile uint32_t DMAADDR; volatile uint32_t DMACOUNT; volatile uint32_t pad; } __USBHS_DMA_CHANNEL_t; /* USBHS module register set */ typedef struct __attribute__((aligned(4),packed)) { volatile __USBHS_FADDR_t FADDRbits; volatile __USBHS_POWER_t POWERbits; volatile uint16_t INTRTX; volatile uint16_t INTRRX; volatile __USBHS_INTRTXE_t INTRTXEbits; volatile __USBHS_INTRRXE_t INTRRXEbits; volatile uint8_t INTRUSB; volatile __USBHS_INTRUSBE_t INTRUSBEbits; volatile __USBHS_FRAME_t FRAMEbits; volatile __USBHS_INDEX_t INDEXbits; volatile __USBHS_TESTMODE_t TESTMODEbits; volatile __USBHS_EPCSR_t INDEXED_EPCSR; volatile uint32_t FIFO[16]; volatile __USBHS_DEVCTL_t DEVCTLbits; volatile uint8_t MISC; volatile __USBHS_TXFIFOSZ_t TXFIFOSZbits; volatile __USBHS_RXFIFOSZ_t RXFIFOSZbits; volatile __USBHS_TXFIFOADD_t TXFIFOADDbits; volatile __USBHS_RXFIFOADD_t RXFIFOADDbits; volatile uint32_t VCONTROL; volatile uint16_t HWVERS; volatile uint8_t padding1[10]; volatile uint8_t EPINFO; volatile uint8_t RAMINFO; volatile uint8_t LINKINFO; volatile uint8_t VPLEN; volatile uint8_t HS_EOF1; volatile uint8_t FS_EOF1; volatile uint8_t LS_EOF1; volatile __USBHS_SOFTRST_t SOFTRSTbits; volatile __USBHS_TARGET_ADDR_t TADDR[16]; volatile __USBHS_EPCSR_t EPCSR[16]; volatile uint32_t DMA_INTR; volatile __USBHS_DMA_CHANNEL_t DMA_CHANNEL[8]; volatile uint32_t RQPKTXOUNT[16]; } usbhs_registers_t; #endif ================================================ FILE: src/portable/microchip/samd/dcd_samd.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAMD21, OPT_MCU_SAML2X, OPT_MCU_SAMD51, OPT_MCU_SAME5X) #include "sam.h" #include "device/dcd.h" /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ static TU_ATTR_ALIGNED(4) UsbDeviceDescBank sram_registers[8][2]; // Setup packet is only 8 bytes in length. However under certain scenario, // USB DMA controller may decide to overwrite/overflow the buffer with // 2 extra bytes of CRC. From datasheet's "Management of SETUP Transactions" section // If the number of received data bytes is the maximum data payload specified by // PCKSIZE.SIZE minus one, only the first CRC data is written to the data buffer. // If the number of received data is equal or less than the data payload specified // by PCKSIZE.SIZE minus two, both CRC data bytes are written to the data buffer. // Therefore we will need to increase it to 10 bytes here. static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8+2]; // ready for receiving SETUP packet static inline void prepare_setup(void) { // Only make sure the EP0 OUT buffer is ready sram_registers[0][0].ADDR.reg = (uint32_t) _setup_packet; sram_registers[0][0].PCKSIZE.bit.MULTI_PACKET_SIZE = sizeof(tusb_control_request_t); sram_registers[0][0].PCKSIZE.bit.BYTE_COUNT = 0; } // Setup the control endpoint 0. static void bus_reset(void) { // Max size of packets is 64 bytes. UsbDeviceDescBank* bank_out = &sram_registers[0][TUSB_DIR_OUT]; bank_out->PCKSIZE.bit.SIZE = 0x3; UsbDeviceDescBank* bank_in = &sram_registers[0][TUSB_DIR_IN]; bank_in->PCKSIZE.bit.SIZE = 0x3; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[0]; ep->EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0x1) | USB_DEVICE_EPCFG_EPTYPE1(0x1); ep->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP; // Prepare for setup packet prepare_setup(); } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; // Reset to get in a clean state. USB->DEVICE.CTRLA.bit.SWRST = true; while (USB->DEVICE.SYNCBUSY.bit.SWRST == 0) {} while (USB->DEVICE.SYNCBUSY.bit.SWRST == 1) {} USB->DEVICE.PADCAL.bit.TRANSP = (*((uint32_t*) USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; USB->DEVICE.PADCAL.bit.TRANSN = (*((uint32_t*) USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; USB->DEVICE.PADCAL.bit.TRIM = (*((uint32_t*) USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; USB->DEVICE.QOSCTRL.bit.CQOS = 3; // High Quality USB->DEVICE.QOSCTRL.bit.DQOS = 3; // High Quality // Configure registers USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE | USB_CTRLA_RUNSTDBY; while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1) {} USB->DEVICE.INTFLAG.reg |= USB->DEVICE.INTFLAG.reg; // clear pending USB->DEVICE.INTENSET.reg = /* USB_DEVICE_INTENSET_SOF | */ USB_DEVICE_INTENSET_EORST; return true; } #if TU_CHECK_MCU(OPT_MCU_SAMD51, OPT_MCU_SAME5X) void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB_0_IRQn); NVIC_EnableIRQ(USB_1_IRQn); NVIC_EnableIRQ(USB_2_IRQn); NVIC_EnableIRQ(USB_3_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB_3_IRQn); NVIC_DisableIRQ(USB_2_IRQn); NVIC_DisableIRQ(USB_1_IRQn); NVIC_DisableIRQ(USB_0_IRQn); } #elif TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAMD21, OPT_MCU_SAML2X) void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB_IRQn); } #else #error "No implementation available for dcd_int_enable / dcd_int_disable" #endif void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) dev_addr; // Response with zlp status dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); // DCD can only set address after status for this request is complete // do it at dcd_edpt0_status_complete() // Enable SUSPEND interrupt since the bus signal D+/D- are stable now. USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTENCLR_SUSPEND; // clear pending USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SUSPEND; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; USB->DEVICE.CTRLB.bit.UPRSM = 1; } // disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void) rhport; USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH; } // connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void) rhport; USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; if (en) { USB->DEVICE.INTENSET.bit.SOF = 1; } else { USB->DEVICE.INTENCLR.bit.SOF = 1; } } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS ) { uint8_t const dev_addr = (uint8_t) request->wValue; USB->DEVICE.DADD.reg = USB_DEVICE_DADD_DADD(dev_addr) | USB_DEVICE_DADD_ADDEN; } // Just finished status stage, prepare for next setup packet // Note: we may already prepare setup when queueing the control status. // but it has no harm to do it again here prepare_setup(); } bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void) rhport; uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; uint32_t size_value = 0; while (size_value < 7) { if (1 << (size_value + 3) >= tu_edpt_packet_size(desc_edpt)) { break; } size_value++; } // unsupported endpoint size if ( size_value == 7 && tu_edpt_packet_size(desc_edpt) > 1023 ) return false; bank->PCKSIZE.bit.SIZE = size_value; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; if ( dir == TUSB_DIR_OUT ) { ep->EPCFG.bit.EPTYPE0 = desc_edpt->bmAttributes.xfer + 1; ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT; // clear stall & dtoggle ep->EPINTENSET.bit.TRCPT0 = true; }else { ep->EPCFG.bit.EPTYPE1 = desc_edpt->bmAttributes.xfer + 1; ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN; // clear stall & dtoggle ep->EPINTENSET.bit.TRCPT1 = true; } return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; bank->ADDR.reg = (uint32_t) buffer; // A SETUP token can occur immediately after an ZLP Status. // So make sure we have a valid buffer for setup packet. // Status = ZLP EP0 with direction opposite to one in the dir bit of current setup if ( (epnum == 0) && (buffer == NULL) && (total_bytes == 0) && (dir != tu_edpt_dir(_setup_packet[0])) ) { prepare_setup(); } if ( dir == TUSB_DIR_OUT ) { bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes; bank->PCKSIZE.bit.BYTE_COUNT = 0; ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL0; } else { bank->PCKSIZE.bit.MULTI_PACKET_SIZE = 0; bank->PCKSIZE.bit.BYTE_COUNT = total_bytes; ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL1; } return true; } void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; } else { ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; } } void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN; } else { ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT; } } //--------------------------------------------------------------------+ // Interrupt Handler //--------------------------------------------------------------------+ static void maybe_transfer_complete(void) { uint32_t epints = USB->DEVICE.EPINTSMRY.reg; for (uint8_t epnum = 0; epnum < USB_EPT_NUM; epnum++) { if ((epints & (1 << epnum)) == 0) { continue; } UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; uint32_t epintflag = ep->EPINTFLAG.reg; // Handle IN completions if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT1) != 0) { UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_IN]; uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, total_transfer_size, XFER_RESULT_SUCCESS, true); ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; } // Handle OUT completions if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT0) != 0) { UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_OUT]; uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; dcd_event_xfer_complete(0, epnum, total_transfer_size, XFER_RESULT_SUCCESS, true); ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; } } } void dcd_int_handler (uint8_t rhport) { (void) rhport; uint32_t int_status = USB->DEVICE.INTFLAG.reg & USB->DEVICE.INTENSET.reg; // Start of Frame if ( int_status & USB_DEVICE_INTFLAG_SOF ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; const uint32_t frame = USB->DEVICE.FNUM.bit.FNUM; dcd_event_sof(0, frame, true); //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } // SAMD doesn't distinguish between Suspend and Disconnect state. // Both condition will cause SUSPEND interrupt triggered. // To prevent being triggered when D+/D- are not stable, SUSPEND interrupt is only // enabled when we received SET_ADDRESS request and cleared on Bus Reset if ( int_status & USB_DEVICE_INTFLAG_SUSPEND ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SUSPEND; // Enable wakeup interrupt USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_WAKEUP; // clear pending USB->DEVICE.INTENSET.reg = USB_DEVICE_INTFLAG_WAKEUP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } // Wakeup interrupt is only enabled when we got suspended. // Wakeup interrupt will disable itself if ( int_status & USB_DEVICE_INTFLAG_WAKEUP ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_WAKEUP; // disable wakeup interrupt itself USB->DEVICE.INTENCLR.reg = USB_DEVICE_INTFLAG_WAKEUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } // Enable of Reset if ( int_status & USB_DEVICE_INTFLAG_EORST ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; // Disable both suspend and wakeup interrupt USB->DEVICE.INTENCLR.reg = USB_DEVICE_INTFLAG_WAKEUP | USB_DEVICE_INTFLAG_SUSPEND; bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); } // Handle SETUP packet if (USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP) { // This copies the data elsewhere so we can reuse the buffer. dcd_event_setup_received(0, _setup_packet, true); // Although Setup packet only set RXSTP bit, // TRCPT0 bit could already be set by previous ZLP OUT Status (not handled until now). // Since control status complete event is optional, we can just clear TRCPT0 and skip the status event USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP | USB_DEVICE_EPINTFLAG_TRCPT0; } // Handle complete transfer maybe_transfer_complete(); } #endif ================================================ FILE: src/portable/microchip/samd/hcd_samd.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 ChrisDeadman * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) && \ TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAMD21, OPT_MCU_SAML2X, OPT_MCU_SAMD51, OPT_MCU_SAME5X) #include "host/hcd.h" #include "sam.h" /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ #define USB_HOST_PTYPE_DIS 0x0 #define USB_HOST_PTYPE_CTRL 0x1 #define USB_HOST_PTYPE_ISO 0x2 #define USB_HOST_PTYPE_BULK 0x3 #define USB_HOST_PTYPE_INT 0x4 #define USB_HOST_PTYPE_EXT 0x5 #define USB_HOST_PCFG_PTOKEN_SETUP 0x0 #define USB_HOST_PCFG_PTOKEN_IN 0x1 #define USB_HOST_PCFG_PTOKEN_OUT 0x2 #define USB_PCKSIZE_ENUM(size) \ ((size) >= 1024 ? 7 \ : (size) >= 1023 ? 7 \ : (size) > 256 ? 6 \ : (size) > 128 ? 5 \ : (size) > 64 ? 4 \ : (size) > 32 ? 3 \ : (size) > 16 ? 2 \ : (size) > 8 ? 1 \ : 0) // Uncomment to use fake frame number. // Low-Speed devices stall FNUM during enumeration :/ // #define HCD_SAMD_FAKE_FNUM typedef struct { uint8_t dev_addr; uint8_t ep_addr; uint16_t max_packet_size; uint16_t xfer_length; uint16_t xfer_remaining; } usb_pipe_status_t; CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static volatile UsbHostDescriptor usb_pipe_table[USB_PIPE_NUM]; CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static volatile usb_pipe_status_t usb_pipe_status_table[USB_PIPE_NUM]; CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static volatile uint32_t fake_fnum; static uint8_t samd_configure_pipe(uint8_t dev_addr, uint8_t ep_addr) { uint8_t pipe; uint8_t token; volatile usb_pipe_status_t* pipe_status; bool same_addr = false; bool same_ep_addr = false; // evaluate pipe token token = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_HOST_PCFG_PTOKEN_IN : tu_edpt_number(ep_addr) == 0 ? USB_HOST_PCFG_PTOKEN_SETUP : USB_HOST_PCFG_PTOKEN_OUT; TU_LOG3("samd_configure_pipe(token=%02X, dev_addr=%02X, ep_addr=%02X)=", token, dev_addr, ep_addr); // find already allocated pipe for (pipe = 0; pipe < USB_PIPE_NUM; pipe++) { pipe_status = &usb_pipe_status_table[pipe]; same_addr = (pipe_status->dev_addr == dev_addr); same_ep_addr = (tu_edpt_number(pipe_status->ep_addr) == tu_edpt_number(ep_addr)); if (same_ep_addr && (same_addr || (tu_edpt_number(ep_addr) == 0))) { break; } } // allocate from pool of free pipes if (pipe >= USB_PIPE_NUM) { for (pipe = 0; pipe < USB_PIPE_NUM; pipe++) { pipe_status = &usb_pipe_status_table[pipe]; // found a free pipe if (pipe_status->dev_addr >= UINT8_MAX) { break; } } } // no pipe available :( if (pipe >= USB_PIPE_NUM) { TU_LOG3("ERR_NO_PIPE\r\n"); return pipe; } TU_LOG3("%d\r\n", pipe); // no transfer should be in progress TU_ASSERT(((USB->HOST.HostPipe[pipe].PCFG.bit.PTYPE == USB_HOST_PTYPE_DIS) || USB->HOST.HostPipe[pipe].PSTATUS.bit.PFREEZE == 1), USB_PIPE_NUM); // update addr and ep_addr pipe_status->dev_addr = dev_addr; pipe_status->ep_addr = ep_addr; usb_pipe_table[pipe].HostDescBank[0].CTRL_PIPE.bit.PDADDR = dev_addr; usb_pipe_table[pipe].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = tu_edpt_number(ep_addr); // token specific configuration USB->HOST.HostPipe[pipe].PCFG.bit.PTOKEN = token; USB->HOST.HostPipe[pipe].PINTENCLR.reg = USB_HOST_PINTENCLR_MASK; if (token == USB_HOST_PCFG_PTOKEN_SETUP) { USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_DTGL; USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TXSTP; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_STALL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_PERR; } else if (token == USB_HOST_PCFG_PTOKEN_IN) { USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_STALL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_PERR; } else { USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_STALL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL; USB->HOST.HostPipe[pipe].PINTENSET.reg = USB_HOST_PINTENSET_PERR; } return pipe; } static void samd_free_pipe(uint8_t pipe) { volatile usb_pipe_status_t* pipe_status = &usb_pipe_status_table[pipe]; pipe_status->dev_addr = UINT8_MAX; pipe_status->ep_addr = UINT8_MAX; pipe_status->max_packet_size = 0; pipe_status->xfer_length = 0; pipe_status->xfer_remaining = 0; USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; USB->HOST.HostPipe[pipe].PCFG.reg &= ~USB_HOST_PCFG_PTYPE_Msk; USB->HOST.HostPipe[pipe].PINTENCLR.reg = USB_HOST_PINTENCLR_MASK; memset((uint8_t*)(uintptr_t) &usb_pipe_table[pipe], 0, sizeof(usb_pipe_table[pipe])); } static void samd_free_all_pipes(void) { for (uint8_t pipe = 0; pipe < USB_PIPE_NUM; pipe++) { samd_free_pipe(pipe); } } static bool samd_on_xfer(uint8_t pipe, xfer_result_t xfer_result) { uint16_t xfer_delta; bool xfer_complete; volatile usb_pipe_status_t* pipe_status = &usb_pipe_status_table[pipe]; // freeze the pipe USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; // get number of transferred bytes if (xfer_result == XFER_RESULT_SUCCESS) { xfer_delta = usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT; } else { xfer_delta = 0; } TU_LOG3("samd_on_xfer(%d, result=%d, xdelta=%d, rem=%d)\r\n", xfer_result, pipe, xfer_delta, pipe_status->xfer_remaining); // update pipe status if (xfer_delta > pipe_status->xfer_remaining) { xfer_delta = pipe_status->xfer_remaining; } pipe_status->xfer_remaining -= xfer_delta; pipe_status->xfer_length += xfer_delta; // last packet handling if (xfer_delta < pipe_status->max_packet_size) { pipe_status->xfer_remaining = 0; } // transfer complete xfer_complete = (xfer_result != XFER_RESULT_SUCCESS) || (pipe_status->xfer_remaining == 0); if (xfer_complete) { return true; } // continue receiving if (tu_edpt_dir(pipe_status->ep_addr) == TUSB_DIR_IN) { usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; } // continue sending else { usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = (pipe_status->xfer_remaining < pipe_status->max_packet_size) ? pipe_status->xfer_remaining : pipe_status->max_packet_size; USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; } // advance packet buffer usb_pipe_table[pipe].HostDescBank[0].ADDR.reg += xfer_delta; // start next transfer USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; return false; } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; uint16_t int_flags; uint8_t pint_flags; xfer_result_t xfer_result; volatile usb_pipe_status_t* pipe_status; // // Check INTFLAG // int_flags = USB->HOST.INTFLAG.reg; if (int_flags & USB_HOST_INTFLAG_HSOF) { USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_HSOF; } if (int_flags & USB_HOST_INTFLAG_RST) { TU_LOG2("USB_HOST_INTFLAG_RST\r\n"); USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST; } if (int_flags & USB_HOST_INTFLAG_WAKEUP) { TU_LOG3("USB_HOST_INTFLAG_WAKEUP\r\n"); USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_WAKEUP; } if (int_flags & USB_HOST_INTFLAG_DNRSM) { TU_LOG3("USB_HOST_INTFLAG_DNRSM\r\n"); USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DNRSM; } if (int_flags & USB_HOST_INTFLAG_UPRSM) { TU_LOG3("USB_HOST_INTFLAG_UPRSM\r\n"); USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_UPRSM; } if (int_flags & USB_HOST_INTFLAG_RAMACER) { TU_LOG1("USB_HOST_INTFLAG_RAMACER\r\n"); USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RAMACER; } if (int_flags & USB_HOST_INTFLAG_DCONN) { USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DCONN; hcd_event_device_attach(rhport, in_isr); } if (int_flags & USB_HOST_INTFLAG_DDISC) { USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DDISC; hcd_event_device_remove(rhport, in_isr); } // handle pipe interrupts for (uint8_t pipe = 0; pipe < USB_PIPE_NUM; pipe++) { // get pipe handle pipe_status = &usb_pipe_status_table[pipe]; if (pipe_status->dev_addr >= UINT8_MAX) { continue; } // // Check PINTFLAG // pint_flags = USB->HOST.HostPipe[pipe].PINTFLAG.reg; xfer_result = XFER_RESULT_INVALID; if (pint_flags & USB_HOST_PINTFLAG_TRCPT0) { USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT0; xfer_result = XFER_RESULT_SUCCESS; } if (pint_flags & USB_HOST_PINTFLAG_TRCPT1) { USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT1; xfer_result = XFER_RESULT_SUCCESS; } if (pint_flags & USB_HOST_PINTFLAG_TXSTP) { USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TXSTP; xfer_result = XFER_RESULT_SUCCESS; } if (pint_flags & USB_HOST_PINTFLAG_STALL) { TU_LOG2("USB_HOST_PINTFLAG_STALL\r\n"); USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_STALL; xfer_result = XFER_RESULT_STALLED; } if (pint_flags & USB_HOST_PINTFLAG_TRFAIL) { USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRFAIL; if (usb_pipe_table[pipe].HostDescBank[0].STATUS_BK.reg & USB_HOST_STATUS_BK_ERRORFLOW) { TU_LOG1("USB_HOST_STATUS_BK_ERRORFLOW\r\n"); xfer_result = XFER_RESULT_FAILED; } else if (usb_pipe_table[pipe].HostDescBank[0].STATUS_BK.reg & USB_HOST_STATUS_BK_CRCERR) { TU_LOG1("USB_HOST_STATUS_BK_CRCERR\r\n"); xfer_result = XFER_RESULT_FAILED; } else { // SAMD Quirk #1: // Likes to report TRFAIL for no apparent reason -> ignore } } if (pint_flags & USB_HOST_PINTFLAG_PERR) { USB->HOST.HostPipe[pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_PERR; // Handled by STATUS_PIPE checks below } // // Check STATUS_PIPE // if (usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg & USB_HOST_STATUS_PIPE_DTGLER) { TU_LOG1("USB_HOST_STATUS_PIPE_DTGLER\r\n"); usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg &= ~USB_HOST_STATUS_PIPE_DTGLER; xfer_result = XFER_RESULT_FAILED; } if (usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg & USB_HOST_STATUS_PIPE_DAPIDER) { TU_LOG1("USB_HOST_STATUS_PIPE_DAPIDER\r\n"); usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg &= ~USB_HOST_STATUS_PIPE_DAPIDER; xfer_result = XFER_RESULT_FAILED; } if (usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg & USB_HOST_STATUS_PIPE_PIDER) { TU_LOG1("USB_HOST_STATUS_PIPE_PIDER\r\n"); usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg &= ~USB_HOST_STATUS_PIPE_PIDER; xfer_result = XFER_RESULT_FAILED; } if (usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg & USB_HOST_STATUS_PIPE_CRC16ER) { TU_LOG1("USB_HOST_STATUS_PIPE_CRC16ER\r\n"); usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg &= ~USB_HOST_STATUS_PIPE_CRC16ER; xfer_result = XFER_RESULT_FAILED; } if (usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg & USB_HOST_STATUS_PIPE_TOUTER) { usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.reg &= ~USB_HOST_STATUS_PIPE_TOUTER; if ((USB->HOST.HostPipe[pipe].PCFG.bit.PTYPE == USB_HOST_PTYPE_INT) && (tu_edpt_dir(pipe_status->ep_addr) == TUSB_DIR_IN)) { // ignore timeouts from INT pipes } else { if (xfer_result == XFER_RESULT_INVALID) { xfer_result = XFER_RESULT_TIMEOUT; } } } // prevent PERR from too high error counts, that is handled by TinyUSB anyways usb_pipe_table[pipe].HostDescBank[0].STATUS_PIPE.bit.ERCNT = 0; // no updates if (xfer_result == XFER_RESULT_INVALID) { continue; } // continue / complete transfer if (samd_on_xfer(pipe, xfer_result)) { hcd_event_xfer_complete(pipe_status->dev_addr, pipe_status->ep_addr, pipe_status->xfer_length, xfer_result, true); } } } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { TU_ASSERT(rhport == 0); (void) rh_init; fake_fnum = 0; // reset to get in a clean state. USB->HOST.CTRLA.bit.SWRST = 1; while (USB->HOST.SYNCBUSY.bit.SWRST == 0) ; while (USB->HOST.SYNCBUSY.bit.SWRST == 1) ; // load pad calibration USB->HOST.PADCAL.bit.TRANSP = (*((uint32_t*) USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; USB->HOST.PADCAL.bit.TRANSN = (*((uint32_t*) USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; USB->HOST.PADCAL.bit.TRIM = (*((uint32_t*) USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; USB->HOST.QOSCTRL.bit.CQOS = 3; // High Quality USB->HOST.QOSCTRL.bit.DQOS = 3; // High Quality // configure host-mode samd_free_all_pipes(); // initializes pipe handles and usb_pipe_table USB->HOST.DESCADD.reg = (uint32_t) (&usb_pipe_table[0]); USB->HOST.CTRLB.reg = USB_HOST_CTRLB_SPDCONF_NORMAL | USB_HOST_CTRLB_VBUSOK; USB->HOST.CTRLA.reg = USB_CTRLA_MODE_HOST | USB_CTRLA_ENABLE | USB_CTRLA_RUNSTDBY; while (USB->HOST.SYNCBUSY.bit.ENABLE == 1) ; // enable basic USB interrupts USB->HOST.INTFLAG.reg |= USB->HOST.INTFLAG.reg; // clear pending USB->HOST.INTENCLR.reg = USB_HOST_INTENCLR_MASK; USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DCONN; USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DDISC; USB->HOST.INTENSET.reg = USB_HOST_INTENSET_WAKEUP; USB->HOST.INTENSET.reg = USB_HOST_INTENSET_RST; return true; } #if TU_CHECK_MCU(OPT_MCU_SAMD51, OPT_MCU_SAME5X) // Enable USB interrupt void hcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB_0_IRQn); NVIC_EnableIRQ(USB_1_IRQn); NVIC_EnableIRQ(USB_2_IRQn); NVIC_EnableIRQ(USB_3_IRQn); } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB_3_IRQn); NVIC_DisableIRQ(USB_2_IRQn); NVIC_DisableIRQ(USB_1_IRQn); NVIC_DisableIRQ(USB_0_IRQn); } #elif TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAMD21, OPT_MCU_SAML2X) // Enable USB interrupt void hcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB_IRQn); } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB_IRQn); } #else #error "No implementation available for hcd_int_enable / hcd_int_disable" #endif // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; // SAMD Quirk #2: // FNUM is stalled before enumeration of Low-Speed devices. // internal frame counter can be used as workaround (not very accurate) #ifdef HCD_SAMD_FAKE_FNUM uint8_t start, current, prev; uint8_t loop_count = (USB->HOST.STATUS.bit.SPEED == TUSB_SPEED_HIGH) ? 8 : 1; for (uint8_t i = 0; i < loop_count; i++) { start = USB->HOST.FLENHIGH.reg; current = start; // wait until wrap-around prev = current; while (current <= start) { current = USB->HOST.FLENHIGH.reg; if (current > prev) break; prev = current; } // wait until start is reached again prev = current; while (current > start) { current = USB->HOST.FLENHIGH.reg; if (current > prev) break; prev = current; } } fake_fnum += 1; return fake_fnum; #else return USB->HOST.FNUM.bit.FNUM; #endif // HCD_SAMD_FAKE_FNUM } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { TU_ASSERT(rhport == 0); return USB->HOST.STATUS.bit.LINESTATE != 0; } // Reset USB bus on the port. Return immediately, bus reset sequence may not be // complete. Some port would require hcd_port_reset_end() to be invoked after 10ms to // complete the reset sequence. void hcd_port_reset(uint8_t rhport) { hcd_int_disable(rhport); samd_free_all_pipes(); USB->HOST.INTFLAG.reg |= USB->HOST.INTFLAG.reg; // clear pending USB->HOST.CTRLB.bit.BUSRESET = 1; fake_fnum = 0; } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { while (USB->HOST.INTFLAG.bit.RST == 0) ; USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST; USB->HOST.CTRLB.bit.SOFE = 1; hcd_int_enable(rhport); } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; switch (USB->HOST.STATUS.bit.SPEED) { case 0: return TUSB_SPEED_FULL; case 1: return TUSB_SPEED_LOW; case 2: return TUSB_SPEED_HIGH; default: return TUSB_SPEED_INVALID; } } // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void) rhport; for (uint8_t pipe = 0; pipe < USB_PIPE_NUM; pipe++) { volatile usb_pipe_status_t* pipe_status = &usb_pipe_status_table[pipe]; if (pipe_status->dev_addr == dev_addr) { samd_free_pipe(pipe); } } } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const* ep_desc) { TU_ASSERT(rhport == 0); uint8_t pipe; volatile usb_pipe_status_t* pipe_status; const uint8_t ep_addr = ep_desc->bEndpointAddress; const uint8_t bmAttributes = (ep_desc->bmAttributes.xfer) | ((ep_desc->bmAttributes.sync) << 2) | ((ep_desc->bmAttributes.usage) << 4); // configure the pipe pipe = samd_configure_pipe(dev_addr, ep_addr); if (pipe >= USB_PIPE_NUM) { return false; } // initial configuration pipe_status = &usb_pipe_status_table[pipe]; USB->HOST.HostPipe[pipe].PCFG.reg &= ~USB_HOST_PCFG_PTYPE_Msk; USB->HOST.HostPipe[pipe].PCFG.bit.PTYPE = bmAttributes + 1; USB->HOST.HostPipe[pipe].BINTERVAL.reg = ep_desc->bInterval; USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_DTGL; USB->HOST.HostPipe[pipe].PINTENCLR.reg = USB_HOST_PINTENCLR_MASK; pipe_status->max_packet_size = ep_desc->wMaxPacketSize; usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.SIZE = USB_PCKSIZE_ENUM(pipe_status->max_packet_size); usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.AUTO_ZLP = 0; return true; } // Submit a special transfer to send 8-byte Setup Packet, when complete // hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { TU_ASSERT(rhport == 0); uint8_t pipe; volatile usb_pipe_status_t* pipe_status; // configure the pipe pipe = samd_configure_pipe(dev_addr, 0); if (pipe >= USB_PIPE_NUM) { return false; } // prepare transfer pipe_status = &usb_pipe_status_table[pipe]; usb_pipe_table[pipe].HostDescBank[0].ADDR.reg = (uint32_t) setup_packet; pipe_status->xfer_remaining = 8; pipe_status->xfer_length = 0; usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 8; usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; // clear pending interrupts USB->HOST.HostPipe[pipe].PINTFLAG.reg |= USB->HOST.HostPipe[pipe].PINTFLAG.reg; // begin transfer USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; return true; } // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t* buffer, uint16_t buflen) { TU_ASSERT(rhport == 0); uint8_t pipe; volatile usb_pipe_status_t* pipe_status; // configure the pipe pipe = samd_configure_pipe(dev_addr, ep_addr); if (pipe >= USB_PIPE_NUM) { return false; } // prepare transfer pipe_status = &usb_pipe_status_table[pipe]; usb_pipe_table[pipe].HostDescBank[0].ADDR.reg = (uint32_t) buffer; pipe_status->xfer_remaining = buflen; pipe_status->xfer_length = 0; // receive data if (tu_edpt_dir(pipe_status->ep_addr) == TUSB_DIR_IN) { usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = pipe_status->max_packet_size; USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; } // send data else { usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = (pipe_status->xfer_remaining < pipe_status->max_packet_size) ? pipe_status->xfer_remaining : pipe_status->max_packet_size; usb_pipe_table[pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; } // clear pending interrupts USB->HOST.HostPipe[pipe].PINTFLAG.reg |= USB->HOST.HostPipe[pipe].PINTFLAG.reg; // begin transfer USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; return true; } // Abort a queued transfer. Note: it can only abort transfer that has not been // started Return true if a queued transfer is aborted, false if there is no transfer // to abort bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { TU_ASSERT(rhport == 0); uint8_t pipe; volatile usb_pipe_status_t* pipe_status; TU_LOG3("hcd_edpt_abort_xfer(dev_addr=%02X, ep_addr=%02X)=", dev_addr, ep_addr); // find the pipe for (pipe = 0; pipe < USB_PIPE_NUM; pipe++) { pipe_status = &usb_pipe_status_table[pipe]; if ((pipe_status->dev_addr == dev_addr) && (pipe_status->ep_addr == ep_addr)) { break; } } // pipe not found if (pipe >= USB_PIPE_NUM) { TU_LOG3("ERR_NO_PIPE\r\n"); return false; } TU_LOG3("%d\r\n", pipe); // no transfer in progress if (USB->HOST.HostPipe[pipe].PSTATUS.bit.PFREEZE == 1) { return false; } // abort the transfer USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; pipe_status = &usb_pipe_status_table[pipe]; pipe_status->xfer_length = 0; pipe_status->xfer_remaining = 0; return true; } // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { TU_ASSERT(rhport == 0); uint8_t pipe; volatile usb_pipe_status_t* pipe_status; TU_LOG3("hcd_edpt_clear_stall(dev_addr=%02X, ep_addr=%02X)=", dev_addr, ep_addr); // find the pipe for (pipe = 0; pipe < USB_PIPE_NUM; pipe++) { pipe_status = &usb_pipe_status_table[pipe]; if ((pipe_status->dev_addr == dev_addr) && (pipe_status->ep_addr == ep_addr)) { break; } } // pipe not found if (pipe >= USB_PIPE_NUM) { TU_LOG3("ERR_NO_PIPE\r\n"); return false; } TU_LOG3("%d\r\n", pipe); // clear pending interrupts USB->HOST.HostPipe[pipe].PINTFLAG.reg |= USB->HOST.HostPipe[pipe].PINTFLAG.reg; // clear stalled state USB->HOST.HostPipe[pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; USB->HOST.HostPipe[pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_DTGL; return true; } #endif ================================================ FILE: src/portable/microchip/samg/dcd_samg.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUSB_MCU == OPT_MCU_SAMG #include "sam.h" #include "device/dcd.h" // TODO should support (SAM3S || SAM4S || SAM4E || SAMG55) //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #define EP_COUNT 6 // Transfer descriptor typedef struct { uint8_t* buffer; // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API uint16_t total_len; volatile uint16_t actual_len; uint16_t epsize; } xfer_desc_t; // Endpoint 0-5, each can only be either OUT or In xfer_desc_t _dcd_xfer[EP_COUNT]; TU_ATTR_ALWAYS_INLINE static inline void xfer_epsize_set(xfer_desc_t* xfer, uint16_t epsize) { xfer->epsize = epsize; } TU_ATTR_ALWAYS_INLINE static inline void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes) { xfer->buffer = buffer; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->total_len = total_bytes; xfer->actual_len = 0; } TU_ATTR_ALWAYS_INLINE static inline void xfer_end(xfer_desc_t* xfer) { xfer->buffer = NULL; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->total_len = 0; xfer->actual_len = 0; } TU_ATTR_ALWAYS_INLINE static inline uint16_t xfer_packet_len(xfer_desc_t* xfer) { // also cover zero-length packet return tu_min16(xfer->total_len - xfer->actual_len, xfer->epsize); } TU_ATTR_ALWAYS_INLINE static inline void xfer_packet_done(xfer_desc_t* xfer) { uint16_t const xact_len = xfer_packet_len(xfer); xfer->buffer += xact_len; xfer->actual_len += xact_len; } //------------- Transaction helpers -------------// // Write data to EP FIFO, return number of written bytes static void xact_ep_write(uint8_t epnum, uint8_t* buffer, uint16_t xact_len) { for(uint16_t i=0; iUDP_FDR[epnum] = (uint32_t) buffer[i]; } } // Read data from EP FIFO static void xact_ep_read(uint8_t epnum, uint8_t* buffer, uint16_t xact_len) { for(uint16_t i=0; iUDP_FDR[epnum]; } } //! Bitmap for all status bits in CSR that are not affected by a value 1. #define CSR_NO_EFFECT_1_ALL (UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT | UDP_CSR_RXSETUP | UDP_CSR_TXCOMP) // Per Specs: CSR need synchronization each write TU_ATTR_ALWAYS_INLINE static inline void csr_write(uint8_t epnum, uint32_t value) { uint32_t const csr = value; UDP->UDP_CSR[epnum] = csr; volatile uint32_t nop_count; for (nop_count = 0; nop_count < 20; nop_count ++) { __NOP(); } } // Per Specs: CSR need synchronization each write TU_ATTR_ALWAYS_INLINE static inline void csr_set(uint8_t epnum, uint32_t mask) { csr_write(epnum, UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL | mask); } // Per Specs: CSR need synchronization each write TU_ATTR_ALWAYS_INLINE static inline void csr_clear(uint8_t epnum, uint32_t mask) { csr_write(epnum, (UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL) & ~mask); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ // Set up endpoint 0, clear all other endpoints static void bus_reset(void) { tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); xfer_epsize_set(&_dcd_xfer[0], CFG_TUD_ENDPOINT0_SIZE); // Enable EP0 control csr_write(0, UDP_CSR_EPEDS_Msk); // Enable interrupt : EP0, Suspend, Resume, Wakeup UDP->UDP_IER = UDP_IER_EP0INT_Msk | UDP_IER_RXSUSP_Msk | UDP_IER_RXRSM_Msk | UDP_IER_WAKEUP_Msk; // Enable transceiver UDP->UDP_TXVC &= ~UDP_TXVC_TXVDIS_Msk; } // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); dcd_connect(rhport); return true; } // Enable device interrupt void dcd_int_enable (uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(UDP_IRQn); } // Disable device interrupt void dcd_int_disable (uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(UDP_IRQn); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; // Response with zlp status dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); // DCD can only set address after status for this request is complete. // do it at dcd_edpt0_status_complete() } // Wake up host void dcd_remote_wakeup (uint8_t rhport) { (void) rhport; } void dcd_connect(uint8_t rhport) { (void) rhport; // Enable pull-up, disable transceiver UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk; } void dcd_disconnect(uint8_t rhport) { (void) rhport; // disable both pullup and transceiver UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { if (request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t) request->wValue; // Enable addressed state UDP->UDP_GLB_STAT |= UDP_GLB_STAT_FADDEN_Msk; // Set new address & Function enable bit UDP->UDP_FADDR = UDP_FADDR_FEN_Msk | UDP_FADDR_FADD(dev_addr); } else if (request->bRequest == TUSB_REQ_SET_CONFIGURATION) { // Configured State UDP->UDP_GLB_STAT |= UDP_GLB_STAT_CONFG_Msk; } } } // Configure endpoint's registers according to descriptor // SAMG doesn't support a same endpoint number with IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(ep_desc->bEndpointAddress); // TODO Isochronous is not supported yet TU_VERIFY(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); TU_VERIFY(epnum < EP_COUNT); // Must not already enabled TU_ASSERT((UDP->UDP_CSR[epnum] & UDP_CSR_EPEDS_Msk) == 0); xfer_epsize_set(&_dcd_xfer[epnum], tu_edpt_packet_size(ep_desc)); // Configure type and enable EP csr_write(epnum, UDP_CSR_EPEDS_Msk | UDP_CSR_EPTYPE(ep_desc->bmAttributes.xfer + 4*dir)); // Enable EP Interrupt for IN if (dir == TUSB_DIR_IN) UDP->UDP_IER |= (1 << epnum); return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_desc_t* xfer = &_dcd_xfer[epnum]; xfer_begin(xfer, buffer, total_bytes); if (dir == TUSB_DIR_OUT) { // Enable interrupt when starting OUT transfer if (epnum != 0) UDP->UDP_IER |= (1 << epnum); } else { xact_ep_write(epnum, xfer->buffer, xfer_packet_len(xfer)); // TX ready for transfer csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); } return true; } #if 0 // TODO support dcd_edpt_xfer_fifo API bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; return true; } #endif // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; // For EP0 USBD will stall both EP0 Out and In with 0x00 and 0x80 // only handle one by skipping 0x80 if ( ep_addr == tu_edpt_addr(0, TUSB_DIR_IN_MASK) ) return; uint8_t const epnum = tu_edpt_number(ep_addr); // Set force stall bit csr_set(epnum, UDP_CSR_FORCESTALL_Msk); } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); // clear stall csr_clear(epnum, UDP_CSR_FORCESTALL_Msk); // must also reset EP to clear data toggle UDP->UDP_RST_EP |= (1 << epnum); UDP->UDP_RST_EP &= ~(1 << epnum); } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { uint32_t const intr_mask = UDP->UDP_IMR; uint32_t const intr_status = UDP->UDP_ISR & intr_mask; // clear interrupt UDP->UDP_ICR = intr_status; // Bus reset if (intr_status & UDP_ISR_ENDBUSRES_Msk) { bus_reset(); dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } // SOF // if (intr_status & UDP_ISR_SOFINT_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); // Suspend if (intr_status & UDP_ISR_RXSUSP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); // Resume if (intr_status & UDP_ISR_RXRSM_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); // Wakeup if (intr_status & UDP_ISR_WAKEUP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); //------------- Endpoints -------------// if ( intr_status & TU_BIT(0) ) { // setup packet if ( UDP->UDP_CSR[0] & UDP_CSR_RXSETUP ) { // get setup from FIFO uint8_t setup[8]; for(uint8_t i=0; iUDP_FDR[0]; } // notify usbd dcd_event_setup_received(rhport, setup, true); // Set EP direction bit according to DATA stage // MUST only be set before RXSETUP is clear per specs if ( tu_edpt_dir(setup[0]) ) { csr_set(0, UDP_CSR_DIR_Msk); } else { csr_clear(0, UDP_CSR_DIR_Msk); } // Clear Setup, stall and other on-going transfer bits csr_clear(0, UDP_CSR_RXSETUP_Msk | UDP_CSR_TXPKTRDY_Msk | UDP_CSR_TXCOMP_Msk | UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT_Msk | UDP_CSR_FORCESTALL_Msk); } } for(uint8_t epnum = 0; epnum < EP_COUNT; epnum++) { if ( intr_status & TU_BIT(epnum) ) { xfer_desc_t* xfer = &_dcd_xfer[epnum]; //------------- Endpoint IN -------------// if (UDP->UDP_CSR[epnum] & UDP_CSR_TXCOMP_Msk) { xfer_packet_done(xfer); uint16_t const xact_len = xfer_packet_len(xfer); if (xact_len) { // write to EP fifo #if 0 // TODO support dcd_edpt_xfer_fifo if (xfer->ff) { tu_fifo_read_n_access_mode(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len, true); } else #endif { xact_ep_write(epnum, xfer->buffer, xact_len); } // TX ready for transfer csr_set(epnum, UDP_CSR_TXPKTRDY_Msk); }else { // xfer is complete dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); // Required since control OUT can happen right after before stack handle this event xfer_end(xfer); } // Clear TX Complete bit csr_clear(epnum, UDP_CSR_TXCOMP_Msk); } //------------- Endpoint OUT -------------// // Ping-Pong is a MUST for Bulk/Iso // NOTE: When both Bank0 and Bank1 are both set, there is no way to know which one comes first uint32_t const banks_complete = UDP->UDP_CSR[epnum] & (UDP_CSR_RX_DATA_BK0_Msk | UDP_CSR_RX_DATA_BK1_Msk); if (banks_complete) { uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos); // Read from EP fifo #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_write_n_access_mode(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len, true); } else #endif { xact_ep_read(epnum, xfer->buffer, xact_len); } xfer_packet_done(xfer); if ( 0 == xfer_packet_len(xfer) ) { // Disable OUT EP interrupt when transfer is complete if (epnum != 0) UDP->UDP_IDR |= (1 << epnum); dcd_event_xfer_complete(rhport, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true); xfer_end(xfer); } // Clear DATA Bank0/1 bit csr_clear(epnum, banks_complete); } // Stall sent to host if (UDP->UDP_CSR[epnum] & UDP_CSR_STALLSENT_Msk) { csr_clear(epnum, UDP_CSR_STALLSENT_Msk); } } } } #endif ================================================ FILE: src/portable/microchip/samx7x/dcd_samx7x.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2021, HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMX7X #include "device/dcd.h" #include "sam.h" #include "samx7x_common.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ // Dual bank can improve performance, but need 2 times bigger packet buffer // As SAM7x has only 4KB packet buffer, use with caution ! // Enable in FS mode as packets are smaller #ifndef USE_DUAL_BANK #if TUD_OPT_HIGH_SPEED #define USE_DUAL_BANK 0 #else #define USE_DUAL_BANK 1 #endif #endif #define EP_GET_FIFO_PTR(ep, scale) \ (((TU_XSTRCAT(TU_STRCAT(uint, scale), _t)(*)[0x8000 / ((scale) / 8)]) FIFO_RAM_ADDR)[(ep)]) // Transfer control context typedef struct { uint8_t *buffer; uint16_t total_len; uint16_t queued_len; uint16_t max_packet_size; uint8_t interval; tu_fifo_t *fifo; } xfer_ctl_t; static tusb_speed_t get_speed(void); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint8_t ep_ix); static xfer_ctl_t xfer_status[EP_MAX]; static const tusb_desc_endpoint_t ep0_desc = { .bEndpointAddress = 0x00, .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, }; #if CFG_TUD_MEM_DCACHE_ENABLE bool dcd_dcache_clean(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_clean(addr, data_size); } bool dcd_dcache_invalidate(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_invalidate(addr, data_size); } bool dcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return samx7x_dcache_clean_invalidate(addr, data_size); } #endif //------------------------------------------------------------------ // Device API //------------------------------------------------------------------ // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rh_init; dcd_connect(rhport); return true; } // Enable device interrupt void dcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ((IRQn_Type)ID_USBHS); } // Disable device interrupt void dcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ((IRQn_Type)ID_USBHS); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; // DCD can only set address after status for this request is complete // do it at dcd_edpt0_status_complete() // Response with zlp status dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; USB_REG->DEVCTRL |= DEVCTRL_RMWKUP; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void)rhport; dcd_int_disable(rhport); // Enable the USB controller in device mode USB_REG->CTRL = CTRL_UIMOD | CTRL_USBE; while (!(USB_REG->SR & SR_CLKUSABLE)) ; #if TUD_OPT_HIGH_SPEED USB_REG->DEVCTRL &= ~DEVCTRL_SPDCONF; #else USB_REG->DEVCTRL |= DEVCTRL_SPDCONF_LOW_POWER; #endif // Enable the End Of Reset, Suspend & Wakeup interrupts USB_REG->DEVIER = (DEVIER_EORSTES | DEVIER_SUSPES | DEVIER_WAKEUPES); // Clear the End Of Reset, SOF & Wakeup interrupts USB_REG->DEVICR = (DEVICR_EORSTC | DEVICR_SOFC | DEVICR_WAKEUPC); // Manually set the Suspend Interrupt USB_REG->DEVIFR |= DEVIFR_SUSPS; // Ack the Wakeup Interrupt USB_REG->DEVICR = DEVICR_WAKEUPC; // Attach the device USB_REG->DEVCTRL &= ~DEVCTRL_DETACH; // Freeze USB clock USB_REG->CTRL |= CTRL_FRZCLK; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void)rhport; dcd_int_disable(rhport); // Disable all endpoints USB_REG->DEVEPT &= ~(0x3FF << DEVEPT_EPEN0_Pos); // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; while (!(USB_REG->SR & SR_CLKUSABLE)) ; // Clear all the pending interrupts USB_REG->DEVICR = DEVICR_Msk; // Disable all interrupts USB_REG->DEVIDR = DEVIDR_Msk; // Detach the device USB_REG->DEVCTRL |= DEVCTRL_DETACH; // Disable the device address USB_REG->DEVCTRL &= ~(DEVCTRL_ADDEN | DEVCTRL_UADD); } void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; if (en) { USB_REG->DEVIER = DEVIER_SOFES; } else { USB_REG->DEVIDR = DEVIDR_SOFEC; } } static tusb_speed_t get_speed(void) { switch (USB_REG->SR & SR_SPEED) { case SR_SPEED_FULL_SPEED: default: return TUSB_SPEED_FULL; case SR_SPEED_HIGH_SPEED: return TUSB_SPEED_HIGH; case SR_SPEED_LOW_SPEED: return TUSB_SPEED_LOW; } } static void dcd_ep_handler(uint8_t ep_ix) { uint32_t int_status = USB_REG->DEVEPTISR[ep_ix]; int_status &= USB_REG->DEVEPTIMR[ep_ix]; uint16_t count = (USB_REG->DEVEPTISR[ep_ix] & DEVEPTISR_BYCT) >> DEVEPTISR_BYCT_Pos; xfer_ctl_t *xfer = &xfer_status[ep_ix]; if (ep_ix == 0U) { static uint8_t ctrl_dir; if (int_status & DEVEPTISR_CTRL_RXSTPI) { ctrl_dir = (USB_REG->DEVEPTISR[0] & DEVEPTISR_CTRL_CTRLDIR) >> DEVEPTISR_CTRL_CTRLDIR_Pos; // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { uint8_t *ptr = EP_GET_FIFO_PTR(0, 8); dcd_event_setup_received(0, ptr, true); } // Ack and disable SETUP interrupt USB_REG->DEVEPTICR[0] = DEVEPTICR_CTRL_RXSTPIC; USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_RXSTPEC; } if (int_status & DEVEPTISR_RXOUTI) { uint8_t *ptr = EP_GET_FIFO_PTR(0, 8); if (count && xfer->total_len) { uint16_t remain = xfer->total_len - xfer->queued_len; if (count > remain) { count = remain; } if (xfer->buffer) { memcpy(xfer->buffer + xfer->queued_len, ptr, count); } else { tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } // Acknowledge the interrupt USB_REG->DEVEPTICR[0] = DEVEPTICR_RXOUTIC; if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // RX COMPLETE dcd_event_xfer_complete(0, 0, xfer->queued_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt USB_REG->DEVEPTIDR[0] = DEVEPTIDR_RXOUTEC; // Re-enable SETUP interrupt if (ctrl_dir == 1) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } } if (int_status & DEVEPTISR_TXINI) { // Disable the interrupt USB_REG->DEVEPTIDR[0] = DEVEPTIDR_TXINEC; if ((xfer->total_len != xfer->queued_len)) { // TX not complete dcd_transmit_packet(xfer, 0); } else { // TX complete dcd_event_xfer_complete(0, 0x80 + 0, xfer->total_len, XFER_RESULT_SUCCESS, true); // Re-enable SETUP interrupt if (ctrl_dir == 0) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } } } else { if (int_status & DEVEPTISR_RXOUTI) { if (count && xfer->total_len) { uint16_t remain = xfer->total_len - xfer->queued_len; if (count > remain) { count = remain; } uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix, 8); if (xfer->buffer) { memcpy(xfer->buffer + xfer->queued_len, ptr, count); } else { tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } // Clear the FIFO control flag to receive more data. USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; // Acknowledge the interrupt USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_RXOUTIC; if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // RX COMPLETE dcd_event_xfer_complete(0, ep_ix, xfer->queued_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_RXOUTEC; // Though the host could still send, we don't know. } } if (int_status & DEVEPTISR_TXINI) { // Acknowledge the interrupt USB_REG->DEVEPTICR[ep_ix] = DEVEPTICR_TXINIC; if ((xfer->total_len != xfer->queued_len)) { // TX not complete dcd_transmit_packet(xfer, ep_ix); } else { // TX complete dcd_event_xfer_complete(0, 0x80 + ep_ix, xfer->total_len, XFER_RESULT_SUCCESS, true); // Disable the interrupt USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_TXINEC; } } } } static void dcd_dma_handler(uint8_t ep_ix) { uint32_t status = USB_REG->DEVDMA[ep_ix - 1].DEVDMASTATUS; if (status & DEVDMASTATUS_CHANN_ENB) { return; // Ignore EOT_STA interrupt } // Disable DMA interrupt USB_REG->DEVIDR = DEVIDR_DMA_1 << (ep_ix - 1); xfer_ctl_t *xfer = &xfer_status[ep_ix]; uint16_t count = xfer->total_len - ((status & DEVDMASTATUS_BUFF_COUNT) >> DEVDMASTATUS_BUFF_COUNT_Pos); if (USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR) { dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true); } else { dcd_dcache_invalidate(xfer->buffer, count); dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true); } } void dcd_int_handler(uint8_t rhport) { (void)rhport; uint32_t int_status = USB_REG->DEVISR; int_status &= USB_REG->DEVIMR; // End of reset interrupt if (int_status & DEVISR_EORST) { // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; while (!(USB_REG->SR & SR_CLKUSABLE)) ; // Reset all endpoints for (int ep_ix = 1; ep_ix < EP_MAX; ep_ix++) { USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + ep_ix); USB_REG->DEVEPT &= ~(1 << (DEVEPT_EPRST0_Pos + ep_ix)); } dcd_edpt_open(0, &ep0_desc); USB_REG->DEVICR = DEVICR_EORSTC; USB_REG->DEVICR = DEVICR_WAKEUPC; USB_REG->DEVICR = DEVICR_SUSPC; USB_REG->DEVIER = DEVIER_SUSPES; dcd_event_bus_reset(rhport, get_speed(), true); } // End of Wakeup interrupt if (int_status & DEVISR_WAKEUP) { USB_REG->CTRL &= ~CTRL_FRZCLK; while (!(USB_REG->SR & SR_CLKUSABLE)) ; USB_REG->DEVICR = DEVICR_WAKEUPC; USB_REG->DEVIDR = DEVIDR_WAKEUPEC; USB_REG->DEVIER = DEVIER_SUSPES; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } // Suspend interrupt if (int_status & DEVISR_SUSP) { // Unfreeze USB clock USB_REG->CTRL &= ~CTRL_FRZCLK; while (!(USB_REG->SR & SR_CLKUSABLE)) ; USB_REG->DEVICR = DEVICR_SUSPC; USB_REG->DEVIDR = DEVIDR_SUSPEC; USB_REG->DEVIER = DEVIER_WAKEUPES; USB_REG->CTRL |= CTRL_FRZCLK; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (int_status & DEVISR_SOF) { USB_REG->DEVICR = DEVICR_SOFC; dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } // Endpoints interrupt for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) { if (int_status & (DEVISR_PEP_0 << ep_ix)) { dcd_ep_handler(ep_ix); } } // Endpoints DMA interrupt for (int ep_ix = 0; ep_ix < EP_MAX; ep_ix++) { if (EP_DMA_SUPPORT(ep_ix)) { if (int_status & (DEVISR_DMA_1 << (ep_ix - 1))) { dcd_dma_handler(ep_ix); } } } } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *request) { (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { const uint8_t dev_addr = (uint8_t)request->wValue; USB_REG->DEVCTRL |= dev_addr | DEVCTRL_ADDEN; } } // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_desc->bEndpointAddress); const uint8_t dir = tu_edpt_dir(ep_desc->bEndpointAddress); const uint16_t epMaxPktSize = tu_edpt_packet_size(ep_desc); const tusb_xfer_type_t eptype = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; uint8_t fifoSize = 0; // FIFO size uint16_t defaultEndpointSize = 8; // Default size of Endpoint // Find upper 2 power number of epMaxPktSize if (epMaxPktSize) { while (defaultEndpointSize < epMaxPktSize) { fifoSize++; defaultEndpointSize <<= 1; } } xfer_status[epnum].max_packet_size = epMaxPktSize; USB_REG->DEVEPT |= 1 << (DEVEPT_EPRST0_Pos + epnum); USB_REG->DEVEPT &= ~(1 << (DEVEPT_EPRST0_Pos + epnum)); if (epnum == 0) { // Enable the control endpoint - Endpoint 0 USB_REG->DEVEPT |= DEVEPT_EPEN0; // Configure the Endpoint 0 configuration register USB_REG->DEVEPTCFG[0] = ((fifoSize << DEVEPTCFG_EPSIZE_Pos) | (TUSB_XFER_CONTROL << DEVEPTCFG_EPTYPE_Pos) | (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | DEVEPTCFG_ALLOC); USB_REG->DEVEPTIER[0] = DEVEPTIER_RSTDTS; USB_REG->DEVEPTIDR[0] = DEVEPTIDR_CTRL_STALLRQC; if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[0] & DEVEPTISR_CFGOK)) { // Endpoint configuration is successful USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; // Enable Endpoint 0 Interrupts USB_REG->DEVIER = DEVIER_PEP_0; return true; } else { // Endpoint configuration is not successful return false; } } else { // Enable the endpoint USB_REG->DEVEPT |= ((0x01 << epnum) << DEVEPT_EPEN0_Pos); // Set up the maxpacket size, fifo start address fifosize // and enable the interrupt. CLear the data toggle. // AUTOSW is needed for DMA ack ! USB_REG->DEVEPTCFG[epnum] = ((fifoSize << DEVEPTCFG_EPSIZE_Pos) | (eptype << DEVEPTCFG_EPTYPE_Pos) | (DEVEPTCFG_EPBK_1_BANK << DEVEPTCFG_EPBK_Pos) | DEVEPTCFG_AUTOSW | ((dir & 0x01) << DEVEPTCFG_EPDIR_Pos)); if (eptype == TUSB_XFER_ISOCHRONOUS) { USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_NBTRANS_1_TRANS; } #if USE_DUAL_BANK if (eptype == TUSB_XFER_ISOCHRONOUS || eptype == TUSB_XFER_BULK) { USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_EPBK_2_BANK; } #endif USB_REG->DEVEPTCFG[epnum] |= DEVEPTCFG_ALLOC; USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RSTDTS; USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; if (DEVEPTISR_CFGOK == (USB_REG->DEVEPTISR[epnum] & DEVEPTISR_CFGOK)) { USB_REG->DEVIER = ((0x01 << epnum) << DEVIER_PEP_0_Pos); return true; } else { // Endpoint configuration is not successful return false; } } } void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } static void dcd_transmit_packet(xfer_ctl_t *xfer, uint8_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); if (len) { if (len > xfer->max_packet_size) { len = xfer->max_packet_size; } uint8_t *ptr = EP_GET_FIFO_PTR(ep_ix, 8); if (xfer->buffer) { memcpy(ptr, xfer->buffer + xfer->queued_len, len); } else { tu_hwfifo_write_from_fifo(ptr, xfer->fifo, len, NULL); } __DSB(); __ISB(); xfer->queued_len = (uint16_t)(xfer->queued_len + len); } if (ep_ix == 0U) { // Control endpoint: clear the interrupt flag to send the data USB_REG->DEVEPTICR[0] = DEVEPTICR_TXINIC; } else { // Other endpoint types: clear the FIFO control flag to send the data USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC; } USB_REG->DEVEPTIER[ep_ix] = DEVEPTIER_TXINES; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { (void)is_isr; (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = &xfer_status[epnum]; xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->fifo = NULL; if (EP_DMA_SUPPORT(epnum) && total_bytes != 0) { uint32_t udd_dma_ctrl = total_bytes << DEVDMACONTROL_BUFF_LENGTH_Pos; if (dir == TUSB_DIR_OUT) { udd_dma_ctrl |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; } else { udd_dma_ctrl |= DEVDMACONTROL_END_B_EN; dcd_dcache_clean(xfer->buffer, total_bytes); } USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)buffer; udd_dma_ctrl |= DEVDMACONTROL_END_BUFFIT | DEVDMACONTROL_CHANN_ENB; USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl; USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1); } else { if (dir == TUSB_DIR_OUT) { USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; } else { dcd_transmit_packet(xfer, epnum); } } return true; } // The number of bytes has to be given explicitly to allow more flexible control of how many // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { (void)is_isr; (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = &xfer_status[epnum]; xfer->buffer = NULL; xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->fifo = ff; if (dir == TUSB_DIR_OUT) { USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES; } else { dcd_transmit_packet(xfer, epnum); } return true; } // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); USB_REG->DEVEPTIER[epnum] = DEVEPTIER_CTRL_STALLRQS; // Re-enable SETUP interrupt if (epnum == 0) { USB_REG->DEVEPTIER[0] = DEVEPTIER_CTRL_RXSTPES; } } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RSTDTS; } #endif ================================================ FILE: src/portable/microchip/samx7x/samx7x_common.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Microchip Technology Inc. * Copyright (c) 2018, hathach (tinyusb.org) * Copyright (c) 2021, HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _COMMON_USB_REGS_H_ #define _COMMON_USB_REGS_H_ #if CFG_TUSB_MCU == OPT_MCU_SAMX7X /* -------- DEVDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Device DMA Channel Next Descriptor Address Register -------- */ #define DEVDMANXTDSC_OFFSET (0x00) /**< (DEVDMANXTDSC) Device DMA Channel Next Descriptor Address Register Offset */ #define DEVDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (DEVDMANXTDSC) Next Descriptor Address Position */ #define DEVDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << DEVDMANXTDSC_NXT_DSC_ADD_Pos) /**< (DEVDMANXTDSC) Next Descriptor Address Mask */ #define DEVDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (DEVDMANXTDSC) Register Mask */ /* -------- DEVDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Device DMA Channel Address Register -------- */ #define DEVDMAADDRESS_OFFSET (0x04) /**< (DEVDMAADDRESS) Device DMA Channel Address Register Offset */ #define DEVDMAADDRESS_BUFF_ADD_Pos 0 /**< (DEVDMAADDRESS) Buffer Address Position */ #define DEVDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << DEVDMAADDRESS_BUFF_ADD_Pos) /**< (DEVDMAADDRESS) Buffer Address Mask */ #define DEVDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (DEVDMAADDRESS) Register Mask */ /* -------- DEVDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Device DMA Channel Control Register -------- */ #define DEVDMACONTROL_OFFSET (0x08) /**< (DEVDMACONTROL) Device DMA Channel Control Register Offset */ #define DEVDMACONTROL_CHANN_ENB_Pos 0 /**< (DEVDMACONTROL) Channel Enable Command Position */ #define DEVDMACONTROL_CHANN_ENB (_U_(0x1) << DEVDMACONTROL_CHANN_ENB_Pos) /**< (DEVDMACONTROL) Channel Enable Command Mask */ #define DEVDMACONTROL_LDNXT_DSC_Pos 1 /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ #define DEVDMACONTROL_LDNXT_DSC (_U_(0x1) << DEVDMACONTROL_LDNXT_DSC_Pos) /**< (DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ #define DEVDMACONTROL_END_TR_EN_Pos 2 /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ #define DEVDMACONTROL_END_TR_EN (_U_(0x1) << DEVDMACONTROL_END_TR_EN_Pos) /**< (DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ #define DEVDMACONTROL_END_B_EN_Pos 3 /**< (DEVDMACONTROL) End of Buffer Enable Control Position */ #define DEVDMACONTROL_END_B_EN (_U_(0x1) << DEVDMACONTROL_END_B_EN_Pos) /**< (DEVDMACONTROL) End of Buffer Enable Control Mask */ #define DEVDMACONTROL_END_TR_IT_Pos 4 /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Position */ #define DEVDMACONTROL_END_TR_IT (_U_(0x1) << DEVDMACONTROL_END_TR_IT_Pos) /**< (DEVDMACONTROL) End of Transfer Interrupt Enable Mask */ #define DEVDMACONTROL_END_BUFFIT_Pos 5 /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Position */ #define DEVDMACONTROL_END_BUFFIT (_U_(0x1) << DEVDMACONTROL_END_BUFFIT_Pos) /**< (DEVDMACONTROL) End of Buffer Interrupt Enable Mask */ #define DEVDMACONTROL_DESC_LD_IT_Pos 6 /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Position */ #define DEVDMACONTROL_DESC_LD_IT (_U_(0x1) << DEVDMACONTROL_DESC_LD_IT_Pos) /**< (DEVDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ #define DEVDMACONTROL_BURST_LCK_Pos 7 /**< (DEVDMACONTROL) Burst Lock Enable Position */ #define DEVDMACONTROL_BURST_LCK (_U_(0x1) << DEVDMACONTROL_BURST_LCK_Pos) /**< (DEVDMACONTROL) Burst Lock Enable Mask */ #define DEVDMACONTROL_BUFF_LENGTH_Pos 16 /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Position */ #define DEVDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << DEVDMACONTROL_BUFF_LENGTH_Pos) /**< (DEVDMACONTROL) Buffer Byte Length (Write-only) Mask */ #define DEVDMACONTROL_Msk _U_(0xFFFF00FF) /**< (DEVDMACONTROL) Register Mask */ /* -------- DEVDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Device DMA Channel Status Register -------- */ #define DEVDMASTATUS_OFFSET (0x0C) /**< (DEVDMASTATUS) Device DMA Channel Status Register Offset */ #define DEVDMASTATUS_CHANN_ENB_Pos 0 /**< (DEVDMASTATUS) Channel Enable Status Position */ #define DEVDMASTATUS_CHANN_ENB (_U_(0x1) << DEVDMASTATUS_CHANN_ENB_Pos) /**< (DEVDMASTATUS) Channel Enable Status Mask */ #define DEVDMASTATUS_CHANN_ACT_Pos 1 /**< (DEVDMASTATUS) Channel Active Status Position */ #define DEVDMASTATUS_CHANN_ACT (_U_(0x1) << DEVDMASTATUS_CHANN_ACT_Pos) /**< (DEVDMASTATUS) Channel Active Status Mask */ #define DEVDMASTATUS_END_TR_ST_Pos 4 /**< (DEVDMASTATUS) End of Channel Transfer Status Position */ #define DEVDMASTATUS_END_TR_ST (_U_(0x1) << DEVDMASTATUS_END_TR_ST_Pos) /**< (DEVDMASTATUS) End of Channel Transfer Status Mask */ #define DEVDMASTATUS_END_BF_ST_Pos 5 /**< (DEVDMASTATUS) End of Channel Buffer Status Position */ #define DEVDMASTATUS_END_BF_ST (_U_(0x1) << DEVDMASTATUS_END_BF_ST_Pos) /**< (DEVDMASTATUS) End of Channel Buffer Status Mask */ #define DEVDMASTATUS_DESC_LDST_Pos 6 /**< (DEVDMASTATUS) Descriptor Loaded Status Position */ #define DEVDMASTATUS_DESC_LDST (_U_(0x1) << DEVDMASTATUS_DESC_LDST_Pos) /**< (DEVDMASTATUS) Descriptor Loaded Status Mask */ #define DEVDMASTATUS_BUFF_COUNT_Pos 16 /**< (DEVDMASTATUS) Buffer Byte Count Position */ #define DEVDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << DEVDMASTATUS_BUFF_COUNT_Pos) /**< (DEVDMASTATUS) Buffer Byte Count Mask */ #define DEVDMASTATUS_Msk _U_(0xFFFF0073) /**< (DEVDMASTATUS) Register Mask */ /* -------- HSTDMANXTDSC : (USBHS Offset: 0x00) (R/W 32) Host DMA Channel Next Descriptor Address Register -------- */ #define HSTDMANXTDSC_OFFSET (0x00) /**< (HSTDMANXTDSC) Host DMA Channel Next Descriptor Address Register Offset */ #define HSTDMANXTDSC_NXT_DSC_ADD_Pos 0 /**< (HSTDMANXTDSC) Next Descriptor Address Position */ #define HSTDMANXTDSC_NXT_DSC_ADD (_U_(0xFFFFFFFF) << HSTDMANXTDSC_NXT_DSC_ADD_Pos) /**< (HSTDMANXTDSC) Next Descriptor Address Mask */ #define HSTDMANXTDSC_Msk _U_(0xFFFFFFFF) /**< (HSTDMANXTDSC) Register Mask */ /* -------- HSTDMAADDRESS : (USBHS Offset: 0x04) (R/W 32) Host DMA Channel Address Register -------- */ #define HSTDMAADDRESS_OFFSET (0x04) /**< (HSTDMAADDRESS) Host DMA Channel Address Register Offset */ #define HSTDMAADDRESS_BUFF_ADD_Pos 0 /**< (HSTDMAADDRESS) Buffer Address Position */ #define HSTDMAADDRESS_BUFF_ADD (_U_(0xFFFFFFFF) << HSTDMAADDRESS_BUFF_ADD_Pos) /**< (HSTDMAADDRESS) Buffer Address Mask */ #define HSTDMAADDRESS_Msk _U_(0xFFFFFFFF) /**< (HSTDMAADDRESS) Register Mask */ /* -------- HSTDMACONTROL : (USBHS Offset: 0x08) (R/W 32) Host DMA Channel Control Register -------- */ #define HSTDMACONTROL_OFFSET (0x08) /**< (HSTDMACONTROL) Host DMA Channel Control Register Offset */ #define HSTDMACONTROL_CHANN_ENB_Pos 0 /**< (HSTDMACONTROL) Channel Enable Command Position */ #define HSTDMACONTROL_CHANN_ENB (_U_(0x1) << HSTDMACONTROL_CHANN_ENB_Pos) /**< (HSTDMACONTROL) Channel Enable Command Mask */ #define HSTDMACONTROL_LDNXT_DSC_Pos 1 /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Position */ #define HSTDMACONTROL_LDNXT_DSC (_U_(0x1) << HSTDMACONTROL_LDNXT_DSC_Pos) /**< (HSTDMACONTROL) Load Next Channel Transfer Descriptor Enable Command Mask */ #define HSTDMACONTROL_END_TR_EN_Pos 2 /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Position */ #define HSTDMACONTROL_END_TR_EN (_U_(0x1) << HSTDMACONTROL_END_TR_EN_Pos) /**< (HSTDMACONTROL) End of Transfer Enable Control (OUT transfers only) Mask */ #define HSTDMACONTROL_END_B_EN_Pos 3 /**< (HSTDMACONTROL) End of Buffer Enable Control Position */ #define HSTDMACONTROL_END_B_EN (_U_(0x1) << HSTDMACONTROL_END_B_EN_Pos) /**< (HSTDMACONTROL) End of Buffer Enable Control Mask */ #define HSTDMACONTROL_END_TR_IT_Pos 4 /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Position */ #define HSTDMACONTROL_END_TR_IT (_U_(0x1) << HSTDMACONTROL_END_TR_IT_Pos) /**< (HSTDMACONTROL) End of Transfer Interrupt Enable Mask */ #define HSTDMACONTROL_END_BUFFIT_Pos 5 /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Position */ #define HSTDMACONTROL_END_BUFFIT (_U_(0x1) << HSTDMACONTROL_END_BUFFIT_Pos) /**< (HSTDMACONTROL) End of Buffer Interrupt Enable Mask */ #define HSTDMACONTROL_DESC_LD_IT_Pos 6 /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Position */ #define HSTDMACONTROL_DESC_LD_IT (_U_(0x1) << HSTDMACONTROL_DESC_LD_IT_Pos) /**< (HSTDMACONTROL) Descriptor Loaded Interrupt Enable Mask */ #define HSTDMACONTROL_BURST_LCK_Pos 7 /**< (HSTDMACONTROL) Burst Lock Enable Position */ #define HSTDMACONTROL_BURST_LCK (_U_(0x1) << HSTDMACONTROL_BURST_LCK_Pos) /**< (HSTDMACONTROL) Burst Lock Enable Mask */ #define HSTDMACONTROL_BUFF_LENGTH_Pos 16 /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Position */ #define HSTDMACONTROL_BUFF_LENGTH (_U_(0xFFFF) << HSTDMACONTROL_BUFF_LENGTH_Pos) /**< (HSTDMACONTROL) Buffer Byte Length (Write-only) Mask */ #define HSTDMACONTROL_Msk _U_(0xFFFF00FF) /**< (HSTDMACONTROL) Register Mask */ /* -------- HSTDMASTATUS : (USBHS Offset: 0x0c) (R/W 32) Host DMA Channel Status Register -------- */ #define HSTDMASTATUS_OFFSET (0x0C) /**< (HSTDMASTATUS) Host DMA Channel Status Register Offset */ #define HSTDMASTATUS_CHANN_ENB_Pos 0 /**< (HSTDMASTATUS) Channel Enable Status Position */ #define HSTDMASTATUS_CHANN_ENB (_U_(0x1) << HSTDMASTATUS_CHANN_ENB_Pos) /**< (HSTDMASTATUS) Channel Enable Status Mask */ #define HSTDMASTATUS_CHANN_ACT_Pos 1 /**< (HSTDMASTATUS) Channel Active Status Position */ #define HSTDMASTATUS_CHANN_ACT (_U_(0x1) << HSTDMASTATUS_CHANN_ACT_Pos) /**< (HSTDMASTATUS) Channel Active Status Mask */ #define HSTDMASTATUS_END_TR_ST_Pos 4 /**< (HSTDMASTATUS) End of Channel Transfer Status Position */ #define HSTDMASTATUS_END_TR_ST (_U_(0x1) << HSTDMASTATUS_END_TR_ST_Pos) /**< (HSTDMASTATUS) End of Channel Transfer Status Mask */ #define HSTDMASTATUS_END_BF_ST_Pos 5 /**< (HSTDMASTATUS) End of Channel Buffer Status Position */ #define HSTDMASTATUS_END_BF_ST (_U_(0x1) << HSTDMASTATUS_END_BF_ST_Pos) /**< (HSTDMASTATUS) End of Channel Buffer Status Mask */ #define HSTDMASTATUS_DESC_LDST_Pos 6 /**< (HSTDMASTATUS) Descriptor Loaded Status Position */ #define HSTDMASTATUS_DESC_LDST (_U_(0x1) << HSTDMASTATUS_DESC_LDST_Pos) /**< (HSTDMASTATUS) Descriptor Loaded Status Mask */ #define HSTDMASTATUS_BUFF_COUNT_Pos 16 /**< (HSTDMASTATUS) Buffer Byte Count Position */ #define HSTDMASTATUS_BUFF_COUNT (_U_(0xFFFF) << HSTDMASTATUS_BUFF_COUNT_Pos) /**< (HSTDMASTATUS) Buffer Byte Count Mask */ #define HSTDMASTATUS_Msk _U_(0xFFFF0073) /**< (HSTDMASTATUS) Register Mask */ /* -------- DEVCTRL : (USBHS Offset: 0x00) (R/W 32) Device General Control Register -------- */ #define DEVCTRL_OFFSET (0x00) /**< (DEVCTRL) Device General Control Register Offset */ #define DEVCTRL_UADD_Pos 0 /**< (DEVCTRL) USB Address Position */ #define DEVCTRL_UADD (_U_(0x7F) << DEVCTRL_UADD_Pos) /**< (DEVCTRL) USB Address Mask */ #define DEVCTRL_ADDEN_Pos 7 /**< (DEVCTRL) Address Enable Position */ #define DEVCTRL_ADDEN (_U_(0x1) << DEVCTRL_ADDEN_Pos) /**< (DEVCTRL) Address Enable Mask */ #define DEVCTRL_DETACH_Pos 8 /**< (DEVCTRL) Detach Position */ #define DEVCTRL_DETACH (_U_(0x1) << DEVCTRL_DETACH_Pos) /**< (DEVCTRL) Detach Mask */ #define DEVCTRL_RMWKUP_Pos 9 /**< (DEVCTRL) Remote Wake-Up Position */ #define DEVCTRL_RMWKUP (_U_(0x1) << DEVCTRL_RMWKUP_Pos) /**< (DEVCTRL) Remote Wake-Up Mask */ #define DEVCTRL_SPDCONF_Pos 10 /**< (DEVCTRL) Mode Configuration Position */ #define DEVCTRL_SPDCONF (_U_(0x3) << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Mode Configuration Mask */ #define DEVCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. */ #define DEVCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (DEVCTRL) For a better consumption, if high speed is not needed. */ #define DEVCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (DEVCTRL) Forced high speed. */ #define DEVCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. */ #define DEVCTRL_SPDCONF_NORMAL (DEVCTRL_SPDCONF_NORMAL_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the host is high-speed-capable. Position */ #define DEVCTRL_SPDCONF_LOW_POWER (DEVCTRL_SPDCONF_LOW_POWER_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) For a better consumption, if high speed is not needed. Position */ #define DEVCTRL_SPDCONF_HIGH_SPEED (DEVCTRL_SPDCONF_HIGH_SPEED_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) Forced high speed. Position */ #define DEVCTRL_SPDCONF_FORCED_FS (DEVCTRL_SPDCONF_FORCED_FS_Val << DEVCTRL_SPDCONF_Pos) /**< (DEVCTRL) The peripheral remains in Full-speed mode whatever the host speed capability. Position */ #define DEVCTRL_LS_Pos 12 /**< (DEVCTRL) Low-Speed Mode Force Position */ #define DEVCTRL_LS (_U_(0x1) << DEVCTRL_LS_Pos) /**< (DEVCTRL) Low-Speed Mode Force Mask */ #define DEVCTRL_TSTJ_Pos 13 /**< (DEVCTRL) Test mode J Position */ #define DEVCTRL_TSTJ (_U_(0x1) << DEVCTRL_TSTJ_Pos) /**< (DEVCTRL) Test mode J Mask */ #define DEVCTRL_TSTK_Pos 14 /**< (DEVCTRL) Test mode K Position */ #define DEVCTRL_TSTK (_U_(0x1) << DEVCTRL_TSTK_Pos) /**< (DEVCTRL) Test mode K Mask */ #define DEVCTRL_TSTPCKT_Pos 15 /**< (DEVCTRL) Test packet mode Position */ #define DEVCTRL_TSTPCKT (_U_(0x1) << DEVCTRL_TSTPCKT_Pos) /**< (DEVCTRL) Test packet mode Mask */ #define DEVCTRL_OPMODE2_Pos 16 /**< (DEVCTRL) Specific Operational mode Position */ #define DEVCTRL_OPMODE2 (_U_(0x1) << DEVCTRL_OPMODE2_Pos) /**< (DEVCTRL) Specific Operational mode Mask */ #define DEVCTRL_Msk _U_(0x1FFFF) /**< (DEVCTRL) Register Mask */ #define DEVCTRL_OPMODE_Pos 16 /**< (DEVCTRL Position) Specific Operational mode */ #define DEVCTRL_OPMODE (_U_(0x1) << DEVCTRL_OPMODE_Pos) /**< (DEVCTRL Mask) OPMODE */ /* -------- DEVISR : (USBHS Offset: 0x04) (R/ 32) Device Global Interrupt Status Register -------- */ #define DEVISR_OFFSET (0x04) /**< (DEVISR) Device Global Interrupt Status Register Offset */ #define DEVISR_SUSP_Pos 0 /**< (DEVISR) Suspend Interrupt Position */ #define DEVISR_SUSP (_U_(0x1) << DEVISR_SUSP_Pos) /**< (DEVISR) Suspend Interrupt Mask */ #define DEVISR_MSOF_Pos 1 /**< (DEVISR) Micro Start of Frame Interrupt Position */ #define DEVISR_MSOF (_U_(0x1) << DEVISR_MSOF_Pos) /**< (DEVISR) Micro Start of Frame Interrupt Mask */ #define DEVISR_SOF_Pos 2 /**< (DEVISR) Start of Frame Interrupt Position */ #define DEVISR_SOF (_U_(0x1) << DEVISR_SOF_Pos) /**< (DEVISR) Start of Frame Interrupt Mask */ #define DEVISR_EORST_Pos 3 /**< (DEVISR) End of Reset Interrupt Position */ #define DEVISR_EORST (_U_(0x1) << DEVISR_EORST_Pos) /**< (DEVISR) End of Reset Interrupt Mask */ #define DEVISR_WAKEUP_Pos 4 /**< (DEVISR) Wake-Up Interrupt Position */ #define DEVISR_WAKEUP (_U_(0x1) << DEVISR_WAKEUP_Pos) /**< (DEVISR) Wake-Up Interrupt Mask */ #define DEVISR_EORSM_Pos 5 /**< (DEVISR) End of Resume Interrupt Position */ #define DEVISR_EORSM (_U_(0x1) << DEVISR_EORSM_Pos) /**< (DEVISR) End of Resume Interrupt Mask */ #define DEVISR_UPRSM_Pos 6 /**< (DEVISR) Upstream Resume Interrupt Position */ #define DEVISR_UPRSM (_U_(0x1) << DEVISR_UPRSM_Pos) /**< (DEVISR) Upstream Resume Interrupt Mask */ #define DEVISR_PEP_0_Pos 12 /**< (DEVISR) Endpoint 0 Interrupt Position */ #define DEVISR_PEP_0 (_U_(0x1) << DEVISR_PEP_0_Pos) /**< (DEVISR) Endpoint 0 Interrupt Mask */ #define DEVISR_PEP_1_Pos 13 /**< (DEVISR) Endpoint 1 Interrupt Position */ #define DEVISR_PEP_1 (_U_(0x1) << DEVISR_PEP_1_Pos) /**< (DEVISR) Endpoint 1 Interrupt Mask */ #define DEVISR_PEP_2_Pos 14 /**< (DEVISR) Endpoint 2 Interrupt Position */ #define DEVISR_PEP_2 (_U_(0x1) << DEVISR_PEP_2_Pos) /**< (DEVISR) Endpoint 2 Interrupt Mask */ #define DEVISR_PEP_3_Pos 15 /**< (DEVISR) Endpoint 3 Interrupt Position */ #define DEVISR_PEP_3 (_U_(0x1) << DEVISR_PEP_3_Pos) /**< (DEVISR) Endpoint 3 Interrupt Mask */ #define DEVISR_PEP_4_Pos 16 /**< (DEVISR) Endpoint 4 Interrupt Position */ #define DEVISR_PEP_4 (_U_(0x1) << DEVISR_PEP_4_Pos) /**< (DEVISR) Endpoint 4 Interrupt Mask */ #define DEVISR_PEP_5_Pos 17 /**< (DEVISR) Endpoint 5 Interrupt Position */ #define DEVISR_PEP_5 (_U_(0x1) << DEVISR_PEP_5_Pos) /**< (DEVISR) Endpoint 5 Interrupt Mask */ #define DEVISR_PEP_6_Pos 18 /**< (DEVISR) Endpoint 6 Interrupt Position */ #define DEVISR_PEP_6 (_U_(0x1) << DEVISR_PEP_6_Pos) /**< (DEVISR) Endpoint 6 Interrupt Mask */ #define DEVISR_PEP_7_Pos 19 /**< (DEVISR) Endpoint 7 Interrupt Position */ #define DEVISR_PEP_7 (_U_(0x1) << DEVISR_PEP_7_Pos) /**< (DEVISR) Endpoint 7 Interrupt Mask */ #define DEVISR_PEP_8_Pos 20 /**< (DEVISR) Endpoint 8 Interrupt Position */ #define DEVISR_PEP_8 (_U_(0x1) << DEVISR_PEP_8_Pos) /**< (DEVISR) Endpoint 8 Interrupt Mask */ #define DEVISR_PEP_9_Pos 21 /**< (DEVISR) Endpoint 9 Interrupt Position */ #define DEVISR_PEP_9 (_U_(0x1) << DEVISR_PEP_9_Pos) /**< (DEVISR) Endpoint 9 Interrupt Mask */ #define DEVISR_DMA_1_Pos 25 /**< (DEVISR) DMA Channel 1 Interrupt Position */ #define DEVISR_DMA_1 (_U_(0x1) << DEVISR_DMA_1_Pos) /**< (DEVISR) DMA Channel 1 Interrupt Mask */ #define DEVISR_DMA_2_Pos 26 /**< (DEVISR) DMA Channel 2 Interrupt Position */ #define DEVISR_DMA_2 (_U_(0x1) << DEVISR_DMA_2_Pos) /**< (DEVISR) DMA Channel 2 Interrupt Mask */ #define DEVISR_DMA_3_Pos 27 /**< (DEVISR) DMA Channel 3 Interrupt Position */ #define DEVISR_DMA_3 (_U_(0x1) << DEVISR_DMA_3_Pos) /**< (DEVISR) DMA Channel 3 Interrupt Mask */ #define DEVISR_DMA_4_Pos 28 /**< (DEVISR) DMA Channel 4 Interrupt Position */ #define DEVISR_DMA_4 (_U_(0x1) << DEVISR_DMA_4_Pos) /**< (DEVISR) DMA Channel 4 Interrupt Mask */ #define DEVISR_DMA_5_Pos 29 /**< (DEVISR) DMA Channel 5 Interrupt Position */ #define DEVISR_DMA_5 (_U_(0x1) << DEVISR_DMA_5_Pos) /**< (DEVISR) DMA Channel 5 Interrupt Mask */ #define DEVISR_DMA_6_Pos 30 /**< (DEVISR) DMA Channel 6 Interrupt Position */ #define DEVISR_DMA_6 (_U_(0x1) << DEVISR_DMA_6_Pos) /**< (DEVISR) DMA Channel 6 Interrupt Mask */ #define DEVISR_DMA_7_Pos 31 /**< (DEVISR) DMA Channel 7 Interrupt Position */ #define DEVISR_DMA_7 (_U_(0x1) << DEVISR_DMA_7_Pos) /**< (DEVISR) DMA Channel 7 Interrupt Mask */ #define DEVISR_Msk _U_(0xFE3FF07F) /**< (DEVISR) Register Mask */ #define DEVISR_PEP__Pos 12 /**< (DEVISR Position) Endpoint x Interrupt */ #define DEVISR_PEP_ (_U_(0x3FF) << DEVISR_PEP__Pos) /**< (DEVISR Mask) PEP_ */ #define DEVISR_DMA__Pos 25 /**< (DEVISR Position) DMA Channel 7 Interrupt */ #define DEVISR_DMA_ (_U_(0x7F) << DEVISR_DMA__Pos) /**< (DEVISR Mask) DMA_ */ /* -------- DEVICR : (USBHS Offset: 0x08) (/W 32) Device Global Interrupt Clear Register -------- */ #define DEVICR_OFFSET (0x08) /**< (DEVICR) Device Global Interrupt Clear Register Offset */ #define DEVICR_SUSPC_Pos 0 /**< (DEVICR) Suspend Interrupt Clear Position */ #define DEVICR_SUSPC (_U_(0x1) << DEVICR_SUSPC_Pos) /**< (DEVICR) Suspend Interrupt Clear Mask */ #define DEVICR_MSOFC_Pos 1 /**< (DEVICR) Micro Start of Frame Interrupt Clear Position */ #define DEVICR_MSOFC (_U_(0x1) << DEVICR_MSOFC_Pos) /**< (DEVICR) Micro Start of Frame Interrupt Clear Mask */ #define DEVICR_SOFC_Pos 2 /**< (DEVICR) Start of Frame Interrupt Clear Position */ #define DEVICR_SOFC (_U_(0x1) << DEVICR_SOFC_Pos) /**< (DEVICR) Start of Frame Interrupt Clear Mask */ #define DEVICR_EORSTC_Pos 3 /**< (DEVICR) End of Reset Interrupt Clear Position */ #define DEVICR_EORSTC (_U_(0x1) << DEVICR_EORSTC_Pos) /**< (DEVICR) End of Reset Interrupt Clear Mask */ #define DEVICR_WAKEUPC_Pos 4 /**< (DEVICR) Wake-Up Interrupt Clear Position */ #define DEVICR_WAKEUPC (_U_(0x1) << DEVICR_WAKEUPC_Pos) /**< (DEVICR) Wake-Up Interrupt Clear Mask */ #define DEVICR_EORSMC_Pos 5 /**< (DEVICR) End of Resume Interrupt Clear Position */ #define DEVICR_EORSMC (_U_(0x1) << DEVICR_EORSMC_Pos) /**< (DEVICR) End of Resume Interrupt Clear Mask */ #define DEVICR_UPRSMC_Pos 6 /**< (DEVICR) Upstream Resume Interrupt Clear Position */ #define DEVICR_UPRSMC (_U_(0x1) << DEVICR_UPRSMC_Pos) /**< (DEVICR) Upstream Resume Interrupt Clear Mask */ #define DEVICR_Msk _U_(0x7F) /**< (DEVICR) Register Mask */ /* -------- DEVIFR : (USBHS Offset: 0x0c) (/W 32) Device Global Interrupt Set Register -------- */ #define DEVIFR_OFFSET (0x0C) /**< (DEVIFR) Device Global Interrupt Set Register Offset */ #define DEVIFR_SUSPS_Pos 0 /**< (DEVIFR) Suspend Interrupt Set Position */ #define DEVIFR_SUSPS (_U_(0x1) << DEVIFR_SUSPS_Pos) /**< (DEVIFR) Suspend Interrupt Set Mask */ #define DEVIFR_MSOFS_Pos 1 /**< (DEVIFR) Micro Start of Frame Interrupt Set Position */ #define DEVIFR_MSOFS (_U_(0x1) << DEVIFR_MSOFS_Pos) /**< (DEVIFR) Micro Start of Frame Interrupt Set Mask */ #define DEVIFR_SOFS_Pos 2 /**< (DEVIFR) Start of Frame Interrupt Set Position */ #define DEVIFR_SOFS (_U_(0x1) << DEVIFR_SOFS_Pos) /**< (DEVIFR) Start of Frame Interrupt Set Mask */ #define DEVIFR_EORSTS_Pos 3 /**< (DEVIFR) End of Reset Interrupt Set Position */ #define DEVIFR_EORSTS (_U_(0x1) << DEVIFR_EORSTS_Pos) /**< (DEVIFR) End of Reset Interrupt Set Mask */ #define DEVIFR_WAKEUPS_Pos 4 /**< (DEVIFR) Wake-Up Interrupt Set Position */ #define DEVIFR_WAKEUPS (_U_(0x1) << DEVIFR_WAKEUPS_Pos) /**< (DEVIFR) Wake-Up Interrupt Set Mask */ #define DEVIFR_EORSMS_Pos 5 /**< (DEVIFR) End of Resume Interrupt Set Position */ #define DEVIFR_EORSMS (_U_(0x1) << DEVIFR_EORSMS_Pos) /**< (DEVIFR) End of Resume Interrupt Set Mask */ #define DEVIFR_UPRSMS_Pos 6 /**< (DEVIFR) Upstream Resume Interrupt Set Position */ #define DEVIFR_UPRSMS (_U_(0x1) << DEVIFR_UPRSMS_Pos) /**< (DEVIFR) Upstream Resume Interrupt Set Mask */ #define DEVIFR_DMA_1_Pos 25 /**< (DEVIFR) DMA Channel 1 Interrupt Set Position */ #define DEVIFR_DMA_1 (_U_(0x1) << DEVIFR_DMA_1_Pos) /**< (DEVIFR) DMA Channel 1 Interrupt Set Mask */ #define DEVIFR_DMA_2_Pos 26 /**< (DEVIFR) DMA Channel 2 Interrupt Set Position */ #define DEVIFR_DMA_2 (_U_(0x1) << DEVIFR_DMA_2_Pos) /**< (DEVIFR) DMA Channel 2 Interrupt Set Mask */ #define DEVIFR_DMA_3_Pos 27 /**< (DEVIFR) DMA Channel 3 Interrupt Set Position */ #define DEVIFR_DMA_3 (_U_(0x1) << DEVIFR_DMA_3_Pos) /**< (DEVIFR) DMA Channel 3 Interrupt Set Mask */ #define DEVIFR_DMA_4_Pos 28 /**< (DEVIFR) DMA Channel 4 Interrupt Set Position */ #define DEVIFR_DMA_4 (_U_(0x1) << DEVIFR_DMA_4_Pos) /**< (DEVIFR) DMA Channel 4 Interrupt Set Mask */ #define DEVIFR_DMA_5_Pos 29 /**< (DEVIFR) DMA Channel 5 Interrupt Set Position */ #define DEVIFR_DMA_5 (_U_(0x1) << DEVIFR_DMA_5_Pos) /**< (DEVIFR) DMA Channel 5 Interrupt Set Mask */ #define DEVIFR_DMA_6_Pos 30 /**< (DEVIFR) DMA Channel 6 Interrupt Set Position */ #define DEVIFR_DMA_6 (_U_(0x1) << DEVIFR_DMA_6_Pos) /**< (DEVIFR) DMA Channel 6 Interrupt Set Mask */ #define DEVIFR_DMA_7_Pos 31 /**< (DEVIFR) DMA Channel 7 Interrupt Set Position */ #define DEVIFR_DMA_7 (_U_(0x1) << DEVIFR_DMA_7_Pos) /**< (DEVIFR) DMA Channel 7 Interrupt Set Mask */ #define DEVIFR_Msk _U_(0xFE00007F) /**< (DEVIFR) Register Mask */ #define DEVIFR_DMA__Pos 25 /**< (DEVIFR Position) DMA Channel 7 Interrupt Set */ #define DEVIFR_DMA_ (_U_(0x7F) << DEVIFR_DMA__Pos) /**< (DEVIFR Mask) DMA_ */ /* -------- DEVIMR : (USBHS Offset: 0x10) (R/ 32) Device Global Interrupt Mask Register -------- */ #define DEVIMR_OFFSET (0x10) /**< (DEVIMR) Device Global Interrupt Mask Register Offset */ #define DEVIMR_SUSPE_Pos 0 /**< (DEVIMR) Suspend Interrupt Mask Position */ #define DEVIMR_SUSPE (_U_(0x1) << DEVIMR_SUSPE_Pos) /**< (DEVIMR) Suspend Interrupt Mask Mask */ #define DEVIMR_MSOFE_Pos 1 /**< (DEVIMR) Micro Start of Frame Interrupt Mask Position */ #define DEVIMR_MSOFE (_U_(0x1) << DEVIMR_MSOFE_Pos) /**< (DEVIMR) Micro Start of Frame Interrupt Mask Mask */ #define DEVIMR_SOFE_Pos 2 /**< (DEVIMR) Start of Frame Interrupt Mask Position */ #define DEVIMR_SOFE (_U_(0x1) << DEVIMR_SOFE_Pos) /**< (DEVIMR) Start of Frame Interrupt Mask Mask */ #define DEVIMR_EORSTE_Pos 3 /**< (DEVIMR) End of Reset Interrupt Mask Position */ #define DEVIMR_EORSTE (_U_(0x1) << DEVIMR_EORSTE_Pos) /**< (DEVIMR) End of Reset Interrupt Mask Mask */ #define DEVIMR_WAKEUPE_Pos 4 /**< (DEVIMR) Wake-Up Interrupt Mask Position */ #define DEVIMR_WAKEUPE (_U_(0x1) << DEVIMR_WAKEUPE_Pos) /**< (DEVIMR) Wake-Up Interrupt Mask Mask */ #define DEVIMR_EORSME_Pos 5 /**< (DEVIMR) End of Resume Interrupt Mask Position */ #define DEVIMR_EORSME (_U_(0x1) << DEVIMR_EORSME_Pos) /**< (DEVIMR) End of Resume Interrupt Mask Mask */ #define DEVIMR_UPRSME_Pos 6 /**< (DEVIMR) Upstream Resume Interrupt Mask Position */ #define DEVIMR_UPRSME (_U_(0x1) << DEVIMR_UPRSME_Pos) /**< (DEVIMR) Upstream Resume Interrupt Mask Mask */ #define DEVIMR_PEP_0_Pos 12 /**< (DEVIMR) Endpoint 0 Interrupt Mask Position */ #define DEVIMR_PEP_0 (_U_(0x1) << DEVIMR_PEP_0_Pos) /**< (DEVIMR) Endpoint 0 Interrupt Mask Mask */ #define DEVIMR_PEP_1_Pos 13 /**< (DEVIMR) Endpoint 1 Interrupt Mask Position */ #define DEVIMR_PEP_1 (_U_(0x1) << DEVIMR_PEP_1_Pos) /**< (DEVIMR) Endpoint 1 Interrupt Mask Mask */ #define DEVIMR_PEP_2_Pos 14 /**< (DEVIMR) Endpoint 2 Interrupt Mask Position */ #define DEVIMR_PEP_2 (_U_(0x1) << DEVIMR_PEP_2_Pos) /**< (DEVIMR) Endpoint 2 Interrupt Mask Mask */ #define DEVIMR_PEP_3_Pos 15 /**< (DEVIMR) Endpoint 3 Interrupt Mask Position */ #define DEVIMR_PEP_3 (_U_(0x1) << DEVIMR_PEP_3_Pos) /**< (DEVIMR) Endpoint 3 Interrupt Mask Mask */ #define DEVIMR_PEP_4_Pos 16 /**< (DEVIMR) Endpoint 4 Interrupt Mask Position */ #define DEVIMR_PEP_4 (_U_(0x1) << DEVIMR_PEP_4_Pos) /**< (DEVIMR) Endpoint 4 Interrupt Mask Mask */ #define DEVIMR_PEP_5_Pos 17 /**< (DEVIMR) Endpoint 5 Interrupt Mask Position */ #define DEVIMR_PEP_5 (_U_(0x1) << DEVIMR_PEP_5_Pos) /**< (DEVIMR) Endpoint 5 Interrupt Mask Mask */ #define DEVIMR_PEP_6_Pos 18 /**< (DEVIMR) Endpoint 6 Interrupt Mask Position */ #define DEVIMR_PEP_6 (_U_(0x1) << DEVIMR_PEP_6_Pos) /**< (DEVIMR) Endpoint 6 Interrupt Mask Mask */ #define DEVIMR_PEP_7_Pos 19 /**< (DEVIMR) Endpoint 7 Interrupt Mask Position */ #define DEVIMR_PEP_7 (_U_(0x1) << DEVIMR_PEP_7_Pos) /**< (DEVIMR) Endpoint 7 Interrupt Mask Mask */ #define DEVIMR_PEP_8_Pos 20 /**< (DEVIMR) Endpoint 8 Interrupt Mask Position */ #define DEVIMR_PEP_8 (_U_(0x1) << DEVIMR_PEP_8_Pos) /**< (DEVIMR) Endpoint 8 Interrupt Mask Mask */ #define DEVIMR_PEP_9_Pos 21 /**< (DEVIMR) Endpoint 9 Interrupt Mask Position */ #define DEVIMR_PEP_9 (_U_(0x1) << DEVIMR_PEP_9_Pos) /**< (DEVIMR) Endpoint 9 Interrupt Mask Mask */ #define DEVIMR_DMA_1_Pos 25 /**< (DEVIMR) DMA Channel 1 Interrupt Mask Position */ #define DEVIMR_DMA_1 (_U_(0x1) << DEVIMR_DMA_1_Pos) /**< (DEVIMR) DMA Channel 1 Interrupt Mask Mask */ #define DEVIMR_DMA_2_Pos 26 /**< (DEVIMR) DMA Channel 2 Interrupt Mask Position */ #define DEVIMR_DMA_2 (_U_(0x1) << DEVIMR_DMA_2_Pos) /**< (DEVIMR) DMA Channel 2 Interrupt Mask Mask */ #define DEVIMR_DMA_3_Pos 27 /**< (DEVIMR) DMA Channel 3 Interrupt Mask Position */ #define DEVIMR_DMA_3 (_U_(0x1) << DEVIMR_DMA_3_Pos) /**< (DEVIMR) DMA Channel 3 Interrupt Mask Mask */ #define DEVIMR_DMA_4_Pos 28 /**< (DEVIMR) DMA Channel 4 Interrupt Mask Position */ #define DEVIMR_DMA_4 (_U_(0x1) << DEVIMR_DMA_4_Pos) /**< (DEVIMR) DMA Channel 4 Interrupt Mask Mask */ #define DEVIMR_DMA_5_Pos 29 /**< (DEVIMR) DMA Channel 5 Interrupt Mask Position */ #define DEVIMR_DMA_5 (_U_(0x1) << DEVIMR_DMA_5_Pos) /**< (DEVIMR) DMA Channel 5 Interrupt Mask Mask */ #define DEVIMR_DMA_6_Pos 30 /**< (DEVIMR) DMA Channel 6 Interrupt Mask Position */ #define DEVIMR_DMA_6 (_U_(0x1) << DEVIMR_DMA_6_Pos) /**< (DEVIMR) DMA Channel 6 Interrupt Mask Mask */ #define DEVIMR_DMA_7_Pos 31 /**< (DEVIMR) DMA Channel 7 Interrupt Mask Position */ #define DEVIMR_DMA_7 (_U_(0x1) << DEVIMR_DMA_7_Pos) /**< (DEVIMR) DMA Channel 7 Interrupt Mask Mask */ #define DEVIMR_Msk _U_(0xFE3FF07F) /**< (DEVIMR) Register Mask */ #define DEVIMR_PEP__Pos 12 /**< (DEVIMR Position) Endpoint x Interrupt Mask */ #define DEVIMR_PEP_ (_U_(0x3FF) << DEVIMR_PEP__Pos) /**< (DEVIMR Mask) PEP_ */ #define DEVIMR_DMA__Pos 25 /**< (DEVIMR Position) DMA Channel 7 Interrupt Mask */ #define DEVIMR_DMA_ (_U_(0x7F) << DEVIMR_DMA__Pos) /**< (DEVIMR Mask) DMA_ */ /* -------- DEVIDR : (USBHS Offset: 0x14) (/W 32) Device Global Interrupt Disable Register -------- */ #define DEVIDR_OFFSET (0x14) /**< (DEVIDR) Device Global Interrupt Disable Register Offset */ #define DEVIDR_SUSPEC_Pos 0 /**< (DEVIDR) Suspend Interrupt Disable Position */ #define DEVIDR_SUSPEC (_U_(0x1) << DEVIDR_SUSPEC_Pos) /**< (DEVIDR) Suspend Interrupt Disable Mask */ #define DEVIDR_MSOFEC_Pos 1 /**< (DEVIDR) Micro Start of Frame Interrupt Disable Position */ #define DEVIDR_MSOFEC (_U_(0x1) << DEVIDR_MSOFEC_Pos) /**< (DEVIDR) Micro Start of Frame Interrupt Disable Mask */ #define DEVIDR_SOFEC_Pos 2 /**< (DEVIDR) Start of Frame Interrupt Disable Position */ #define DEVIDR_SOFEC (_U_(0x1) << DEVIDR_SOFEC_Pos) /**< (DEVIDR) Start of Frame Interrupt Disable Mask */ #define DEVIDR_EORSTEC_Pos 3 /**< (DEVIDR) End of Reset Interrupt Disable Position */ #define DEVIDR_EORSTEC (_U_(0x1) << DEVIDR_EORSTEC_Pos) /**< (DEVIDR) End of Reset Interrupt Disable Mask */ #define DEVIDR_WAKEUPEC_Pos 4 /**< (DEVIDR) Wake-Up Interrupt Disable Position */ #define DEVIDR_WAKEUPEC (_U_(0x1) << DEVIDR_WAKEUPEC_Pos) /**< (DEVIDR) Wake-Up Interrupt Disable Mask */ #define DEVIDR_EORSMEC_Pos 5 /**< (DEVIDR) End of Resume Interrupt Disable Position */ #define DEVIDR_EORSMEC (_U_(0x1) << DEVIDR_EORSMEC_Pos) /**< (DEVIDR) End of Resume Interrupt Disable Mask */ #define DEVIDR_UPRSMEC_Pos 6 /**< (DEVIDR) Upstream Resume Interrupt Disable Position */ #define DEVIDR_UPRSMEC (_U_(0x1) << DEVIDR_UPRSMEC_Pos) /**< (DEVIDR) Upstream Resume Interrupt Disable Mask */ #define DEVIDR_PEP_0_Pos 12 /**< (DEVIDR) Endpoint 0 Interrupt Disable Position */ #define DEVIDR_PEP_0 (_U_(0x1) << DEVIDR_PEP_0_Pos) /**< (DEVIDR) Endpoint 0 Interrupt Disable Mask */ #define DEVIDR_PEP_1_Pos 13 /**< (DEVIDR) Endpoint 1 Interrupt Disable Position */ #define DEVIDR_PEP_1 (_U_(0x1) << DEVIDR_PEP_1_Pos) /**< (DEVIDR) Endpoint 1 Interrupt Disable Mask */ #define DEVIDR_PEP_2_Pos 14 /**< (DEVIDR) Endpoint 2 Interrupt Disable Position */ #define DEVIDR_PEP_2 (_U_(0x1) << DEVIDR_PEP_2_Pos) /**< (DEVIDR) Endpoint 2 Interrupt Disable Mask */ #define DEVIDR_PEP_3_Pos 15 /**< (DEVIDR) Endpoint 3 Interrupt Disable Position */ #define DEVIDR_PEP_3 (_U_(0x1) << DEVIDR_PEP_3_Pos) /**< (DEVIDR) Endpoint 3 Interrupt Disable Mask */ #define DEVIDR_PEP_4_Pos 16 /**< (DEVIDR) Endpoint 4 Interrupt Disable Position */ #define DEVIDR_PEP_4 (_U_(0x1) << DEVIDR_PEP_4_Pos) /**< (DEVIDR) Endpoint 4 Interrupt Disable Mask */ #define DEVIDR_PEP_5_Pos 17 /**< (DEVIDR) Endpoint 5 Interrupt Disable Position */ #define DEVIDR_PEP_5 (_U_(0x1) << DEVIDR_PEP_5_Pos) /**< (DEVIDR) Endpoint 5 Interrupt Disable Mask */ #define DEVIDR_PEP_6_Pos 18 /**< (DEVIDR) Endpoint 6 Interrupt Disable Position */ #define DEVIDR_PEP_6 (_U_(0x1) << DEVIDR_PEP_6_Pos) /**< (DEVIDR) Endpoint 6 Interrupt Disable Mask */ #define DEVIDR_PEP_7_Pos 19 /**< (DEVIDR) Endpoint 7 Interrupt Disable Position */ #define DEVIDR_PEP_7 (_U_(0x1) << DEVIDR_PEP_7_Pos) /**< (DEVIDR) Endpoint 7 Interrupt Disable Mask */ #define DEVIDR_PEP_8_Pos 20 /**< (DEVIDR) Endpoint 8 Interrupt Disable Position */ #define DEVIDR_PEP_8 (_U_(0x1) << DEVIDR_PEP_8_Pos) /**< (DEVIDR) Endpoint 8 Interrupt Disable Mask */ #define DEVIDR_PEP_9_Pos 21 /**< (DEVIDR) Endpoint 9 Interrupt Disable Position */ #define DEVIDR_PEP_9 (_U_(0x1) << DEVIDR_PEP_9_Pos) /**< (DEVIDR) Endpoint 9 Interrupt Disable Mask */ #define DEVIDR_DMA_1_Pos 25 /**< (DEVIDR) DMA Channel 1 Interrupt Disable Position */ #define DEVIDR_DMA_1 (_U_(0x1) << DEVIDR_DMA_1_Pos) /**< (DEVIDR) DMA Channel 1 Interrupt Disable Mask */ #define DEVIDR_DMA_2_Pos 26 /**< (DEVIDR) DMA Channel 2 Interrupt Disable Position */ #define DEVIDR_DMA_2 (_U_(0x1) << DEVIDR_DMA_2_Pos) /**< (DEVIDR) DMA Channel 2 Interrupt Disable Mask */ #define DEVIDR_DMA_3_Pos 27 /**< (DEVIDR) DMA Channel 3 Interrupt Disable Position */ #define DEVIDR_DMA_3 (_U_(0x1) << DEVIDR_DMA_3_Pos) /**< (DEVIDR) DMA Channel 3 Interrupt Disable Mask */ #define DEVIDR_DMA_4_Pos 28 /**< (DEVIDR) DMA Channel 4 Interrupt Disable Position */ #define DEVIDR_DMA_4 (_U_(0x1) << DEVIDR_DMA_4_Pos) /**< (DEVIDR) DMA Channel 4 Interrupt Disable Mask */ #define DEVIDR_DMA_5_Pos 29 /**< (DEVIDR) DMA Channel 5 Interrupt Disable Position */ #define DEVIDR_DMA_5 (_U_(0x1) << DEVIDR_DMA_5_Pos) /**< (DEVIDR) DMA Channel 5 Interrupt Disable Mask */ #define DEVIDR_DMA_6_Pos 30 /**< (DEVIDR) DMA Channel 6 Interrupt Disable Position */ #define DEVIDR_DMA_6 (_U_(0x1) << DEVIDR_DMA_6_Pos) /**< (DEVIDR) DMA Channel 6 Interrupt Disable Mask */ #define DEVIDR_DMA_7_Pos 31 /**< (DEVIDR) DMA Channel 7 Interrupt Disable Position */ #define DEVIDR_DMA_7 (_U_(0x1) << DEVIDR_DMA_7_Pos) /**< (DEVIDR) DMA Channel 7 Interrupt Disable Mask */ #define DEVIDR_Msk _U_(0xFE3FF07F) /**< (DEVIDR) Register Mask */ #define DEVIDR_PEP__Pos 12 /**< (DEVIDR Position) Endpoint x Interrupt Disable */ #define DEVIDR_PEP_ (_U_(0x3FF) << DEVIDR_PEP__Pos) /**< (DEVIDR Mask) PEP_ */ #define DEVIDR_DMA__Pos 25 /**< (DEVIDR Position) DMA Channel 7 Interrupt Disable */ #define DEVIDR_DMA_ (_U_(0x7F) << DEVIDR_DMA__Pos) /**< (DEVIDR Mask) DMA_ */ /* -------- DEVIER : (USBHS Offset: 0x18) (/W 32) Device Global Interrupt Enable Register -------- */ #define DEVIER_OFFSET (0x18) /**< (DEVIER) Device Global Interrupt Enable Register Offset */ #define DEVIER_SUSPES_Pos 0 /**< (DEVIER) Suspend Interrupt Enable Position */ #define DEVIER_SUSPES (_U_(0x1) << DEVIER_SUSPES_Pos) /**< (DEVIER) Suspend Interrupt Enable Mask */ #define DEVIER_MSOFES_Pos 1 /**< (DEVIER) Micro Start of Frame Interrupt Enable Position */ #define DEVIER_MSOFES (_U_(0x1) << DEVIER_MSOFES_Pos) /**< (DEVIER) Micro Start of Frame Interrupt Enable Mask */ #define DEVIER_SOFES_Pos 2 /**< (DEVIER) Start of Frame Interrupt Enable Position */ #define DEVIER_SOFES (_U_(0x1) << DEVIER_SOFES_Pos) /**< (DEVIER) Start of Frame Interrupt Enable Mask */ #define DEVIER_EORSTES_Pos 3 /**< (DEVIER) End of Reset Interrupt Enable Position */ #define DEVIER_EORSTES (_U_(0x1) << DEVIER_EORSTES_Pos) /**< (DEVIER) End of Reset Interrupt Enable Mask */ #define DEVIER_WAKEUPES_Pos 4 /**< (DEVIER) Wake-Up Interrupt Enable Position */ #define DEVIER_WAKEUPES (_U_(0x1) << DEVIER_WAKEUPES_Pos) /**< (DEVIER) Wake-Up Interrupt Enable Mask */ #define DEVIER_EORSMES_Pos 5 /**< (DEVIER) End of Resume Interrupt Enable Position */ #define DEVIER_EORSMES (_U_(0x1) << DEVIER_EORSMES_Pos) /**< (DEVIER) End of Resume Interrupt Enable Mask */ #define DEVIER_UPRSMES_Pos 6 /**< (DEVIER) Upstream Resume Interrupt Enable Position */ #define DEVIER_UPRSMES (_U_(0x1) << DEVIER_UPRSMES_Pos) /**< (DEVIER) Upstream Resume Interrupt Enable Mask */ #define DEVIER_PEP_0_Pos 12 /**< (DEVIER) Endpoint 0 Interrupt Enable Position */ #define DEVIER_PEP_0 (_U_(0x1) << DEVIER_PEP_0_Pos) /**< (DEVIER) Endpoint 0 Interrupt Enable Mask */ #define DEVIER_PEP_1_Pos 13 /**< (DEVIER) Endpoint 1 Interrupt Enable Position */ #define DEVIER_PEP_1 (_U_(0x1) << DEVIER_PEP_1_Pos) /**< (DEVIER) Endpoint 1 Interrupt Enable Mask */ #define DEVIER_PEP_2_Pos 14 /**< (DEVIER) Endpoint 2 Interrupt Enable Position */ #define DEVIER_PEP_2 (_U_(0x1) << DEVIER_PEP_2_Pos) /**< (DEVIER) Endpoint 2 Interrupt Enable Mask */ #define DEVIER_PEP_3_Pos 15 /**< (DEVIER) Endpoint 3 Interrupt Enable Position */ #define DEVIER_PEP_3 (_U_(0x1) << DEVIER_PEP_3_Pos) /**< (DEVIER) Endpoint 3 Interrupt Enable Mask */ #define DEVIER_PEP_4_Pos 16 /**< (DEVIER) Endpoint 4 Interrupt Enable Position */ #define DEVIER_PEP_4 (_U_(0x1) << DEVIER_PEP_4_Pos) /**< (DEVIER) Endpoint 4 Interrupt Enable Mask */ #define DEVIER_PEP_5_Pos 17 /**< (DEVIER) Endpoint 5 Interrupt Enable Position */ #define DEVIER_PEP_5 (_U_(0x1) << DEVIER_PEP_5_Pos) /**< (DEVIER) Endpoint 5 Interrupt Enable Mask */ #define DEVIER_PEP_6_Pos 18 /**< (DEVIER) Endpoint 6 Interrupt Enable Position */ #define DEVIER_PEP_6 (_U_(0x1) << DEVIER_PEP_6_Pos) /**< (DEVIER) Endpoint 6 Interrupt Enable Mask */ #define DEVIER_PEP_7_Pos 19 /**< (DEVIER) Endpoint 7 Interrupt Enable Position */ #define DEVIER_PEP_7 (_U_(0x1) << DEVIER_PEP_7_Pos) /**< (DEVIER) Endpoint 7 Interrupt Enable Mask */ #define DEVIER_PEP_8_Pos 20 /**< (DEVIER) Endpoint 8 Interrupt Enable Position */ #define DEVIER_PEP_8 (_U_(0x1) << DEVIER_PEP_8_Pos) /**< (DEVIER) Endpoint 8 Interrupt Enable Mask */ #define DEVIER_PEP_9_Pos 21 /**< (DEVIER) Endpoint 9 Interrupt Enable Position */ #define DEVIER_PEP_9 (_U_(0x1) << DEVIER_PEP_9_Pos) /**< (DEVIER) Endpoint 9 Interrupt Enable Mask */ #define DEVIER_DMA_1_Pos 25 /**< (DEVIER) DMA Channel 1 Interrupt Enable Position */ #define DEVIER_DMA_1 (_U_(0x1) << DEVIER_DMA_1_Pos) /**< (DEVIER) DMA Channel 1 Interrupt Enable Mask */ #define DEVIER_DMA_2_Pos 26 /**< (DEVIER) DMA Channel 2 Interrupt Enable Position */ #define DEVIER_DMA_2 (_U_(0x1) << DEVIER_DMA_2_Pos) /**< (DEVIER) DMA Channel 2 Interrupt Enable Mask */ #define DEVIER_DMA_3_Pos 27 /**< (DEVIER) DMA Channel 3 Interrupt Enable Position */ #define DEVIER_DMA_3 (_U_(0x1) << DEVIER_DMA_3_Pos) /**< (DEVIER) DMA Channel 3 Interrupt Enable Mask */ #define DEVIER_DMA_4_Pos 28 /**< (DEVIER) DMA Channel 4 Interrupt Enable Position */ #define DEVIER_DMA_4 (_U_(0x1) << DEVIER_DMA_4_Pos) /**< (DEVIER) DMA Channel 4 Interrupt Enable Mask */ #define DEVIER_DMA_5_Pos 29 /**< (DEVIER) DMA Channel 5 Interrupt Enable Position */ #define DEVIER_DMA_5 (_U_(0x1) << DEVIER_DMA_5_Pos) /**< (DEVIER) DMA Channel 5 Interrupt Enable Mask */ #define DEVIER_DMA_6_Pos 30 /**< (DEVIER) DMA Channel 6 Interrupt Enable Position */ #define DEVIER_DMA_6 (_U_(0x1) << DEVIER_DMA_6_Pos) /**< (DEVIER) DMA Channel 6 Interrupt Enable Mask */ #define DEVIER_DMA_7_Pos 31 /**< (DEVIER) DMA Channel 7 Interrupt Enable Position */ #define DEVIER_DMA_7 (_U_(0x1) << DEVIER_DMA_7_Pos) /**< (DEVIER) DMA Channel 7 Interrupt Enable Mask */ #define DEVIER_Msk _U_(0xFE3FF07F) /**< (DEVIER) Register Mask */ #define DEVIER_PEP__Pos 12 /**< (DEVIER Position) Endpoint x Interrupt Enable */ #define DEVIER_PEP_ (_U_(0x3FF) << DEVIER_PEP__Pos) /**< (DEVIER Mask) PEP_ */ #define DEVIER_DMA__Pos 25 /**< (DEVIER Position) DMA Channel 7 Interrupt Enable */ #define DEVIER_DMA_ (_U_(0x7F) << DEVIER_DMA__Pos) /**< (DEVIER Mask) DMA_ */ /* -------- DEVEPT : (USBHS Offset: 0x1c) (R/W 32) Device Endpoint Register -------- */ #define DEVEPT_OFFSET (0x1C) /**< (DEVEPT) Device Endpoint Register Offset */ #define DEVEPT_EPEN0_Pos 0 /**< (DEVEPT) Endpoint 0 Enable Position */ #define DEVEPT_EPEN0 (_U_(0x1) << DEVEPT_EPEN0_Pos) /**< (DEVEPT) Endpoint 0 Enable Mask */ #define DEVEPT_EPEN1_Pos 1 /**< (DEVEPT) Endpoint 1 Enable Position */ #define DEVEPT_EPEN1 (_U_(0x1) << DEVEPT_EPEN1_Pos) /**< (DEVEPT) Endpoint 1 Enable Mask */ #define DEVEPT_EPEN2_Pos 2 /**< (DEVEPT) Endpoint 2 Enable Position */ #define DEVEPT_EPEN2 (_U_(0x1) << DEVEPT_EPEN2_Pos) /**< (DEVEPT) Endpoint 2 Enable Mask */ #define DEVEPT_EPEN3_Pos 3 /**< (DEVEPT) Endpoint 3 Enable Position */ #define DEVEPT_EPEN3 (_U_(0x1) << DEVEPT_EPEN3_Pos) /**< (DEVEPT) Endpoint 3 Enable Mask */ #define DEVEPT_EPEN4_Pos 4 /**< (DEVEPT) Endpoint 4 Enable Position */ #define DEVEPT_EPEN4 (_U_(0x1) << DEVEPT_EPEN4_Pos) /**< (DEVEPT) Endpoint 4 Enable Mask */ #define DEVEPT_EPEN5_Pos 5 /**< (DEVEPT) Endpoint 5 Enable Position */ #define DEVEPT_EPEN5 (_U_(0x1) << DEVEPT_EPEN5_Pos) /**< (DEVEPT) Endpoint 5 Enable Mask */ #define DEVEPT_EPEN6_Pos 6 /**< (DEVEPT) Endpoint 6 Enable Position */ #define DEVEPT_EPEN6 (_U_(0x1) << DEVEPT_EPEN6_Pos) /**< (DEVEPT) Endpoint 6 Enable Mask */ #define DEVEPT_EPEN7_Pos 7 /**< (DEVEPT) Endpoint 7 Enable Position */ #define DEVEPT_EPEN7 (_U_(0x1) << DEVEPT_EPEN7_Pos) /**< (DEVEPT) Endpoint 7 Enable Mask */ #define DEVEPT_EPEN8_Pos 8 /**< (DEVEPT) Endpoint 8 Enable Position */ #define DEVEPT_EPEN8 (_U_(0x1) << DEVEPT_EPEN8_Pos) /**< (DEVEPT) Endpoint 8 Enable Mask */ #define DEVEPT_EPEN9_Pos 9 /**< (DEVEPT) Endpoint 9 Enable Position */ #define DEVEPT_EPEN9 (_U_(0x1) << DEVEPT_EPEN9_Pos) /**< (DEVEPT) Endpoint 9 Enable Mask */ #define DEVEPT_EPRST0_Pos 16 /**< (DEVEPT) Endpoint 0 Reset Position */ #define DEVEPT_EPRST0 (_U_(0x1) << DEVEPT_EPRST0_Pos) /**< (DEVEPT) Endpoint 0 Reset Mask */ #define DEVEPT_EPRST1_Pos 17 /**< (DEVEPT) Endpoint 1 Reset Position */ #define DEVEPT_EPRST1 (_U_(0x1) << DEVEPT_EPRST1_Pos) /**< (DEVEPT) Endpoint 1 Reset Mask */ #define DEVEPT_EPRST2_Pos 18 /**< (DEVEPT) Endpoint 2 Reset Position */ #define DEVEPT_EPRST2 (_U_(0x1) << DEVEPT_EPRST2_Pos) /**< (DEVEPT) Endpoint 2 Reset Mask */ #define DEVEPT_EPRST3_Pos 19 /**< (DEVEPT) Endpoint 3 Reset Position */ #define DEVEPT_EPRST3 (_U_(0x1) << DEVEPT_EPRST3_Pos) /**< (DEVEPT) Endpoint 3 Reset Mask */ #define DEVEPT_EPRST4_Pos 20 /**< (DEVEPT) Endpoint 4 Reset Position */ #define DEVEPT_EPRST4 (_U_(0x1) << DEVEPT_EPRST4_Pos) /**< (DEVEPT) Endpoint 4 Reset Mask */ #define DEVEPT_EPRST5_Pos 21 /**< (DEVEPT) Endpoint 5 Reset Position */ #define DEVEPT_EPRST5 (_U_(0x1) << DEVEPT_EPRST5_Pos) /**< (DEVEPT) Endpoint 5 Reset Mask */ #define DEVEPT_EPRST6_Pos 22 /**< (DEVEPT) Endpoint 6 Reset Position */ #define DEVEPT_EPRST6 (_U_(0x1) << DEVEPT_EPRST6_Pos) /**< (DEVEPT) Endpoint 6 Reset Mask */ #define DEVEPT_EPRST7_Pos 23 /**< (DEVEPT) Endpoint 7 Reset Position */ #define DEVEPT_EPRST7 (_U_(0x1) << DEVEPT_EPRST7_Pos) /**< (DEVEPT) Endpoint 7 Reset Mask */ #define DEVEPT_EPRST8_Pos 24 /**< (DEVEPT) Endpoint 8 Reset Position */ #define DEVEPT_EPRST8 (_U_(0x1) << DEVEPT_EPRST8_Pos) /**< (DEVEPT) Endpoint 8 Reset Mask */ #define DEVEPT_EPRST9_Pos 25 /**< (DEVEPT) Endpoint 9 Reset Position */ #define DEVEPT_EPRST9 (_U_(0x1) << DEVEPT_EPRST9_Pos) /**< (DEVEPT) Endpoint 9 Reset Mask */ #define DEVEPT_Msk _U_(0x3FF03FF) /**< (DEVEPT) Register Mask */ #define DEVEPT_EPEN_Pos 0 /**< (DEVEPT Position) Endpoint x Enable */ #define DEVEPT_EPEN (_U_(0x3FF) << DEVEPT_EPEN_Pos) /**< (DEVEPT Mask) EPEN */ #define DEVEPT_EPRST_Pos 16 /**< (DEVEPT Position) Endpoint 9 Reset */ #define DEVEPT_EPRST (_U_(0x3FF) << DEVEPT_EPRST_Pos) /**< (DEVEPT Mask) EPRST */ /* -------- DEVFNUM : (USBHS Offset: 0x20) (R/ 32) Device Frame Number Register -------- */ #define DEVFNUM_OFFSET (0x20) /**< (DEVFNUM) Device Frame Number Register Offset */ #define DEVFNUM_MFNUM_Pos 0 /**< (DEVFNUM) Micro Frame Number Position */ #define DEVFNUM_MFNUM (_U_(0x7) << DEVFNUM_MFNUM_Pos) /**< (DEVFNUM) Micro Frame Number Mask */ #define DEVFNUM_FNUM_Pos 3 /**< (DEVFNUM) Frame Number Position */ #define DEVFNUM_FNUM (_U_(0x7FF) << DEVFNUM_FNUM_Pos) /**< (DEVFNUM) Frame Number Mask */ #define DEVFNUM_FNCERR_Pos 15 /**< (DEVFNUM) Frame Number CRC Error Position */ #define DEVFNUM_FNCERR (_U_(0x1) << DEVFNUM_FNCERR_Pos) /**< (DEVFNUM) Frame Number CRC Error Mask */ #define DEVFNUM_Msk _U_(0xBFFF) /**< (DEVFNUM) Register Mask */ /* -------- DEVEPTCFG : (USBHS Offset: 0x100) (R/W 32) Device Endpoint Configuration Register -------- */ #define DEVEPTCFG_OFFSET (0x100) /**< (DEVEPTCFG) Device Endpoint Configuration Register Offset */ #define DEVEPTCFG_ALLOC_Pos 1 /**< (DEVEPTCFG) Endpoint Memory Allocate Position */ #define DEVEPTCFG_ALLOC (_U_(0x1) << DEVEPTCFG_ALLOC_Pos) /**< (DEVEPTCFG) Endpoint Memory Allocate Mask */ #define DEVEPTCFG_EPBK_Pos 2 /**< (DEVEPTCFG) Endpoint Banks Position */ #define DEVEPTCFG_EPBK (_U_(0x3) << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Endpoint Banks Mask */ #define DEVEPTCFG_EPBK_1_BANK_Val _U_(0x0) /**< (DEVEPTCFG) Single-bank endpoint */ #define DEVEPTCFG_EPBK_2_BANK_Val _U_(0x1) /**< (DEVEPTCFG) Double-bank endpoint */ #define DEVEPTCFG_EPBK_3_BANK_Val _U_(0x2) /**< (DEVEPTCFG) Triple-bank endpoint */ #define DEVEPTCFG_EPBK_1_BANK (DEVEPTCFG_EPBK_1_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Single-bank endpoint Position */ #define DEVEPTCFG_EPBK_2_BANK (DEVEPTCFG_EPBK_2_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Double-bank endpoint Position */ #define DEVEPTCFG_EPBK_3_BANK (DEVEPTCFG_EPBK_3_BANK_Val << DEVEPTCFG_EPBK_Pos) /**< (DEVEPTCFG) Triple-bank endpoint Position */ #define DEVEPTCFG_EPSIZE_Pos 4 /**< (DEVEPTCFG) Endpoint Size Position */ #define DEVEPTCFG_EPSIZE (_U_(0x7) << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) Endpoint Size Mask */ #define DEVEPTCFG_EPSIZE_8_BYTE_Val _U_(0x0) /**< (DEVEPTCFG) 8 bytes */ #define DEVEPTCFG_EPSIZE_16_BYTE_Val _U_(0x1) /**< (DEVEPTCFG) 16 bytes */ #define DEVEPTCFG_EPSIZE_32_BYTE_Val _U_(0x2) /**< (DEVEPTCFG) 32 bytes */ #define DEVEPTCFG_EPSIZE_64_BYTE_Val _U_(0x3) /**< (DEVEPTCFG) 64 bytes */ #define DEVEPTCFG_EPSIZE_128_BYTE_Val _U_(0x4) /**< (DEVEPTCFG) 128 bytes */ #define DEVEPTCFG_EPSIZE_256_BYTE_Val _U_(0x5) /**< (DEVEPTCFG) 256 bytes */ #define DEVEPTCFG_EPSIZE_512_BYTE_Val _U_(0x6) /**< (DEVEPTCFG) 512 bytes */ #define DEVEPTCFG_EPSIZE_1024_BYTE_Val _U_(0x7) /**< (DEVEPTCFG) 1024 bytes */ #define DEVEPTCFG_EPSIZE_8_BYTE (DEVEPTCFG_EPSIZE_8_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 8 bytes Position */ #define DEVEPTCFG_EPSIZE_16_BYTE (DEVEPTCFG_EPSIZE_16_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 16 bytes Position */ #define DEVEPTCFG_EPSIZE_32_BYTE (DEVEPTCFG_EPSIZE_32_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 32 bytes Position */ #define DEVEPTCFG_EPSIZE_64_BYTE (DEVEPTCFG_EPSIZE_64_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 64 bytes Position */ #define DEVEPTCFG_EPSIZE_128_BYTE (DEVEPTCFG_EPSIZE_128_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 128 bytes Position */ #define DEVEPTCFG_EPSIZE_256_BYTE (DEVEPTCFG_EPSIZE_256_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 256 bytes Position */ #define DEVEPTCFG_EPSIZE_512_BYTE (DEVEPTCFG_EPSIZE_512_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 512 bytes Position */ #define DEVEPTCFG_EPSIZE_1024_BYTE (DEVEPTCFG_EPSIZE_1024_BYTE_Val << DEVEPTCFG_EPSIZE_Pos) /**< (DEVEPTCFG) 1024 bytes Position */ #define DEVEPTCFG_EPDIR_Pos 8 /**< (DEVEPTCFG) Endpoint Direction Position */ #define DEVEPTCFG_EPDIR (_U_(0x1) << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) Endpoint Direction Mask */ #define DEVEPTCFG_EPDIR_OUT_Val _U_(0x0) /**< (DEVEPTCFG) The endpoint direction is OUT. */ #define DEVEPTCFG_EPDIR_IN_Val _U_(0x1) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). */ #define DEVEPTCFG_EPDIR_OUT (DEVEPTCFG_EPDIR_OUT_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is OUT. Position */ #define DEVEPTCFG_EPDIR_IN (DEVEPTCFG_EPDIR_IN_Val << DEVEPTCFG_EPDIR_Pos) /**< (DEVEPTCFG) The endpoint direction is IN (nor for control endpoints). Position */ #define DEVEPTCFG_AUTOSW_Pos 9 /**< (DEVEPTCFG) Automatic Switch Position */ #define DEVEPTCFG_AUTOSW (_U_(0x1) << DEVEPTCFG_AUTOSW_Pos) /**< (DEVEPTCFG) Automatic Switch Mask */ #define DEVEPTCFG_EPTYPE_Pos 11 /**< (DEVEPTCFG) Endpoint Type Position */ #define DEVEPTCFG_EPTYPE (_U_(0x3) << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Endpoint Type Mask */ #define DEVEPTCFG_EPTYPE_CTRL_Val _U_(0x0) /**< (DEVEPTCFG) Control */ #define DEVEPTCFG_EPTYPE_ISO_Val _U_(0x1) /**< (DEVEPTCFG) Isochronous */ #define DEVEPTCFG_EPTYPE_BLK_Val _U_(0x2) /**< (DEVEPTCFG) Bulk */ #define DEVEPTCFG_EPTYPE_INTRPT_Val _U_(0x3) /**< (DEVEPTCFG) Interrupt */ #define DEVEPTCFG_EPTYPE_CTRL (DEVEPTCFG_EPTYPE_CTRL_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Control Position */ #define DEVEPTCFG_EPTYPE_ISO (DEVEPTCFG_EPTYPE_ISO_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Isochronous Position */ #define DEVEPTCFG_EPTYPE_BLK (DEVEPTCFG_EPTYPE_BLK_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Bulk Position */ #define DEVEPTCFG_EPTYPE_INTRPT (DEVEPTCFG_EPTYPE_INTRPT_Val << DEVEPTCFG_EPTYPE_Pos) /**< (DEVEPTCFG) Interrupt Position */ #define DEVEPTCFG_NBTRANS_Pos 13 /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Position */ #define DEVEPTCFG_NBTRANS (_U_(0x3) << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Number of transactions per microframe for isochronous endpoint Mask */ #define DEVEPTCFG_NBTRANS_0_TRANS_Val _U_(0x0) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. */ #define DEVEPTCFG_NBTRANS_1_TRANS_Val _U_(0x1) /**< (DEVEPTCFG) Default value: one transaction per microframe. */ #define DEVEPTCFG_NBTRANS_2_TRANS_Val _U_(0x2) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. */ #define DEVEPTCFG_NBTRANS_3_TRANS_Val _U_(0x3) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. */ #define DEVEPTCFG_NBTRANS_0_TRANS (DEVEPTCFG_NBTRANS_0_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Reserved to endpoint that does not have the high-bandwidth isochronous capability. Position */ #define DEVEPTCFG_NBTRANS_1_TRANS (DEVEPTCFG_NBTRANS_1_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Default value: one transaction per microframe. Position */ #define DEVEPTCFG_NBTRANS_2_TRANS (DEVEPTCFG_NBTRANS_2_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Two transactions per microframe. This endpoint should be configured as double-bank. Position */ #define DEVEPTCFG_NBTRANS_3_TRANS (DEVEPTCFG_NBTRANS_3_TRANS_Val << DEVEPTCFG_NBTRANS_Pos) /**< (DEVEPTCFG) Three transactions per microframe. This endpoint should be configured as triple-bank. Position */ #define DEVEPTCFG_Msk _U_(0x7B7E) /**< (DEVEPTCFG) Register Mask */ /* -------- DEVEPTISR : (USBHS Offset: 0x130) (R/ 32) Device Endpoint Interrupt Status Register -------- */ #define DEVEPTISR_OFFSET (0x130) /**< (DEVEPTISR) Device Endpoint Interrupt Status Register Offset */ #define DEVEPTISR_TXINI_Pos 0 /**< (DEVEPTISR) Transmitted IN Data Interrupt Position */ #define DEVEPTISR_TXINI (_U_(0x1) << DEVEPTISR_TXINI_Pos) /**< (DEVEPTISR) Transmitted IN Data Interrupt Mask */ #define DEVEPTISR_RXOUTI_Pos 1 /**< (DEVEPTISR) Received OUT Data Interrupt Position */ #define DEVEPTISR_RXOUTI (_U_(0x1) << DEVEPTISR_RXOUTI_Pos) /**< (DEVEPTISR) Received OUT Data Interrupt Mask */ #define DEVEPTISR_OVERFI_Pos 5 /**< (DEVEPTISR) Overflow Interrupt Position */ #define DEVEPTISR_OVERFI (_U_(0x1) << DEVEPTISR_OVERFI_Pos) /**< (DEVEPTISR) Overflow Interrupt Mask */ #define DEVEPTISR_SHORTPACKET_Pos 7 /**< (DEVEPTISR) Short Packet Interrupt Position */ #define DEVEPTISR_SHORTPACKET (_U_(0x1) << DEVEPTISR_SHORTPACKET_Pos) /**< (DEVEPTISR) Short Packet Interrupt Mask */ #define DEVEPTISR_DTSEQ_Pos 8 /**< (DEVEPTISR) Data Toggle Sequence Position */ #define DEVEPTISR_DTSEQ (_U_(0x3) << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data Toggle Sequence Mask */ #define DEVEPTISR_DTSEQ_DATA0_Val _U_(0x0) /**< (DEVEPTISR) Data0 toggle sequence */ #define DEVEPTISR_DTSEQ_DATA1_Val _U_(0x1) /**< (DEVEPTISR) Data1 toggle sequence */ #define DEVEPTISR_DTSEQ_DATA2_Val _U_(0x2) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ #define DEVEPTISR_DTSEQ_MDATA_Val _U_(0x3) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint */ #define DEVEPTISR_DTSEQ_DATA0 (DEVEPTISR_DTSEQ_DATA0_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data0 toggle sequence Position */ #define DEVEPTISR_DTSEQ_DATA1 (DEVEPTISR_DTSEQ_DATA1_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Data1 toggle sequence Position */ #define DEVEPTISR_DTSEQ_DATA2 (DEVEPTISR_DTSEQ_DATA2_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ #define DEVEPTISR_DTSEQ_MDATA (DEVEPTISR_DTSEQ_MDATA_Val << DEVEPTISR_DTSEQ_Pos) /**< (DEVEPTISR) Reserved for high-bandwidth isochronous endpoint Position */ #define DEVEPTISR_NBUSYBK_Pos 12 /**< (DEVEPTISR) Number of Busy Banks Position */ #define DEVEPTISR_NBUSYBK (_U_(0x3) << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) Number of Busy Banks Mask */ #define DEVEPTISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (DEVEPTISR) 0 busy bank (all banks free) */ #define DEVEPTISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (DEVEPTISR) 1 busy bank */ #define DEVEPTISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (DEVEPTISR) 2 busy banks */ #define DEVEPTISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (DEVEPTISR) 3 busy banks */ #define DEVEPTISR_NBUSYBK_0_BUSY (DEVEPTISR_NBUSYBK_0_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 0 busy bank (all banks free) Position */ #define DEVEPTISR_NBUSYBK_1_BUSY (DEVEPTISR_NBUSYBK_1_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 1 busy bank Position */ #define DEVEPTISR_NBUSYBK_2_BUSY (DEVEPTISR_NBUSYBK_2_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 2 busy banks Position */ #define DEVEPTISR_NBUSYBK_3_BUSY (DEVEPTISR_NBUSYBK_3_BUSY_Val << DEVEPTISR_NBUSYBK_Pos) /**< (DEVEPTISR) 3 busy banks Position */ #define DEVEPTISR_CURRBK_Pos 14 /**< (DEVEPTISR) Current Bank Position */ #define DEVEPTISR_CURRBK (_U_(0x3) << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current Bank Mask */ #define DEVEPTISR_CURRBK_BANK0_Val _U_(0x0) /**< (DEVEPTISR) Current bank is bank0 */ #define DEVEPTISR_CURRBK_BANK1_Val _U_(0x1) /**< (DEVEPTISR) Current bank is bank1 */ #define DEVEPTISR_CURRBK_BANK2_Val _U_(0x2) /**< (DEVEPTISR) Current bank is bank2 */ #define DEVEPTISR_CURRBK_BANK0 (DEVEPTISR_CURRBK_BANK0_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank0 Position */ #define DEVEPTISR_CURRBK_BANK1 (DEVEPTISR_CURRBK_BANK1_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank1 Position */ #define DEVEPTISR_CURRBK_BANK2 (DEVEPTISR_CURRBK_BANK2_Val << DEVEPTISR_CURRBK_Pos) /**< (DEVEPTISR) Current bank is bank2 Position */ #define DEVEPTISR_RWALL_Pos 16 /**< (DEVEPTISR) Read/Write Allowed Position */ #define DEVEPTISR_RWALL (_U_(0x1) << DEVEPTISR_RWALL_Pos) /**< (DEVEPTISR) Read/Write Allowed Mask */ #define DEVEPTISR_CFGOK_Pos 18 /**< (DEVEPTISR) Configuration OK Status Position */ #define DEVEPTISR_CFGOK (_U_(0x1) << DEVEPTISR_CFGOK_Pos) /**< (DEVEPTISR) Configuration OK Status Mask */ #define DEVEPTISR_BYCT_Pos 20 /**< (DEVEPTISR) Byte Count Position */ #define DEVEPTISR_BYCT (_U_(0x7FF) << DEVEPTISR_BYCT_Pos) /**< (DEVEPTISR) Byte Count Mask */ #define DEVEPTISR_Msk _U_(0x7FF5F3A3) /**< (DEVEPTISR) Register Mask */ /* CTRL mode */ #define DEVEPTISR_CTRL_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ #define DEVEPTISR_CTRL_RXSTPI (_U_(0x1) << DEVEPTISR_CTRL_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ #define DEVEPTISR_CTRL_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ #define DEVEPTISR_CTRL_NAKOUTI (_U_(0x1) << DEVEPTISR_CTRL_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ #define DEVEPTISR_CTRL_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ #define DEVEPTISR_CTRL_NAKINI (_U_(0x1) << DEVEPTISR_CTRL_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ #define DEVEPTISR_CTRL_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ #define DEVEPTISR_CTRL_STALLEDI (_U_(0x1) << DEVEPTISR_CTRL_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ #define DEVEPTISR_CTRL_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ #define DEVEPTISR_CTRL_CTRLDIR (_U_(0x1) << DEVEPTISR_CTRL_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ #define DEVEPTISR_CTRL_Msk _U_(0x2005C) /**< (DEVEPTISR_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTISR_ISO_UNDERFI_Pos 2 /**< (DEVEPTISR) Underflow Interrupt Position */ #define DEVEPTISR_ISO_UNDERFI (_U_(0x1) << DEVEPTISR_ISO_UNDERFI_Pos) /**< (DEVEPTISR) Underflow Interrupt Mask */ #define DEVEPTISR_ISO_HBISOINERRI_Pos 3 /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ #define DEVEPTISR_ISO_HBISOINERRI (_U_(0x1) << DEVEPTISR_ISO_HBISOINERRI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ #define DEVEPTISR_ISO_HBISOFLUSHI_Pos 4 /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Position */ #define DEVEPTISR_ISO_HBISOFLUSHI (_U_(0x1) << DEVEPTISR_ISO_HBISOFLUSHI_Pos) /**< (DEVEPTISR) High Bandwidth Isochronous IN Flush Interrupt Mask */ #define DEVEPTISR_ISO_CRCERRI_Pos 6 /**< (DEVEPTISR) CRC Error Interrupt Position */ #define DEVEPTISR_ISO_CRCERRI (_U_(0x1) << DEVEPTISR_ISO_CRCERRI_Pos) /**< (DEVEPTISR) CRC Error Interrupt Mask */ #define DEVEPTISR_ISO_ERRORTRANS_Pos 10 /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Position */ #define DEVEPTISR_ISO_ERRORTRANS (_U_(0x1) << DEVEPTISR_ISO_ERRORTRANS_Pos) /**< (DEVEPTISR) High-bandwidth Isochronous OUT Endpoint Transaction Error Interrupt Mask */ #define DEVEPTISR_ISO_Msk _U_(0x45C) /**< (DEVEPTISR_ISO) Register Mask */ /* BLK mode */ #define DEVEPTISR_BLK_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ #define DEVEPTISR_BLK_RXSTPI (_U_(0x1) << DEVEPTISR_BLK_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ #define DEVEPTISR_BLK_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ #define DEVEPTISR_BLK_NAKOUTI (_U_(0x1) << DEVEPTISR_BLK_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ #define DEVEPTISR_BLK_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ #define DEVEPTISR_BLK_NAKINI (_U_(0x1) << DEVEPTISR_BLK_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ #define DEVEPTISR_BLK_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ #define DEVEPTISR_BLK_STALLEDI (_U_(0x1) << DEVEPTISR_BLK_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ #define DEVEPTISR_BLK_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ #define DEVEPTISR_BLK_CTRLDIR (_U_(0x1) << DEVEPTISR_BLK_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ #define DEVEPTISR_BLK_Msk _U_(0x2005C) /**< (DEVEPTISR_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTISR_INTRPT_RXSTPI_Pos 2 /**< (DEVEPTISR) Received SETUP Interrupt Position */ #define DEVEPTISR_INTRPT_RXSTPI (_U_(0x1) << DEVEPTISR_INTRPT_RXSTPI_Pos) /**< (DEVEPTISR) Received SETUP Interrupt Mask */ #define DEVEPTISR_INTRPT_NAKOUTI_Pos 3 /**< (DEVEPTISR) NAKed OUT Interrupt Position */ #define DEVEPTISR_INTRPT_NAKOUTI (_U_(0x1) << DEVEPTISR_INTRPT_NAKOUTI_Pos) /**< (DEVEPTISR) NAKed OUT Interrupt Mask */ #define DEVEPTISR_INTRPT_NAKINI_Pos 4 /**< (DEVEPTISR) NAKed IN Interrupt Position */ #define DEVEPTISR_INTRPT_NAKINI (_U_(0x1) << DEVEPTISR_INTRPT_NAKINI_Pos) /**< (DEVEPTISR) NAKed IN Interrupt Mask */ #define DEVEPTISR_INTRPT_STALLEDI_Pos 6 /**< (DEVEPTISR) STALLed Interrupt Position */ #define DEVEPTISR_INTRPT_STALLEDI (_U_(0x1) << DEVEPTISR_INTRPT_STALLEDI_Pos) /**< (DEVEPTISR) STALLed Interrupt Mask */ #define DEVEPTISR_INTRPT_CTRLDIR_Pos 17 /**< (DEVEPTISR) Control Direction Position */ #define DEVEPTISR_INTRPT_CTRLDIR (_U_(0x1) << DEVEPTISR_INTRPT_CTRLDIR_Pos) /**< (DEVEPTISR) Control Direction Mask */ #define DEVEPTISR_INTRPT_Msk _U_(0x2005C) /**< (DEVEPTISR_INTRPT) Register Mask */ /* -------- DEVEPTICR : (USBHS Offset: 0x160) (/W 32) Device Endpoint Interrupt Clear Register -------- */ #define DEVEPTICR_OFFSET (0x160) /**< (DEVEPTICR) Device Endpoint Interrupt Clear Register Offset */ #define DEVEPTICR_TXINIC_Pos 0 /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Position */ #define DEVEPTICR_TXINIC (_U_(0x1) << DEVEPTICR_TXINIC_Pos) /**< (DEVEPTICR) Transmitted IN Data Interrupt Clear Mask */ #define DEVEPTICR_RXOUTIC_Pos 1 /**< (DEVEPTICR) Received OUT Data Interrupt Clear Position */ #define DEVEPTICR_RXOUTIC (_U_(0x1) << DEVEPTICR_RXOUTIC_Pos) /**< (DEVEPTICR) Received OUT Data Interrupt Clear Mask */ #define DEVEPTICR_OVERFIC_Pos 5 /**< (DEVEPTICR) Overflow Interrupt Clear Position */ #define DEVEPTICR_OVERFIC (_U_(0x1) << DEVEPTICR_OVERFIC_Pos) /**< (DEVEPTICR) Overflow Interrupt Clear Mask */ #define DEVEPTICR_SHORTPACKETC_Pos 7 /**< (DEVEPTICR) Short Packet Interrupt Clear Position */ #define DEVEPTICR_SHORTPACKETC (_U_(0x1) << DEVEPTICR_SHORTPACKETC_Pos) /**< (DEVEPTICR) Short Packet Interrupt Clear Mask */ #define DEVEPTICR_Msk _U_(0xA3) /**< (DEVEPTICR) Register Mask */ /* CTRL mode */ #define DEVEPTICR_CTRL_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ #define DEVEPTICR_CTRL_RXSTPIC (_U_(0x1) << DEVEPTICR_CTRL_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ #define DEVEPTICR_CTRL_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ #define DEVEPTICR_CTRL_NAKOUTIC (_U_(0x1) << DEVEPTICR_CTRL_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTICR_CTRL_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ #define DEVEPTICR_CTRL_NAKINIC (_U_(0x1) << DEVEPTICR_CTRL_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ #define DEVEPTICR_CTRL_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ #define DEVEPTICR_CTRL_STALLEDIC (_U_(0x1) << DEVEPTICR_CTRL_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ #define DEVEPTICR_CTRL_Msk _U_(0x5C) /**< (DEVEPTICR_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTICR_ISO_UNDERFIC_Pos 2 /**< (DEVEPTICR) Underflow Interrupt Clear Position */ #define DEVEPTICR_ISO_UNDERFIC (_U_(0x1) << DEVEPTICR_ISO_UNDERFIC_Pos) /**< (DEVEPTICR) Underflow Interrupt Clear Mask */ #define DEVEPTICR_ISO_HBISOINERRIC_Pos 3 /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ #define DEVEPTICR_ISO_HBISOINERRIC (_U_(0x1) << DEVEPTICR_ISO_HBISOINERRIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ #define DEVEPTICR_ISO_HBISOFLUSHIC_Pos 4 /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ #define DEVEPTICR_ISO_HBISOFLUSHIC (_U_(0x1) << DEVEPTICR_ISO_HBISOFLUSHIC_Pos) /**< (DEVEPTICR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ #define DEVEPTICR_ISO_CRCERRIC_Pos 6 /**< (DEVEPTICR) CRC Error Interrupt Clear Position */ #define DEVEPTICR_ISO_CRCERRIC (_U_(0x1) << DEVEPTICR_ISO_CRCERRIC_Pos) /**< (DEVEPTICR) CRC Error Interrupt Clear Mask */ #define DEVEPTICR_ISO_Msk _U_(0x5C) /**< (DEVEPTICR_ISO) Register Mask */ /* BLK mode */ #define DEVEPTICR_BLK_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ #define DEVEPTICR_BLK_RXSTPIC (_U_(0x1) << DEVEPTICR_BLK_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ #define DEVEPTICR_BLK_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ #define DEVEPTICR_BLK_NAKOUTIC (_U_(0x1) << DEVEPTICR_BLK_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTICR_BLK_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ #define DEVEPTICR_BLK_NAKINIC (_U_(0x1) << DEVEPTICR_BLK_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ #define DEVEPTICR_BLK_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ #define DEVEPTICR_BLK_STALLEDIC (_U_(0x1) << DEVEPTICR_BLK_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ #define DEVEPTICR_BLK_Msk _U_(0x5C) /**< (DEVEPTICR_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTICR_INTRPT_RXSTPIC_Pos 2 /**< (DEVEPTICR) Received SETUP Interrupt Clear Position */ #define DEVEPTICR_INTRPT_RXSTPIC (_U_(0x1) << DEVEPTICR_INTRPT_RXSTPIC_Pos) /**< (DEVEPTICR) Received SETUP Interrupt Clear Mask */ #define DEVEPTICR_INTRPT_NAKOUTIC_Pos 3 /**< (DEVEPTICR) NAKed OUT Interrupt Clear Position */ #define DEVEPTICR_INTRPT_NAKOUTIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKOUTIC_Pos) /**< (DEVEPTICR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTICR_INTRPT_NAKINIC_Pos 4 /**< (DEVEPTICR) NAKed IN Interrupt Clear Position */ #define DEVEPTICR_INTRPT_NAKINIC (_U_(0x1) << DEVEPTICR_INTRPT_NAKINIC_Pos) /**< (DEVEPTICR) NAKed IN Interrupt Clear Mask */ #define DEVEPTICR_INTRPT_STALLEDIC_Pos 6 /**< (DEVEPTICR) STALLed Interrupt Clear Position */ #define DEVEPTICR_INTRPT_STALLEDIC (_U_(0x1) << DEVEPTICR_INTRPT_STALLEDIC_Pos) /**< (DEVEPTICR) STALLed Interrupt Clear Mask */ #define DEVEPTICR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTICR_INTRPT) Register Mask */ /* -------- DEVEPTIFR : (USBHS Offset: 0x190) (/W 32) Device Endpoint Interrupt Set Register -------- */ #define DEVEPTIFR_OFFSET (0x190) /**< (DEVEPTIFR) Device Endpoint Interrupt Set Register Offset */ #define DEVEPTIFR_TXINIS_Pos 0 /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Position */ #define DEVEPTIFR_TXINIS (_U_(0x1) << DEVEPTIFR_TXINIS_Pos) /**< (DEVEPTIFR) Transmitted IN Data Interrupt Set Mask */ #define DEVEPTIFR_RXOUTIS_Pos 1 /**< (DEVEPTIFR) Received OUT Data Interrupt Set Position */ #define DEVEPTIFR_RXOUTIS (_U_(0x1) << DEVEPTIFR_RXOUTIS_Pos) /**< (DEVEPTIFR) Received OUT Data Interrupt Set Mask */ #define DEVEPTIFR_OVERFIS_Pos 5 /**< (DEVEPTIFR) Overflow Interrupt Set Position */ #define DEVEPTIFR_OVERFIS (_U_(0x1) << DEVEPTIFR_OVERFIS_Pos) /**< (DEVEPTIFR) Overflow Interrupt Set Mask */ #define DEVEPTIFR_SHORTPACKETS_Pos 7 /**< (DEVEPTIFR) Short Packet Interrupt Set Position */ #define DEVEPTIFR_SHORTPACKETS (_U_(0x1) << DEVEPTIFR_SHORTPACKETS_Pos) /**< (DEVEPTIFR) Short Packet Interrupt Set Mask */ #define DEVEPTIFR_NBUSYBKS_Pos 12 /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Position */ #define DEVEPTIFR_NBUSYBKS (_U_(0x1) << DEVEPTIFR_NBUSYBKS_Pos) /**< (DEVEPTIFR) Number of Busy Banks Interrupt Set Mask */ #define DEVEPTIFR_Msk _U_(0x10A3) /**< (DEVEPTIFR) Register Mask */ /* CTRL mode */ #define DEVEPTIFR_CTRL_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ #define DEVEPTIFR_CTRL_RXSTPIS (_U_(0x1) << DEVEPTIFR_CTRL_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ #define DEVEPTIFR_CTRL_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ #define DEVEPTIFR_CTRL_NAKOUTIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ #define DEVEPTIFR_CTRL_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ #define DEVEPTIFR_CTRL_NAKINIS (_U_(0x1) << DEVEPTIFR_CTRL_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ #define DEVEPTIFR_CTRL_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ #define DEVEPTIFR_CTRL_STALLEDIS (_U_(0x1) << DEVEPTIFR_CTRL_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ #define DEVEPTIFR_CTRL_Msk _U_(0x5C) /**< (DEVEPTIFR_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTIFR_ISO_UNDERFIS_Pos 2 /**< (DEVEPTIFR) Underflow Interrupt Set Position */ #define DEVEPTIFR_ISO_UNDERFIS (_U_(0x1) << DEVEPTIFR_ISO_UNDERFIS_Pos) /**< (DEVEPTIFR) Underflow Interrupt Set Mask */ #define DEVEPTIFR_ISO_HBISOINERRIS_Pos 3 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Position */ #define DEVEPTIFR_ISO_HBISOINERRIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOINERRIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Underflow Error Interrupt Set Mask */ #define DEVEPTIFR_ISO_HBISOFLUSHIS_Pos 4 /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Position */ #define DEVEPTIFR_ISO_HBISOFLUSHIS (_U_(0x1) << DEVEPTIFR_ISO_HBISOFLUSHIS_Pos) /**< (DEVEPTIFR) High Bandwidth Isochronous IN Flush Interrupt Set Mask */ #define DEVEPTIFR_ISO_CRCERRIS_Pos 6 /**< (DEVEPTIFR) CRC Error Interrupt Set Position */ #define DEVEPTIFR_ISO_CRCERRIS (_U_(0x1) << DEVEPTIFR_ISO_CRCERRIS_Pos) /**< (DEVEPTIFR) CRC Error Interrupt Set Mask */ #define DEVEPTIFR_ISO_Msk _U_(0x5C) /**< (DEVEPTIFR_ISO) Register Mask */ /* BLK mode */ #define DEVEPTIFR_BLK_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ #define DEVEPTIFR_BLK_RXSTPIS (_U_(0x1) << DEVEPTIFR_BLK_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ #define DEVEPTIFR_BLK_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ #define DEVEPTIFR_BLK_NAKOUTIS (_U_(0x1) << DEVEPTIFR_BLK_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ #define DEVEPTIFR_BLK_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ #define DEVEPTIFR_BLK_NAKINIS (_U_(0x1) << DEVEPTIFR_BLK_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ #define DEVEPTIFR_BLK_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ #define DEVEPTIFR_BLK_STALLEDIS (_U_(0x1) << DEVEPTIFR_BLK_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ #define DEVEPTIFR_BLK_Msk _U_(0x5C) /**< (DEVEPTIFR_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTIFR_INTRPT_RXSTPIS_Pos 2 /**< (DEVEPTIFR) Received SETUP Interrupt Set Position */ #define DEVEPTIFR_INTRPT_RXSTPIS (_U_(0x1) << DEVEPTIFR_INTRPT_RXSTPIS_Pos) /**< (DEVEPTIFR) Received SETUP Interrupt Set Mask */ #define DEVEPTIFR_INTRPT_NAKOUTIS_Pos 3 /**< (DEVEPTIFR) NAKed OUT Interrupt Set Position */ #define DEVEPTIFR_INTRPT_NAKOUTIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKOUTIS_Pos) /**< (DEVEPTIFR) NAKed OUT Interrupt Set Mask */ #define DEVEPTIFR_INTRPT_NAKINIS_Pos 4 /**< (DEVEPTIFR) NAKed IN Interrupt Set Position */ #define DEVEPTIFR_INTRPT_NAKINIS (_U_(0x1) << DEVEPTIFR_INTRPT_NAKINIS_Pos) /**< (DEVEPTIFR) NAKed IN Interrupt Set Mask */ #define DEVEPTIFR_INTRPT_STALLEDIS_Pos 6 /**< (DEVEPTIFR) STALLed Interrupt Set Position */ #define DEVEPTIFR_INTRPT_STALLEDIS (_U_(0x1) << DEVEPTIFR_INTRPT_STALLEDIS_Pos) /**< (DEVEPTIFR) STALLed Interrupt Set Mask */ #define DEVEPTIFR_INTRPT_Msk _U_(0x5C) /**< (DEVEPTIFR_INTRPT) Register Mask */ /* -------- DEVEPTIMR : (USBHS Offset: 0x1c0) (R/ 32) Device Endpoint Interrupt Mask Register -------- */ #define DEVEPTIMR_OFFSET (0x1C0) /**< (DEVEPTIMR) Device Endpoint Interrupt Mask Register Offset */ #define DEVEPTIMR_TXINE_Pos 0 /**< (DEVEPTIMR) Transmitted IN Data Interrupt Position */ #define DEVEPTIMR_TXINE (_U_(0x1) << DEVEPTIMR_TXINE_Pos) /**< (DEVEPTIMR) Transmitted IN Data Interrupt Mask */ #define DEVEPTIMR_RXOUTE_Pos 1 /**< (DEVEPTIMR) Received OUT Data Interrupt Position */ #define DEVEPTIMR_RXOUTE (_U_(0x1) << DEVEPTIMR_RXOUTE_Pos) /**< (DEVEPTIMR) Received OUT Data Interrupt Mask */ #define DEVEPTIMR_OVERFE_Pos 5 /**< (DEVEPTIMR) Overflow Interrupt Position */ #define DEVEPTIMR_OVERFE (_U_(0x1) << DEVEPTIMR_OVERFE_Pos) /**< (DEVEPTIMR) Overflow Interrupt Mask */ #define DEVEPTIMR_SHORTPACKETE_Pos 7 /**< (DEVEPTIMR) Short Packet Interrupt Position */ #define DEVEPTIMR_SHORTPACKETE (_U_(0x1) << DEVEPTIMR_SHORTPACKETE_Pos) /**< (DEVEPTIMR) Short Packet Interrupt Mask */ #define DEVEPTIMR_NBUSYBKE_Pos 12 /**< (DEVEPTIMR) Number of Busy Banks Interrupt Position */ #define DEVEPTIMR_NBUSYBKE (_U_(0x1) << DEVEPTIMR_NBUSYBKE_Pos) /**< (DEVEPTIMR) Number of Busy Banks Interrupt Mask */ #define DEVEPTIMR_KILLBK_Pos 13 /**< (DEVEPTIMR) Kill IN Bank Position */ #define DEVEPTIMR_KILLBK (_U_(0x1) << DEVEPTIMR_KILLBK_Pos) /**< (DEVEPTIMR) Kill IN Bank Mask */ #define DEVEPTIMR_FIFOCON_Pos 14 /**< (DEVEPTIMR) FIFO Control Position */ #define DEVEPTIMR_FIFOCON (_U_(0x1) << DEVEPTIMR_FIFOCON_Pos) /**< (DEVEPTIMR) FIFO Control Mask */ #define DEVEPTIMR_EPDISHDMA_Pos 16 /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Position */ #define DEVEPTIMR_EPDISHDMA (_U_(0x1) << DEVEPTIMR_EPDISHDMA_Pos) /**< (DEVEPTIMR) Endpoint Interrupts Disable HDMA Request Mask */ #define DEVEPTIMR_RSTDT_Pos 18 /**< (DEVEPTIMR) Reset Data Toggle Position */ #define DEVEPTIMR_RSTDT (_U_(0x1) << DEVEPTIMR_RSTDT_Pos) /**< (DEVEPTIMR) Reset Data Toggle Mask */ #define DEVEPTIMR_Msk _U_(0x570A3) /**< (DEVEPTIMR) Register Mask */ /* CTRL mode */ #define DEVEPTIMR_CTRL_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ #define DEVEPTIMR_CTRL_RXSTPE (_U_(0x1) << DEVEPTIMR_CTRL_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ #define DEVEPTIMR_CTRL_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ #define DEVEPTIMR_CTRL_NAKOUTE (_U_(0x1) << DEVEPTIMR_CTRL_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ #define DEVEPTIMR_CTRL_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ #define DEVEPTIMR_CTRL_NAKINE (_U_(0x1) << DEVEPTIMR_CTRL_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ #define DEVEPTIMR_CTRL_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ #define DEVEPTIMR_CTRL_STALLEDE (_U_(0x1) << DEVEPTIMR_CTRL_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ #define DEVEPTIMR_CTRL_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ #define DEVEPTIMR_CTRL_NYETDIS (_U_(0x1) << DEVEPTIMR_CTRL_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ #define DEVEPTIMR_CTRL_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ #define DEVEPTIMR_CTRL_STALLRQ (_U_(0x1) << DEVEPTIMR_CTRL_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ #define DEVEPTIMR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIMR_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTIMR_ISO_UNDERFE_Pos 2 /**< (DEVEPTIMR) Underflow Interrupt Position */ #define DEVEPTIMR_ISO_UNDERFE (_U_(0x1) << DEVEPTIMR_ISO_UNDERFE_Pos) /**< (DEVEPTIMR) Underflow Interrupt Mask */ #define DEVEPTIMR_ISO_HBISOINERRE_Pos 3 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Position */ #define DEVEPTIMR_ISO_HBISOINERRE (_U_(0x1) << DEVEPTIMR_ISO_HBISOINERRE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Underflow Error Interrupt Mask */ #define DEVEPTIMR_ISO_HBISOFLUSHE_Pos 4 /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Position */ #define DEVEPTIMR_ISO_HBISOFLUSHE (_U_(0x1) << DEVEPTIMR_ISO_HBISOFLUSHE_Pos) /**< (DEVEPTIMR) High Bandwidth Isochronous IN Flush Interrupt Mask */ #define DEVEPTIMR_ISO_CRCERRE_Pos 6 /**< (DEVEPTIMR) CRC Error Interrupt Position */ #define DEVEPTIMR_ISO_CRCERRE (_U_(0x1) << DEVEPTIMR_ISO_CRCERRE_Pos) /**< (DEVEPTIMR) CRC Error Interrupt Mask */ #define DEVEPTIMR_ISO_MDATAE_Pos 8 /**< (DEVEPTIMR) MData Interrupt Position */ #define DEVEPTIMR_ISO_MDATAE (_U_(0x1) << DEVEPTIMR_ISO_MDATAE_Pos) /**< (DEVEPTIMR) MData Interrupt Mask */ #define DEVEPTIMR_ISO_DATAXE_Pos 9 /**< (DEVEPTIMR) DataX Interrupt Position */ #define DEVEPTIMR_ISO_DATAXE (_U_(0x1) << DEVEPTIMR_ISO_DATAXE_Pos) /**< (DEVEPTIMR) DataX Interrupt Mask */ #define DEVEPTIMR_ISO_ERRORTRANSE_Pos 10 /**< (DEVEPTIMR) Transaction Error Interrupt Position */ #define DEVEPTIMR_ISO_ERRORTRANSE (_U_(0x1) << DEVEPTIMR_ISO_ERRORTRANSE_Pos) /**< (DEVEPTIMR) Transaction Error Interrupt Mask */ #define DEVEPTIMR_ISO_Msk _U_(0x75C) /**< (DEVEPTIMR_ISO) Register Mask */ /* BLK mode */ #define DEVEPTIMR_BLK_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ #define DEVEPTIMR_BLK_RXSTPE (_U_(0x1) << DEVEPTIMR_BLK_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ #define DEVEPTIMR_BLK_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ #define DEVEPTIMR_BLK_NAKOUTE (_U_(0x1) << DEVEPTIMR_BLK_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ #define DEVEPTIMR_BLK_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ #define DEVEPTIMR_BLK_NAKINE (_U_(0x1) << DEVEPTIMR_BLK_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ #define DEVEPTIMR_BLK_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ #define DEVEPTIMR_BLK_STALLEDE (_U_(0x1) << DEVEPTIMR_BLK_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ #define DEVEPTIMR_BLK_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ #define DEVEPTIMR_BLK_NYETDIS (_U_(0x1) << DEVEPTIMR_BLK_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ #define DEVEPTIMR_BLK_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ #define DEVEPTIMR_BLK_STALLRQ (_U_(0x1) << DEVEPTIMR_BLK_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ #define DEVEPTIMR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIMR_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTIMR_INTRPT_RXSTPE_Pos 2 /**< (DEVEPTIMR) Received SETUP Interrupt Position */ #define DEVEPTIMR_INTRPT_RXSTPE (_U_(0x1) << DEVEPTIMR_INTRPT_RXSTPE_Pos) /**< (DEVEPTIMR) Received SETUP Interrupt Mask */ #define DEVEPTIMR_INTRPT_NAKOUTE_Pos 3 /**< (DEVEPTIMR) NAKed OUT Interrupt Position */ #define DEVEPTIMR_INTRPT_NAKOUTE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKOUTE_Pos) /**< (DEVEPTIMR) NAKed OUT Interrupt Mask */ #define DEVEPTIMR_INTRPT_NAKINE_Pos 4 /**< (DEVEPTIMR) NAKed IN Interrupt Position */ #define DEVEPTIMR_INTRPT_NAKINE (_U_(0x1) << DEVEPTIMR_INTRPT_NAKINE_Pos) /**< (DEVEPTIMR) NAKed IN Interrupt Mask */ #define DEVEPTIMR_INTRPT_STALLEDE_Pos 6 /**< (DEVEPTIMR) STALLed Interrupt Position */ #define DEVEPTIMR_INTRPT_STALLEDE (_U_(0x1) << DEVEPTIMR_INTRPT_STALLEDE_Pos) /**< (DEVEPTIMR) STALLed Interrupt Mask */ #define DEVEPTIMR_INTRPT_NYETDIS_Pos 17 /**< (DEVEPTIMR) NYET Token Disable Position */ #define DEVEPTIMR_INTRPT_NYETDIS (_U_(0x1) << DEVEPTIMR_INTRPT_NYETDIS_Pos) /**< (DEVEPTIMR) NYET Token Disable Mask */ #define DEVEPTIMR_INTRPT_STALLRQ_Pos 19 /**< (DEVEPTIMR) STALL Request Position */ #define DEVEPTIMR_INTRPT_STALLRQ (_U_(0x1) << DEVEPTIMR_INTRPT_STALLRQ_Pos) /**< (DEVEPTIMR) STALL Request Mask */ #define DEVEPTIMR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIMR_INTRPT) Register Mask */ /* -------- DEVEPTIER : (USBHS Offset: 0x1f0) (/W 32) Device Endpoint Interrupt Enable Register -------- */ #define DEVEPTIER_OFFSET (0x1F0) /**< (DEVEPTIER) Device Endpoint Interrupt Enable Register Offset */ #define DEVEPTIER_TXINES_Pos 0 /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Position */ #define DEVEPTIER_TXINES (_U_(0x1) << DEVEPTIER_TXINES_Pos) /**< (DEVEPTIER) Transmitted IN Data Interrupt Enable Mask */ #define DEVEPTIER_RXOUTES_Pos 1 /**< (DEVEPTIER) Received OUT Data Interrupt Enable Position */ #define DEVEPTIER_RXOUTES (_U_(0x1) << DEVEPTIER_RXOUTES_Pos) /**< (DEVEPTIER) Received OUT Data Interrupt Enable Mask */ #define DEVEPTIER_OVERFES_Pos 5 /**< (DEVEPTIER) Overflow Interrupt Enable Position */ #define DEVEPTIER_OVERFES (_U_(0x1) << DEVEPTIER_OVERFES_Pos) /**< (DEVEPTIER) Overflow Interrupt Enable Mask */ #define DEVEPTIER_SHORTPACKETES_Pos 7 /**< (DEVEPTIER) Short Packet Interrupt Enable Position */ #define DEVEPTIER_SHORTPACKETES (_U_(0x1) << DEVEPTIER_SHORTPACKETES_Pos) /**< (DEVEPTIER) Short Packet Interrupt Enable Mask */ #define DEVEPTIER_NBUSYBKES_Pos 12 /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Position */ #define DEVEPTIER_NBUSYBKES (_U_(0x1) << DEVEPTIER_NBUSYBKES_Pos) /**< (DEVEPTIER) Number of Busy Banks Interrupt Enable Mask */ #define DEVEPTIER_KILLBKS_Pos 13 /**< (DEVEPTIER) Kill IN Bank Position */ #define DEVEPTIER_KILLBKS (_U_(0x1) << DEVEPTIER_KILLBKS_Pos) /**< (DEVEPTIER) Kill IN Bank Mask */ #define DEVEPTIER_FIFOCONS_Pos 14 /**< (DEVEPTIER) FIFO Control Position */ #define DEVEPTIER_FIFOCONS (_U_(0x1) << DEVEPTIER_FIFOCONS_Pos) /**< (DEVEPTIER) FIFO Control Mask */ #define DEVEPTIER_EPDISHDMAS_Pos 16 /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Position */ #define DEVEPTIER_EPDISHDMAS (_U_(0x1) << DEVEPTIER_EPDISHDMAS_Pos) /**< (DEVEPTIER) Endpoint Interrupts Disable HDMA Request Enable Mask */ #define DEVEPTIER_RSTDTS_Pos 18 /**< (DEVEPTIER) Reset Data Toggle Enable Position */ #define DEVEPTIER_RSTDTS (_U_(0x1) << DEVEPTIER_RSTDTS_Pos) /**< (DEVEPTIER) Reset Data Toggle Enable Mask */ #define DEVEPTIER_Msk _U_(0x570A3) /**< (DEVEPTIER) Register Mask */ /* CTRL mode */ #define DEVEPTIER_CTRL_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ #define DEVEPTIER_CTRL_RXSTPES (_U_(0x1) << DEVEPTIER_CTRL_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ #define DEVEPTIER_CTRL_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ #define DEVEPTIER_CTRL_NAKOUTES (_U_(0x1) << DEVEPTIER_CTRL_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ #define DEVEPTIER_CTRL_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ #define DEVEPTIER_CTRL_NAKINES (_U_(0x1) << DEVEPTIER_CTRL_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ #define DEVEPTIER_CTRL_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ #define DEVEPTIER_CTRL_STALLEDES (_U_(0x1) << DEVEPTIER_CTRL_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ #define DEVEPTIER_CTRL_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ #define DEVEPTIER_CTRL_NYETDISS (_U_(0x1) << DEVEPTIER_CTRL_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ #define DEVEPTIER_CTRL_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ #define DEVEPTIER_CTRL_STALLRQS (_U_(0x1) << DEVEPTIER_CTRL_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ #define DEVEPTIER_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIER_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTIER_ISO_UNDERFES_Pos 2 /**< (DEVEPTIER) Underflow Interrupt Enable Position */ #define DEVEPTIER_ISO_UNDERFES (_U_(0x1) << DEVEPTIER_ISO_UNDERFES_Pos) /**< (DEVEPTIER) Underflow Interrupt Enable Mask */ #define DEVEPTIER_ISO_HBISOINERRES_Pos 3 /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Position */ #define DEVEPTIER_ISO_HBISOINERRES (_U_(0x1) << DEVEPTIER_ISO_HBISOINERRES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Underflow Error Interrupt Enable Mask */ #define DEVEPTIER_ISO_HBISOFLUSHES_Pos 4 /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Position */ #define DEVEPTIER_ISO_HBISOFLUSHES (_U_(0x1) << DEVEPTIER_ISO_HBISOFLUSHES_Pos) /**< (DEVEPTIER) High Bandwidth Isochronous IN Flush Interrupt Enable Mask */ #define DEVEPTIER_ISO_CRCERRES_Pos 6 /**< (DEVEPTIER) CRC Error Interrupt Enable Position */ #define DEVEPTIER_ISO_CRCERRES (_U_(0x1) << DEVEPTIER_ISO_CRCERRES_Pos) /**< (DEVEPTIER) CRC Error Interrupt Enable Mask */ #define DEVEPTIER_ISO_MDATAES_Pos 8 /**< (DEVEPTIER) MData Interrupt Enable Position */ #define DEVEPTIER_ISO_MDATAES (_U_(0x1) << DEVEPTIER_ISO_MDATAES_Pos) /**< (DEVEPTIER) MData Interrupt Enable Mask */ #define DEVEPTIER_ISO_DATAXES_Pos 9 /**< (DEVEPTIER) DataX Interrupt Enable Position */ #define DEVEPTIER_ISO_DATAXES (_U_(0x1) << DEVEPTIER_ISO_DATAXES_Pos) /**< (DEVEPTIER) DataX Interrupt Enable Mask */ #define DEVEPTIER_ISO_ERRORTRANSES_Pos 10 /**< (DEVEPTIER) Transaction Error Interrupt Enable Position */ #define DEVEPTIER_ISO_ERRORTRANSES (_U_(0x1) << DEVEPTIER_ISO_ERRORTRANSES_Pos) /**< (DEVEPTIER) Transaction Error Interrupt Enable Mask */ #define DEVEPTIER_ISO_Msk _U_(0x75C) /**< (DEVEPTIER_ISO) Register Mask */ /* BLK mode */ #define DEVEPTIER_BLK_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ #define DEVEPTIER_BLK_RXSTPES (_U_(0x1) << DEVEPTIER_BLK_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ #define DEVEPTIER_BLK_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ #define DEVEPTIER_BLK_NAKOUTES (_U_(0x1) << DEVEPTIER_BLK_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ #define DEVEPTIER_BLK_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ #define DEVEPTIER_BLK_NAKINES (_U_(0x1) << DEVEPTIER_BLK_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ #define DEVEPTIER_BLK_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ #define DEVEPTIER_BLK_STALLEDES (_U_(0x1) << DEVEPTIER_BLK_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ #define DEVEPTIER_BLK_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ #define DEVEPTIER_BLK_NYETDISS (_U_(0x1) << DEVEPTIER_BLK_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ #define DEVEPTIER_BLK_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ #define DEVEPTIER_BLK_STALLRQS (_U_(0x1) << DEVEPTIER_BLK_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ #define DEVEPTIER_BLK_Msk _U_(0xA005C) /**< (DEVEPTIER_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTIER_INTRPT_RXSTPES_Pos 2 /**< (DEVEPTIER) Received SETUP Interrupt Enable Position */ #define DEVEPTIER_INTRPT_RXSTPES (_U_(0x1) << DEVEPTIER_INTRPT_RXSTPES_Pos) /**< (DEVEPTIER) Received SETUP Interrupt Enable Mask */ #define DEVEPTIER_INTRPT_NAKOUTES_Pos 3 /**< (DEVEPTIER) NAKed OUT Interrupt Enable Position */ #define DEVEPTIER_INTRPT_NAKOUTES (_U_(0x1) << DEVEPTIER_INTRPT_NAKOUTES_Pos) /**< (DEVEPTIER) NAKed OUT Interrupt Enable Mask */ #define DEVEPTIER_INTRPT_NAKINES_Pos 4 /**< (DEVEPTIER) NAKed IN Interrupt Enable Position */ #define DEVEPTIER_INTRPT_NAKINES (_U_(0x1) << DEVEPTIER_INTRPT_NAKINES_Pos) /**< (DEVEPTIER) NAKed IN Interrupt Enable Mask */ #define DEVEPTIER_INTRPT_STALLEDES_Pos 6 /**< (DEVEPTIER) STALLed Interrupt Enable Position */ #define DEVEPTIER_INTRPT_STALLEDES (_U_(0x1) << DEVEPTIER_INTRPT_STALLEDES_Pos) /**< (DEVEPTIER) STALLed Interrupt Enable Mask */ #define DEVEPTIER_INTRPT_NYETDISS_Pos 17 /**< (DEVEPTIER) NYET Token Disable Enable Position */ #define DEVEPTIER_INTRPT_NYETDISS (_U_(0x1) << DEVEPTIER_INTRPT_NYETDISS_Pos) /**< (DEVEPTIER) NYET Token Disable Enable Mask */ #define DEVEPTIER_INTRPT_STALLRQS_Pos 19 /**< (DEVEPTIER) STALL Request Enable Position */ #define DEVEPTIER_INTRPT_STALLRQS (_U_(0x1) << DEVEPTIER_INTRPT_STALLRQS_Pos) /**< (DEVEPTIER) STALL Request Enable Mask */ #define DEVEPTIER_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIER_INTRPT) Register Mask */ /* -------- DEVEPTIDR : (USBHS Offset: 0x220) (/W 32) Device Endpoint Interrupt Disable Register -------- */ #define DEVEPTIDR_OFFSET (0x220) /**< (DEVEPTIDR) Device Endpoint Interrupt Disable Register Offset */ #define DEVEPTIDR_TXINEC_Pos 0 /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Position */ #define DEVEPTIDR_TXINEC (_U_(0x1) << DEVEPTIDR_TXINEC_Pos) /**< (DEVEPTIDR) Transmitted IN Interrupt Clear Mask */ #define DEVEPTIDR_RXOUTEC_Pos 1 /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Position */ #define DEVEPTIDR_RXOUTEC (_U_(0x1) << DEVEPTIDR_RXOUTEC_Pos) /**< (DEVEPTIDR) Received OUT Data Interrupt Clear Mask */ #define DEVEPTIDR_OVERFEC_Pos 5 /**< (DEVEPTIDR) Overflow Interrupt Clear Position */ #define DEVEPTIDR_OVERFEC (_U_(0x1) << DEVEPTIDR_OVERFEC_Pos) /**< (DEVEPTIDR) Overflow Interrupt Clear Mask */ #define DEVEPTIDR_SHORTPACKETEC_Pos 7 /**< (DEVEPTIDR) Shortpacket Interrupt Clear Position */ #define DEVEPTIDR_SHORTPACKETEC (_U_(0x1) << DEVEPTIDR_SHORTPACKETEC_Pos) /**< (DEVEPTIDR) Shortpacket Interrupt Clear Mask */ #define DEVEPTIDR_NBUSYBKEC_Pos 12 /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Position */ #define DEVEPTIDR_NBUSYBKEC (_U_(0x1) << DEVEPTIDR_NBUSYBKEC_Pos) /**< (DEVEPTIDR) Number of Busy Banks Interrupt Clear Mask */ #define DEVEPTIDR_FIFOCONC_Pos 14 /**< (DEVEPTIDR) FIFO Control Clear Position */ #define DEVEPTIDR_FIFOCONC (_U_(0x1) << DEVEPTIDR_FIFOCONC_Pos) /**< (DEVEPTIDR) FIFO Control Clear Mask */ #define DEVEPTIDR_EPDISHDMAC_Pos 16 /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Position */ #define DEVEPTIDR_EPDISHDMAC (_U_(0x1) << DEVEPTIDR_EPDISHDMAC_Pos) /**< (DEVEPTIDR) Endpoint Interrupts Disable HDMA Request Clear Mask */ #define DEVEPTIDR_Msk _U_(0x150A3) /**< (DEVEPTIDR) Register Mask */ /* CTRL mode */ #define DEVEPTIDR_CTRL_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ #define DEVEPTIDR_CTRL_RXSTPEC (_U_(0x1) << DEVEPTIDR_CTRL_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ #define DEVEPTIDR_CTRL_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ #define DEVEPTIDR_CTRL_NAKOUTEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTIDR_CTRL_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ #define DEVEPTIDR_CTRL_NAKINEC (_U_(0x1) << DEVEPTIDR_CTRL_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ #define DEVEPTIDR_CTRL_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ #define DEVEPTIDR_CTRL_STALLEDEC (_U_(0x1) << DEVEPTIDR_CTRL_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ #define DEVEPTIDR_CTRL_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ #define DEVEPTIDR_CTRL_NYETDISC (_U_(0x1) << DEVEPTIDR_CTRL_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ #define DEVEPTIDR_CTRL_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ #define DEVEPTIDR_CTRL_STALLRQC (_U_(0x1) << DEVEPTIDR_CTRL_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ #define DEVEPTIDR_CTRL_Msk _U_(0xA005C) /**< (DEVEPTIDR_CTRL) Register Mask */ /* ISO mode */ #define DEVEPTIDR_ISO_UNDERFEC_Pos 2 /**< (DEVEPTIDR) Underflow Interrupt Clear Position */ #define DEVEPTIDR_ISO_UNDERFEC (_U_(0x1) << DEVEPTIDR_ISO_UNDERFEC_Pos) /**< (DEVEPTIDR) Underflow Interrupt Clear Mask */ #define DEVEPTIDR_ISO_HBISOINERREC_Pos 3 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Position */ #define DEVEPTIDR_ISO_HBISOINERREC (_U_(0x1) << DEVEPTIDR_ISO_HBISOINERREC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Underflow Error Interrupt Clear Mask */ #define DEVEPTIDR_ISO_HBISOFLUSHEC_Pos 4 /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Position */ #define DEVEPTIDR_ISO_HBISOFLUSHEC (_U_(0x1) << DEVEPTIDR_ISO_HBISOFLUSHEC_Pos) /**< (DEVEPTIDR) High Bandwidth Isochronous IN Flush Interrupt Clear Mask */ #define DEVEPTIDR_ISO_MDATAEC_Pos 8 /**< (DEVEPTIDR) MData Interrupt Clear Position */ #define DEVEPTIDR_ISO_MDATAEC (_U_(0x1) << DEVEPTIDR_ISO_MDATAEC_Pos) /**< (DEVEPTIDR) MData Interrupt Clear Mask */ #define DEVEPTIDR_ISO_DATAXEC_Pos 9 /**< (DEVEPTIDR) DataX Interrupt Clear Position */ #define DEVEPTIDR_ISO_DATAXEC (_U_(0x1) << DEVEPTIDR_ISO_DATAXEC_Pos) /**< (DEVEPTIDR) DataX Interrupt Clear Mask */ #define DEVEPTIDR_ISO_ERRORTRANSEC_Pos 10 /**< (DEVEPTIDR) Transaction Error Interrupt Clear Position */ #define DEVEPTIDR_ISO_ERRORTRANSEC (_U_(0x1) << DEVEPTIDR_ISO_ERRORTRANSEC_Pos) /**< (DEVEPTIDR) Transaction Error Interrupt Clear Mask */ #define DEVEPTIDR_ISO_Msk _U_(0x71C) /**< (DEVEPTIDR_ISO) Register Mask */ /* BLK mode */ #define DEVEPTIDR_BLK_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ #define DEVEPTIDR_BLK_RXSTPEC (_U_(0x1) << DEVEPTIDR_BLK_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ #define DEVEPTIDR_BLK_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ #define DEVEPTIDR_BLK_NAKOUTEC (_U_(0x1) << DEVEPTIDR_BLK_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTIDR_BLK_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ #define DEVEPTIDR_BLK_NAKINEC (_U_(0x1) << DEVEPTIDR_BLK_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ #define DEVEPTIDR_BLK_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ #define DEVEPTIDR_BLK_STALLEDEC (_U_(0x1) << DEVEPTIDR_BLK_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ #define DEVEPTIDR_BLK_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ #define DEVEPTIDR_BLK_NYETDISC (_U_(0x1) << DEVEPTIDR_BLK_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ #define DEVEPTIDR_BLK_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ #define DEVEPTIDR_BLK_STALLRQC (_U_(0x1) << DEVEPTIDR_BLK_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ #define DEVEPTIDR_BLK_Msk _U_(0xA005C) /**< (DEVEPTIDR_BLK) Register Mask */ /* INTRPT mode */ #define DEVEPTIDR_INTRPT_RXSTPEC_Pos 2 /**< (DEVEPTIDR) Received SETUP Interrupt Clear Position */ #define DEVEPTIDR_INTRPT_RXSTPEC (_U_(0x1) << DEVEPTIDR_INTRPT_RXSTPEC_Pos) /**< (DEVEPTIDR) Received SETUP Interrupt Clear Mask */ #define DEVEPTIDR_INTRPT_NAKOUTEC_Pos 3 /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Position */ #define DEVEPTIDR_INTRPT_NAKOUTEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKOUTEC_Pos) /**< (DEVEPTIDR) NAKed OUT Interrupt Clear Mask */ #define DEVEPTIDR_INTRPT_NAKINEC_Pos 4 /**< (DEVEPTIDR) NAKed IN Interrupt Clear Position */ #define DEVEPTIDR_INTRPT_NAKINEC (_U_(0x1) << DEVEPTIDR_INTRPT_NAKINEC_Pos) /**< (DEVEPTIDR) NAKed IN Interrupt Clear Mask */ #define DEVEPTIDR_INTRPT_STALLEDEC_Pos 6 /**< (DEVEPTIDR) STALLed Interrupt Clear Position */ #define DEVEPTIDR_INTRPT_STALLEDEC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLEDEC_Pos) /**< (DEVEPTIDR) STALLed Interrupt Clear Mask */ #define DEVEPTIDR_INTRPT_NYETDISC_Pos 17 /**< (DEVEPTIDR) NYET Token Disable Clear Position */ #define DEVEPTIDR_INTRPT_NYETDISC (_U_(0x1) << DEVEPTIDR_INTRPT_NYETDISC_Pos) /**< (DEVEPTIDR) NYET Token Disable Clear Mask */ #define DEVEPTIDR_INTRPT_STALLRQC_Pos 19 /**< (DEVEPTIDR) STALL Request Clear Position */ #define DEVEPTIDR_INTRPT_STALLRQC (_U_(0x1) << DEVEPTIDR_INTRPT_STALLRQC_Pos) /**< (DEVEPTIDR) STALL Request Clear Mask */ #define DEVEPTIDR_INTRPT_Msk _U_(0xA005C) /**< (DEVEPTIDR_INTRPT) Register Mask */ /* -------- HSTCTRL : (USBHS Offset: 0x400) (R/W 32) Host General Control Register -------- */ #define HSTCTRL_OFFSET (0x400) /**< (HSTCTRL) Host General Control Register Offset */ #define HSTCTRL_SOFE_Pos 8 /**< (HSTCTRL) Start of Frame Generation Enable Position */ #define HSTCTRL_SOFE (_U_(0x1) << HSTCTRL_SOFE_Pos) /**< (HSTCTRL) Start of Frame Generation Enable Mask */ #define HSTCTRL_RESET_Pos 9 /**< (HSTCTRL) Send USB Reset Position */ #define HSTCTRL_RESET (_U_(0x1) << HSTCTRL_RESET_Pos) /**< (HSTCTRL) Send USB Reset Mask */ #define HSTCTRL_RESUME_Pos 10 /**< (HSTCTRL) Send USB Resume Position */ #define HSTCTRL_RESUME (_U_(0x1) << HSTCTRL_RESUME_Pos) /**< (HSTCTRL) Send USB Resume Mask */ #define HSTCTRL_SPDCONF_Pos 12 /**< (HSTCTRL) Mode Configuration Position */ #define HSTCTRL_SPDCONF (_U_(0x3) << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Mode Configuration Mask */ #define HSTCTRL_SPDCONF_NORMAL_Val _U_(0x0) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. */ #define HSTCTRL_SPDCONF_LOW_POWER_Val _U_(0x1) /**< (HSTCTRL) For a better consumption, if high speed is not needed. */ #define HSTCTRL_SPDCONF_HIGH_SPEED_Val _U_(0x2) /**< (HSTCTRL) Forced high speed. */ #define HSTCTRL_SPDCONF_FORCED_FS_Val _U_(0x3) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. */ #define HSTCTRL_SPDCONF_NORMAL (HSTCTRL_SPDCONF_NORMAL_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host starts in Full-speed mode and performs a high-speed reset to switch to High-speed mode if the downstream peripheral is high-speed capable. Position */ #define HSTCTRL_SPDCONF_LOW_POWER (HSTCTRL_SPDCONF_LOW_POWER_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) For a better consumption, if high speed is not needed. Position */ #define HSTCTRL_SPDCONF_HIGH_SPEED (HSTCTRL_SPDCONF_HIGH_SPEED_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) Forced high speed. Position */ #define HSTCTRL_SPDCONF_FORCED_FS (HSTCTRL_SPDCONF_FORCED_FS_Val << HSTCTRL_SPDCONF_Pos) /**< (HSTCTRL) The host remains in Full-speed mode whatever the peripheral speed capability. Position */ #define HSTCTRL_Msk _U_(0x3700) /**< (HSTCTRL) Register Mask */ /* -------- HSTISR : (USBHS Offset: 0x404) (R/ 32) Host Global Interrupt Status Register -------- */ #define HSTISR_OFFSET (0x404) /**< (HSTISR) Host Global Interrupt Status Register Offset */ #define HSTISR_DCONNI_Pos 0 /**< (HSTISR) Device Connection Interrupt Position */ #define HSTISR_DCONNI (_U_(0x1) << HSTISR_DCONNI_Pos) /**< (HSTISR) Device Connection Interrupt Mask */ #define HSTISR_DDISCI_Pos 1 /**< (HSTISR) Device Disconnection Interrupt Position */ #define HSTISR_DDISCI (_U_(0x1) << HSTISR_DDISCI_Pos) /**< (HSTISR) Device Disconnection Interrupt Mask */ #define HSTISR_RSTI_Pos 2 /**< (HSTISR) USB Reset Sent Interrupt Position */ #define HSTISR_RSTI (_U_(0x1) << HSTISR_RSTI_Pos) /**< (HSTISR) USB Reset Sent Interrupt Mask */ #define HSTISR_RSMEDI_Pos 3 /**< (HSTISR) Downstream Resume Sent Interrupt Position */ #define HSTISR_RSMEDI (_U_(0x1) << HSTISR_RSMEDI_Pos) /**< (HSTISR) Downstream Resume Sent Interrupt Mask */ #define HSTISR_RXRSMI_Pos 4 /**< (HSTISR) Upstream Resume Received Interrupt Position */ #define HSTISR_RXRSMI (_U_(0x1) << HSTISR_RXRSMI_Pos) /**< (HSTISR) Upstream Resume Received Interrupt Mask */ #define HSTISR_HSOFI_Pos 5 /**< (HSTISR) Host Start of Frame Interrupt Position */ #define HSTISR_HSOFI (_U_(0x1) << HSTISR_HSOFI_Pos) /**< (HSTISR) Host Start of Frame Interrupt Mask */ #define HSTISR_HWUPI_Pos 6 /**< (HSTISR) Host Wake-Up Interrupt Position */ #define HSTISR_HWUPI (_U_(0x1) << HSTISR_HWUPI_Pos) /**< (HSTISR) Host Wake-Up Interrupt Mask */ #define HSTISR_PEP_0_Pos 8 /**< (HSTISR) Pipe 0 Interrupt Position */ #define HSTISR_PEP_0 (_U_(0x1) << HSTISR_PEP_0_Pos) /**< (HSTISR) Pipe 0 Interrupt Mask */ #define HSTISR_PEP_1_Pos 9 /**< (HSTISR) Pipe 1 Interrupt Position */ #define HSTISR_PEP_1 (_U_(0x1) << HSTISR_PEP_1_Pos) /**< (HSTISR) Pipe 1 Interrupt Mask */ #define HSTISR_PEP_2_Pos 10 /**< (HSTISR) Pipe 2 Interrupt Position */ #define HSTISR_PEP_2 (_U_(0x1) << HSTISR_PEP_2_Pos) /**< (HSTISR) Pipe 2 Interrupt Mask */ #define HSTISR_PEP_3_Pos 11 /**< (HSTISR) Pipe 3 Interrupt Position */ #define HSTISR_PEP_3 (_U_(0x1) << HSTISR_PEP_3_Pos) /**< (HSTISR) Pipe 3 Interrupt Mask */ #define HSTISR_PEP_4_Pos 12 /**< (HSTISR) Pipe 4 Interrupt Position */ #define HSTISR_PEP_4 (_U_(0x1) << HSTISR_PEP_4_Pos) /**< (HSTISR) Pipe 4 Interrupt Mask */ #define HSTISR_PEP_5_Pos 13 /**< (HSTISR) Pipe 5 Interrupt Position */ #define HSTISR_PEP_5 (_U_(0x1) << HSTISR_PEP_5_Pos) /**< (HSTISR) Pipe 5 Interrupt Mask */ #define HSTISR_PEP_6_Pos 14 /**< (HSTISR) Pipe 6 Interrupt Position */ #define HSTISR_PEP_6 (_U_(0x1) << HSTISR_PEP_6_Pos) /**< (HSTISR) Pipe 6 Interrupt Mask */ #define HSTISR_PEP_7_Pos 15 /**< (HSTISR) Pipe 7 Interrupt Position */ #define HSTISR_PEP_7 (_U_(0x1) << HSTISR_PEP_7_Pos) /**< (HSTISR) Pipe 7 Interrupt Mask */ #define HSTISR_PEP_8_Pos 16 /**< (HSTISR) Pipe 8 Interrupt Position */ #define HSTISR_PEP_8 (_U_(0x1) << HSTISR_PEP_8_Pos) /**< (HSTISR) Pipe 8 Interrupt Mask */ #define HSTISR_PEP_9_Pos 17 /**< (HSTISR) Pipe 9 Interrupt Position */ #define HSTISR_PEP_9 (_U_(0x1) << HSTISR_PEP_9_Pos) /**< (HSTISR) Pipe 9 Interrupt Mask */ #define HSTISR_DMA_0_Pos 25 /**< (HSTISR) DMA Channel 0 Interrupt Position */ #define HSTISR_DMA_0 (_U_(0x1) << HSTISR_DMA_0_Pos) /**< (HSTISR) DMA Channel 0 Interrupt Mask */ #define HSTISR_DMA_1_Pos 26 /**< (HSTISR) DMA Channel 1 Interrupt Position */ #define HSTISR_DMA_1 (_U_(0x1) << HSTISR_DMA_1_Pos) /**< (HSTISR) DMA Channel 1 Interrupt Mask */ #define HSTISR_DMA_2_Pos 27 /**< (HSTISR) DMA Channel 2 Interrupt Position */ #define HSTISR_DMA_2 (_U_(0x1) << HSTISR_DMA_2_Pos) /**< (HSTISR) DMA Channel 2 Interrupt Mask */ #define HSTISR_DMA_3_Pos 28 /**< (HSTISR) DMA Channel 3 Interrupt Position */ #define HSTISR_DMA_3 (_U_(0x1) << HSTISR_DMA_3_Pos) /**< (HSTISR) DMA Channel 3 Interrupt Mask */ #define HSTISR_DMA_4_Pos 29 /**< (HSTISR) DMA Channel 4 Interrupt Position */ #define HSTISR_DMA_4 (_U_(0x1) << HSTISR_DMA_4_Pos) /**< (HSTISR) DMA Channel 4 Interrupt Mask */ #define HSTISR_DMA_5_Pos 30 /**< (HSTISR) DMA Channel 5 Interrupt Position */ #define HSTISR_DMA_5 (_U_(0x1) << HSTISR_DMA_5_Pos) /**< (HSTISR) DMA Channel 5 Interrupt Mask */ #define HSTISR_DMA_6_Pos 31 /**< (HSTISR) DMA Channel 6 Interrupt Position */ #define HSTISR_DMA_6 (_U_(0x1) << HSTISR_DMA_6_Pos) /**< (HSTISR) DMA Channel 6 Interrupt Mask */ #define HSTISR_Msk _U_(0xFE03FF7F) /**< (HSTISR) Register Mask */ #define HSTISR_PEP__Pos 8 /**< (HSTISR Position) Pipe x Interrupt */ #define HSTISR_PEP_ (_U_(0x3FF) << HSTISR_PEP__Pos) /**< (HSTISR Mask) PEP_ */ #define HSTISR_DMA__Pos 25 /**< (HSTISR Position) DMA Channel 6 Interrupt */ #define HSTISR_DMA_ (_U_(0x7F) << HSTISR_DMA__Pos) /**< (HSTISR Mask) DMA_ */ /* -------- HSTICR : (USBHS Offset: 0x408) (/W 32) Host Global Interrupt Clear Register -------- */ #define HSTICR_OFFSET (0x408) /**< (HSTICR) Host Global Interrupt Clear Register Offset */ #define HSTICR_DCONNIC_Pos 0 /**< (HSTICR) Device Connection Interrupt Clear Position */ #define HSTICR_DCONNIC (_U_(0x1) << HSTICR_DCONNIC_Pos) /**< (HSTICR) Device Connection Interrupt Clear Mask */ #define HSTICR_DDISCIC_Pos 1 /**< (HSTICR) Device Disconnection Interrupt Clear Position */ #define HSTICR_DDISCIC (_U_(0x1) << HSTICR_DDISCIC_Pos) /**< (HSTICR) Device Disconnection Interrupt Clear Mask */ #define HSTICR_RSTIC_Pos 2 /**< (HSTICR) USB Reset Sent Interrupt Clear Position */ #define HSTICR_RSTIC (_U_(0x1) << HSTICR_RSTIC_Pos) /**< (HSTICR) USB Reset Sent Interrupt Clear Mask */ #define HSTICR_RSMEDIC_Pos 3 /**< (HSTICR) Downstream Resume Sent Interrupt Clear Position */ #define HSTICR_RSMEDIC (_U_(0x1) << HSTICR_RSMEDIC_Pos) /**< (HSTICR) Downstream Resume Sent Interrupt Clear Mask */ #define HSTICR_RXRSMIC_Pos 4 /**< (HSTICR) Upstream Resume Received Interrupt Clear Position */ #define HSTICR_RXRSMIC (_U_(0x1) << HSTICR_RXRSMIC_Pos) /**< (HSTICR) Upstream Resume Received Interrupt Clear Mask */ #define HSTICR_HSOFIC_Pos 5 /**< (HSTICR) Host Start of Frame Interrupt Clear Position */ #define HSTICR_HSOFIC (_U_(0x1) << HSTICR_HSOFIC_Pos) /**< (HSTICR) Host Start of Frame Interrupt Clear Mask */ #define HSTICR_HWUPIC_Pos 6 /**< (HSTICR) Host Wake-Up Interrupt Clear Position */ #define HSTICR_HWUPIC (_U_(0x1) << HSTICR_HWUPIC_Pos) /**< (HSTICR) Host Wake-Up Interrupt Clear Mask */ #define HSTICR_Msk _U_(0x7F) /**< (HSTICR) Register Mask */ /* -------- HSTIFR : (USBHS Offset: 0x40c) (/W 32) Host Global Interrupt Set Register -------- */ #define HSTIFR_OFFSET (0x40C) /**< (HSTIFR) Host Global Interrupt Set Register Offset */ #define HSTIFR_DCONNIS_Pos 0 /**< (HSTIFR) Device Connection Interrupt Set Position */ #define HSTIFR_DCONNIS (_U_(0x1) << HSTIFR_DCONNIS_Pos) /**< (HSTIFR) Device Connection Interrupt Set Mask */ #define HSTIFR_DDISCIS_Pos 1 /**< (HSTIFR) Device Disconnection Interrupt Set Position */ #define HSTIFR_DDISCIS (_U_(0x1) << HSTIFR_DDISCIS_Pos) /**< (HSTIFR) Device Disconnection Interrupt Set Mask */ #define HSTIFR_RSTIS_Pos 2 /**< (HSTIFR) USB Reset Sent Interrupt Set Position */ #define HSTIFR_RSTIS (_U_(0x1) << HSTIFR_RSTIS_Pos) /**< (HSTIFR) USB Reset Sent Interrupt Set Mask */ #define HSTIFR_RSMEDIS_Pos 3 /**< (HSTIFR) Downstream Resume Sent Interrupt Set Position */ #define HSTIFR_RSMEDIS (_U_(0x1) << HSTIFR_RSMEDIS_Pos) /**< (HSTIFR) Downstream Resume Sent Interrupt Set Mask */ #define HSTIFR_RXRSMIS_Pos 4 /**< (HSTIFR) Upstream Resume Received Interrupt Set Position */ #define HSTIFR_RXRSMIS (_U_(0x1) << HSTIFR_RXRSMIS_Pos) /**< (HSTIFR) Upstream Resume Received Interrupt Set Mask */ #define HSTIFR_HSOFIS_Pos 5 /**< (HSTIFR) Host Start of Frame Interrupt Set Position */ #define HSTIFR_HSOFIS (_U_(0x1) << HSTIFR_HSOFIS_Pos) /**< (HSTIFR) Host Start of Frame Interrupt Set Mask */ #define HSTIFR_HWUPIS_Pos 6 /**< (HSTIFR) Host Wake-Up Interrupt Set Position */ #define HSTIFR_HWUPIS (_U_(0x1) << HSTIFR_HWUPIS_Pos) /**< (HSTIFR) Host Wake-Up Interrupt Set Mask */ #define HSTIFR_DMA_0_Pos 25 /**< (HSTIFR) DMA Channel 0 Interrupt Set Position */ #define HSTIFR_DMA_0 (_U_(0x1) << HSTIFR_DMA_0_Pos) /**< (HSTIFR) DMA Channel 0 Interrupt Set Mask */ #define HSTIFR_DMA_1_Pos 26 /**< (HSTIFR) DMA Channel 1 Interrupt Set Position */ #define HSTIFR_DMA_1 (_U_(0x1) << HSTIFR_DMA_1_Pos) /**< (HSTIFR) DMA Channel 1 Interrupt Set Mask */ #define HSTIFR_DMA_2_Pos 27 /**< (HSTIFR) DMA Channel 2 Interrupt Set Position */ #define HSTIFR_DMA_2 (_U_(0x1) << HSTIFR_DMA_2_Pos) /**< (HSTIFR) DMA Channel 2 Interrupt Set Mask */ #define HSTIFR_DMA_3_Pos 28 /**< (HSTIFR) DMA Channel 3 Interrupt Set Position */ #define HSTIFR_DMA_3 (_U_(0x1) << HSTIFR_DMA_3_Pos) /**< (HSTIFR) DMA Channel 3 Interrupt Set Mask */ #define HSTIFR_DMA_4_Pos 29 /**< (HSTIFR) DMA Channel 4 Interrupt Set Position */ #define HSTIFR_DMA_4 (_U_(0x1) << HSTIFR_DMA_4_Pos) /**< (HSTIFR) DMA Channel 4 Interrupt Set Mask */ #define HSTIFR_DMA_5_Pos 30 /**< (HSTIFR) DMA Channel 5 Interrupt Set Position */ #define HSTIFR_DMA_5 (_U_(0x1) << HSTIFR_DMA_5_Pos) /**< (HSTIFR) DMA Channel 5 Interrupt Set Mask */ #define HSTIFR_DMA_6_Pos 31 /**< (HSTIFR) DMA Channel 6 Interrupt Set Position */ #define HSTIFR_DMA_6 (_U_(0x1) << HSTIFR_DMA_6_Pos) /**< (HSTIFR) DMA Channel 6 Interrupt Set Mask */ #define HSTIFR_Msk _U_(0xFE00007F) /**< (HSTIFR) Register Mask */ #define HSTIFR_DMA__Pos 25 /**< (HSTIFR Position) DMA Channel 6 Interrupt Set */ #define HSTIFR_DMA_ (_U_(0x7F) << HSTIFR_DMA__Pos) /**< (HSTIFR Mask) DMA_ */ /* -------- HSTIMR : (USBHS Offset: 0x410) (R/ 32) Host Global Interrupt Mask Register -------- */ #define HSTIMR_OFFSET (0x410) /**< (HSTIMR) Host Global Interrupt Mask Register Offset */ #define HSTIMR_DCONNIE_Pos 0 /**< (HSTIMR) Device Connection Interrupt Enable Position */ #define HSTIMR_DCONNIE (_U_(0x1) << HSTIMR_DCONNIE_Pos) /**< (HSTIMR) Device Connection Interrupt Enable Mask */ #define HSTIMR_DDISCIE_Pos 1 /**< (HSTIMR) Device Disconnection Interrupt Enable Position */ #define HSTIMR_DDISCIE (_U_(0x1) << HSTIMR_DDISCIE_Pos) /**< (HSTIMR) Device Disconnection Interrupt Enable Mask */ #define HSTIMR_RSTIE_Pos 2 /**< (HSTIMR) USB Reset Sent Interrupt Enable Position */ #define HSTIMR_RSTIE (_U_(0x1) << HSTIMR_RSTIE_Pos) /**< (HSTIMR) USB Reset Sent Interrupt Enable Mask */ #define HSTIMR_RSMEDIE_Pos 3 /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Position */ #define HSTIMR_RSMEDIE (_U_(0x1) << HSTIMR_RSMEDIE_Pos) /**< (HSTIMR) Downstream Resume Sent Interrupt Enable Mask */ #define HSTIMR_RXRSMIE_Pos 4 /**< (HSTIMR) Upstream Resume Received Interrupt Enable Position */ #define HSTIMR_RXRSMIE (_U_(0x1) << HSTIMR_RXRSMIE_Pos) /**< (HSTIMR) Upstream Resume Received Interrupt Enable Mask */ #define HSTIMR_HSOFIE_Pos 5 /**< (HSTIMR) Host Start of Frame Interrupt Enable Position */ #define HSTIMR_HSOFIE (_U_(0x1) << HSTIMR_HSOFIE_Pos) /**< (HSTIMR) Host Start of Frame Interrupt Enable Mask */ #define HSTIMR_HWUPIE_Pos 6 /**< (HSTIMR) Host Wake-Up Interrupt Enable Position */ #define HSTIMR_HWUPIE (_U_(0x1) << HSTIMR_HWUPIE_Pos) /**< (HSTIMR) Host Wake-Up Interrupt Enable Mask */ #define HSTIMR_PEP_0_Pos 8 /**< (HSTIMR) Pipe 0 Interrupt Enable Position */ #define HSTIMR_PEP_0 (_U_(0x1) << HSTIMR_PEP_0_Pos) /**< (HSTIMR) Pipe 0 Interrupt Enable Mask */ #define HSTIMR_PEP_1_Pos 9 /**< (HSTIMR) Pipe 1 Interrupt Enable Position */ #define HSTIMR_PEP_1 (_U_(0x1) << HSTIMR_PEP_1_Pos) /**< (HSTIMR) Pipe 1 Interrupt Enable Mask */ #define HSTIMR_PEP_2_Pos 10 /**< (HSTIMR) Pipe 2 Interrupt Enable Position */ #define HSTIMR_PEP_2 (_U_(0x1) << HSTIMR_PEP_2_Pos) /**< (HSTIMR) Pipe 2 Interrupt Enable Mask */ #define HSTIMR_PEP_3_Pos 11 /**< (HSTIMR) Pipe 3 Interrupt Enable Position */ #define HSTIMR_PEP_3 (_U_(0x1) << HSTIMR_PEP_3_Pos) /**< (HSTIMR) Pipe 3 Interrupt Enable Mask */ #define HSTIMR_PEP_4_Pos 12 /**< (HSTIMR) Pipe 4 Interrupt Enable Position */ #define HSTIMR_PEP_4 (_U_(0x1) << HSTIMR_PEP_4_Pos) /**< (HSTIMR) Pipe 4 Interrupt Enable Mask */ #define HSTIMR_PEP_5_Pos 13 /**< (HSTIMR) Pipe 5 Interrupt Enable Position */ #define HSTIMR_PEP_5 (_U_(0x1) << HSTIMR_PEP_5_Pos) /**< (HSTIMR) Pipe 5 Interrupt Enable Mask */ #define HSTIMR_PEP_6_Pos 14 /**< (HSTIMR) Pipe 6 Interrupt Enable Position */ #define HSTIMR_PEP_6 (_U_(0x1) << HSTIMR_PEP_6_Pos) /**< (HSTIMR) Pipe 6 Interrupt Enable Mask */ #define HSTIMR_PEP_7_Pos 15 /**< (HSTIMR) Pipe 7 Interrupt Enable Position */ #define HSTIMR_PEP_7 (_U_(0x1) << HSTIMR_PEP_7_Pos) /**< (HSTIMR) Pipe 7 Interrupt Enable Mask */ #define HSTIMR_PEP_8_Pos 16 /**< (HSTIMR) Pipe 8 Interrupt Enable Position */ #define HSTIMR_PEP_8 (_U_(0x1) << HSTIMR_PEP_8_Pos) /**< (HSTIMR) Pipe 8 Interrupt Enable Mask */ #define HSTIMR_PEP_9_Pos 17 /**< (HSTIMR) Pipe 9 Interrupt Enable Position */ #define HSTIMR_PEP_9 (_U_(0x1) << HSTIMR_PEP_9_Pos) /**< (HSTIMR) Pipe 9 Interrupt Enable Mask */ #define HSTIMR_DMA_0_Pos 25 /**< (HSTIMR) DMA Channel 0 Interrupt Enable Position */ #define HSTIMR_DMA_0 (_U_(0x1) << HSTIMR_DMA_0_Pos) /**< (HSTIMR) DMA Channel 0 Interrupt Enable Mask */ #define HSTIMR_DMA_1_Pos 26 /**< (HSTIMR) DMA Channel 1 Interrupt Enable Position */ #define HSTIMR_DMA_1 (_U_(0x1) << HSTIMR_DMA_1_Pos) /**< (HSTIMR) DMA Channel 1 Interrupt Enable Mask */ #define HSTIMR_DMA_2_Pos 27 /**< (HSTIMR) DMA Channel 2 Interrupt Enable Position */ #define HSTIMR_DMA_2 (_U_(0x1) << HSTIMR_DMA_2_Pos) /**< (HSTIMR) DMA Channel 2 Interrupt Enable Mask */ #define HSTIMR_DMA_3_Pos 28 /**< (HSTIMR) DMA Channel 3 Interrupt Enable Position */ #define HSTIMR_DMA_3 (_U_(0x1) << HSTIMR_DMA_3_Pos) /**< (HSTIMR) DMA Channel 3 Interrupt Enable Mask */ #define HSTIMR_DMA_4_Pos 29 /**< (HSTIMR) DMA Channel 4 Interrupt Enable Position */ #define HSTIMR_DMA_4 (_U_(0x1) << HSTIMR_DMA_4_Pos) /**< (HSTIMR) DMA Channel 4 Interrupt Enable Mask */ #define HSTIMR_DMA_5_Pos 30 /**< (HSTIMR) DMA Channel 5 Interrupt Enable Position */ #define HSTIMR_DMA_5 (_U_(0x1) << HSTIMR_DMA_5_Pos) /**< (HSTIMR) DMA Channel 5 Interrupt Enable Mask */ #define HSTIMR_DMA_6_Pos 31 /**< (HSTIMR) DMA Channel 6 Interrupt Enable Position */ #define HSTIMR_DMA_6 (_U_(0x1) << HSTIMR_DMA_6_Pos) /**< (HSTIMR) DMA Channel 6 Interrupt Enable Mask */ #define HSTIMR_Msk _U_(0xFE03FF7F) /**< (HSTIMR) Register Mask */ #define HSTIMR_PEP__Pos 8 /**< (HSTIMR Position) Pipe x Interrupt Enable */ #define HSTIMR_PEP_ (_U_(0x3FF) << HSTIMR_PEP__Pos) /**< (HSTIMR Mask) PEP_ */ #define HSTIMR_DMA__Pos 25 /**< (HSTIMR Position) DMA Channel 6 Interrupt Enable */ #define HSTIMR_DMA_ (_U_(0x7F) << HSTIMR_DMA__Pos) /**< (HSTIMR Mask) DMA_ */ /* -------- HSTIDR : (USBHS Offset: 0x414) (/W 32) Host Global Interrupt Disable Register -------- */ #define HSTIDR_OFFSET (0x414) /**< (HSTIDR) Host Global Interrupt Disable Register Offset */ #define HSTIDR_DCONNIEC_Pos 0 /**< (HSTIDR) Device Connection Interrupt Disable Position */ #define HSTIDR_DCONNIEC (_U_(0x1) << HSTIDR_DCONNIEC_Pos) /**< (HSTIDR) Device Connection Interrupt Disable Mask */ #define HSTIDR_DDISCIEC_Pos 1 /**< (HSTIDR) Device Disconnection Interrupt Disable Position */ #define HSTIDR_DDISCIEC (_U_(0x1) << HSTIDR_DDISCIEC_Pos) /**< (HSTIDR) Device Disconnection Interrupt Disable Mask */ #define HSTIDR_RSTIEC_Pos 2 /**< (HSTIDR) USB Reset Sent Interrupt Disable Position */ #define HSTIDR_RSTIEC (_U_(0x1) << HSTIDR_RSTIEC_Pos) /**< (HSTIDR) USB Reset Sent Interrupt Disable Mask */ #define HSTIDR_RSMEDIEC_Pos 3 /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Position */ #define HSTIDR_RSMEDIEC (_U_(0x1) << HSTIDR_RSMEDIEC_Pos) /**< (HSTIDR) Downstream Resume Sent Interrupt Disable Mask */ #define HSTIDR_RXRSMIEC_Pos 4 /**< (HSTIDR) Upstream Resume Received Interrupt Disable Position */ #define HSTIDR_RXRSMIEC (_U_(0x1) << HSTIDR_RXRSMIEC_Pos) /**< (HSTIDR) Upstream Resume Received Interrupt Disable Mask */ #define HSTIDR_HSOFIEC_Pos 5 /**< (HSTIDR) Host Start of Frame Interrupt Disable Position */ #define HSTIDR_HSOFIEC (_U_(0x1) << HSTIDR_HSOFIEC_Pos) /**< (HSTIDR) Host Start of Frame Interrupt Disable Mask */ #define HSTIDR_HWUPIEC_Pos 6 /**< (HSTIDR) Host Wake-Up Interrupt Disable Position */ #define HSTIDR_HWUPIEC (_U_(0x1) << HSTIDR_HWUPIEC_Pos) /**< (HSTIDR) Host Wake-Up Interrupt Disable Mask */ #define HSTIDR_PEP_0_Pos 8 /**< (HSTIDR) Pipe 0 Interrupt Disable Position */ #define HSTIDR_PEP_0 (_U_(0x1) << HSTIDR_PEP_0_Pos) /**< (HSTIDR) Pipe 0 Interrupt Disable Mask */ #define HSTIDR_PEP_1_Pos 9 /**< (HSTIDR) Pipe 1 Interrupt Disable Position */ #define HSTIDR_PEP_1 (_U_(0x1) << HSTIDR_PEP_1_Pos) /**< (HSTIDR) Pipe 1 Interrupt Disable Mask */ #define HSTIDR_PEP_2_Pos 10 /**< (HSTIDR) Pipe 2 Interrupt Disable Position */ #define HSTIDR_PEP_2 (_U_(0x1) << HSTIDR_PEP_2_Pos) /**< (HSTIDR) Pipe 2 Interrupt Disable Mask */ #define HSTIDR_PEP_3_Pos 11 /**< (HSTIDR) Pipe 3 Interrupt Disable Position */ #define HSTIDR_PEP_3 (_U_(0x1) << HSTIDR_PEP_3_Pos) /**< (HSTIDR) Pipe 3 Interrupt Disable Mask */ #define HSTIDR_PEP_4_Pos 12 /**< (HSTIDR) Pipe 4 Interrupt Disable Position */ #define HSTIDR_PEP_4 (_U_(0x1) << HSTIDR_PEP_4_Pos) /**< (HSTIDR) Pipe 4 Interrupt Disable Mask */ #define HSTIDR_PEP_5_Pos 13 /**< (HSTIDR) Pipe 5 Interrupt Disable Position */ #define HSTIDR_PEP_5 (_U_(0x1) << HSTIDR_PEP_5_Pos) /**< (HSTIDR) Pipe 5 Interrupt Disable Mask */ #define HSTIDR_PEP_6_Pos 14 /**< (HSTIDR) Pipe 6 Interrupt Disable Position */ #define HSTIDR_PEP_6 (_U_(0x1) << HSTIDR_PEP_6_Pos) /**< (HSTIDR) Pipe 6 Interrupt Disable Mask */ #define HSTIDR_PEP_7_Pos 15 /**< (HSTIDR) Pipe 7 Interrupt Disable Position */ #define HSTIDR_PEP_7 (_U_(0x1) << HSTIDR_PEP_7_Pos) /**< (HSTIDR) Pipe 7 Interrupt Disable Mask */ #define HSTIDR_PEP_8_Pos 16 /**< (HSTIDR) Pipe 8 Interrupt Disable Position */ #define HSTIDR_PEP_8 (_U_(0x1) << HSTIDR_PEP_8_Pos) /**< (HSTIDR) Pipe 8 Interrupt Disable Mask */ #define HSTIDR_PEP_9_Pos 17 /**< (HSTIDR) Pipe 9 Interrupt Disable Position */ #define HSTIDR_PEP_9 (_U_(0x1) << HSTIDR_PEP_9_Pos) /**< (HSTIDR) Pipe 9 Interrupt Disable Mask */ #define HSTIDR_DMA_0_Pos 25 /**< (HSTIDR) DMA Channel 0 Interrupt Disable Position */ #define HSTIDR_DMA_0 (_U_(0x1) << HSTIDR_DMA_0_Pos) /**< (HSTIDR) DMA Channel 0 Interrupt Disable Mask */ #define HSTIDR_DMA_1_Pos 26 /**< (HSTIDR) DMA Channel 1 Interrupt Disable Position */ #define HSTIDR_DMA_1 (_U_(0x1) << HSTIDR_DMA_1_Pos) /**< (HSTIDR) DMA Channel 1 Interrupt Disable Mask */ #define HSTIDR_DMA_2_Pos 27 /**< (HSTIDR) DMA Channel 2 Interrupt Disable Position */ #define HSTIDR_DMA_2 (_U_(0x1) << HSTIDR_DMA_2_Pos) /**< (HSTIDR) DMA Channel 2 Interrupt Disable Mask */ #define HSTIDR_DMA_3_Pos 28 /**< (HSTIDR) DMA Channel 3 Interrupt Disable Position */ #define HSTIDR_DMA_3 (_U_(0x1) << HSTIDR_DMA_3_Pos) /**< (HSTIDR) DMA Channel 3 Interrupt Disable Mask */ #define HSTIDR_DMA_4_Pos 29 /**< (HSTIDR) DMA Channel 4 Interrupt Disable Position */ #define HSTIDR_DMA_4 (_U_(0x1) << HSTIDR_DMA_4_Pos) /**< (HSTIDR) DMA Channel 4 Interrupt Disable Mask */ #define HSTIDR_DMA_5_Pos 30 /**< (HSTIDR) DMA Channel 5 Interrupt Disable Position */ #define HSTIDR_DMA_5 (_U_(0x1) << HSTIDR_DMA_5_Pos) /**< (HSTIDR) DMA Channel 5 Interrupt Disable Mask */ #define HSTIDR_DMA_6_Pos 31 /**< (HSTIDR) DMA Channel 6 Interrupt Disable Position */ #define HSTIDR_DMA_6 (_U_(0x1) << HSTIDR_DMA_6_Pos) /**< (HSTIDR) DMA Channel 6 Interrupt Disable Mask */ #define HSTIDR_Msk _U_(0xFE03FF7F) /**< (HSTIDR) Register Mask */ #define HSTIDR_PEP__Pos 8 /**< (HSTIDR Position) Pipe x Interrupt Disable */ #define HSTIDR_PEP_ (_U_(0x3FF) << HSTIDR_PEP__Pos) /**< (HSTIDR Mask) PEP_ */ #define HSTIDR_DMA__Pos 25 /**< (HSTIDR Position) DMA Channel 6 Interrupt Disable */ #define HSTIDR_DMA_ (_U_(0x7F) << HSTIDR_DMA__Pos) /**< (HSTIDR Mask) DMA_ */ /* -------- HSTIER : (USBHS Offset: 0x418) (/W 32) Host Global Interrupt Enable Register -------- */ #define HSTIER_OFFSET (0x418) /**< (HSTIER) Host Global Interrupt Enable Register Offset */ #define HSTIER_DCONNIES_Pos 0 /**< (HSTIER) Device Connection Interrupt Enable Position */ #define HSTIER_DCONNIES (_U_(0x1) << HSTIER_DCONNIES_Pos) /**< (HSTIER) Device Connection Interrupt Enable Mask */ #define HSTIER_DDISCIES_Pos 1 /**< (HSTIER) Device Disconnection Interrupt Enable Position */ #define HSTIER_DDISCIES (_U_(0x1) << HSTIER_DDISCIES_Pos) /**< (HSTIER) Device Disconnection Interrupt Enable Mask */ #define HSTIER_RSTIES_Pos 2 /**< (HSTIER) USB Reset Sent Interrupt Enable Position */ #define HSTIER_RSTIES (_U_(0x1) << HSTIER_RSTIES_Pos) /**< (HSTIER) USB Reset Sent Interrupt Enable Mask */ #define HSTIER_RSMEDIES_Pos 3 /**< (HSTIER) Downstream Resume Sent Interrupt Enable Position */ #define HSTIER_RSMEDIES (_U_(0x1) << HSTIER_RSMEDIES_Pos) /**< (HSTIER) Downstream Resume Sent Interrupt Enable Mask */ #define HSTIER_RXRSMIES_Pos 4 /**< (HSTIER) Upstream Resume Received Interrupt Enable Position */ #define HSTIER_RXRSMIES (_U_(0x1) << HSTIER_RXRSMIES_Pos) /**< (HSTIER) Upstream Resume Received Interrupt Enable Mask */ #define HSTIER_HSOFIES_Pos 5 /**< (HSTIER) Host Start of Frame Interrupt Enable Position */ #define HSTIER_HSOFIES (_U_(0x1) << HSTIER_HSOFIES_Pos) /**< (HSTIER) Host Start of Frame Interrupt Enable Mask */ #define HSTIER_HWUPIES_Pos 6 /**< (HSTIER) Host Wake-Up Interrupt Enable Position */ #define HSTIER_HWUPIES (_U_(0x1) << HSTIER_HWUPIES_Pos) /**< (HSTIER) Host Wake-Up Interrupt Enable Mask */ #define HSTIER_PEP_0_Pos 8 /**< (HSTIER) Pipe 0 Interrupt Enable Position */ #define HSTIER_PEP_0 (_U_(0x1) << HSTIER_PEP_0_Pos) /**< (HSTIER) Pipe 0 Interrupt Enable Mask */ #define HSTIER_PEP_1_Pos 9 /**< (HSTIER) Pipe 1 Interrupt Enable Position */ #define HSTIER_PEP_1 (_U_(0x1) << HSTIER_PEP_1_Pos) /**< (HSTIER) Pipe 1 Interrupt Enable Mask */ #define HSTIER_PEP_2_Pos 10 /**< (HSTIER) Pipe 2 Interrupt Enable Position */ #define HSTIER_PEP_2 (_U_(0x1) << HSTIER_PEP_2_Pos) /**< (HSTIER) Pipe 2 Interrupt Enable Mask */ #define HSTIER_PEP_3_Pos 11 /**< (HSTIER) Pipe 3 Interrupt Enable Position */ #define HSTIER_PEP_3 (_U_(0x1) << HSTIER_PEP_3_Pos) /**< (HSTIER) Pipe 3 Interrupt Enable Mask */ #define HSTIER_PEP_4_Pos 12 /**< (HSTIER) Pipe 4 Interrupt Enable Position */ #define HSTIER_PEP_4 (_U_(0x1) << HSTIER_PEP_4_Pos) /**< (HSTIER) Pipe 4 Interrupt Enable Mask */ #define HSTIER_PEP_5_Pos 13 /**< (HSTIER) Pipe 5 Interrupt Enable Position */ #define HSTIER_PEP_5 (_U_(0x1) << HSTIER_PEP_5_Pos) /**< (HSTIER) Pipe 5 Interrupt Enable Mask */ #define HSTIER_PEP_6_Pos 14 /**< (HSTIER) Pipe 6 Interrupt Enable Position */ #define HSTIER_PEP_6 (_U_(0x1) << HSTIER_PEP_6_Pos) /**< (HSTIER) Pipe 6 Interrupt Enable Mask */ #define HSTIER_PEP_7_Pos 15 /**< (HSTIER) Pipe 7 Interrupt Enable Position */ #define HSTIER_PEP_7 (_U_(0x1) << HSTIER_PEP_7_Pos) /**< (HSTIER) Pipe 7 Interrupt Enable Mask */ #define HSTIER_PEP_8_Pos 16 /**< (HSTIER) Pipe 8 Interrupt Enable Position */ #define HSTIER_PEP_8 (_U_(0x1) << HSTIER_PEP_8_Pos) /**< (HSTIER) Pipe 8 Interrupt Enable Mask */ #define HSTIER_PEP_9_Pos 17 /**< (HSTIER) Pipe 9 Interrupt Enable Position */ #define HSTIER_PEP_9 (_U_(0x1) << HSTIER_PEP_9_Pos) /**< (HSTIER) Pipe 9 Interrupt Enable Mask */ #define HSTIER_DMA_0_Pos 25 /**< (HSTIER) DMA Channel 0 Interrupt Enable Position */ #define HSTIER_DMA_0 (_U_(0x1) << HSTIER_DMA_0_Pos) /**< (HSTIER) DMA Channel 0 Interrupt Enable Mask */ #define HSTIER_DMA_1_Pos 26 /**< (HSTIER) DMA Channel 1 Interrupt Enable Position */ #define HSTIER_DMA_1 (_U_(0x1) << HSTIER_DMA_1_Pos) /**< (HSTIER) DMA Channel 1 Interrupt Enable Mask */ #define HSTIER_DMA_2_Pos 27 /**< (HSTIER) DMA Channel 2 Interrupt Enable Position */ #define HSTIER_DMA_2 (_U_(0x1) << HSTIER_DMA_2_Pos) /**< (HSTIER) DMA Channel 2 Interrupt Enable Mask */ #define HSTIER_DMA_3_Pos 28 /**< (HSTIER) DMA Channel 3 Interrupt Enable Position */ #define HSTIER_DMA_3 (_U_(0x1) << HSTIER_DMA_3_Pos) /**< (HSTIER) DMA Channel 3 Interrupt Enable Mask */ #define HSTIER_DMA_4_Pos 29 /**< (HSTIER) DMA Channel 4 Interrupt Enable Position */ #define HSTIER_DMA_4 (_U_(0x1) << HSTIER_DMA_4_Pos) /**< (HSTIER) DMA Channel 4 Interrupt Enable Mask */ #define HSTIER_DMA_5_Pos 30 /**< (HSTIER) DMA Channel 5 Interrupt Enable Position */ #define HSTIER_DMA_5 (_U_(0x1) << HSTIER_DMA_5_Pos) /**< (HSTIER) DMA Channel 5 Interrupt Enable Mask */ #define HSTIER_DMA_6_Pos 31 /**< (HSTIER) DMA Channel 6 Interrupt Enable Position */ #define HSTIER_DMA_6 (_U_(0x1) << HSTIER_DMA_6_Pos) /**< (HSTIER) DMA Channel 6 Interrupt Enable Mask */ #define HSTIER_Msk _U_(0xFE03FF7F) /**< (HSTIER) Register Mask */ #define HSTIER_PEP__Pos 8 /**< (HSTIER Position) Pipe x Interrupt Enable */ #define HSTIER_PEP_ (_U_(0x3FF) << HSTIER_PEP__Pos) /**< (HSTIER Mask) PEP_ */ #define HSTIER_DMA__Pos 25 /**< (HSTIER Position) DMA Channel 6 Interrupt Enable */ #define HSTIER_DMA_ (_U_(0x7F) << HSTIER_DMA__Pos) /**< (HSTIER Mask) DMA_ */ /* -------- HSTPIP : (USBHS Offset: 0x41c) (R/W 32) Host Pipe Register -------- */ #define HSTPIP_OFFSET (0x41C) /**< (HSTPIP) Host Pipe Register Offset */ #define HSTPIP_PEN0_Pos 0 /**< (HSTPIP) Pipe 0 Enable Position */ #define HSTPIP_PEN0 (_U_(0x1) << HSTPIP_PEN0_Pos) /**< (HSTPIP) Pipe 0 Enable Mask */ #define HSTPIP_PEN1_Pos 1 /**< (HSTPIP) Pipe 1 Enable Position */ #define HSTPIP_PEN1 (_U_(0x1) << HSTPIP_PEN1_Pos) /**< (HSTPIP) Pipe 1 Enable Mask */ #define HSTPIP_PEN2_Pos 2 /**< (HSTPIP) Pipe 2 Enable Position */ #define HSTPIP_PEN2 (_U_(0x1) << HSTPIP_PEN2_Pos) /**< (HSTPIP) Pipe 2 Enable Mask */ #define HSTPIP_PEN3_Pos 3 /**< (HSTPIP) Pipe 3 Enable Position */ #define HSTPIP_PEN3 (_U_(0x1) << HSTPIP_PEN3_Pos) /**< (HSTPIP) Pipe 3 Enable Mask */ #define HSTPIP_PEN4_Pos 4 /**< (HSTPIP) Pipe 4 Enable Position */ #define HSTPIP_PEN4 (_U_(0x1) << HSTPIP_PEN4_Pos) /**< (HSTPIP) Pipe 4 Enable Mask */ #define HSTPIP_PEN5_Pos 5 /**< (HSTPIP) Pipe 5 Enable Position */ #define HSTPIP_PEN5 (_U_(0x1) << HSTPIP_PEN5_Pos) /**< (HSTPIP) Pipe 5 Enable Mask */ #define HSTPIP_PEN6_Pos 6 /**< (HSTPIP) Pipe 6 Enable Position */ #define HSTPIP_PEN6 (_U_(0x1) << HSTPIP_PEN6_Pos) /**< (HSTPIP) Pipe 6 Enable Mask */ #define HSTPIP_PEN7_Pos 7 /**< (HSTPIP) Pipe 7 Enable Position */ #define HSTPIP_PEN7 (_U_(0x1) << HSTPIP_PEN7_Pos) /**< (HSTPIP) Pipe 7 Enable Mask */ #define HSTPIP_PEN8_Pos 8 /**< (HSTPIP) Pipe 8 Enable Position */ #define HSTPIP_PEN8 (_U_(0x1) << HSTPIP_PEN8_Pos) /**< (HSTPIP) Pipe 8 Enable Mask */ #define HSTPIP_PRST0_Pos 16 /**< (HSTPIP) Pipe 0 Reset Position */ #define HSTPIP_PRST0 (_U_(0x1) << HSTPIP_PRST0_Pos) /**< (HSTPIP) Pipe 0 Reset Mask */ #define HSTPIP_PRST1_Pos 17 /**< (HSTPIP) Pipe 1 Reset Position */ #define HSTPIP_PRST1 (_U_(0x1) << HSTPIP_PRST1_Pos) /**< (HSTPIP) Pipe 1 Reset Mask */ #define HSTPIP_PRST2_Pos 18 /**< (HSTPIP) Pipe 2 Reset Position */ #define HSTPIP_PRST2 (_U_(0x1) << HSTPIP_PRST2_Pos) /**< (HSTPIP) Pipe 2 Reset Mask */ #define HSTPIP_PRST3_Pos 19 /**< (HSTPIP) Pipe 3 Reset Position */ #define HSTPIP_PRST3 (_U_(0x1) << HSTPIP_PRST3_Pos) /**< (HSTPIP) Pipe 3 Reset Mask */ #define HSTPIP_PRST4_Pos 20 /**< (HSTPIP) Pipe 4 Reset Position */ #define HSTPIP_PRST4 (_U_(0x1) << HSTPIP_PRST4_Pos) /**< (HSTPIP) Pipe 4 Reset Mask */ #define HSTPIP_PRST5_Pos 21 /**< (HSTPIP) Pipe 5 Reset Position */ #define HSTPIP_PRST5 (_U_(0x1) << HSTPIP_PRST5_Pos) /**< (HSTPIP) Pipe 5 Reset Mask */ #define HSTPIP_PRST6_Pos 22 /**< (HSTPIP) Pipe 6 Reset Position */ #define HSTPIP_PRST6 (_U_(0x1) << HSTPIP_PRST6_Pos) /**< (HSTPIP) Pipe 6 Reset Mask */ #define HSTPIP_PRST7_Pos 23 /**< (HSTPIP) Pipe 7 Reset Position */ #define HSTPIP_PRST7 (_U_(0x1) << HSTPIP_PRST7_Pos) /**< (HSTPIP) Pipe 7 Reset Mask */ #define HSTPIP_PRST8_Pos 24 /**< (HSTPIP) Pipe 8 Reset Position */ #define HSTPIP_PRST8 (_U_(0x1) << HSTPIP_PRST8_Pos) /**< (HSTPIP) Pipe 8 Reset Mask */ #define HSTPIP_Msk _U_(0x1FF01FF) /**< (HSTPIP) Register Mask */ #define HSTPIP_PEN_Pos 0 /**< (HSTPIP Position) Pipe x Enable */ #define HSTPIP_PEN (_U_(0x1FF) << HSTPIP_PEN_Pos) /**< (HSTPIP Mask) PEN */ #define HSTPIP_PRST_Pos 16 /**< (HSTPIP Position) Pipe 8 Reset */ #define HSTPIP_PRST (_U_(0x1FF) << HSTPIP_PRST_Pos) /**< (HSTPIP Mask) PRST */ /* -------- HSTFNUM : (USBHS Offset: 0x420) (R/W 32) Host Frame Number Register -------- */ #define HSTFNUM_OFFSET (0x420) /**< (HSTFNUM) Host Frame Number Register Offset */ #define HSTFNUM_MFNUM_Pos 0 /**< (HSTFNUM) Micro Frame Number Position */ #define HSTFNUM_MFNUM (_U_(0x7) << HSTFNUM_MFNUM_Pos) /**< (HSTFNUM) Micro Frame Number Mask */ #define HSTFNUM_FNUM_Pos 3 /**< (HSTFNUM) Frame Number Position */ #define HSTFNUM_FNUM (_U_(0x7FF) << HSTFNUM_FNUM_Pos) /**< (HSTFNUM) Frame Number Mask */ #define HSTFNUM_FLENHIGH_Pos 16 /**< (HSTFNUM) Frame Length Position */ #define HSTFNUM_FLENHIGH (_U_(0xFF) << HSTFNUM_FLENHIGH_Pos) /**< (HSTFNUM) Frame Length Mask */ #define HSTFNUM_Msk _U_(0xFF3FFF) /**< (HSTFNUM) Register Mask */ /* -------- HSTADDR1 : (USBHS Offset: 0x424) (R/W 32) Host Address 1 Register -------- */ #define HSTADDR1_OFFSET (0x424) /**< (HSTADDR1) Host Address 1 Register Offset */ #define HSTADDR1_HSTADDRP0_Pos 0 /**< (HSTADDR1) USB Host Address Position */ #define HSTADDR1_HSTADDRP0 (_U_(0x7F) << HSTADDR1_HSTADDRP0_Pos) /**< (HSTADDR1) USB Host Address Mask */ #define HSTADDR1_HSTADDRP1_Pos 8 /**< (HSTADDR1) USB Host Address Position */ #define HSTADDR1_HSTADDRP1 (_U_(0x7F) << HSTADDR1_HSTADDRP1_Pos) /**< (HSTADDR1) USB Host Address Mask */ #define HSTADDR1_HSTADDRP2_Pos 16 /**< (HSTADDR1) USB Host Address Position */ #define HSTADDR1_HSTADDRP2 (_U_(0x7F) << HSTADDR1_HSTADDRP2_Pos) /**< (HSTADDR1) USB Host Address Mask */ #define HSTADDR1_HSTADDRP3_Pos 24 /**< (HSTADDR1) USB Host Address Position */ #define HSTADDR1_HSTADDRP3 (_U_(0x7F) << HSTADDR1_HSTADDRP3_Pos) /**< (HSTADDR1) USB Host Address Mask */ #define HSTADDR1_Msk _U_(0x7F7F7F7F) /**< (HSTADDR1) Register Mask */ /* -------- HSTADDR2 : (USBHS Offset: 0x428) (R/W 32) Host Address 2 Register -------- */ #define HSTADDR2_OFFSET (0x428) /**< (HSTADDR2) Host Address 2 Register Offset */ #define HSTADDR2_HSTADDRP4_Pos 0 /**< (HSTADDR2) USB Host Address Position */ #define HSTADDR2_HSTADDRP4 (_U_(0x7F) << HSTADDR2_HSTADDRP4_Pos) /**< (HSTADDR2) USB Host Address Mask */ #define HSTADDR2_HSTADDRP5_Pos 8 /**< (HSTADDR2) USB Host Address Position */ #define HSTADDR2_HSTADDRP5 (_U_(0x7F) << HSTADDR2_HSTADDRP5_Pos) /**< (HSTADDR2) USB Host Address Mask */ #define HSTADDR2_HSTADDRP6_Pos 16 /**< (HSTADDR2) USB Host Address Position */ #define HSTADDR2_HSTADDRP6 (_U_(0x7F) << HSTADDR2_HSTADDRP6_Pos) /**< (HSTADDR2) USB Host Address Mask */ #define HSTADDR2_HSTADDRP7_Pos 24 /**< (HSTADDR2) USB Host Address Position */ #define HSTADDR2_HSTADDRP7 (_U_(0x7F) << HSTADDR2_HSTADDRP7_Pos) /**< (HSTADDR2) USB Host Address Mask */ #define HSTADDR2_Msk _U_(0x7F7F7F7F) /**< (HSTADDR2) Register Mask */ /* -------- HSTADDR3 : (USBHS Offset: 0x42c) (R/W 32) Host Address 3 Register -------- */ #define HSTADDR3_OFFSET (0x42C) /**< (HSTADDR3) Host Address 3 Register Offset */ #define HSTADDR3_HSTADDRP8_Pos 0 /**< (HSTADDR3) USB Host Address Position */ #define HSTADDR3_HSTADDRP8 (_U_(0x7F) << HSTADDR3_HSTADDRP8_Pos) /**< (HSTADDR3) USB Host Address Mask */ #define HSTADDR3_HSTADDRP9_Pos 8 /**< (HSTADDR3) USB Host Address Position */ #define HSTADDR3_HSTADDRP9 (_U_(0x7F) << HSTADDR3_HSTADDRP9_Pos) /**< (HSTADDR3) USB Host Address Mask */ #define HSTADDR3_Msk _U_(0x7F7F) /**< (HSTADDR3) Register Mask */ /* -------- HSTPIPCFG : (USBHS Offset: 0x500) (R/W 32) Host Pipe Configuration Register -------- */ #define HSTPIPCFG_OFFSET (0x500) /**< (HSTPIPCFG) Host Pipe Configuration Register Offset */ #define HSTPIPCFG_ALLOC_Pos 1 /**< (HSTPIPCFG) Pipe Memory Allocate Position */ #define HSTPIPCFG_ALLOC (_U_(0x1) << HSTPIPCFG_ALLOC_Pos) /**< (HSTPIPCFG) Pipe Memory Allocate Mask */ #define HSTPIPCFG_PBK_Pos 2 /**< (HSTPIPCFG) Pipe Banks Position */ #define HSTPIPCFG_PBK (_U_(0x3) << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Pipe Banks Mask */ #define HSTPIPCFG_PBK_1_BANK_Val _U_(0x0) /**< (HSTPIPCFG) Single-bank pipe */ #define HSTPIPCFG_PBK_2_BANK_Val _U_(0x1) /**< (HSTPIPCFG) Double-bank pipe */ #define HSTPIPCFG_PBK_3_BANK_Val _U_(0x2) /**< (HSTPIPCFG) Triple-bank pipe */ #define HSTPIPCFG_PBK_1_BANK (HSTPIPCFG_PBK_1_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Single-bank pipe Position */ #define HSTPIPCFG_PBK_2_BANK (HSTPIPCFG_PBK_2_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Double-bank pipe Position */ #define HSTPIPCFG_PBK_3_BANK (HSTPIPCFG_PBK_3_BANK_Val << HSTPIPCFG_PBK_Pos) /**< (HSTPIPCFG) Triple-bank pipe Position */ #define HSTPIPCFG_PSIZE_Pos 4 /**< (HSTPIPCFG) Pipe Size Position */ #define HSTPIPCFG_PSIZE (_U_(0x7) << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) Pipe Size Mask */ #define HSTPIPCFG_PSIZE_8_BYTE_Val _U_(0x0) /**< (HSTPIPCFG) 8 bytes */ #define HSTPIPCFG_PSIZE_16_BYTE_Val _U_(0x1) /**< (HSTPIPCFG) 16 bytes */ #define HSTPIPCFG_PSIZE_32_BYTE_Val _U_(0x2) /**< (HSTPIPCFG) 32 bytes */ #define HSTPIPCFG_PSIZE_64_BYTE_Val _U_(0x3) /**< (HSTPIPCFG) 64 bytes */ #define HSTPIPCFG_PSIZE_128_BYTE_Val _U_(0x4) /**< (HSTPIPCFG) 128 bytes */ #define HSTPIPCFG_PSIZE_256_BYTE_Val _U_(0x5) /**< (HSTPIPCFG) 256 bytes */ #define HSTPIPCFG_PSIZE_512_BYTE_Val _U_(0x6) /**< (HSTPIPCFG) 512 bytes */ #define HSTPIPCFG_PSIZE_1024_BYTE_Val _U_(0x7) /**< (HSTPIPCFG) 1024 bytes */ #define HSTPIPCFG_PSIZE_8_BYTE (HSTPIPCFG_PSIZE_8_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 8 bytes Position */ #define HSTPIPCFG_PSIZE_16_BYTE (HSTPIPCFG_PSIZE_16_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 16 bytes Position */ #define HSTPIPCFG_PSIZE_32_BYTE (HSTPIPCFG_PSIZE_32_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 32 bytes Position */ #define HSTPIPCFG_PSIZE_64_BYTE (HSTPIPCFG_PSIZE_64_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 64 bytes Position */ #define HSTPIPCFG_PSIZE_128_BYTE (HSTPIPCFG_PSIZE_128_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 128 bytes Position */ #define HSTPIPCFG_PSIZE_256_BYTE (HSTPIPCFG_PSIZE_256_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 256 bytes Position */ #define HSTPIPCFG_PSIZE_512_BYTE (HSTPIPCFG_PSIZE_512_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 512 bytes Position */ #define HSTPIPCFG_PSIZE_1024_BYTE (HSTPIPCFG_PSIZE_1024_BYTE_Val << HSTPIPCFG_PSIZE_Pos) /**< (HSTPIPCFG) 1024 bytes Position */ #define HSTPIPCFG_PTOKEN_Pos 8 /**< (HSTPIPCFG) Pipe Token Position */ #define HSTPIPCFG_PTOKEN (_U_(0x3) << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) Pipe Token Mask */ #define HSTPIPCFG_PTOKEN_SETUP_Val _U_(0x0) /**< (HSTPIPCFG) SETUP */ #define HSTPIPCFG_PTOKEN_IN_Val _U_(0x1) /**< (HSTPIPCFG) IN */ #define HSTPIPCFG_PTOKEN_OUT_Val _U_(0x2) /**< (HSTPIPCFG) OUT */ #define HSTPIPCFG_PTOKEN_SETUP (HSTPIPCFG_PTOKEN_SETUP_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) SETUP Position */ #define HSTPIPCFG_PTOKEN_IN (HSTPIPCFG_PTOKEN_IN_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) IN Position */ #define HSTPIPCFG_PTOKEN_OUT (HSTPIPCFG_PTOKEN_OUT_Val << HSTPIPCFG_PTOKEN_Pos) /**< (HSTPIPCFG) OUT Position */ #define HSTPIPCFG_AUTOSW_Pos 10 /**< (HSTPIPCFG) Automatic Switch Position */ #define HSTPIPCFG_AUTOSW (_U_(0x1) << HSTPIPCFG_AUTOSW_Pos) /**< (HSTPIPCFG) Automatic Switch Mask */ #define HSTPIPCFG_PTYPE_Pos 12 /**< (HSTPIPCFG) Pipe Type Position */ #define HSTPIPCFG_PTYPE (_U_(0x3) << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Pipe Type Mask */ #define HSTPIPCFG_PTYPE_CTRL_Val _U_(0x0) /**< (HSTPIPCFG) Control */ #define HSTPIPCFG_PTYPE_ISO_Val _U_(0x1) /**< (HSTPIPCFG) Isochronous */ #define HSTPIPCFG_PTYPE_BLK_Val _U_(0x2) /**< (HSTPIPCFG) Bulk */ #define HSTPIPCFG_PTYPE_INTRPT_Val _U_(0x3) /**< (HSTPIPCFG) Interrupt */ #define HSTPIPCFG_PTYPE_CTRL (HSTPIPCFG_PTYPE_CTRL_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Control Position */ #define HSTPIPCFG_PTYPE_ISO (HSTPIPCFG_PTYPE_ISO_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Isochronous Position */ #define HSTPIPCFG_PTYPE_BLK (HSTPIPCFG_PTYPE_BLK_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Bulk Position */ #define HSTPIPCFG_PTYPE_INTRPT (HSTPIPCFG_PTYPE_INTRPT_Val << HSTPIPCFG_PTYPE_Pos) /**< (HSTPIPCFG) Interrupt Position */ #define HSTPIPCFG_PEPNUM_Pos 16 /**< (HSTPIPCFG) Pipe Endpoint Number Position */ #define HSTPIPCFG_PEPNUM (_U_(0xF) << HSTPIPCFG_PEPNUM_Pos) /**< (HSTPIPCFG) Pipe Endpoint Number Mask */ #define HSTPIPCFG_INTFRQ_Pos 24 /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Position */ #define HSTPIPCFG_INTFRQ (_U_(0xFF) << HSTPIPCFG_INTFRQ_Pos) /**< (HSTPIPCFG) Pipe Interrupt Request Frequency Mask */ #define HSTPIPCFG_Msk _U_(0xFF0F377E) /**< (HSTPIPCFG) Register Mask */ /* CTRL_BULK mode */ #define HSTPIPCFG_CTRL_BULK_PINGEN_Pos 20 /**< (HSTPIPCFG) Ping Enable Position */ #define HSTPIPCFG_CTRL_BULK_PINGEN (_U_(0x1) << HSTPIPCFG_CTRL_BULK_PINGEN_Pos) /**< (HSTPIPCFG) Ping Enable Mask */ #define HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos 24 /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Position */ #define HSTPIPCFG_CTRL_BULK_BINTERVAL (_U_(0xFF) << HSTPIPCFG_CTRL_BULK_BINTERVAL_Pos) /**< (HSTPIPCFG) bInterval Parameter for the Bulk-Out/Ping Transaction Mask */ #define HSTPIPCFG_CTRL_BULK_Msk _U_(0xFF100000) /**< (HSTPIPCFG_CTRL_BULK) Register Mask */ /* -------- HSTPIPISR : (USBHS Offset: 0x530) (R/ 32) Host Pipe Status Register -------- */ #define HSTPIPISR_OFFSET (0x530) /**< (HSTPIPISR) Host Pipe Status Register Offset */ #define HSTPIPISR_RXINI_Pos 0 /**< (HSTPIPISR) Received IN Data Interrupt Position */ #define HSTPIPISR_RXINI (_U_(0x1) << HSTPIPISR_RXINI_Pos) /**< (HSTPIPISR) Received IN Data Interrupt Mask */ #define HSTPIPISR_TXOUTI_Pos 1 /**< (HSTPIPISR) Transmitted OUT Data Interrupt Position */ #define HSTPIPISR_TXOUTI (_U_(0x1) << HSTPIPISR_TXOUTI_Pos) /**< (HSTPIPISR) Transmitted OUT Data Interrupt Mask */ #define HSTPIPISR_PERRI_Pos 3 /**< (HSTPIPISR) Pipe Error Interrupt Position */ #define HSTPIPISR_PERRI (_U_(0x1) << HSTPIPISR_PERRI_Pos) /**< (HSTPIPISR) Pipe Error Interrupt Mask */ #define HSTPIPISR_NAKEDI_Pos 4 /**< (HSTPIPISR) NAKed Interrupt Position */ #define HSTPIPISR_NAKEDI (_U_(0x1) << HSTPIPISR_NAKEDI_Pos) /**< (HSTPIPISR) NAKed Interrupt Mask */ #define HSTPIPISR_OVERFI_Pos 5 /**< (HSTPIPISR) Overflow Interrupt Position */ #define HSTPIPISR_OVERFI (_U_(0x1) << HSTPIPISR_OVERFI_Pos) /**< (HSTPIPISR) Overflow Interrupt Mask */ #define HSTPIPISR_SHORTPACKETI_Pos 7 /**< (HSTPIPISR) Short Packet Interrupt Position */ #define HSTPIPISR_SHORTPACKETI (_U_(0x1) << HSTPIPISR_SHORTPACKETI_Pos) /**< (HSTPIPISR) Short Packet Interrupt Mask */ #define HSTPIPISR_DTSEQ_Pos 8 /**< (HSTPIPISR) Data Toggle Sequence Position */ #define HSTPIPISR_DTSEQ (_U_(0x3) << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data Toggle Sequence Mask */ #define HSTPIPISR_DTSEQ_DATA0_Val _U_(0x0) /**< (HSTPIPISR) Data0 toggle sequence */ #define HSTPIPISR_DTSEQ_DATA1_Val _U_(0x1) /**< (HSTPIPISR) Data1 toggle sequence */ #define HSTPIPISR_DTSEQ_DATA0 (HSTPIPISR_DTSEQ_DATA0_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data0 toggle sequence Position */ #define HSTPIPISR_DTSEQ_DATA1 (HSTPIPISR_DTSEQ_DATA1_Val << HSTPIPISR_DTSEQ_Pos) /**< (HSTPIPISR) Data1 toggle sequence Position */ #define HSTPIPISR_NBUSYBK_Pos 12 /**< (HSTPIPISR) Number of Busy Banks Position */ #define HSTPIPISR_NBUSYBK (_U_(0x3) << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) Number of Busy Banks Mask */ #define HSTPIPISR_NBUSYBK_0_BUSY_Val _U_(0x0) /**< (HSTPIPISR) 0 busy bank (all banks free) */ #define HSTPIPISR_NBUSYBK_1_BUSY_Val _U_(0x1) /**< (HSTPIPISR) 1 busy bank */ #define HSTPIPISR_NBUSYBK_2_BUSY_Val _U_(0x2) /**< (HSTPIPISR) 2 busy banks */ #define HSTPIPISR_NBUSYBK_3_BUSY_Val _U_(0x3) /**< (HSTPIPISR) 3 busy banks */ #define HSTPIPISR_NBUSYBK_0_BUSY (HSTPIPISR_NBUSYBK_0_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 0 busy bank (all banks free) Position */ #define HSTPIPISR_NBUSYBK_1_BUSY (HSTPIPISR_NBUSYBK_1_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 1 busy bank Position */ #define HSTPIPISR_NBUSYBK_2_BUSY (HSTPIPISR_NBUSYBK_2_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 2 busy banks Position */ #define HSTPIPISR_NBUSYBK_3_BUSY (HSTPIPISR_NBUSYBK_3_BUSY_Val << HSTPIPISR_NBUSYBK_Pos) /**< (HSTPIPISR) 3 busy banks Position */ #define HSTPIPISR_CURRBK_Pos 14 /**< (HSTPIPISR) Current Bank Position */ #define HSTPIPISR_CURRBK (_U_(0x3) << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current Bank Mask */ #define HSTPIPISR_CURRBK_BANK0_Val _U_(0x0) /**< (HSTPIPISR) Current bank is bank0 */ #define HSTPIPISR_CURRBK_BANK1_Val _U_(0x1) /**< (HSTPIPISR) Current bank is bank1 */ #define HSTPIPISR_CURRBK_BANK2_Val _U_(0x2) /**< (HSTPIPISR) Current bank is bank2 */ #define HSTPIPISR_CURRBK_BANK0 (HSTPIPISR_CURRBK_BANK0_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank0 Position */ #define HSTPIPISR_CURRBK_BANK1 (HSTPIPISR_CURRBK_BANK1_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank1 Position */ #define HSTPIPISR_CURRBK_BANK2 (HSTPIPISR_CURRBK_BANK2_Val << HSTPIPISR_CURRBK_Pos) /**< (HSTPIPISR) Current bank is bank2 Position */ #define HSTPIPISR_RWALL_Pos 16 /**< (HSTPIPISR) Read/Write Allowed Position */ #define HSTPIPISR_RWALL (_U_(0x1) << HSTPIPISR_RWALL_Pos) /**< (HSTPIPISR) Read/Write Allowed Mask */ #define HSTPIPISR_CFGOK_Pos 18 /**< (HSTPIPISR) Configuration OK Status Position */ #define HSTPIPISR_CFGOK (_U_(0x1) << HSTPIPISR_CFGOK_Pos) /**< (HSTPIPISR) Configuration OK Status Mask */ #define HSTPIPISR_PBYCT_Pos 20 /**< (HSTPIPISR) Pipe Byte Count Position */ #define HSTPIPISR_PBYCT (_U_(0x7FF) << HSTPIPISR_PBYCT_Pos) /**< (HSTPIPISR) Pipe Byte Count Mask */ #define HSTPIPISR_Msk _U_(0x7FF5F3BB) /**< (HSTPIPISR) Register Mask */ /* CTRL mode */ #define HSTPIPISR_CTRL_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ #define HSTPIPISR_CTRL_TXSTPI (_U_(0x1) << HSTPIPISR_CTRL_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ #define HSTPIPISR_CTRL_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ #define HSTPIPISR_CTRL_RXSTALLDI (_U_(0x1) << HSTPIPISR_CTRL_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ #define HSTPIPISR_CTRL_Msk _U_(0x44) /**< (HSTPIPISR_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPISR_ISO_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ #define HSTPIPISR_ISO_UNDERFI (_U_(0x1) << HSTPIPISR_ISO_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ #define HSTPIPISR_ISO_CRCERRI_Pos 6 /**< (HSTPIPISR) CRC Error Interrupt Position */ #define HSTPIPISR_ISO_CRCERRI (_U_(0x1) << HSTPIPISR_ISO_CRCERRI_Pos) /**< (HSTPIPISR) CRC Error Interrupt Mask */ #define HSTPIPISR_ISO_Msk _U_(0x44) /**< (HSTPIPISR_ISO) Register Mask */ /* BLK mode */ #define HSTPIPISR_BLK_TXSTPI_Pos 2 /**< (HSTPIPISR) Transmitted SETUP Interrupt Position */ #define HSTPIPISR_BLK_TXSTPI (_U_(0x1) << HSTPIPISR_BLK_TXSTPI_Pos) /**< (HSTPIPISR) Transmitted SETUP Interrupt Mask */ #define HSTPIPISR_BLK_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ #define HSTPIPISR_BLK_RXSTALLDI (_U_(0x1) << HSTPIPISR_BLK_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ #define HSTPIPISR_BLK_Msk _U_(0x44) /**< (HSTPIPISR_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPISR_INTRPT_UNDERFI_Pos 2 /**< (HSTPIPISR) Underflow Interrupt Position */ #define HSTPIPISR_INTRPT_UNDERFI (_U_(0x1) << HSTPIPISR_INTRPT_UNDERFI_Pos) /**< (HSTPIPISR) Underflow Interrupt Mask */ #define HSTPIPISR_INTRPT_RXSTALLDI_Pos 6 /**< (HSTPIPISR) Received STALLed Interrupt Position */ #define HSTPIPISR_INTRPT_RXSTALLDI (_U_(0x1) << HSTPIPISR_INTRPT_RXSTALLDI_Pos) /**< (HSTPIPISR) Received STALLed Interrupt Mask */ #define HSTPIPISR_INTRPT_Msk _U_(0x44) /**< (HSTPIPISR_INTRPT) Register Mask */ /* -------- HSTPIPICR : (USBHS Offset: 0x560) (/W 32) Host Pipe Clear Register -------- */ #define HSTPIPICR_OFFSET (0x560) /**< (HSTPIPICR) Host Pipe Clear Register Offset */ #define HSTPIPICR_RXINIC_Pos 0 /**< (HSTPIPICR) Received IN Data Interrupt Clear Position */ #define HSTPIPICR_RXINIC (_U_(0x1) << HSTPIPICR_RXINIC_Pos) /**< (HSTPIPICR) Received IN Data Interrupt Clear Mask */ #define HSTPIPICR_TXOUTIC_Pos 1 /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Position */ #define HSTPIPICR_TXOUTIC (_U_(0x1) << HSTPIPICR_TXOUTIC_Pos) /**< (HSTPIPICR) Transmitted OUT Data Interrupt Clear Mask */ #define HSTPIPICR_NAKEDIC_Pos 4 /**< (HSTPIPICR) NAKed Interrupt Clear Position */ #define HSTPIPICR_NAKEDIC (_U_(0x1) << HSTPIPICR_NAKEDIC_Pos) /**< (HSTPIPICR) NAKed Interrupt Clear Mask */ #define HSTPIPICR_OVERFIC_Pos 5 /**< (HSTPIPICR) Overflow Interrupt Clear Position */ #define HSTPIPICR_OVERFIC (_U_(0x1) << HSTPIPICR_OVERFIC_Pos) /**< (HSTPIPICR) Overflow Interrupt Clear Mask */ #define HSTPIPICR_SHORTPACKETIC_Pos 7 /**< (HSTPIPICR) Short Packet Interrupt Clear Position */ #define HSTPIPICR_SHORTPACKETIC (_U_(0x1) << HSTPIPICR_SHORTPACKETIC_Pos) /**< (HSTPIPICR) Short Packet Interrupt Clear Mask */ #define HSTPIPICR_Msk _U_(0xB3) /**< (HSTPIPICR) Register Mask */ /* CTRL mode */ #define HSTPIPICR_CTRL_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ #define HSTPIPICR_CTRL_TXSTPIC (_U_(0x1) << HSTPIPICR_CTRL_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ #define HSTPIPICR_CTRL_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ #define HSTPIPICR_CTRL_RXSTALLDIC (_U_(0x1) << HSTPIPICR_CTRL_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ #define HSTPIPICR_CTRL_Msk _U_(0x44) /**< (HSTPIPICR_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPICR_ISO_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ #define HSTPIPICR_ISO_UNDERFIC (_U_(0x1) << HSTPIPICR_ISO_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ #define HSTPIPICR_ISO_CRCERRIC_Pos 6 /**< (HSTPIPICR) CRC Error Interrupt Clear Position */ #define HSTPIPICR_ISO_CRCERRIC (_U_(0x1) << HSTPIPICR_ISO_CRCERRIC_Pos) /**< (HSTPIPICR) CRC Error Interrupt Clear Mask */ #define HSTPIPICR_ISO_Msk _U_(0x44) /**< (HSTPIPICR_ISO) Register Mask */ /* BLK mode */ #define HSTPIPICR_BLK_TXSTPIC_Pos 2 /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Position */ #define HSTPIPICR_BLK_TXSTPIC (_U_(0x1) << HSTPIPICR_BLK_TXSTPIC_Pos) /**< (HSTPIPICR) Transmitted SETUP Interrupt Clear Mask */ #define HSTPIPICR_BLK_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ #define HSTPIPICR_BLK_RXSTALLDIC (_U_(0x1) << HSTPIPICR_BLK_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ #define HSTPIPICR_BLK_Msk _U_(0x44) /**< (HSTPIPICR_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPICR_INTRPT_UNDERFIC_Pos 2 /**< (HSTPIPICR) Underflow Interrupt Clear Position */ #define HSTPIPICR_INTRPT_UNDERFIC (_U_(0x1) << HSTPIPICR_INTRPT_UNDERFIC_Pos) /**< (HSTPIPICR) Underflow Interrupt Clear Mask */ #define HSTPIPICR_INTRPT_RXSTALLDIC_Pos 6 /**< (HSTPIPICR) Received STALLed Interrupt Clear Position */ #define HSTPIPICR_INTRPT_RXSTALLDIC (_U_(0x1) << HSTPIPICR_INTRPT_RXSTALLDIC_Pos) /**< (HSTPIPICR) Received STALLed Interrupt Clear Mask */ #define HSTPIPICR_INTRPT_Msk _U_(0x44) /**< (HSTPIPICR_INTRPT) Register Mask */ /* -------- HSTPIPIFR : (USBHS Offset: 0x590) (/W 32) Host Pipe Set Register -------- */ #define HSTPIPIFR_OFFSET (0x590) /**< (HSTPIPIFR) Host Pipe Set Register Offset */ #define HSTPIPIFR_RXINIS_Pos 0 /**< (HSTPIPIFR) Received IN Data Interrupt Set Position */ #define HSTPIPIFR_RXINIS (_U_(0x1) << HSTPIPIFR_RXINIS_Pos) /**< (HSTPIPIFR) Received IN Data Interrupt Set Mask */ #define HSTPIPIFR_TXOUTIS_Pos 1 /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Position */ #define HSTPIPIFR_TXOUTIS (_U_(0x1) << HSTPIPIFR_TXOUTIS_Pos) /**< (HSTPIPIFR) Transmitted OUT Data Interrupt Set Mask */ #define HSTPIPIFR_PERRIS_Pos 3 /**< (HSTPIPIFR) Pipe Error Interrupt Set Position */ #define HSTPIPIFR_PERRIS (_U_(0x1) << HSTPIPIFR_PERRIS_Pos) /**< (HSTPIPIFR) Pipe Error Interrupt Set Mask */ #define HSTPIPIFR_NAKEDIS_Pos 4 /**< (HSTPIPIFR) NAKed Interrupt Set Position */ #define HSTPIPIFR_NAKEDIS (_U_(0x1) << HSTPIPIFR_NAKEDIS_Pos) /**< (HSTPIPIFR) NAKed Interrupt Set Mask */ #define HSTPIPIFR_OVERFIS_Pos 5 /**< (HSTPIPIFR) Overflow Interrupt Set Position */ #define HSTPIPIFR_OVERFIS (_U_(0x1) << HSTPIPIFR_OVERFIS_Pos) /**< (HSTPIPIFR) Overflow Interrupt Set Mask */ #define HSTPIPIFR_SHORTPACKETIS_Pos 7 /**< (HSTPIPIFR) Short Packet Interrupt Set Position */ #define HSTPIPIFR_SHORTPACKETIS (_U_(0x1) << HSTPIPIFR_SHORTPACKETIS_Pos) /**< (HSTPIPIFR) Short Packet Interrupt Set Mask */ #define HSTPIPIFR_NBUSYBKS_Pos 12 /**< (HSTPIPIFR) Number of Busy Banks Set Position */ #define HSTPIPIFR_NBUSYBKS (_U_(0x1) << HSTPIPIFR_NBUSYBKS_Pos) /**< (HSTPIPIFR) Number of Busy Banks Set Mask */ #define HSTPIPIFR_Msk _U_(0x10BB) /**< (HSTPIPIFR) Register Mask */ /* CTRL mode */ #define HSTPIPIFR_CTRL_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ #define HSTPIPIFR_CTRL_TXSTPIS (_U_(0x1) << HSTPIPIFR_CTRL_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ #define HSTPIPIFR_CTRL_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ #define HSTPIPIFR_CTRL_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_CTRL_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ #define HSTPIPIFR_CTRL_Msk _U_(0x44) /**< (HSTPIPIFR_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPIFR_ISO_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ #define HSTPIPIFR_ISO_UNDERFIS (_U_(0x1) << HSTPIPIFR_ISO_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ #define HSTPIPIFR_ISO_CRCERRIS_Pos 6 /**< (HSTPIPIFR) CRC Error Interrupt Set Position */ #define HSTPIPIFR_ISO_CRCERRIS (_U_(0x1) << HSTPIPIFR_ISO_CRCERRIS_Pos) /**< (HSTPIPIFR) CRC Error Interrupt Set Mask */ #define HSTPIPIFR_ISO_Msk _U_(0x44) /**< (HSTPIPIFR_ISO) Register Mask */ /* BLK mode */ #define HSTPIPIFR_BLK_TXSTPIS_Pos 2 /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Position */ #define HSTPIPIFR_BLK_TXSTPIS (_U_(0x1) << HSTPIPIFR_BLK_TXSTPIS_Pos) /**< (HSTPIPIFR) Transmitted SETUP Interrupt Set Mask */ #define HSTPIPIFR_BLK_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ #define HSTPIPIFR_BLK_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_BLK_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ #define HSTPIPIFR_BLK_Msk _U_(0x44) /**< (HSTPIPIFR_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPIFR_INTRPT_UNDERFIS_Pos 2 /**< (HSTPIPIFR) Underflow Interrupt Set Position */ #define HSTPIPIFR_INTRPT_UNDERFIS (_U_(0x1) << HSTPIPIFR_INTRPT_UNDERFIS_Pos) /**< (HSTPIPIFR) Underflow Interrupt Set Mask */ #define HSTPIPIFR_INTRPT_RXSTALLDIS_Pos 6 /**< (HSTPIPIFR) Received STALLed Interrupt Set Position */ #define HSTPIPIFR_INTRPT_RXSTALLDIS (_U_(0x1) << HSTPIPIFR_INTRPT_RXSTALLDIS_Pos) /**< (HSTPIPIFR) Received STALLed Interrupt Set Mask */ #define HSTPIPIFR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIFR_INTRPT) Register Mask */ /* -------- HSTPIPIMR : (USBHS Offset: 0x5c0) (R/ 32) Host Pipe Mask Register -------- */ #define HSTPIPIMR_OFFSET (0x5C0) /**< (HSTPIPIMR) Host Pipe Mask Register Offset */ #define HSTPIPIMR_RXINE_Pos 0 /**< (HSTPIPIMR) Received IN Data Interrupt Enable Position */ #define HSTPIPIMR_RXINE (_U_(0x1) << HSTPIPIMR_RXINE_Pos) /**< (HSTPIPIMR) Received IN Data Interrupt Enable Mask */ #define HSTPIPIMR_TXOUTE_Pos 1 /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Position */ #define HSTPIPIMR_TXOUTE (_U_(0x1) << HSTPIPIMR_TXOUTE_Pos) /**< (HSTPIPIMR) Transmitted OUT Data Interrupt Enable Mask */ #define HSTPIPIMR_PERRE_Pos 3 /**< (HSTPIPIMR) Pipe Error Interrupt Enable Position */ #define HSTPIPIMR_PERRE (_U_(0x1) << HSTPIPIMR_PERRE_Pos) /**< (HSTPIPIMR) Pipe Error Interrupt Enable Mask */ #define HSTPIPIMR_NAKEDE_Pos 4 /**< (HSTPIPIMR) NAKed Interrupt Enable Position */ #define HSTPIPIMR_NAKEDE (_U_(0x1) << HSTPIPIMR_NAKEDE_Pos) /**< (HSTPIPIMR) NAKed Interrupt Enable Mask */ #define HSTPIPIMR_OVERFIE_Pos 5 /**< (HSTPIPIMR) Overflow Interrupt Enable Position */ #define HSTPIPIMR_OVERFIE (_U_(0x1) << HSTPIPIMR_OVERFIE_Pos) /**< (HSTPIPIMR) Overflow Interrupt Enable Mask */ #define HSTPIPIMR_SHORTPACKETIE_Pos 7 /**< (HSTPIPIMR) Short Packet Interrupt Enable Position */ #define HSTPIPIMR_SHORTPACKETIE (_U_(0x1) << HSTPIPIMR_SHORTPACKETIE_Pos) /**< (HSTPIPIMR) Short Packet Interrupt Enable Mask */ #define HSTPIPIMR_NBUSYBKE_Pos 12 /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Position */ #define HSTPIPIMR_NBUSYBKE (_U_(0x1) << HSTPIPIMR_NBUSYBKE_Pos) /**< (HSTPIPIMR) Number of Busy Banks Interrupt Enable Mask */ #define HSTPIPIMR_FIFOCON_Pos 14 /**< (HSTPIPIMR) FIFO Control Position */ #define HSTPIPIMR_FIFOCON (_U_(0x1) << HSTPIPIMR_FIFOCON_Pos) /**< (HSTPIPIMR) FIFO Control Mask */ #define HSTPIPIMR_PDISHDMA_Pos 16 /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Position */ #define HSTPIPIMR_PDISHDMA (_U_(0x1) << HSTPIPIMR_PDISHDMA_Pos) /**< (HSTPIPIMR) Pipe Interrupts Disable HDMA Request Enable Mask */ #define HSTPIPIMR_PFREEZE_Pos 17 /**< (HSTPIPIMR) Pipe Freeze Position */ #define HSTPIPIMR_PFREEZE (_U_(0x1) << HSTPIPIMR_PFREEZE_Pos) /**< (HSTPIPIMR) Pipe Freeze Mask */ #define HSTPIPIMR_RSTDT_Pos 18 /**< (HSTPIPIMR) Reset Data Toggle Position */ #define HSTPIPIMR_RSTDT (_U_(0x1) << HSTPIPIMR_RSTDT_Pos) /**< (HSTPIPIMR) Reset Data Toggle Mask */ #define HSTPIPIMR_Msk _U_(0x750BB) /**< (HSTPIPIMR) Register Mask */ /* CTRL mode */ #define HSTPIPIMR_CTRL_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ #define HSTPIPIMR_CTRL_TXSTPE (_U_(0x1) << HSTPIPIMR_CTRL_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ #define HSTPIPIMR_CTRL_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ #define HSTPIPIMR_CTRL_RXSTALLDE (_U_(0x1) << HSTPIPIMR_CTRL_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ #define HSTPIPIMR_CTRL_Msk _U_(0x44) /**< (HSTPIPIMR_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPIMR_ISO_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ #define HSTPIPIMR_ISO_UNDERFIE (_U_(0x1) << HSTPIPIMR_ISO_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ #define HSTPIPIMR_ISO_CRCERRE_Pos 6 /**< (HSTPIPIMR) CRC Error Interrupt Enable Position */ #define HSTPIPIMR_ISO_CRCERRE (_U_(0x1) << HSTPIPIMR_ISO_CRCERRE_Pos) /**< (HSTPIPIMR) CRC Error Interrupt Enable Mask */ #define HSTPIPIMR_ISO_Msk _U_(0x44) /**< (HSTPIPIMR_ISO) Register Mask */ /* BLK mode */ #define HSTPIPIMR_BLK_TXSTPE_Pos 2 /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Position */ #define HSTPIPIMR_BLK_TXSTPE (_U_(0x1) << HSTPIPIMR_BLK_TXSTPE_Pos) /**< (HSTPIPIMR) Transmitted SETUP Interrupt Enable Mask */ #define HSTPIPIMR_BLK_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ #define HSTPIPIMR_BLK_RXSTALLDE (_U_(0x1) << HSTPIPIMR_BLK_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ #define HSTPIPIMR_BLK_Msk _U_(0x44) /**< (HSTPIPIMR_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPIMR_INTRPT_UNDERFIE_Pos 2 /**< (HSTPIPIMR) Underflow Interrupt Enable Position */ #define HSTPIPIMR_INTRPT_UNDERFIE (_U_(0x1) << HSTPIPIMR_INTRPT_UNDERFIE_Pos) /**< (HSTPIPIMR) Underflow Interrupt Enable Mask */ #define HSTPIPIMR_INTRPT_RXSTALLDE_Pos 6 /**< (HSTPIPIMR) Received STALLed Interrupt Enable Position */ #define HSTPIPIMR_INTRPT_RXSTALLDE (_U_(0x1) << HSTPIPIMR_INTRPT_RXSTALLDE_Pos) /**< (HSTPIPIMR) Received STALLed Interrupt Enable Mask */ #define HSTPIPIMR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIMR_INTRPT) Register Mask */ /* -------- HSTPIPIER : (USBHS Offset: 0x5f0) (/W 32) Host Pipe Enable Register -------- */ #define HSTPIPIER_OFFSET (0x5F0) /**< (HSTPIPIER) Host Pipe Enable Register Offset */ #define HSTPIPIER_RXINES_Pos 0 /**< (HSTPIPIER) Received IN Data Interrupt Enable Position */ #define HSTPIPIER_RXINES (_U_(0x1) << HSTPIPIER_RXINES_Pos) /**< (HSTPIPIER) Received IN Data Interrupt Enable Mask */ #define HSTPIPIER_TXOUTES_Pos 1 /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Position */ #define HSTPIPIER_TXOUTES (_U_(0x1) << HSTPIPIER_TXOUTES_Pos) /**< (HSTPIPIER) Transmitted OUT Data Interrupt Enable Mask */ #define HSTPIPIER_PERRES_Pos 3 /**< (HSTPIPIER) Pipe Error Interrupt Enable Position */ #define HSTPIPIER_PERRES (_U_(0x1) << HSTPIPIER_PERRES_Pos) /**< (HSTPIPIER) Pipe Error Interrupt Enable Mask */ #define HSTPIPIER_NAKEDES_Pos 4 /**< (HSTPIPIER) NAKed Interrupt Enable Position */ #define HSTPIPIER_NAKEDES (_U_(0x1) << HSTPIPIER_NAKEDES_Pos) /**< (HSTPIPIER) NAKed Interrupt Enable Mask */ #define HSTPIPIER_OVERFIES_Pos 5 /**< (HSTPIPIER) Overflow Interrupt Enable Position */ #define HSTPIPIER_OVERFIES (_U_(0x1) << HSTPIPIER_OVERFIES_Pos) /**< (HSTPIPIER) Overflow Interrupt Enable Mask */ #define HSTPIPIER_SHORTPACKETIES_Pos 7 /**< (HSTPIPIER) Short Packet Interrupt Enable Position */ #define HSTPIPIER_SHORTPACKETIES (_U_(0x1) << HSTPIPIER_SHORTPACKETIES_Pos) /**< (HSTPIPIER) Short Packet Interrupt Enable Mask */ #define HSTPIPIER_NBUSYBKES_Pos 12 /**< (HSTPIPIER) Number of Busy Banks Enable Position */ #define HSTPIPIER_NBUSYBKES (_U_(0x1) << HSTPIPIER_NBUSYBKES_Pos) /**< (HSTPIPIER) Number of Busy Banks Enable Mask */ #define HSTPIPIER_PDISHDMAS_Pos 16 /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Position */ #define HSTPIPIER_PDISHDMAS (_U_(0x1) << HSTPIPIER_PDISHDMAS_Pos) /**< (HSTPIPIER) Pipe Interrupts Disable HDMA Request Enable Mask */ #define HSTPIPIER_PFREEZES_Pos 17 /**< (HSTPIPIER) Pipe Freeze Enable Position */ #define HSTPIPIER_PFREEZES (_U_(0x1) << HSTPIPIER_PFREEZES_Pos) /**< (HSTPIPIER) Pipe Freeze Enable Mask */ #define HSTPIPIER_RSTDTS_Pos 18 /**< (HSTPIPIER) Reset Data Toggle Enable Position */ #define HSTPIPIER_RSTDTS (_U_(0x1) << HSTPIPIER_RSTDTS_Pos) /**< (HSTPIPIER) Reset Data Toggle Enable Mask */ #define HSTPIPIER_Msk _U_(0x710BB) /**< (HSTPIPIER) Register Mask */ /* CTRL mode */ #define HSTPIPIER_CTRL_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ #define HSTPIPIER_CTRL_TXSTPES (_U_(0x1) << HSTPIPIER_CTRL_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ #define HSTPIPIER_CTRL_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ #define HSTPIPIER_CTRL_RXSTALLDES (_U_(0x1) << HSTPIPIER_CTRL_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ #define HSTPIPIER_CTRL_Msk _U_(0x44) /**< (HSTPIPIER_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPIER_ISO_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ #define HSTPIPIER_ISO_UNDERFIES (_U_(0x1) << HSTPIPIER_ISO_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ #define HSTPIPIER_ISO_CRCERRES_Pos 6 /**< (HSTPIPIER) CRC Error Interrupt Enable Position */ #define HSTPIPIER_ISO_CRCERRES (_U_(0x1) << HSTPIPIER_ISO_CRCERRES_Pos) /**< (HSTPIPIER) CRC Error Interrupt Enable Mask */ #define HSTPIPIER_ISO_Msk _U_(0x44) /**< (HSTPIPIER_ISO) Register Mask */ /* BLK mode */ #define HSTPIPIER_BLK_TXSTPES_Pos 2 /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Position */ #define HSTPIPIER_BLK_TXSTPES (_U_(0x1) << HSTPIPIER_BLK_TXSTPES_Pos) /**< (HSTPIPIER) Transmitted SETUP Interrupt Enable Mask */ #define HSTPIPIER_BLK_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ #define HSTPIPIER_BLK_RXSTALLDES (_U_(0x1) << HSTPIPIER_BLK_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ #define HSTPIPIER_BLK_Msk _U_(0x44) /**< (HSTPIPIER_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPIER_INTRPT_UNDERFIES_Pos 2 /**< (HSTPIPIER) Underflow Interrupt Enable Position */ #define HSTPIPIER_INTRPT_UNDERFIES (_U_(0x1) << HSTPIPIER_INTRPT_UNDERFIES_Pos) /**< (HSTPIPIER) Underflow Interrupt Enable Mask */ #define HSTPIPIER_INTRPT_RXSTALLDES_Pos 6 /**< (HSTPIPIER) Received STALLed Interrupt Enable Position */ #define HSTPIPIER_INTRPT_RXSTALLDES (_U_(0x1) << HSTPIPIER_INTRPT_RXSTALLDES_Pos) /**< (HSTPIPIER) Received STALLed Interrupt Enable Mask */ #define HSTPIPIER_INTRPT_Msk _U_(0x44) /**< (HSTPIPIER_INTRPT) Register Mask */ /* -------- HSTPIPIDR : (USBHS Offset: 0x620) (/W 32) Host Pipe Disable Register -------- */ #define HSTPIPIDR_OFFSET (0x620) /**< (HSTPIPIDR) Host Pipe Disable Register Offset */ #define HSTPIPIDR_RXINEC_Pos 0 /**< (HSTPIPIDR) Received IN Data Interrupt Disable Position */ #define HSTPIPIDR_RXINEC (_U_(0x1) << HSTPIPIDR_RXINEC_Pos) /**< (HSTPIPIDR) Received IN Data Interrupt Disable Mask */ #define HSTPIPIDR_TXOUTEC_Pos 1 /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Position */ #define HSTPIPIDR_TXOUTEC (_U_(0x1) << HSTPIPIDR_TXOUTEC_Pos) /**< (HSTPIPIDR) Transmitted OUT Data Interrupt Disable Mask */ #define HSTPIPIDR_PERREC_Pos 3 /**< (HSTPIPIDR) Pipe Error Interrupt Disable Position */ #define HSTPIPIDR_PERREC (_U_(0x1) << HSTPIPIDR_PERREC_Pos) /**< (HSTPIPIDR) Pipe Error Interrupt Disable Mask */ #define HSTPIPIDR_NAKEDEC_Pos 4 /**< (HSTPIPIDR) NAKed Interrupt Disable Position */ #define HSTPIPIDR_NAKEDEC (_U_(0x1) << HSTPIPIDR_NAKEDEC_Pos) /**< (HSTPIPIDR) NAKed Interrupt Disable Mask */ #define HSTPIPIDR_OVERFIEC_Pos 5 /**< (HSTPIPIDR) Overflow Interrupt Disable Position */ #define HSTPIPIDR_OVERFIEC (_U_(0x1) << HSTPIPIDR_OVERFIEC_Pos) /**< (HSTPIPIDR) Overflow Interrupt Disable Mask */ #define HSTPIPIDR_SHORTPACKETIEC_Pos 7 /**< (HSTPIPIDR) Short Packet Interrupt Disable Position */ #define HSTPIPIDR_SHORTPACKETIEC (_U_(0x1) << HSTPIPIDR_SHORTPACKETIEC_Pos) /**< (HSTPIPIDR) Short Packet Interrupt Disable Mask */ #define HSTPIPIDR_NBUSYBKEC_Pos 12 /**< (HSTPIPIDR) Number of Busy Banks Disable Position */ #define HSTPIPIDR_NBUSYBKEC (_U_(0x1) << HSTPIPIDR_NBUSYBKEC_Pos) /**< (HSTPIPIDR) Number of Busy Banks Disable Mask */ #define HSTPIPIDR_FIFOCONC_Pos 14 /**< (HSTPIPIDR) FIFO Control Disable Position */ #define HSTPIPIDR_FIFOCONC (_U_(0x1) << HSTPIPIDR_FIFOCONC_Pos) /**< (HSTPIPIDR) FIFO Control Disable Mask */ #define HSTPIPIDR_PDISHDMAC_Pos 16 /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Position */ #define HSTPIPIDR_PDISHDMAC (_U_(0x1) << HSTPIPIDR_PDISHDMAC_Pos) /**< (HSTPIPIDR) Pipe Interrupts Disable HDMA Request Disable Mask */ #define HSTPIPIDR_PFREEZEC_Pos 17 /**< (HSTPIPIDR) Pipe Freeze Disable Position */ #define HSTPIPIDR_PFREEZEC (_U_(0x1) << HSTPIPIDR_PFREEZEC_Pos) /**< (HSTPIPIDR) Pipe Freeze Disable Mask */ #define HSTPIPIDR_Msk _U_(0x350BB) /**< (HSTPIPIDR) Register Mask */ /* CTRL mode */ #define HSTPIPIDR_CTRL_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ #define HSTPIPIDR_CTRL_TXSTPEC (_U_(0x1) << HSTPIPIDR_CTRL_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ #define HSTPIPIDR_CTRL_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ #define HSTPIPIDR_CTRL_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_CTRL_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ #define HSTPIPIDR_CTRL_Msk _U_(0x44) /**< (HSTPIPIDR_CTRL) Register Mask */ /* ISO mode */ #define HSTPIPIDR_ISO_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ #define HSTPIPIDR_ISO_UNDERFIEC (_U_(0x1) << HSTPIPIDR_ISO_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ #define HSTPIPIDR_ISO_CRCERREC_Pos 6 /**< (HSTPIPIDR) CRC Error Interrupt Disable Position */ #define HSTPIPIDR_ISO_CRCERREC (_U_(0x1) << HSTPIPIDR_ISO_CRCERREC_Pos) /**< (HSTPIPIDR) CRC Error Interrupt Disable Mask */ #define HSTPIPIDR_ISO_Msk _U_(0x44) /**< (HSTPIPIDR_ISO) Register Mask */ /* BLK mode */ #define HSTPIPIDR_BLK_TXSTPEC_Pos 2 /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Position */ #define HSTPIPIDR_BLK_TXSTPEC (_U_(0x1) << HSTPIPIDR_BLK_TXSTPEC_Pos) /**< (HSTPIPIDR) Transmitted SETUP Interrupt Disable Mask */ #define HSTPIPIDR_BLK_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ #define HSTPIPIDR_BLK_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_BLK_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ #define HSTPIPIDR_BLK_Msk _U_(0x44) /**< (HSTPIPIDR_BLK) Register Mask */ /* INTRPT mode */ #define HSTPIPIDR_INTRPT_UNDERFIEC_Pos 2 /**< (HSTPIPIDR) Underflow Interrupt Disable Position */ #define HSTPIPIDR_INTRPT_UNDERFIEC (_U_(0x1) << HSTPIPIDR_INTRPT_UNDERFIEC_Pos) /**< (HSTPIPIDR) Underflow Interrupt Disable Mask */ #define HSTPIPIDR_INTRPT_RXSTALLDEC_Pos 6 /**< (HSTPIPIDR) Received STALLed Interrupt Disable Position */ #define HSTPIPIDR_INTRPT_RXSTALLDEC (_U_(0x1) << HSTPIPIDR_INTRPT_RXSTALLDEC_Pos) /**< (HSTPIPIDR) Received STALLed Interrupt Disable Mask */ #define HSTPIPIDR_INTRPT_Msk _U_(0x44) /**< (HSTPIPIDR_INTRPT) Register Mask */ /* -------- HSTPIPINRQ : (USBHS Offset: 0x650) (R/W 32) Host Pipe IN Request Register -------- */ #define HSTPIPINRQ_OFFSET (0x650) /**< (HSTPIPINRQ) Host Pipe IN Request Register Offset */ #define HSTPIPINRQ_INRQ_Pos 0 /**< (HSTPIPINRQ) IN Request Number before Freeze Position */ #define HSTPIPINRQ_INRQ (_U_(0xFF) << HSTPIPINRQ_INRQ_Pos) /**< (HSTPIPINRQ) IN Request Number before Freeze Mask */ #define HSTPIPINRQ_INMODE_Pos 8 /**< (HSTPIPINRQ) IN Request Mode Position */ #define HSTPIPINRQ_INMODE (_U_(0x1) << HSTPIPINRQ_INMODE_Pos) /**< (HSTPIPINRQ) IN Request Mode Mask */ #define HSTPIPINRQ_Msk _U_(0x1FF) /**< (HSTPIPINRQ) Register Mask */ /* -------- HSTPIPERR : (USBHS Offset: 0x680) (R/W 32) Host Pipe Error Register -------- */ #define HSTPIPERR_OFFSET (0x680) /**< (HSTPIPERR) Host Pipe Error Register Offset */ #define HSTPIPERR_DATATGL_Pos 0 /**< (HSTPIPERR) Data Toggle Error Position */ #define HSTPIPERR_DATATGL (_U_(0x1) << HSTPIPERR_DATATGL_Pos) /**< (HSTPIPERR) Data Toggle Error Mask */ #define HSTPIPERR_DATAPID_Pos 1 /**< (HSTPIPERR) Data PID Error Position */ #define HSTPIPERR_DATAPID (_U_(0x1) << HSTPIPERR_DATAPID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ #define HSTPIPERR_PID_Pos 2 /**< (HSTPIPERR) Data PID Error Position */ #define HSTPIPERR_PID (_U_(0x1) << HSTPIPERR_PID_Pos) /**< (HSTPIPERR) Data PID Error Mask */ #define HSTPIPERR_TIMEOUT_Pos 3 /**< (HSTPIPERR) Time-Out Error Position */ #define HSTPIPERR_TIMEOUT (_U_(0x1) << HSTPIPERR_TIMEOUT_Pos) /**< (HSTPIPERR) Time-Out Error Mask */ #define HSTPIPERR_CRC16_Pos 4 /**< (HSTPIPERR) CRC16 Error Position */ #define HSTPIPERR_CRC16 (_U_(0x1) << HSTPIPERR_CRC16_Pos) /**< (HSTPIPERR) CRC16 Error Mask */ #define HSTPIPERR_COUNTER_Pos 5 /**< (HSTPIPERR) Error Counter Position */ #define HSTPIPERR_COUNTER (_U_(0x3) << HSTPIPERR_COUNTER_Pos) /**< (HSTPIPERR) Error Counter Mask */ #define HSTPIPERR_Msk _U_(0x7F) /**< (HSTPIPERR) Register Mask */ #define HSTPIPERR_CRC_Pos 4 /**< (HSTPIPERR Position) CRCx6 Error */ #define HSTPIPERR_CRC (_U_(0x1) << HSTPIPERR_CRC_Pos) /**< (HSTPIPERR Mask) CRC */ /* -------- CTRL : (USBHS Offset: 0x800) (R/W 32) General Control Register -------- */ #define CTRL_OFFSET (0x800) /**< (CTRL) General Control Register Offset */ #define CTRL_RDERRE_Pos 4 /**< (CTRL) Remote Device Connection Error Interrupt Enable Position */ #define CTRL_RDERRE (_U_(0x1) << CTRL_RDERRE_Pos) /**< (CTRL) Remote Device Connection Error Interrupt Enable Mask */ #define CTRL_VBUSHWC_Pos 8 /**< (CTRL) VBUS Hardware Control Position */ #define CTRL_VBUSHWC (_U_(0x1) << CTRL_VBUSHWC_Pos) /**< (CTRL) VBUS Hardware Control Mask */ #define CTRL_FRZCLK_Pos 14 /**< (CTRL) Freeze USB Clock Position */ #define CTRL_FRZCLK (_U_(0x1) << CTRL_FRZCLK_Pos) /**< (CTRL) Freeze USB Clock Mask */ #define CTRL_USBE_Pos 15 /**< (CTRL) USBHS Enable Position */ #define CTRL_USBE (_U_(0x1) << CTRL_USBE_Pos) /**< (CTRL) USBHS Enable Mask */ #define CTRL_UID_Pos 24 /**< (CTRL) UID Pin Enable Position */ #define CTRL_UID (_U_(0x1) << CTRL_UID_Pos) /**< (CTRL) UID Pin Enable Mask */ #define CTRL_UIMOD_Pos 25 /**< (CTRL) USBHS Mode Position */ #define CTRL_UIMOD (_U_(0x1) << CTRL_UIMOD_Pos) /**< (CTRL) USBHS Mode Mask */ #define CTRL_UIMOD_HOST_Val _U_(0x0) /**< (CTRL) The module is in USB Host mode. */ #define CTRL_UIMOD_DEVICE_Val _U_(0x1) /**< (CTRL) The module is in USB Device mode. */ #define CTRL_UIMOD_HOST (CTRL_UIMOD_HOST_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Host mode. Position */ #define CTRL_UIMOD_DEVICE (CTRL_UIMOD_DEVICE_Val << CTRL_UIMOD_Pos) /**< (CTRL) The module is in USB Device mode. Position */ #define CTRL_Msk _U_(0x300C110) /**< (CTRL) Register Mask */ /* -------- SR : (USBHS Offset: 0x804) (R/ 32) General Status Register -------- */ #define SR_OFFSET (0x804) /**< (SR) General Status Register Offset */ #define SR_RDERRI_Pos 4 /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Position */ #define SR_RDERRI (_U_(0x1) << SR_RDERRI_Pos) /**< (SR) Remote Device Connection Error Interrupt (Host mode only) Mask */ #define SR_SPEED_Pos 12 /**< (SR) Speed Status (Device mode only) Position */ #define SR_SPEED (_U_(0x3) << SR_SPEED_Pos) /**< (SR) Speed Status (Device mode only) Mask */ #define SR_SPEED_FULL_SPEED_Val _U_(0x0) /**< (SR) Full-Speed mode */ #define SR_SPEED_HIGH_SPEED_Val _U_(0x1) /**< (SR) High-Speed mode */ #define SR_SPEED_LOW_SPEED_Val _U_(0x2) /**< (SR) Low-Speed mode */ #define SR_SPEED_FULL_SPEED (SR_SPEED_FULL_SPEED_Val << SR_SPEED_Pos) /**< (SR) Full-Speed mode Position */ #define SR_SPEED_HIGH_SPEED (SR_SPEED_HIGH_SPEED_Val << SR_SPEED_Pos) /**< (SR) High-Speed mode Position */ #define SR_SPEED_LOW_SPEED (SR_SPEED_LOW_SPEED_Val << SR_SPEED_Pos) /**< (SR) Low-Speed mode Position */ #define SR_CLKUSABLE_Pos 14 /**< (SR) UTMI Clock Usable Position */ #define SR_CLKUSABLE (_U_(0x1) << SR_CLKUSABLE_Pos) /**< (SR) UTMI Clock Usable Mask */ #define SR_Msk _U_(0x7010) /**< (SR) Register Mask */ /* -------- SCR : (USBHS Offset: 0x808) (/W 32) General Status Clear Register -------- */ #define SCR_OFFSET (0x808) /**< (SCR) General Status Clear Register Offset */ #define SCR_RDERRIC_Pos 4 /**< (SCR) Remote Device Connection Error Interrupt Clear Position */ #define SCR_RDERRIC (_U_(0x1) << SCR_RDERRIC_Pos) /**< (SCR) Remote Device Connection Error Interrupt Clear Mask */ #define SCR_Msk _U_(0x10) /**< (SCR) Register Mask */ /* -------- SFR : (USBHS Offset: 0x80c) (/W 32) General Status Set Register -------- */ #define SFR_OFFSET (0x80C) /**< (SFR) General Status Set Register Offset */ #define SFR_RDERRIS_Pos 4 /**< (SFR) Remote Device Connection Error Interrupt Set Position */ #define SFR_RDERRIS (_U_(0x1) << SFR_RDERRIS_Pos) /**< (SFR) Remote Device Connection Error Interrupt Set Mask */ #define SFR_VBUSRQS_Pos 9 /**< (SFR) VBUS Request Set Position */ #define SFR_VBUSRQS (_U_(0x1) << SFR_VBUSRQS_Pos) /**< (SFR) VBUS Request Set Mask */ #define SFR_Msk _U_(0x210) /**< (SFR) Register Mask */ /** \brief DEVDMA hardware registers */ typedef struct { __IO uint32_t DEVDMANXTDSC; /**< (DEVDMA Offset: 0x00) Device DMA Channel Next Descriptor Address Register */ __IO uint32_t DEVDMAADDRESS; /**< (DEVDMA Offset: 0x04) Device DMA Channel Address Register */ __IO uint32_t DEVDMACONTROL; /**< (DEVDMA Offset: 0x08) Device DMA Channel Control Register */ __IO uint32_t DEVDMASTATUS; /**< (DEVDMA Offset: 0x0C) Device DMA Channel Status Register */ } devdma_t; /** \brief HSTDMA hardware registers */ typedef struct { __IO uint32_t HSTDMANXTDSC; /**< (HSTDMA Offset: 0x00) Host DMA Channel Next Descriptor Address Register */ __IO uint32_t HSTDMAADDRESS; /**< (HSTDMA Offset: 0x04) Host DMA Channel Address Register */ __IO uint32_t HSTDMACONTROL; /**< (HSTDMA Offset: 0x08) Host DMA Channel Control Register */ __IO uint32_t HSTDMASTATUS; /**< (HSTDMA Offset: 0x0C) Host DMA Channel Status Register */ } hstdma_t; /** \brief USBHS hardware registers */ typedef struct { __IO uint32_t DEVCTRL; /**< (USBHS Offset: 0x00) Device General Control Register */ __I uint32_t DEVISR; /**< (USBHS Offset: 0x04) Device Global Interrupt Status Register */ __O uint32_t DEVICR; /**< (USBHS Offset: 0x08) Device Global Interrupt Clear Register */ __O uint32_t DEVIFR; /**< (USBHS Offset: 0x0C) Device Global Interrupt Set Register */ __I uint32_t DEVIMR; /**< (USBHS Offset: 0x10) Device Global Interrupt Mask Register */ __O uint32_t DEVIDR; /**< (USBHS Offset: 0x14) Device Global Interrupt Disable Register */ __O uint32_t DEVIER; /**< (USBHS Offset: 0x18) Device Global Interrupt Enable Register */ __IO uint32_t DEVEPT; /**< (USBHS Offset: 0x1C) Device Endpoint Register */ __I uint32_t DEVFNUM; /**< (USBHS Offset: 0x20) Device Frame Number Register */ __I uint8_t Reserved1[220]; __IO uint32_t DEVEPTCFG[10]; /**< (USBHS Offset: 0x100) Device Endpoint Configuration Register */ __I uint8_t Reserved2[8]; __I uint32_t DEVEPTISR[10]; /**< (USBHS Offset: 0x130) Device Endpoint Interrupt Status Register */ __I uint8_t Reserved3[8]; __O uint32_t DEVEPTICR[10]; /**< (USBHS Offset: 0x160) Device Endpoint Interrupt Clear Register */ __I uint8_t Reserved4[8]; __O uint32_t DEVEPTIFR[10]; /**< (USBHS Offset: 0x190) Device Endpoint Interrupt Set Register */ __I uint8_t Reserved5[8]; __I uint32_t DEVEPTIMR[10]; /**< (USBHS Offset: 0x1C0) Device Endpoint Interrupt Mask Register */ __I uint8_t Reserved6[8]; __O uint32_t DEVEPTIER[10]; /**< (USBHS Offset: 0x1F0) Device Endpoint Interrupt Enable Register */ __I uint8_t Reserved7[8]; __O uint32_t DEVEPTIDR[10]; /**< (USBHS Offset: 0x220) Device Endpoint Interrupt Disable Register */ __I uint8_t Reserved8[200]; devdma_t DEVDMA[7]; /**< Offset: 0x310 Device DMA Channel Next Descriptor Address Register */ __I uint8_t Reserved9[128]; __IO uint32_t HSTCTRL; /**< (USBHS Offset: 0x400) Host General Control Register */ __I uint32_t HSTISR; /**< (USBHS Offset: 0x404) Host Global Interrupt Status Register */ __O uint32_t HSTICR; /**< (USBHS Offset: 0x408) Host Global Interrupt Clear Register */ __O uint32_t HSTIFR; /**< (USBHS Offset: 0x40C) Host Global Interrupt Set Register */ __I uint32_t HSTIMR; /**< (USBHS Offset: 0x410) Host Global Interrupt Mask Register */ __O uint32_t HSTIDR; /**< (USBHS Offset: 0x414) Host Global Interrupt Disable Register */ __O uint32_t HSTIER; /**< (USBHS Offset: 0x418) Host Global Interrupt Enable Register */ __IO uint32_t HSTPIP; /**< (USBHS Offset: 0x41C) Host Pipe Register */ __IO uint32_t HSTFNUM; /**< (USBHS Offset: 0x420) Host Frame Number Register */ __IO uint32_t HSTADDR1; /**< (USBHS Offset: 0x424) Host Address 1 Register */ __IO uint32_t HSTADDR2; /**< (USBHS Offset: 0x428) Host Address 2 Register */ __IO uint32_t HSTADDR3; /**< (USBHS Offset: 0x42C) Host Address 3 Register */ __I uint8_t Reserved10[208]; __IO uint32_t HSTPIPCFG[10]; /**< (USBHS Offset: 0x500) Host Pipe Configuration Register */ __I uint8_t Reserved11[8]; __I uint32_t HSTPIPISR[10]; /**< (USBHS Offset: 0x530) Host Pipe Status Register */ __I uint8_t Reserved12[8]; __O uint32_t HSTPIPICR[10]; /**< (USBHS Offset: 0x560) Host Pipe Clear Register */ __I uint8_t Reserved13[8]; __O uint32_t HSTPIPIFR[10]; /**< (USBHS Offset: 0x590) Host Pipe Set Register */ __I uint8_t Reserved14[8]; __I uint32_t HSTPIPIMR[10]; /**< (USBHS Offset: 0x5C0) Host Pipe Mask Register */ __I uint8_t Reserved15[8]; __O uint32_t HSTPIPIER[10]; /**< (USBHS Offset: 0x5F0) Host Pipe Enable Register */ __I uint8_t Reserved16[8]; __O uint32_t HSTPIPIDR[10]; /**< (USBHS Offset: 0x620) Host Pipe Disable Register */ __I uint8_t Reserved17[8]; __IO uint32_t HSTPIPINRQ[10]; /**< (USBHS Offset: 0x650) Host Pipe IN Request Register */ __I uint8_t Reserved18[8]; __IO uint32_t HSTPIPERR[10]; /**< (USBHS Offset: 0x680) Host Pipe Error Register */ __I uint8_t Reserved19[104]; hstdma_t HSTDMA[7]; /**< Offset: 0x710 Host DMA Channel Next Descriptor Address Register */ __I uint8_t Reserved20[128]; __IO uint32_t CTRL; /**< (USBHS Offset: 0x800) General Control Register */ __I uint32_t SR; /**< (USBHS Offset: 0x804) General Status Register */ __O uint32_t SCR; /**< (USBHS Offset: 0x808) General Status Clear Register */ __O uint32_t SFR; /**< (USBHS Offset: 0x80C) General Status Set Register */ } dcd_registers_t; #define USB_REG ((dcd_registers_t *)0x40038000U) /**< \brief (USBHS) Base Address */ #define EP_MAX 10 #define FIFO_RAM_ADDR 0xA0100000u // Errata: The DMA feature is not available for Pipe/Endpoint 7 #define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6 && CFG_TUD_SAMX7X_DMA_ENABLE) //------------- DCache -------------// #if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE typedef struct { uintptr_t start; uintptr_t end; } mem_region_t; // Can be used to define additional uncached regions #ifndef CFG_SAMX7X_MEM_UNCACHED_REGIONS #define CFG_SAMX7X_MEM_UNCACHED_REGIONS #endif static mem_region_t uncached_regions[] = { // DTCM {.start = 0x20000000, .end = 0x203fffff}, CFG_SAMX7X_MEM_UNCACHED_REGIONS }; TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) { if (size & (CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) { size = (size & ~(CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) + CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT; } return size; } TU_ATTR_ALWAYS_INLINE static inline bool is_cache_mem(uintptr_t addr) { if (0 == (SCB->CCR & SCB_CCR_DC_Msk)) { return false; // D-Cache is disabled } for (unsigned int i = 0; i < TU_ARRAY_SIZE(uncached_regions); i++) { if (uncached_regions[i].start <= addr && addr <= uncached_regions[i].end) { return false; } } return true; } TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } #endif #else // TODO : SAM3U #endif #endif /* _COMMON_USB_REGS_H_ */ ================================================ FILE: src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 SE TEAM * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_MM32F327X) #include "reg_usb_otg_fs.h" #include "mm32_device.h" #include "hal_conf.h" #include "device/dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { TOK_PID_OUT = 0x1u, TOK_PID_IN = 0x9u, TOK_PID_SETUP = 0xDu, }; typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { uint16_t : 2; uint16_t tok_pid : 4; uint16_t data : 1; uint16_t own : 1; uint16_t : 8; }; struct { uint16_t : 2; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; uint16_t : 10; }; }; uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; } buffer_descriptor_t; TU_VERIFY_STATIC(sizeof(buffer_descriptor_t) == 8, "size is not correct"); typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { uint32_t max_packet_size : 11; uint32_t : 5; uint32_t odd : 1; uint32_t : 15; }; }; uint16_t length; uint16_t remaining; } endpoint_state_t; TU_VERIFY_STATIC(sizeof(endpoint_state_t) == 8, "size is not correct"); typedef struct { union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; uint16_t bda[512]; }; TU_ATTR_ALIGNED(4) union { endpoint_state_t endpoint[16][2]; endpoint_state_t endpoint_unified[16 * 2]; }; uint8_t setup_packet[8]; uint8_t addr; } dcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; TU_VERIFY_STATIC(sizeof(_dcd.bdt) == 512, "size is not correct"); static void prepare_next_setup_packet(uint8_t rhport) { const unsigned out_odd = _dcd.endpoint[0][0].odd; const unsigned in_odd = _dcd.endpoint[0][1].odd; if (_dcd.bdt[0][0][out_odd].own) { TU_LOG1("DCD fail to prepare the next SETUP %d %d\r\n", out_odd, in_odd); return; } _dcd.bdt[0][0][out_odd].data = 0; _dcd.bdt[0][0][out_odd ^ 1].data = 1; _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) { if (USB_OTG_FS->EP_CTL[0] & USB_ENDPT_EPSTALL_MASK) { /* clear stall condition of the control pipe */ prepare_next_setup_packet(rhport); USB_OTG_FS->EP_CTL[0] &= ~USB_ENDPT_EPSTALL_MASK; } } static void process_tokdne(uint8_t rhport) { const unsigned s = USB_OTG_FS->STAT; USB_OTG_FS->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; unsigned odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; /* fetch pid before discarded by the next steps */ const unsigned pid = bd->tok_pid; /* reset values for a next transfer */ bd->bdt_stall = 0; bd->dts = 1; bd->ninc = 0; bd->keep = 0; /* update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, bd->addr, true); USB_OTG_FS->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; return; } if (s >> 4) { TU_LOG1("TKDNE %x\r\n", s); } const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; if (remaining && bc == ep->max_packet_size) { /* continue the transferring consecutive data */ ep->remaining = remaining; const int next_remaining = remaining - ep->max_packet_size; if (next_remaining > 0) { /* prepare to the after next transfer */ bd->addr += ep->max_packet_size * 2; bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size : next_remaining; __DSB(); bd->own = 1; /* the own bit must set after addr */ } return; } const unsigned length = ep->length; dcd_event_xfer_complete(rhport, ((s & USB_STAT_TX_MASK) << 4) | (s >> USB_STAT_ENDP_SHIFT), length - remaining, XFER_RESULT_SUCCESS, true); if (0 == (s & USB_STAT_ENDP_MASK) && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ if (_dcd.addr) { /* When the transfer was the SetAddress, * the device address should be updated here. */ USB_OTG_FS->ADDR = _dcd.addr; _dcd.addr = 0; } prepare_next_setup_packet(rhport); } } static void process_bus_reset(uint8_t rhport) { USB_OTG_FS->CTL |= USB_CTL_ODDRST_MASK; USB_OTG_FS->ADDR = 0; USB_OTG_FS->INT_ENB = (USB_OTG_FS->INT_ENB & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; USB_OTG_FS->EP_CTL[0] = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; for (unsigned i = 1; i < 16; ++i) { USB_OTG_FS->EP_CTL[i] = 0; } buffer_descriptor_t *bd = _dcd.bdt[0][0]; for (unsigned i = 0; i < sizeof(_dcd.bdt) / sizeof(*bd); ++i, ++bd) { bd->head = 0; } const endpoint_state_t ep0 = { .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, .odd = 0, .length = 0, .remaining = 0, }; _dcd.endpoint[0][0] = ep0; _dcd.endpoint[0][1] = ep0; tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); _dcd.addr = 0; prepare_next_setup_packet(rhport); USB_OTG_FS->CTL &= ~USB_CTL_ODDRST_MASK; dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } static void process_bus_inactive(uint8_t rhport) { (void)rhport; const unsigned inten = USB_OTG_FS->INT_ENB; USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } static void process_bus_active(uint8_t rhport) { (void)rhport; const unsigned inten = USB_OTG_FS->INT_ENB; USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rhport; (void)rh_init; tu_memclr(&_dcd, sizeof(_dcd)); USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); USB_OTG_FS->BDT_PAGE_02 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); USB_OTG_FS->BDT_PAGE_03 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); dcd_connect(rhport); NVIC_ClearPendingIRQ(USB_FS_IRQn); return true; } #define USB_DEVICE_INTERRUPT_PRIORITY (3U) void dcd_int_enable(uint8_t rhport) { uint8_t irqNumber; irqNumber = USB_FS_IRQn; (void)rhport; USB_OTG_FS->INT_ENB = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY); NVIC_EnableIRQ(USB_FS_IRQn); } void dcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB_FS_IRQn); USB_OTG_FS->INT_ENB = 0; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)rhport; _dcd.addr = dev_addr & 0x7F; /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } #ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif extern u32 SystemCoreClock; #ifdef __GNUC__ #pragma GCC diagnostic pop #endif void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; unsigned cnt = SystemCoreClock / 100; USB_OTG_FS->CTL |= USB_CTL_RESUME_MASK; while (cnt--) { __NOP(); } USB_OTG_FS->CTL &= ~USB_CTL_RESUME_MASK; } void dcd_connect(uint8_t rhport) { (void)rhport; USB_OTG_FS->CTL |= USB_CTL_USBENSOFEN_MASK; } void dcd_disconnect(uint8_t rhport) { (void)rhport; USB_OTG_FS->CTL = 0; } void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; (void)en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { (void)rhport; const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = ep_addr & 0xFu; const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; const unsigned xfer = ep_desc->bmAttributes.xfer; endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; const unsigned odd = ep->odd; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; /* No support for control transfer */ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); ep->max_packet_size = tu_edpt_packet_size(ep_desc); unsigned val = USB_ENDPT_EPCTLDIS_MASK; val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0; val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; USB_OTG_FS->EP_CTL[epn] |= val; if (xfer != TUSB_XFER_ISOCHRONOUS) { bd[odd].dts = 1; bd[odd].data = 0; bd[odd ^ 1].dts = 1; bd[odd ^ 1].data = 1; } return true; } void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; // TODO implement dcd_edpt_close_all() } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const unsigned epn = ep_addr & 0xFu; const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; USB_OTG_FS->EP_CTL[epn] &= ~msk; ep->max_packet_size = 0; ep->length = 0; ep->remaining = 0; bd->head = 0; } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } #endif bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; NVIC_DisableIRQ(USB_FS_IRQn); const unsigned epn = ep_addr & 0xFu; const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; if (bd->own) { TU_LOG1("DCD XFER fail %x %d %lx %lx\r\n", ep_addr, total_bytes, ep->state, bd->head); return false; /* The last transfer has not completed */ } ep->length = total_bytes; ep->remaining = total_bytes; const unsigned mps = ep->max_packet_size; if (total_bytes > mps) { buffer_descriptor_t *next = ep->odd ? bd - 1 : bd + 1; /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ next->bc = total_bytes >= 2 * mps ? mps : total_bytes - mps; next->addr = buffer + mps; next->own = 1; } bd->bc = total_bytes >= mps ? mps : total_bytes; bd->addr = buffer; __DSB(); bd->own = 1; /* the own bit must set after addr */ NVIC_EnableIRQ(USB_FS_IRQn); return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const unsigned epn = ep_addr & 0xFu; if (0 == epn) { USB_OTG_FS->EP_CTL[epn] |= USB_ENDPT_EPSTALL_MASK; } else { const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; bd[0].bdt_stall = 1; bd[1].bdt_stall = 1; } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const unsigned epn = ep_addr & 0xFu; const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; bd[odd ^ 1].own = 0; bd[odd ^ 1].data = 1; bd[odd ^ 1].bdt_stall = 0; bd[odd].own = 0; bd[odd].data = 0; bd[odd].bdt_stall = 0; } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { (void)rhport; uint32_t is = USB_OTG_FS->INT_STAT; uint32_t msk = USB_OTG_FS->INT_ENB; USB_OTG_FS->INT_STAT = is & ~msk; is &= msk; if (is & USB_ISTAT_ERROR_MASK) { /* TODO: */ uint32_t es = USB_OTG_FS->ERR_STAT; USB_OTG_FS->ERR_STAT = es; USB_OTG_FS->INT_STAT = is; /* discard any pending events */ return; } if (is & USB_ISTAT_USBRST_MASK) { USB_OTG_FS->INT_STAT = is; /* discard any pending events */ process_bus_reset(rhport); return; } if (is & USB_ISTAT_SLEEP_MASK) { USB_OTG_FS->INT_STAT = USB_ISTAT_SLEEP_MASK; process_bus_inactive(rhport); return; } if (is & USB_ISTAT_RESUME_MASK) { USB_OTG_FS->INT_STAT = USB_ISTAT_RESUME_MASK; process_bus_active(rhport); return; } if (is & USB_ISTAT_SOFTOK_MASK) { USB_OTG_FS->INT_STAT = USB_ISTAT_SOFTOK_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); return; } if (is & USB_ISTAT_STALL_MASK) { USB_OTG_FS->INT_STAT = USB_ISTAT_STALL_MASK; process_stall(rhport); return; } if (is & USB_ISTAT_TOKDNE_MASK) { process_tokdne(rhport); return; } } #endif ================================================ FILE: src/portable/nordic/nrf5x/dcd_nrf5x.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NRF5X #include // Suppress warning caused by nrfx driver #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include "nrf.h" #include "nrfx_clock.h" #include "nrf_erratas.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "device/dcd.h" // TODO remove later #include "device/usbd.h" #include "device/usbd_pvt.h" // to use defer function helper #if CFG_TUSB_OS == OPT_OS_MYNEWT #include "mcu/mcu.h" #endif /* Try to detect nrfx version if not configured with CFG_TUD_NRF_NRFX_VERSION * nrfx v1 and v2 are concurrently developed. There is no NRFX_VERSION only MDK VERSION which is as follows: * - v3.0.0: 8.53.1 (conflict with v2.11.0), v3.1.0: 8.55.0 ... * - v2.11.0: 8.53.1, v2.6.0: 8.44.1, v2.5.0: 8.40.2, v2.4.0: 8.37.0, v2.3.0: 8.35.0, v2.2.0: 8.32.1, v2.1.0: 8.30.2, * v2.0.0: 8.29.0 * - v1.9.0: 8.40.3, v1.8.6: 8.35.0 (conflict with v2.3.0), v1.8.5: 8.32.3, v1.8.4: 8.32.1 (conflict with v2.2.0), * v1.8.2: 8.32.1 (conflict with v2.2.0), v1.8.1: 8.27.1 * Therefore the check for v1 would be: * - MDK < 8.29.0 (v2.0), MDK == 8.32.3, 8.40.3 * - in case of conflict User of those version must upgrade to other 1.x version or set CFG_TUD_NRF_NRFX_VERSION */ #ifndef CFG_TUD_NRF_NRFX_VERSION #define MDK_VERSION (10000 * MDK_MAJOR_VERSION + 100 * MDK_MINOR_VERSION + MDK_MICRO_VERSION) #if MDK_VERSION < 82900 || MDK_VERSION == 83203 || MDK_VERSION == 84003 // nrfx <= 1.8.1, or 1.8.5 or 1.9.0 #define CFG_TUD_NRF_NRFX_VERSION 1 #elif MDK_VERSION < 85301 #define CFG_TUD_NRF_NRFX_VERSION 2 #elif MDK_VERSION < 87300 #define CFG_TUD_NRF_NRFX_VERSION 3 #else #define CFG_TUD_NRF_NRFX_VERSION 4 #endif #endif /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ enum { // Max allowed by USB specs MAX_PACKET_SIZE = 64, // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT EDPT_END_ALL_MASK = (0xff << USBD_INTEN_ENDEPIN0_Pos) | (0xff << USBD_INTEN_ENDEPOUT0_Pos) | USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk }; enum { EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN EP_CBI_COUNT = 8 // Control Bulk Interrupt endpoints count }; // Transfer Descriptor typedef struct { uint8_t* buffer; uint16_t total_len; volatile uint16_t actual_len; uint16_t mps; // max packet size // nRF will auto accept OUT packet after DMA is done // indicate packet is already ACK volatile bool data_received; volatile bool started; // Set to true when data was transferred from RAM to ISO IN output buffer. // New data can be put in ISO IN output buffer after SOF. bool iso_in_transfer_ready; } xfer_td_t; // Data for managing dcd static struct { // All 8 endpoints including control IN & OUT (offset 1) // +1 for ISO endpoints xfer_td_t xfer[EP_CBI_COUNT + 1][2]; // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA atomic_flag dma_running; // Track whether sof has been manually enabled bool sof_enabled; } _dcd; /*------------------------------------------------------------------*/ /* Control / Bulk / Interrupt (CBI) Transfer *------------------------------------------------------------------*/ // check if we are in ISR TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) ? true : false; } // helper to start DMA static void start_dma(volatile uint32_t* reg_startep) { (*reg_startep) = 1; __ISB(); __DSB(); // TASKS_EP0STATUS, TASKS_EP0RCVOUT seem to need EasyDMA to be available // However these don't trigger any DMA transfer and got ENDED event subsequently // Therefore dma_pending is corrected right away if ((reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT)) { atomic_flag_clear(&_dcd.dma_running); } } static void edpt_dma_start(volatile uint32_t* reg_startep) { if (atomic_flag_test_and_set(&_dcd.dma_running)) { usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, is_in_isr()); } else { start_dma(reg_startep); } } // DMA is complete static void edpt_dma_end(void) { atomic_flag_clear(&_dcd.dma_running); } // helper getting td static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) { return &_dcd.xfer[epnum][dir]; } static void xact_out_dma(uint8_t epnum); // Function wraps xact_out_dma which wants uint8_t while usbd_defer_func wants void (*)(void *) static void xact_out_dma_wrapper(void* epnum) { xact_out_dma((uint8_t) ((uintptr_t) epnum)); } // Start DMA to move data from Endpoint -> RAM static void xact_out_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint32_t xact_len; // DMA can't be active during read of SIZE.EPOUT or SIZE.ISOOUT, so try to lock, // If already running defer call regardless if it was called from ISR or task, if (atomic_flag_test_and_set(&_dcd.dma_running)) { usbd_defer_func((osal_task_func_t) xact_out_dma_wrapper, (void*) (uint32_t) epnum, is_in_isr()); return; } if (epnum == EP_ISO_NUM) { xact_len = NRF_USBD->SIZE.ISOOUT; // If ZERO bit is set, ignore ISOOUT length if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) { xact_len = 0; atomic_flag_clear(&_dcd.dma_running); } else { if (xfer->started) { // Trigger DMA move data from Endpoint -> SRAM NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer; NRF_USBD->ISOOUT.MAXCNT = xact_len; start_dma(&NRF_USBD->TASKS_STARTISOOUT); } else { atomic_flag_clear(&_dcd.dma_running); } } } else { // limit xact len to remaining length xact_len = tu_min16((uint16_t) NRF_USBD->SIZE.EPOUT[epnum], xfer->total_len - xfer->actual_len); // Trigger DMA move data from Endpoint -> SRAM NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPOUT[epnum].MAXCNT = xact_len; start_dma(&NRF_USBD->TASKS_STARTEPOUT[epnum]); } } // Prepare for a CBI transaction IN, call at the start // it start DMA to transfer data from RAM -> Endpoint static void xact_in_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); // Each transaction is up to Max Packet Size uint16_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps); NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].MAXCNT = xact_len; edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; TU_LOG2("dcd init\r\n"); return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; // Set Address is automatically update by hw controller, nothing to do // Enable usbevent for suspend and resume detection // Since the bus signal D+/D- are stable now. // Clear current pending first NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE; NRF_USBD->EVENTS_USBEVENT = 0; NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; // Bring controller out of low power mode // will start wakeup when USBWUALLOWED is set NRF_USBD->LOWPOWER = 0; } // disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 0; // Disable Pull-up does not trigger Power USB Removed, in fact it have no // impact on the USB Power status at all -> need to submit unplugged event to the stack. dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); } // connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 1; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; if (en) { _dcd.sof_enabled = true; NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; } else { _dcd.sof_enabled = false; NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; uint8_t const ep_addr = desc_edpt->bEndpointAddress; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); _dcd.xfer[epnum][dir].mps = tu_edpt_packet_size(desc_edpt); if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) { if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN |= TU_BIT(epnum); // Write any value to SIZE register will allow nRF to ACK/accept data NRF_USBD->SIZE.EPOUT[epnum] = 0; } else { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); NRF_USBD->EPINEN |= TU_BIT(epnum); } // clear stall and reset DataToggle NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; } else { TU_ASSERT(epnum == EP_ISO_NUM); if (dir == TUSB_DIR_OUT) { // SPLIT ISO buffer when ISO IN endpoint is already opened. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; // Clear old events NRF_USBD->EVENTS_ENDISOOUT = 0; // Clear SOF event in case interrupt was not enabled yet. if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; // Enable SOF and ISOOUT interrupts, and ISOOUT endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOOUT_Msk | USBD_INTENSET_SOF_Msk; NRF_USBD->EPOUTEN |= USBD_EPOUTEN_ISOOUT_Msk; } else { NRF_USBD->EVENTS_ENDISOIN = 0; // SPLIT ISO buffer when ISO OUT endpoint is already opened. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; // Clear SOF event in case interrupt was not enabled yet. if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; // Enable SOF and ISOIN interrupts, and ISOIN endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOIN_Msk | USBD_INTENSET_SOF_Msk; NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; } } __ISB(); __DSB(); return true; } void dcd_edpt_close_all(uint8_t rhport) { // disable interrupt to prevent race condition dcd_int_disable(rhport); // disable all non-control (bulk + interrupt) endpoints for (uint8_t ep = 1; ep < EP_CBI_COUNT; ep++) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + ep) | TU_BIT(USBD_INTEN_ENDEPIN0_Pos + ep); NRF_USBD->TASKS_STARTEPIN[ep] = 0; NRF_USBD->TASKS_STARTEPOUT[ep] = 0; tu_memclr(_dcd.xfer[ep], 2 * sizeof(xfer_td_t)); } // disable both ISO NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk | USBD_INTENCLR_ENDISOOUT_Msk | USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; tu_memclr(_dcd.xfer[EP_ISO_NUM], 2 * sizeof(xfer_td_t)); // de-activate all non-control NRF_USBD->EPOUTEN = 1UL; NRF_USBD->EPINEN = 1UL; dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); if (epnum != EP_ISO_NUM) { // CBI if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN &= ~TU_BIT(epnum); } else { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); NRF_USBD->EPINEN &= ~TU_BIT(epnum); } } else { _dcd.xfer[EP_ISO_NUM][dir].mps = 0; // ISO if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOOUT_Msk; NRF_USBD->EPOUTEN &= ~USBD_EPOUTEN_ISOOUT_Msk; NRF_USBD->EVENTS_ENDISOOUT = 0; } else { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->EPINEN &= ~USBD_EPINEN_ISOIN_Msk; } // One of the ISO endpoints closed, no need to split buffers any more. NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; // When both ISO endpoint are close there is no need for SOF any more. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } _dcd.xfer[epnum][dir].started = false; __ISB(); __DSB(); } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } #endif bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) { (void) rhport; (void) is_isr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); TU_ASSERT(!xfer->started); xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->actual_len = 0; // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); } else { // started just set, it could start DMA transfer if interrupt was trigger after this line // code only needs to start transfer (from Endpoint to RAM) when data_received was set // before started was set. If started is NOT set but data_received is, it means that // current transfer was already finished and next data is already present in endpoint and // can be consumed by future transfer __ISB(); __DSB(); if (xfer->data_received && xfer->started) { // Data is already received previously // start DMA to copy to SRAM xfer->data_received = false; xact_out_dma(epnum); } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } } } else { // Start DMA to copy data from RAM -> Endpoint xact_in_dma(epnum); } return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); if (epnum == 0) { NRF_USBD->TASKS_EP0STALL = 1; } else if (epnum != EP_ISO_NUM) { NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr; // Note: nRF can auto ACK packet OUT before get stalled. // There maybe data in endpoint fifo already, we need to pull it out if ((dir == TUSB_DIR_OUT) && xfer->data_received) { xfer->data_received = false; xact_out_dma(epnum); } } __ISB(); __DSB(); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); if (epnum != 0 && epnum != EP_ISO_NUM) { // reset data toggle to DATA0 // First write this register with VALUE=Nop to select the endpoint, then either read it to get the status from // VALUE, or write it again with VALUE=Data0 or Data1 NRF_USBD->DTOGGLE = ep_addr; NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; // clear stall NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; // Write any value to SIZE register will allow nRF to ACK/accept data if (dir == TUSB_DIR_OUT) NRF_USBD->SIZE.EPOUT[epnum] = 0; __ISB(); __DSB(); } } /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ static void bus_reset(void) { // 6.35.6 USB controller automatically disabled all endpoints (except control) NRF_USBD->EPOUTEN = 1UL; NRF_USBD->EPINEN = 1UL; for (int i = 0; i < 8; i++) { NRF_USBD->TASKS_STARTEPIN[i] = 0; NRF_USBD->TASKS_STARTEPOUT[i] = 0; } NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; // Clear USB Event Interrupt NRF_USBD->EVENTS_USBEVENT = 0; NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE; // Reset interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk; tu_varclr(&_dcd); _dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE; _dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE; } void dcd_int_handler(uint8_t rhport) { (void) rhport; uint32_t const inten = NRF_USBD->INTEN; uint32_t int_status = 0; volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET; for (uint8_t i = 0; i < USBD_INTEN_EPDATA_Pos + 1; i++) { if (tu_bit_test(inten, i) && regevt[i]) { int_status |= TU_BIT(i); // event clear regevt[i] = 0; __ISB(); __DSB(); } } if (int_status & USBD_INTEN_USBRESET_Msk) { bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); } // ISOIN: Data was moved to endpoint buffer, client will be notified in SOF if (int_status & USBD_INTEN_ENDISOIN_Msk) { xfer_td_t* xfer = get_td(EP_ISO_NUM, TUSB_DIR_IN); xfer->actual_len = NRF_USBD->ISOIN.AMOUNT; // Data transferred from RAM to endpoint output buffer. // Next transfer can be scheduled after SOF. xfer->iso_in_transfer_ready = true; } if (int_status & USBD_INTEN_SOF_Msk) { bool iso_enabled = false; // ISOOUT: Transfer data gathered in previous frame from buffer to RAM if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; // Transfer from endpoint to RAM only if data is not corrupted if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_ISOOUTCRC_Msk) == 0) { xact_out_dma(EP_ISO_NUM); } } // ISOIN: Notify client that data was transferred if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) { iso_enabled = true; xfer_td_t* xfer = get_td(EP_ISO_NUM, TUSB_DIR_IN); if (xfer->iso_in_transfer_ready) { xfer->iso_in_transfer_ready = false; dcd_event_xfer_complete(0, EP_ISO_NUM | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } } if (!iso_enabled && !_dcd.sof_enabled) { // SOF interrupt not manually enabled and ISO endpoint is not used, // SOF is only enabled one-time for remote wakeup so we disable it now NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } const uint32_t frame = NRF_USBD->FRAMECNTR; dcd_event_sof(0, frame, true); //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } if (int_status & USBD_INTEN_USBEVENT_Msk) { TU_LOG(3, "EVENTCAUSE = 0x%04" PRIX32 "\r\n", NRF_USBD->EVENTCAUSE); enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt if (evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk) { // Put controller into low power mode // Leave HFXO disable to application, since it may be used by other peripherals NRF_USBD->LOWPOWER = 1; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk) { // USB is out of low power mode, and wakeup is allowed // Initiate RESUME signal NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume; NRF_USBD->TASKS_DPDMDRIVE = 1; // There is no Resume interrupt for remote wakeup, enable SOF for to report bus ready state // Clear SOF event in case interrupt was not enabled yet. if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0) NRF_USBD->EVENTS_SOF = 0; NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; } if (evt_cause & USBD_EVENTCAUSE_RESUME_Msk) { dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } // Setup tokens are specific to the Control endpoint. if (int_status & USBD_INTEN_EP0SETUP_Msk) { uint8_t const setup[8] = { NRF_USBD->BMREQUESTTYPE, NRF_USBD->BREQUEST, NRF_USBD->WVALUEL, NRF_USBD->WVALUEH, NRF_USBD->WINDEXL, NRF_USBD->WINDEXH, NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH }; // nrf5x hw auto handle set address, there is no need to inform usb stack tusb_control_request_t const* request = (tusb_control_request_t const*) setup; if (!(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && TUSB_REQ_SET_ADDRESS == request->bRequest)) { dcd_event_setup_received(0, setup, true); } } if (int_status & EDPT_END_ALL_MASK) { // DMA complete move data from SRAM <-> Endpoint // Must before endpoint transfer handling edpt_dma_end(); } //--------------------------------------------------------------------+ /* Control/Bulk/Interrupt (CBI) Transfer * * Data flow is: * (bus) (dma) * Host <-------> Endpoint <-------> RAM * * For CBI OUT: * - Host -> Endpoint * EPDATA (or EP0DATADONE) interrupted, check EPDATASTATUS.EPOUT[i] * to start DMA. For Bulk/Interrupt, this step can occur automatically (without sw), * which means data may or may not be ready (out_received flag). * - Endpoint -> RAM * ENDEPOUT[i] interrupted, transaction complete, sw prepare next transaction * * For CBI IN: * - RAM -> Endpoint * ENDEPIN[i] interrupted indicate DMA is complete. HW will start * to move data to host * - Endpoint -> Host * EPDATA (or EP0DATADONE) interrupted, check EPDATASTATUS.EPIN[i]. * Transaction is complete, sw prepare next transaction * * Note: in both Control In and Out of Data stage from Host <-> Endpoint * EP0DATADONE will be set as interrupt source */ //--------------------------------------------------------------------+ /* CBI OUT: Endpoint -> SRAM (aka transaction complete) * Note: Since nRF controller auto ACK next packet without SW awareness * We must handle this stage before Host -> Endpoint just in case 2 event happens at once * * ISO OUT: Transaction must fit in single packet, it can be shorter then total * len if Host decides to sent fewer bytes, it this case transaction is also * complete and next transfer is not initiated here like for CBI. */ for (uint8_t epnum = 0; epnum < EP_CBI_COUNT + 1; epnum++) { if (tu_bit_test(int_status, USBD_INTEN_ENDEPOUT0_Pos + epnum)) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint16_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT; xfer->buffer += xact_len; xfer->actual_len += xact_len; // Transfer complete if transaction len < Max Packet Size or total len is transferred if ((epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len)) { if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } } else { TU_ASSERT(xfer->started,); xfer->total_len = xfer->actual_len; xfer->started = false; // CBI OUT complete dcd_event_xfer_complete(0, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true); } } // Ended event for CBI IN : nothing to do } // Endpoint <-> Host ( In & OUT ) if (int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk)) { uint32_t data_status = NRF_USBD->EPDATASTATUS; NRF_USBD->EPDATASTATUS = data_status; __ISB(); __DSB(); // EP0DATADONE is set with either Control Out on IN Data // Since EPDATASTATUS cannot be used to determine whether it is control OUT or IN. // We will use BMREQUESTTYPE in setup packet to determine the direction bool const is_control_in = (int_status & USBD_INTEN_EP0DATADONE_Msk) && (NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); bool const is_control_out = (int_status & USBD_INTEN_EP0DATADONE_Msk) && !(NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); // CBI In: Endpoint -> Host (transaction complete) for (uint8_t epnum = 0; epnum < EP_CBI_COUNT; epnum++) { if (tu_bit_test(data_status, epnum) || (epnum == 0 && is_control_in)) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); uint8_t const xact_len = NRF_USBD->EPIN[epnum].AMOUNT; xfer->buffer += xact_len; xfer->actual_len += xact_len; if (xfer->actual_len < xfer->total_len) { // Start DMA to copy next data packet xact_in_dma(epnum); } else { // CBI IN complete dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } } } // CBI OUT: Host -> Endpoint for (uint8_t epnum = 0; epnum < EP_CBI_COUNT; epnum++) { if (tu_bit_test(data_status, 16 + epnum) || (epnum == 0 && is_control_out)) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); if (xfer->started && xfer->actual_len < xfer->total_len) { xact_out_dma(epnum); } else { // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet // Mark this endpoint with data received xfer->data_received = true; } } } } } //--------------------------------------------------------------------+ // HFCLK helper //--------------------------------------------------------------------+ #ifdef SOFTDEVICE_PRESENT // For enable/disable hfclk with SoftDevice #include "nrf_mbr.h" #include "nrf_sdm.h" #include "nrf_soc.h" #ifndef SD_MAGIC_NUMBER #define SD_MAGIC_NUMBER 0x51B1E5DB #endif TU_ATTR_ALWAYS_INLINE static inline bool is_sd_existed(void) { return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER; } // check if SD is existed and enabled TU_ATTR_ALWAYS_INLINE static inline bool is_sd_enabled(void) { if ( !is_sd_existed() ) return false; uint8_t sd_en = false; (void) sd_softdevice_is_enabled(&sd_en); return sd_en; } #endif static bool hfclk_running(void) { #ifdef SOFTDEVICE_PRESENT if (is_sd_enabled()) { uint32_t is_running = 0; (void)sd_clock_hfclk_is_running(&is_running); return (is_running ? true : false); } #endif #if CFG_TUD_NRF_NRFX_VERSION == 1 return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); #else return nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, NULL); #endif } static void hfclk_enable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_request(); return; #else // already running, nothing to do if (hfclk_running()) { return; } #ifdef SOFTDEVICE_PRESENT if (is_sd_enabled()) { (void)sd_clock_hfclk_request(); return; } #endif #if CFG_TUD_NRF_NRFX_VERSION == 1 nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); #else nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); #endif #endif } static void hfclk_disable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_release(); return; #else #ifdef SOFTDEVICE_PRESENT if ( is_sd_enabled() ) { (void)sd_clock_hfclk_release(); return; } #endif #if CFG_TUD_NRF_NRFX_VERSION == 1 nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif #endif } // Power & Clock Peripheral on nRF5x to manage USB // // USB Bus power is managed by Power module, there are 3 VBUS power events: // Detected, Ready, Removed. Upon these power events, This function will // enable ( or disable ) usb & hfclk peripheral, set the usb pin pull up // accordingly to the controller Startup/Standby Sequence in USBD 51.4 specs. // // Therefore this function must be called to handle USB power event by // - nrfx_power_usbevt_init() : if Softdevice is not used or enabled // - SoftDevice SOC event : if SD is used and enabled void tusb_hal_nrf_power_event(uint32_t event); void tusb_hal_nrf_power_event(uint32_t event) { // Value is chosen to be as same as NRFX_POWER_USB_EVT_* in nrfx_power.h enum { USB_EVT_DETECTED = 0, USB_EVT_REMOVED = 1, USB_EVT_READY = 2 }; #if CFG_TUSB_DEBUG >= 3 const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; TU_LOG(3, "Power USB event: %s\r\n", power_evt_str[event]); #endif switch (event) { case USB_EVT_DETECTED: if (!NRF_USBD->ENABLE) { // Prepare for receiving READY event: disable interrupt since we will blocking wait NRF_USBD->INTENCLR = USBD_INTEN_USBEVENT_Msk; NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; __ISB(); __DSB(); // for sync #ifdef NRF52_SERIES // NRF53 does not need this errata // ERRATA 171, 187, 166 if (nrf52_errata_187()) { // CRITICAL_REGION_ENTER(); if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; } else { *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; } // CRITICAL_REGION_EXIT(); } if (nrf52_errata_171()) { // CRITICAL_REGION_ENTER(); if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; } else { *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; } // CRITICAL_REGION_EXIT(); } #endif // Enable the peripheral (will cause Ready event) NRF_USBD->ENABLE = 1; __ISB(); __DSB(); // for sync // Enable HFCLK hfclk_enable(); } break; case USB_EVT_READY: // Skip if pull-up is enabled and HCLK is already running. // Application probably call this more than necessary. if (NRF_USBD->USBPULLUP && hfclk_running()) break; // Waiting for USBD peripheral enabled while (!(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE)) {} NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; __ISB(); __DSB(); // for sync #ifdef NRF52_SERIES if (nrf52_errata_171()) { // CRITICAL_REGION_ENTER(); if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; } else { *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } if (nrf52_errata_187()) { // CRITICAL_REGION_ENTER(); if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; } else { *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } if (nrf52_errata_166()) { *((volatile uint32_t*) (NRF_USBD_BASE + 0x800)) = 0x7E3; *((volatile uint32_t*) (NRF_USBD_BASE + 0x804)) = 0x40; __ISB(); __DSB(); } #endif // ISO buffer Lower half for IN, upper half for OUT NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; // Enable bus-reset interrupt NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; // Enable interrupt, priorities should be set by application NVIC_ClearPendingIRQ(USBD_IRQn); // Don't enable USBD interrupt yet, if dcd_init() did not finish yet // Interrupt will be enabled by tud_init(), when USB stack is ready // to handle interrupts. if (tud_inited()) { NVIC_EnableIRQ(USBD_IRQn); } // Wait for HFCLK while (!hfclk_running()) {} // Enable pull up NRF_USBD->USBPULLUP = 1; __ISB(); __DSB(); // for sync break; case USB_EVT_REMOVED: if (NRF_USBD->ENABLE) { // Abort all transfers // Disable pull up NRF_USBD->USBPULLUP = 0; __ISB(); __DSB(); // for sync // Disable Interrupt NVIC_DisableIRQ(USBD_IRQn); // disable all interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->ENABLE = 0; __ISB(); __DSB(); // for sync hfclk_disable(); dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); } break; default: break; } } #endif ================================================ FILE: src/portable/nuvoton/nuc120/dcd_nuc120.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019-2020 Peter Lawrence * * 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. * * This file is part of the TinyUSB stack. */ /* Theory of operation: The NUC100/NUC120 USBD peripheral has six "EP"s, but each is simplex, so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for EP0_IN and EP0_OUT respectively. This leaves up to four for user usage. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC120) #include "device/dcd.h" #include "NUC100Series.h" /* allocation of USBD RAM for Setup, EP0_IN, and and EP_OUT */ #define PERIPH_SETUP_BUF_BASE 0 #define PERIPH_SETUP_BUF_LEN 8 #define PERIPH_EP0_BUF_BASE (PERIPH_SETUP_BUF_BASE + PERIPH_SETUP_BUF_LEN) #define PERIPH_EP0_BUF_LEN CFG_TUD_ENDPOINT0_SIZE #define PERIPH_EP1_BUF_BASE (PERIPH_EP0_BUF_BASE + PERIPH_EP0_BUF_LEN) #define PERIPH_EP1_BUF_LEN CFG_TUD_ENDPOINT0_SIZE #define PERIPH_EP2_BUF_BASE (PERIPH_EP1_BUF_BASE + PERIPH_EP1_BUF_LEN) /* rather important info unfortunately not provided by device include files: how much there is */ #define USBD_BUF_SIZE 512 enum ep_enum { PERIPH_EP0 = 0, PERIPH_EP1 = 1, PERIPH_EP2 = 2, PERIPH_EP3 = 3, PERIPH_EP4 = 4, PERIPH_EP5 = 5, PERIPH_MAX_EP, }; /* set by dcd_set_address() */ static volatile uint8_t assigned_address; /* reset by dcd_init(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ static uint32_t bufseg_addr; /* used by dcd_edpt_xfer() and the ISR to reset the data sync (DATA0/DATA1) in an EP0_IN transfer */ static bool active_ep0_xfer; /* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ static struct xfer_ctl_t { uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ // tu_fifo_t * ff; /* pointer to FIFO required for dcd_edpt_xfer_fifo() */ // TODO support dcd_edpt_xfer_fifo API union { uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ }; uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ } xfer_table[PERIPH_MAX_EP]; /* local helper functions */ static void usb_attach(void) { USBD->DRVSE0 &= ~USBD_DRVSE0_DRVSE0_Msk; } static void usb_detach(void) { USBD->DRVSE0 |= USBD_DRVSE0_DRVSE0_Msk; } static inline void usb_memcpy(uint8_t *dest, uint8_t *src, uint16_t size) { while(size--) *dest++ = *src++; } static void usb_control_send_zlp(void) { USBD->EP[PERIPH_EP0].CFG |= USBD_CFG_DSQ_SYNC_Msk; USBD->EP[PERIPH_EP0].MXPLD = 0; } /* reconstruct ep_addr from particular USB Configuration Register */ static uint8_t decode_ep_addr(USBD_EP_T *ep) { uint8_t ep_addr = ep->CFG & USBD_CFG_EP_NUM_Msk; if ( USBD_CFG_EPMODE_IN == (ep->CFG & USBD_CFG_STATE_Msk) ) ep_addr |= TUSB_DIR_IN_MASK; return ep_addr; } /* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EP0...) */ static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) { USBD_EP_T *ep; enum ep_enum ep_index; for (ep_index = PERIPH_EP0, ep = USBD->EP; ep_index < PERIPH_MAX_EP; ep_index++, ep++) { if (add) { /* take first peripheral endpoint that is unused */ if (0 == (ep->CFG & USBD_CFG_STATE_Msk)) return ep; } else { /* find a peripheral endpoint that matches ep_addr */ uint8_t candidate_ep_addr = decode_ep_addr(ep); if (candidate_ep_addr == ep_addr) return ep; } } return NULL; } /* perform an IN endpoint transfer; this is called by dcd_edpt_xfer() and the ISR */ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) { uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now); } else #endif { // USB SRAM seems to only support byte access and memcpy could possibly do it by words usb_memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); } ep->MXPLD = bytes_now; } /* called by dcd_init() as well as by the ISR during a USB bus reset */ static void bus_reset(void) { USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) { USBD->EP[ep_index].CFG = 0; USBD->EP[ep_index].CFGP = 0; } /* allocate the default EP0 endpoints */ USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; /* USB RAM beyond what we've allocated above is available to the user */ bufseg_addr = PERIPH_EP2_BUF_BASE; /* Reset USB device address */ USBD->FADDR = 0; /* reset EP0_IN flag */ active_ep0_xfer = false; } /* centralized location for USBD interrupt enable bit mask */ static const uint32_t enabled_irqs = USBD_INTSTS_FLDET_STS_Msk | USBD_INTSTS_BUS_STS_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USB_STS_Msk; /* NUC100/NUC120 TinyUSB API driver implementation */ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; USBD->ATTR = 0x7D0; usb_detach(); bus_reset(); usb_attach(); USBD->INTSTS = enabled_irqs; USBD->INTEN = enabled_irqs; return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ assigned_address = dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; USBD->ATTR = USBD_ATTR_RWAKEUP_Msk; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { (void) rhport; USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); TU_ASSERT(ep); /* mine the data for the information we need */ int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); int const size = tu_edpt_packet_size(p_endpoint_desc); tusb_xfer_type_t const type = (tusb_xfer_type_t) p_endpoint_desc->bmAttributes.xfer; struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* allocate buffer from USB RAM */ ep->BUFSEG = bufseg_addr; bufseg_addr += size; TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); /* construct USB Configuration Register value and then write it */ uint32_t cfg = tu_edpt_number(p_endpoint_desc->bEndpointAddress); cfg |= (TUSB_DIR_IN == dir) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; if (TUSB_XFER_ISOCHRONOUS == type) cfg |= USBD_CFG_TYPE_ISO; ep->CFG = cfg; /* make a note of the endpoint size */ xfer->max_packet_size = size; return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; // TODO not implemented yet } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void) rhport; (void) desc_ep; return false; // TODO not implemented yet } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = buffer; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; /* for the first of one or more EP0_IN packets in a message, the first must be DATA1 */ if ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQ_SYNC_Msk; if (TUSB_DIR_IN == dir) { dcd_in_xfer(xfer, ep); } else { xfer->out_bytes_so_far = 0; ep->MXPLD = xfer->max_packet_size; } return true; } #if 0 // TODO support dcd_edpt_xfer_fifo API bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = NULL; // Indicates a FIFO shall be used xfer->ff = ff; xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; if (TUSB_DIR_IN == dir) { dcd_in_xfer(xfer, ep); } else { xfer->out_bytes_so_far = 0; ep->MXPLD = xfer->max_packet_size; } return true; } #endif void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); ep->CFGP |= USBD_CFGP_SSTALL_Msk; } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); ep->CFG |= USBD_CFG_CSTALL_Msk; } void dcd_int_handler(uint8_t rhport) { (void) rhport; uint32_t status = USBD->INTSTS; uint32_t state = USBD->ATTR & 0xf; if(status & USBD_INTSTS_FLDET_STS_Msk) { if(USBD->FLDET & USBD_FLDET_FLDET_Msk) { /* USB connect */ USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; } else { /* USB disconnect */ USBD->ATTR &= ~USBD_ATTR_USB_EN_Msk; } } if(status & USBD_INTSTS_BUS_STS_Msk) { if(state & USBD_STATE_USBRST) { /* USB bus reset */ USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); } if(state & USBD_STATE_SUSPEND) { /* Enable USB but disable PHY */ USBD->ATTR &= ~USBD_ATTR_PHY_EN_Msk; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if(state & USBD_STATE_RESUME) { /* Enable USB and enable PHY */ USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } if(status & USBD_INTSTS_SETUP_Msk) { /* clear the data ready flag of control endpoints */ USBD->EP[PERIPH_EP0].CFGP |= USBD_CFGP_CLRRDY_Msk; USBD->EP[PERIPH_EP1].CFGP |= USBD_CFGP_CLRRDY_Msk; /* get SETUP packet from USB buffer */ dcd_event_setup_received(0, (uint8_t *)USBD_BUF_BASE, true); } if(status & USBD_INTSTS_USB_STS_Msk) { if (status & (1UL << USBD_INTSTS_EPEVT_Pos)) /* PERIPH_EP0 (EP0_IN) event: this is treated separately from the rest */ { /* given ACK from host has happened, we can now set the address (if not already done) */ if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) USBD->FADDR = assigned_address; uint16_t const available_bytes = USBD->EP[PERIPH_EP0].MXPLD; active_ep0_xfer = (available_bytes == xfer_table[PERIPH_EP0].max_packet_size); dcd_event_xfer_complete(0, 0x80, available_bytes, XFER_RESULT_SUCCESS, true); } /* service PERIPH_EP1 through PERIPH_EP7 */ enum ep_enum ep_index; uint32_t mask; struct xfer_ctl_t *xfer; USBD_EP_T *ep; for (ep_index = PERIPH_EP1, mask = (2UL << USBD_INTSTS_EPEVT_Pos), xfer = &xfer_table[PERIPH_EP1], ep = &USBD->EP[PERIPH_EP1]; ep_index < PERIPH_MAX_EP; ep_index++, mask <<= 1, xfer++, ep++) { if(status & mask) { USBD->INTSTS = mask; uint16_t const available_bytes = ep->MXPLD; uint8_t const ep_addr = decode_ep_addr(ep); bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); if (out_ep) { /* copy the data from the PC to the previously provided buffer */ #if 0 // // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes); } else #endif { // USB SRAM seems to only support byte access and memcpy could possibly do it by words usb_memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); xfer->data_ptr += available_bytes; } xfer->out_bytes_so_far += available_bytes; /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); else ep->MXPLD = xfer->max_packet_size; } else { /* update the bookkeeping to reflect the data that has now been sent to the PC */ xfer->in_remaining_bytes -= available_bytes; xfer->data_ptr += available_bytes; /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ if (xfer->in_remaining_bytes) dcd_in_xfer(xfer, ep); else dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); } } } } /* acknowledge all interrupts */ USBD->INTSTS = status & enabled_irqs; } void dcd_disconnect(uint8_t rhport) { (void) rhport; usb_detach(); } void dcd_connect(uint8_t rhport) { (void) rhport; usb_attach(); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } #endif ================================================ FILE: src/portable/nuvoton/nuc121/dcd_nuc121.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Peter Lawrence * * 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. * * This file is part of the TinyUSB stack. */ /* Theory of operation: The NUC121/NUC125/NUC126 USBD peripheral has eight "EP"s, but each is simplex, so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for EP0_IN and EP0_OUT respectively. This leaves up to six for user usage. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && ( (CFG_TUSB_MCU == OPT_MCU_NUC121) || (CFG_TUSB_MCU == OPT_MCU_NUC126) ) #include "device/dcd.h" #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "NuMicro.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) // We disable SOF for now until needed later on #ifndef USE_SOF # define USE_SOF 0 #endif /* allocation of USBD RAM for Setup, EP0_IN, and and EP_OUT */ #define PERIPH_SETUP_BUF_BASE 0 #define PERIPH_SETUP_BUF_LEN 8 #define PERIPH_EP0_BUF_BASE (PERIPH_SETUP_BUF_BASE + PERIPH_SETUP_BUF_LEN) #define PERIPH_EP0_BUF_LEN CFG_TUD_ENDPOINT0_SIZE #define PERIPH_EP1_BUF_BASE (PERIPH_EP0_BUF_BASE + PERIPH_EP0_BUF_LEN) #define PERIPH_EP1_BUF_LEN CFG_TUD_ENDPOINT0_SIZE #define PERIPH_EP2_BUF_BASE (PERIPH_EP1_BUF_BASE + PERIPH_EP1_BUF_LEN) /* rather important info unfortunately not provided by device include files: how much there is */ #define USBD_BUF_SIZE ((CFG_TUSB_MCU == OPT_MCU_NUC121) ? 768 : 512) enum ep_enum { PERIPH_EP0 = 0, PERIPH_EP1 = 1, PERIPH_EP2 = 2, PERIPH_EP3 = 3, PERIPH_EP4 = 4, PERIPH_EP5 = 5, PERIPH_EP6 = 6, PERIPH_EP7 = 7, PERIPH_MAX_EP, }; /* reset by dcd_init(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ static uint32_t bufseg_addr; /* used by dcd_edpt_xfer() and the ISR to reset the data sync (DATA0/DATA1) in an EP0_IN transfer */ static bool active_ep0_xfer; /* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_in_xfer(), and the ISR */ static struct xfer_ctl_t { uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API union { uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ }; uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ } xfer_table[PERIPH_MAX_EP]; /* local helper functions */ static void usb_attach(void) { USBD->SE0 &= ~USBD_SE0_SE0_Msk; } static void usb_detach(void) { USBD->SE0 |= USBD_SE0_SE0_Msk; } static inline void usb_memcpy(uint8_t *dest, uint8_t *src, uint16_t size) { while(size--) *dest++ = *src++; } static void usb_control_send_zlp(void) { USBD->EP[PERIPH_EP0].CFG |= USBD_CFG_DSQSYNC_Msk; USBD->EP[PERIPH_EP0].MXPLD = 0; } /* reconstruct ep_addr from particular USB Configuration Register */ static uint8_t decode_ep_addr(USBD_EP_T *ep) { uint8_t ep_addr = ep->CFG & USBD_CFG_EPNUM_Msk; if ( USBD_CFG_EPMODE_IN == (ep->CFG & USBD_CFG_STATE_Msk) ) ep_addr |= TUSB_DIR_IN_MASK; return ep_addr; } /* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EP0...) */ static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) { USBD_EP_T *ep; enum ep_enum ep_index; for (ep_index = PERIPH_EP0, ep = USBD->EP; ep_index < PERIPH_MAX_EP; ep_index++, ep++) { if (add) { /* take first peripheral endpoint that is unused */ if (0 == (ep->CFG & USBD_CFG_STATE_Msk)) return ep; } else { /* find a peripheral endpoint that matches ep_addr */ uint8_t candidate_ep_addr = decode_ep_addr(ep); if (candidate_ep_addr == ep_addr) return ep; } } return NULL; } /* perform an IN endpoint transfer; this is called by dcd_edpt_xfer() and the ISR */ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) { uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now); } else #endif { // USB SRAM seems to only support byte access and memcpy could possibly do it by words usb_memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now); } ep->MXPLD = bytes_now; } /* called by dcd_init() as well as by the ISR during a USB bus reset */ static void bus_reset(void) { USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) { USBD->EP[ep_index].CFG = 0; USBD->EP[ep_index].CFGP = 0; } /* allocate the default EP0 endpoints */ USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; /* USB RAM beyond what we've allocated above is available to the user */ bufseg_addr = PERIPH_EP2_BUF_BASE; /* Reset USB device address */ USBD->FADDR = 0; /* reset EP0_IN flag */ active_ep0_xfer = false; } /* centralized location for USBD interrupt enable bit mask */ enum { ENABLED_IRQS = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USBIF_Msk | (USE_SOF ? USBD_INTSTS_SOFIF_Msk : 0) }; /* NUC121/NUC125/NUC126 TinyUSB API driver implementation */ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; #ifdef SUPPORT_LPM USBD->ATTR = 0x7D0 | USBD_LPMACK; #else USBD->ATTR = 0x7D0; #endif usb_detach(); bus_reset(); usb_attach(); USBD->INTSTS = ENABLED_IRQS; USBD->INTEN = ENABLED_IRQS; return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ // DCD can only set address after status for this request is complete. // do it at dcd_edpt0_status_complete() } static void remote_wakeup_delay(void) { // try to delay for 1 ms uint32_t count = SystemCoreClock / 1000; while(count--) __NOP(); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; // Enable PHY before sending Resume('K') state USBD->ATTR |= USBD_ATTR_PHYEN_Msk; USBD->ATTR |= USBD_ATTR_RWAKEUP_Msk; // Per specs: remote wakeup signal bit must be clear within 1-15ms remote_wakeup_delay(); USBD->ATTR &=~USBD_ATTR_RWAKEUP_Msk; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { (void) rhport; USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); TU_ASSERT(ep); /* mine the data for the information we need */ int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); int const size = tu_edpt_packet_size(p_endpoint_desc); tusb_xfer_type_t const type = (tusb_xfer_type_t) p_endpoint_desc->bmAttributes.xfer; struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* allocate buffer from USB RAM */ ep->BUFSEG = bufseg_addr; bufseg_addr += size; TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); /* construct USB Configuration Register value and then write it */ uint32_t cfg = tu_edpt_number(p_endpoint_desc->bEndpointAddress); cfg |= (TUSB_DIR_IN == dir) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; if (TUSB_XFER_ISOCHRONOUS == type) { cfg |= USBD_CFG_TYPE_ISO; } ep->CFG = cfg; /* make a note of the endpoint size */ xfer->max_packet_size = size; return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; // TODO not implemented yet } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void) rhport; (void) desc_ep; return false; // TODO not implemented yet } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = buffer; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; /* for the first of one or more EP0_IN packets in a message, the first must be DATA1 */ if ( (0x80 == ep_addr) && !active_ep0_xfer ) ep->CFG |= USBD_CFG_DSQSYNC_Msk; if (TUSB_DIR_IN == dir) { dcd_in_xfer(xfer, ep); } else { xfer->out_bytes_so_far = 0; ep->MXPLD = xfer->max_packet_size; } return true; } #if 0 // TODO support dcd_edpt_xfer_fifo API bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = NULL; // Indicates a FIFO shall be used xfer->ff = ff; xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; if (TUSB_DIR_IN == dir) { dcd_in_xfer(xfer, ep); } else { xfer->out_bytes_so_far = 0; ep->MXPLD = xfer->max_packet_size; } return true; } #endif void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); ep->CFGP |= USBD_CFGP_SSTALL_Msk; } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); ep->CFG = (ep->CFG & ~USBD_CFG_DSQSYNC_Msk) | USBD_CFG_CSTALL_Msk; } void dcd_int_handler(uint8_t rhport) { (void) rhport; // Mask non-enabled irqs, ex. SOF uint32_t status = USBD->INTSTS & (ENABLED_IRQS | 0xffffff00); #ifdef SUPPORT_LPM uint32_t state = USBD->ATTR & 0x300f; #else uint32_t state = USBD->ATTR & 0xf; #endif if(status & USBD_INTSTS_VBDETIF_Msk) { if(USBD->VBUSDET & USBD_VBUSDET_VBUSDET_Msk) { /* USB connect */ USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; } else { /* USB disconnect */ USBD->ATTR &= ~USBD_ATTR_USBEN_Msk; } } if(status & USBD_INTSTS_BUSIF_Msk) { if(state & USBD_ATTR_USBRST_Msk) { /* USB bus reset */ USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); } if(state & USBD_ATTR_SUSPEND_Msk) { /* Enable USB but disable PHY */ USBD->ATTR &= ~USBD_ATTR_PHYEN_Msk; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if(state & USBD_ATTR_RESUME_Msk) { /* Enable USB and enable PHY */ USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } if(status & USBD_INTSTS_SETUP_Msk) { /* clear the data ready flag of control endpoints */ USBD->EP[PERIPH_EP0].CFGP |= USBD_CFGP_CLRRDY_Msk; USBD->EP[PERIPH_EP1].CFGP |= USBD_CFGP_CLRRDY_Msk; /* get SETUP packet from USB buffer */ dcd_event_setup_received(0, (uint8_t *)USBD_BUF_BASE, true); } if(status & USBD_INTSTS_USBIF_Msk) { if (status & USBD_INTSTS_EPEVT0_Msk) /* PERIPH_EP0 (EP0_IN) event: this is treated separately from the rest */ { uint16_t const available_bytes = USBD->EP[PERIPH_EP0].MXPLD; active_ep0_xfer = (available_bytes == xfer_table[PERIPH_EP0].max_packet_size); dcd_event_xfer_complete(0, 0x80, available_bytes, XFER_RESULT_SUCCESS, true); } /* service PERIPH_EP1 through PERIPH_EP7 */ enum ep_enum ep_index; uint32_t mask; struct xfer_ctl_t *xfer; USBD_EP_T *ep; for (ep_index = PERIPH_EP1, mask = USBD_INTSTS_EPEVT1_Msk, xfer = &xfer_table[PERIPH_EP1], ep = &USBD->EP[PERIPH_EP1]; ep_index <= PERIPH_EP7; ep_index++, mask <<= 1, xfer++, ep++) { if(status & mask) { USBD->INTSTS = mask; uint16_t const available_bytes = ep->MXPLD; uint8_t const ep_addr = decode_ep_addr(ep); bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); if (out_ep) { /* copy the data from the PC to the previously provided buffer */ #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes); } else #endif { // USB SRAM seems to only support byte access and memcpy could possibly do it by words usb_memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes); xfer->data_ptr += available_bytes; } xfer->out_bytes_so_far += available_bytes; /* when the transfer is finished, alert TinyUSB; otherwise, accept more data */ if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); else ep->MXPLD = xfer->max_packet_size; } else { /* update the bookkeeping to reflect the data that has now been sent to the PC */ xfer->in_remaining_bytes -= available_bytes; xfer->data_ptr += available_bytes; /* if more data to send, send it; otherwise, alert TinyUSB that we've finished */ if (xfer->in_remaining_bytes) dcd_in_xfer(xfer, ep); else dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); } } } } if(status & USBD_INTSTS_SOFIF_Msk) { /* Start-Of-Frame event */ dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } /* acknowledge all interrupts */ USBD->INTSTS = status & ENABLED_IRQS; } // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS ) { uint8_t const dev_addr = (uint8_t) request->wValue; // Setting new address after the whole request is complete USBD->FADDR = dev_addr; } } void dcd_disconnect(uint8_t rhport) { (void) rhport; usb_detach(); } void dcd_connect(uint8_t rhport) { (void) rhport; usb_attach(); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } #endif ================================================ FILE: src/portable/nuvoton/nuc505/dcd_nuc505.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Peter Lawrence * * 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. * * This file is part of the TinyUSB stack. */ /* Theory of operation: The NUC505 USBD peripheral has twelve "EP"s, where each is simplex, in addition to dedicated support for the control endpoint (EP0). The non-user endpoints are referred to as "user" EPs in this code, and follow the datasheet nomenclature of EPA through EPL. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505) #include "device/dcd.h" #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "NUC505Series.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif /* * The DMA functionality of the USBD peripheral does not appear to succeed with * transfer lengths that are longer (> 64 bytes) and are not a multiple of 4. * Keep disabled for now. */ #define USE_DMA 0 /* rather important info unfortunately not provided by device include files */ #define USBD_BUF_SIZE 2048 /* how much USB buffer space there is */ #define USBD_MAX_DMA_LEN 0x1000 /* max bytes that can be DMAed at one time */ enum ep_enum { PERIPH_EPA = 0, PERIPH_EPB = 1, PERIPH_EPC = 2, PERIPH_EPD = 3, PERIPH_EPE = 4, PERIPH_EPF = 5, PERIPH_EPG = 6, PERIPH_EPH = 7, PERIPH_EPI = 8, PERIPH_EPJ = 9, PERIPH_EPK = 10, PERIPH_EPL = 11, PERIPH_MAX_EP, }; static const uint8_t epcfg_eptype_table[] = { [TUSB_XFER_CONTROL] = 0, /* won't happen, since control EPs have dedicated registers */ [TUSB_XFER_ISOCHRONOUS] = 3 << USBD_EPCFG_EPTYPE_Pos, [TUSB_XFER_BULK] = 1 << USBD_EPCFG_EPTYPE_Pos, [TUSB_XFER_INTERRUPT] = 2 << USBD_EPCFG_EPTYPE_Pos, }; static const uint8_t eprspctl_eptype_table[] = { [TUSB_XFER_CONTROL] = 0, /* won't happen, since control EPs have dedicated registers */ [TUSB_XFER_ISOCHRONOUS] = 2 << USBD_EPRSPCTL_MODE_Pos, /* Fly Mode */ [TUSB_XFER_BULK] = 0 << USBD_EPRSPCTL_MODE_Pos, /* Auto-Validate Mode */ [TUSB_XFER_INTERRUPT] = 1 << USBD_EPRSPCTL_MODE_Pos, /* Manual-Validate Mode */ }; /* set by dcd_set_address() */ static volatile uint8_t assigned_address; /* reset by bus_reset(), this is used by dcd_edpt_open() to assign USBD peripheral buffer addresses */ static uint32_t bufseg_addr; /* RAM table needed to track ongoing transfers performed by dcd_edpt_xfer(), dcd_userEP_in_xfer(), and the ISR */ static struct xfer_ctl_t { uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */ // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API union { uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */ uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */ }; uint16_t max_packet_size; /* needed since device driver only finds out this at runtime */ uint16_t total_bytes; /* quantity needed to pass as argument to dcd_event_xfer_complete() (for IN endpoints) */ uint8_t ep_addr; bool dma_requested; } xfer_table[PERIPH_MAX_EP]; /* in addition to xfer_table, additional bespoke bookkeeping is maintained for control EP0 IN */ static struct { uint8_t *data_ptr; uint16_t in_remaining_bytes; uint16_t total_bytes; } ctrl_in_xfer; static volatile struct xfer_ctl_t *current_dma_xfer; /* local helper functions */ static void usb_attach(void) { USBD->PHYCTL |= USBD_PHYCTL_DPPUEN_Msk; } static void usb_detach(void) { USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk; } static void usb_control_send_zlp(void) { USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; USBD->CEPCTL = 0; /* clear NAKCLR bit */ USBD->CEPINTEN = USBD_CEPINTEN_STSDONEIEN_Msk; } /* map 8-bit ep_addr into peripheral endpoint index (PERIPH_EPA...) */ static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add) { USBD_EP_T *ep; enum ep_enum ep_index; struct xfer_ctl_t *xfer; for (ep_index = PERIPH_EPA, xfer = &xfer_table[PERIPH_EPA], ep = USBD->EP; ep_index < PERIPH_MAX_EP; ep_index++, xfer++, ep++) { if (add) { /* take first peripheral endpoint that is unused */ if (0 == (ep->EPCFG & USBD_EPCFG_EPEN_Msk)) return ep; } else { /* find a peripheral endpoint that matches ep_addr */ if (xfer->ep_addr == ep_addr) return ep; } } return NULL; } /* perform a non-control IN endpoint transfer; this is called by the ISR */ static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) { uint16_t const bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size); /* precompute what amount of data will be left */ xfer->in_remaining_bytes -= bytes_now; /* if there will be no more data to send, we replace the BUFEMPTYIF EP interrupt with TXPKIF; that way, we alert TinyUSB as soon as this last packet has been sent */ if (0 == xfer->in_remaining_bytes) { ep->EPINTSTS = USBD_EPINTSTS_TXPKIF_Msk; ep->EPINTEN = USBD_EPINTEN_TXPKIEN_Msk; } /* provided buffers are thankfully 32-bit aligned, allowing most data to be transferred as 32-bit */ #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_read_n_access_mode(xfer->ff, (void *) (&ep->EPDAT_BYTE), bytes_now, true); } else #endif { uint16_t countdown = bytes_now; while (countdown > 3) { uint32_t u32; memcpy(&u32, xfer->data_ptr, 4); ep->EPDAT = u32; xfer->data_ptr += 4; countdown -= 4; } while (countdown--) ep->EPDAT_BYTE = *xfer->data_ptr++; } /* for short packets, we must nudge the peripheral to say 'that's all folks' */ if (bytes_now != xfer->max_packet_size) ep->EPRSPCTL = USBD_EPRSPCTL_SHORTTXEN_Msk; } /* called by dcd_init() as well as by the ISR during a USB bus reset */ static void bus_reset(void) { for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++) { USBD->EP[ep_index].EPCFG = 0; xfer_table[ep_index].dma_requested = false; } USBD->DMACNT = 0; USBD->DMACTL = USBD_DMACTL_DMARST_Msk; USBD->DMACTL = 0; /* allocate the default EP0 endpoints */ USBD->CEPBUFSTART = 0; USBD->CEPBUFEND = 0 + CFG_TUD_ENDPOINT0_SIZE - 1; /* USB RAM beyond what we've allocated above is available to the user */ bufseg_addr = CFG_TUD_ENDPOINT0_SIZE; /* Reset USB device address */ USBD->FADDR = 0; current_dma_xfer = NULL; } #if USE_DMA /* this must only be called by the ISR; it does its best to share the single DMA engine across all user EPs (IN and OUT) */ static void service_dma(void) { if (current_dma_xfer) return; enum ep_enum ep_index; struct xfer_ctl_t *xfer; USBD_EP_T *ep; for (ep_index = PERIPH_EPA, xfer = &xfer_table[PERIPH_EPA], ep = &USBD->EP[PERIPH_EPA]; ep_index < PERIPH_MAX_EP; ep_index++, xfer++, ep++) { uint16_t const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk; if (!xfer->dma_requested || !available_bytes) continue; /* instruct DMA to copy the data from the PC to the previously provided buffer when the bus interrupt DMADONEIEN subsequently fires, the transfer will have finished */ USBD->DMACTL = xfer->ep_addr & USBD_DMACTL_EPNUM_Msk; USBD->DMAADDR = (uint32_t)xfer->data_ptr; USBD->DMACNT = available_bytes; USBD->BUSINTSTS = USBD_BUSINTSTS_DMADONEIF_Msk; xfer->out_bytes_so_far += available_bytes; current_dma_xfer = xfer; USBD->DMACTL |= USBD_DMACTL_DMAEN_Msk; return; } } #endif /* centralized location for USBD interrupt enable bit masks */ static const uint32_t enabled_irqs = USBD_GINTEN_USBIEN_Msk | \ USBD_GINTEN_EPAIEN_Msk | USBD_GINTEN_EPBIEN_Msk | USBD_GINTEN_EPCIEN_Msk | USBD_GINTEN_EPDIEN_Msk | USBD_GINTEN_EPEIEN_Msk | USBD_GINTEN_EPFIEN_Msk | \ USBD_GINTEN_EPGIEN_Msk | USBD_GINTEN_EPHIEN_Msk | USBD_GINTEN_EPIIEN_Msk | USBD_GINTEN_EPJIEN_Msk | USBD_GINTEN_EPKIEN_Msk | USBD_GINTEN_EPLIEN_Msk | \ USBD_GINTEN_CEPIEN_Msk; /* NUC505 TinyUSB API driver implementation */ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; /* configure interrupts in their initial state; BUSINTEN and CEPINTEN will be subsequently and dynamically re-written as needed */ USBD->GINTEN = enabled_irqs; USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_VBUSDETIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; USBD->CEPINTEN = 0; bus_reset(); usb_attach(); return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; usb_control_send_zlp(); /* SET_ADDRESS is the one exception where TinyUSB doesn't use dcd_edpt_xfer() to generate a ZLP */ assigned_address = dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; USBD->OPER |= USBD_OPER_RESUMEEN_Msk; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { (void) rhport; USBD_EP_T *ep = ep_entry(p_endpoint_desc->bEndpointAddress, true); TU_ASSERT(ep); /* mine the data for the information we need */ int const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); int const size = tu_edpt_packet_size(p_endpoint_desc); tusb_xfer_type_t const type = p_endpoint_desc->bmAttributes.xfer; struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* allocate buffer from USB RAM */ ep->EPBUFSTART = bufseg_addr; bufseg_addr += size; ep->EPBUFEND = bufseg_addr - 1; TU_ASSERT(bufseg_addr <= USBD_BUF_SIZE); ep->EPMPS = size; ep->EPRSPCTL = USB_EP_RSPCTL_FLUSH | eprspctl_eptype_table[type]; /* construct USB Configuration Register value and then write it */ uint32_t cfg = (uint32_t)tu_edpt_number(p_endpoint_desc->bEndpointAddress) << USBD_EPCFG_EPNUM_Pos; if (TUSB_DIR_IN == dir) cfg |= USBD_EPCFG_EPDIR_Msk; cfg |= epcfg_eptype_table[type] | USBD_EPCFG_EPEN_Msk; ep->EPCFG = cfg; /* make a note of the endpoint particulars */ xfer->max_packet_size = size; xfer->ep_addr = p_endpoint_desc->bEndpointAddress; return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; // TODO not implemented yet } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void) rhport; (void) desc_ep; return false; // TODO not implemented yet } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; if (0x80 == ep_addr) /* control EP0 IN */ { if (total_bytes) { USBD->CEPCTL = USBD_CEPCTL_FLUSH_Msk; ctrl_in_xfer.data_ptr = buffer; ctrl_in_xfer.in_remaining_bytes = total_bytes; ctrl_in_xfer.total_bytes = total_bytes; USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk; USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk; } else { usb_control_send_zlp(); } } else if (0x00 == ep_addr) /* control EP0 OUT */ { if (total_bytes) { /* if TinyUSB is asking for EP0 OUT data, it is almost certainly already in the buffer */ while (total_bytes < USBD->CEPRXCNT); for (int count = 0; count < total_bytes; count++) *buffer++ = USBD->CEPDAT_BYTE; dcd_event_xfer_complete(0, ep_addr, total_bytes, XFER_RESULT_SUCCESS, true); } } else { /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); TU_ASSERT(ep); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = buffer; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; if (TUSB_DIR_IN == dir) { ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk; } else { xfer->out_bytes_so_far = 0; ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk; } } return true; } #if 0 // TODO support dcd_edpt_xfer_fifo API bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; TU_ASSERT(0x80 != ep_addr && 0x00 != ep_addr); // Must not be used for control stuff /* mine the data for the information we need */ tusb_dir_t dir = tu_edpt_dir(ep_addr); USBD_EP_T *ep = ep_entry(ep_addr, false); struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP]; /* store away the information we'll needing now and later */ xfer->data_ptr = NULL; // Indicates a FIFO shall be used xfer->ff = ff; xfer->in_remaining_bytes = total_bytes; xfer->total_bytes = total_bytes; if (TUSB_DIR_IN == dir) { ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk; } else { xfer->out_bytes_so_far = 0; ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk; } return true; } #endif void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if (tu_edpt_number(ep_addr)) { USBD_EP_T *ep = ep_entry(ep_addr, false); TU_ASSERT(ep, ); ep->EPRSPCTL = (ep->EPRSPCTL & 0xf7) | USBD_EPRSPCTL_HALT_Msk; } else { USBD->CEPCTL = USBD_CEPCTL_STALLEN_Msk; } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if (tu_edpt_number(ep_addr)) { USBD_EP_T *ep = ep_entry(ep_addr, false); TU_ASSERT(ep, ); ep->EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk; } } void dcd_int_handler(uint8_t rhport) { (void) rhport; uint32_t status = USBD->GINTSTS; /* USB interrupt */ if (status & USBD_GINTSTS_USBIF_Msk) { uint32_t bus_state = USBD->BUSINTSTS; if (bus_state & USBD_BUSINTSTS_SOFIF_Msk) { /* Start-Of-Frame event */ dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } if (bus_state & USBD_BUSINTSTS_RSTIF_Msk) { bus_reset(); USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; USBD->CEPINTSTS = 0x1ffc; tusb_speed_t speed = (USBD->OPER & USBD_OPER_CURSPD_Msk) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; dcd_event_bus_reset(0, speed, true); } if (bus_state & USBD_BUSINTSTS_RESUMEIF_Msk) { USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } if (bus_state & USBD_BUSINTSTS_SUSPENDIF_Msk) { USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (bus_state & USBD_BUSINTSTS_HISPDIF_Msk) { USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; } if (bus_state & USBD_BUSINTSTS_DMADONEIF_Msk) { #if USE_DMA if (current_dma_xfer) { current_dma_xfer->dma_requested = false; uint16_t available_bytes = USBD->DMACNT & USBD_DMACNT_DMACNT_Msk; /* if the most recent DMA finishes the transfer, alert TinyUSB; otherwise, the next RXPKIF/INTKIF endpoint interrupt will prompt the next DMA */ if ( (current_dma_xfer->total_bytes == current_dma_xfer->out_bytes_so_far) || (available_bytes < current_dma_xfer->max_packet_size) ) { dcd_event_xfer_complete(0, current_dma_xfer->ep_addr, current_dma_xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); } current_dma_xfer = NULL; service_dma(); } #endif } if (bus_state & USBD_BUSINTSTS_VBUSDETIF_Msk) { if (USBD->PHYCTL & USBD_PHYCTL_VBUSDET_Msk) { /* USB connect */ USBD->PHYCTL |= USBD_PHYCTL_PHYEN_Msk | USBD_PHYCTL_DPPUEN_Msk; } else { /* USB disconnect */ USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk; } } USBD->BUSINTSTS = bus_state & (USBD_BUSINTSTS_SOFIF_Msk | USBD_BUSINTSTS_RSTIF_Msk | USBD_BUSINTSTS_RESUMEIF_Msk | USBD_BUSINTSTS_SUSPENDIF_Msk | USBD_BUSINTSTS_HISPDIF_Msk | USBD_BUSINTSTS_DMADONEIF_Msk | USBD_BUSINTSTS_PHYCLKVLDIF_Msk | USBD_BUSINTSTS_VBUSDETIF_Msk); } if (status & USBD_GINTSTS_CEPIF_Msk) { uint32_t cep_state = USBD->CEPINTSTS & USBD->CEPINTEN; if (cep_state & USBD_CEPINTSTS_SETUPPKIF_Msk) { /* get SETUP packet from USB buffer */ uint8_t setup_packet[8]; setup_packet[0] = (uint8_t)(USBD->SETUP1_0 >> 0); setup_packet[1] = (uint8_t)(USBD->SETUP1_0 >> 8); setup_packet[2] = (uint8_t)(USBD->SETUP3_2 >> 0); setup_packet[3] = (uint8_t)(USBD->SETUP3_2 >> 8); setup_packet[4] = (uint8_t)(USBD->SETUP5_4 >> 0); setup_packet[5] = (uint8_t)(USBD->SETUP5_4 >> 8); setup_packet[6] = (uint8_t)(USBD->SETUP7_6 >> 0); setup_packet[7] = (uint8_t)(USBD->SETUP7_6 >> 8); dcd_event_setup_received(0, setup_packet, true); } else if (cep_state & USBD_CEPINTSTS_INTKIF_Msk) { USBD->CEPINTSTS = USBD_CEPINTSTS_TXPKIF_Msk; if (!(cep_state & USBD_CEPINTSTS_STSDONEIF_Msk)) { USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk; uint16_t bytes_now = tu_min16(ctrl_in_xfer.in_remaining_bytes, CFG_TUD_ENDPOINT0_SIZE); for (int count = 0; count < bytes_now; count++) USBD->CEPDAT_BYTE = *ctrl_in_xfer.data_ptr++; ctrl_in_xfer.in_remaining_bytes -= bytes_now; USBD_START_CEP_IN(bytes_now); } else { USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk; } } else if (cep_state & USBD_CEPINTSTS_TXPKIF_Msk) { USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR); /* alert TinyUSB that the EP0 IN transfer has finished */ if ( (0 == ctrl_in_xfer.in_remaining_bytes) || (0 == ctrl_in_xfer.total_bytes) ) dcd_event_xfer_complete(0, 0x80, ctrl_in_xfer.total_bytes, XFER_RESULT_SUCCESS, true); if (ctrl_in_xfer.in_remaining_bytes) { USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk; USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk; } else { /* TinyUSB does its own fragmentation and ZLP for EP0; a transfer of zero means a ZLP */ if (0 == ctrl_in_xfer.total_bytes) USBD->CEPCTL = USBD_CEPCTL_ZEROLEN_Msk; USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk; USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk; } } else if (cep_state & USBD_CEPINTSTS_STSDONEIF_Msk) { /* given ACK from host has happened, we can now set the address (if not already done) */ if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) { USBD->FADDR = assigned_address; for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++) { if (USBD->EP[ep_index].EPCFG & USBD_EPCFG_EPEN_Msk) USBD->EP[ep_index].EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk; } } USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; } USBD->CEPINTSTS = cep_state; return; } if (status & (USBD_GINTSTS_EPAIF_Msk | USBD_GINTSTS_EPBIF_Msk | USBD_GINTSTS_EPCIF_Msk | USBD_GINTSTS_EPDIF_Msk | USBD_GINTSTS_EPEIF_Msk | USBD_GINTSTS_EPFIF_Msk | USBD_GINTSTS_EPGIF_Msk | USBD_GINTSTS_EPHIF_Msk | USBD_GINTSTS_EPIIF_Msk | USBD_GINTSTS_EPJIF_Msk | USBD_GINTSTS_EPKIF_Msk | USBD_GINTSTS_EPLIF_Msk)) { /* service PERIPH_EPA through PERIPH_EPL */ enum ep_enum ep_index; uint32_t mask; struct xfer_ctl_t *xfer; USBD_EP_T *ep; for (ep_index = PERIPH_EPA, mask = USBD_GINTSTS_EPAIF_Msk, xfer = &xfer_table[PERIPH_EPA], ep = &USBD->EP[PERIPH_EPA]; ep_index < PERIPH_MAX_EP; ep_index++, mask <<= 1, xfer++, ep++) { if(status & mask) { uint8_t const ep_addr = xfer->ep_addr; bool const out_ep = !(ep_addr & TUSB_DIR_IN_MASK); uint32_t ep_state = ep->EPINTSTS & ep->EPINTEN; if (out_ep) { #if USE_DMA xfer->dma_requested = true; service_dma(); #else uint16_t const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk; /* copy the data from the PC to the previously provided buffer */ #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_write_n_access_mode(xfer->ff, (const void *) &ep->EPDAT_BYTE, tu_min16(available_bytes, xfer->total_bytes - xfer->out_bytes_so_far), true); } else #endif { for (int count = 0; (count < available_bytes) && (xfer->out_bytes_so_far < xfer->total_bytes); count++, xfer->out_bytes_so_far++) { *xfer->data_ptr++ = ep->EPDAT_BYTE; } } /* when the transfer is finished, alert TinyUSB; otherwise, continue accepting more data */ if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) ) { dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true); } #endif } else if (ep_state & USBD_EPINTSTS_BUFEMPTYIF_Msk) { /* send any remaining data */ dcd_userEP_in_xfer(xfer, ep); } else if (ep_state & USBD_EPINTSTS_TXPKIF_Msk) { /* alert TinyUSB that we've finished */ dcd_event_xfer_complete(0, ep_addr, xfer->total_bytes, XFER_RESULT_SUCCESS, true); ep->EPINTEN = 0; } ep->EPINTSTS = ep_state; } } } } void dcd_disconnect(uint8_t rhport) { (void) rhport; usb_detach(); } void dcd_connect(uint8_t rhport) { (void) rhport; usb_attach(); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } #endif ================================================ FILE: src/portable/nxp/khci/dcd_khci.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS) #ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS #include "fsl_device_registers.h" #define KHCI USB0 #else #error "MCU is not supported" #endif #include "device/dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { TOK_PID_OUT = 0x1u, TOK_PID_IN = 0x9u, TOK_PID_SETUP = 0xDu, }; typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { uint16_t : 2; __IO uint16_t tok_pid : 4; uint16_t data : 1; __IO uint16_t own : 1; uint16_t : 8; }; struct { uint16_t : 2; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; uint16_t : 10; }; }; __IO uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; }buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { uint32_t max_packet_size :11; uint32_t : 5; uint32_t odd : 1; uint32_t :15; }; }; uint16_t length; uint16_t remaining; }endpoint_state_t; TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); typedef struct { union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; uint16_t bda[512]; }; TU_ATTR_ALIGNED(4) union { endpoint_state_t endpoint[16][2]; endpoint_state_t endpoint_unified[16 * 2]; }; uint8_t setup_packet[8]; uint8_t addr; }dcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); static void prepare_next_setup_packet(uint8_t rhport) { const unsigned out_odd = _dcd.endpoint[0][0].odd; const unsigned in_odd = _dcd.endpoint[0][1].odd; TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, ); _dcd.bdt[0][0][out_odd].data = 0; _dcd.bdt[0][0][out_odd ^ 1].data = 1; _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) { for (int i = 0; i < 16; ++i) { unsigned const endpt = KHCI->ENDPOINT[i].ENDPT; if (endpt & USB_ENDPT_EPSTALL_MASK) { // prepare next setup if endpoint0 if ( i == 0 ) prepare_next_setup_packet(rhport); // clear stall bit KHCI->ENDPOINT[i].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK; } } } static void process_tokdne(uint8_t rhport) { const unsigned s = KHCI->STAT; KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT); uint8_t const dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT; unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; /* fetch pid before discarded by the next steps */ const unsigned pid = bd->tok_pid; /* reset values for a next transfer */ bd->bdt_stall = 0; bd->dts = 1; bd->ninc = 0; bd->keep = 0; /* update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, bd->addr, true); KHCI->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; return; } const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; if (remaining && bc == ep->max_packet_size) { /* continue the transferring consecutive data */ ep->remaining = remaining; const int next_remaining = remaining - ep->max_packet_size; if (next_remaining > 0) { /* prepare to the after next transfer */ bd->addr += ep->max_packet_size * 2; bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; __DSB(); bd->own = 1; /* the own bit must set after addr */ } return; } const unsigned length = ep->length; dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), length - remaining, XFER_RESULT_SUCCESS, true); if (0 == epnum && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ if (_dcd.addr) { /* When the transfer was the SetAddress, * the device address should be updated here. */ KHCI->ADDR = _dcd.addr; _dcd.addr = 0; } prepare_next_setup_packet(rhport); } } static void process_bus_reset(uint8_t rhport) { KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; KHCI->CTL |= USB_CTL_ODDRST_MASK; KHCI->ADDR = 0; KHCI->INTEN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; for (unsigned i = 1; i < 16; ++i) { KHCI->ENDPOINT[i].ENDPT = 0; } buffer_descriptor_t *bd = _dcd.bdt[0][0]; for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } const endpoint_state_t ep0 = { .max_packet_size = CFG_TUD_ENDPOINT0_SIZE, .odd = 0, .length = 0, .remaining = 0, }; _dcd.endpoint[0][0] = ep0; _dcd.endpoint[0][1] = ep0; tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0])); _dcd.addr = 0; prepare_next_setup_packet(rhport); KHCI->CTL &= ~USB_CTL_ODDRST_MASK; dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } static void process_bus_sleep(uint8_t rhport) { // Enable resume & disable suspend interrupt const unsigned inten = KHCI->INTEN; KHCI->INTEN = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; KHCI->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; KHCI->USBCTRL |= USB_USBCTRL_SUSP_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } static void process_bus_resume(uint8_t rhport) { // Enable suspend & disable resume interrupt const unsigned inten = KHCI->INTEN; KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; // will also clear USB_USBTRC0_USB_RESUME_INT_MASK KHCI->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; KHCI->INTEN = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; // save crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; #endif KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); // restore crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; #endif tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); KHCI->INTEN = USB_INTEN_USBRSTEN_MASK; dcd_connect(rhport); NVIC_ClearPendingIRQ(USB0_IRQn); return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB0_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB0_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { _dcd.addr = dev_addr & 0x7F; /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; KHCI->CTL |= USB_CTL_RESUME_MASK; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); KHCI->CTL &= ~USB_CTL_RESUME_MASK; } void dcd_connect(uint8_t rhport) { (void) rhport; KHCI->USBCTRL = 0; KHCI->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; } void dcd_disconnect(uint8_t rhport) { (void) rhport; KHCI->CTL = 0; KHCI->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ static bool edpt_open(uint8_t rhport, uint8_t ep_addr, uint16_t max_packet_size, tusb_xfer_type_t xfer) { (void)rhport; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; const unsigned odd = ep->odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; /* No support for control transfer */ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); ep->max_packet_size = max_packet_size; unsigned val = USB_ENDPT_EPCTLDIS_MASK; val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0; val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; KHCI->ENDPOINT[epn].ENDPT |= val; if (xfer != TUSB_XFER_ISOCHRONOUS) { bd[odd].dts = 1; bd[odd].data = 0; bd[odd ^ 1].dts = 1; bd[odd ^ 1].data = 1; } return true; } bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { return edpt_open(rhport, ep_desc->bEndpointAddress, tu_edpt_packet_size(ep_desc), ep_desc->bmAttributes.xfer); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { return edpt_open(rhport, ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS); } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { const unsigned epn = tu_edpt_number(ep_desc->bEndpointAddress); const unsigned dir = tu_edpt_dir(ep_desc->bEndpointAddress); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; dcd_int_disable(rhport); ep->max_packet_size = tu_edpt_packet_size(ep_desc); dcd_int_enable(rhport); return true; } void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); for (unsigned i = 1; i < 16; ++i) { KHCI->ENDPOINT[i].ENDPT = 0; } if (ie) NVIC_EnableIRQ(USB0_IRQn); buffer_descriptor_t *bd = _dcd.bdt[1][0]; for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { bd->head = 0; } endpoint_state_t *ep = &_dcd.endpoint[1][0]; for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) { /* Clear except the odd */ ep->max_packet_size = 0; ep->length = 0; ep->remaining = 0; } } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) rhport; (void) is_isr; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; TU_ASSERT(0 == bd->own); const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); ep->length = total_bytes; ep->remaining = total_bytes; const unsigned mps = ep->max_packet_size; if (total_bytes > mps) { buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; next->addr = buffer + mps; next->own = 1; } bd->bc = total_bytes >= mps ? mps: total_bytes; bd->addr = buffer; __DSB(); bd->own = 1; /* This bit must be set last */ if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { KHCI->ENDPOINT[epn].ENDPT |= USB_ENDPT_EPSTALL_MASK; } else { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd]; TU_ASSERT(0 == bd->own,); const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); bd->bdt_stall = 1; __DSB(); bd->own = 1; /* This bit must be set last */ if (ie) NVIC_EnableIRQ(USB0_IRQn); } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; const unsigned epn = tu_edpt_number(ep_addr); TU_VERIFY(epn,); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned odd = _dcd.endpoint[epn][dir].odd; buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; TU_VERIFY(bd[odd].own,); const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); bd[odd].own = 0; __DSB(); // clear stall bd[odd].bdt_stall = 0; // Reset data toggle bd[odd ].data = 0; bd[odd ^ 1].data = 1; // We already cleared this in ISR, but just clear it here to be safe const unsigned endpt = KHCI->ENDPOINT[epn].ENDPT; if (endpt & USB_ENDPT_EPSTALL_MASK) { KHCI->ENDPOINT[epn].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK; } if (ie) NVIC_EnableIRQ(USB0_IRQn); } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; // clear non-enabled interrupts KHCI->ISTAT = is & ~msk; is &= msk; if (is & USB_ISTAT_ERROR_MASK) { /* TODO: */ uint32_t es = KHCI->ERRSTAT; KHCI->ERRSTAT = es; KHCI->ISTAT = is; /* discard any pending events */ } if (is & USB_ISTAT_USBRST_MASK) { KHCI->ISTAT = is; /* discard any pending events */ process_bus_reset(rhport); } if (is & USB_ISTAT_SLEEP_MASK) { // TU_LOG3("Suspend: "); TU_LOG2_HEX(is); // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good KHCI->ISTAT = USB_ISTAT_SLEEP_MASK; process_bus_sleep(rhport); } #if 0 // ISTAT_RESUME never trigger, probably for host mode ? if (is & USB_ISTAT_RESUME_MASK) { // TU_LOG2("ISTAT Resume: "); TU_LOG2_HEX(is); KHCI->ISTAT = USB_ISTAT_RESUME_MASK; process_bus_resume(rhport); } #endif if (KHCI->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) { // TU_LOG2("USBTRC0 Resume: "); TU_LOG2_HEX(is); TU_LOG2_HEX(KHCI->USBTRC0); process_bus_resume(rhport); } if (is & USB_ISTAT_SOFTOK_MASK) { KHCI->ISTAT = USB_ISTAT_SOFTOK_MASK; dcd_event_sof(rhport, tu_u16(KHCI->FRMNUMH, KHCI->FRMNUML), true); } if (is & USB_ISTAT_STALL_MASK) { KHCI->ISTAT = USB_ISTAT_STALL_MASK; process_stall(rhport); } if (is & USB_ISTAT_TOKDNE_MASK) { process_tokdne(rhport); } } #endif ================================================ FILE: src/portable/nxp/khci/hcd_khci.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji Kitayama * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS) #ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS #include "fsl_device_registers.h" #define KHCI USB0 #else #error "MCU is not supported" #endif #include "host/hcd.h" #include "host/usbh.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { TOK_PID_OUT = 0x1u, TOK_PID_IN = 0x9u, TOK_PID_SETUP = 0xDu, TOK_PID_DATA0 = 0x3u, TOK_PID_DATA1 = 0xbu, TOK_PID_ACK = 0x2u, TOK_PID_STALL = 0xeu, TOK_PID_NAK = 0xau, TOK_PID_BUSTO = 0x0u, TOK_PID_ERR = 0xfu, }; typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { uint16_t : 2; __IO uint16_t tok_pid : 4; uint16_t data : 1; __IO uint16_t own : 1; uint16_t : 8; }; struct { uint16_t : 2; uint16_t bdt_stall : 1; uint16_t dts : 1; uint16_t ninc : 1; uint16_t keep : 1; uint16_t : 10; }; }; __IO uint16_t bc : 10; uint16_t : 6; }; }; uint8_t *addr; }buffer_descriptor_t; TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { uint32_t pipenum:16; uint32_t odd : 1; uint32_t : 0; }; }; uint8_t *buffer; uint16_t length; uint16_t remaining; } endpoint_state_t; typedef struct TU_ATTR_PACKED { uint8_t dev_addr; uint8_t ep_addr; uint16_t max_packet_size; union { uint8_t flags; struct { uint8_t data : 1; uint8_t xfer : 2; uint8_t : 0; }; }; uint8_t *buffer; uint16_t length; uint16_t remaining; } pipe_state_t; typedef struct { union { /* [OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[2][2]; uint16_t bda[2*2]; }; endpoint_state_t endpoint[2]; pipe_state_t pipe[CFG_TUH_ENDPOINT_MAX * 2]; uint32_t in_progress; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe is in progress */ uint32_t pending; /* Bitmap. Each bit indicates that a transfer of the corresponding pipe will be resume the next frame */ bool need_reset; /* The device has not been reset after connection. */ } hcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd; //CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _rx_buf[1024]; static int find_pipe(uint8_t dev_addr, uint8_t ep_addr) { /* Find the target pipe */ int num; for (num = 0; num < CFG_TUH_ENDPOINT_MAX * 2; ++num) { pipe_state_t *p = &_hcd.pipe[num]; if ((p->dev_addr == dev_addr) && (p->ep_addr == ep_addr)) return num; } return -1; } static int prepare_packets(int pipenum) { pipe_state_t *pipe = &_hcd.pipe[pipenum]; unsigned const dir_tx = tu_edpt_dir(pipe->ep_addr) ? 0 : 1; endpoint_state_t *ep = &_hcd.endpoint[dir_tx]; unsigned const odd = ep->odd; buffer_descriptor_t *bd = _hcd.bdt[dir_tx]; TU_ASSERT(0 == bd[odd].own, -1); // TU_LOG1(" %p dir %d odd %d data %d\r\n", &bd[odd], dir_tx, odd, pipe->data); ep->pipenum = pipenum; bd[odd ].data = pipe->data; bd[odd ^ 1].data = pipe->data ^ 1; bd[odd ^ 1].own = 0; /* reset values for a next transfer */ int num_tokens = 0; /* The number of prepared packets */ unsigned const mps = pipe->max_packet_size; unsigned const rem = pipe->remaining; if (rem > mps) { /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ bd[odd ^ 1].bc = rem >= 2 * mps ? mps: rem - mps; bd[odd ^ 1].addr = pipe->buffer + mps; bd[odd ^ 1].own = 1; if (dir_tx) ++num_tokens; } bd[odd].bc = rem >= mps ? mps: rem; bd[odd].addr = pipe->buffer; __DSB(); bd[odd].own = 1; /* This bit must be set last */ ++num_tokens; return num_tokens; } static int select_next_pipenum(int pipenum) { unsigned wip = _hcd.in_progress & ~_hcd.pending; if (!wip) return -1; unsigned msk = TU_GENMASK(31, pipenum); int next = __builtin_ctz(wip & msk); if (next) return next; msk = TU_GENMASK(pipenum, 0); next = __builtin_ctz(wip & msk); return next; } /* When transfer is completed, return true. */ static bool continue_transfer(int pipenum, buffer_descriptor_t *bd) { pipe_state_t *pipe = &_hcd.pipe[pipenum]; unsigned const bc = bd->bc; unsigned const rem = pipe->remaining - bc; pipe->remaining = rem; if (rem && bc == pipe->max_packet_size) { int const next_rem = rem - pipe->max_packet_size; if (next_rem > 0) { /* Prepare to the after next transfer */ bd->addr += pipe->max_packet_size * 2; bd->bc = next_rem > pipe->max_packet_size ? pipe->max_packet_size: next_rem; __DSB(); bd->own = 1; /* This bit must be set last */ while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = KHCI->TOKEN; /* Queue the same token as the last */ } else if (TUSB_DIR_IN == tu_edpt_dir(pipe->ep_addr)) { /* IN */ while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = KHCI->TOKEN; } return true; } pipe->data = bd->data ^ 1; return false; } static bool resume_transfer(int pipenum) { int num_tokens = prepare_packets(pipenum); TU_ASSERT(0 <= num_tokens); const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *pipe = &_hcd.pipe[pipenum]; unsigned flags = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; flags |= USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; switch (pipe->xfer) { case TUSB_XFER_CONTROL: flags |= USB_ENDPT_EPHSHK_MASK; break; case TUSB_XFER_ISOCHRONOUS: flags |= USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; break; default: flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; break; } // TU_LOG1(" resume pipenum %d flags %x\r\n", pipenum, flags); KHCI->ENDPOINT[0].ENDPT = flags; KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr; unsigned const token = tu_edpt_number(pipe->ep_addr) | ((tu_edpt_dir(pipe->ep_addr) ? TOK_PID_IN: TOK_PID_OUT) << USB_TOKEN_TOKENPID_SHIFT); do { while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = token; } while (--num_tokens); if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } static void suspend_transfer(int pipenum, buffer_descriptor_t *bd) { pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe->buffer = bd->addr; pipe->data = bd->data ^ 1; if ((TUSB_XFER_INTERRUPT == pipe->xfer) || (TUSB_XFER_BULK == pipe->xfer)) { _hcd.pending |= TU_BIT(pipenum); KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; } } static void process_tokdne(uint8_t rhport) { (void)rhport; const unsigned s = KHCI->STAT; KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ uint8_t const dir_in = (s & USB_STAT_TX_MASK) ? TUSB_DIR_OUT: TUSB_DIR_IN; unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; buffer_descriptor_t *bd = (buffer_descriptor_t *)&_hcd.bda[s]; endpoint_state_t *ep = &_hcd.endpoint[s >> 3]; /* fetch status before discarded by the next steps */ const unsigned pid = bd->tok_pid; /* reset values for a next transfer */ bd->bdt_stall = 0; bd->dts = 1; bd->ninc = 0; bd->keep = 0; /* Update the odd variable to prepare for the next transfer */ ep->odd = odd ^ 1; int pipenum = ep->pipenum; int next_pipenum; // TU_LOG1("TOKDNE %x PID %x pipe %d\r\n", s, pid, pipenum); xfer_result_t result; switch (pid) { default: if (continue_transfer(pipenum, bd)) return; result = XFER_RESULT_SUCCESS; break; case TOK_PID_NAK: suspend_transfer(pipenum, bd); next_pipenum = select_next_pipenum(pipenum); if (0 <= next_pipenum) resume_transfer(next_pipenum); return; case TOK_PID_STALL: result = XFER_RESULT_STALLED; break; case TOK_PID_ERR: /* mismatch toggle bit */ case TOK_PID_BUSTO: result = XFER_RESULT_FAILED; break; } _hcd.in_progress &= ~TU_BIT(pipenum); pipe_state_t *pipe = &_hcd.pipe[ep->pipenum]; hcd_event_xfer_complete(pipe->dev_addr, tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in), pipe->length - pipe->remaining, result, true); next_pipenum = select_next_pipenum(pipenum); if (0 <= next_pipenum) resume_transfer(next_pipenum); } static void process_attach(uint8_t rhport) { unsigned ctl = KHCI->CTL; if (!(ctl & USB_CTL_JSTATE_MASK)) { /* The attached device is a low speed device. */ KHCI->ADDR = USB_ADDR_LSEN_MASK; KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_HOSTWOHUB_MASK; } hcd_event_device_attach(rhport, true); } static void process_bus_reset(uint8_t rhport) { KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; KHCI->ADDR = 0; KHCI->ENDPOINT[0].ENDPT = 0; hcd_event_device_remove(rhport, true); _hcd.in_progress = 0; _hcd.pending = 0; buffer_descriptor_t *bd = &_hcd.bdt[0][0]; for (unsigned i = 0; i < 2; ++i, ++bd) { bd->head = 0; } } /*------------------------------------------------------------------*/ /* Host API *------------------------------------------------------------------*/ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); tu_memclr(&_hcd, sizeof(_hcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_hcd.bdt >> 8); KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_hcd.bdt >> 16); KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_hcd.bdt >> 24); KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; KHCI->CTL |= USB_CTL_ODDRST_MASK; for (unsigned i = 0; i < 16; ++i) { KHCI->ENDPOINT[i].ENDPT = 0; } KHCI->CTL &= ~USB_CTL_ODDRST_MASK; KHCI->SOFTHLD = 74; /* for 64-byte packets */ // KHCI->SOFTHLD = 144; /* for low speed 8-byte packets */ KHCI->CTL = USB_CTL_HOSTMODEEN_MASK | USB_CTL_SE0_MASK; KHCI->USBCTRL = USB_USBCTRL_PDE_MASK; NVIC_ClearPendingIRQ(USB0_IRQn); KHCI->INTEN = USB_INTEN_ATTACHEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_USBRSTEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; KHCI->ERREN = 0xff; return true; } void hcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB0_IRQn); } void hcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB0_IRQn); } uint32_t hcd_frame_number(uint8_t rhport) { (void)rhport; /* The device must be reset at least once after connection * in order to start the frame counter. */ if (_hcd.need_reset) hcd_port_reset(rhport); uint32_t frmnum = KHCI->FRMNUML; frmnum |= KHCI->FRMNUMH << 8u; return frmnum; } /*--------------------------------------------------------------------+ * Port API *--------------------------------------------------------------------+ */ bool hcd_port_connect_status(uint8_t rhport) { (void)rhport; if (KHCI->ISTAT & USB_ISTAT_ATTACH_MASK) return true; return false; } void hcd_port_reset(uint8_t rhport) { (void)rhport; KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK; KHCI->CTL |= USB_CTL_RESET_MASK; unsigned cnt = SystemCoreClock / 100; while (cnt--) __NOP(); KHCI->CTL &= ~USB_CTL_RESET_MASK; KHCI->CTL |= USB_CTL_USBENSOFEN_MASK; _hcd.need_reset = false; } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; tusb_speed_t speed = TUSB_SPEED_FULL; const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); if (KHCI->ADDR & USB_ADDR_LSEN_MASK) speed = TUSB_SPEED_LOW; if (ie) NVIC_EnableIRQ(USB0_IRQn); return speed; } void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void)rhport; const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *p = &_hcd.pipe[0]; pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; for (;p != end; ++p) { if (p->dev_addr == dev_addr) tu_memclr(p, sizeof(*p)); } if (ie) NVIC_EnableIRQ(USB0_IRQn); } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void)rhport; // TU_LOG1("SETUP %u\r\n", dev_addr); TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(0))); int pipenum = find_pipe(dev_addr, 0); if (pipenum < 0) return false; pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe[0].data = 0; pipe[0].buffer = (uint8_t*)(uintptr_t)setup_packet; pipe[0].length = 8; pipe[0].remaining = 8; pipe[1].data = 1; if (1 != prepare_packets(pipenum)) return false; _hcd.in_progress |= TU_BIT(pipenum); unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK; KHCI->ENDPOINT[0].ENDPT = hostwohub | USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | dev_addr; while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ; KHCI->TOKEN = (TOK_PID_SETUP << USB_TOKEN_TOKENPID_SHIFT); return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; uint8_t const ep_addr = ep_desc->bEndpointAddress; // TU_LOG1("O %u %x\r\n", dev_addr, ep_addr); /* Find a free pipe */ pipe_state_t *p = &_hcd.pipe[0]; pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; if (dev_addr || ep_addr) { p += 2; for (; p < end && (p->dev_addr || p->ep_addr); ++p) ; if (p == end) return false; } p->dev_addr = dev_addr; p->ep_addr = ep_addr; p->max_packet_size = ep_desc->wMaxPacketSize; p->xfer = ep_desc->bmAttributes.xfer; p->data = 0; if (!ep_addr) { /* Open one more pipe for Control IN transfer */ TU_ASSERT(TUSB_XFER_CONTROL == p->xfer); pipe_state_t *q = p + 1; TU_ASSERT(!q->dev_addr && !q->ep_addr); q->dev_addr = dev_addr; q->ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); q->max_packet_size = ep_desc->wMaxPacketSize; q->xfer = ep_desc->bmAttributes.xfer; q->data = 1; } return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } /* The address of buffer must be aligned to 4 byte boundary. And it must be at least 4 bytes long. * DMA writes data in 4 byte unit */ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void)rhport; // TU_LOG1("X %u %x %x %d\r\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen); int pipenum = find_pipe(dev_addr, ep_addr); TU_ASSERT(0 <= pipenum); TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(pipenum))); unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); pipe_state_t *pipe = &_hcd.pipe[pipenum]; pipe->buffer = buffer; pipe->length = buflen; pipe->remaining = buflen; _hcd.in_progress |= TU_BIT(pipenum); _hcd.pending |= TU_BIT(pipenum); /* Send at the next Frame */ KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK; if (ie) NVIC_EnableIRQ(USB0_IRQn); return true; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; // TODO not implemented yet return false; } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; if (!tu_edpt_number(ep_addr)) return true; int num = find_pipe(dev_addr, ep_addr); if (num < 0) return false; pipe_state_t *p = &_hcd.pipe[num]; p->data = 0; /* Reset data toggle */ return true; } /*--------------------------------------------------------------------+ * ISR *--------------------------------------------------------------------+*/ void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; // TU_LOG1("S %lx\r\n", is); /* clear disabled interrupts */ KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK; is &= msk; if (is & USB_ISTAT_ERROR_MASK) { unsigned err = KHCI->ERRSTAT; if (err) { TU_LOG1(" ERR %x\r\n", err); KHCI->ERRSTAT = err; } else { KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK; } } if (is & USB_ISTAT_USBRST_MASK) { KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK; process_bus_reset(rhport); return; } if (is & USB_ISTAT_ATTACH_MASK) { KHCI->INTEN = (msk & ~USB_INTEN_ATTACHEN_MASK) | USB_INTEN_USBRSTEN_MASK; _hcd.need_reset = true; process_attach(rhport); return; } if (is & USB_ISTAT_STALL_MASK) { KHCI->ISTAT = USB_ISTAT_STALL_MASK; } if (is & USB_ISTAT_SOFTOK_MASK) { msk &= ~USB_ISTAT_SOFTOK_MASK; KHCI->INTEN = msk; if (_hcd.pending) { int pipenum = __builtin_ctz(_hcd.pending); _hcd.pending = 0; if (!(is & USB_ISTAT_TOKDNE_MASK)) resume_transfer(pipenum); } } if (is & USB_ISTAT_TOKDNE_MASK) { process_tokdne(rhport); } } #endif ================================================ FILE: src/portable/nxp/lpc17_40/dcd_lpc17_40.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && \ (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) #include "device/dcd.h" #include "dcd_lpc17_40.h" #include "chip.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ #define DCD_ENDPOINT_MAX 32 typedef struct TU_ATTR_ALIGNED(4) { //------------- Word 0 -------------// uint32_t next; //------------- Word 1 -------------// uint16_t atle_mode : 2; // 00: normal, 01: ATLE (auto length extraction) uint16_t next_valid : 1; uint16_t : 1; ///< reserved uint16_t isochronous : 1; // is an iso endpoint uint16_t max_packet_size : 11; volatile uint16_t buflen; // bytes for non-iso, number of packets for iso endpoint //------------- Word 2 -------------// volatile uint32_t buffer; //------------- Word 3 -------------// volatile uint16_t retired : 1; // initialized to zero volatile uint16_t status : 4; volatile uint16_t iso_last_packet_valid : 1; volatile uint16_t atle_lsb_extracted : 1; // used in ATLE mode volatile uint16_t atle_msb_extracted : 1; // used in ATLE mode volatile uint16_t atle_mess_len_position : 6; // used in ATLE mode uint16_t : 2; volatile uint16_t present_count; // For non-iso : The number of bytes transferred by the DMA engine // For iso : number of packets //------------- Word 4 -------------// // uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso }dma_desc_t; TU_VERIFY_STATIC( sizeof(dma_desc_t) == 16, "size is not correct"); // TODO not support ISO for now typedef struct { // must be 128 byte aligned volatile dma_desc_t* udca[DCD_ENDPOINT_MAX]; // TODO DMA does not support control transfer (0-1 are not used, offset to reduce memory) dma_desc_t dd[DCD_ENDPOINT_MAX]; struct { uint8_t* out_buffer; uint8_t out_bytes; volatile bool out_received; // indicate if data is already received in endpoint uint8_t in_bytes; } control; } dcd_data_t; CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd; //--------------------------------------------------------------------+ // SIE Command //--------------------------------------------------------------------+ static void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) { LPC_USB->DevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK); LPC_USB->CmdCode = (phase << 8) | (code_data << 16); uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK; while ((LPC_USB->DevIntSt & wait_flag) == 0) {} LPC_USB->DevIntClr = wait_flag; } static void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data) { sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code); if (data_len) { sie_cmd_code(SIE_CMDPHASE_WRITE, data); } } static uint8_t sie_read (uint8_t cmd_code) { sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code); sie_cmd_code(SIE_CMDPHASE_READ , cmd_code); return (uint8_t) LPC_USB->CmdData; } //--------------------------------------------------------------------+ // PIPE HELPER //--------------------------------------------------------------------+ static inline uint8_t ep_addr2idx(uint8_t ep_addr) { return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); } static void set_ep_size(uint8_t ep_id, uint16_t max_packet_size) { // follows example in 11.10.4.2 LPC_USB->ReEp |= TU_BIT(ep_id); LPC_USB->EpInd = ep_id; // select index before setting packet size LPC_USB->MaxPSize = max_packet_size; while ((LPC_USB->DevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {} LPC_USB->DevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK; } //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ static void bus_reset(void) { // step 7 : slave mode set up LPC_USB->EpIntClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->DevIntClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->EpIntEn = 0x03UL; // control endpoint cannot use DMA, non-control all use DMA LPC_USB->EpIntPri = 0x03UL; // fast for control endpoint // step 8 : DMA set up LPC_USB->EpDMADis = 0xFFFFFFFF; // firstly disable all dma LPC_USB->DMARClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->EoTIntClr = 0xFFFFFFFF; LPC_USB->NDDRIntClr = 0xFFFFFFFF; LPC_USB->SysErrIntClr = 0xFFFFFFFF; tu_memclr(&_dcd, sizeof(dcd_data_t)); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; //------------- user manual 11.13 usb device controller initialization -------------// // step 6 : set up control endpoint set_ep_size(0, CFG_TUD_ENDPOINT0_SIZE); set_ep_size(1, CFG_TUD_ENDPOINT0_SIZE); bus_reset(); LPC_USB->DevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_FAST_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK); LPC_USB->UDCAH = (uint32_t) _dcd.udca; LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK); dcd_connect(rhport); // Clear pending IRQ NVIC_ClearPendingIRQ(USB_IRQn); return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); sie_write(SIE_CMDCODE_SET_ADDRESS, 1, 0x80 | dev_addr); // 7th bit is : device_enable // Also Set Configure Device to enable non-control endpoint response sie_write(SIE_CMDCODE_CONFIGURE_DEVICE, 1, 1); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; } void dcd_connect(uint8_t rhport) { (void) rhport; sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, SIE_DEV_STATUS_CONNECT_STATUS_MASK); } void dcd_disconnect(uint8_t rhport) { (void) rhport; sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // CONTROL HELPER //--------------------------------------------------------------------+ static inline uint8_t byte2dword(uint8_t bytes) { return (bytes + 3) / 4; // length in dwords } static void control_ep_write(void const * buffer, uint8_t len) { uint32_t const * buf32 = (uint32_t const *) buffer; LPC_USB->Ctrl = USBCTRL_WRITE_ENABLE_MASK; // logical endpoint = 0 LPC_USB->TxPLen = (uint32_t) len; for (uint8_t count = 0; count < byte2dword(len); count++) { LPC_USB->TxData = *buf32; // NOTE: cortex M3 have no problem with alignment buf32++; } LPC_USB->Ctrl = 0; // select control IN & validate the endpoint sie_write(SIE_CMDCODE_ENDPOINT_SELECT+1, 0, 0); sie_write(SIE_CMDCODE_BUFFER_VALIDATE , 0, 0); } static uint8_t control_ep_read(void * buffer, uint8_t len) { LPC_USB->Ctrl = USBCTRL_READ_ENABLE_MASK; // logical endpoint = 0 while ((LPC_USB->RxPLen & USBRXPLEN_PACKET_READY_MASK) == 0) {} // TODO blocking, should have timeout len = tu_min8(len, (uint8_t) (LPC_USB->RxPLen & USBRXPLEN_PACKET_LENGTH_MASK) ); uint32_t *buf32 = (uint32_t*) buffer; for (uint8_t count=0; count < byte2dword(len); count++) { *buf32 = LPC_USB->RxData; buf32++; } LPC_USB->Ctrl = 0; // select control OUT & clear the endpoint sie_write(SIE_CMDCODE_ENDPOINT_SELECT+0, 0, 0); sie_write(SIE_CMDCODE_BUFFER_CLEAR , 0, 0); return len; } //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { (void) rhport; uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress); // Endpoint type is fixed to endpoint number // 1: interrupt, 2: Bulk, 3: Iso and so on switch ( p_endpoint_desc->bmAttributes.xfer ) { case TUSB_XFER_INTERRUPT: TU_ASSERT((epnum % 3) == 1); break; case TUSB_XFER_BULK: TU_ASSERT((epnum % 3) == 2 || (epnum == 15)); break; case TUSB_XFER_ISOCHRONOUS: TU_ASSERT((epnum % 3) == 0 && (epnum != 0) && (epnum != 15)); break; default: break; } //------------- Realize Endpoint with Max Packet Size -------------// const uint16_t ep_size = tu_edpt_packet_size(p_endpoint_desc); set_ep_size(ep_id, ep_size); //------------- first DD prepare -------------// dma_desc_t* const dd = &_dcd.dd[ep_id]; tu_memclr(dd, sizeof(dma_desc_t)); dd->isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; dd->max_packet_size = ep_size; dd->retired = 1; // invalid at first sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS + ep_id, 1, 0); // clear all endpoint status return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if ( tu_edpt_number(ep_addr) == 0 ) { sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK); }else { uint8_t ep_id = ep_addr2idx( ep_addr ); sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, SIE_SET_ENDPOINT_STALLED_MASK); } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t ep_id = ep_addr2idx(ep_addr); sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0); } static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t * buffer, uint8_t len) { (void) rhport; if ( dir ) { _dcd.control.in_bytes = len; control_ep_write(buffer, len); }else { if ( _dcd.control.out_received ) { // Already received the DATA OUT packet _dcd.control.out_received = false; _dcd.control.out_buffer = NULL; _dcd.control.out_bytes = 0; uint8_t received = control_ep_read(buffer, len); dcd_event_xfer_complete(0, 0, received, XFER_RESULT_SUCCESS, true); }else { _dcd.control.out_buffer = buffer; _dcd.control.out_bytes = len; } } return true; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; // Control transfer is not DMA support, and must be done in slave mode if ( tu_edpt_number(ep_addr) == 0 ) { return control_xact(rhport, tu_edpt_dir(ep_addr), buffer, (uint8_t) total_bytes); } else { uint8_t ep_id = ep_addr2idx(ep_addr); dma_desc_t* dd = &_dcd.dd[ep_id]; // Prepare DMA descriptor // Isochronous & max packet size must be preserved, Other fields of dd should be clear uint16_t const ep_size = dd->max_packet_size; uint8_t is_iso = dd->isochronous; tu_memclr(dd, sizeof(dma_desc_t)); dd->isochronous = is_iso; dd->max_packet_size = ep_size; dd->buffer = (uint32_t) buffer; dd->buflen = total_bytes; _dcd.udca[ep_id] = dd; if ( ep_id % 2 ) { // Clear EP interrupt before Enable DMA LPC_USB->EpIntEn &= ~TU_BIT(ep_id); LPC_USB->EpDMAEn = TU_BIT(ep_id); // endpoint IN need to actively raise DMA request LPC_USB->DMARSet = TU_BIT(ep_id); }else { // Enable DMA LPC_USB->EpDMAEn = TU_BIT(ep_id); } return true; } } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ // handle control xfer (slave mode) static void control_xfer_isr(uint8_t rhport, uint32_t ep_int_status) { // Control out complete if ( ep_int_status & TU_BIT(0) ) { bool is_setup = sie_read(SIE_CMDCODE_ENDPOINT_SELECT+0) & SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK; LPC_USB->EpIntClr = TU_BIT(0); if (is_setup) { uint8_t setup_packet[8]; control_ep_read(setup_packet, 8); // TODO read before clear setup above dcd_event_setup_received(rhport, setup_packet, true); } else if ( _dcd.control.out_buffer ) { // software queued transfer previously uint8_t received = control_ep_read(_dcd.control.out_buffer, _dcd.control.out_bytes); _dcd.control.out_buffer = NULL; _dcd.control.out_bytes = 0; dcd_event_xfer_complete(rhport, 0, received, XFER_RESULT_SUCCESS, true); }else { // hardware auto ack packet -> mark as received _dcd.control.out_received = true; } } // Control In complete if ( ep_int_status & TU_BIT(1) ) { LPC_USB->EpIntClr = TU_BIT(1); dcd_event_xfer_complete(rhport, TUSB_DIR_IN_MASK, _dcd.control.in_bytes, XFER_RESULT_SUCCESS, true); } } // handle bus event signal static void bus_event_isr(uint8_t rhport) { uint8_t const dev_status = sie_read(SIE_CMDCODE_DEVICE_STATUS); if (dev_status & SIE_DEV_STATUS_RESET_MASK) { bus_reset(); dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } if (dev_status & SIE_DEV_STATUS_CONNECT_CHANGE_MASK) { // device is disconnected, require using VBUS (P1_30) dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } if (dev_status & SIE_DEV_STATUS_SUSPEND_CHANGE_MASK) { if (dev_status & SIE_DEV_STATUS_SUSPEND_MASK) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } else { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } } } // Helper to complete a DMA descriptor for non-control transfer static void dd_complete_isr(uint8_t rhport, uint8_t ep_id) { dma_desc_t* const dd = &_dcd.dd[ep_id]; uint8_t result = (dd->status == DD_STATUS_NORMAL || dd->status == DD_STATUS_DATA_UNDERUN) ? XFER_RESULT_SUCCESS : XFER_RESULT_FAILED; uint8_t const ep_addr = (ep_id / 2) | ((ep_id & 0x01) ? TUSB_DIR_IN_MASK : 0); dcd_event_xfer_complete(rhport, ep_addr, dd->present_count, result, true); } // main USB IRQ handler void dcd_int_handler(uint8_t rhport) { uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn; LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt // Bus event if (dev_int_status & DEV_INT_DEVICE_STATUS_MASK) { bus_event_isr(rhport); } // Endpoint interrupt uint32_t const ep_int_status = LPC_USB->EpIntSt & LPC_USB->EpIntEn; // Control Endpoint are fast if (dev_int_status & DEV_INT_ENDPOINT_FAST_MASK) { // Note clear USBEpIntClr will also clear the setup received bit --> clear after handle setup packet // Only clear USBEpIntClr 1 endpoint each, and should wait for CDFULL bit set control_xfer_isr(rhport, ep_int_status); } // non-control IN are slow if (dev_int_status & DEV_INT_ENDPOINT_SLOW_MASK) { for ( uint8_t ep_id = 3; ep_id < DCD_ENDPOINT_MAX; ep_id += 2 ) { if ( tu_bit_test(ep_int_status, ep_id) ) { LPC_USB->EpIntClr = TU_BIT(ep_id); // Clear Ep interrupt for next DMA LPC_USB->EpIntEn &= ~TU_BIT(ep_id); dd_complete_isr(rhport, ep_id); } } } // DMA transfer complete (RAM <-> EP) for Non-Control // OUT: USB transfer is fully complete // IN : UBS transfer is still on-going -> enable EpIntEn to know when it is complete uint32_t const dma_int_status = LPC_USB->DMAIntSt & LPC_USB->DMAIntEn; if (dma_int_status & DMA_INT_END_OF_XFER_MASK) { uint32_t const eot = LPC_USB->EoTIntSt; LPC_USB->EoTIntClr = eot; // acknowledge interrupt source for ( uint8_t ep_id = 2; ep_id < DCD_ENDPOINT_MAX; ep_id++ ) { if ( tu_bit_test(eot, ep_id) ) { if ( ep_id & 0x01 ) { // IN enable EpInt for end of usb transfer LPC_USB->EpIntEn |= TU_BIT(ep_id); }else { // OUT dd_complete_isr(rhport, ep_id); } } } } // Errors if ( (dev_int_status & DEV_INT_ERROR_MASK) || (dma_int_status & DMA_INT_ERROR_MASK) ) { uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS); (void) error_status; TU_BREAKPOINT(); } } #endif ================================================ FILE: src/portable/nxp/lpc17_40/dcd_lpc17_40.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DCD_LPC17_40_H_ #define TUSB_DCD_LPC17_40_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Register Interface //--------------------------------------------------------------------+ //------------- USB Interrupt USBIntSt -------------// //enum { // DCD_USB_REQ_LOW_PRIO_MASK = TU_BIT(0), // DCD_USB_REQ_HIGH_PRIO_MASK = TU_BIT(1), // DCD_USB_REQ_DMA_MASK = TU_BIT(2), // DCD_USB_REQ_NEED_CLOCK_MASK = TU_BIT(8), // DCD_USB_REQ_ENABLE_MASK = TU_BIT(31) //}; //------------- Device Interrupt USBDevInt -------------// enum { DEV_INT_FRAME_MASK = TU_BIT(0), DEV_INT_ENDPOINT_FAST_MASK = TU_BIT(1), DEV_INT_ENDPOINT_SLOW_MASK = TU_BIT(2), DEV_INT_DEVICE_STATUS_MASK = TU_BIT(3), DEV_INT_COMMAND_CODE_EMPTY_MASK = TU_BIT(4), DEV_INT_COMMAND_DATA_FULL_MASK = TU_BIT(5), DEV_INT_RX_ENDPOINT_PACKET_MASK = TU_BIT(6), DEV_INT_TX_ENDPOINT_PACKET_MASK = TU_BIT(7), DEV_INT_ENDPOINT_REALIZED_MASK = TU_BIT(8), DEV_INT_ERROR_MASK = TU_BIT(9) }; //------------- DMA Interrupt USBDMAInt-------------// enum { DMA_INT_END_OF_XFER_MASK = TU_BIT(0), DMA_INT_NEW_DD_REQUEST_MASK = TU_BIT(1), DMA_INT_ERROR_MASK = TU_BIT(2) }; //------------- USBCtrl -------------// enum { USBCTRL_READ_ENABLE_MASK = TU_BIT(0), USBCTRL_WRITE_ENABLE_MASK = TU_BIT(1), }; //------------- USBRxPLen -------------// enum { USBRXPLEN_PACKET_LENGTH_MASK = (TU_BIT(10)-1), USBRXPLEN_DATA_VALID_MASK = TU_BIT(10), USBRXPLEN_PACKET_READY_MASK = TU_BIT(11), }; //------------- SIE Command Code -------------// typedef enum { SIE_CMDPHASE_WRITE = 1, SIE_CMDPHASE_READ = 2, SIE_CMDPHASE_COMMAND = 5 } sie_cmdphase_t; enum { // device commands SIE_CMDCODE_SET_ADDRESS = 0xd0, SIE_CMDCODE_CONFIGURE_DEVICE = 0xd8, SIE_CMDCODE_SET_MODE = 0xf3, SIE_CMDCODE_READ_FRAME_NUMBER = 0xf5, SIE_CMDCODE_READ_TEST_REGISTER = 0xfd, SIE_CMDCODE_DEVICE_STATUS = 0xfe, SIE_CMDCODE_GET_ERROR = 0xff, SIE_CMDCODE_READ_ERROR_STATUS = 0xfb, // endpoint commands SIE_CMDCODE_ENDPOINT_SELECT = 0x00, // + endpoint index SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT = 0x40, // + endpoint index, should use USBEpIntClr instead SIE_CMDCODE_ENDPOINT_SET_STATUS = 0x40, // + endpoint index SIE_CMDCODE_BUFFER_CLEAR = 0xf2, SIE_CMDCODE_BUFFER_VALIDATE = 0xfa }; //------------- SIE Device Status (get/set from SIE_CMDCODE_DEVICE_STATUS) -------------// enum { SIE_DEV_STATUS_CONNECT_STATUS_MASK = TU_BIT(0), SIE_DEV_STATUS_CONNECT_CHANGE_MASK = TU_BIT(1), SIE_DEV_STATUS_SUSPEND_MASK = TU_BIT(2), SIE_DEV_STATUS_SUSPEND_CHANGE_MASK = TU_BIT(3), SIE_DEV_STATUS_RESET_MASK = TU_BIT(4) }; //------------- SIE Select Endpoint Command -------------// enum { SIE_SELECT_ENDPOINT_FULL_EMPTY_MASK = TU_BIT(0), // 0: empty, 1 full. IN endpoint checks empty, OUT endpoint check full SIE_SELECT_ENDPOINT_STALL_MASK = TU_BIT(1), SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK = TU_BIT(2), // clear by SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT SIE_SELECT_ENDPOINT_PACKET_OVERWRITTEN_MASK = TU_BIT(3), // previous packet is overwritten by a SETUP packet SIE_SELECT_ENDPOINT_NAK_MASK = TU_BIT(4), // last packet response is NAK (auto clear by an ACK) SIE_SELECT_ENDPOINT_BUFFER1_FULL_MASK = TU_BIT(5), SIE_SELECT_ENDPOINT_BUFFER2_FULL_MASK = TU_BIT(6) }; typedef enum { SIE_SET_ENDPOINT_STALLED_MASK = TU_BIT(0), SIE_SET_ENDPOINT_DISABLED_MASK = TU_BIT(5), SIE_SET_ENDPOINT_RATE_FEEDBACK_MASK = TU_BIT(6), SIE_SET_ENDPOINT_CONDITION_STALLED_MASK = TU_BIT(7), }sie_endpoint_set_status_mask_t; //------------- DMA Descriptor Status -------------// enum { DD_STATUS_NOT_SERVICED = 0, DD_STATUS_BEING_SERVICED, DD_STATUS_NORMAL, DD_STATUS_DATA_UNDERUN, // short packet DD_STATUS_DATA_OVERRUN, DD_STATUS_SYSTEM_ERROR }; #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" /* Since 2012 starting with LPC11uxx, NXP start to use common USB Device Controller with code name LPC IP3511 * for almost their new MCUs. Currently supported and tested families are * - LPC11U68, LPC11U37 * - LPC1347 * - LPC51U68 * - LPC54114 * - LPC55s69 */ #if CFG_TUD_ENABLED && defined(TUP_USBIP_IP3511) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) // LPCOpen #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "chip.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #else // SDK #include "fsl_device_registers.h" #define INCLUDE_FSL_DEVICE_REGISTERS #endif #include "device/dcd.h" //--------------------------------------------------------------------+ // IP3511 Registers //--------------------------------------------------------------------+ typedef struct { __IO uint32_t DEVCMDSTAT; // Device Command/Status register, offset: 0x0 __I uint32_t INFO; // Info register, offset: 0x4 __IO uint32_t EPLISTSTART; // EP Command/Status List start address, offset: 0x8 __IO uint32_t DATABUFSTART; // Data buffer start address, offset: 0xC __IO uint32_t LPM; // Link Power Management register, offset: 0x10 __IO uint32_t EPSKIP; // Endpoint skip, offset: 0x14 __IO uint32_t EPINUSE; // Endpoint Buffer in use, offset: 0x18 __IO uint32_t EPBUFCFG; // Endpoint Buffer Configuration register, offset: 0x1C __IO uint32_t INTSTAT; // interrupt status register, offset: 0x20 __IO uint32_t INTEN; // interrupt enable register, offset: 0x24 __IO uint32_t INTSETSTAT; // set interrupt status register, offset: 0x28 uint8_t RESERVED_0[8]; __I uint32_t EPTOGGLE; // Endpoint toggle register, offset: 0x34 } dcd_registers_t; // Max nbytes for each control/bulk/interrupt transfer enum { NBYTES_ISO_FS_MAX = 1023, // FS ISO NBYTES_ISO_HS_MAX = 1024, // HS ISO NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt. TODO some FS can do burst with higher size e.g 1024. Need to test NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 }; enum { INT_SOF_MASK = TU_BIT(30), INT_DEVICE_STATUS_MASK = TU_BIT(31) }; enum { DEVCMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, DEVCMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), DEVCMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), DEVCMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state DEVCMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), // 23-22 is link speed (only available for HighSpeed port) DEVCMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), DEVCMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), DEVCMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), DEVCMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), }; enum { DEVCMDSTAT_SPEED_SHIFT = 22 }; //--------------------------------------------------------------------+ // Endpoint Command/Status List //--------------------------------------------------------------------+ // EP Command/Status field definition enum { EPCS_TYPE = TU_BIT(26), EPCS_RF_TV = TU_BIT(27), EPCS_TOGGLE_RESET = TU_BIT(28), EPCS_STALL = TU_BIT(29), EPCS_DISABLED = TU_BIT(30), EPCS_ACTIVE = TU_BIT(31), }; // Endpoint Command/Status typedef union TU_ATTR_PACKED { // Full and High speed has different bit layout for buffer_offset and nbytes // TODO FS/HS layout depends on the max speed of controller e.g // lpc55s69 PORT0 is only FS but actually has the same layout as HS on port1 // Buffer (aligned 64) = DATABUFSTART [31:22] | buffer_offset [21:6] volatile struct { uint32_t offset : 16; uint32_t nbytes : 10; uint32_t TU_RESERVED : 6; } buffer_fs; // Buffer (aligned 64) = USB_RAM [31:17] | buffer_offset [16:6] volatile struct { uint32_t offset : 11 ; uint32_t nbytes : 15 ; uint32_t TU_RESERVED : 6 ; } buffer_hs; volatile struct { uint32_t TU_RESERVED : 26; uint32_t type : 1 ; uint32_t rf_tv : 1 ; // rate feedback or toggle value uint32_t toggle_reset : 1 ; uint32_t stall : 1 ; uint32_t disable : 1 ; uint32_t active : 1 ; } cmd_sts; }ep_cmd_sts_t; TU_VERIFY_STATIC( sizeof(ep_cmd_sts_t) == 4, "size is not correct" ); // Software transfer management typedef struct { uint16_t total_bytes; uint16_t xferred_bytes; uint16_t nbytes; // prevent unaligned access on Highspeed port on USB_SRAM uint16_t TU_RESERVED; }xfer_dma_t; // Absolute max of endpoints pairs for all port // - 11 13 15 51 54 has 5x2 endpoints // - 55 usb0 (FS) has 5x2 endpoints, usb1 (HS) has 6x2 endpoints #define MAX_EP_PAIRS 6 // NOTE data will be transferred as soon as dcd get request by dcd_pipe(_queue)_xfer using double buffering. // current_td is used to keep track of number of remaining & xferred bytes of the current request. typedef struct { // 256 byte aligned, 2 for double buffer (not used) // Each cmd_sts can only transfer up to DMA_NBYTES_MAX bytes each ep_cmd_sts_t ep[2*MAX_EP_PAIRS][2]; xfer_dma_t dma[2*MAX_EP_PAIRS]; TU_ATTR_ALIGNED(64) uint8_t setup_packet[8]; }dcd_data_t; // EP list must be 256-byte aligned // Some MCU controller may require this variable to be placed in specific SRAM region. // For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000) // Use CFG_TUD_MEM_SECTION to place it accordingly. CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; // Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug) // TODO find way to save memory CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; //--------------------------------------------------------------------+ // Multiple Controllers //--------------------------------------------------------------------+ typedef struct { dcd_registers_t* regs; // registers const bool is_highspeed; // max link speed const IRQn_Type irqnum; // IRQ number const uint8_t ep_pairs; // Max bi-directional Endpoints }dcd_controller_t; #ifdef INCLUDE_FSL_DEVICE_REGISTERS static const dcd_controller_t _dcd_controller[] = { { .regs = (dcd_registers_t*) USB0_BASE , .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT { .regs = (dcd_registers_t*) USBHSD_BASE, .is_highspeed = true, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } #endif }; #else static const dcd_controller_t _dcd_controller[] = { { .regs = (dcd_registers_t*) LPC_USB0_BASE, .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = 5 }, }; #endif #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT #define IP3511_HAS_HIGHSPEED #endif //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const * buffer) { uint32_t addr = (uint32_t) buffer; TU_ASSERT( (addr & 0x3f) == 0, 0 ); return ( (addr >> 6) & 0xFFFFUL ) ; } TU_ATTR_ALWAYS_INLINE static inline uint8_t ep_addr2id(uint8_t ep_addr) { return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); } TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(ep_cmd_sts_t* ep_cs, bool is_highspeed) { return is_highspeed ? (ep_cs[0].cmd_sts.type && !ep_cs[0].cmd_sts.rf_tv) : ep_cs->cmd_sts.type; } TU_ATTR_ALWAYS_INLINE TU_ATTR_UNUSED static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) { return (ep_cs[0].cmd_sts.type == 0) && (ep_cs[0].cmd_sts.rf_tv == 0); } TU_ATTR_ALWAYS_INLINE static inline ep_cmd_sts_t* get_ep_cs(uint8_t ep_id) { return _dcd.ep[ep_id]; } TU_ATTR_ALWAYS_INLINE static inline bool rhport_is_highspeed(uint8_t rhport) { return _dcd_controller[rhport].is_highspeed; } //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ static void prepare_setup_packet(uint8_t rhport) { uint16_t const buf_offset = get_buf_offset(_dcd.setup_packet); if ( _dcd_controller[rhport].is_highspeed ) { _dcd.ep[0][1].buffer_hs.offset = buf_offset; } else { _dcd.ep[0][1].buffer_fs.offset = buf_offset; } } static void edpt_reset(uint8_t rhport, uint8_t ep_id) { (void) rhport; tu_memclr(&_dcd.ep[ep_id], sizeof(_dcd.ep[ep_id])); } static void edpt_reset_all(uint8_t rhport) { for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id) { edpt_reset(rhport, ep_id); } prepare_setup_packet(rhport); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; edpt_reset_all(rhport); dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->EPLISTSTART = (uint32_t) _dcd.ep; dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK; dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK | DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum); return true; } void dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(_dcd_controller[rhport].irqnum); } void dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(_dcd_controller[rhport].irqnum); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_ADDR_MASK; dcd_reg->DEVCMDSTAT |= dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; } void dcd_connect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_disconnect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; // TODO cannot able to STALL Control OUT endpoint !!!!! FIXME try some walk-around uint8_t const ep_id = ep_addr2id(ep_addr); _dcd.ep[ep_id][0].cmd_sts.stall = 1; } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const ep_id = ep_addr2id(ep_addr); _dcd.ep[ep_id][0].cmd_sts.stall = 0; _dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1; _dcd.ep[ep_id][0].cmd_sts.rf_tv = 0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { //------------- Prepare Queue Head -------------// uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); // Check if endpoint is available TU_ASSERT( ep_cs[0].cmd_sts.disable && ep_cs[1].cmd_sts.disable ); edpt_reset(rhport, ep_id); switch (p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_ISOCHRONOUS: ep_cs[0].cmd_sts.type = 1; break; case TUSB_XFER_INTERRUPT: // What is interrupt endpoint in rate feedback mode ? if ( rhport_is_highspeed(rhport) ) { ep_cs[0].cmd_sts.type = 1; ep_cs[0].cmd_sts.rf_tv = 1; } break; case TUSB_XFER_BULK: // nothing to do both type and rf_tv are 0 break; default: break; } // Enable EP interrupt dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->INTEN |= TU_BIT(ep_id); return true; } void dcd_edpt_close_all (uint8_t rhport) { for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id) { _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t ep_id = ep_addr2id(ep_addr); _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual) _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } #endif static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) { uint16_t nbytes; ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); const bool is_iso = ep_is_iso(ep_cs, _dcd_controller[rhport].is_highspeed); if ( rhport_is_highspeed(rhport) ) { nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_HS_MAX : NBYTES_CBI_HS_MAX); #if TU_CHECK_MCU(OPT_MCU_LPC54) // LPC54 Errata USB.1: In USB high-speed device mode, the NBytes field does not decrement after BULK OUT transfer. // Suggested Work-around: Program the NByte to the max packet size (512) // Actual Work-around: round up NByte to multiple of 4. // Note: this can cause buffer overflowed and corrupt data if host send more data than total_bytes if ( (ep_id > 1) && (ep_id & 0x01) == 0 && ep_is_bulk(ep_cs) ) { if ( nbytes & 0x03 ) { nbytes = tu_align4(nbytes) + 4; } } #endif ep_cs[0].buffer_hs.offset = buf_offset; ep_cs[0].buffer_hs.nbytes = nbytes; }else { nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); ep_cs[0].buffer_fs.offset = buf_offset; ep_cs[0].buffer_fs.nbytes = nbytes; } _dcd.dma[ep_id].nbytes = nbytes; ep_cs[0].cmd_sts.active = 1; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; uint8_t const ep_id = ep_addr2id(ep_addr); if (!buffer || total_bytes == 0) { // Although having no data, ZLPs can cause buffer overwritten to zeroes. Probably due to USB/DMA controller side // effect/bug. Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART buffer = (uint8_t *) (uint32_t) dummy; } tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); return true; } //--------------------------------------------------------------------+ // IRQ //--------------------------------------------------------------------+ static void bus_reset(uint8_t rhport) { tu_memclr(&_dcd, sizeof(dcd_data_t)); edpt_reset_all(rhport); // disable all endpoints as specified by LPC55S69 UM Table 778 for(uint8_t ep_id = 0; ep_id < 2*MAX_EP_PAIRS; ep_id++) { _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; dcd_reg->EPINUSE = 0; dcd_reg->EPBUFCFG = 0; dcd_reg->EPSKIP = 0xFFFFFFFF; dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints } static void process_xfer_isr(uint8_t rhport, uint32_t int_status) { uint8_t const max_ep = 2*_dcd_controller[rhport].ep_pairs; for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) { if ( tu_bit_test(int_status, ep_id) ) { ep_cmd_sts_t * ep_cs = &_dcd.ep[ep_id][0]; xfer_dma_t* xfer_dma = &_dcd.dma[ep_id]; if ( ep_id <= 1 ) { // For control endpoint, we need to manually clear Active bit ep_cs->cmd_sts.active = 0; } uint16_t buf_offset; uint16_t buf_nbytes; if ( rhport_is_highspeed(rhport) ) { buf_offset = ep_cs->buffer_hs.offset; buf_nbytes = ep_cs->buffer_hs.nbytes; #if TU_CHECK_MCU(OPT_MCU_LPC54) // LPC54 Errata USB.2: In USB high-speed device mode, the NBytes field is not correct after BULK IN transfer // There is no work-around. For EP in transfer, the NByte value can be ignored after a packet is transmitted. if ( (ep_id > 1) && (ep_id & 0x01) == 1 && ep_is_bulk(ep_cs) ) { buf_nbytes = 0; } #endif } else { buf_offset = ep_cs->buffer_fs.offset; buf_nbytes = ep_cs->buffer_fs.nbytes; } xfer_dma->xferred_bytes += xfer_dma->nbytes - buf_nbytes; if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) { // There is more data to transfer // buff_offset has been already increased by hw to correct value for next transfer prepare_ep_xfer(rhport, ep_id, buf_offset, xfer_dma->total_bytes - xfer_dma->xferred_bytes); } else { // for detecting ZLP xfer_dma->total_bytes = xfer_dma->xferred_bytes; uint8_t const ep_addr = tu_edpt_addr(ep_id / 2, ep_id & 0x01); // TODO no way determine if the transfer is failed or not dcd_event_xfer_complete(rhport, ep_addr, xfer_dma->xferred_bytes, XFER_RESULT_SUCCESS, true); } } } } void dcd_int_handler(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; uint32_t const cmd_stat = dcd_reg->DEVCMDSTAT; uint32_t int_status = dcd_reg->INTSTAT; int_status &= dcd_reg->INTEN; dcd_reg->INTSTAT = int_status; // Acknowledge handled interrupt if (int_status == 0) return; //------------- Device Status -------------// if ( int_status & INT_DEVICE_STATUS_MASK ) { dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; if ( cmd_stat & DEVCMDSTAT_RESET_CHANGE_MASK) // bus reset { bus_reset(rhport); tusb_speed_t speed = TUSB_SPEED_FULL; if ( _dcd_controller[rhport].is_highspeed ) { // 0 : reserved, 1 : full, 2 : high, 3: super if ( 2 == ((cmd_stat >> DEVCMDSTAT_SPEED_SHIFT) & 0x3UL) ) { speed= TUSB_SPEED_HIGH; } } dcd_event_bus_reset(rhport, speed, true); } if (cmd_stat & DEVCMDSTAT_CONNECT_CHANGE_MASK) { // device disconnect if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { // debouncing as this can be set when device is powering dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } if (cmd_stat & DEVCMDSTAT_SUSPEND_CHANGE_MASK) { // suspend signal, bus idle for more than 3ms // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { dcd_event_bus_signal(rhport, (cmd_stat & DEVCMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); } } } // Setup Receive if ( tu_bit_test(int_status, 0) && (cmd_stat & DEVCMDSTAT_SETUP_RECEIVED_MASK) ) { // Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints _dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0; _dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0; dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; dcd_event_setup_received(rhport, _dcd.setup_packet, true); // keep waiting for next setup prepare_setup_packet(rhport); // clear bit0 int_status = tu_bit_clear(int_status, 0); } // Endpoint transfer complete interrupt process_xfer_isr(rhport, int_status); } #endif ================================================ FILE: src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 HiFiPhile (Zixun LI) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_IP3516) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "common/tusb_common.h" #include "host/hcd.h" #include "host/usbh.h" #include "hcd_lpc_ip3516.h" #if TU_CHECK_MCU(OPT_MCU_LPC55, OPT_MCU_LPC54) #include "fsl_device_registers.h" #else #error "Unsupported MCUs" #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_LPC54) #define ATLPTD ATL_PTD_BASE_ADDR #define INTPTD INT_PTD_BASE_ADDR #define ISOPTD ISO_PTD_BASE_ADDR #define ATLPTDD ATL_PTD_DONE_MAP #define INTPTDD INT_PTD_DONE_MAP #define ISOPTDD ISO_PTD_DONE_MAP #define ATLPTDS ATL_PTD_SKIP_MAP #define INTPTDS INT_PTD_SKIP_MAP #define ISOPTDS ISO_PTD_SKIP_MAP #define DATAPAYLOAD DATA_PAYLOAD_BASE_ADDR #define LASTPTD LAST_PTD_INUSE #define USBHSH_ATLPTD_ATL_BASE_MASK USBHSH_ATL_PTD_BASE_ADDR_ATL_BASE_MASK #define USBHSH_INTPTD_INT_BASE_MASK USBHSH_INT_PTD_BASE_ADDR_INT_BASE_MASK #define USBHSH_ISOPTD_ISO_BASE_MASK USBHSH_ISO_PTD_BASE_ADDR_ISO_BASE_MASK #define USBHSH_DATAPAYLOAD_DAT_BASE_MASK USBHSH_DATA_PAYLOAD_BASE_ADDR_DAT_BASE_MASK #define USBHSH_LASTPTD_ATL_LAST USBHSH_LAST_PTD_INUSE_ATL_LAST #define USBHSH_LASTPTD_INT_LAST USBHSH_LAST_PTD_INUSE_INT_LAST #define USBHSH_LASTPTD_ISO_LAST USBHSH_LAST_PTD_INUSE_ISO_LAST #endif #define USBHSH_PORTSC1_W1C_MASK (USBHSH_PORTSC1_CSC_MASK | USBHSH_PORTSC1_PEDC_MASK | USBHSH_PORTSC1_OCC_MASK) #define IP3516_PSPD_LOW 0 #define IP3516_PSPD_FULL 1 #define IP3516_PSPD_HIGH 2 //--------------------------------------------------------------------+ // Proprietary Transfer Descriptor //--------------------------------------------------------------------+ CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(1024) static ip3516_ptd_t _ptd; static struct { uint32_t uframe_number; uint32_t uframe_length; bool attached; // Track attachment state to avoid duplicate events, sometimes high-speed disconnection detector is not reliable } _hcd_data; //--------------------------------------------------------------------+ // Helper Functions //--------------------------------------------------------------------+ static inline bool is_ptd_free(const ptd_ctrl1_t ctrl1) { return ctrl1.mps == 0; } static inline bool is_xfer_async(tusb_xfer_type_t xfer_type) { return (xfer_type == TUSB_XFER_CONTROL || xfer_type == TUSB_XFER_BULK); } static inline void ptd_clear_state(ptd_state_t *state) { ptd_state_t local = {.value = 0}; local.ep_type = state->ep_type; // preserve ep_type local.token = state->token; // preserve token local.data_toggle = state->data_toggle; // preserve data_toggle *state = local; } static inline uint8_t ptd_find_free(tusb_xfer_type_t xfer_type) { uint8_t max_count; intptr_t ptd_array; switch (xfer_type) { case TUSB_XFER_CONTROL: case TUSB_XFER_BULK: max_count = IP3516_ATL_NUM; ptd_array = (intptr_t)&_ptd.atl; break; case TUSB_XFER_INTERRUPT: max_count = IP3516_PTL_NUM; ptd_array = (intptr_t)&_ptd.intr; break; case TUSB_XFER_ISOCHRONOUS: max_count = IP3516_PTL_NUM; ptd_array = (intptr_t)&_ptd.iso; break; default: return TUSB_INDEX_INVALID_8; } for (uint8_t i = 0; i < max_count; i++) { // For ATL: stride is sizeof(ip3516_atl_t) = 16 bytes = 4 words // For PTL: stride is sizeof(ip3516_ptl_t) = 32 bytes = 8 words uint8_t stride = is_xfer_async(xfer_type) ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); ptd_ctrl1_t *ctrl1 = (ptd_ctrl1_t *)(ptd_array + i * stride); if (is_ptd_free(*ctrl1)) { return i; } } return TUSB_INDEX_INVALID_8; // No free PTD found } // Close all PTDs associated with a specific device address static void close_ptds_by_device(uint8_t dev_addr, intptr_t ptd_array, uint8_t max_count, uint8_t stride, volatile uint32_t *skip_reg) { uint32_t skip_mask = 0; for (uint8_t i = 0; i < max_count; i++) { intptr_t ptd_ptr = ptd_array + i * stride; ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); if (!is_ptd_free(*ptd_ctrl1) && ptd_ctrl2->dev_addr == dev_addr) { *skip_reg |= (1 << i); skip_mask |= (1 << i); } } if (skip_mask) { // Wait 1 uframe for PTDs to be inactive (with timeout) uint32_t start_uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; uint32_t timeout = 10000; while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == start_uframe && timeout > 0) { timeout--; } // Clear PTDs for (uint8_t i = 0; i < max_count; i++) { if (skip_mask & (1 << i)) { intptr_t ptd_ptr = ptd_array + i * stride; tu_memclr((void *)ptd_ptr, stride); } } // Clear skip bits *skip_reg &= ~skip_mask; } } // Check if a PTD matches the given endpoint criteria static bool ptd_matches(intptr_t ptd_ptr, uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir) { ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); if (is_ptd_free(*ptd_ctrl1)) { return false; } ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); if (ptd_ctrl2->dev_addr != dev_addr || ptd_ctrl2->ep_num != ep_num) { return false; } ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); bool is_control = (ptd_state->ep_type == TUSB_XFER_CONTROL); // For control endpoint, match both IN and OUT directions if (is_control) { return true; } if (ep_dir == TUSB_DIR_IN && ptd_state->token == IP3516_PTD_TOKEN_IN) { return true; } if (ep_dir == TUSB_DIR_OUT && ptd_state->token == IP3516_PTD_TOKEN_OUT) { return true; } return false; } // Find and close a specific PTD static bool find_and_close_ptd(uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir, intptr_t ptd_array, uint8_t max_count, uint8_t stride, volatile uint32_t *skip_reg) { for (uint8_t i = 0; i < max_count; i++) { intptr_t ptd_ptr = ptd_array + i * stride; if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { if (skip_reg) { *skip_reg |= (1 << i); // Wait 1 uframe for PTD to be inactive (with timeout) uint32_t start_uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; uint32_t timeout = 10000; while (((USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT) == start_uframe && timeout > 0) { timeout--; } // Just clear state ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); ptd_clear_state(ptd_state); ptd_ctrl1->valid = 0; *skip_reg &= ~(1 << i); } else { // Clear PTD tu_memclr((void *)ptd_ptr, stride); } return true; } } return false; } // Find an opened PTD static intptr_t find_opened_ptd(uint8_t dev_addr, uint8_t ep_addr) { const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); // Search in ATL for (uint8_t i = 0; i < IP3516_ATL_NUM; i++) { intptr_t ptd_ptr = (intptr_t)&_ptd.atl[i]; if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { return ptd_ptr; } } // Search in INT for (uint8_t i = 0; i < IP3516_PTL_NUM; i++) { intptr_t ptd_ptr = (intptr_t)&_ptd.intr[i]; if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { return ptd_ptr; } } // Search in ISO for (uint8_t i = 0; i < IP3516_PTL_NUM; i++) { intptr_t ptd_ptr = (intptr_t)&_ptd.iso[i]; if (ptd_matches(ptd_ptr, dev_addr, ep_num, ep_dir)) { return ptd_ptr; } } return 0; } static bool edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen, bool is_setup) { const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); TU_ASSERT(ptd_ptr != 0); ptd_ctrl1_t *ptd_ctrl1 = (ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); ptd_data_t *ptd_data = (ptd_data_t *)(ptd_ptr + offsetof(ip3516_atl_t, data)); ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); // Setup data buffer and length ptd_data->data_addr = (uint32_t)(uintptr_t)buffer & IP3516_PTD_DATA_ADDR_MASK; ptd_data->xfer_len = buflen; // Clear previous state ptd_clear_state(ptd_state); // Set token for EP0 if (ep_num == 0) { if (is_setup) { ptd_state->token = IP3516_PTD_TOKEN_SETUP; ptd_state->data_toggle = 0; } else { ptd_state->token = (ep_dir == TUSB_DIR_IN) ? IP3516_PTD_TOKEN_IN : IP3516_PTD_TOKEN_OUT; ptd_state->data_toggle = 1; } } // Interrupt split transfer needs to be relaunched manually if NAKed if (ptd_ctrl2->split && ptd_state->ep_type == TUSB_XFER_INTERRUPT) { ptd_ctrl2->reload = 0x0f; ptd_state->nak_cnt = 0x0f; } // Activate PTD ptd_ctrl1->valid = 1; ptd_state->active = 1; return true; } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rh_init; (void)rhport; // Reset controller USBHSH->USBCMD |= USBHSH_USBCMD_HCRESET_MASK; while (USBHSH->USBCMD & USBHSH_USBCMD_HCRESET_MASK) {} USBHSH->PORTMODE = USBHSH_PORTMODE_SW_CTRL_PDCOM_MASK; tu_memclr(&_ptd, sizeof(_ptd)); tu_varclr(&_hcd_data); // Set base addresses USBHSH->ATLPTD = (uint32_t)&_ptd.atl & USBHSH_ATLPTD_ATL_BASE_MASK; USBHSH->INTPTD = (uint32_t)&_ptd.intr & USBHSH_INTPTD_INT_BASE_MASK; USBHSH->ISOPTD = (uint32_t)&_ptd.iso & USBHSH_ISOPTD_ISO_BASE_MASK; USBHSH->DATAPAYLOAD = (uint32_t)&_ptd & USBHSH_DATAPAYLOAD_DAT_BASE_MASK; // Turn on power switch if (USBHSH->HCSPARAMS & USBHSH_HCSPARAMS_PPC_MASK) { USBHSH->PORTSC1 |= USBHSH_PORTSC1_PP_MASK; } // Get frame list size uint32_t fls = (USBHSH->USBCMD & USBHSH_USBCMD_FLS_MASK) >> USBHSH_USBCMD_FLS_SHIFT; _hcd_data.uframe_length = 8192 >> fls; // Clear pending interrupts USBHSH->USBSTS = 0xFFFFFFFF; // Enable interrupts USBHSH->USBINTR = USBHSH_USBINTR_ATL_IRQ_E_MASK | USBHSH_USBINTR_INT_IRQ_E_MASK | USBHSH_USBINTR_ISO_IRQ_E_MASK | USBHSH_USBINTR_PCDE_MASK | USBHSH_USBINTR_FLRE_MASK; // Enable all PTDs USBHSH->LASTPTD = USBHSH_LASTPTD_ATL_LAST(IP3516_ATL_NUM - 1) | USBHSH_LASTPTD_INT_LAST(IP3516_PTL_NUM - 1) | USBHSH_LASTPTD_ISO_LAST(IP3516_PTL_NUM - 1); // Enable controller USBHSH->USBCMD = USBHSH_USBCMD_ATL_EN_MASK | USBHSH_USBCMD_INT_EN_MASK | USBHSH_USBCMD_ISO_EN_MASK | USBHSH_USBCMD_RS_MASK; return true; } // Enable USB interrupt void hcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB1_IRQn); } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB1_IRQn); } bool hcd_deinit(uint8_t rhport) { (void)rhport; // Disable interrupts USBHSH->USBINTR = 0; USBHSH->USBSTS = 0xFFFFFFFF; // Disable controller USBHSH->USBCMD &= ~(USBHSH_USBCMD_ATL_EN_MASK | USBHSH_USBCMD_INT_EN_MASK | USBHSH_USBCMD_ISO_EN_MASK | USBHSH_USBCMD_RS_MASK); // Turn off power switch if (USBHSH->HCSPARAMS & USBHSH_HCSPARAMS_PPC_MASK) { USBHSH->PORTSC1 &= ~USBHSH_PORTSC1_PP_MASK; } // Connect PHY to device mode USBHSH->PORTMODE = USBHSH_PORTMODE_SW_CTRL_PDCOM_MASK | USBHSH_PORTMODE_DEV_ENABLE_MASK; return true; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport) { (void)rhport; uint32_t status = USBHSH->PORTSC1 & ~USBHSH_PORTSC1_W1C_MASK; USBHSH->PORTSC1 = status | USBHSH_PORTSC1_PR_MASK; } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { (void)rhport; uint32_t status = USBHSH->PORTSC1 & ~USBHSH_PORTSC1_W1C_MASK; USBHSH->PORTSC1 = status & ~USBHSH_PORTSC1_PR_MASK; while (USBHSH->PORTSC1 & USBHSH_PORTSC1_PR_MASK) {} #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; if (pspd == IP3516_PSPD_HIGH) { // enable phy disconnection for high speed USBPHY->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; } #endif } // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { (void)rhport; return (USBHSH->PORTSC1 & USBHSH_PORTSC1_CCS_MASK) ? true : false; } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; uint32_t pspd = (USBHSH->PORTSC1 & USBHSH_PORTSC1_PSPD_MASK) >> USBHSH_PORTSC1_PSPD_SHIFT; switch (pspd) { case IP3516_PSPD_LOW: return TUSB_SPEED_LOW; case IP3516_PSPD_FULL: return TUSB_SPEED_FULL; case IP3516_PSPD_HIGH: return TUSB_SPEED_HIGH; default: return TUSB_SPEED_INVALID; } } // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void)rhport; uint32_t uframe = (USBHSH->FLADJ_FRINDEX & USBHSH_FLADJ_FRINDEX_FRINDEX_MASK) >> USBHSH_FLADJ_FRINDEX_FRINDEX_SHIFT; uframe &= (_hcd_data.uframe_length - 1); return (uframe + _hcd_data.uframe_number) >> 3; } // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void)rhport; close_ptds_by_device(dev_addr, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), &USBHSH->ATLPTDS); close_ptds_by_device(dev_addr, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->INTPTDS); close_ptds_by_device(dev_addr, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->ISOPTDS); } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ static inline intptr_t get_ptd_from_index(tusb_xfer_type_t xfer_type, uint8_t ptd_index) { if (is_xfer_async(xfer_type)) { return (intptr_t)&_ptd.atl[ptd_index]; } else { if (xfer_type == TUSB_XFER_INTERRUPT) { return (intptr_t)&_ptd.intr[ptd_index]; } else { return (intptr_t)&_ptd.iso[ptd_index]; } } } // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t *ep_desc) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress); const tusb_xfer_type_t xfer_type = (tusb_xfer_type_t)ep_desc->bmAttributes.xfer; tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); // Find a free PTD uint8_t ptd_index = ptd_find_free(xfer_type); TU_ASSERT(ptd_index != TUSB_INDEX_INVALID_8); // Configure PTD intptr_t ptd_ptr = get_ptd_from_index(xfer_type, ptd_index); volatile ptd_ctrl1_t *ctrl1 = (volatile ptd_ctrl1_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl1)); volatile ptd_ctrl2_t *ctrl2 = (volatile ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); volatile ptd_data_t *data = (volatile ptd_data_t *)(ptd_ptr + offsetof(ip3516_atl_t, data)); volatile ptd_state_t *state = (volatile ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); // Initialize PTD fields ctrl1->mps = ep_desc->wMaxPacketSize; ctrl1->mult = 1; ctrl2->dev_addr = dev_addr; ctrl2->ep_num = ep_num; ctrl2->speed = bus_info.speed == TUSB_SPEED_LOW ? 2 : 0; ctrl2->hub_addr = bus_info.hub_addr; ctrl2->hub_port = bus_info.hub_port; ctrl2->split = (hcd_port_speed_get(rhport) == TUSB_SPEED_HIGH) && (bus_info.speed != TUSB_SPEED_HIGH) ? 1 : 0; data->intr = 1; state->ep_type = (uint32_t)xfer_type; state->token = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? IP3516_PTD_TOKEN_IN : IP3516_PTD_TOKEN_OUT; if (!is_xfer_async(xfer_type)) { ip3516_ptl_t *ptd = (ip3516_ptl_t *)ptd_ptr; uint32_t uframe_interval; if (bus_info.speed == TUSB_SPEED_HIGH) { uframe_interval = 1 << (ep_desc->bInterval - 1); } else { uframe_interval = ep_desc->bInterval << 3; // round down to nearest power of 2 uframe_interval = 1 << tu_log2(uframe_interval); } uframe_interval = tu_min32(uframe_interval, IP3516_MAX_UFRAME); // uframe_active is an 8-bit mask, where each bit corresponds to a micro-frame within a 1ms frame. // A '1' indicates the endpoint should be polled in that micro-frame. // For example: // Interval 1 (poll every u-frame) -> mask is 0b11111111 (0xFF) // Interval 2 (poll every 2nd u-frame, e.g., 0, 2, 4, 6) -> mask is 0b10101010 (0xAA) // Interval 4 (poll every 4th u-frame, e.g., 0, 4) -> mask is 0b10001000 (0x88) // Interval 8 (poll every 8th u-frame, e.g., 0) -> mask is 0b10000000 (0x80) switch (uframe_interval) { case 1: ptd->status.uframe_active = 0xFF; break; case 2: ptd->status.uframe_active = 0xAA; break; case 4: ptd->status.uframe_active = 0x11; break; case 8: ptd->status.uframe_active = 0x01; break; default: // For intervals > 8, we poll once per frame (every 8 u-frames) and use ctrl1.uframe to skip frames. ptd->status.uframe_active = 0x01; if (uframe_interval >= 16) { ctrl1->uframe = tu_log2(uframe_interval) - 3; } break; } if (ctrl2->split) { // 11.18.1 Best Case Full-Speed Budget // // A microframe of time allows at most 187.5 raw bytes of signaling on a full-speed bus. // The best case full-speed budget assumes that 188 full-speed bytes occur in each microframe. // // A 1 ms frame subdivided into microframes of budget time: // // Microframes Y_0 Y_1 Y_2 Y_3 Y_4 Y_5 Y_6 Y_7 // Max wire time 187.5 187.5 187.5 187.5 187.5 187.5 32 // Best case wire budget 188 188 188 188 188 188 29 // // 11.18.4 Host Split Transaction Scheduling Requirements // // 1. The host must never schedule a start-split in microframe Y_6. // 2. For isochronous OUT full-speed transactions, for each microframe in which the transaction is // budgeted, the host must schedule a 188 (or the remaining data size) data byte start-split transaction. // For isochronous IN and interrupt IN/OUT full-/low-speed transactions, a single start-split must be // scheduled in the microframe before the transaction is budgeted to start on the full-/low-speed bus. // 3. For isochronous OUT full-speed transactions, the host must never schedule a complete-split. The // TT response to a complete-split for an isochronous OUT is undefined. // For interrupt IN/OUT full-/low-speed transactions, the host must schedule a complete-split // transaction in each of the two microframes following the first microframe in which the full-/low- // speed transaction is budgeted. An additional complete-split must also be scheduled in the third // following microframe unless the full-/low-speed transaction was budgeted to start in microframe Y_6 // For isochronous IN full-speed transactions, for each microframe in which the full-speed transaction // is budgeted, a complete-split must be scheduled for each following microframe. // Also, determine the last microframe in which a complete-split is scheduled, call it L. // If L is less than Y_6, schedule additional complete-splits in microframe L+1 and L+2. // If L is equal to Y_6, schedule one complete-split in microframe Y_7. // // TODO: Implement budget check scheduling // Otherwise, it may cause bus contention with other split transfers // Here we simply start interrupt transfers for Y_0 and Y1 and isochronous transfers for Y_2 if (xfer_type == TUSB_XFER_ISOCHRONOUS) { const uint8_t ss_slot = 2; // Start-split slot const uint8_t slots = (ep_desc->wMaxPacketSize + 187) / 188; const tusb_dir_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); if (ep_dir == TUSB_DIR_IN) { if (ep_desc->wMaxPacketSize > 192) { ctrl1->mps = 192; } ptd->status.uframe_active = 1 << ss_slot; for (uint8_t i = 0; i < slots; i++) { ptd->iso_in_0.uframe_complete |= 1 << (2 + ss_slot + i); } // Schedule additional complete-splits if needed uint8_t last_complete = ss_slot + slots + 1; if (last_complete < 6) { ptd->iso_in_0.uframe_complete |= 1 << (ss_slot + last_complete + 1); ptd->iso_in_0.uframe_complete |= 1 << (ss_slot + last_complete + 2); } else if (last_complete == 6) { ptd->iso_in_0.uframe_complete |= 1 << 7; } } else { if (ep_desc->wMaxPacketSize > 188) { ctrl1->mps = 188; } for (uint8_t i = 0; i < slots; i++) { ptd->status.uframe_active |= 1 << (ss_slot + i); } } } else { // Start-split slot, jigging to avoid bus contention: EP odd -> Y_1, EP even -> Y_0 const uint8_t ss_slot = ep_num & 0x01; ptd->status.uframe_active = 1 << ss_slot; // Complete-split slots: next 3 u-frames ptd->iso_in_0.uframe_complete = 0x1c << ss_slot; } } } return true; } // Close an opened endpoint bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); // Search in ATL if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), NULL)) { return true; } // Search in INT if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), NULL)) { return true; } // Search in ISO if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), NULL)) { return true; } return false; } // Submit a transfer on an endpoint bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void)rhport; return edpt_xfer(dev_addr, ep_addr, buffer, buflen, false); } // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); // Search in ATL if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.atl, IP3516_ATL_NUM, sizeof(ip3516_atl_t), &USBHSH->ATLPTDS)) { return true; } // Search in INT if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.intr, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->INTPTDS)) { return true; } // Search in ISO if (find_and_close_ptd(dev_addr, ep_num, ep_dir, (intptr_t)&_ptd.iso, IP3516_PTL_NUM, sizeof(ip3516_ptl_t), &USBHSH->ISOPTDS)) { return true; } return false; } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, const uint8_t setup_packet[8]) { (void)rhport; return edpt_xfer(dev_addr, 0x00, (uint8_t *)(uintptr_t)setup_packet, 8, true); } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void)rhport; intptr_t ptd_ptr = find_opened_ptd(dev_addr, ep_addr); TU_ASSERT(ptd_ptr != 0); ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); ptd_clear_state(ptd_state); ptd_state->data_toggle = 0; // reset data toggle to DATA0 return true; } //--------------------------------------------------------------------+ // Interrupt Handler //--------------------------------------------------------------------+ // Handle port status change event static inline void handle_port_status_change(uint8_t rhport) { const uint32_t status = USBHSH->PORTSC1; if (status & USBHSH_PORTSC1_CSC_MASK) { if (status & USBHSH_PORTSC1_CCS_MASK && !_hcd_data.attached) { _hcd_data.attached = true; hcd_event_device_attach(rhport, true); } else { _hcd_data.attached = false; hcd_event_device_remove(rhport, true); #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) // disable phy disconnection for high speed USBPHY->CTRL &= ~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; #endif } } USBHSH->PORTSC1 |= status & USBHSH_PORTSC1_W1C_MASK; } // Handle PTD done interrupt static inline void handle_ptd_done(uint32_t done_status, intptr_t ptd_array, bool is_async) { uint8_t max_count = is_async ? IP3516_ATL_NUM : IP3516_PTL_NUM; uint8_t stride = is_async ? sizeof(ip3516_atl_t) : sizeof(ip3516_ptl_t); for (uint8_t i = 0; i < max_count; i++) { if (done_status & (1 << i)) { intptr_t ptd_ptr = ptd_array + i * stride; ptd_ctrl2_t *ptd_ctrl2 = (ptd_ctrl2_t *)(ptd_ptr + offsetof(ip3516_atl_t, ctrl2)); ptd_state_t *ptd_state = (ptd_state_t *)(ptd_ptr + offsetof(ip3516_atl_t, state)); xfer_result_t result; if (ptd_state->halt) { result = XFER_RESULT_STALLED; } else if (ptd_state->error || ptd_state->babble) { result = XFER_RESULT_FAILED; } else { result = XFER_RESULT_SUCCESS; } uint8_t ep_addr = ptd_ctrl2->ep_num | (ptd_state->token == IP3516_PTD_TOKEN_IN ? 0x80 : 0x00); hcd_event_xfer_complete(ptd_ctrl2->dev_addr, ep_addr, ptd_state->xferred_len, result, true); } } } void hcd_int_handler(uint8_t rhport, bool in_isr) { (void)in_isr; uint32_t int_status = USBHSH->USBSTS; USBHSH->USBSTS = int_status; // clear interrupt status // Port Change Detect if (int_status & USBHSH_USBSTS_PCD_MASK) { handle_port_status_change(rhport); } // Frame List Rollover if (int_status & USBHSH_USBSTS_FLR_MASK) { _hcd_data.uframe_number += _hcd_data.uframe_length; } // ATL done if (int_status & USBHSH_USBSTS_ATL_IRQ_MASK) { uint32_t done_status = USBHSH->ATLPTDD; handle_ptd_done(done_status, (intptr_t)&_ptd.atl, true); USBHSH->ATLPTDD = done_status; } // INT done if (int_status & USBHSH_USBSTS_INT_IRQ_MASK) { uint32_t done_status = USBHSH->INTPTDD; handle_ptd_done(done_status, (intptr_t)&_ptd.intr, false); USBHSH->INTPTDD = done_status; } // ISO done if (int_status & USBHSH_USBSTS_ISO_IRQ_MASK) { uint32_t done_status = USBHSH->ISOPTDD; handle_ptd_done(done_status, (intptr_t)&_ptd.iso, false); USBHSH->ISOPTDD = done_status; } } #endif ================================================ FILE: src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 HiFiPhile (Zixun LI) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_HCD_IP3516_H_ #define TUSB_HCD_IP3516_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // IP3516 CONFIGURATION & CONSTANTS //--------------------------------------------------------------------+ #define IP3516_ATL_NUM 32 #define IP3516_PTL_NUM 32 #define IP3516_PTD_TOKEN_OUT 0x00U #define IP3516_PTD_TOKEN_IN 0x01U #define IP3516_PTD_TOKEN_SETUP 0x02U #define IP3516_PTD_EPTYPE_OUT 0x00U #define IP3516_PTD_EPTYPE_IN 0x01U #define IP3516_PTD_EPTYPE_SETUP 0x02U #define IP3516_PTD_MAX_TRANSFER_LENGTH 0x7FFFU #define IP3516_PTD_DATA_ADDR_MASK 0xFFFFU #define IP3516_MAX_UFRAME (1UL << 8) #define IP3516_PERIODIC_TRANSFER_GAP (3U) #define IP3516_ISO_MULTIPLE_TRANSFER (8U) //--------------------------------------------------------------------+ // IP3516 PTD Data Structure //--------------------------------------------------------------------+ // Control Word 1 typedef union { uint32_t value; struct { uint32_t valid : 1; uint32_t next_ptd : 5; uint32_t : 1; uint32_t jump : 1; uint32_t uframe : 8; uint32_t mps : 11; uint32_t : 1; uint32_t mult : 2; uint32_t : 2; }; } ptd_ctrl1_t; TU_VERIFY_STATIC(sizeof(ptd_ctrl1_t) == 4, "size is not correct"); // Control Word 2 typedef union { uint32_t value; struct { uint32_t ep_num : 4; uint32_t dev_addr : 7; uint32_t split : 1; uint32_t reload : 4; uint32_t speed : 2; uint32_t hub_port : 7; uint32_t hub_addr : 7; }; } ptd_ctrl2_t; TU_VERIFY_STATIC(sizeof(ptd_ctrl2_t) == 4, "size is not correct"); // Data Word typedef union { uint32_t value; struct { uint32_t xfer_len : 15; uint32_t intr : 1; uint32_t data_addr : 16; }; } ptd_data_t; TU_VERIFY_STATIC(sizeof(ptd_data_t) == 4, "size is not correct"); // State Word typedef union { uint32_t value; struct { uint32_t xferred_len : 15; uint32_t token : 2; uint32_t ep_type : 2; uint32_t nak_cnt : 4; uint32_t err_cnt : 2; uint32_t data_toggle : 1; uint32_t ping : 1; uint32_t start_complete : 1; uint32_t error : 1; uint32_t babble : 1; uint32_t halt : 1; uint32_t active : 1; }; } ptd_state_t; TU_VERIFY_STATIC(sizeof(ptd_state_t) == 4, "size is not correct"); // Status Word typedef union { uint32_t value; struct { uint32_t uframe_active : 8; uint32_t iso_status0 : 3; uint32_t iso_status1 : 3; uint32_t iso_status2 : 3; uint32_t iso_status3 : 3; uint32_t iso_status4 : 3; uint32_t iso_status5 : 3; uint32_t iso_status6 : 3; uint32_t iso_status7 : 3; }; } ptd_status_t; TU_VERIFY_STATIC(sizeof(ptd_status_t) == 4, "size is not correct"); // ATL (Asynchronous Transfer List) structure typedef volatile struct { ptd_ctrl1_t ctrl1; ptd_ctrl2_t ctrl2; ptd_data_t data; ptd_state_t state; } ip3516_atl_t; TU_VERIFY_STATIC(sizeof(ip3516_atl_t) == 16, "size is not correct"); // PTL (Periodic Transfer List) structure typedef volatile struct { ptd_ctrl1_t ctrl1; ptd_ctrl2_t ctrl2; ptd_data_t data; ptd_state_t state; ptd_status_t status; union { uint32_t value; struct { uint32_t uframe_complete : 8; uint32_t spl_iso_in_0 : 24; }; } iso_in_0; uint32_t iso_in_1; uint32_t iso_in_2; } ip3516_ptl_t; TU_VERIFY_STATIC(sizeof(ip3516_ptl_t) == 32, "size is not correct"); // Proprietary Transfer Descriptor typedef struct { ip3516_ptl_t intr[IP3516_PTL_NUM]; ip3516_ptl_t iso[IP3516_PTL_NUM]; ip3516_atl_t atl[IP3516_ATL_NUM]; } ip3516_ptd_t; #ifdef __cplusplus } #endif #endif /* TUSB_HCD_IP3516_H_ */ ================================================ FILE: src/portable/ohci/ohci.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_OHCI) #ifndef TUP_OHCI_RHPORTS #error OHCI is enabled, but TUP_OHCI_RHPORTS is not defined. #endif //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "osal/osal.h" #include "host/hcd.h" #include "host/usbh.h" #include "ohci.h" #if defined(TUP_USBIP_OHCI_NXP) #include "ohci_nxp.h" #else #error Unsupported OHCI IP #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ enum { OHCI_CONTROL_FUNCSTATE_RESET = 0, OHCI_CONTROL_FUNCSTATE_RESUME, OHCI_CONTROL_FUNCSTATE_OPERATIONAL, OHCI_CONTROL_FUNCSTATE_SUSPEND }; enum { OHCI_CONTROL_CONTROL_BULK_RATIO = 3, ///< This specifies the service ratio between Control and Bulk EDs. 0 = 1:1, 3 = 4:1 OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK = TU_BIT(2), OHCI_CONTROL_LIST_ISOCHRONOUS_ENABLE_MASK = TU_BIT(3), OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK = TU_BIT(4), OHCI_CONTROL_LIST_BULK_ENABLE_MASK = TU_BIT(5), }; enum { OHCI_FMINTERVAL_FI = 0x2EDF, // 7.3.1 nominal (reset) value OHCI_FMINTERVAL_FSMPS = (6*(OHCI_FMINTERVAL_FI-210)) / 7, // 5.4 calculated based on maximum overhead + bit stuffing }; enum { OHCI_PERIODIC_START = 0x3E67 }; enum { OHCI_INT_SCHEDULING_OVERUN_MASK = TU_BIT(0), OHCI_INT_WRITEBACK_DONEHEAD_MASK = TU_BIT(1), OHCI_INT_SOF_MASK = TU_BIT(2), OHCI_INT_RESUME_DETECTED_MASK = TU_BIT(3), OHCI_INT_UNRECOVERABLE_ERROR_MASK = TU_BIT(4), OHCI_INT_FRAME_OVERFLOW_MASK = TU_BIT(5), OHCI_INT_RHPORT_STATUS_CHANGE_MASK = TU_BIT(6), OHCI_INT_OWNERSHIP_CHANGE_MASK = TU_BIT(30), OHCI_INT_MASTER_ENABLE_MASK = TU_BIT(31), }; enum { RHPORT_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), RHPORT_PORT_ENABLE_STATUS_MASK = TU_BIT(1), RHPORT_PORT_SUSPEND_STATUS_MASK = TU_BIT(2), RHPORT_PORT_OVER_CURRENT_INDICATOR_MASK = TU_BIT(3), RHPORT_PORT_RESET_STATUS_MASK = TU_BIT(4), ///< write '1' to reset port RHPORT_PORT_POWER_STATUS_MASK = TU_BIT(8), RHPORT_LOW_SPEED_DEVICE_ATTACHED_MASK = TU_BIT(9), RHPORT_CONNECT_STATUS_CHANGE_MASK = TU_BIT(16), RHPORT_PORT_ENABLE_CHANGE_MASK = TU_BIT(17), RHPORT_PORT_SUSPEND_CHANGE_MASK = TU_BIT(18), RHPORT_OVER_CURRENT_CHANGE_MASK = TU_BIT(19), RHPORT_PORT_RESET_CHANGE_MASK = TU_BIT(20), RHPORT_ALL_CHANGE_MASK = RHPORT_CONNECT_STATUS_CHANGE_MASK | RHPORT_PORT_ENABLE_CHANGE_MASK | RHPORT_PORT_SUSPEND_CHANGE_MASK | RHPORT_OVER_CURRENT_CHANGE_MASK | RHPORT_PORT_RESET_CHANGE_MASK }; enum { OHCI_CCODE_NO_ERROR = 0, OHCI_CCODE_CRC = 1, OHCI_CCODE_BIT_STUFFING = 2, OHCI_CCODE_DATA_TOGGLE_MISMATCH = 3, OHCI_CCODE_STALL = 4, OHCI_CCODE_DEVICE_NOT_RESPONDING = 5, OHCI_CCODE_PID_CHECK_FAILURE = 6, OHCI_CCODE_UNEXPECTED_PID = 7, OHCI_CCODE_DATA_OVERRUN = 8, OHCI_CCODE_DATA_UNDERRUN = 9, OHCI_CCODE_BUFFER_OVERRUN = 12, OHCI_CCODE_BUFFER_UNDERRUN = 13, OHCI_CCODE_NOT_ACCESSED = 14, }; enum { OHCI_INT_ON_COMPLETE_YES = 0, OHCI_INT_ON_COMPLETE_NO = 0x7 // 0b111 }; enum { GTD_DT_TOGGLE_CARRY = 0, GTD_DT_DATA0 = TU_BIT(1) | 0, GTD_DT_DATA1 = TU_BIT(1) | 1, }; enum { PID_SETUP = 0, PID_OUT, PID_IN, }; enum { PID_FROM_TD = 0, }; //--------------------------------------------------------------------+ // Support for explicit D-cache operations //--------------------------------------------------------------------+ TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; } // Optional macro to access ED in uncached way #ifndef hcd_dcache_uncached #define hcd_dcache_uncached(x) (x) #endif //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(256) static ohci_data_t ohci_data; static ohci_ed_t * const p_ed_head[] = { [TUSB_XFER_CONTROL] = hcd_dcache_uncached(&ohci_data.control[0].ed), [TUSB_XFER_BULK ] = hcd_dcache_uncached(&ohci_data.bulk_head_ed), [TUSB_XFER_INTERRUPT] = hcd_dcache_uncached(&ohci_data.period_head_ed), [TUSB_XFER_ISOCHRONOUS] = NULL // TODO Isochronous }; static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed); static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr); static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd); static ohci_ed_t* ed_from_addr(uint8_t dev_addr, uint8_t ep_addr); TU_ATTR_ALWAYS_INLINE static inline ohci_ed_t* ed_control(uint8_t daddr) { return hcd_dcache_uncached(&ohci_data.control[daddr].ed); } //--------------------------------------------------------------------+ // USBH-HCD API //--------------------------------------------------------------------+ // If your system requires separation of virtual and physical memory, implement // tusb_app_virt_to_phys and tusb_app_virt_to_phys in your application. TU_ATTR_ALWAYS_INLINE static inline void *_phys_addr(void *virtual_address) { return tusb_app_virt_to_phys(virtual_address); } TU_ATTR_ALWAYS_INLINE static inline void *_virt_addr(void *physical_address) { return tusb_app_phys_to_virt(physical_address); } // Initialization according to 5.1.1.4 bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; ohci_phy_init(rhport); //------------- Data Structure init -------------// tu_memclr(&ohci_data, sizeof(ohci_data_t)); // assign all interrupt pointers to period head ed for(uint8_t i=0; i<32; i++) { ohci_data.hcca.interrupt_table[i] = (uint32_t) _phys_addr(&ohci_data.period_head_ed); } ohci_data.control[0].ed.w0.skip = 1; ohci_data.bulk_head_ed.w0.skip = 1; ohci_data.period_head_ed.w0.skip = 1; //If OHCI hardware is in SMM mode, gain ownership (Ref OHCI spec 5.1.1.3.3) if (OHCI_REG->control_bit.interrupt_routing == 1) { OHCI_REG->command_status_bit.ownership_change_request = 1; while (OHCI_REG->control_bit.interrupt_routing == 1) {} } else if (OHCI_REG->control_bit.hc_functional_state != OHCI_CONTROL_FUNCSTATE_RESET && OHCI_REG->control_bit.hc_functional_state != OHCI_CONTROL_FUNCSTATE_OPERATIONAL) { //If OHCI hardware has come from warm-boot, signal resume (Ref OHCI spec 5.1.1.3.4) //Wait 20 ms. (Ref Usb spec 7.1.7.7) OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_RESUME; tusb_time_delay_ms_api(20); } hcd_dcache_clean(&ohci_data, sizeof(ohci_data)); // reset controller OHCI_REG->command_status_bit.controller_reset = 1; while( OHCI_REG->command_status_bit.controller_reset ) {} // should not take longer than 10 us //------------- init ohci registers -------------// OHCI_REG->control_head_ed = (uint32_t) _phys_addr(&ohci_data.control[0].ed); OHCI_REG->bulk_head_ed = (uint32_t) _phys_addr(&ohci_data.bulk_head_ed); OHCI_REG->hcca = (uint32_t) _phys_addr(&ohci_data.hcca); OHCI_REG->interrupt_disable = OHCI_REG->interrupt_enable; // disable all interrupts OHCI_REG->interrupt_status = OHCI_REG->interrupt_status; // clear current set bits OHCI_REG->interrupt_enable = OHCI_INT_WRITEBACK_DONEHEAD_MASK | OHCI_INT_RESUME_DETECTED_MASK | OHCI_INT_UNRECOVERABLE_ERROR_MASK | OHCI_INT_FRAME_OVERFLOW_MASK | OHCI_INT_RHPORT_STATUS_CHANGE_MASK | OHCI_INT_MASTER_ENABLE_MASK; OHCI_REG->control = OHCI_CONTROL_CONTROL_BULK_RATIO | OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK | OHCI_CONTROL_LIST_BULK_ENABLE_MASK | OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK; // TODO Isochronous OHCI_REG->frame_interval = (OHCI_FMINTERVAL_FSMPS << 16) | OHCI_FMINTERVAL_FI; OHCI_REG->frame_interval ^= (1ul << 31); //Must toggle when frame_interval is updated. OHCI_REG->periodic_start = (OHCI_FMINTERVAL_FI * 9) / 10; // Periodic start is 90% of frame interval OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // make HC's state to operational state TODO use this to suspend (save power) OHCI_REG->rh_status_bit.local_power_status_change = 1; // set global power for ports tusb_time_delay_ms_api(OHCI_REG->rh_descriptorA_bit.power_on_to_good_time * 2); // Wait POTG after power up return true; } uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return (ohci_data.frame_number_hi << 16) | OHCI_REG->frame_number; } //--------------------------------------------------------------------+ // PORT API //--------------------------------------------------------------------+ void hcd_port_reset(uint8_t hostid) { OHCI_REG->rhport_status[hostid] = RHPORT_PORT_RESET_STATUS_MASK; } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } bool hcd_port_connect_status(uint8_t hostid) { return OHCI_REG->rhport_status_bit[hostid].current_connect_status; } tusb_speed_t hcd_port_speed_get(uint8_t hostid) { return OHCI_REG->rhport_status_bit[hostid].low_speed_device_attached ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; } // endpoints are tied to an address, which only reclaim after a long delay when enumerating // thus there is no need to make sure ED is not in HC's cahed as it will not for sure void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // TODO OHCI (void) rhport; // addr0 serves as static head --> only set skip bit if (dev_addr == 0) { ohci_ed_t* ed = ed_control(0); ed->w0.skip = 1; } else { ed_list_remove_by_addr(p_ed_head[TUSB_XFER_CONTROL], dev_addr); // remove control ed_list_remove_by_addr(p_ed_head[TUSB_XFER_BULK], dev_addr); // remove bulk ed_list_remove_by_addr(p_ed_head[TUSB_XFER_INTERRUPT], dev_addr); // remove interrupt // TODO remove ISO } } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // List Helper //--------------------------------------------------------------------+ static inline tusb_xfer_type_t ed_get_xfer_type(ohci_ed_word0_t w0) { return (w0.ep_number == 0 ) ? TUSB_XFER_CONTROL : (w0.is_iso ) ? TUSB_XFER_ISOCHRONOUS : (w0.is_interrupt_xfer) ? TUSB_XFER_INTERRUPT : TUSB_XFER_BULK; } static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t ep_addr, uint8_t xfer_type, uint8_t interval) { (void) interval; // address 0 is used as async head, which always on the list --> cannot be cleared if (dev_addr != 0) { p_ed->td_tail = 0; p_ed->td_head.address = 0; p_ed->next = 0; } tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); ohci_ed_word0_t w0 = {.value = 0}; w0.dev_addr = dev_addr; w0.ep_number = ep_addr & 0x0F; w0.pid = (xfer_type == TUSB_XFER_CONTROL) ? PID_FROM_TD : (tu_edpt_dir(ep_addr) ? PID_IN : PID_OUT); w0.speed = bus_info.speed; w0.is_iso = (xfer_type == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; w0.max_packet_size = ep_size; w0.used = 1; w0.is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0); p_ed->w0 = w0; } static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes) { tu_memclr(p_td, sizeof(ohci_gtd_t)); p_td->used = 1; gtd_get_extra_data(p_td)->expected_bytes = total_bytes; p_td->buffer_rounding = 1; // less than queued length is not a error p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO; p_td->condition_code = OHCI_CCODE_NOT_ACCESSED; uint8_t *cbp = (uint8_t *) _phys_addr(data_ptr); p_td->current_buffer_pointer = cbp; if ( total_bytes ) { p_td->buffer_end = _phys_addr(data_ptr + total_bytes - 1); } else { p_td->buffer_end = cbp; } } static ohci_ed_t* ed_from_addr(uint8_t dev_addr, uint8_t ep_addr) { if (tu_edpt_number(ep_addr) == 0) { return ed_control(dev_addr); } ohci_ed_t* ed_pool = ohci_data.ed_pool; for (size_t i = 0; i < ED_MAX; i++) { ohci_ed_t* qhd = hcd_dcache_uncached(&ed_pool[i]); if ((qhd->w0.dev_addr == dev_addr) && ep_addr == tu_edpt_addr(qhd->w0.ep_number, qhd->w0.pid == PID_IN)) { return qhd; } } return NULL; } static ohci_ed_t* ed_find_free(void) { ohci_ed_t* ed_pool = ohci_data.ed_pool; for (size_t i = 0; i < ED_MAX; i++) { ohci_ed_t* qhd = hcd_dcache_uncached(&ed_pool[i]); if (!qhd->w0.used) { return qhd; } } return NULL; } static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed) { p_ed->next = p_pre->next; p_pre->next = (uint32_t) _phys_addr(p_ed); } static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr) { ohci_ed_t* p_prev = p_head; while (p_prev->next) { ohci_ed_t* ed = (ohci_ed_t*)_virt_addr((void*)p_prev->next); if (ed->w0.dev_addr == dev_addr) { // Prevent Host Controller from processing this ED while we remove it ed->w0.skip = 1; // unlink ed, will also move up p_prev p_prev->next = ed->next; // point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED ed->next = (uint32_t)_phys_addr(p_head); ed->w0.used = 0; ed->w0.skip = 0; } else { p_prev = (ohci_ed_t*)_virt_addr((void*)p_prev->next); } } } static ohci_gtd_t* gtd_find_free(void) { for (uint8_t i = 0; i < GTD_MAX; i++) { if (!ohci_data.gtd_pool[i].used) { return &ohci_data.gtd_pool[i]; } } return NULL; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const* ep_desc) { (void)rhport; // TODO iso support TU_ASSERT(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); //------------- Prepare Queue Head -------------// ohci_ed_t* p_ed; if (ep_desc->bEndpointAddress == 0) { p_ed = ed_control(dev_addr); } else { p_ed = ed_find_free(); } TU_ASSERT(p_ed); ed_init(p_ed, dev_addr, tu_edpt_packet_size(ep_desc), ep_desc->bEndpointAddress, ep_desc->bmAttributes.xfer, ep_desc->bInterval); // control of dev0 is used as static async head if (dev_addr == 0) { p_ed->w0.skip = 0; // only need to clear skip bit return true; } if (tu_edpt_number(ep_desc->bEndpointAddress) != 0) { // Get an empty TD and use it as the end-of-list marker. // This marker TD will be used when a transfer is made on this EP // (and a new, empty TD will be allocated for the next-next transfer). ohci_gtd_t* gtd = gtd_find_free(); TU_ASSERT(gtd); p_ed->td_head.address = (uint32_t)_phys_addr(gtd); p_ed->td_tail = (uint32_t)_phys_addr(gtd); } ed_list_insert(p_ed_head[ep_desc->bmAttributes.xfer], p_ed); return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; ohci_ed_t* ed = ed_control(dev_addr); ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd; hcd_dcache_clean(setup_packet, 8); gtd_init(qtd, (uint8_t*)(uintptr_t) setup_packet, 8); qtd->index = dev_addr; qtd->pid = PID_SETUP; qtd->data_toggle = GTD_DT_DATA0; qtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; hcd_dcache_clean(qtd, sizeof(ohci_gtd_t)); //------------- Attach TDs list to Control Endpoint -------------// ed->td_head.address = (uint32_t) _phys_addr(qtd); OHCI_REG->command_status_bit.control_list_filled = 1; return true; } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); // IN transfer: invalidate buffer, OUT transfer: clean buffer if (dir) { hcd_dcache_invalidate(buffer, buflen); } else { hcd_dcache_clean(buffer, buflen); } ohci_ed_t * ed = ed_from_addr(dev_addr, ep_addr); TU_ASSERT(ed); if (epnum == 0) { ohci_gtd_t* gtd = &ohci_data.control[dev_addr].gtd; gtd_init(gtd, buffer, buflen); gtd->index = dev_addr; gtd->pid = dir ? PID_IN : PID_OUT; gtd->data_toggle = GTD_DT_DATA1; // Both Data and Ack stage start with DATA1 gtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; hcd_dcache_clean(gtd, sizeof(ohci_gtd_t)); ed->td_head.address = (uint32_t)_phys_addr(gtd); OHCI_REG->command_status_bit.control_list_filled = 1; } else { tusb_xfer_type_t xfer_type = ed_get_xfer_type(ed->w0); ohci_gtd_t* gtd = (ohci_gtd_t*)_virt_addr((void*)ed->td_tail); gtd_init(gtd, buffer, buflen); gtd->index = ed-ohci_data.ed_pool; gtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES; // Insert a new, empty TD at the tail, to be used by the next transfer ohci_gtd_t* new_gtd = gtd_find_free(); TU_ASSERT(new_gtd); gtd->next = (uint32_t)_phys_addr(new_gtd); hcd_dcache_clean(gtd, sizeof(ohci_gtd_t)); ed->td_tail = (uint32_t)_phys_addr(new_gtd); if (TUSB_XFER_BULK == xfer_type) { OHCI_REG->command_status_bit.bulk_list_filled = 1; } } return true; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; // TODO not implemented yet return false; } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); TU_ASSERT(p_ed); ohci_ed_word2_t td_head = p_ed->td_head; td_head.toggle = 0; // reset data toggle td_head.halted = 0; p_ed->td_head = td_head; if (TUSB_XFER_BULK == ed_get_xfer_type(p_ed->w0)) { OHCI_REG->command_status_bit.bulk_list_filled = 1; } return true; } //--------------------------------------------------------------------+ // OHCI Interrupt Handler //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool is_itd(ohci_td_item_t* item) { (void) item; return false; // ISO not supported yet } static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head) { ohci_td_item_t* td_reverse_head = NULL; while(td_head != NULL) { td_head = _virt_addr(td_head); const uint32_t item_size = is_itd(td_head) ? sizeof(ohci_itd_t) : sizeof(ohci_gtd_t); hcd_dcache_invalidate(td_head, item_size); const uint32_t next = td_head->next; // make current's item become reverse's first item td_head->next = (uint32_t) td_reverse_head; td_reverse_head = _phys_addr(td_head); td_head = (ohci_td_item_t*) next; // advance to next item } return _virt_addr(td_reverse_head); } TU_ATTR_ALWAYS_INLINE static inline bool gtd_is_control(ohci_gtd_t const * const p_qtd) { return ((uint32_t) p_qtd) < ((uint32_t) ohci_data.gtd_pool); // check ohci_data_t for memory layout } TU_ATTR_ALWAYS_INLINE static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const* const p_qtd) { ohci_ed_t* ed; if (gtd_is_control(p_qtd)) { ed = &ohci_data.control[p_qtd->index].ed; } else { ed = &ohci_data.ed_pool[p_qtd->index]; } return hcd_dcache_uncached(ed); } static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd) { if (gtd_is_control(gtd)) { uint8_t idx = ((uintptr_t)gtd - (uintptr_t)&ohci_data.control->gtd) / sizeof(ohci_data.control[0]); return &ohci_data.gtd_extra_control[idx]; }else { return &ohci_data.gtd_extra[gtd - ohci_data.gtd_pool]; } } TU_ATTR_ALWAYS_INLINE static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer) { // 5.2.9 OHCI sample code // CBP is 0 mean all data is transferred if (current_buffer == 0) { return 0; } return (tu_align4k(buffer_end ^ current_buffer) ? 0x1000 : 0) + tu_offset4k(buffer_end) - tu_offset4k(current_buffer) + 1; } static void done_queue_isr(uint8_t hostid) { (void)hostid; // done head is written in reversed order of completion --> need to reverse the done queue first ohci_td_item_t* td_head = list_reverse((ohci_td_item_t*)tu_align16(ohci_data.hcca.done_head)); ohci_data.hcca.done_head = 0; while (td_head != NULL) { // TODO check if td_head is iso td //------------- Non ISO transfer -------------// ohci_gtd_t* const qtd = (ohci_gtd_t*) td_head; xfer_result_t const event = (qtd->condition_code == OHCI_CCODE_NO_ERROR) ? XFER_RESULT_SUCCESS : (qtd->condition_code == OHCI_CCODE_STALL) ? XFER_RESULT_STALLED : XFER_RESULT_FAILED; qtd->used = 0; // free TD if ((qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS)) { const ohci_ed_t* ed = gtd_get_ed(qtd); const ohci_ed_word0_t ed_w0 = ed->w0; const uint32_t xferred_bytes = gtd_get_extra_data(qtd)->expected_bytes - gtd_xfer_byte_left((uint32_t)qtd->buffer_end, (uint32_t)qtd->current_buffer_pointer); uint8_t dir = (ed_w0.ep_number == 0) ? (qtd->pid == PID_IN) : (ed_w0.pid == PID_IN); const uint8_t ep_addr = tu_edpt_addr(ed_w0.ep_number, dir); hcd_event_xfer_complete(ed_w0.dev_addr, ep_addr, xferred_bytes, event, true); } td_head = (ohci_td_item_t*)_virt_addr((void*)td_head->next); } } void hcd_int_handler(uint8_t hostid, bool in_isr) { (void)in_isr; uint32_t const int_en = OHCI_REG->interrupt_enable; uint32_t const int_status = OHCI_REG->interrupt_status & int_en; if (int_status == 0) { return; } // Disable MIE as per OHCI spec 5.3 OHCI_REG->interrupt_disable = OHCI_INT_MASTER_ENABLE_MASK; // Frame number overflow if (int_status & OHCI_INT_FRAME_OVERFLOW_MASK) { ohci_data.frame_number_hi++; } //------------- RootHub status -------------// if (int_status & OHCI_INT_RHPORT_STATUS_CHANGE_MASK) { for (int i = 0; i < TUP_OHCI_RHPORTS; i++) { uint32_t const rhport_status = OHCI_REG->rhport_status[i] & RHPORT_ALL_CHANGE_MASK; if (rhport_status & RHPORT_CONNECT_STATUS_CHANGE_MASK) { // TODO check if remote wake-up if (OHCI_REG->rhport_status_bit[i].current_connect_status) { // TODO reset port immediately, without this controller will got 2-3 (debouncing connection status change) OHCI_REG->rhport_status[i] = RHPORT_PORT_RESET_STATUS_MASK; hcd_event_device_attach(i, true); } else { hcd_event_device_remove(i, true); } } if (rhport_status & RHPORT_PORT_SUSPEND_CHANGE_MASK) { } OHCI_REG->rhport_status[i] = rhport_status; // acknowledge all interrupt } } //------------- Transfer Complete -------------// if (int_status & OHCI_INT_WRITEBACK_DONEHEAD_MASK) { done_queue_isr(hostid); } OHCI_REG->interrupt_status = int_status; // Acknowledge handled interrupt OHCI_REG->interrupt_enable = OHCI_INT_MASTER_ENABLE_MASK; // Enable MIE } //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ #endif ================================================ FILE: src/portable/ohci/ohci.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OHCI_H_ #define TUSB_OHCI_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // OHCI CONFIGURATION & CONSTANTS //--------------------------------------------------------------------+ #define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enabled #define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) // TODO merge OHCI with EHCI enum { OHCI_MAX_ITD = 4 }; #define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX) #define GTD_MAX ED_MAX // tinyUSB's OHCI implementation caps number of EDs to 8 bits TU_VERIFY_STATIC (ED_MAX <= 256, "Reduce CFG_TUH_DEVICE_MAX or CFG_TUH_ENDPOINT_MAX"); #define GTD_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16) #define ED_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 16) #define ITD_ALIGN_SIZE TU_MAX(CFG_TUH_MEM_DCACHE_LINE_SIZE, 32) //--------------------------------------------------------------------+ // OHCI Data Structure //--------------------------------------------------------------------+ typedef struct { uint32_t interrupt_table[32]; volatile uint16_t frame_number; volatile uint16_t frame_pad; volatile uint32_t done_head; uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256 }ohci_hcca_t; // TU_ATTR_ALIGNED(256) TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" ); // An OHCI host controller is controlled using data structures placed in memory (RAM). // It needs to both read and write these data structures (as defined by the OHCI specification), // and this can be mentally conceptualized similar to two software threads running on // two different CPUs. In order to prevent a _data race_ where data gets corrupted, // the CPU and the OHCI host controller need to agree on how the memory should be accessed. // In this driver, we do this by transferring logical ownership of transfer descriptors (TDs) // between the CPU and the OHCI host controller. Only the device which holds the logical ownership // is allowed to read or write the TD. This ownership is not visible anywhere in the code, // but it instead must be inferred based on the logical state of the transfer. // // If dcache-supporting mode is enabled, we need to do additional manual cache operations // in order to correctly transfer this logical ownership and prevent data corruption. // In order to do this, we also choose to align each OHCI TD so that it doesn't // share CPU cache lines with other TDs. This is because manual cache operations // can only be performed on cache line granularity. In other words, one cache line is // the _smallest_ amount that can be read/written at a time. If there were to be multiple TDs // in the same cache line, they would be required to always have the same logical ownership. // This ends up being impossible to guarantee, so we choose a design which avoids the situation entirely. // common link item for gtd and itd for list travel typedef struct TU_ATTR_ALIGNED(16) { uint32_t reserved[2]; volatile uint32_t next; uint32_t reserved2; }ohci_td_item_t; typedef struct TU_ATTR_ALIGNED(GTD_ALIGN_SIZE) { // Word 0 uint32_t used : 1; uint32_t index : 8; // endpoint index the gtd belongs to, or device address in case of control xfer uint32_t : 9; // can be used uint32_t buffer_rounding : 1; uint32_t pid : 2; uint32_t delay_interrupt : 3; volatile uint32_t data_toggle : 2; volatile uint32_t error_count : 2; volatile uint32_t condition_code : 4; // Word 1 uint8_t* volatile current_buffer_pointer; // Word 2 : next TD volatile uint32_t next; // Word 3 uint8_t* buffer_end; } ohci_gtd_t; TU_VERIFY_STATIC(sizeof(ohci_gtd_t) == GTD_ALIGN_SIZE, "size is not correct" ); typedef union { struct { uint32_t dev_addr : 7; uint32_t ep_number : 4; uint32_t pid : 2; uint32_t speed : 1; uint32_t skip : 1; uint32_t is_iso : 1; uint32_t max_packet_size : 11; // HCD: make use of 5 reserved bits uint32_t used : 1; uint32_t is_interrupt_xfer : 1; uint32_t : 3; }; uint32_t value; } ohci_ed_word0_t; TU_VERIFY_STATIC(sizeof(ohci_ed_word0_t) == 4, "size is not correct" ); typedef union { uint32_t address; struct { uint32_t halted : 1; uint32_t toggle : 1; uint32_t : 30; }; } ohci_ed_word2_t; TU_VERIFY_STATIC(sizeof(ohci_ed_word2_t) == 4, "size is not correct" ); typedef struct TU_ATTR_ALIGNED(ED_ALIGN_SIZE) { ohci_ed_word0_t w0; // Word 0 uint32_t td_tail; // Word 1 volatile ohci_ed_word2_t td_head; // Word 2 uint32_t next; // Word 3 } ohci_ed_t; TU_VERIFY_STATIC(sizeof(ohci_ed_t) == ED_ALIGN_SIZE, "size is not correct" ); typedef struct TU_ATTR_ALIGNED(ITD_ALIGN_SIZE) { /*---------- Word 1 ----------*/ uint32_t starting_frame : 16; uint32_t : 5; // can be used uint32_t delay_interrupt : 3; uint32_t frame_count : 3; uint32_t : 1; // can be used volatile uint32_t condition_code : 4; /*---------- Word 2 ----------*/ uint32_t buffer_page0; // 12 lsb bits can be used /*---------- Word 3 ----------*/ volatile uint32_t next; /*---------- Word 4 ----------*/ uint32_t buffer_end; /*---------- Word 5-8 ----------*/ volatile uint16_t offset_packetstatus[8]; } ohci_itd_t; TU_VERIFY_STATIC(sizeof(ohci_itd_t) == ITD_ALIGN_SIZE, "size is not correct" ); typedef struct { uint16_t expected_bytes; // up to 8192 bytes so max is 13 bits } gtd_extra_data_t; TU_VERIFY_STATIC(sizeof(gtd_extra_data_t) == 2, "size is not correct" ); // structure with member alignment required from large to small typedef struct TU_ATTR_ALIGNED(256) { ohci_hcca_t hcca; ohci_ed_t bulk_head_ed; // static bulk head (dummy) ohci_ed_t period_head_ed; // static periodic list head (dummy) // control endpoints has reserved resources struct { ohci_ed_t ed; ohci_gtd_t gtd; } control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1]; // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 ohci_ed_t ed_pool[ED_MAX]; ohci_gtd_t gtd_pool[GTD_MAX]; // extra data needed by TDs that can't fit in the TD struct gtd_extra_data_t gtd_extra_control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1]; gtd_extra_data_t gtd_extra[GTD_MAX]; volatile uint16_t frame_number_hi; } ohci_data_t; //--------------------------------------------------------------------+ // OHCI Operational Register //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ // OHCI Data Organization //--------------------------------------------------------------------+ typedef volatile struct { uint32_t revision; // 0x00 union { uint32_t control; // 0x04 struct { uint32_t control_bulk_service_ratio : 2; uint32_t periodic_list_enable : 1; uint32_t isochronous_enable : 1; uint32_t control_list_enable : 1; uint32_t bulk_list_enable : 1; uint32_t hc_functional_state : 2; uint32_t interrupt_routing : 1; uint32_t remote_wakeup_connected : 1; uint32_t remote_wakeup_enale : 1; uint32_t TU_RESERVED : 21; }control_bit; }; union { uint32_t command_status; // 0x08 struct { uint32_t controller_reset : 1; uint32_t control_list_filled : 1; uint32_t bulk_list_filled : 1; uint32_t ownership_change_request : 1; uint32_t : 12; uint32_t scheduling_overrun_count : 2; }command_status_bit; }; uint32_t interrupt_status; // 0x0C uint32_t interrupt_enable; // 0x10 uint32_t interrupt_disable; // 0x14 uint32_t hcca; // 0x18 uint32_t period_current_ed; // 0x1C uint32_t control_head_ed; // 0x20 uint32_t control_current_ed; // 0x24 uint32_t bulk_head_ed; // 0x28 uint32_t bulk_current_ed; // 0x2C uint32_t done_head; // 0x30 uint32_t frame_interval; // 0x34 uint32_t frame_remaining; // 0x38 uint32_t frame_number; // 0x3C uint32_t periodic_start; // 0x40 uint32_t lowspeed_threshold; // 0x44 union { uint32_t rh_descriptorA; // 0x48 struct { uint32_t number_downstream_ports : 8; uint32_t power_switching_mode : 1; uint32_t no_power_switching : 1; uint32_t device_type : 1; uint32_t overcurrent_protection_mode : 1; uint32_t no_over_current_protection : 1; uint32_t reserved : 11; uint32_t power_on_to_good_time : 8; } rh_descriptorA_bit; }; union { uint32_t rh_descriptorB; // 0x4C struct { uint32_t device_removable : 16; uint32_t port_power_control_mask : 16; } rh_descriptorB_bit; }; union { uint32_t rh_status; // 0x50 struct { uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power uint32_t over_current_indicator : 1; uint32_t : 13; uint32_t device_remote_wakeup_enable : 1; uint32_t local_power_status_change : 1; uint32_t over_current_indicator_change : 1; uint32_t : 13; uint32_t clear_remote_wakeup_enable : 1; }rh_status_bit; }; union { uint32_t rhport_status[TUP_OHCI_RHPORTS]; // 0x54 struct { uint32_t current_connect_status : 1; uint32_t port_enable_status : 1; uint32_t port_suspend_status : 1; uint32_t port_over_current_indicator : 1; uint32_t port_reset_status : 1; uint32_t : 3; uint32_t port_power_status : 1; uint32_t low_speed_device_attached : 1; uint32_t : 6; uint32_t connect_status_change : 1; uint32_t port_enable_status_change : 1; uint32_t port_suspend_status_change : 1; uint32_t port_over_current_indicator_change : 1; uint32_t port_reset_status_change : 1; uint32_t TU_RESERVED : 11; }rhport_status_bit[TUP_OHCI_RHPORTS]; }; }ohci_registers_t; TU_VERIFY_STATIC( sizeof(ohci_registers_t) == (0x54 + (4 * TUP_OHCI_RHPORTS)), "size is not correct"); #ifdef __cplusplus } #endif #endif /* TUSB_OHCI_H_ */ ================================================ FILE: src/portable/ohci/ohci_nxp.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_OHCI_NXP_H #define TUSB_OHCI_NXP_H #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #include "chip.h" #define OHCI_REG ((ohci_registers_t *) LPC_USB_BASE) void hcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB_IRQn); } void hcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB_IRQn); } static void ohci_phy_init(uint8_t rhport) { (void) rhport; } #else #include "fsl_device_registers.h" // for LPC55 USB0 controller #define OHCI_REG ((ohci_registers_t *) USBFSH_BASE) static void ohci_phy_init(uint8_t rhport) { (void) rhport; } void hcd_int_enable(uint8_t rhport) { (void)rhport; NVIC_EnableIRQ(USB0_IRQn); } void hcd_int_disable(uint8_t rhport) { (void)rhport; NVIC_DisableIRQ(USB0_IRQn); } #endif #endif ================================================ FILE: src/portable/raspberrypi/pio_usb/dcd_pio_usb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUD_RPI_PIO_USB #include "pico.h" #include "pio_usb.h" #include "pio_usb_ll.h" #include "device/dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #define RHPORT_OFFSET 1 #define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) //------------- -------------// static usb_device_t *usb_device = NULL; static usb_descriptor_buffers_t desc; /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; usb_device = pio_usb_device_init(&config, &desc); return true; } // Enable device interrupt void dcd_int_enable (uint8_t rhport) { (void) rhport; } // Disable device interrupt void dcd_int_disable (uint8_t rhport) { (void) rhport; } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { // must be called before queuing status pio_usb_device_set_address(dev_addr); dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); } // Wake up host void dcd_remote_wakeup (uint8_t rhport) { (void) rhport; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void) rhport; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void) rhport; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { (void) rhport; return pio_usb_device_endpoint_open((uint8_t const*) desc_ep); } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); return pio_usb_ll_transfer_start(ep, buffer, total_bytes); } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c //bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) //{ // (void) rhport; // (void) ep_addr; // (void) ff; // (void) total_bytes; // return false; //} // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); ep->has_transfer = false; ep->stalled = true; } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr); ep->data_id = 0; ep->stalled = false; } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ static void __no_inline_not_in_flash_func(handle_endpoint_irq)(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t* ep_reg) { const uint32_t ep_all = *ep_reg; for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) { uint32_t const mask = (1u << ep_idx); if (ep_all & mask) { endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx); dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true); } } // clear all (*ep_reg) &= ~ep_all; } // IRQ Handler void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) { uint8_t const tu_rhport = root_id + 1; root_port_t* rport = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = rport->ints; if (ints & PIO_USB_INTS_RESET_END_BITS) { dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true); } if (ints & PIO_USB_INTS_SETUP_REQ_BITS) { dcd_event_setup_received(tu_rhport, rport->setup_packet, true); } if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { handle_endpoint_irq(tu_rhport, XFER_RESULT_SUCCESS, &rport->ep_complete); } if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { handle_endpoint_irq(tu_rhport, XFER_RESULT_STALLED, &rport->ep_stalled); } if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) { handle_endpoint_irq(tu_rhport, XFER_RESULT_FAILED, &rport->ep_error); } // clear all rport->ints &= ~ints; } #endif ================================================ FILE: src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO_USB #include "pico.h" #include "pio_usb.h" #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #endif #include "pio_usb_ll.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "osal/osal.h" #include "host/hcd.h" #include "host/usbh.h" #define RHPORT_OFFSET 1 #define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET) static pio_usb_configuration_t pio_host_cfg = PIO_USB_DEFAULT_CONFIG; //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUH_CFGID_RPI_PIO_USB_CONFIGURATION); memcpy(&pio_host_cfg, cfg_param, sizeof(pio_usb_configuration_t)); return true; } bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; // To run USB SOF interrupt in core1, call this init in core1 pio_usb_host_init(&pio_host_cfg); return true; } void hcd_port_reset(uint8_t rhport) { uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_port_reset_start(pio_rhport); } void hcd_port_reset_end(uint8_t rhport) { uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_port_reset_end(pio_rhport); } bool hcd_port_connect_status(uint8_t rhport) { uint8_t const pio_rhport = RHPORT_PIO(rhport); root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport); port_pin_status_t line_state = pio_usb_bus_get_line_state(root); return line_state != PORT_PIN_SE0; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { // TODO determine link speed uint8_t const pio_rhport = RHPORT_PIO(rhport); return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW; } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { uint8_t const pio_rhport = RHPORT_PIO(rhport); pio_usb_host_close_device(pio_rhport, dev_addr); } uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return pio_usb_host_get_frame_number(); } void hcd_int_enable(uint8_t rhport) { (void) rhport; } void hcd_int_disable(uint8_t rhport) { (void) rhport; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *desc_ep) { tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); bool const need_pre = (bus_info.hub_addr && bus_info.speed == TUSB_SPEED_LOW); uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const *) desc_ep, need_pre); } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_close(pio_rhport, daddr, ep_addr); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen); } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_endpoint_abort_transfer(pio_rhport, dev_addr, ep_addr); } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { uint8_t const pio_rhport = RHPORT_PIO(rhport); return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet); } //bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) //{ // // EPX is shared, so multiple device addresses and endpoint addresses share that // // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own // // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint // // on that device // pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\r\n", dev_addr, ep_addr); // struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); // assert(ep); // bool busy = ep->active; // pico_trace("busy == %d\r\n", busy); // return busy; //} bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; return true; } static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t *rport, xfer_result_t result, volatile uint32_t *ep_reg) { (void) rport; const uint32_t ep_all = *ep_reg; for ( uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++ ) { uint32_t const mask = (1u << ep_idx); if ( ep_all & mask ) { endpoint_t * ep = PIO_USB_ENDPOINT(ep_idx); hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true); } } // clear all (*ep_reg) &= ~ep_all; } // IRQ Handler void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { uint8_t const tu_rhport = root_id + 1; root_port_t *rport = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = rport->ints; if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); } if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS ) { handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled); } if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS ) { handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); } if ( ints & PIO_USB_INTS_CONNECT_BITS ) { hcd_event_device_attach(tu_rhport, true); } if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { hcd_event_device_remove(tu_rhport, true); } // clear all rport->ints &= ~ints; } #endif ================================================ FILE: src/portable/raspberrypi/rp2040/dcd_rp2040.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB #include "pico.h" #include "hardware/sync.h" #include "rp2040_usb.h" #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX #include "pico/fix/rp2040_usb_device_enumeration.h" #endif #include "device/dcd.h" // Current implementation force vbus detection as always present, causing device think it is always plugged into host. // Therefore, it cannot detect disconnect event, mistaken it as suspend. // Note: won't work if change to 0 (for now) #define FORCE_VBUS_DETECT 1 #define USB_INTS_ERROR_BITS \ (USB_INTS_ERROR_DATA_SEQ_BITS | USB_INTS_ERROR_BIT_STUFF_BITS | USB_INTS_ERROR_CRC_BITS | \ USB_INTS_ERROR_RX_OVERFLOW_BITS | USB_INTS_ERROR_RX_TIMEOUT_BITS) /*------------------------------------------------------------------*/ /* Low level controller *------------------------------------------------------------------*/ // HW buffer pointer from USB buffer space (max 3840 bytes) static uint8_t *hw_buffer_ptr; // USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in. static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; // SOF may be used by remote wakeup as RESUME, this indicates whether SOF is actually used by usbd static bool _sof_enable = false; TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get(uint8_t epnum, tusb_dir_t dir) { return &hw_endpoints[epnum][dir]; } TU_ATTR_ALWAYS_INLINE static inline hw_endpoint_t *hw_endpoint_get_by_addr(uint8_t ep_addr) { const uint8_t num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); return hw_endpoint_get(num, dir); } // main processing for dcd_edpt_iso_activate static void hw_endpoint_init(hw_endpoint_t *ep, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { ep->ep_addr = ep_addr; ep->next_pid = 0u; ep->wMaxPacketSize = wMaxPacketSize; // Clear existing buffer control state io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); *buf_ctrl_reg = 0; // allocated hw buffer const uint8_t epnum = tu_edpt_number(ep_addr); if (epnum == 0) { // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; } else { // round up size to multiple of 64 uint16_t size = (uint16_t)tu_round_up(wMaxPacketSize, 64); // double buffered Bulk endpoint if (transfer_type == TUSB_XFER_BULK) { size *= 2u; #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { ep->e15_bulk_in = true; } #endif } // assign buffer ep->hw_data_buf = hw_buffer_ptr; hw_buffer_ptr += size; hard_assert(hw_buffer_ptr < usb_dpram->epx_data + sizeof(usb_dpram->epx_data)); pico_info(" Allocated %d bytes (0x%p)\r\n", size, ep->hw_data_buf); } } static void hw_endpoint_enable(hw_endpoint_t *ep, uint8_t transfer_type) { io_rw_32 *ctrl_reg = hwep_ctrl_reg_device(ep); // Set endpoint control register to enable (EP0 has no endpoint control register) if (ctrl_reg != NULL) { const uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | hw_data_offset(ep->hw_data_buf); *ctrl_reg = ctrl_value; } } // Init and enable endpoint static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { const uint8_t epnum = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); hw_endpoint_init(ep, ep_addr, wMaxPacketSize, transfer_type); hw_endpoint_enable(ep, transfer_type); } static void hw_endpoint_abort_xfer(struct hw_endpoint* ep) { // Abort any pending transfer const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); const uint8_t epnum = tu_edpt_number(ep->ep_addr); const uint32_t abort_mask = TU_BIT((epnum << 1) | (dir ? 0 : 1)); // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. if (rp2040_chip_version() >= 2) { usb_hw_set->abort = abort_mask; while ((usb_hw->abort_done & abort_mask) != abort_mask) {} } uint32_t buf_ctrl = USB_BUF_CTRL_SEL; // reset to buffer 0 if (ep->next_pid) { buf_ctrl |= USB_BUF_CTRL_DATA1_PID; } io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl); hw_endpoint_reset_transfer(ep); if (rp2040_chip_version() >= 2) { usb_hw_clear->abort_done = abort_mask; usb_hw_clear->abort = abort_mask; } } static void __tusb_irq_path_func(handle_hw_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); uint bit = 1u; for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) { if (remaining_buffers & bit) { // clear this in advance usb_hw_clear->buf_status = bit; // IN transfer for even i, OUT transfer for odd i const uint8_t epnum = i >> 1u; const tusb_dir_t dir = (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN; hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); const bool done = hw_endpoint_xfer_continue(ep); if (done) { // Notify usbd const uint16_t xferred_len = ep->xferred_len; hw_endpoint_reset_transfer(ep); dcd_event_xfer_complete(0, ep->ep_addr, xferred_len, XFER_RESULT_SUCCESS, true); } remaining_buffers &= ~bit; } bit <<= 1u; } } TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) { // If we have finished this transfer on EP0 set pid back to 1 for next // setup transfer. Also clear a stall in case for (uint8_t dir = 0; dir < 2; dir++) { struct hw_endpoint *ep = hw_endpoint_get(0, dir); ep->next_pid = 1u; if (ep->active) { hw_endpoint_abort_xfer(ep); // Abort any pending transfer per USB specs } } } static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { // Disable all non-control for (uint8_t i = 0; i < USB_MAX_ENDPOINTS - 1; i++) { usb_dpram->ep_ctrl[i].in = 0; usb_dpram->ep_ctrl[i].out = 0; } // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2 * sizeof(hw_endpoint_t)); // reclaim buffer space hw_buffer_ptr = &usb_dpram->epx_data[0]; } static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { const uint32_t status = usb_hw->ints; uint32_t handled = 0; if (status & USB_INTF_DEV_SOF_BITS) { bool keep_sof_alive = false; handled |= USB_INTF_DEV_SOF_BITS; #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX // Errata 15 workaround for Device Bulk-In endpoint e15_last_sof = time_us_32(); for (uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++) { struct hw_endpoint *ep = hw_endpoint_get(i, TUSB_DIR_IN); // Active Bulk IN endpoint requires SOF if (ep->e15_bulk_in && ep->active) { keep_sof_alive = true; hw_endpoint_lock_update(ep, 1); if (ep->pending) { ep->pending = 0; hw_endpoint_start_next_buffer(ep); } hw_endpoint_lock_update(ep, -1); } } #endif // disable SOF interrupt if it is used for RESUME in remote wakeup if (!keep_sof_alive && !_sof_enable) { usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; } dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); } // xfer events are handled before setup req. So if a transfer completes immediately // before closing the EP, the events will be delivered in same order. if (status & USB_INTS_BUFF_STATUS_BITS) { handled |= USB_INTS_BUFF_STATUS_BITS; handle_hw_buff_status(); } if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; uint8_t const* setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); // reset pid to both 1 (data and ack) reset_ep0(); // Pass setup packet to tiny usb dcd_event_setup_received(0, setup, true); usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS; } #if FORCE_VBUS_DETECT == 0 // Since we force VBUS detect On, device will always think it is connected and // couldn't distinguish between disconnect and suspend if (status & USB_INTS_DEV_CONN_DIS_BITS) { handled |= USB_INTS_DEV_CONN_DIS_BITS; if (usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS) { // Connected: nothing to do } else { // Disconnected dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); } usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS; } #endif // SE0 for 2.5 us or more (will last at least 10ms) if (status & USB_INTS_BUS_RESET_BITS) { pico_trace("BUS RESET\r\n"); handled |= USB_INTS_BUS_RESET_BITS; usb_hw->dev_addr_ctrl = 0; reset_non_control_endpoints(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS; #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX // Only run enumeration workaround if pull up is enabled if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) { rp2040_usb_device_enumeration_fix(); } #endif } /* Note from pico datasheet 4.1.2.6.4 (v1.2) * If you enable the suspend interrupt, it is likely you will see a suspend interrupt when * the device is first connected but the bus is idle. The bus can be idle for a few ms before * the host begins sending start of frame packets. You will also see a suspend interrupt * when the device is disconnected if you do not have a VBUS detect circuit connected. This is * because without VBUS detection, it is impossible to tell the difference between * being disconnected and suspended. */ if (status & USB_INTS_DEV_SUSPEND_BITS) { handled |= USB_INTS_DEV_SUSPEND_BITS; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS; } if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) { handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS; } if (status ^ handled) { panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); } } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ // older SDK #ifndef PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; assert(rhport == 0); TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); // Reset hardware to default state rp2usb_init(); #if FORCE_VBUS_DETECT // Force VBUS detect so the device thinks it is plugged into a host usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; #endif irq_add_shared_handler(USBCTRL_IRQ, dcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // Init control endpoints tu_memclr(hw_endpoints[0], 2 * sizeof(hw_endpoint_t)); hw_endpoint_open(0x0, 64, TUSB_XFER_CONTROL); hw_endpoint_open(0x80, 64, TUSB_XFER_CONTROL); // Init non-control endpoints reset_non_control_endpoints(); // Initializes the USB peripheral for device mode and enables it. // Don't need to enable the pull up here. Force VBUS usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS; // Enable individual controller IRQS here. Processor interrupt enable will be used // for the global interrupt enable... // Note: Force VBUS detect cause disconnection not detectable usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); dcd_connect(rhport); return true; } bool dcd_deinit(uint8_t rhport) { (void) rhport; reset_non_control_endpoints(); irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); // reset usb hardware into initial state reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); return true; } void dcd_int_enable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, true); } void dcd_int_disable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, false); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; // Can't set device address in hardware until status xfer has complete // Send 0len complete response on EP0 IN dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); } void dcd_remote_wakeup(__unused uint8_t rhport) { pico_info("dcd_remote_wakeup %d\n", rhport); assert(rhport == 0); // since RESUME interrupt is not triggered if we are the one initiate // briefly enable SOF to notify usbd when bus is ready usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; usb_hw_set->sie_ctrl = USB_SIE_CTRL_RESUME_BITS; } // disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(__unused uint8_t rhport) { (void) rhport; usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } // connect by enabling internal pull-up resistor on D+/D- void dcd_connect(__unused uint8_t rhport) { (void) rhport; usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; _sof_enable = en; if (en) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; } #if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX else { // Don't clear immediately if the SOF workaround is in use. // The SOF handler will conditionally disable the interrupt. usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; } #endif } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { usb_hw->dev_addr_ctrl = (uint8_t) request->wValue; } } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; const uint8_t xfer_type = desc_edpt->bmAttributes.xfer; hw_endpoint_open(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), xfer_type); return true; } // New API: Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); hw_endpoint_init(ep, ep_addr, largest_packet_size, TUSB_XFER_ISOCHRONOUS); return true; } // New API: Configure and enable an ISO endpoint according to descriptor bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_desc->bEndpointAddress); const tusb_dir_t dir = tu_edpt_dir(ep_desc->bEndpointAddress); struct hw_endpoint *ep = hw_endpoint_get(epnum, dir); TU_ASSERT(ep->hw_data_buf != NULL); // must be inited and allocated previously if (ep->active) { hw_endpoint_abort_xfer(ep); // abort any pending transfer } ep->wMaxPacketSize = ep_desc->wMaxPacketSize; hw_endpoint_enable(ep, TUSB_XFER_ISOCHRONOUS); return true; } void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; // may need to use EP Abort reset_non_control_endpoints(); } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { (void)rhport; (void)is_isr; hw_endpoint_t *ep = hw_endpoint_get_by_addr(ep_addr); hw_endpoint_xfer_start(ep, buffer, NULL, total_bytes); return true; } #if CFG_TUD_EDPT_DEDICATED_HWFIFO bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { (void)rhport; (void)is_isr; hw_endpoint_t *ep = hw_endpoint_get_by_addr(ep_addr); hw_endpoint_xfer_start(ep, NULL, ff, total_bytes); return true; } #endif void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t epnum = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); hw_endpoint_t *ep = hw_endpoint_get(epnum, dir); if (epnum == 0) { // A stall on EP0 has to be armed so it can be cleared on the next setup packet usb_hw_set->ep_stall_arm = (dir == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS; } // stall and clear current pending buffer, may need to use EP_ABORT io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); hwbuf_ctrl_set(buf_ctrl_reg, USB_BUF_CTRL_STALL); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if (tu_edpt_number(ep_addr)) { struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; io_rw_32 *buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); hwbuf_ctrl_clear_mask(buf_ctrl_reg, USB_BUF_CTRL_STALL); } } void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) { (void) rhport; dcd_rp2040_irq(); } #endif ================================================ FILE: src/portable/raspberrypi/rp2040/hcd_rp2040.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * Copyright (c) 2021 Ha Thach (tinyusb.org) for Double Buffered * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB && !CFG_TUH_MAX3421 #include "pico.h" #include "rp2040_usb.h" //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "osal/osal.h" #include "host/hcd.h" #include "host/usbh.h" // port 0 is native USB port, other is counted as software PIO #define RHPORT_NATIVE 0 //--------------------------------------------------------------------+ // Low level rp2040 controller functions //--------------------------------------------------------------------+ #ifndef PICO_USB_HOST_INTERRUPT_ENDPOINTS #define PICO_USB_HOST_INTERRUPT_ENDPOINTS (USB_MAX_ENDPOINTS - 1) #endif static_assert(PICO_USB_HOST_INTERRUPT_ENDPOINTS <= USB_MAX_ENDPOINTS, ""); // Host mode uses one shared endpoint register for non-interrupt endpoint static struct hw_endpoint ep_pool[1 + PICO_USB_HOST_INTERRUPT_ENDPOINTS]; #define epx (ep_pool[0]) // Flags we set by default in sie_ctrl (we add other bits on top) enum { SIE_CTRL_BASE = USB_SIE_CTRL_SOF_EN_BITS | USB_SIE_CTRL_KEEP_ALIVE_EN_BITS | USB_SIE_CTRL_PULLDOWN_EN_BITS | USB_SIE_CTRL_EP0_INT_1BUF_BITS }; static struct hw_endpoint *get_dev_ep(uint8_t dev_addr, uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); if (num == 0) { return &epx; } for (uint32_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) { struct hw_endpoint *ep = &ep_pool[i]; if (ep->configured && (ep->dev_addr == dev_addr) && (ep->ep_addr == ep_addr)) { return ep; } } return NULL; } TU_ATTR_ALWAYS_INLINE static inline uint8_t dev_speed(void) { return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB; } TU_ATTR_ALWAYS_INLINE static inline bool need_pre(uint8_t dev_addr) { // If this device is different to the speed of the root device // (i.e. is a low speed device on a full speed hub) then need pre return hcd_port_speed_get(0) != tuh_speed_get(dev_addr); } static void __tusb_irq_path_func(hw_xfer_complete)(struct hw_endpoint *ep, xfer_result_t xfer_result) { // Mark transfer as done before we tell the tinyusb stack uint8_t dev_addr = ep->dev_addr; uint8_t ep_addr = ep->ep_addr; uint xferred_len = ep->xferred_len; hw_endpoint_reset_transfer(ep); hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, xfer_result, true); } static void __tusb_irq_path_func(handle_hwbuf_status_bit)(uint bit, struct hw_endpoint *ep) { usb_hw_clear->buf_status = bit; const bool done = hw_endpoint_xfer_continue(ep); if (done) { hw_xfer_complete(ep, XFER_RESULT_SUCCESS); } } static void __tusb_irq_path_func(handle_hwbuf_status)(void) { uint32_t buf_status = usb_hw->buf_status; pico_trace("buf_status 0x%08lx\n", buf_status); // Check EPX first uint32_t bit = 1u; if (buf_status & bit) { buf_status &= ~bit; struct hw_endpoint * ep = &epx; handle_hwbuf_status_bit(bit, ep); } // Check "interrupt" (asynchronous) endpoints for both IN and OUT for (uint i = 1; i <= USB_HOST_INTERRUPT_ENDPOINTS && buf_status; i++) { // EPX is bit 0 & 1 // IEP1 IN is bit 2 // IEP1 OUT is bit 3 // IEP2 IN is bit 4 // IEP2 OUT is bit 5 // IEP3 IN is bit 6 // IEP3 OUT is bit 7 // etc for (uint j = 0; j < 2; j++) { bit = 1 << (i * 2 + j); if (buf_status & bit) { buf_status &= ~bit; handle_hwbuf_status_bit(bit, &ep_pool[i]); } } } if (buf_status) { panic("Unhandled buffer %d\n", buf_status); } } static void __tusb_irq_path_func(hw_trans_complete)(void) { if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) { pico_trace("Sent setup packet\n"); struct hw_endpoint *ep = &epx; assert(ep->active); // Set transferred length to 8 for a setup packet ep->xferred_len = 8; hw_xfer_complete(ep, XFER_RESULT_SUCCESS); } else { // Don't care. Will handle this in buff status return; } } static void __tusb_irq_path_func(hcd_rp2040_irq)(void) { uint32_t status = usb_hw->ints; uint32_t handled = 0; if ( status & USB_INTS_HOST_CONN_DIS_BITS ) { handled |= USB_INTS_HOST_CONN_DIS_BITS; if ( dev_speed() ) { hcd_event_device_attach(RHPORT_NATIVE, true); } else { hcd_event_device_remove(RHPORT_NATIVE, true); } // Clear speed change interrupt usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS; } if ( status & USB_INTS_STALL_BITS ) { // We have rx'd a stall from the device // NOTE THIS SHOULD HAVE PRIORITY OVER BUFF_STATUS // AND TRANS_COMPLETE as the stall is an alternative response // to one of those events pico_trace("Stall REC\n"); handled |= USB_INTS_STALL_BITS; usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS; hw_xfer_complete(&epx, XFER_RESULT_STALLED); } if ( status & USB_INTS_BUFF_STATUS_BITS ) { handled |= USB_INTS_BUFF_STATUS_BITS; TU_LOG(2, "Buffer complete\r\n"); handle_hwbuf_status(); } if ( status & USB_INTS_TRANS_COMPLETE_BITS ) { handled |= USB_INTS_TRANS_COMPLETE_BITS; usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS; TU_LOG(2, "Transfer complete\r\n"); hw_trans_complete(); } if ( status & USB_INTS_ERROR_RX_TIMEOUT_BITS ) { handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS; usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS; } if ( status & USB_INTS_ERROR_DATA_SEQ_BITS ) { usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS; TU_LOG(3, " Seq Error: [0] = 0x%04u [1] = 0x%04x\r\n", tu_u32_low16(*hwbuf_ctrl_reg_host(&epx)), tu_u32_high16(*hwbuf_ctrl_reg_host(&epx))); panic("Data Seq Error \n"); } if ( status ^ handled ) { panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); } } void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport, bool in_isr) { (void) rhport; (void) in_isr; hcd_rp2040_irq(); } static struct hw_endpoint *_next_free_interrupt_ep(void) { struct hw_endpoint * ep = NULL; for ( uint i = 1; i < TU_ARRAY_SIZE(ep_pool); i++ ) { ep = &ep_pool[i]; if ( !ep->configured ) { // Will be configured by hw_endpoint_init / hw_endpoint_allocate ep->interrupt_num = (uint8_t) (i - 1); return ep; } } return ep; } static hw_endpoint_t *hw_endpoint_allocate(uint8_t transfer_type) { hw_endpoint_t *ep = NULL; if (transfer_type == TUSB_XFER_CONTROL) { ep = &epx; ep->hw_data_buf = &usbh_dpram->epx_data[0]; } else { // Note: even though datasheet name these "Interrupt" endpoints. These are actually // "Asynchronous" endpoints and can be used for other type such as: Bulk (ISO need confirmation) ep = _next_free_interrupt_ep(); pico_info("Allocate %s ep %d\n", tu_edpt_type_str(transfer_type), ep->interrupt_num); assert(ep); // 0 for epx (double buffered): TODO increase to 1024 for ISO // 2x64 for intep0 // 3x64 for intep1 // etc ep->hw_data_buf = &usbh_dpram->epx_data[64 * (ep->interrupt_num + 2)]; } return ep; } static void hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type, uint8_t bmInterval) { // Already has data buffer, endpoint control, and buffer control allocated at this point assert(ep->hw_data_buf); uint8_t const num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); ep->ep_addr = ep_addr; ep->dev_addr = dev_addr; // Response to a setup packet on EP0 starts with pid of 1 ep->next_pid = (num == 0 ? 1u : 0u); ep->wMaxPacketSize = wMaxPacketSize; pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, transfer_type); pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf); uint dpram_offset = hw_data_offset(ep->hw_data_buf); // Bits 0-5 should be 0 assert(!(dpram_offset & 0b111111)); // Fill in endpoint control register with buffer offset uint32_t ctrl_value = EP_CTRL_ENABLE_BITS | EP_CTRL_INTERRUPT_PER_BUFFER | ((uint32_t)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; if (bmInterval) { ctrl_value |= (uint32_t)((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } io_rw_32 *ctrl_reg = hwep_ctrl_reg_host(ep); *ctrl_reg = ctrl_value; pico_trace("endpoint control (0x%p) <- 0x%lx\n", ctrl_reg, ctrl_value); ep->configured = true; if (ep != &epx) { // Endpoint has its own addr_endp and interrupt bits to be setup! // This is an interrupt/async endpoint. so need to set up ADDR_ENDP register with: // - device address // - endpoint number / direction // - preamble uint32_t reg = (uint32_t)(dev_addr | (num << USB_ADDR_ENDP1_ENDPOINT_LSB)); if (dir == TUSB_DIR_OUT) { reg |= USB_ADDR_ENDP1_INTEP_DIR_BITS; } if (need_pre(dev_addr)) { reg |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS; } usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = reg; // Finally, enable interrupt that endpoint usb_hw_set->int_ep_ctrl = 1 << (ep->interrupt_num + 1); // If it's an interrupt endpoint we need to set up the buffer control register } } //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; pico_trace("hcd_init %d\n", rhport); assert(rhport == 0); // Reset any previous state rp2usb_init(); // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En) usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS; // Remove shared irq if it was previously added so as not to fill up shared irq slots irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); irq_add_shared_handler(USBCTRL_IRQ, hcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // clear epx and interrupt eps memset(&ep_pool, 0, sizeof(ep_pool)); // Enable in host mode with SOF / Keep alive on usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS; usb_hw->sie_ctrl = SIE_CTRL_BASE; usb_hw->inte = USB_INTE_BUFF_STATUS_BITS | USB_INTE_HOST_CONN_DIS_BITS | USB_INTE_HOST_RESUME_BITS | USB_INTE_STALL_BITS | USB_INTE_TRANS_COMPLETE_BITS | USB_INTE_ERROR_RX_TIMEOUT_BITS | USB_INTE_ERROR_DATA_SEQ_BITS ; return true; } bool hcd_deinit(uint8_t rhport) { (void) rhport; irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); return true; } void hcd_port_reset(uint8_t rhport) { (void) rhport; pico_trace("hcd_port_reset\n"); assert(rhport == 0); // TODO: Nothing to do here yet. Perhaps need to reset some state? } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; pico_trace("hcd_port_connect_status\n"); assert(rhport == 0); return usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; assert(rhport == 0); // TODO: Should enumval this register switch ( dev_speed() ) { case 1: return TUSB_SPEED_LOW; case 2: return TUSB_SPEED_FULL; default: panic("Invalid speed\n"); // return TUSB_SPEED_INVALID; } } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { pico_trace("hcd_device_close %d\n", dev_addr); (void) rhport; // reset epx if it is currently active with unplugged device if (epx.configured && epx.active && epx.dev_addr == dev_addr) { epx.configured = false; *hwep_ctrl_reg_host(&epx) = 0; *hwbuf_ctrl_reg_host(&epx) = 0; hw_endpoint_reset_transfer(&epx); } // dev0 only has ep0 if (dev_addr != 0) { for (size_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++) { hw_endpoint_t *ep = &ep_pool[i]; if (ep->dev_addr == dev_addr && ep->configured) { // in case it is an interrupt endpoint, disable it usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1)); usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0; // unconfigure the endpoint ep->configured = false; *hwep_ctrl_reg_host(ep) = 0; *hwbuf_ctrl_reg_host(ep) = 0; hw_endpoint_reset_transfer(ep); } } } } uint32_t hcd_frame_number(uint8_t rhport) { (void)rhport; return usb_hw->sof_rd; } void hcd_int_enable(uint8_t rhport) { (void)rhport; irq_set_enabled(USBCTRL_IRQ, true); } void hcd_int_disable(uint8_t rhport) { (void)rhport; // todo we should check this is disabling from the correct core; note currently this is never called irq_set_enabled(USBCTRL_IRQ, false); } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t *ep_desc) { (void)rhport; pico_trace("hcd_edpt_open dev_addr %d, ep_addr %d\n", dev_addr, ep_desc->bEndpointAddress); hw_endpoint_t *ep = hw_endpoint_allocate(ep_desc->bmAttributes.xfer); TU_ASSERT(ep); hw_endpoint_init(ep, dev_addr, ep_desc->bEndpointAddress, tu_edpt_packet_size(ep_desc), ep_desc->bmAttributes.xfer, ep_desc->bInterval); return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void) rhport; pico_trace("hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d\n", dev_addr, ep_addr, buflen); const uint8_t ep_num = tu_edpt_number(ep_addr); tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); // Get appropriate ep. Either EPX or interrupt endpoint struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); TU_ASSERT(ep); // EP should be inactive assert(!ep->active); // Control endpoint can change direction 0x00 <-> 0x80 if (ep_addr != ep->ep_addr) { assert(ep_num == 0); // Direction has flipped on endpoint control so re init it but with same properties hw_endpoint_init(ep, dev_addr, ep_addr, ep->wMaxPacketSize, TUSB_XFER_CONTROL, 0); } // If a normal transfer (non-interrupt) then initiate using // sie ctrl registers. Otherwise, interrupt ep registers should // already be configured if (ep == &epx) { hw_endpoint_xfer_start(ep, buffer, NULL, buflen); // That has set up buffer control, endpoint control etc // for host we have to initiate the transfer usb_hw->dev_addr_ctrl = (uint32_t) (dev_addr | (ep_num << USB_ADDR_ENDP_ENDPOINT_LSB)); uint32_t flags = USB_SIE_CTRL_START_TRANS_BITS | SIE_CTRL_BASE | (ep_dir ? USB_SIE_CTRL_RECEIVE_DATA_BITS : USB_SIE_CTRL_SEND_DATA_BITS) | (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); // START_TRANS bit on SIE_CTRL seems to exhibit the same behavior as the AVAILABLE bit // described in RP2040 Datasheet, release 2.1, section "4.1.2.5.1. Concurrent access". // We write everything except the START_TRANS bit first, then wait some cycles. usb_hw->sie_ctrl = flags & ~USB_SIE_CTRL_START_TRANS_BITS; busy_wait_at_least_cycles(12); usb_hw->sie_ctrl = flags; } else { hw_endpoint_xfer_start(ep, buffer, NULL, buflen); } return true; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; // TODO not implemented yet return false; } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; // Copy data into setup packet buffer for (uint8_t i = 0; i < 8; i++) { usbh_dpram->setup_packet[i] = setup_packet[i]; } // Configure EP0 struct with setup info for the trans complete hw_endpoint_t *ep = hw_endpoint_allocate((uint8_t)TUSB_XFER_CONTROL); TU_ASSERT(ep); // EPX should be inactive assert(!ep->active); // EP0 out hw_endpoint_init(ep, dev_addr, 0x00, ep->wMaxPacketSize, 0, 0); assert(ep->configured); ep->remaining_len = 8; ep->active = true; // Set device address usb_hw->dev_addr_ctrl = dev_addr; // Set pre if we are a low speed device on full speed hub uint32_t const flags = SIE_CTRL_BASE | USB_SIE_CTRL_SEND_SETUP_BITS | USB_SIE_CTRL_START_TRANS_BITS | (need_pre(dev_addr) ? USB_SIE_CTRL_PREAMBLE_EN_BITS : 0); // START_TRANS bit on SIE_CTRL seems to exhibit the same behavior as the AVAILABLE bit // described in RP2040 Datasheet, release 2.1, section "4.1.2.5.1. Concurrent access". // We write everything except the START_TRANS bit first, then wait some cycles. usb_hw->sie_ctrl = flags & ~USB_SIE_CTRL_START_TRANS_BITS; busy_wait_at_least_cycles(12); usb_hw->sie_ctrl = flags; return true; } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; panic("hcd_clear_stall"); // return true; } #endif ================================================ FILE: src/portable/raspberrypi/rp2040/rp2040_usb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * Copyright (c) 2021 Ha Thach (tinyusb.org) for Double Buffered * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUSB_MCU == OPT_MCU_RP2040 #include #include "rp2040_usb.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPE //--------------------------------------------------------------------+ static void sync_xfer(hw_endpoint_t *ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX static bool e15_is_critical_frame_period(struct hw_endpoint *ep); #else #define e15_is_critical_frame_period(x) (false) #endif //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ // Provide own byte by byte memcpy as not all copies are aligned static void unaligned_memcpy(uint8_t *dst, const uint8_t *src, size_t n) { while (n--) { *dst++ = *src++; } } #if CFG_TUD_EDPT_DEDICATED_HWFIFO void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) { (void)access_mode; unaligned_memcpy((uint8_t *)(uintptr_t)hwfifo, src, len); } void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) { (void)access_mode; unaligned_memcpy(dest, (const uint8_t *)(uintptr_t)hwfifo, len); } #endif void rp2usb_init(void) { // Reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); #ifdef __GNUC__ // Clear any previous state just in case #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" #if __GNUC__ > 6 #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif #endif memset(usb_dpram, 0, sizeof(*usb_dpram)); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // Mux the controller to the onboard usb phy usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS; TU_LOG2_INT(sizeof(hw_endpoint_t)); } void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->active = false; ep->remaining_len = 0; ep->xferred_len = 0; ep->user_buf = 0; } void __tusb_irq_path_func(hwbuf_ctrl_update)(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask) { const bool is_host = rp2usb_is_host_mode(); uint32_t value = 0; uint32_t buf_ctrl = *buf_ctrl_reg; if (and_mask) { value = buf_ctrl & and_mask; } if (or_mask) { value |= or_mask; if (or_mask & USB_BUF_CTRL_AVAIL) { if (buf_ctrl & USB_BUF_CTRL_AVAIL) { panic("buf_ctrl @ 0x%lX already available", (uintptr_t)buf_ctrl_reg); } *buf_ctrl_reg = value & ~USB_BUF_CTRL_AVAIL; // Section 4.1.2.7.1 (rp2040) / 12.7.3.7.1 (rp2350) Concurrent access: after write to buffer control, we need to // wait at least 1/48 mhz (usb clock), 12 cycles should be good for 48*12Mhz = 576Mhz. // Don't need delay in host mode as host is in charge if (!is_host) { busy_wait_at_least_cycles(12); } } } *buf_ctrl_reg = value; } // prepare buffer, move data if tx, return buffer control static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id, bool is_rx) { const uint16_t buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); ep->remaining_len = (uint16_t) (ep->remaining_len - buflen); uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; // PID buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; ep->next_pid ^= 1u; if (!is_rx) { if (buflen) { // Copy data from user buffer/fifo to hw buffer uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; #if CFG_TUD_EDPT_DEDICATED_HWFIFO if (ep->is_xfer_fifo) { // not in sram, may mess up timing with E15 workaround tu_hwfifo_write_from_fifo(hw_buf, ep->user_fifo, buflen, NULL); } else #endif { unaligned_memcpy(hw_buf, ep->user_buf, buflen); ep->user_buf += buflen; } } // Mark as full buf_ctrl |= USB_BUF_CTRL_FULL; } // Is this the last buffer? Only really matters for host mode. Will trigger // the trans complete irq but also stop it polling. We only really care about // trans complete for setup packets being sent if (ep->remaining_len == 0) { buf_ctrl |= USB_BUF_CTRL_LAST; } if (buf_id) { buf_ctrl = buf_ctrl << 16; } return buf_ctrl; } // Prepare buffer control register value void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); bool is_rx; bool is_host = false; io_rw_32 *ep_ctrl_reg; io_rw_32 *buf_ctrl_reg; #if CFG_TUH_ENABLED is_host = rp2usb_is_host_mode(); if (is_host) { buf_ctrl_reg = hwbuf_ctrl_reg_host(ep); ep_ctrl_reg = hwep_ctrl_reg_host(ep); is_rx = (dir == TUSB_DIR_IN); } else #endif { buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); ep_ctrl_reg = hwep_ctrl_reg_device(ep); is_rx = (dir == TUSB_DIR_OUT); } // always compute and start with buffer 0 uint32_t buf_ctrl = prepare_ep_buffer(ep, 0, is_rx) | USB_BUF_CTRL_SEL; // EP0 has no endpoint control register, also usbd only schedule 1 packet at a time (single buffer) if (ep_ctrl_reg != NULL) { uint32_t ep_ctrl = *ep_ctrl_reg; // For now: skip double buffered for RX e.g OUT endpoint in Device mode, since host could send < 64 bytes and cause // short packet on buffer0 // NOTE: this could happen to Host mode IN endpoint Also, Host mode "interrupt" endpoint hardware is only single // buffered, // NOTE2: Currently Host bulk is implemented using "interrupt" endpoint const bool force_single = (!is_host && is_rx) || (is_host && tu_edpt_number(ep->ep_addr) != 0); if (ep->remaining_len && !force_single) { // Use buffer 1 (double buffered) if there is still data // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) buf_ctrl |= prepare_ep_buffer(ep, 1, is_rx); // Set endpoint control double buffered bit if needed ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; } else { // Single buffered since 1 is enough ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; } *ep_ctrl_reg = ep_ctrl; } TU_LOG(3, " Prepare BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); // Finally, write to buffer_control which will trigger the transfer // the next time the controller polls this dpram address hwbuf_ctrl_set(buf_ctrl_reg, buf_ctrl); } void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, tu_fifo_t *ff, uint16_t total_len) { (void) ff; hw_endpoint_lock_update(ep, 1); if (ep->active) { // TODO: Is this acceptable for interrupt packets? TU_LOG(1, "WARN: starting new transfer on already active ep %02X\r\n", ep->ep_addr); hw_endpoint_reset_transfer(ep); } // Fill in info now that we're kicking off the hw ep->remaining_len = total_len; ep->xferred_len = 0; ep->active = true; #if CFG_TUD_EDPT_DEDICATED_HWFIFO if (ff != NULL) { ep->user_fifo = ff; ep->is_xfer_fifo = true; } else #endif { ep->user_buf = buffer; ep->is_xfer_fifo = false; } #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX if (ep->e15_bulk_in) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; } if (e15_is_critical_frame_period(ep)) { ep->pending = 1; // skip transfer if we are in critical frame period } else #endif { hw_endpoint_start_next_buffer(ep); } hw_endpoint_lock_update(ep, -1); } // sync endpoint buffer and return transferred bytes static uint16_t __tusb_irq_path_func(sync_ep_buffer)(hw_endpoint_t *ep, io_rw_32 *buf_ctrl_reg, uint8_t buf_id, bool is_rx) { uint32_t buf_ctrl = *buf_ctrl_reg; if (buf_id) { buf_ctrl = buf_ctrl >> 16; } const uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; if (!is_rx) { // We are continuing a transfer here. If we are TX, we have successfully // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); } else { // If we have received some data, so can increase the length // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); uint8_t *hw_buf = ep->hw_data_buf + buf_id * 64; #if CFG_TUD_EDPT_DEDICATED_HWFIFO if (ep->is_xfer_fifo) { // not in sram, may mess up timing with E15 workaround tu_hwfifo_read_to_fifo(hw_buf, ep->user_fifo, xferred_bytes, NULL); } else #endif { unaligned_memcpy(ep->user_buf, hw_buf, xferred_bytes); ep->user_buf += xferred_bytes; } } ep->xferred_len += xferred_bytes; // Short packet if (xferred_bytes < ep->wMaxPacketSize) { // Reduce total length as this is last packet ep->remaining_len = 0; } return xferred_bytes; } // Update hw endpoint struct with info from hardware after a buff status interrupt static void __tusb_irq_path_func(sync_xfer)(hw_endpoint_t *ep) { // const uint8_t ep_num = tu_edpt_number(ep->ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep->ep_addr); io_rw_32 *buf_ctrl_reg; io_rw_32 *ep_ctrl_reg; bool is_rx; #if CFG_TUH_ENABLED const bool is_host = rp2usb_is_host_mode(); if (is_host) { buf_ctrl_reg = hwbuf_ctrl_reg_host(ep); ep_ctrl_reg = hwep_ctrl_reg_host(ep); is_rx = (dir == TUSB_DIR_IN); } else #endif { buf_ctrl_reg = hwbuf_ctrl_reg_device(ep); ep_ctrl_reg = hwep_ctrl_reg_device(ep); is_rx = (dir == TUSB_DIR_OUT); } TU_LOG(3, " Sync BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(*buf_ctrl_reg), tu_u32_high16(*buf_ctrl_reg)); uint16_t buf0_bytes = sync_ep_buffer(ep, buf_ctrl_reg, 0, is_rx); // always sync buffer 0 // sync buffer 1 if double buffered if (ep_ctrl_reg != NULL && (*ep_ctrl_reg) & EP_CTRL_DOUBLE_BUFFERED_BITS) { if (buf0_bytes == ep->wMaxPacketSize) { // sync buffer 1 if not short packet sync_ep_buffer(ep, buf_ctrl_reg, 1, is_rx); } else { // short packet on buffer 0 // TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example // At this time (currently trigger per 2 buffer), the buffer1 is probably filled with data from // the next transfer (not current one). For now we disable double buffered for device OUT // NOTE this could happen to Host IN #if 0 uint8_t const ep_num = tu_edpt_number(ep->ep_addr); uint8_t const dir = (uint8_t) tu_edpt_dir(ep->ep_addr); uint8_t const ep_id = 2*ep_num + (dir ? 0 : 1); // abort queued transfer on buffer 1 usb_hw->abort |= TU_BIT(ep_id); while ( !(usb_hw->abort_done & TU_BIT(ep_id)) ) {} uint32_t ep_ctrl = *ep->endpoint_control; ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; io_rw_32 *buf_ctrl_reg = is_host ? hwbuf_ctrl_reg_host(ep) : hwbuf_ctrl_reg_device(ep); hwbuf_ctrl_set(buf_ctrl_reg, 0); usb_hw->abort &= ~TU_BIT(ep_id); TU_LOG(3, "----SHORT PACKET buffer0 on EP %02X:\r\n", ep->ep_addr); TU_LOG(3, " BufCtrl: [0] = 0x%04x [1] = 0x%04x\r\n", tu_u32_low16(buf_ctrl), tu_u32_high16(buf_ctrl)); #endif } } } // Returns true if transfer is complete bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { hw_endpoint_lock_update(ep, 1); // Part way through a transfer if (!ep->active) { panic("Can't continue xfer on inactive ep %02X", ep->ep_addr); } sync_xfer(ep); // Update EP struct from hardware state // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb if (ep->remaining_len == 0) { pico_trace("Completed transfer of %d bytes on ep %02X\r\n", ep->xferred_len, ep->ep_addr); // Notify caller we are done so it can notify the tinyusb stack hw_endpoint_lock_update(ep, -1); return true; } else { #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX if (e15_is_critical_frame_period(ep)) { ep->pending = 1; } else #endif { hw_endpoint_start_next_buffer(ep); } } hw_endpoint_lock_update(ep, -1); // More work to do return false; } //--------------------------------------------------------------------+ // Errata 15 //--------------------------------------------------------------------+ #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX // E15 is fixed with RP2350 /* Don't mark IN buffers as available during the last 200us of a full-speed frame. This avoids a situation seen with the USB2.0 hub on a Raspberry Pi 4 where a late IN token before the next full-speed SOF can cause port babble and a corrupt ACK packet. The nature of the data corruption has a chance to cause device lockup. Use the next SOF to mark delayed buffers as available. This reduces available Bulk IN bandwidth by approximately 20%, and requires that the SOF interrupt is enabled while these transfers are ongoing. Inherit the top-level enable from the corresponding Pico-SDK flag. Applications that will not use the device in a situation where it could be plugged into a Pi 4 or Pi 400 (for example, when directly connected to a commodity hub or other host) can turn off the flag in the SDK. */ volatile uint32_t e15_last_sof = 0; // check if we need to apply Errata 15 workaround : i.e // Endpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame static bool __tusb_irq_path_func(e15_is_critical_frame_period)(struct hw_endpoint* ep) { if (!ep->e15_bulk_in) { return false; } /* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point. * The device state machine cannot recover from receiving an incorrect PID * when it is expecting an ACK. */ uint32_t delta = time_us_32() - e15_last_sof; if (delta < 800 || delta > 998) { return false; } TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof); return true; } #endif // TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX #endif ================================================ FILE: src/portable/raspberrypi/rp2040/rp2040_usb.h ================================================ #ifndef RP2040_COMMON_H_ #define RP2040_COMMON_H_ #include "pico.h" #include "hardware/structs/usb.h" #include "hardware/irq.h" #include "hardware/resets.h" #include "hardware/timer.h" #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" #if defined(RP2040_USB_HOST_MODE) && defined(RP2040_USB_DEVICE_MODE) #error TinyUSB device and host mode not supported at the same time #endif // E5 and E15 only apply to RP2040 #if defined(PICO_RP2040) && PICO_RP2040 == 1 // RP2040 E5: USB device fails to exit RESET state on busy USB bus. #if defined(PICO_RP2040_USB_DEVICE_ENUMERATION_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX) #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX PICO_RP2040_USB_DEVICE_ENUMERATION_FIX #endif // RP2040 E15: USB Device controller will hang if certain bus errors occur during an IN transfer. #if defined(PICO_RP2040_USB_DEVICE_UFRAME_FIX) && !defined(TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX) #define TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX PICO_RP2040_USB_DEVICE_UFRAME_FIX #endif #endif #ifndef TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX #define TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX 0 #endif #ifndef TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX #define TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX 0 #endif #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX #undef PICO_RP2040_USB_FAST_IRQ #define PICO_RP2040_USB_FAST_IRQ 1 #endif #ifndef PICO_RP2040_USB_FAST_IRQ #define PICO_RP2040_USB_FAST_IRQ 0 #endif #if PICO_RP2040_USB_FAST_IRQ #define __tusb_irq_path_func(x) __no_inline_not_in_flash_func(x) #else #define __tusb_irq_path_func(x) x #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #define usb_hw_set ((usb_hw_t *) hw_set_alias_untyped(usb_hw)) #define usb_hw_clear ((usb_hw_t *) hw_clear_alias_untyped(usb_hw)) #define pico_info(...) TU_LOG(2, __VA_ARGS__) #define pico_trace(...) TU_LOG(3, __VA_ARGS__) // Hardware information per endpoint typedef struct hw_endpoint { uint8_t ep_addr; uint8_t next_pid; bool active; // transferring data bool is_xfer_fifo; // transfer using fifo #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX bool e15_bulk_in; // Errata15 device bulk in uint8_t pending; // Transfer scheduled but not active #endif #if CFG_TUH_ENABLED bool configured; // Is this a valid struct uint8_t dev_addr; uint8_t interrupt_num; // for host interrupt endpoints #endif uint16_t wMaxPacketSize; uint8_t *hw_data_buf; // Buffer pointer in usb dpram // transfer info union { uint8_t *user_buf; // User buffer in main memory tu_fifo_t *user_fifo; }; uint16_t remaining_len; uint16_t xferred_len; } hw_endpoint_t; #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX extern volatile uint32_t e15_last_sof; #endif void rp2usb_init(void); // if usb hardware is in host mode TU_ATTR_ALWAYS_INLINE static inline bool rp2usb_is_host_mode(void) { return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; } void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, tu_fifo_t *ff, uint16_t total_len); bool hw_endpoint_xfer_continue(struct hw_endpoint *ep); void hw_endpoint_reset_transfer(struct hw_endpoint *ep); void hw_endpoint_start_next_buffer(struct hw_endpoint *ep); TU_ATTR_ALWAYS_INLINE static inline void hw_endpoint_lock_update(__unused struct hw_endpoint * ep, __unused int delta) { // todo add critsec as necessary to prevent issues between worker and IRQ... // note that this is perhaps as simple as disabling IRQs because it would make // sense to have worker and IRQ on same core, however I think using critsec is about equivalent. } // #if CFG_TUD_ENABLED TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_device(struct hw_endpoint *ep) { uint8_t const epnum = tu_edpt_number(ep->ep_addr); const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); if (epnum == 0) { // EP0 has no endpoint control register because the buffer offsets are fixed and always enabled return NULL; } return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_ctrl[epnum - 1].in : &usb_dpram->ep_ctrl[epnum - 1].out; } TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_device(struct hw_endpoint *ep) { const uint8_t epnum = tu_edpt_number(ep->ep_addr); const uint8_t dir = (uint8_t)tu_edpt_dir(ep->ep_addr); return (dir == TUSB_DIR_IN) ? &usb_dpram->ep_buf_ctrl[epnum].in : &usb_dpram->ep_buf_ctrl[epnum].out; } // #endif #if CFG_TUH_ENABLED TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwep_ctrl_reg_host(struct hw_endpoint *ep) { if (tu_edpt_number(ep->ep_addr) == 0) { return &usbh_dpram->epx_ctrl; } return &usbh_dpram->int_ep_ctrl[ep->interrupt_num].ctrl; } TU_ATTR_ALWAYS_INLINE static inline io_rw_32 *hwbuf_ctrl_reg_host(struct hw_endpoint *ep) { if (tu_edpt_number(ep->ep_addr) == 0) { return &usbh_dpram->epx_buf_ctrl; } return &usbh_dpram->int_ep_buffer_ctrl[ep->interrupt_num].ctrl; } #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void hwbuf_ctrl_update(io_rw_32 *buf_ctrl_reg, uint32_t and_mask, uint32_t or_mask); TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set(io_rw_32 *buf_ctrl_reg, uint32_t value) { hwbuf_ctrl_update(buf_ctrl_reg, 0, value); } TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_set_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { hwbuf_ctrl_update(buf_ctrl_reg, ~value, value); } TU_ATTR_ALWAYS_INLINE static inline void hwbuf_ctrl_clear_mask(io_rw_32 *buf_ctrl_reg, uint32_t value) { hwbuf_ctrl_update(buf_ctrl_reg, ~value, 0); } static inline uintptr_t hw_data_offset(uint8_t *buf) { // Remove usb base from buffer pointer return (uintptr_t)buf ^ (uintptr_t)usb_dpram; } #endif ================================================ FILE: src/portable/renesas/rusb2/dcd_rusb2.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Koji Kitayama * Portions copyrighted (c) 2021 Roland Winistoerfer * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_RUSB2) #include "device/dcd.h" #include "rusb2_common.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ enum { PIPE_COUNT = 10, }; typedef struct { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ uint8_t ep; /* an assigned endpoint address */ uint8_t ff; /* `buf` is TU_FUFO or POD */ } pipe_state_t; typedef struct { pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ // Track whether sof has been manually enabled bool sof_enabled; } dcd_data_t; static dcd_data_t _dcd; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ // Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer // - Pipes 1 and 2: Bulk or ISO // - Pipes 3 to 5: Bulk // - Pipes 6 to 9: Interrupt // // Note: for small mcu such as // - RA2A1: only pipe 4-7 are available, and no support for ISO static unsigned find_pipe(unsigned xfer_type) { #if defined(BSP_MCU_GROUP_RA2A1) const uint8_t pipe_idx_arr[4][2] = { { 0, 0 }, // Control { 0, 0 }, // Isochronous not supported { 4, 5 }, // Bulk { 6, 7 }, // Interrupt }; #else const uint8_t pipe_idx_arr[4][2] = { { 0, 0 }, // Control { 1, 2 }, // Isochronous { 1, 5 }, // Bulk { 6, 9 }, // Interrupt }; #endif // find backward since only pipe 1, 2 support ISO const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; for (int i = idx_last; i >= idx_first; i--) { if (0 == _dcd.pipe[i].ep) return i; } return 0; } static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { return (volatile uint16_t*)&(rusb->DCPCTR); } } static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); if (epn) { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; return get_pipectr(rusb, num); } else { return get_pipectr(rusb, 0); } } static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { return rusb->DCPMAXP_b.MXPS; } static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { rusb->PIPESEL = num; return rusb->PIPEMAXP; } static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} while ( !rusb->D0FIFOCTR_b.FRDY ) {} } //--------------------------------------------------------------------+ // Pipe Transfer //--------------------------------------------------------------------+ static bool pipe0_xfer_in(rusb2_reg_t *rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } const uint16_t mps = edpt0_max_packet_size(rusb); const uint16_t len = tu_min16(mps, rem); void *buf = pipe->buf; if (len) { // uint16_t fifo_sel = RUSB2_CFIFOSEL_ISEL_WRITE | FIFOSEL_BIGEND; tu_hwfifo_access_t access_mode; access_mode.param = (uintptr_t)rusb; // if (rusb2_is_highspeed_reg(rusb)) { // fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT; access_mode.data_stride = 4u; } else { // fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT; access_mode.data_stride = 2u; } // rusb->CFIFOSEL = fifo_sel; // while (0 == (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) {} if (pipe->ff) { tu_hwfifo_write_from_fifo(&rusb->CFIFO, (tu_fifo_t *)buf, len, &access_mode); } else { tu_hwfifo_write(&rusb->CFIFO, buf, len, &access_mode); pipe->buf = (uint8_t *)buf + len; } } if (len < mps) { rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } pipe->remaining = rem - len; return false; } static bool pipe0_xfer_out(rusb2_reg_t *rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; const uint16_t mps = edpt0_max_packet_size(rusb); const uint16_t vld = rusb->CFIFOCTR_b.DTLN; const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; if (len) { tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; if (pipe->ff) { tu_hwfifo_read_to_fifo(&rusb->CFIFO, (tu_fifo_t *)buf, len, &access_mode); } else { tu_hwfifo_read(&rusb->CFIFO, buf, len, &access_mode); pipe->buf = (uint8_t *)buf + len; } } if (len < mps) { rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } return false; } static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } const uint16_t fifo_sel = num | FIFOSEL_BIGEND; const bool is_highspeed = rusb2_is_highspeed_reg(rusb); if (is_highspeed) { rusb->D0FIFOSEL = fifo_sel | RUSB2_FIFOSEL_MBW_32BIT; } else { rusb->D0FIFOSEL = fifo_sel | RUSB2_FIFOSEL_MBW_16BIT; } const uint16_t mps = edpt_max_packet_size(rusb, num); pipe_wait_for_ready(rusb, num); uint16_t len = tu_min16(rem, mps); void *buf = pipe->buf; if (len) { tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; if (pipe->ff) { tu_hwfifo_write_from_fifo(&rusb->D0FIFO, (tu_fifo_t *)buf, len, &access_mode); } else { tu_hwfifo_write(&rusb->D0FIFO, buf, len, &access_mode); pipe->buf = (uint8_t *)buf + len; } } if (len < mps) { rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; return false; } static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; const uint16_t rem = pipe->remaining; uint16_t fifo_sel = num | FIFOSEL_BIGEND; if (rusb2_is_highspeed_reg(rusb)) { fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT; } else { fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT; } rusb->D0FIFOSEL = fifo_sel; const uint16_t mps = edpt_max_packet_size(rusb, num); pipe_wait_for_ready(rusb, num); const uint16_t vld = rusb->D0FIFOCTR_b.DTLN; const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; if (len) { tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; if (pipe->ff) { tu_hwfifo_read_to_fifo(&rusb->D0FIFO, (tu_fifo_t *)buf, len, &access_mode); } else { tu_hwfifo_read(&rusb->D0FIFO, buf, len, &access_mode); pipe->buf = (uint8_t *)buf + len; } } if (len < mps) { rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } return false; } static void process_setup_packet(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); if (0 == (rusb->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return; rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; uint16_t setup_packet[4] = { tu_htole16(rusb->USBREQ), tu_htole16(rusb->USBVAL), tu_htole16(rusb->USBINDX), tu_htole16(rusb->USBLENG) }; rusb->INTSTS0 = ~((uint16_t) RUSB2_INTSTS0_VALID_Msk); dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true); } static void process_status_completion(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); uint8_t ep_addr; /* Check the data stage direction */ if (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) { /* IN transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); } else { /* OUT transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); } dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true); } static bool process_pipe0_xfer(rusb2_reg_t *rusb, int buffer_type, uint8_t ep_addr, void *buffer, uint16_t total_bytes) { uint16_t fifo_sel = (rusb2_is_highspeed_reg(rusb) ? RUSB2_FIFOSEL_MBW_32BIT : RUSB2_FIFOSEL_MBW_16BIT) | FIFOSEL_BIGEND; /* configure fifo direction and access unit settings */ if (ep_addr != 0) { // Control IN fifo_sel |= RUSB2_CFIFOSEL_ISEL_WRITE; } rusb->CFIFOSEL = fifo_sel; while ((rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) != (fifo_sel & RUSB2_CFIFOSEL_ISEL_WRITE)) { // wait until ISEL_WRITE take effect } pipe_state_t *pipe = &_dcd.pipe[0]; pipe->ff = buffer_type; pipe->length = total_bytes; pipe->remaining = total_bytes; if (total_bytes) { pipe->buf = buffer; if (ep_addr) { /* IN */ TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); pipe0_xfer_in(rusb); } rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; } else { /* ZLP */ pipe->buf = NULL; rusb->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF; } return true; } static bool process_pipe_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; TU_ASSERT(num); pipe_state_t *pipe = &_dcd.pipe[num]; pipe->ff = buffer_type; pipe->buf = buffer; pipe->length = total_bytes; pipe->remaining = total_bytes; if (dir) { /* IN */ if (total_bytes) { pipe_xfer_in(rusb, num); } else { /* ZLP */ rusb->D0FIFOSEL = num; pipe_wait_for_ready(rusb, num); rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; rusb->D0FIFOSEL = 0; /* if CURPIPE bits changes, check written value */ while (rusb->D0FIFOSEL_b.CURPIPE) {} } } else { // OUT volatile reg_pipetre_t *pt = get_pipetre(rusb, num); if (pt) { const uint16_t mps = edpt_max_packet_size(rusb, num); volatile uint16_t *ctr = get_pipectr(rusb, num); if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; pt->TRE = TU_BIT(8); pt->TRN = (total_bytes + mps - 1) / mps; pt->TRENB = 1; *ctr = RUSB2_PIPE_CTR_PID_BUF; } } // TU_LOG2("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); return true; } static bool process_edpt_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { return process_pipe0_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } else { return process_pipe_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } } static void process_pipe0_bemp(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); bool completed = pipe0_xfer_in(rusb); if (completed) { pipe_state_t *pipe = &_dcd.pipe[0]; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), pipe->length, XFER_RESULT_SUCCESS, true); } } static void process_pipe_brdy(uint8_t rhport, unsigned num) { rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned dir = tu_edpt_dir(pipe->ep); bool completed; if (dir) { /* IN */ completed = pipe_xfer_in(rusb, num); } else { // OUT if (num) { completed = pipe_xfer_out(rusb, num); } else { completed = pipe0_xfer_out(rusb); } } if (completed) { dcd_event_xfer_complete(rhport, pipe->ep, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); // TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining); } } static void process_bus_reset(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb->BEMPENB = 1; rusb->BRDYENB = 1; rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ rusb->D1FIFOSEL = 0; while (rusb->D1FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_CTR[0])); volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_TR[0].E)); for (int i = 1; i <= 5; ++i) { rusb->PIPESEL = i; rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; *tre = TU_BIT(8); tre += 2; } for (int i = 6; i <= 9; ++i) { rusb->PIPESEL = i; rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; } tu_varclr(&_dcd); TU_LOG3("Bus reset, RHST = %u\r\n", rusb->DVSTCTR0_b.RHST); tusb_speed_t speed; switch(rusb->DVSTCTR0 & RUSB2_DVSTCTR0_RHST_Msk) { case RUSB2_DVSTCTR0_RHST_LS: speed = TUSB_SPEED_LOW; break; case RUSB2_DVSTCTR0_RHST_FS: speed = TUSB_SPEED_FULL; break; case RUSB2_DVSTCTR0_RHST_HS: speed = TUSB_SPEED_HIGH; break; default: TU_ASSERT(false, ); } dcd_event_bus_reset(rhport, speed, true); } static void process_set_address(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); const uint16_t addr = rusb->USBADDR_b.USBADDR; if (!addr) { return; } const tusb_control_request_t setup_packet = { #if defined(__CCRX__) .bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */ #else .bmRequestType = 0, #endif .bRequest = TUSB_REQ_SET_ADDRESS, .wValue = addr, .wIndex = 0, .wLength = 0, }; dcd_event_setup_received(rhport, (const uint8_t *) &setup_packet, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ #if 0 // previously present in the rx driver before generalization static uint32_t disable_interrupt(void) { uint32_t pswi; #if defined(__CCRX__) pswi = get_psw() & 0x010000; clrpsw_i(); #else pswi = __builtin_rx_mvfc(0) & 0x010000; __builtin_rx_clrpsw('I'); #endif return pswi; } static void enable_interrupt(uint32_t pswi) { #if defined(__CCRX__) set_psw(get_psw() | pswi); #else __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi); #endif } #endif bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); // We disable SOF for now until needed later on. // Since TinyUSB doesn't use SOF for now, and this interrupt often (1ms interval) _dcd.sof_enabled = false; #ifdef RUSB2_SUPPORT_HIGHSPEED if ( rusb2_is_highspeed_rhport(rhport) ) { rusb->SYSCFG_b.HSE = 1; // leave CLKSEL as default (0x11) 24Mhz // Power and reset UTMI Phy uint16_t physet = (rusb->PHYSET | RUSB2_PHYSET_PLLRESET_Msk) & ~RUSB2_PHYSET_DIRPD_Msk; rusb->PHYSET = physet; R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); rusb->PHYSET_b.PLLRESET = 0; // set UTMI to operating mode and wait for PLL lock confirmation rusb->LPSTS_b.SUSPENDM = 1; while (!rusb->PLLSTA_b.PLLLOCK) {} rusb->SYSCFG_b.DRPD = 0; rusb->SYSCFG_b.USBE = 1; // Set CPU bus wait time (fine tunne later) // rusb2->BUSWAIT |= 0x0F00U; rusb->PHYSET_b.REPSEL = 1; } else #endif { rusb->SYSCFG_b.SCKE = 1; while (!rusb->SYSCFG_b.SCKE) {} rusb->SYSCFG_b.DRPD = 0; rusb->SYSCFG_b.DCFM = 0; rusb->SYSCFG_b.USBE = 1; // MCU specific PHY init rusb2_phy_init(); rusb->PHYSLEW = 0x5; rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ } /* Setup default control pipe */ rusb->DCPMAXP_b.MXPS = 64; rusb->INTSTS0 = 0; rusb->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (_dcd.sof_enabled ? RUSB2_INTSTS0_SOFR_Msk : 0) | RUSB2_INTSTS0_RESM_Msk; rusb->BEMPENB = 1; rusb->BRDYENB = 1; // If VBUS (detect) pin is not used, application need to call tud_connect() manually after tud_init() if (rusb->INTSTS0_b.VBSTS) { dcd_connect(rhport); } return true; } void dcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb->DVSTCTR0_b.WKUP = 1; } void dcd_connect(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); if ( rusb2_is_highspeed_rhport(rhport)) { rusb->SYSCFG_b.CNEN = 1; } rusb->SYSCFG_b.DPRPU = 1; } void dcd_disconnect(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb->SYSCFG_b.DPRPU = 0; } void dcd_sof_enable(uint8_t rhport, bool en) { rusb2_reg_t* rusb = RUSB2_REG(rhport); _dcd.sof_enabled = en; rusb->INTENB0_b.SOFE = en ? 1: 0; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); if (xfer == TUSB_XFER_ISOCHRONOUS) { // Fullspeed ISO is limit to 256 bytes if ( !rusb2_is_highspeed_rhport(rhport) && mps > 256) { return false; } } const unsigned num = find_pipe(xfer); TU_ASSERT(num); _dcd.pipe[num].ep = ep_addr; _dcd.ep[dir][epn] = num; /* setup pipe */ dcd_int_disable(rhport); if ( rusb2_is_highspeed_rhport(rhport) ) { // FIXME shouldn't be after pipe selection and config, also the BUFNMB should be changed // depending on the allocation scheme rusb->PIPEBUF = 0x7C08; } rusb->PIPESEL = num; rusb->PIPEMAXP = mps; volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; unsigned cfg = (dir << 4) | epn; if (xfer == TUSB_XFER_BULK) { cfg |= (RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk); } else if (xfer == TUSB_XFER_INTERRUPT) { cfg |= RUSB2_PIPECFG_TYPE_INT; } else { cfg |= (RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk); } rusb->PIPECFG = cfg; rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); if (dir || (xfer != TUSB_XFER_BULK)) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } // TU_LOG1("O %d %x %x\r\n", rusb->PIPESEL, rusb->PIPECFG, rusb->PIPEMAXP); dcd_int_enable(rhport); return true; } void dcd_edpt_close_all(uint8_t rhport) { unsigned i = TU_ARRAY_SIZE(_dcd.pipe); dcd_int_disable(rhport); while (--i) { /* Close all pipes except 0 */ const unsigned ep_addr = _dcd.pipe[i].ep; if (!ep_addr) continue; dcd_edpt_close(rhport, ep_addr); } dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; rusb->BRDYENB &= ~TU_BIT(num); volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = 0; rusb->PIPESEL = num; rusb->PIPECFG = 0; _dcd.pipe[num].ep = 0; _dcd.ep[dir][epn] = 0; } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } #endif bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; rusb2_reg_t* rusb = RUSB2_REG(rhport); dcd_int_disable(rhport); bool r = process_edpt_xfer(rusb, 0, ep_addr, buffer, total_bytes); dcd_int_enable(rhport); return r; } bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 rusb2_reg_t* rusb = RUSB2_REG(rhport); dcd_int_disable(rhport); bool r = process_edpt_xfer(rusb, 1, ep_addr, ff, total_bytes); dcd_int_enable(rhport); return r; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); if (!ctr) { return; } dcd_int_disable(rhport); const uint32_t pid = *ctr & 0x3; *ctr = pid | RUSB2_PIPE_CTR_PID_STALL; *ctr = RUSB2_PIPE_CTR_PID_STALL; dcd_int_enable(rhport); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { rusb2_reg_t * rusb = RUSB2_REG(rhport); volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); if (!ctr) { return; } dcd_int_disable(rhport); *ctr = RUSB2_PIPE_CTR_SQCLR_Msk; if (tu_edpt_dir(ep_addr)) { /* IN */ *ctr = RUSB2_PIPE_CTR_PID_BUF; } else { const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)]; rusb->PIPESEL = num; if (rusb->PIPECFG_b.TYPE != 1) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } } dcd_int_enable(rhport); } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ #if defined(__CCRX__) TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { unsigned int count = 0; while ((value & 1) == 0) { value >>= 1; count++; } return count; } #endif void dcd_int_handler(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); uint16_t is0 = rusb->INTSTS0; /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ rusb->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk | RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk; // VBUS changes if ( is0 & RUSB2_INTSTS0_VBINT_Msk ) { if ( rusb->INTSTS0_b.VBSTS ) { dcd_connect(rhport); } else { dcd_disconnect(rhport); } } // Resumed if ( is0 & RUSB2_INTSTS0_RESM_Msk ) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); if (!_dcd.sof_enabled) { rusb->INTENB0_b.SOFE = 0; } } // SOF received if ( (is0 & RUSB2_INTSTS0_SOFR_Msk) && rusb->INTENB0_b.SOFE ) { // USBD will exit suspended mode when SOF event is received const uint32_t frame = rusb->FRMNUM_b.FRNM; dcd_event_sof(rhport, frame, true); if (!_dcd.sof_enabled) { rusb->INTENB0_b.SOFE = 0; } } // Device state changes if ( is0 & RUSB2_INTSTS0_DVST_Msk ) { switch (is0 & RUSB2_INTSTS0_DVSQ_Msk) { case RUSB2_INTSTS0_DVSQ_STATE_DEF: process_bus_reset(rhport); break; case RUSB2_INTSTS0_DVSQ_STATE_ADDR: process_set_address(rhport); break; case RUSB2_INTSTS0_DVSQ_STATE_SUSP0: case RUSB2_INTSTS0_DVSQ_STATE_SUSP1: case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); if (!_dcd.sof_enabled) { rusb->INTENB0_b.SOFE = 1; } default: break; } } // if ( is0 & RUSB2_INTSTS0_NRDY_Msk ) { // rusb->NRDYSTS = 0; // } // Control transfer stage changes if ( is0 & RUSB2_INTSTS0_CTRT_Msk ) { if ( is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA ) { /* A setup packet has been received. */ process_setup_packet(rhport); } else if ( 0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk) ) { /* A ZLP has been sent/received. */ process_status_completion(rhport); } } // Buffer empty if ( is0 & RUSB2_INTSTS0_BEMP_Msk ) { const uint16_t s = rusb->BEMPSTS; rusb->BEMPSTS = 0; if ( s & 1 ) { process_pipe0_bemp(rhport); } } // Buffer ready if ( is0 & RUSB2_INTSTS0_BRDY_Msk ) { const unsigned m = rusb->BRDYENB; unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { const unsigned num = __builtin_ctz(s); process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); } } } #endif ================================================ FILE: src/portable/renesas/rusb2/hcd_rusb2.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji Kitayama * Portions copyrighted (c) 2021 Roland Winistoerfer * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_RUSB2) #include "host/hcd.h" #include "host/usbh.h" #include "rusb2_common.h" #define TU_RUSB2_HCD_DBG 2 //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ enum { PIPE_COUNT = 10, }; TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN typedef union TU_ATTR_PACKED { struct { volatile uint16_t u8: 8; volatile uint16_t : 0; }; volatile uint16_t u16; } hw_fifo_t; typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ struct { uint32_t ep : 8; /* an assigned endpoint address */ uint32_t dev : 8; /* an assigned device address */ uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ uint32_t : 0; }; } pipe_state_t; TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_ATTR_BIT_FIELD_ORDER_END typedef struct { pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ } hcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static hcd_data_t _hcd; // TODO merged with DCD // Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer // - Pipes 1 and 2: Bulk or ISO // - Pipes 3 to 5: Bulk // - Pipes 6 to 9: Interrupt // // Note: for small mcu such as // - RA2A1: only pipe 4-7 are available, and no support for ISO static unsigned find_pipe(unsigned xfer_type) { const uint8_t pipe_idx_arr[4][2] = { { 0, 0 }, // Control { 1, 2 }, // Isochronous { 1, 5 }, // Bulk { 6, 9 }, // Interrupt }; // find backward since only pipe 1, 2 support ISO const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; for (int i = idx_last; i >= idx_first; i--) { if (0 == _hcd.pipe[i].ep) return i; } return 0; } static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { return (volatile uint16_t*)&(rusb->DCPCTR); } } static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } static volatile uint16_t* addr_to_pipectr(uint8_t rhport, uint8_t dev_addr, unsigned ep_addr) { rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); if (epn) { const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1]; return get_pipectr(rusb, num); } else { return get_pipectr(rusb, 0); } } static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { return rusb->DCPMAXP_b.MXPS; } static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { rusb->PIPESEL = num; return rusb->PIPEMAXP_b.MXPS; } static inline void pipe_wait_for_ready(rusb2_reg_t* rusb, unsigned num) { while (rusb->D0FIFOSEL_b.CURPIPE != num) ; while (!rusb->D0FIFOCTR_b.FRDY) {} } static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; const unsigned mps = edpt0_max_packet_size(rusb); const unsigned vld = rusb->CFIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; // pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len); tu_hwfifo_read(&rusb->CFIFO, buf, len, &access_mode); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return false; } static bool pipe0_xfer_out(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } const unsigned mps = edpt0_max_packet_size(rusb); const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; if (len) { tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; // pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len); tu_hwfifo_write(&rusb->CFIFO, buf, len, &access_mode); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } pipe->remaining = rem - len; return false; } static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; uint16_t fifo_sel = num | FIFOSEL_BIGEND; if (rusb2_is_highspeed_reg(rusb)) { fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT; } else { fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT; } rusb->D0FIFOSEL = fifo_sel; const unsigned mps = edpt_max_packet_size(rusb, num); pipe_wait_for_ready(rusb, num); const unsigned vld = rusb->D0FIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { // pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len); tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; tu_hwfifo_read(&rusb->D0FIFO, buf, len, &access_mode); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { rusb->D0FIFOCTR = RUSB2_D0FIFOCTR_BCLR_Msk; } rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } return false; } static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } uint16_t fifo_sel = num | FIFOSEL_BIGEND; if (rusb2_is_highspeed_reg(rusb)) { fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT; } else { fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT; } rusb->D0FIFOSEL = fifo_sel; const unsigned mps = edpt_max_packet_size(rusb, num); pipe_wait_for_ready(rusb, num); const unsigned len = TU_MIN(rem, mps); void *buf = pipe->buf; if (len) { // pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len); tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u), .param = (uintptr_t)rusb}; tu_hwfifo_write(&rusb->D0FIFO, buf, len, &access_mode); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { rusb->D0FIFOCTR = RUSB2_D0FIFOCTR_BVAL_Msk; } rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; return false; } static bool process_pipe0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { (void)dev_addr; rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned dir_in = tu_edpt_dir(ep_addr); uint16_t fifo_sel = (rusb2_is_highspeed_reg(rusb) ? RUSB2_FIFOSEL_MBW_32BIT : RUSB2_FIFOSEL_MBW_16BIT) | FIFOSEL_BIGEND; /* configure fifo direction and access unit settings */ if (dir_in == TUSB_DIR_OUT) { fifo_sel |= RUSB2_CFIFOSEL_ISEL_WRITE; } rusb->CFIFOSEL = fifo_sel; while ((rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) != (fifo_sel & RUSB2_CFIFOSEL_ISEL_WRITE)) { // wait until ISEL_WRITE take effect } pipe_state_t *pipe = &_hcd.pipe[0]; pipe->ep = ep_addr; pipe->length = buflen; pipe->remaining = buflen; if (buflen) { pipe->buf = buffer; if (!dir_in) { /* OUT */ TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); pipe0_xfer_out(rusb); } } else { /* ZLP */ pipe->buf = NULL; if (!dir_in) { /* OUT */ rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } if (dir_in == rusb->DCPCFG_b.DIR) { TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == rusb->DCPCTR_b.PID); rusb->DCPCTR_b.SQSET = 1; rusb->DCPCFG_b.DIR = dir_in ^ 1; } } rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return true; } static bool process_pipe_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen) { rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr - 1][dir_in][epn - 1]; TU_ASSERT(num); pipe_state_t *pipe = &_hcd.pipe[num]; pipe->buf = buffer; pipe->length = buflen; pipe->remaining = buflen; if (!dir_in) { /* OUT */ if (buflen) { pipe_xfer_out(rusb, num); } else { /* ZLP */ rusb->D0FIFOSEL = num; pipe_wait_for_ready(rusb, num); rusb->D0FIFOCTR = RUSB2_D0FIFOCTR_BVAL_Msk; rusb->D0FIFOSEL = 0; while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ } } else { volatile uint16_t *ctr = get_pipectr(rusb, num); volatile reg_pipetre_t *pt = get_pipetre(rusb, num); if (pt) { const unsigned mps = edpt_max_packet_size(rusb, num); if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; pt->TRE = TU_BIT(8); pt->TRN = (buflen + mps - 1) / mps; pt->TRENB = 1; } *ctr = RUSB2_PIPE_CTR_PID_BUF; } return true; } static bool process_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { return process_pipe0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } else { return process_pipe_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } } static void process_pipe0_bemp(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); bool completed = pipe0_xfer_out(rusb); if (completed) { pipe_state_t *pipe = &_hcd.pipe[0]; hcd_event_xfer_complete(pipe->dev, tu_edpt_addr(0, TUSB_DIR_OUT), pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); } } static void process_pipe_nrdy(uint8_t rhport, unsigned num) { rusb2_reg_t* rusb = RUSB2_REG(rhport); xfer_result_t result; uint16_t volatile *ctr = get_pipectr(rusb, num); TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\r\n", num, *ctr); switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) { default: return; case RUSB2_PIPE_CTR_PID_STALL: result = XFER_RESULT_STALLED; break; case RUSB2_PIPE_CTR_PID_STALL2: result = XFER_RESULT_STALLED; break; case RUSB2_PIPE_CTR_PID_NAK: result = XFER_RESULT_FAILED; break; } pipe_state_t *pipe = &_hcd.pipe[num]; hcd_event_xfer_complete(pipe->dev, pipe->ep, pipe->length - pipe->remaining, result, true); } static void process_pipe_brdy(uint8_t rhport, unsigned num) { rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned dir_in = tu_edpt_dir(pipe->ep); bool completed; if (dir_in) { /* IN */ if (num) { completed = pipe_xfer_in(rusb, num); } else { completed = pipe0_xfer_in(rusb); } } else { completed = pipe_xfer_out(rusb, num); } if (completed) { hcd_event_xfer_complete(pipe->dev, pipe->ep, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); TU_LOG(TU_RUSB2_HCD_DBG, "C %d %d\r\n", num, pipe->length - pipe->remaining); } } /*------------------------------------------------------------------*/ /* Host API *------------------------------------------------------------------*/ #if 0 // previously present in the rx driver before generalization static uint32_t disable_interrupt(void) { uint32_t pswi; #if defined(__CCRX__) pswi = get_psw() & 0x010000; clrpsw_i(); #else pswi = __builtin_rx_mvfc(0) & 0x010000; __builtin_rx_clrpsw('I'); #endif return pswi; } static void enable_interrupt(uint32_t pswi) { #if defined(__CCRX__) set_psw(get_psw() | pswi); #else __builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi); #endif } #endif bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); #ifdef RUSB2_SUPPORT_HIGHSPEED if (rusb2_is_highspeed_rhport(rhport) ) { rusb->SYSCFG_b.HSE = 1; rusb->PHYSET_b.HSEB = 0; rusb->PHYSET_b.DIRPD = 0; R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); rusb->PHYSET_b.PLLRESET = 0; rusb->LPSTS_b.SUSPENDM = 1; while ( !rusb->PLLSTA_b.PLLLOCK ); rusb->SYSCFG_b.DRPD = 1; rusb->SYSCFG_b.DCFM = 1; rusb->SYSCFG_b.DPRPU = 0; rusb->SYSCFG_b.CNEN = 1; rusb->BUSWAIT |= 0x0F00U; rusb->SOFCFG_b.INTL = 1; rusb->DVSTCTR0_b.VBUSEN = 1; rusb->CFIFOSEL_b.MBW = 1; rusb->D0FIFOSEL_b.MBW = 1; rusb->D1FIFOSEL_b.MBW = 1; rusb->INTSTS0 = 0; for ( volatile int i = 0; i < 30000; ++i ); rusb->SYSCFG_b.USBE = 1; } else #endif { rusb->SYSCFG_b.SCKE = 1; while ( !rusb->SYSCFG_b.SCKE ) {} rusb->SYSCFG_b.DCFM = 1; // Host function rusb->SYSCFG_b.DPRPU = 0; // Disable D+ pull up rusb->SYSCFG_b.DRPD = 1; // Enable D+/D- pull down rusb->DVSTCTR0_b.VBUSEN = 1; for ( volatile int i = 0; i < 30000; ++i ) {} // FIXME do we need to wait here? how long ? //R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS); rusb->SYSCFG_b.USBE = 1; // MCU specific PHY init rusb2_phy_init(); rusb->PHYSLEW = 0x5; rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ } /* Setup default control pipe */ rusb->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; rusb->DCPMAXP = 64; rusb->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk; rusb->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk; rusb->BEMPENB = 1; rusb->NRDYENB = 1; rusb->BRDYENB = 1; return true; } void hcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } void hcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } uint32_t hcd_frame_number(uint8_t rhport) { rusb2_reg_t *rusb = RUSB2_REG(rhport); return rusb->FRMNUM_b.FRNM; } /*--------------------------------------------------------------------+ * Port API *--------------------------------------------------------------------+*/ bool hcd_port_connect_status(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); const uint16_t line_state = rusb->SYSSTS0 & RUSB2_SYSSTS0_LNST_Msk; return line_state == RUSB2_SYSSTS0_LNST_FS_J || line_state == RUSB2_SYSSTS0_LNST_FS_K; } void hcd_port_reset(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb->DVSTCTR0_b.USBRST = 1; } void hcd_port_reset_end(uint8_t rhport) { rusb2_reg_t *rusb = RUSB2_REG(rhport); rusb->DVSTCTR0_b.USBRST = 0; } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); switch (rusb->DVSTCTR0_b.RHST) { case RUSB2_DVSTCTR0_RHST_HS: return TUSB_SPEED_HIGH; case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL; case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; default: return TUSB_SPEED_INVALID; } } void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { rusb2_reg_t* rusb = RUSB2_REG(rhport); uint16_t volatile *ctr; TU_ASSERT(dev_addr < 6,); /* USBa can only handle addresses from 0 to 5. */ if (!dev_addr) return; _hcd.ctl_mps[dev_addr] = 0; uint8_t *ep = &_hcd.ep[dev_addr - 1][0][0]; for (int i = 0; i < 2 * 15; ++i, ++ep) { unsigned num = *ep; if (!num || (dev_addr != _hcd.pipe[num].dev)) continue; ctr = (uint16_t volatile*)&rusb->PIPE_CTR[num - 1]; *ctr = 0; rusb->NRDYENB &= ~TU_BIT(num); rusb->BRDYENB &= ~TU_BIT(num); rusb->PIPESEL = num; rusb->PIPECFG = 0; rusb->PIPEMAXP = 0; _hcd.pipe[num].ep = 0; _hcd.pipe[num].dev = 0; *ep = 0; } } /*--------------------------------------------------------------------+ * Endpoints API *--------------------------------------------------------------------+*/ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ rusb2_reg_t* rusb = RUSB2_REG(rhport); TU_LOG(TU_RUSB2_HCD_DBG, "S %d %x\r\n", dev_addr, rusb->DCPCTR); TU_ASSERT(0 == rusb->DCPCTR_b.SUREQ); rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; _hcd.pipe[0].buf = NULL; _hcd.pipe[0].length = 8; _hcd.pipe[0].remaining = 0; _hcd.pipe[0].dev = dev_addr; while (rusb->DCPCTR_b.PBUSY) ; rusb->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; /* Set direction in advance for DATA stage */ uint8_t const bmRequesttype = setup_packet[0]; rusb->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0]; rusb->USBREQ = tu_htole16(p[0]); rusb->USBVAL = p[1]; rusb->USBINDX = p[2]; rusb->USBLENG = p[3]; rusb->DCPCTR_b.SUREQ = 1; return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) { TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned mps = tu_edpt_packet_size(ep_desc); if (0 == epn) { rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &rusb->DEVADD[0]; devadd += dev_addr; while (rusb->DCPCTR_b.PBUSY) {} rusb->DCPMAXP = (dev_addr << 12) | mps; *devadd = (TUSB_SPEED_FULL == bus_info.speed) ? RUSB2_DEVADD_USBSPD_FS : RUSB2_DEVADD_USBSPD_LS; _hcd.ctl_mps[dev_addr] = mps; return true; } const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { /* USBa supports up to 256 bytes */ return false; } const unsigned num = find_pipe(xfer); if (!num) return false; _hcd.pipe[num].dev = dev_addr; _hcd.pipe[num].ep = ep_addr; _hcd.ep[dev_addr - 1][dir_in][epn - 1] = num; /* setup pipe */ hcd_int_disable(rhport); rusb->PIPESEL = num; rusb->PIPEMAXP = (dev_addr << 12) | mps; volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; unsigned cfg = ((1 ^ dir_in) << 4) | epn; if (xfer == TUSB_XFER_BULK) { cfg |= RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk; } else if (xfer == TUSB_XFER_INTERRUPT) { cfg |= RUSB2_PIPECFG_TYPE_INT; } else { cfg |= RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk; } rusb->PIPECFG = cfg; rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->NRDYENB |= TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); if (!dir_in) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } hcd_int_enable(rhport); return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { bool r; hcd_int_disable(rhport); TU_LOG(TU_RUSB2_HCD_DBG, "X %d %x %u\r\n", dev_addr, ep_addr, buflen); r = process_edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); hcd_int_enable(rhport); return r; } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; // TODO not implemented yet return false; } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr); TU_ASSERT(ctr); const uint32_t pid = *ctr & 0x3; if (pid & 2) { *ctr = pid & 2; *ctr = 0; } *ctr = RUSB2_PIPE_CTR_SQCLR_Msk; unsigned const epn = tu_edpt_number(ep_addr); if (!epn) return true; if (!tu_edpt_dir(ep_addr)) { /* OUT */ *ctr = RUSB2_PIPE_CTR_PID_BUF; } return true; } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ #if defined(__CCRX__) TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { unsigned int count = 0; while ((value & 1) == 0) { value >>= 1; count++; } return count; } #endif void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; rusb2_reg_t* rusb = RUSB2_REG(rhport); unsigned is0 = rusb->INTSTS0; unsigned is1 = rusb->INTSTS1; /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ rusb->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1); rusb->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0); TU_LOG3("IS %04x %04x\r\n", is0, is1); is1 &= rusb->INTENB1; is0 &= rusb->INTENB0; if (is1 & RUSB2_INTSTS1_SACK_Msk) { /* Set DATA1 in advance for the next transfer. */ rusb->DCPCTR_b.SQSET = 1; hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); } if (is1 & RUSB2_INTSTS1_SIGN_Msk) { hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); } if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { rusb->DVSTCTR0_b.UACT = 1; rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; hcd_event_device_attach(rhport, true); } if (is1 & RUSB2_INTSTS1_DTCH_Msk) { rusb->DVSTCTR0_b.UACT = 0; if (rusb->DCPCTR_b.SUREQ) { rusb->DCPCTR_b.SUREQCLR = 1; } rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk; hcd_event_device_remove(rhport, true); } if (is0 & RUSB2_INTSTS0_BEMP_Msk) { const unsigned s = rusb->BEMPSTS; rusb->BEMPSTS = 0; if (s & 1) { process_pipe0_bemp(rhport); } } if (is0 & RUSB2_INTSTS0_NRDY_Msk) { const unsigned m = rusb->NRDYENB; unsigned s = rusb->NRDYSTS & m; rusb->NRDYSTS = ~s; while (s) { const unsigned num = __builtin_ctz(s); process_pipe_nrdy(rhport, num); s &= ~TU_BIT(num); } } if (is0 & RUSB2_INTSTS0_BRDY_Msk) { const unsigned m = rusb->BRDYENB; unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { const unsigned num = __builtin_ctz(s); process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); } } } #endif ================================================ FILE: src/portable/renesas/rusb2/rusb2_common.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if defined(TUP_USBIP_RUSB2) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED) #include "osal/osal.h" #include "common/tusb_fifo.h" #include "rusb2_common.h" #if TU_CHECK_MCU(OPT_MCU_RAXXX) #include "rusb2_ra.h" // USBFS_INT_IRQn and USBHS_USB_INT_RESUME_IRQn are generated by FSP rusb2_controller_t rusb2_controller[] = { {.reg_base = R_USB_FS0_BASE, .irqnum = USBFS_INT_IRQn}, #ifdef RUSB2_SUPPORT_HIGHSPEED {.reg_base = R_USB_HS0_BASE, .irqnum = USBHS_USB_INT_RESUME_IRQn}, #endif }; // Application API for setting IRQ number. May throw warnings for missing prototypes. void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum); void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum) { rusb2_controller[rhport].irqnum = irqnum; } #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ static void hwfifo_set_mbw(rusb2_reg_t *rusb, uintptr_t hwfifo, uint16_t mbw) { volatile uint16_t *fifo_sel; if (hwfifo == (uintptr_t)&rusb->CFIFO) { fifo_sel = &rusb->CFIFOSEL; } else if (hwfifo == (uintptr_t)&rusb->D0FIFO) { fifo_sel = &rusb->D0FIFOSEL; } else if (hwfifo == (uintptr_t)&rusb->D1FIFO) { fifo_sel = &rusb->D1FIFOSEL; } else { return; } *fifo_sel = (*fifo_sel & ~RUSB2_CFIFOSEL_MBW_Msk) | mbw; } // write to hwfifo from buffer with access mode void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) { rusb2_reg_t *rusb = (rusb2_reg_t *)access_mode->param; const uint8_t *buf8 = (const uint8_t *)src; volatile uint16_t *ff16; volatile uint8_t *ff8; const bool is_highspeed = rusb2_is_highspeed_reg(rusb); if (is_highspeed) { ff16 = (volatile uint16_t *)((uintptr_t)hwfifo + 2); ff8 = (volatile uint8_t *)((uintptr_t)hwfifo + 3); } else { ff16 = (volatile uint16_t *)hwfifo; ff8 = ((volatile uint8_t *)hwfifo); } // 32-bit access for highspeed if (is_highspeed) { volatile uint32_t *ff32 = (volatile uint32_t *)hwfifo; while (len >= 4) { *ff32 = tu_unaligned_read32(buf8); buf8 += 4; len -= 4; } if (len >= 2) { // switch to 16-bit access hwfifo_set_mbw(rusb, (uintptr_t)hwfifo, RUSB2_FIFOSEL_MBW_16BIT); } } // 16-bit access while (len >= 2) { *ff16 = tu_unaligned_read16(buf8); buf8 += 2; len -= 2; } // 8-bit access does not need to change MBW if (len > 0) { *ff8 = *buf8; ++buf8; } } #endif ================================================ FILE: src/portable/renesas/rusb2/rusb2_common.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #pragma once #include "common/tusb_common.h" #include "rusb2_type.h" #if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) #include "rusb2_rx.h" #elif TU_CHECK_MCU(OPT_MCU_RAXXX) #include "rusb2_ra.h" // Hack for D0FIFO definitions on RA Cortex-M23 #if defined(RENESAS_CORTEX_M23) #define D0FIFO CFIFO #define D0FIFOSEL CFIFOSEL #define D0FIFOSEL_b CFIFOSEL_b #define D1FIFOSEL CFIFOSEL #define D1FIFOSEL_b CFIFOSEL_b #define D0FIFOCTR CFIFOCTR #define D0FIFOCTR_b CFIFOCTR_b #endif #else #error "Unsupported MCU" #endif //--------------------------------------------------------------------+ // Common //--------------------------------------------------------------------+ enum { FIFOSEL_BIGEND = (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0) }; ================================================ FILE: src/portable/renesas/rusb2/rusb2_ra.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Rafael Silva (@perigoso) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _RUSB2_RA_H_ #define _RUSB2_RA_H_ #ifdef __cplusplus extern "C" { #endif #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #pragma GCC diagnostic ignored "-Wundef" // extra push due to https://github.com/renesas/fsp/pull/278 #pragma GCC diagnostic push #endif /* renesas fsp api */ #include "bsp_api.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // IAR does not have __builtin_ctz #if defined(__ICCARM__) #define __builtin_ctz(x) __iar_builtin_CLZ(__iar_builtin_RBIT(x)) #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef struct { uint32_t reg_base; int32_t irqnum; }rusb2_controller_t; #if defined(BSP_MCU_GROUP_RA6M5) || defined(BSP_MCU_GROUP_RA6M3) || (BSP_CFG_MCU_PART_SERIES == 8) #define RUSB2_SUPPORT_HIGHSPEED #define RUSB2_CONTROLLER_COUNT 2 #define rusb2_is_highspeed_rhport(_p) (_p == 1) #define rusb2_is_highspeed_reg(_reg) (_reg == RUSB2_REG(1)) #else #define RUSB2_CONTROLLER_COUNT 1 #define rusb2_is_highspeed_rhport(_p) (false) #define rusb2_is_highspeed_reg(_reg) (false) #endif extern rusb2_controller_t rusb2_controller[]; #define RUSB2_REG(_p) ((rusb2_reg_t*) rusb2_controller[_p].reg_base) //--------------------------------------------------------------------+ // RUSB2 API //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { uint32_t const mask = 1U << (11+rhport); if (start) { R_MSTP->MSTPCRB &= ~mask; }else { R_MSTP->MSTPCRB |= mask; } } TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { NVIC_EnableIRQ(rusb2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) { NVIC_DisableIRQ(rusb2_controller[rhport].irqnum); } // MCU specific PHY init TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) { } #ifdef __cplusplus } #endif #endif /* _RUSB2_RA_H_ */ ================================================ FILE: src/portable/renesas/rusb2/rusb2_rx.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2020 Koji Kitayama * Portions copyrighted (c) 2021 Roland Winistoerfer * Copyright (c) 2022 Rafael Silva (@perigoso) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _RUSB2_RX_H_ #define _RUSB2_RX_H_ #ifdef __cplusplus extern "C" { #endif #include "iodefine.h" #define RUSB2_REG_BASE (0x000A0000) TU_ATTR_ALWAYS_INLINE static inline rusb2_reg_t* RUSB2_REG(uint8_t rhport) { (void) rhport; return (rusb2_reg_t *) RUSB2_REG_BASE; } #define rusb2_is_highspeed_rhport(_p) (false) #define rusb2_is_highspeed_reg(_reg) (false) //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Start/Stop MSTP TODO implement later TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { (void) rhport; (void) start; } TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { (void) rhport; #if (CFG_TUSB_MCU == OPT_MCU_RX72N) IEN(PERIB, INTB185) = 1; #else IEN(USB0, USBI0) = 1; #endif } TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) { (void) rhport; #if (CFG_TUSB_MCU == OPT_MCU_RX72N) IEN(PERIB, INTB185) = 0; #else IEN(USB0, USBI0) = 0; #endif } // MCU specific PHY init TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) { #if (CFG_TUSB_MCU == OPT_MCU_RX72N) IR(PERIB, INTB185) = 0; #else IR(USB0, USBI0) = 0; #endif } #ifdef __cplusplus } #endif #endif /* _RUSB2_RX_H_ */ ================================================ FILE: src/portable/renesas/rusb2/rusb2_type.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Rafael Silva (@perigoso) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_RUSB2_TYPE_H_ #define TUSB_RUSB2_TYPE_H_ #include #include #ifdef __cplusplus extern "C" { #endif // CCRX specific attribute to generate a Code that Accesses Variables in the Declared Size #ifdef __CCRX__ #define _ccrx_evenaccess __evenaccess #else #define _ccrx_evenaccess #endif //--------------------------------------------------------------------+ // Register Definitions //--------------------------------------------------------------------+ /* Start of definition of packed structs (used by the CCRX toolchain) */ TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN // TODO same as RUSB2_PIPE_TR_t typedef struct TU_ATTR_PACKED _ccrx_evenaccess { union { struct { uint16_t : 8; uint16_t TRCLR: 1; uint16_t TRENB: 1; uint16_t : 0; }; uint16_t TRE; }; uint16_t TRN; } reg_pipetre_t; typedef struct { union { volatile uint16_t E; /* (@ 0x00000000) Pipe Transaction Counter Enable Register */ struct TU_ATTR_PACKED { uint16_t : 8; volatile uint16_t TRCLR : 1; /* [8..8] Transaction Counter Clear */ volatile uint16_t TRENB : 1; /* [9..9] Transaction Counter Enable */ uint16_t : 6; } E_b; }; union { volatile uint16_t N; /* (@ 0x00000002) Pipe Transaction Counter Register */ struct TU_ATTR_PACKED { volatile uint16_t TRNCNT : 16; /* [15..0] Transaction Counter */ } N_b; }; } RUSB2_PIPE_TR_t; /* Size = 4 (0x4) */ /* RUSB2 Registers Structure */ typedef struct _ccrx_evenaccess { union { volatile uint16_t SYSCFG; /* (@ 0x00000000) System Configuration Control Register */ struct TU_ATTR_PACKED { volatile uint16_t USBE : 1; /* [0..0] USB Operation Enable */ uint16_t : 2; volatile uint16_t DMRPU : 1; /* [3..3] D- Line Resistor Control */ volatile uint16_t DPRPU : 1; /* [4..4] D+ Line Resistor Control */ volatile uint16_t DRPD : 1; /* [5..5] D+/D- Line Resistor Control */ volatile uint16_t DCFM : 1; /* [6..6] Controller Function Select */ volatile uint16_t HSE : 1; // [7..7] High-Speed Operation Enable volatile uint16_t CNEN : 1; /* [8..8] CNEN Single End Receiver Enable */ uint16_t : 1; volatile uint16_t SCKE : 1; /* [10..10] USB Clock Enable */ uint16_t : 5; } SYSCFG_b; }; union { volatile uint16_t BUSWAIT; /* (@ 0x00000002) CPU Bus Wait Register */ struct TU_ATTR_PACKED { volatile uint16_t BWAIT : 4; /* [3..0] CPU Bus Access Wait Specification BWAIT waits (BWAIT+2 access cycles) */ uint16_t : 12; } BUSWAIT_b; }; union { volatile const uint16_t SYSSTS0; /* (@ 0x00000004) System Configuration Status Register 0 */ struct TU_ATTR_PACKED { volatile const uint16_t LNST : 2; /* [1..0] USB Data Line Status Monitor */ volatile const uint16_t IDMON : 1; /* [2..2] External ID0 Input Pin Monitor */ uint16_t : 2; volatile const uint16_t SOFEA : 1; /* [5..5] SOF Active Monitor While Host Controller Function is Selected. */ volatile const uint16_t HTACT : 1; /* [6..6] USB Host Sequencer Status Monitor */ uint16_t : 7; volatile const uint16_t OVCMON : 2; /* [15..14] External USB0_OVRCURA/ USB0_OVRCURB Input Pin Monitor */ } SYSSTS0_b; }; union { volatile const uint16_t PLLSTA; /* (@ 0x00000006) PLL Status Register */ struct TU_ATTR_PACKED { volatile const uint16_t PLLLOCK : 1; /* [0..0] PLL Lock Flag */ uint16_t : 15; } PLLSTA_b; }; union { volatile uint16_t DVSTCTR0; /* (@ 0x00000008) Device State Control Register 0 */ struct TU_ATTR_PACKED { volatile const uint16_t RHST : 3; /* [2..0] USB Bus Reset Status */ uint16_t : 1; volatile uint16_t UACT : 1; /* [4..4] USB Bus Enable */ volatile uint16_t RESUME : 1; /* [5..5] Resume Output */ volatile uint16_t USBRST : 1; /* [6..6] USB Bus Reset Output */ volatile uint16_t RWUPE : 1; /* [7..7] Wakeup Detection Enable */ volatile uint16_t WKUP : 1; /* [8..8] Wakeup Output */ volatile uint16_t VBUSEN : 1; /* [9..9] USB_VBUSEN Output Pin Control */ volatile uint16_t EXICEN : 1; /* [10..10] USB_EXICEN Output Pin Control */ volatile uint16_t HNPBTOA : 1; /* [11..11] Host Negotiation Protocol (HNP) */ uint16_t : 4; } DVSTCTR0_b; }; volatile const uint16_t RESERVED; union { volatile uint16_t TESTMODE; /* (@ 0x0000000C) USB Test Mode Register */ struct TU_ATTR_PACKED { volatile uint16_t UTST : 4; /* [3..0] Test Mode */ uint16_t : 12; } TESTMODE_b; }; volatile const uint16_t RESERVED1; volatile const uint32_t RESERVED2; union { volatile uint32_t CFIFO; /* (@ 0x00000014) CFIFO Port Register */ struct TU_ATTR_PACKED { union { volatile uint16_t CFIFOL; /* (@ 0x00000014) CFIFO Port Register L */ volatile uint8_t CFIFOLL; /* (@ 0x00000014) CFIFO Port Register LL */ }; union { volatile uint16_t CFIFOH; /* (@ 0x00000016) CFIFO Port Register H */ struct TU_ATTR_PACKED { volatile const uint8_t RESERVED3; volatile uint8_t CFIFOHH; /* (@ 0x00000017) CFIFO Port Register HH */ }; }; }; }; union { volatile uint32_t D0FIFO; /* (@ 0x00000018) D0FIFO Port Register */ struct TU_ATTR_PACKED { union { volatile uint16_t D0FIFOL; /* (@ 0x00000018) D0FIFO Port Register L */ volatile uint8_t D0FIFOLL; /* (@ 0x00000018) D0FIFO Port Register LL */ }; union { volatile uint16_t D0FIFOH; /* (@ 0x0000001A) D0FIFO Port Register H */ struct TU_ATTR_PACKED { volatile const uint8_t RESERVED4; volatile uint8_t D0FIFOHH; /* (@ 0x0000001B) D0FIFO Port Register HH */ }; }; }; }; union { volatile uint32_t D1FIFO; /* (@ 0x0000001C) D1FIFO Port Register */ struct TU_ATTR_PACKED { union { volatile uint16_t D1FIFOL; /* (@ 0x0000001C) D1FIFO Port Register L */ volatile uint8_t D1FIFOLL; /* (@ 0x0000001C) D1FIFO Port Register LL */ }; union { volatile uint16_t D1FIFOH; /* (@ 0x0000001E) D1FIFO Port Register H */ struct TU_ATTR_PACKED { volatile const uint8_t RESERVED5; volatile uint8_t D1FIFOHH; /* (@ 0x0000001F) D1FIFO Port Register HH */ }; }; }; }; union { volatile uint16_t CFIFOSEL; /* (@ 0x00000020) CFIFO Port Select Register */ struct TU_ATTR_PACKED { volatile uint16_t CURPIPE : 4; /* [3..0] CFIFO Port Access Pipe Specification */ uint16_t : 1; volatile uint16_t ISEL : 1; /* [5..5] CFIFO Port Access Direction When DCP is Selected */ uint16_t : 2; volatile uint16_t BIGEND : 1; /* [8..8] CFIFO Port Endian Control */ uint16_t : 1; volatile uint16_t MBW : 2; /* [11..10] CFIFO Port Access Bit Width */ uint16_t : 2; volatile uint16_t REW : 1; /* [14..14] Buffer Pointer Rewind */ volatile uint16_t RCNT : 1; /* [15..15] Read Count Mode */ } CFIFOSEL_b; }; union { volatile uint16_t CFIFOCTR; /* (@ 0x00000022) CFIFO Port Control Register */ struct TU_ATTR_PACKED { volatile const uint16_t DTLN : 12; /* [11..0] Receive Data LengthIndicates the length of the receive data. */ uint16_t : 1; volatile const uint16_t FRDY : 1; /* [13..13] FIFO Port Ready */ volatile uint16_t BCLR : 1; /* [14..14] CPU Buffer ClearNote: Only 0 can be read. */ volatile uint16_t BVAL : 1; /* [15..15] Buffer Memory Valid Flag */ } CFIFOCTR_b; }; volatile const uint32_t RESERVED6; union { volatile uint16_t D0FIFOSEL; /* (@ 0x00000028) D0FIFO Port Select Register */ struct TU_ATTR_PACKED { volatile uint16_t CURPIPE : 4; /* [3..0] FIFO Port Access Pipe Specification */ uint16_t : 4; volatile uint16_t BIGEND : 1; /* [8..8] FIFO Port Endian Control */ uint16_t : 1; volatile uint16_t MBW : 2; /* [11..10] FIFO Port Access Bit Width */ volatile uint16_t DREQE : 1; /* [12..12] DMA/DTC Transfer Request Enable */ volatile uint16_t DCLRM : 1; /* [13..13] Auto Buffer Memory Clear Mode Accessed after Specified Pipe Data is Read */ volatile uint16_t REW : 1; /* [14..14] Buffer Pointer RewindNote: Only 0 can be read. */ volatile uint16_t RCNT : 1; /* [15..15] Read Count Mode */ } D0FIFOSEL_b; }; union { volatile uint16_t D0FIFOCTR; /* (@ 0x0000002A) D0FIFO Port Control Register */ struct TU_ATTR_PACKED { volatile const uint16_t DTLN : 12; /* [11..0] Receive Data LengthIndicates the length of the receive data. */ uint16_t : 1; volatile const uint16_t FRDY : 1; /* [13..13] FIFO Port Ready */ volatile uint16_t BCLR : 1; /* [14..14] CPU Buffer ClearNote: Only 0 can be read. */ volatile uint16_t BVAL : 1; /* [15..15] Buffer Memory Valid Flag */ } D0FIFOCTR_b; }; union { volatile uint16_t D1FIFOSEL; /* (@ 0x0000002C) D1FIFO Port Select Register */ struct TU_ATTR_PACKED { volatile uint16_t CURPIPE : 4; /* [3..0] FIFO Port Access Pipe Specification */ uint16_t : 4; volatile uint16_t BIGEND : 1; /* [8..8] FIFO Port Endian Control */ uint16_t : 1; volatile uint16_t MBW : 2; /* [11..10] FIFO Port Access Bit Width */ volatile uint16_t DREQE : 1; /* [12..12] DMA/DTC Transfer Request Enable */ volatile uint16_t DCLRM : 1; /* [13..13] Auto Buffer Memory Clear Mode Accessed after Specified Pipe Data is Read */ volatile uint16_t REW : 1; /* [14..14] Buffer Pointer Rewind */ volatile uint16_t RCNT : 1; /* [15..15] Read Count Mode */ } D1FIFOSEL_b; }; union { volatile uint16_t D1FIFOCTR; /* (@ 0x0000002E) D1FIFO Port Control Register */ struct TU_ATTR_PACKED { volatile const uint16_t DTLN : 12; /* [11..0] Receive Data LengthIndicates the length of the receive data. */ uint16_t : 1; volatile const uint16_t FRDY : 1; /* [13..13] FIFO Port Ready */ volatile uint16_t BCLR : 1; /* [14..14] CPU Buffer ClearNote: Only 0 can be read. */ volatile uint16_t BVAL : 1; /* [15..15] Buffer Memory Valid Flag */ } D1FIFOCTR_b; }; union { volatile uint16_t INTENB0; /* (@ 0x00000030) Interrupt Enable Register 0 */ struct TU_ATTR_PACKED { uint16_t : 8; volatile uint16_t BRDYE : 1; /* [8..8] Buffer Ready Interrupt Enable */ volatile uint16_t NRDYE : 1; /* [9..9] Buffer Not Ready Response Interrupt Enable */ volatile uint16_t BEMPE : 1; /* [10..10] Buffer Empty Interrupt Enable */ volatile uint16_t CTRE : 1; /* [11..11] Control Transfer Stage Transition Interrupt Enable */ volatile uint16_t DVSE : 1; /* [12..12] Device State Transition Interrupt Enable */ volatile uint16_t SOFE : 1; /* [13..13] Frame Number Update Interrupt Enable */ volatile uint16_t RSME : 1; /* [14..14] Resume Interrupt Enable */ volatile uint16_t VBSE : 1; /* [15..15] VBUS Interrupt Enable */ } INTENB0_b; }; union { volatile uint16_t INTENB1; /* (@ 0x00000032) Interrupt Enable Register 1 */ struct TU_ATTR_PACKED { volatile uint16_t PDDETINTE0 : 1; /* [0..0] PDDETINT0 Detection Interrupt Enable */ uint16_t : 3; volatile uint16_t SACKE : 1; /* [4..4] Setup Transaction Normal Response Interrupt Enable */ volatile uint16_t SIGNE : 1; /* [5..5] Setup Transaction Error Interrupt Enable */ volatile uint16_t EOFERRE : 1; /* [6..6] EOF Error Detection Interrupt Enable */ uint16_t : 1; volatile uint16_t LPMENDE : 1; /*!< [8..8] LPM Transaction End Interrupt Enable */ volatile uint16_t L1RSMENDE : 1; /*!< [9..9] L1 Resume End Interrupt Enable */ uint16_t : 1; volatile uint16_t ATTCHE : 1; /* [11..11] Connection Detection Interrupt Enable */ volatile uint16_t DTCHE : 1; /* [12..12] Disconnection Detection Interrupt Enable */ uint16_t : 1; volatile uint16_t BCHGE : 1; /* [14..14] USB Bus Change Interrupt Enable */ volatile uint16_t OVRCRE : 1; /* [15..15] Overcurrent Input Change Interrupt Enable */ } INTENB1_b; }; volatile const uint16_t RESERVED7; union { volatile uint16_t BRDYENB; /* (@ 0x00000036) BRDY Interrupt Enable Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0BRDYE : 1; /* [0..0] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE1BRDYE : 1; /* [1..1] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE2BRDYE : 1; /* [2..2] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE3BRDYE : 1; /* [3..3] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE4BRDYE : 1; /* [4..4] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE5BRDYE : 1; /* [5..5] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE6BRDYE : 1; /* [6..6] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE7BRDYE : 1; /* [7..7] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8BRDYE : 1; /* [8..8] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9BRDYE : 1; /* [9..9] BRDY Interrupt Enable for PIPE */ uint16_t : 6; } BRDYENB_b; }; union { volatile uint16_t NRDYENB; /* (@ 0x00000038) NRDY Interrupt Enable Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0NRDYE : 1; /* [0..0] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE1NRDYE : 1; /* [1..1] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE2NRDYE : 1; /* [2..2] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE3NRDYE : 1; /* [3..3] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE4NRDYE : 1; /* [4..4] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE5NRDYE : 1; /* [5..5] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE6NRDYE : 1; /* [6..6] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE7NRDYE : 1; /* [7..7] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8NRDYE : 1; /* [8..8] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9NRDYE : 1; /* [9..9] NRDY Interrupt Enable for PIPE */ uint16_t : 6; } NRDYENB_b; }; union { volatile uint16_t BEMPENB; /* (@ 0x0000003A) BEMP Interrupt Enable Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0BEMPE : 1; /* [0..0] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE1BEMPE : 1; /* [1..1] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE2BEMPE : 1; /* [2..2] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE3BEMPE : 1; /* [3..3] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE4BEMPE : 1; /* [4..4] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE5BEMPE : 1; /* [5..5] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE6BEMPE : 1; /* [6..6] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE7BEMPE : 1; /* [7..7] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE8BEMPE : 1; /* [8..8] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE9BEMPE : 1; /* [9..9] BEMP Interrupt Enable for PIPE */ uint16_t : 6; } BEMPENB_b; }; union { volatile uint16_t SOFCFG; /* (@ 0x0000003C) SOF Output Configuration Register */ struct TU_ATTR_PACKED { uint16_t : 4; volatile const uint16_t EDGESTS : 1; /* [4..4] Edge Interrupt Output Status Monitor */ volatile uint16_t INTL : 1; /* [5..5] Interrupt Output Sense Select */ volatile uint16_t BRDYM : 1; /* [6..6] BRDY Interrupt Status Clear Timing */ uint16_t : 1; volatile uint16_t TRNENSEL : 1; /* [8..8] Transaction-Enabled Time Select */ uint16_t : 7; } SOFCFG_b; }; union { volatile uint16_t PHYSET; /* (@ 0x0000003E) PHY Setting Register */ struct TU_ATTR_PACKED { volatile uint16_t DIRPD : 1; /* [0..0] Power-Down Control */ volatile uint16_t PLLRESET : 1; /* [1..1] PLL Reset Control */ uint16_t : 1; volatile uint16_t CDPEN : 1; /* [3..3] Charging Downstream Port Enable */ volatile uint16_t CLKSEL : 2; /* [5..4] Input System Clock Frequency */ uint16_t : 2; volatile uint16_t REPSEL : 2; /* [9..8] Terminating Resistance Adjustment Cycle */ uint16_t : 1; volatile uint16_t REPSTART : 1; /* [11..11] Forcibly Start Terminating Resistance Adjustment */ uint16_t : 3; volatile uint16_t HSEB : 1; /* [15..15] CL-Only Mode */ } PHYSET_b; }; union { volatile uint16_t INTSTS0; /* (@ 0x00000040) Interrupt Status Register 0 */ struct TU_ATTR_PACKED { volatile const uint16_t CTSQ : 3; /* [2..0] Control Transfer Stage */ volatile uint16_t VALID : 1; /* [3..3] USB Request Reception */ volatile const uint16_t DVSQ : 3; /* [6..4] Device State */ volatile const uint16_t VBSTS : 1; /* [7..7] VBUS Input Status */ volatile const uint16_t BRDY : 1; /* [8..8] Buffer Ready Interrupt Status */ volatile const uint16_t NRDY : 1; /* [9..9] Buffer Not Ready Interrupt Status */ volatile const uint16_t BEMP : 1; /* [10..10] Buffer Empty Interrupt Status */ volatile uint16_t CTRT : 1; /* [11..11] Control Transfer Stage Transition Interrupt Status */ volatile uint16_t DVST : 1; /* [12..12] Device State Transition Interrupt Status */ volatile uint16_t SOFR : 1; /* [13..13] Frame Number Refresh Interrupt Status */ volatile uint16_t RESM : 1; /* [14..14] Resume Interrupt Status */ volatile uint16_t VBINT : 1; /* [15..15] VBUS Interrupt Status */ } INTSTS0_b; }; union { volatile uint16_t INTSTS1; /* (@ 0x00000042) Interrupt Status Register 1 */ struct TU_ATTR_PACKED { volatile uint16_t PDDETINT0 : 1; /* [0..0] PDDET0 Detection Interrupt Status */ uint16_t : 3; volatile uint16_t SACK : 1; /* [4..4] Setup Transaction Normal Response Interrupt Status */ volatile uint16_t SIGN : 1; /* [5..5] Setup Transaction Error Interrupt Status */ volatile uint16_t EOFERR : 1; /* [6..6] EOF Error Detection Interrupt Status */ uint16_t : 1; volatile uint16_t LPMEND : 1; /* [8..8] LPM Transaction End Interrupt Status */ volatile uint16_t L1RSMEND : 1; /* [9..9] L1 Resume End Interrupt Status */ uint16_t : 1; volatile uint16_t ATTCH : 1; /* [11..11] ATTCH Interrupt Status */ volatile uint16_t DTCH : 1; /* [12..12] USB Disconnection Detection Interrupt Status */ uint16_t : 1; volatile uint16_t BCHG : 1; /* [14..14] USB Bus Change Interrupt Status */ volatile uint16_t OVRCR : 1; /* [15..15] Overcurrent Input Change Interrupt Status */ } INTSTS1_b; }; volatile const uint16_t RESERVED8; union { volatile uint16_t BRDYSTS; /* (@ 0x00000046) BRDY Interrupt Status Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0BRDY : 1; /* [0..0] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE1BRDY : 1; /* [1..1] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE2BRDY : 1; /* [2..2] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE3BRDY : 1; /* [3..3] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE4BRDY : 1; /* [4..4] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE5BRDY : 1; /* [5..5] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE6BRDY : 1; /* [6..6] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE7BRDY : 1; /* [7..7] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8BRDY : 1; /* [8..8] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9BRDY : 1; /* [9..9] BRDY Interrupt Status for PIPE */ uint16_t : 6; } BRDYSTS_b; }; union { volatile uint16_t NRDYSTS; /* (@ 0x00000048) NRDY Interrupt Status Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0NRDY : 1; /* [0..0] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE1NRDY : 1; /* [1..1] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE2NRDY : 1; /* [2..2] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE3NRDY : 1; /* [3..3] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE4NRDY : 1; /* [4..4] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE5NRDY : 1; /* [5..5] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE6NRDY : 1; /* [6..6] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE7NRDY : 1; /* [7..7] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8NRDY : 1; /* [8..8] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9NRDY : 1; /* [9..9] NRDY Interrupt Status for PIPE */ uint16_t : 6; } NRDYSTS_b; }; union { volatile uint16_t BEMPSTS; /* (@ 0x0000004A) BEMP Interrupt Status Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPE0BEMP : 1; /* [0..0] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE1BEMP : 1; /* [1..1] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE2BEMP : 1; /* [2..2] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE3BEMP : 1; /* [3..3] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE4BEMP : 1; /* [4..4] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE5BEMP : 1; /* [5..5] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE6BEMP : 1; /* [6..6] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE7BEMP : 1; /* [7..7] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE8BEMP : 1; /* [8..8] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE9BEMP : 1; /* [9..9] BEMP Interrupt Status for PIPE */ uint16_t : 6; } BEMPSTS_b; }; union { volatile uint16_t FRMNUM; /* (@ 0x0000004C) Frame Number Register */ struct TU_ATTR_PACKED { volatile const uint16_t FRNM : 11; /* [10..0] Frame NumberLatest frame number */ uint16_t : 3; volatile uint16_t CRCE : 1; /* [14..14] Receive Data Error */ volatile uint16_t OVRN : 1; /* [15..15] Overrun/Underrun Detection Status */ } FRMNUM_b; }; union { volatile uint16_t UFRMNUM; /* (@ 0x0000004E) uFrame Number Register */ struct TU_ATTR_PACKED { volatile const uint16_t UFRNM : 3; /* [2..0] MicroframeIndicate the microframe number. */ uint16_t : 12; volatile uint16_t DVCHG : 1; /* [15..15] Device State Change */ } UFRMNUM_b; }; union { volatile uint16_t USBADDR; /* (@ 0x00000050) USB Address Register */ struct TU_ATTR_PACKED { volatile const uint16_t USBADDR : 7; /* [6..0] USB Address In device controller mode */ uint16_t : 1; volatile uint16_t STSRECOV0 : 3; /* [10..8] Status Recovery */ uint16_t : 5; } USBADDR_b; }; volatile const uint16_t RESERVED9; union { volatile uint16_t USBREQ; /* (@ 0x00000054) USB Request Type Register */ struct TU_ATTR_PACKED { volatile uint16_t BMREQUESTTYPE : 8; /* [7..0] Request TypeThese bits store the USB request bmRequestType value. */ volatile uint16_t BREQUEST : 8; /* [15..8] RequestThese bits store the USB request bRequest value. */ } USBREQ_b; }; union { volatile uint16_t USBVAL; /* (@ 0x00000056) USB Request Value Register */ struct TU_ATTR_PACKED { volatile uint16_t WVALUE : 16; /* [15..0] ValueThese bits store the USB request Value value. */ } USBVAL_b; }; union { volatile uint16_t USBINDX; /* (@ 0x00000058) USB Request Index Register */ struct TU_ATTR_PACKED { volatile uint16_t WINDEX : 16; /* [15..0] IndexThese bits store the USB request wIndex value. */ } USBINDX_b; }; union { volatile uint16_t USBLENG; /* (@ 0x0000005A) USB Request Length Register */ struct TU_ATTR_PACKED { volatile uint16_t WLENGTH : 16; /* [15..0] LengthThese bits store the USB request wLength value. */ } USBLENG_b; }; union { volatile uint16_t DCPCFG; /* (@ 0x0000005C) DCP Configuration Register */ struct TU_ATTR_PACKED { uint16_t : 4; volatile uint16_t DIR : 1; /* [4..4] Transfer Direction */ uint16_t : 2; volatile uint16_t SHTNAK : 1; /* [7..7] Pipe Disabled at End of Transfer */ volatile uint16_t CNTMD : 1; /* [8..8] Continuous Transfer Mode */ uint16_t : 7; } DCPCFG_b; }; union { volatile uint16_t DCPMAXP; /* (@ 0x0000005E) DCP Maximum Packet Size Register */ struct TU_ATTR_PACKED { volatile uint16_t MXPS : 7; /* [6..0] Maximum Packet Size */ uint16_t : 5; volatile uint16_t DEVSEL : 4; /* [15..12] Device Select */ } DCPMAXP_b; }; union { volatile uint16_t DCPCTR; /* (@ 0x00000060) DCP Control Register */ struct TU_ATTR_PACKED { volatile uint16_t PID : 2; /* [1..0] Response PID */ volatile uint16_t CCPL : 1; /* [2..2] Control Transfer End Enable */ uint16_t : 2; volatile const uint16_t PBUSY : 1; /* [5..5] Pipe Busy */ volatile const uint16_t SQMON : 1; /* [6..6] Sequence Toggle Bit Monitor */ volatile uint16_t SQSET : 1; /* [7..7] Sequence Toggle Bit Set */ volatile uint16_t SQCLR : 1; /* [8..8] Sequence Toggle Bit Clear */ uint16_t : 2; volatile uint16_t SUREQCLR : 1; /* [11..11] SUREQ Bit Clear */ volatile uint16_t CSSTS : 1; /* [12..12] Split Transaction COMPLETE SPLIT(CSPLIT) Status */ volatile uint16_t CSCLR : 1; /* [13..13] Split Transaction CSPLIT Status Clear */ volatile uint16_t SUREQ : 1; /* [14..14] Setup Token Transmission */ volatile const uint16_t BSTS : 1; /* [15..15] Buffer Status */ } DCPCTR_b; }; volatile const uint16_t RESERVED10; union { volatile uint16_t PIPESEL; /* (@ 0x00000064) Pipe Window Select Register */ struct TU_ATTR_PACKED { volatile uint16_t PIPESEL : 4; /* [3..0] Pipe Window Select */ uint16_t : 12; } PIPESEL_b; }; volatile const uint16_t RESERVED11; union { volatile uint16_t PIPECFG; /* (@ 0x00000068) Pipe Configuration Register */ struct TU_ATTR_PACKED { volatile uint16_t EPNUM : 4; /* [3..0] Endpoint Number */ volatile uint16_t DIR : 1; /* [4..4] Transfer Direction */ uint16_t : 2; volatile uint16_t SHTNAK : 1; /* [7..7] Pipe Disabled at End of Transfer */ volatile uint16_t CNTMD : 1; /* [8..8] Continuous Transfer Mode */ volatile uint16_t DBLB : 1; /* [9..9] Double Buffer Mode */ volatile uint16_t BFRE : 1; /* [10..10] BRDY Interrupt Operation Specification */ uint16_t : 3; volatile uint16_t TYPE : 2; /* [15..14] Transfer Type */ } PIPECFG_b; }; union { volatile uint16_t PIPEBUF; /*!< (@ 0x0000006A) Pipe Buffer Register */ struct { volatile uint16_t BUFNMB : 8; // [7..0] Buffer NumberThese bits specify the FIFO buffer number of the selected pipe (04h to 87h) uint16_t : 2; volatile uint16_t BUFSIZE : 5; /*!< [14..10] Buffer Size 00h: 64 bytes 01h: 128 bytes : 1Fh: 2 Kbytes */ uint16_t : 1; } PIPEBUF_b; }; union { volatile uint16_t PIPEMAXP; /* (@ 0x0000006C) Pipe Maximum Packet Size Register */ struct TU_ATTR_PACKED { volatile uint16_t MXPS : 11; /* [10..0] Maximum Packet Size */ uint16_t : 1; volatile uint16_t DEVSEL : 4; /* [15..12] Device Select */ } PIPEMAXP_b; }; union { volatile uint16_t PIPEPERI; /* (@ 0x0000006E) Pipe Cycle Control Register */ struct TU_ATTR_PACKED { volatile uint16_t IITV : 3; /* [2..0] Interval Error Detection Interval */ uint16_t : 9; volatile uint16_t IFIS : 1; /* [12..12] Isochronous IN Buffer Flush */ uint16_t : 3; } PIPEPERI_b; }; union { volatile uint16_t PIPE_CTR[9]; /* (@ 0x00000070) Pipe [0..8] Control Register */ struct TU_ATTR_PACKED { volatile uint16_t PID : 2; /* [1..0] Response PID */ uint16_t : 3; volatile const uint16_t PBUSY : 1; /* [5..5] Pipe Busy */ volatile const uint16_t SQMON : 1; /* [6..6] Sequence Toggle Bit Confirmation */ volatile uint16_t SQSET : 1; /* [7..7] Sequence Toggle Bit Set */ volatile uint16_t SQCLR : 1; /* [8..8] Sequence Toggle Bit Clear */ volatile uint16_t ACLRM : 1; /* [9..9] Auto Buffer Clear Mode */ volatile uint16_t ATREPM : 1; /* [10..10] Auto Response Mode */ uint16_t : 1; volatile const uint16_t CSSTS : 1; /* [12..12] CSSTS Status */ volatile uint16_t CSCLR : 1; /* [13..13] CSPLIT Status Clear */ volatile const uint16_t INBUFM : 1; /* [14..14] Transmit Buffer Monitor */ volatile const uint16_t BSTS : 1; /* [15..15] Buffer Status */ } PIPE_CTR_b[9]; }; volatile const uint16_t RESERVED13; volatile const uint32_t RESERVED14[3]; volatile RUSB2_PIPE_TR_t PIPE_TR[5]; /* (@ 0x00000090) Pipe Transaction Counter Registers */ volatile const uint32_t RESERVED15[3]; union { volatile uint16_t USBBCCTRL0; /* (@ 0x000000B0) BC Control Register 0 */ struct TU_ATTR_PACKED { volatile uint16_t RPDME0 : 1; /* [0..0] D- Pin Pull-Down Control */ volatile uint16_t IDPSRCE0 : 1; /* [1..1] D+ Pin IDPSRC Output Control */ volatile uint16_t IDMSINKE0 : 1; /* [2..2] D- Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDPSRCE0 : 1; /* [3..3] D+ Pin VDPSRC (0.6 V) Output Control */ volatile uint16_t IDPSINKE0 : 1; /* [4..4] D+ Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDMSRCE0 : 1; /* [5..5] D- Pin VDMSRC (0.6 V) Output Control */ uint16_t : 1; volatile uint16_t BATCHGE0 : 1; /* [7..7] BC (Battery Charger) Function Ch0 General Enable Control */ volatile const uint16_t CHGDETSTS0 : 1; /* [8..8] D- Pin 0.6 V Input Detection Status */ volatile const uint16_t PDDETSTS0 : 1; /* [9..9] D+ Pin 0.6 V Input Detection Status */ uint16_t : 6; } USBBCCTRL0_b; }; volatile const uint16_t RESERVED16; volatile const uint32_t RESERVED17[4]; union { volatile uint16_t UCKSEL; /* (@ 0x000000C4) USB Clock Selection Register */ struct TU_ATTR_PACKED { volatile uint16_t UCKSELC : 1; /* [0..0] USB Clock Selection */ uint16_t : 15; } UCKSEL_b; }; volatile const uint16_t RESERVED18; volatile const uint32_t RESERVED19; union { volatile uint16_t USBMC; /* (@ 0x000000CC) USB Module Control Register */ struct TU_ATTR_PACKED { volatile uint16_t VDDUSBE : 1; /* [0..0] USB Reference Power Supply Circuit On/Off Control */ uint16_t : 6; volatile uint16_t VDCEN : 1; /* [7..7] USB Regulator On/Off Control */ uint16_t : 8; } USBMC_b; }; volatile const uint16_t RESERVED20; union { volatile uint16_t DEVADD[10]; /* (@ 0x000000D0) Device Address Configuration Register */ struct TU_ATTR_PACKED { uint16_t : 6; volatile uint16_t USBSPD : 2; /* [7..6] Transfer Speed of Communication Target Device */ volatile uint16_t HUBPORT : 3; /* [10..8] Communication Target Connecting Hub Port */ volatile uint16_t UPPHUB : 4; /* [14..11] Communication Target Connecting Hub Register */ uint16_t : 1; } DEVADD_b[10]; }; volatile const uint32_t RESERVED21[3]; union { volatile uint32_t PHYSLEW; /* (@ 0x000000F0) PHY Cross Point Adjustment Register */ struct TU_ATTR_PACKED { volatile uint32_t SLEWR00 : 1; /* [0..0] Receiver Cross Point Adjustment 00 */ volatile uint32_t SLEWR01 : 1; /* [1..1] Receiver Cross Point Adjustment 01 */ volatile uint32_t SLEWF00 : 1; /* [2..2] Receiver Cross Point Adjustment 00 */ volatile uint32_t SLEWF01 : 1; /* [3..3] Receiver Cross Point Adjustment 01 */ uint32_t : 28; } PHYSLEW_b; }; volatile const uint32_t RESERVED22[3]; union { volatile uint16_t LPCTRL; /* (@ 0x00000100) Low Power Control Register */ struct TU_ATTR_PACKED { uint16_t : 7; volatile uint16_t HWUPM : 1; /* [7..7] Resume Return Mode Setting */ uint16_t : 8; } LPCTRL_b; }; union { volatile uint16_t LPSTS; /* (@ 0x00000102) Low Power Status Register */ struct TU_ATTR_PACKED { uint16_t : 14; volatile uint16_t SUSPENDM : 1; /* [14..14] UTMI SuspendM Control */ uint16_t : 1; } LPSTS_b; }; volatile const uint32_t RESERVED23[15]; union { volatile uint16_t BCCTRL; /* (@ 0x00000140) Battery Charging Control Register */ struct TU_ATTR_PACKED { volatile uint16_t IDPSRCE : 1; /* [0..0] IDPSRC Control */ volatile uint16_t IDMSINKE : 1; /* [1..1] IDMSINK Control */ volatile uint16_t VDPSRCE : 1; /* [2..2] VDPSRC Control */ volatile uint16_t IDPSINKE : 1; /* [3..3] IDPSINK Control */ volatile uint16_t VDMSRCE : 1; /* [4..4] VDMSRC Control */ volatile uint16_t DCPMODE : 1; /* [5..5] DCP Mode Control */ uint16_t : 2; volatile const uint16_t CHGDETSTS : 1; /* [8..8] CHGDET Status */ volatile const uint16_t PDDETSTS : 1; /* [9..9] PDDET Status */ uint16_t : 6; } BCCTRL_b; }; volatile const uint16_t RESERVED24; union { volatile uint16_t PL1CTRL1; /* (@ 0x00000144) Function L1 Control Register 1 */ struct TU_ATTR_PACKED { volatile uint16_t L1RESPEN : 1; /* [0..0] L1 Response Enable */ volatile uint16_t L1RESPMD : 2; /* [2..1] L1 Response Mode */ volatile uint16_t L1NEGOMD : 1; /* [3..3] L1 Response Negotiation Control. */ volatile const uint16_t DVSQ : 4; /* [7..4] DVSQ Extension.DVSQ[3] is Mirror of DVSQ[2:0] in INTSTS0. */ volatile uint16_t HIRDTHR : 4; /* [11..8] L1 Response Negotiation Threshold Value */ uint16_t : 2; volatile uint16_t L1EXTMD : 1; /* [14..14] PHY Control Mode at L1 Return */ uint16_t : 1; } PL1CTRL1_b; }; union { volatile uint16_t PL1CTRL2; /* (@ 0x00000146) Function L1 Control Register 2 */ struct TU_ATTR_PACKED { uint16_t : 8; volatile uint16_t HIRDMON : 4; /* [11..8] HIRD Value Monitor */ volatile uint16_t RWEMON : 1; /* [12..12] RWE Value Monitor */ uint16_t : 3; } PL1CTRL2_b; }; union { volatile uint16_t HL1CTRL1; /* (@ 0x00000148) Host L1 Control Register 1 */ struct TU_ATTR_PACKED { volatile uint16_t L1REQ : 1; /* [0..0] L1 Transition Request */ volatile const uint16_t L1STATUS : 2; /* [2..1] L1 Request Completion Status */ uint16_t : 13; } HL1CTRL1_b; }; union { volatile uint16_t HL1CTRL2; /* (@ 0x0000014A) Host L1 Control Register 2 */ struct TU_ATTR_PACKED { volatile uint16_t L1ADDR : 4; /* [3..0] LPM Token DeviceAddress */ uint16_t : 4; volatile uint16_t HIRD : 4; /* [11..8] LPM Token HIRD */ volatile uint16_t L1RWE : 1; /* [12..12] LPM Token L1 Remote Wake Enable */ uint16_t : 2; volatile uint16_t BESL : 1; /* [15..15] BESL & Alternate HIRD */ } HL1CTRL2_b; }; volatile uint32_t RESERVED25_1; union { volatile uint16_t PHYTRIM1; /*!< (@ 0x00000150) PHY Timing Register 1 */ struct { volatile uint16_t DRISE : 2; /*!< [1..0] FS/LS Rising-Edge Output Waveform Adjustment Function */ volatile uint16_t DFALL : 2; /*!< [3..2] FS/LS Falling-Edge Output Waveform Adjustment Function */ uint16_t : 3; volatile uint16_t PCOMPENB : 1; /*!< [7..7] PVDD Start-up Detection */ volatile uint16_t HSIUP : 4; /*!< [11..8] HS Output Level Setting */ volatile uint16_t IMPOFFSET : 3; /*!< [14..12] terminating resistance offset value setting.Offset value for adjusting the terminating resistance. */ uint16_t : 1; } PHYTRIM1_b; }; union { volatile uint16_t PHYTRIM2; /*!< (@ 0x00000152) PHY Timing Register 2 */ struct { volatile uint16_t SQU : 4; /*!< [3..0] Squelch Detection Level */ uint16_t : 3; volatile uint16_t HSRXENMO : 1; /*!< [7..7] HS Receive Enable Control Mode */ volatile uint16_t PDR : 2; /*!< [9..8] HS Output Adjustment Function */ uint16_t : 2; volatile uint16_t DIS : 3; /*!< [14..12] Disconnect Detection Level */ uint16_t : 1; } PHYTRIM2_b; }; volatile uint32_t RESERVED25_2[3]; union { volatile const uint32_t DPUSR0R; /* (@ 0x00000160) Deep Standby USB Transceiver Control/Pin Monitor Register */ struct TU_ATTR_PACKED { uint32_t : 20; volatile const uint32_t DOVCAHM : 1; /* [20..20] OVRCURA InputIndicates OVRCURA input signal on the HS side of USB port. */ volatile const uint32_t DOVCBHM : 1; /* [21..21] OVRCURB InputIndicates OVRCURB input signal on the HS side of USB port. */ uint32_t : 1; volatile const uint32_t DVBSTSHM : 1; /* [23..23] VBUS InputIndicates VBUS input signal on the HS side of USB port. */ uint32_t : 8; } DPUSR0R_b; }; union { volatile uint32_t DPUSR1R; /* (@ 0x00000164) Deep Standby USB Suspend/Resume Interrupt Register */ struct TU_ATTR_PACKED { uint32_t : 4; volatile uint32_t DOVCAHE : 1; /* [4..4] OVRCURA Interrupt Enable Clear */ volatile uint32_t DOVCBHE : 1; /* [5..5] OVRCURB Interrupt Enable Clear */ uint32_t : 1; volatile uint32_t DVBSTSHE : 1; /* [7..7] VBUS Interrupt Enable/Clear */ uint32_t : 12; volatile const uint32_t DOVCAH : 1; /* [20..20] Indication of Return from OVRCURA Interrupt Source */ volatile const uint32_t DOVCBH : 1; /* [21..21] Indication of Return from OVRCURB Interrupt Source */ uint32_t : 1; volatile const uint32_t DVBSTSH : 1; /* [23..23] Indication of Return from VBUS Interrupt Source */ uint32_t : 8; } DPUSR1R_b; }; union { volatile uint16_t DPUSR2R; /* (@ 0x00000168) Deep Standby USB Suspend/Resume Interrupt Register */ struct TU_ATTR_PACKED { volatile const uint16_t DPINT : 1; /* [0..0] Indication of Return from DP Interrupt Source */ volatile const uint16_t DMINT : 1; /* [1..1] Indication of Return from DM Interrupt Source */ uint16_t : 2; volatile const uint16_t DPVAL : 1; /* [4..4] DP InputIndicates DP input signal on the HS side of USB port. */ volatile const uint16_t DMVAL : 1; /* [5..5] DM InputIndicates DM input signal on the HS side of USB port. */ uint16_t : 2; volatile uint16_t DPINTE : 1; /* [8..8] DP Interrupt Enable Clear */ volatile uint16_t DMINTE : 1; /* [9..9] DM Interrupt Enable Clear */ uint16_t : 6; } DPUSR2R_b; }; union { volatile uint16_t DPUSRCR; /* (@ 0x0000016A) Deep Standby USB Suspend/Resume Command Register */ struct TU_ATTR_PACKED { volatile uint16_t FIXPHY : 1; /* [0..0] USB Transceiver Control Fix */ volatile uint16_t FIXPHYPD : 1; /* [1..1] USB Transceiver Control Fix for PLL */ uint16_t : 14; } DPUSRCR_b; }; volatile const uint32_t RESERVED26[165]; union { volatile uint32_t DPUSR0R_FS; /* (@ 0x00000400) Deep Software Standby USB Transceiver Control/Pin Monitor Register */ struct TU_ATTR_PACKED { volatile uint32_t SRPC0 : 1; /* [0..0] USB Single End Receiver Control */ volatile uint32_t RPUE0 : 1; /* [1..1] DP Pull-Up Resistor Control */ uint32_t : 1; volatile uint32_t DRPD0 : 1; /* [3..3] D+/D- Pull-Down Resistor Control */ volatile uint32_t FIXPHY0 : 1; /* [4..4] USB Transceiver Output Fix */ uint32_t : 11; volatile const uint32_t DP0 : 1; /* [16..16] USB0 D+ InputIndicates the D+ input signal of the USB. */ volatile const uint32_t DM0 : 1; /* [17..17] USB D-InputIndicates the D- input signal of the USB. */ uint32_t : 2; volatile const uint32_t DOVCA0 : 1; /* [20..20] USB OVRCURA InputIndicates the OVRCURA input signal of the USB. */ volatile const uint32_t DOVCB0 : 1; /* [21..21] USB OVRCURB InputIndicates the OVRCURB input signal of the USB. */ uint32_t : 1; volatile const uint32_t DVBSTS0 : 1; /* [23..23] USB VBUS InputIndicates the VBUS input signal of the USB. */ uint32_t : 8; } DPUSR0R_FS_b; }; union { volatile uint32_t DPUSR1R_FS; /* (@ 0x00000404) Deep Software Standby USB Suspend/Resume Interrupt Register */ struct TU_ATTR_PACKED { volatile uint32_t DPINTE0 : 1; /* [0..0] USB DP Interrupt Enable/Clear */ volatile uint32_t DMINTE0 : 1; /* [1..1] USB DM Interrupt Enable/Clear */ uint32_t : 2; volatile uint32_t DOVRCRAE0 : 1; /* [4..4] USB OVRCURA Interrupt Enable/Clear */ volatile uint32_t DOVRCRBE0 : 1; /* [5..5] USB OVRCURB Interrupt Enable/Clear */ uint32_t : 1; volatile uint32_t DVBSE0 : 1; /* [7..7] USB VBUS Interrupt Enable/Clear */ uint32_t : 8; volatile const uint32_t DPINT0 : 1; /* [16..16] USB DP Interrupt Source Recovery */ volatile const uint32_t DMINT0 : 1; /* [17..17] USB DM Interrupt Source Recovery */ uint32_t : 2; volatile const uint32_t DOVRCRA0 : 1; /* [20..20] USB OVRCURA Interrupt Source Recovery */ volatile const uint32_t DOVRCRB0 : 1; /* [21..21] USB OVRCURB Interrupt Source Recovery */ uint32_t : 1; volatile const uint32_t DVBINT0 : 1; /* [23..23] USB VBUS Interrupt Source Recovery */ uint32_t : 8; } DPUSR1R_FS_b; }; } rusb2_reg_t; /* Size = 1032 (0x408) */ TU_ATTR_PACKED_END /* End of definition of packed structs (used by the CCRX toolchain) */ TU_ATTR_BIT_FIELD_ORDER_END /*--------------------------------------------------------------------*/ /* Register Bit Definitions */ /*--------------------------------------------------------------------*/ // PIPE_TR // E #define RUSB2_PIPE_TR_E_TRENB_Pos (9UL) /* TRENB (Bit 9) */ #define RUSB2_PIPE_TR_E_TRENB_Msk (0x200UL) /* TRENB (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_TR_E_TRCLR_Pos (8UL) /* TRCLR (Bit 8) */ #define RUSB2_PIPE_TR_E_TRCLR_Msk (0x100UL) /* TRCLR (Bitfield-Mask: 0x01) */ // N #define RUSB2_PIPE_TR_N_TRNCNT_Pos (0UL) /* TRNCNT (Bit 0) */ #define RUSB2_PIPE_TR_N_TRNCNT_Msk (0xffffUL) /* TRNCNT (Bitfield-Mask: 0xffff) */ // Core Registers // SYSCFG #define RUSB2_SYSCFG_SCKE_Pos (10UL) /* SCKE (Bit 10) */ #define RUSB2_SYSCFG_SCKE_Msk (0x400UL) /* SCKE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_CNEN_Pos (8UL) /* CNEN (Bit 8) */ #define RUSB2_SYSCFG_CNEN_Msk (0x100UL) /* CNEN (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_HSE_Pos (7UL) /*!< HSE (Bit 7) */ #define RUSB2_SYSCFG_HSE_Msk (0x80UL) /*!< HSE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DCFM_Pos (6UL) /* DCFM (Bit 6) */ #define RUSB2_SYSCFG_DCFM_Msk (0x40UL) /* DCFM (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DRPD_Pos (5UL) /* DRPD (Bit 5) */ #define RUSB2_SYSCFG_DRPD_Msk (0x20UL) /* DRPD (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DPRPU_Pos (4UL) /* DPRPU (Bit 4) */ #define RUSB2_SYSCFG_DPRPU_Msk (0x10UL) /* DPRPU (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DMRPU_Pos (3UL) /* DMRPU (Bit 3) */ #define RUSB2_SYSCFG_DMRPU_Msk (0x8UL) /* DMRPU (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_USBE_Pos (0UL) /* USBE (Bit 0) */ #define RUSB2_SYSCFG_USBE_Msk (0x1UL) /* USBE (Bitfield-Mask: 0x01) */ // BUSWAIT #define RUSB2_BUSWAIT_BWAIT_Pos (0UL) /* BWAIT (Bit 0) */ #define RUSB2_BUSWAIT_BWAIT_Msk (0xfUL) /* BWAIT (Bitfield-Mask: 0x0f) */ // SYSSTS0 #define RUSB2_SYSSTS0_OVCMON_Pos (14UL) /* OVCMON (Bit 14) */ #define RUSB2_SYSSTS0_OVCMON_Msk (0xc000UL) /* OVCMON (Bitfield-Mask: 0x03) */ #define RUSB2_SYSSTS0_HTACT_Pos (6UL) /* HTACT (Bit 6) */ #define RUSB2_SYSSTS0_HTACT_Msk (0x40UL) /* HTACT (Bitfield-Mask: 0x01) */ #define RUSB2_SYSSTS0_SOFEA_Pos (5UL) /* SOFEA (Bit 5) */ #define RUSB2_SYSSTS0_SOFEA_Msk (0x20UL) /* SOFEA (Bitfield-Mask: 0x01) */ #define RUSB2_SYSSTS0_IDMON_Pos (2UL) /* IDMON (Bit 2) */ #define RUSB2_SYSSTS0_IDMON_Msk (0x4UL) /* IDMON (Bitfield-Mask: 0x01) */ #define RUSB2_SYSSTS0_LNST_Pos (0UL) /* LNST (Bit 0) */ #define RUSB2_SYSSTS0_LNST_Msk (0x3UL) /* LNST (Bitfield-Mask: 0x03) */ // PLLSTA #define RUSB2_PLLSTA_PLLLOCK_Pos (0UL) /* PLLLOCK (Bit 0) */ #define RUSB2_PLLSTA_PLLLOCK_Msk (0x1UL) /* PLLLOCK (Bitfield-Mask: 0x01) */ // DVSTCTR0 #define RUSB2_DVSTCTR0_HNPBTOA_Pos (11UL) /* HNPBTOA (Bit 11) */ #define RUSB2_DVSTCTR0_HNPBTOA_Msk (0x800UL) /* HNPBTOA (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_EXICEN_Pos (10UL) /* EXICEN (Bit 10) */ #define RUSB2_DVSTCTR0_EXICEN_Msk (0x400UL) /* EXICEN (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_VBUSEN_Pos (9UL) /* VBUSEN (Bit 9) */ #define RUSB2_DVSTCTR0_VBUSEN_Msk (0x200UL) /* VBUSEN (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_WKUP_Pos (8UL) /* WKUP (Bit 8) */ #define RUSB2_DVSTCTR0_WKUP_Msk (0x100UL) /* WKUP (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_RWUPE_Pos (7UL) /* RWUPE (Bit 7) */ #define RUSB2_DVSTCTR0_RWUPE_Msk (0x80UL) /* RWUPE (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_USBRST_Pos (6UL) /* USBRST (Bit 6) */ #define RUSB2_DVSTCTR0_USBRST_Msk (0x40UL) /* USBRST (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_RESUME_Pos (5UL) /* RESUME (Bit 5) */ #define RUSB2_DVSTCTR0_RESUME_Msk (0x20UL) /* RESUME (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_UACT_Pos (4UL) /* UACT (Bit 4) */ #define RUSB2_DVSTCTR0_UACT_Msk (0x10UL) /* UACT (Bitfield-Mask: 0x01) */ #define RUSB2_DVSTCTR0_RHST_Pos (0UL) /* RHST (Bit 0) */ #define RUSB2_DVSTCTR0_RHST_Msk (0x7UL) /* RHST (Bitfield-Mask: 0x07) */ // TESTMODE #define RUSB2_TESTMODE_UTST_Pos (0UL) /* UTST (Bit 0) */ #define RUSB2_TESTMODE_UTST_Msk (0xfUL) /* UTST (Bitfield-Mask: 0x0f) */ // CFIFOSEL #define RUSB2_CFIFOSEL_RCNT_Pos (15UL) /* RCNT (Bit 15) */ #define RUSB2_CFIFOSEL_RCNT_Msk (0x8000UL) /* RCNT (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOSEL_REW_Pos (14UL) /* REW (Bit 14) */ #define RUSB2_CFIFOSEL_REW_Msk (0x4000UL) /* REW (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOSEL_MBW_Pos (10UL) /* MBW (Bit 10) */ #define RUSB2_CFIFOSEL_MBW_Msk (0xc00UL) /* MBW (Bitfield-Mask: 0x03) */ #define RUSB2_CFIFOSEL_BIGEND_Pos (8UL) /* BIGEND (Bit 8) */ #define RUSB2_CFIFOSEL_BIGEND_Msk (0x100UL) /* BIGEND (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOSEL_ISEL_Pos (5UL) /* ISEL (Bit 5) */ #define RUSB2_CFIFOSEL_ISEL_Msk (0x20UL) /* ISEL (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOSEL_CURPIPE_Pos (0UL) /* CURPIPE (Bit 0) */ #define RUSB2_CFIFOSEL_CURPIPE_Msk (0xfUL) /* CURPIPE (Bitfield-Mask: 0x0f) */ // CFIFOCTR #define RUSB2_CFIFOCTR_BVAL_Pos (15UL) /* BVAL (Bit 15) */ #define RUSB2_CFIFOCTR_BVAL_Msk (0x8000UL) /* BVAL (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOCTR_BCLR_Pos (14UL) /* BCLR (Bit 14) */ #define RUSB2_CFIFOCTR_BCLR_Msk (0x4000UL) /* BCLR (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOCTR_FRDY_Pos (13UL) /* FRDY (Bit 13) */ #define RUSB2_CFIFOCTR_FRDY_Msk (0x2000UL) /* FRDY (Bitfield-Mask: 0x01) */ #define RUSB2_CFIFOCTR_DTLN_Pos (0UL) /* DTLN (Bit 0) */ #define RUSB2_CFIFOCTR_DTLN_Msk (0xfffUL) /* DTLN (Bitfield-Mask: 0xfff) */ // D0FIFOSEL #define RUSB2_D0FIFOSEL_RCNT_Pos (15UL) /* RCNT (Bit 15) */ #define RUSB2_D0FIFOSEL_RCNT_Msk (0x8000UL) /* RCNT (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOSEL_REW_Pos (14UL) /* REW (Bit 14) */ #define RUSB2_D0FIFOSEL_REW_Msk (0x4000UL) /* REW (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOSEL_DCLRM_Pos (13UL) /* DCLRM (Bit 13) */ #define RUSB2_D0FIFOSEL_DCLRM_Msk (0x2000UL) /* DCLRM (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOSEL_DREQE_Pos (12UL) /* DREQE (Bit 12) */ #define RUSB2_D0FIFOSEL_DREQE_Msk (0x1000UL) /* DREQE (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOSEL_MBW_Pos (10UL) /* MBW (Bit 10) */ #define RUSB2_D0FIFOSEL_MBW_Msk (0xc00UL) /* MBW (Bitfield-Mask: 0x03) */ #define RUSB2_D0FIFOSEL_BIGEND_Pos (8UL) /* BIGEND (Bit 8) */ #define RUSB2_D0FIFOSEL_BIGEND_Msk (0x100UL) /* BIGEND (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOSEL_CURPIPE_Pos (0UL) /* CURPIPE (Bit 0) */ #define RUSB2_D0FIFOSEL_CURPIPE_Msk (0xfUL) /* CURPIPE (Bitfield-Mask: 0x0f) */ // D0FIFOCTR #define RUSB2_D0FIFOCTR_BVAL_Pos (15UL) /* BVAL (Bit 15) */ #define RUSB2_D0FIFOCTR_BVAL_Msk (0x8000UL) /* BVAL (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOCTR_BCLR_Pos (14UL) /* BCLR (Bit 14) */ #define RUSB2_D0FIFOCTR_BCLR_Msk (0x4000UL) /* BCLR (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOCTR_FRDY_Pos (13UL) /* FRDY (Bit 13) */ #define RUSB2_D0FIFOCTR_FRDY_Msk (0x2000UL) /* FRDY (Bitfield-Mask: 0x01) */ #define RUSB2_D0FIFOCTR_DTLN_Pos (0UL) /* DTLN (Bit 0) */ #define RUSB2_D0FIFOCTR_DTLN_Msk (0xfffUL) /* DTLN (Bitfield-Mask: 0xfff) */ // D1FIFOSEL #define RUSB2_D1FIFOSEL_RCNT_Pos (15UL) /* RCNT (Bit 15) */ #define RUSB2_D1FIFOSEL_RCNT_Msk (0x8000UL) /* RCNT (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOSEL_REW_Pos (14UL) /* REW (Bit 14) */ #define RUSB2_D1FIFOSEL_REW_Msk (0x4000UL) /* REW (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOSEL_DCLRM_Pos (13UL) /* DCLRM (Bit 13) */ #define RUSB2_D1FIFOSEL_DCLRM_Msk (0x2000UL) /* DCLRM (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOSEL_DREQE_Pos (12UL) /* DREQE (Bit 12) */ #define RUSB2_D1FIFOSEL_DREQE_Msk (0x1000UL) /* DREQE (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOSEL_MBW_Pos (10UL) /* MBW (Bit 10) */ #define RUSB2_D1FIFOSEL_MBW_Msk (0xc00UL) /* MBW (Bitfield-Mask: 0x03) */ #define RUSB2_D1FIFOSEL_BIGEND_Pos (8UL) /* BIGEND (Bit 8) */ #define RUSB2_D1FIFOSEL_BIGEND_Msk (0x100UL) /* BIGEND (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOSEL_CURPIPE_Pos (0UL) /* CURPIPE (Bit 0) */ #define RUSB2_D1FIFOSEL_CURPIPE_Msk (0xfUL) /* CURPIPE (Bitfield-Mask: 0x0f) */ // D1FIFOCTR #define RUSB2_D1FIFOCTR_BVAL_Pos (15UL) /* BVAL (Bit 15) */ #define RUSB2_D1FIFOCTR_BVAL_Msk (0x8000UL) /* BVAL (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOCTR_BCLR_Pos (14UL) /* BCLR (Bit 14) */ #define RUSB2_D1FIFOCTR_BCLR_Msk (0x4000UL) /* BCLR (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOCTR_FRDY_Pos (13UL) /* FRDY (Bit 13) */ #define RUSB2_D1FIFOCTR_FRDY_Msk (0x2000UL) /* FRDY (Bitfield-Mask: 0x01) */ #define RUSB2_D1FIFOCTR_DTLN_Pos (0UL) /* DTLN (Bit 0) */ #define RUSB2_D1FIFOCTR_DTLN_Msk (0xfffUL) /* DTLN (Bitfield-Mask: 0xfff) */ // INTENB0 #define RUSB2_INTENB0_VBSE_Pos (15UL) /* VBSE (Bit 15) */ #define RUSB2_INTENB0_VBSE_Msk (0x8000UL) /* VBSE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_RSME_Pos (14UL) /* RSME (Bit 14) */ #define RUSB2_INTENB0_RSME_Msk (0x4000UL) /* RSME (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_SOFE_Pos (13UL) /* SOFE (Bit 13) */ #define RUSB2_INTENB0_SOFE_Msk (0x2000UL) /* SOFE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_DVSE_Pos (12UL) /* DVSE (Bit 12) */ #define RUSB2_INTENB0_DVSE_Msk (0x1000UL) /* DVSE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_CTRE_Pos (11UL) /* CTRE (Bit 11) */ #define RUSB2_INTENB0_CTRE_Msk (0x800UL) /* CTRE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_BEMPE_Pos (10UL) /* BEMPE (Bit 10) */ #define RUSB2_INTENB0_BEMPE_Msk (0x400UL) /* BEMPE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_NRDYE_Pos (9UL) /* NRDYE (Bit 9) */ #define RUSB2_INTENB0_NRDYE_Msk (0x200UL) /* NRDYE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB0_BRDYE_Pos (8UL) /* BRDYE (Bit 8) */ #define RUSB2_INTENB0_BRDYE_Msk (0x100UL) /* BRDYE (Bitfield-Mask: 0x01) */ // INTENB1 #define RUSB2_INTENB1_OVRCRE_Pos (15UL) /* OVRCRE (Bit 15) */ #define RUSB2_INTENB1_OVRCRE_Msk (0x8000UL) /* OVRCRE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_BCHGE_Pos (14UL) /* BCHGE (Bit 14) */ #define RUSB2_INTENB1_BCHGE_Msk (0x4000UL) /* BCHGE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_DTCHE_Pos (12UL) /* DTCHE (Bit 12) */ #define RUSB2_INTENB1_DTCHE_Msk (0x1000UL) /* DTCHE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_ATTCHE_Pos (11UL) /* ATTCHE (Bit 11) */ #define RUSB2_INTENB1_ATTCHE_Msk (0x800UL) /* ATTCHE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_L1RSMENDE_Pos (9UL) /*!< L1RSMENDE (Bit 9) */ #define RUSB2_INTENB1_L1RSMENDE_Msk (0x200UL) /*!< L1RSMENDE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_LPMENDE_Pos (8UL) /*!< LPMENDE (Bit 8) */ #define RUSB2_INTENB1_LPMENDE_Msk (0x100UL) /*!< LPMENDE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_EOFERRE_Pos (6UL) /* EOFERRE (Bit 6) */ #define RUSB2_INTENB1_EOFERRE_Msk (0x40UL) /* EOFERRE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_SIGNE_Pos (5UL) /* SIGNE (Bit 5) */ #define RUSB2_INTENB1_SIGNE_Msk (0x20UL) /* SIGNE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_SACKE_Pos (4UL) /* SACKE (Bit 4) */ #define RUSB2_INTENB1_SACKE_Msk (0x10UL) /* SACKE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_PDDETINTE0_Pos (0UL) /* PDDETINTE0 (Bit 0) */ #define RUSB2_INTENB1_PDDETINTE0_Msk (0x1UL) /* PDDETINTE0 (Bitfield-Mask: 0x01) */ // BRDYENB #define RUSB2_BRDYENB_PIPEBRDYE_Pos (0UL) /* PIPEBRDYE (Bit 0) */ #define RUSB2_BRDYENB_PIPEBRDYE_Msk (0x1UL) /* PIPEBRDYE (Bitfield-Mask: 0x01) */ // NRDYENB #define RUSB2_NRDYENB_PIPENRDYE_Pos (0UL) /* PIPENRDYE (Bit 0) */ #define RUSB2_NRDYENB_PIPENRDYE_Msk (0x1UL) /* PIPENRDYE (Bitfield-Mask: 0x01) */ // BEMPENB #define RUSB2_BEMPENB_PIPEBEMPE_Pos (0UL) /* PIPEBEMPE (Bit 0) */ #define RUSB2_BEMPENB_PIPEBEMPE_Msk (0x1UL) /* PIPEBEMPE (Bitfield-Mask: 0x01) */ // SOFCFG #define RUSB2_SOFCFG_TRNENSEL_Pos (8UL) /* TRNENSEL (Bit 8) */ #define RUSB2_SOFCFG_TRNENSEL_Msk (0x100UL) /* TRNENSEL (Bitfield-Mask: 0x01) */ #define RUSB2_SOFCFG_BRDYM_Pos (6UL) /* BRDYM (Bit 6) */ #define RUSB2_SOFCFG_BRDYM_Msk (0x40UL) /* BRDYM (Bitfield-Mask: 0x01) */ #define RUSB2_SOFCFG_INTL_Pos (5UL) /* INTL (Bit 5) */ #define RUSB2_SOFCFG_INTL_Msk (0x20UL) /* INTL (Bitfield-Mask: 0x01) */ #define RUSB2_SOFCFG_EDGESTS_Pos (4UL) /* EDGESTS (Bit 4) */ #define RUSB2_SOFCFG_EDGESTS_Msk (0x10UL) /* EDGESTS (Bitfield-Mask: 0x01) */ // PHYSET #define RUSB2_PHYSET_HSEB_Pos (15UL) /* HSEB (Bit 15) */ #define RUSB2_PHYSET_HSEB_Msk (0x8000UL) /* HSEB (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSET_REPSTART_Pos (11UL) /* REPSTART (Bit 11) */ #define RUSB2_PHYSET_REPSTART_Msk (0x800UL) /* REPSTART (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSET_REPSEL_Pos (8UL) /* REPSEL (Bit 8) */ #define RUSB2_PHYSET_REPSEL_Msk (0x300UL) /* REPSEL (Bitfield-Mask: 0x03) */ #define RUSB2_PHYSET_CLKSEL_Pos (4UL) /* CLKSEL (Bit 4) */ #define RUSB2_PHYSET_CLKSEL_Msk (0x30UL) /* CLKSEL (Bitfield-Mask: 0x03) */ #define RUSB2_PHYSET_CDPEN_Pos (3UL) /* CDPEN (Bit 3) */ #define RUSB2_PHYSET_CDPEN_Msk (0x8UL) /* CDPEN (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSET_PLLRESET_Pos (1UL) /* PLLRESET (Bit 1) */ #define RUSB2_PHYSET_PLLRESET_Msk (0x2UL) /* PLLRESET (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSET_DIRPD_Pos (0UL) /* DIRPD (Bit 0) */ #define RUSB2_PHYSET_DIRPD_Msk (0x1UL) /* DIRPD (Bitfield-Mask: 0x01) */ // INTSTS0 #define RUSB2_INTSTS0_VBINT_Pos (15UL) /* VBINT (Bit 15) */ #define RUSB2_INTSTS0_VBINT_Msk (0x8000UL) /* VBINT (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_RESM_Pos (14UL) /* RESM (Bit 14) */ #define RUSB2_INTSTS0_RESM_Msk (0x4000UL) /* RESM (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_SOFR_Pos (13UL) /* SOFR (Bit 13) */ #define RUSB2_INTSTS0_SOFR_Msk (0x2000UL) /* SOFR (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_DVST_Pos (12UL) /* DVST (Bit 12) */ #define RUSB2_INTSTS0_DVST_Msk (0x1000UL) /* DVST (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_CTRT_Pos (11UL) /* CTRT (Bit 11) */ #define RUSB2_INTSTS0_CTRT_Msk (0x800UL) /* CTRT (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_BEMP_Pos (10UL) /* BEMP (Bit 10) */ #define RUSB2_INTSTS0_BEMP_Msk (0x400UL) /* BEMP (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_NRDY_Pos (9UL) /* NRDY (Bit 9) */ #define RUSB2_INTSTS0_NRDY_Msk (0x200UL) /* NRDY (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_BRDY_Pos (8UL) /* BRDY (Bit 8) */ #define RUSB2_INTSTS0_BRDY_Msk (0x100UL) /* BRDY (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_VBSTS_Pos (7UL) /* VBSTS (Bit 7) */ #define RUSB2_INTSTS0_VBSTS_Msk (0x80UL) /* VBSTS (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_DVSQ_Pos (4UL) /* DVSQ (Bit 4) */ #define RUSB2_INTSTS0_DVSQ_Msk (0x70UL) /* DVSQ (Bitfield-Mask: 0x07) */ #define RUSB2_INTSTS0_VALID_Pos (3UL) /* VALID (Bit 3) */ #define RUSB2_INTSTS0_VALID_Msk (0x8UL) /* VALID (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS0_CTSQ_Pos (0UL) /* CTSQ (Bit 0) */ #define RUSB2_INTSTS0_CTSQ_Msk (0x7UL) /* CTSQ (Bitfield-Mask: 0x07) */ // INTSTS1 #define RUSB2_INTSTS1_OVRCR_Pos (15UL) /* OVRCR (Bit 15) */ #define RUSB2_INTSTS1_OVRCR_Msk (0x8000UL) /* OVRCR (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_BCHG_Pos (14UL) /* BCHG (Bit 14) */ #define RUSB2_INTSTS1_BCHG_Msk (0x4000UL) /* BCHG (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_DTCH_Pos (12UL) /* DTCH (Bit 12) */ #define RUSB2_INTSTS1_DTCH_Msk (0x1000UL) /* DTCH (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_ATTCH_Pos (11UL) /* ATTCH (Bit 11) */ #define RUSB2_INTSTS1_ATTCH_Msk (0x800UL) /* ATTCH (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_L1RSMEND_Pos (9UL) /* L1RSMEND (Bit 9) */ #define RUSB2_INTSTS1_L1RSMEND_Msk (0x200UL) /* L1RSMEND (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_LPMEND_Pos (8UL) /* LPMEND (Bit 8) */ #define RUSB2_INTSTS1_LPMEND_Msk (0x100UL) /* LPMEND (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_EOFERR_Pos (6UL) /* EOFERR (Bit 6) */ #define RUSB2_INTSTS1_EOFERR_Msk (0x40UL) /* EOFERR (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_SIGN_Pos (5UL) /* SIGN (Bit 5) */ #define RUSB2_INTSTS1_SIGN_Msk (0x20UL) /* SIGN (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_SACK_Pos (4UL) /* SACK (Bit 4) */ #define RUSB2_INTSTS1_SACK_Msk (0x10UL) /* SACK (Bitfield-Mask: 0x01) */ #define RUSB2_INTSTS1_PDDETINT0_Pos (0UL) /* PDDETINT0 (Bit 0) */ #define RUSB2_INTSTS1_PDDETINT0_Msk (0x1UL) /* PDDETINT0 (Bitfield-Mask: 0x01) */ // BRDYSTS #define RUSB2_BRDYSTS_PIPEBRDY_Pos (0UL) /* PIPEBRDY (Bit 0) */ #define RUSB2_BRDYSTS_PIPEBRDY_Msk (0x1UL) /* PIPEBRDY (Bitfield-Mask: 0x01) */ // NRDYSTS #define RUSB2_NRDYSTS_PIPENRDY_Pos (0UL) /* PIPENRDY (Bit 0) */ #define RUSB2_NRDYSTS_PIPENRDY_Msk (0x1UL) /* PIPENRDY (Bitfield-Mask: 0x01) */ // BEMPSTS #define RUSB2_BEMPSTS_PIPEBEMP_Pos (0UL) /* PIPEBEMP (Bit 0) */ #define RUSB2_BEMPSTS_PIPEBEMP_Msk (0x1UL) /* PIPEBEMP (Bitfield-Mask: 0x01) */ // FRMNUM #define RUSB2_FRMNUM_OVRN_Pos (15UL) /* OVRN (Bit 15) */ #define RUSB2_FRMNUM_OVRN_Msk (0x8000UL) /* OVRN (Bitfield-Mask: 0x01) */ #define RUSB2_FRMNUM_CRCE_Pos (14UL) /* CRCE (Bit 14) */ #define RUSB2_FRMNUM_CRCE_Msk (0x4000UL) /* CRCE (Bitfield-Mask: 0x01) */ #define RUSB2_FRMNUM_FRNM_Pos (0UL) /* FRNM (Bit 0) */ #define RUSB2_FRMNUM_FRNM_Msk (0x7ffUL) /* FRNM (Bitfield-Mask: 0x7ff) */ // UFRMNUM #define RUSB2_UFRMNUM_DVCHG_Pos (15UL) /* DVCHG (Bit 15) */ #define RUSB2_UFRMNUM_DVCHG_Msk (0x8000UL) /* DVCHG (Bitfield-Mask: 0x01) */ #define RUSB2_UFRMNUM_UFRNM_Pos (0UL) /* UFRNM (Bit 0) */ #define RUSB2_UFRMNUM_UFRNM_Msk (0x7UL) /* UFRNM (Bitfield-Mask: 0x07) */ // USBADDR #define RUSB2_USBADDR_STSRECOV0_Pos (8UL) /* STSRECOV0 (Bit 8) */ #define RUSB2_USBADDR_STSRECOV0_Msk (0x700UL) /* STSRECOV0 (Bitfield-Mask: 0x07) */ #define RUSB2_USBADDR_USBADDR_Pos (0UL) /* USBADDR (Bit 0) */ #define RUSB2_USBADDR_USBADDR_Msk (0x7fUL) /* USBADDR (Bitfield-Mask: 0x7f) */ // USBREQ #define RUSB2_USBREQ_BREQUEST_Pos (8UL) /* BREQUEST (Bit 8) */ #define RUSB2_USBREQ_BREQUEST_Msk (0xff00UL) /* BREQUEST (Bitfield-Mask: 0xff) */ #define RUSB2_USBREQ_BMREQUESTTYPE_Pos (0UL) /* BMREQUESTTYPE (Bit 0) */ #define RUSB2_USBREQ_BMREQUESTTYPE_Msk (0xffUL) /* BMREQUESTTYPE (Bitfield-Mask: 0xff) */ // USBVAL #define RUSB2_USBVAL_WVALUE_Pos (0UL) /* WVALUE (Bit 0) */ #define RUSB2_USBVAL_WVALUE_Msk (0xffffUL) /* WVALUE (Bitfield-Mask: 0xffff) */ // USBINDX #define RUSB2_USBINDX_WINDEX_Pos (0UL) /* WINDEX (Bit 0) */ #define RUSB2_USBINDX_WINDEX_Msk (0xffffUL) /* WINDEX (Bitfield-Mask: 0xffff) */ // USBLENG #define RUSB2_USBLENG_WLENGTH_Pos (0UL) /* WLENGTH (Bit 0) */ #define RUSB2_USBLENG_WLENGTH_Msk (0xffffUL) /* WLENGTH (Bitfield-Mask: 0xffff) */ // DCPCFG #define RUSB2_DCPCFG_CNTMD_Pos (8UL) /* CNTMD (Bit 8) */ #define RUSB2_DCPCFG_CNTMD_Msk (0x100UL) /* CNTMD (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCFG_SHTNAK_Pos (7UL) /* SHTNAK (Bit 7) */ #define RUSB2_DCPCFG_SHTNAK_Msk (0x80UL) /* SHTNAK (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCFG_DIR_Pos (4UL) /* DIR (Bit 4) */ #define RUSB2_DCPCFG_DIR_Msk (0x10UL) /* DIR (Bitfield-Mask: 0x01) */ // DCPMAXP #define RUSB2_DCPMAXP_DEVSEL_Pos (12UL) /* DEVSEL (Bit 12) */ #define RUSB2_DCPMAXP_DEVSEL_Msk (0xf000UL) /* DEVSEL (Bitfield-Mask: 0x0f) */ #define RUSB2_DCPMAXP_MXPS_Pos (0UL) /* MXPS (Bit 0) */ #define RUSB2_DCPMAXP_MXPS_Msk (0x7fUL) /* MXPS (Bitfield-Mask: 0x7f) */ // DCPCTR #define RUSB2_DCPCTR_BSTS_Pos (15UL) /* BSTS (Bit 15) */ #define RUSB2_DCPCTR_BSTS_Msk (0x8000UL) /* BSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQ_Pos (14UL) /* SUREQ (Bit 14) */ #define RUSB2_DCPCTR_SUREQ_Msk (0x4000UL) /* SUREQ (Bitfield-Mask: 0x01) */ #define R_USB_HS0_DCPCTR_CSCLR_Pos (13UL) /*!< CSCLR (Bit 13) */ #define RUSB2_DCPCTR_CSCLR_Msk (0x2000UL) /*!< CSCLR (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_CSSTS_Pos (12UL) /*!< CSSTS (Bit 12) */ #define RUSB2_DCPCTR_CSSTS_Msk (0x1000UL) /*!< CSSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQCLR_Pos (11UL) /* SUREQCLR (Bit 11) */ #define RUSB2_DCPCTR_SUREQCLR_Msk (0x800UL) /* SUREQCLR (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SQCLR_Pos (8UL) /* SQCLR (Bit 8) */ #define RUSB2_DCPCTR_SQCLR_Msk (0x100UL) /* SQCLR (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SQSET_Pos (7UL) /* SQSET (Bit 7) */ #define RUSB2_DCPCTR_SQSET_Msk (0x80UL) /* SQSET (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SQMON_Pos (6UL) /* SQMON (Bit 6) */ #define RUSB2_DCPCTR_SQMON_Msk (0x40UL) /* SQMON (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_PBUSY_Pos (5UL) /* PBUSY (Bit 5) */ #define RUSB2_DCPCTR_PBUSY_Msk (0x20UL) /* PBUSY (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_CCPL_Pos (2UL) /* CCPL (Bit 2) */ #define RUSB2_DCPCTR_CCPL_Msk (0x4UL) /* CCPL (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_PID_Pos (0UL) /* PID (Bit 0) */ #define RUSB2_DCPCTR_PID_Msk (0x3UL) /* PID (Bitfield-Mask: 0x03) */ // PIPESEL #define RUSB2_PIPESEL_PIPESEL_Pos (0UL) /* PIPESEL (Bit 0) */ #define RUSB2_PIPESEL_PIPESEL_Msk (0xfUL) /* PIPESEL (Bitfield-Mask: 0x0f) */ // PIPECFG #define RUSB2_PIPECFG_TYPE_Pos (14UL) /* TYPE (Bit 14) */ #define RUSB2_PIPECFG_TYPE_Msk (0xc000UL) /* TYPE (Bitfield-Mask: 0x03) */ #define RUSB2_PIPECFG_BFRE_Pos (10UL) /* BFRE (Bit 10) */ #define RUSB2_PIPECFG_BFRE_Msk (0x400UL) /* BFRE (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DBLB_Pos (9UL) /* DBLB (Bit 9) */ #define RUSB2_PIPECFG_DBLB_Msk (0x200UL) /* DBLB (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_CNTMD_Pos (8UL) /*!< CNTMD (Bit 8) */ #define RUSB2_PIPECFG_CNTMD_Msk (0x100UL) /*!< CNTMD (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_SHTNAK_Pos (7UL) /* SHTNAK (Bit 7) */ #define RUSB2_PIPECFG_SHTNAK_Msk (0x80UL) /* SHTNAK (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DIR_Pos (4UL) /* DIR (Bit 4) */ #define RUSB2_PIPECFG_DIR_Msk (0x10UL) /* DIR (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_EPNUM_Pos (0UL) /* EPNUM (Bit 0) */ #define RUSB2_PIPECFG_EPNUM_Msk (0xfUL) /* EPNUM (Bitfield-Mask: 0x0f) */ // PIPEBUF #define RUSB2_PIPEBUF_BUFSIZE_Pos (10UL) /*!< BUFSIZE (Bit 10) */ #define RUSB2_PIPEBUF_BUFSIZE_Msk (0x7c00UL) /*!< BUFSIZE (Bitfield-Mask: 0x1f) */ #define RUSB2_PIPEBUF_BUFNMB_Pos (0UL) /*!< BUFNMB (Bit 0) */ #define RUSB2_PIPEBUF_BUFNMB_Msk (0xffUL) /*!< BUFNMB (Bitfield-Mask: 0xff) */ // PIPEMAXP #define RUSB2_PIPEMAXP_DEVSEL_Pos (12UL) /* DEVSEL (Bit 12) */ #define RUSB2_PIPEMAXP_DEVSEL_Msk (0xf000UL) /* DEVSEL (Bitfield-Mask: 0x0f) */ #define RUSB2_PIPEMAXP_MXPS_Pos (0UL) /* MXPS (Bit 0) */ #define RUSB2_PIPEMAXP_MXPS_Msk (0x1ffUL) /* MXPS (Bitfield-Mask: 0x1ff) */ // PIPEPERI #define RUSB2_PIPEPERI_IFIS_Pos (12UL) /* IFIS (Bit 12) */ #define RUSB2_PIPEPERI_IFIS_Msk (0x1000UL) /* IFIS (Bitfield-Mask: 0x01) */ #define RUSB2_PIPEPERI_IITV_Pos (0UL) /* IITV (Bit 0) */ #define RUSB2_PIPEPERI_IITV_Msk (0x7UL) /* IITV (Bitfield-Mask: 0x07) */ // PIPE_CTR #define RUSB2_PIPE_CTR_BSTS_Pos (15UL) /* BSTS (Bit 15) */ #define RUSB2_PIPE_CTR_BSTS_Msk (0x8000UL) /* BSTS (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_INBUFM_Pos (14UL) /* INBUFM (Bit 14) */ #define RUSB2_PIPE_CTR_INBUFM_Msk (0x4000UL) /* INBUFM (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_CSCLR_Pos (13UL) /* CSCLR (Bit 13) */ #define RUSB2_PIPE_CTR_CSCLR_Msk (0x2000UL) /* CSCLR (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_CSSTS_Pos (12UL) /* CSSTS (Bit 12) */ #define RUSB2_PIPE_CTR_CSSTS_Msk (0x1000UL) /* CSSTS (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_ATREPM_Pos (10UL) /* ATREPM (Bit 10) */ #define RUSB2_PIPE_CTR_ATREPM_Msk (0x400UL) /* ATREPM (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_ACLRM_Pos (9UL) /* ACLRM (Bit 9) */ #define RUSB2_PIPE_CTR_ACLRM_Msk (0x200UL) /* ACLRM (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_SQCLR_Pos (8UL) /* SQCLR (Bit 8) */ #define RUSB2_PIPE_CTR_SQCLR_Msk (0x100UL) /* SQCLR (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_SQSET_Pos (7UL) /* SQSET (Bit 7) */ #define RUSB2_PIPE_CTR_SQSET_Msk (0x80UL) /* SQSET (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_SQMON_Pos (6UL) /* SQMON (Bit 6) */ #define RUSB2_PIPE_CTR_SQMON_Msk (0x40UL) /* SQMON (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_PBUSY_Pos (5UL) /* PBUSY (Bit 5) */ #define RUSB2_PIPE_CTR_PBUSY_Msk (0x20UL) /* PBUSY (Bitfield-Mask: 0x01) */ #define RUSB2_PIPE_CTR_PID_Pos (0UL) /* PID (Bit 0) */ #define RUSB2_PIPE_CTR_PID_Msk (0x3UL) /* PID (Bitfield-Mask: 0x03) */ // DEVADD #define RUSB2_DEVADD_UPPHUB_Pos (11UL) /* UPPHUB (Bit 11) */ #define RUSB2_DEVADD_UPPHUB_Msk (0x7800UL) /* UPPHUB (Bitfield-Mask: 0x0f) */ #define RUSB2_DEVADD_HUBPORT_Pos (8UL) /* HUBPORT (Bit 8) */ #define RUSB2_DEVADD_HUBPORT_Msk (0x700UL) /* HUBPORT (Bitfield-Mask: 0x07) */ #define RUSB2_DEVADD_USBSPD_Pos (6UL) /* USBSPD (Bit 6) */ #define RUSB2_DEVADD_USBSPD_Msk (0xc0UL) /* USBSPD (Bitfield-Mask: 0x03) */ // USBBCCTRL0 #define RUSB2_USBBCCTRL0_PDDETSTS0_Pos (9UL) /* PDDETSTS0 (Bit 9) */ #define RUSB2_USBBCCTRL0_PDDETSTS0_Msk (0x200UL) /* PDDETSTS0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_CHGDETSTS0_Pos (8UL) /* CHGDETSTS0 (Bit 8) */ #define RUSB2_USBBCCTRL0_CHGDETSTS0_Msk (0x100UL) /* CHGDETSTS0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_BATCHGE0_Pos (7UL) /* BATCHGE0 (Bit 7) */ #define RUSB2_USBBCCTRL0_BATCHGE0_Msk (0x80UL) /* BATCHGE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_VDMSRCE0_Pos (5UL) /* VDMSRCE0 (Bit 5) */ #define RUSB2_USBBCCTRL0_VDMSRCE0_Msk (0x20UL) /* VDMSRCE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_IDPSINKE0_Pos (4UL) /* IDPSINKE0 (Bit 4) */ #define RUSB2_USBBCCTRL0_IDPSINKE0_Msk (0x10UL) /* IDPSINKE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_VDPSRCE0_Pos (3UL) /* VDPSRCE0 (Bit 3) */ #define RUSB2_USBBCCTRL0_VDPSRCE0_Msk (0x8UL) /* VDPSRCE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_IDMSINKE0_Pos (2UL) /* IDMSINKE0 (Bit 2) */ #define RUSB2_USBBCCTRL0_IDMSINKE0_Msk (0x4UL) /* IDMSINKE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_IDPSRCE0_Pos (1UL) /* IDPSRCE0 (Bit 1) */ #define RUSB2_USBBCCTRL0_IDPSRCE0_Msk (0x2UL) /* IDPSRCE0 (Bitfield-Mask: 0x01) */ #define RUSB2_USBBCCTRL0_RPDME0_Pos (0UL) /* RPDME0 (Bit 0) */ #define RUSB2_USBBCCTRL0_RPDME0_Msk (0x1UL) /* RPDME0 (Bitfield-Mask: 0x01) */ // UCKSEL #define RUSB2_UCKSEL_UCKSELC_Pos (0UL) /* UCKSELC (Bit 0) */ #define RUSB2_UCKSEL_UCKSELC_Msk (0x1UL) /* UCKSELC (Bitfield-Mask: 0x01) */ // USBMC #define RUSB2_USBMC_VDCEN_Pos (7UL) /* VDCEN (Bit 7) */ #define RUSB2_USBMC_VDCEN_Msk (0x80UL) /* VDCEN (Bitfield-Mask: 0x01) */ #define RUSB2_USBMC_VDDUSBE_Pos (0UL) /* VDDUSBE (Bit 0) */ #define RUSB2_USBMC_VDDUSBE_Msk (0x1UL) /* VDDUSBE (Bitfield-Mask: 0x01) */ // PHYSLEW #define RUSB2_PHYSLEW_SLEWF01_Pos (3UL) /* SLEWF01 (Bit 3) */ #define RUSB2_PHYSLEW_SLEWF01_Msk (0x8UL) /* SLEWF01 (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSLEW_SLEWF00_Pos (2UL) /* SLEWF00 (Bit 2) */ #define RUSB2_PHYSLEW_SLEWF00_Msk (0x4UL) /* SLEWF00 (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSLEW_SLEWR01_Pos (1UL) /* SLEWR01 (Bit 1) */ #define RUSB2_PHYSLEW_SLEWR01_Msk (0x2UL) /* SLEWR01 (Bitfield-Mask: 0x01) */ #define RUSB2_PHYSLEW_SLEWR00_Pos (0UL) /* SLEWR00 (Bit 0) */ #define RUSB2_PHYSLEW_SLEWR00_Msk (0x1UL) /* SLEWR00 (Bitfield-Mask: 0x01) */ // LPCTRL #define RUSB2_LPCTRL_HWUPM_Pos (7UL) /* HWUPM (Bit 7) */ #define RUSB2_LPCTRL_HWUPM_Msk (0x80UL) /* HWUPM (Bitfield-Mask: 0x01) */ // LPSTS #define RUSB2_LPSTS_SUSPENDM_Pos (14UL) /* SUSPENDM (Bit 14) */ #define RUSB2_LPSTS_SUSPENDM_Msk (0x4000UL) /* SUSPENDM (Bitfield-Mask: 0x01) */ // BCCTRL #define RUSB2_BCCTRL_PDDETSTS_Pos (9UL) /* PDDETSTS (Bit 9) */ #define RUSB2_BCCTRL_PDDETSTS_Msk (0x200UL) /* PDDETSTS (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_CHGDETSTS_Pos (8UL) /* CHGDETSTS (Bit 8) */ #define RUSB2_BCCTRL_CHGDETSTS_Msk (0x100UL) /* CHGDETSTS (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_DCPMODE_Pos (5UL) /* DCPMODE (Bit 5) */ #define RUSB2_BCCTRL_DCPMODE_Msk (0x20UL) /* DCPMODE (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_VDMSRCE_Pos (4UL) /* VDMSRCE (Bit 4) */ #define RUSB2_BCCTRL_VDMSRCE_Msk (0x10UL) /* VDMSRCE (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_IDPSINKE_Pos (3UL) /* IDPSINKE (Bit 3) */ #define RUSB2_BCCTRL_IDPSINKE_Msk (0x8UL) /* IDPSINKE (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_VDPSRCE_Pos (2UL) /* VDPSRCE (Bit 2) */ #define RUSB2_BCCTRL_VDPSRCE_Msk (0x4UL) /* VDPSRCE (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_IDMSINKE_Pos (1UL) /* IDMSINKE (Bit 1) */ #define RUSB2_BCCTRL_IDMSINKE_Msk (0x2UL) /* IDMSINKE (Bitfield-Mask: 0x01) */ #define RUSB2_BCCTRL_IDPSRCE_Pos (0UL) /* IDPSRCE (Bit 0) */ #define RUSB2_BCCTRL_IDPSRCE_Msk (0x1UL) /* IDPSRCE (Bitfield-Mask: 0x01) */ // PL1CTRL1 #define RUSB2_PL1CTRL1_L1EXTMD_Pos (14UL) /* L1EXTMD (Bit 14) */ #define RUSB2_PL1CTRL1_L1EXTMD_Msk (0x4000UL) /* L1EXTMD (Bitfield-Mask: 0x01) */ #define RUSB2_PL1CTRL1_HIRDTHR_Pos (8UL) /* HIRDTHR (Bit 8) */ #define RUSB2_PL1CTRL1_HIRDTHR_Msk (0xf00UL) /* HIRDTHR (Bitfield-Mask: 0x0f) */ #define RUSB2_PL1CTRL1_DVSQ_Pos (4UL) /* DVSQ (Bit 4) */ #define RUSB2_PL1CTRL1_DVSQ_Msk (0xf0UL) /* DVSQ (Bitfield-Mask: 0x0f) */ #define RUSB2_PL1CTRL1_L1NEGOMD_Pos (3UL) /* L1NEGOMD (Bit 3) */ #define RUSB2_PL1CTRL1_L1NEGOMD_Msk (0x8UL) /* L1NEGOMD (Bitfield-Mask: 0x01) */ #define RUSB2_PL1CTRL1_L1RESPMD_Pos (1UL) /* L1RESPMD (Bit 1) */ #define RUSB2_PL1CTRL1_L1RESPMD_Msk (0x6UL) /* L1RESPMD (Bitfield-Mask: 0x03) */ #define RUSB2_PL1CTRL1_L1RESPEN_Pos (0UL) /* L1RESPEN (Bit 0) */ #define RUSB2_PL1CTRL1_L1RESPEN_Msk (0x1UL) /* L1RESPEN (Bitfield-Mask: 0x01) */ // PL1CTRL2 #define RUSB2_PL1CTRL2_RWEMON_Pos (12UL) /* RWEMON (Bit 12) */ #define RUSB2_PL1CTRL2_RWEMON_Msk (0x1000UL) /* RWEMON (Bitfield-Mask: 0x01) */ #define RUSB2_PL1CTRL2_HIRDMON_Pos (8UL) /* HIRDMON (Bit 8) */ #define RUSB2_PL1CTRL2_HIRDMON_Msk (0xf00UL) /* HIRDMON (Bitfield-Mask: 0x0f) */ // HL1CTRL1 #define RUSB2_HL1CTRL1_L1STATUS_Pos (1UL) /* L1STATUS (Bit 1) */ #define RUSB2_HL1CTRL1_L1STATUS_Msk (0x6UL) /* L1STATUS (Bitfield-Mask: 0x03) */ #define RUSB2_HL1CTRL1_L1REQ_Pos (0UL) /* L1REQ (Bit 0) */ #define RUSB2_HL1CTRL1_L1REQ_Msk (0x1UL) /* L1REQ (Bitfield-Mask: 0x01) */ // HL1CTRL2 #define RUSB2_HL1CTRL2_BESL_Pos (15UL) /* BESL (Bit 15) */ #define RUSB2_HL1CTRL2_BESL_Msk (0x8000UL) /* BESL (Bitfield-Mask: 0x01) */ #define RUSB2_HL1CTRL2_L1RWE_Pos (12UL) /* L1RWE (Bit 12) */ #define RUSB2_HL1CTRL2_L1RWE_Msk (0x1000UL) /* L1RWE (Bitfield-Mask: 0x01) */ #define RUSB2_HL1CTRL2_HIRD_Pos (8UL) /* HIRD (Bit 8) */ #define RUSB2_HL1CTRL2_HIRD_Msk (0xf00UL) /* HIRD (Bitfield-Mask: 0x0f) */ #define RUSB2_HL1CTRL2_L1ADDR_Pos (0UL) /* L1ADDR (Bit 0) */ #define RUSB2_HL1CTRL2_L1ADDR_Msk (0xfUL) /* L1ADDR (Bitfield-Mask: 0x0f) */ // PHYTRIM1 #define RUSB2_PHYTRIM1_IMPOFFSET_Pos (12UL) /*!< IMPOFFSET (Bit 12) */ #define RUSB2_PHYTRIM1_IMPOFFSET_Msk (0x7000UL) /*!< IMPOFFSET (Bitfield-Mask: 0x07) */ #define RUSB2_PHYTRIM1_HSIUP_Pos (8UL) /*!< HSIUP (Bit 8) */ #define RUSB2_PHYTRIM1_HSIUP_Msk (0xf00UL) /*!< HSIUP (Bitfield-Mask: 0x0f) */ #define RUSB2_PHYTRIM1_PCOMPENB_Pos (7UL) /*!< PCOMPENB (Bit 7) */ #define RUSB2_PHYTRIM1_PCOMPENB_Msk (0x80UL) /*!< PCOMPENB (Bitfield-Mask: 0x01) */ #define RUSB2_PHYTRIM1_DFALL_Pos (2UL) /*!< DFALL (Bit 2) */ #define RUSB2_PHYTRIM1_DFALL_Msk (0xcUL) /*!< DFALL (Bitfield-Mask: 0x03) */ #define RUSB2_PHYTRIM1_DRISE_Pos (0UL) /*!< DRISE (Bit 0) */ #define RUSB2_PHYTRIM1_DRISE_Msk (0x3UL) /*!< DRISE (Bitfield-Mask: 0x03) */ // PHYTRIM2 #define RUSB2_PHYTRIM2_DIS_Pos (12UL) /*!< DIS (Bit 12) */ #define RUSB2_PHYTRIM2_DIS_Msk (0x7000UL) /*!< DIS (Bitfield-Mask: 0x07) */ #define RUSB2_PHYTRIM2_PDR_Pos (8UL) /*!< PDR (Bit 8) */ #define RUSB2_PHYTRIM2_PDR_Msk (0x300UL) /*!< PDR (Bitfield-Mask: 0x03) */ #define RUSB2_PHYTRIM2_HSRXENMO_Pos (7UL) /*!< HSRXENMO (Bit 7) */ #define RUSB2_PHYTRIM2_HSRXENMO_Msk (0x80UL) /*!< HSRXENMO (Bitfield-Mask: 0x01) */ #define RUSB2_PHYTRIM2_SQU_Pos (0UL) /*!< SQU (Bit 0) */ #define RUSB2_PHYTRIM2_SQU_Msk (0xfUL) /*!< SQU (Bitfield-Mask: 0x0f) */ // DPUSR0R #define RUSB2_DPUSR0R_DVBSTSHM_Pos (23UL) /* DVBSTSHM (Bit 23) */ #define RUSB2_DPUSR0R_DVBSTSHM_Msk (0x800000UL) /* DVBSTSHM (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_DOVCBHM_Pos (21UL) /* DOVCBHM (Bit 21) */ #define RUSB2_DPUSR0R_DOVCBHM_Msk (0x200000UL) /* DOVCBHM (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_DOVCAHM_Pos (20UL) /* DOVCAHM (Bit 20) */ #define RUSB2_DPUSR0R_DOVCAHM_Msk (0x100000UL) /* DOVCAHM (Bitfield-Mask: 0x01) */ // DPUSR1R #define RUSB2_DPUSR1R_DVBSTSH_Pos (23UL) /* DVBSTSH (Bit 23) */ #define RUSB2_DPUSR1R_DVBSTSH_Msk (0x800000UL) /* DVBSTSH (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_DOVCBH_Pos (21UL) /* DOVCBH (Bit 21) */ #define RUSB2_DPUSR1R_DOVCBH_Msk (0x200000UL) /* DOVCBH (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_DOVCAH_Pos (20UL) /* DOVCAH (Bit 20) */ #define RUSB2_DPUSR1R_DOVCAH_Msk (0x100000UL) /* DOVCAH (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_DVBSTSHE_Pos (7UL) /* DVBSTSHE (Bit 7) */ #define RUSB2_DPUSR1R_DVBSTSHE_Msk (0x80UL) /* DVBSTSHE (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_DOVCBHE_Pos (5UL) /* DOVCBHE (Bit 5) */ #define RUSB2_DPUSR1R_DOVCBHE_Msk (0x20UL) /* DOVCBHE (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_DOVCAHE_Pos (4UL) /* DOVCAHE (Bit 4) */ #define RUSB2_DPUSR1R_DOVCAHE_Msk (0x10UL) /* DOVCAHE (Bitfield-Mask: 0x01) */ // DPUSR2R #define RUSB2_DPUSR2R_DMINTE_Pos (9UL) /* DMINTE (Bit 9) */ #define RUSB2_DPUSR2R_DMINTE_Msk (0x200UL) /* DMINTE (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR2R_DPINTE_Pos (8UL) /* DPINTE (Bit 8) */ #define RUSB2_DPUSR2R_DPINTE_Msk (0x100UL) /* DPINTE (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR2R_DMVAL_Pos (5UL) /* DMVAL (Bit 5) */ #define RUSB2_DPUSR2R_DMVAL_Msk (0x20UL) /* DMVAL (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR2R_DPVAL_Pos (4UL) /* DPVAL (Bit 4) */ #define RUSB2_DPUSR2R_DPVAL_Msk (0x10UL) /* DPVAL (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR2R_DMINT_Pos (1UL) /* DMINT (Bit 1) */ #define RUSB2_DPUSR2R_DMINT_Msk (0x2UL) /* DMINT (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR2R_DPINT_Pos (0UL) /* DPINT (Bit 0) */ #define RUSB2_DPUSR2R_DPINT_Msk (0x1UL) /* DPINT (Bitfield-Mask: 0x01) */ // DPUSRCR #define RUSB2_DPUSRCR_FIXPHYPD_Pos (1UL) /* FIXPHYPD (Bit 1) */ #define RUSB2_DPUSRCR_FIXPHYPD_Msk (0x2UL) /* FIXPHYPD (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSRCR_FIXPHY_Pos (0UL) /* FIXPHY (Bit 0) */ #define RUSB2_DPUSRCR_FIXPHY_Msk (0x1UL) /* FIXPHY (Bitfield-Mask: 0x01) */ // DPUSR0R_FS #define RUSB2_DPUSR0R_FS_DVBSTS0_Pos (23UL) /* DVBSTS0 (Bit 23) */ #define RUSB2_DPUSR0R_FS_DVBSTS0_Msk (0x800000UL) /* DVBSTS0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_DOVCB0_Pos (21UL) /* DOVCB0 (Bit 21) */ #define RUSB2_DPUSR0R_FS_DOVCB0_Msk (0x200000UL) /* DOVCB0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_DOVCA0_Pos (20UL) /* DOVCA0 (Bit 20) */ #define RUSB2_DPUSR0R_FS_DOVCA0_Msk (0x100000UL) /* DOVCA0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_DM0_Pos (17UL) /* DM0 (Bit 17) */ #define RUSB2_DPUSR0R_FS_DM0_Msk (0x20000UL) /* DM0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_DP0_Pos (16UL) /* DP0 (Bit 16) */ #define RUSB2_DPUSR0R_FS_DP0_Msk (0x10000UL) /* DP0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_FIXPHY0_Pos (4UL) /* FIXPHY0 (Bit 4) */ #define RUSB2_DPUSR0R_FS_FIXPHY0_Msk (0x10UL) /* FIXPHY0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_DRPD0_Pos (3UL) /* DRPD0 (Bit 3) */ #define RUSB2_DPUSR0R_FS_DRPD0_Msk (0x8UL) /* DRPD0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_RPUE0_Pos (1UL) /* RPUE0 (Bit 1) */ #define RUSB2_DPUSR0R_FS_RPUE0_Msk (0x2UL) /* RPUE0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR0R_FS_SRPC0_Pos (0UL) /* SRPC0 (Bit 0) */ #define RUSB2_DPUSR0R_FS_SRPC0_Msk (0x1UL) /* SRPC0 (Bitfield-Mask: 0x01) */ // DPUSR1R_FS #define RUSB2_DPUSR1R_FS_DVBINT0_Pos (23UL) /* DVBINT0 (Bit 23) */ #define RUSB2_DPUSR1R_FS_DVBINT0_Msk (0x800000UL) /* DVBINT0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DOVRCRB0_Pos (21UL) /* DOVRCRB0 (Bit 21) */ #define RUSB2_DPUSR1R_FS_DOVRCRB0_Msk (0x200000UL) /* DOVRCRB0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DOVRCRA0_Pos (20UL) /* DOVRCRA0 (Bit 20) */ #define RUSB2_DPUSR1R_FS_DOVRCRA0_Msk (0x100000UL) /* DOVRCRA0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DMINT0_Pos (17UL) /* DMINT0 (Bit 17) */ #define RUSB2_DPUSR1R_FS_DMINT0_Msk (0x20000UL) /* DMINT0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DPINT0_Pos (16UL) /* DPINT0 (Bit 16) */ #define RUSB2_DPUSR1R_FS_DPINT0_Msk (0x10000UL) /* DPINT0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DVBSE0_Pos (7UL) /* DVBSE0 (Bit 7) */ #define RUSB2_DPUSR1R_FS_DVBSE0_Msk (0x80UL) /* DVBSE0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DOVRCRBE0_Pos (5UL) /* DOVRCRBE0 (Bit 5) */ #define RUSB2_DPUSR1R_FS_DOVRCRBE0_Msk (0x20UL) /* DOVRCRBE0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DOVRCRAE0_Pos (4UL) /* DOVRCRAE0 (Bit 4) */ #define RUSB2_DPUSR1R_FS_DOVRCRAE0_Msk (0x10UL) /* DOVRCRAE0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DMINTE0_Pos (1UL) /* DMINTE0 (Bit 1) */ #define RUSB2_DPUSR1R_FS_DMINTE0_Msk (0x2UL) /* DMINTE0 (Bitfield-Mask: 0x01) */ #define RUSB2_DPUSR1R_FS_DPINTE0_Pos (0UL) /* DPINTE0 (Bit 0) */ #define RUSB2_DPUSR1R_FS_DPINTE0_Msk (0x1UL) /* DPINTE0 (Bitfield-Mask: 0x01) */ /*--------------------------------------------------------------------*/ /* Register Bit Utils */ /*--------------------------------------------------------------------*/ #define RUSB2_SYSSTS0_LNST_SE0 (0) #define RUSB2_SYSSTS0_LNST_FS_J (1u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed J state */ #define RUSB2_SYSSTS0_LNST_FS_K (2u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed K state */ #define RUSB2_SYSSTS0_LNST_LS_SE1 (3u << RUSB2_SYSSTS0_LNST_Pos) /* Low-speed SE1 state */ #define RUSB2_DVSTCTR0_RHST_LS (1U << RUSB2_DVSTCTR0_RHST_Pos) /* Low-speed connection */ #define RUSB2_DVSTCTR0_RHST_FS (2U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ #define RUSB2_DVSTCTR0_RHST_HS (3U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ #define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */ #define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */ #define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */ #define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */ #define RUSB2_DEVADD_USBSPD_LS (1U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Low-speed */ #define RUSB2_DEVADD_USBSPD_FS (2U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Full-speed */ #define RUSB2_CFIFOSEL_ISEL_WRITE (1U << RUSB2_CFIFOSEL_ISEL_Pos) /* FIFO write AKA TX*/ #define RUSB2_FIFOSEL_BIGEND (1U << RUSB2_CFIFOSEL_BIGEND_Pos) /* FIFO Big Endian */ #define RUSB2_FIFOSEL_MBW_8BIT (0U << RUSB2_CFIFOSEL_MBW_Pos) /* 8-bit width */ #define RUSB2_FIFOSEL_MBW_16BIT (1U << RUSB2_CFIFOSEL_MBW_Pos) /* 16-bit width */ #define RUSB2_FIFOSEL_MBW_32BIT (2U << RUSB2_CFIFOSEL_MBW_Pos) /* 32-bit width */ #define RUSB2_INTSTS0_CTSQ_CTRL_RDATA (1U << RUSB2_INTSTS0_CTSQ_Pos) #define RUSB2_INTSTS0_DVSQ_STATE_DEF (1U << RUSB2_INTSTS0_DVSQ_Pos) /* Default state */ #define RUSB2_INTSTS0_DVSQ_STATE_ADDR (2U << RUSB2_INTSTS0_DVSQ_Pos) /* Address state */ #define RUSB2_INTSTS0_DVSQ_STATE_SUSP0 (4U << RUSB2_INTSTS0_DVSQ_Pos) /* Suspend state */ #define RUSB2_INTSTS0_DVSQ_STATE_SUSP1 (5U << RUSB2_INTSTS0_DVSQ_Pos) /* Suspend state */ #define RUSB2_INTSTS0_DVSQ_STATE_SUSP2 (6U << RUSB2_INTSTS0_DVSQ_Pos) /* Suspend state */ #define RUSB2_INTSTS0_DVSQ_STATE_SUSP3 (7U << RUSB2_INTSTS0_DVSQ_Pos) /* Suspend state */ #define RUSB2_PIPECFG_TYPE_BULK (1U << RUSB2_PIPECFG_TYPE_Pos) #define RUSB2_PIPECFG_TYPE_INT (2U << RUSB2_PIPECFG_TYPE_Pos) #define RUSB2_PIPECFG_TYPE_ISO (3U << RUSB2_PIPECFG_TYPE_Pos) //--------------------------------------------------------------------+ // Static Assert //--------------------------------------------------------------------+ TU_VERIFY_STATIC(sizeof(RUSB2_PIPE_TR_t) == 4, "incorrect size"); TU_VERIFY_STATIC(sizeof(rusb2_reg_t) == 1032, "incorrect size"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSCFG ) == 0x0000, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BUSWAIT ) == 0x0002, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSSTS0 ) == 0x0004, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PLLSTA ) == 0x0006, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DVSTCTR0 ) == 0x0008, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, TESTMODE ) == 0x000C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFO ) == 0x0014, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFO ) == 0x0018, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFO ) == 0x001C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOSEL ) == 0x0020, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOCTR ) == 0x0022, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOSEL ) == 0x0028, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOCTR ) == 0x002A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOSEL ) == 0x002C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOCTR ) == 0x002E, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB0 ) == 0x0030, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB1 ) == 0x0032, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYENB ) == 0x0036, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYENB ) == 0x0038, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPENB ) == 0x003A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SOFCFG ) == 0x003C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSET ) == 0x003E, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS0 ) == 0x0040, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS1 ) == 0x0042, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYSTS ) == 0x0046, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYSTS ) == 0x0048, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPSTS ) == 0x004A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, FRMNUM ) == 0x004C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UFRMNUM ) == 0x004E, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBADDR ) == 0x0050, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBREQ ) == 0x0054, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBVAL ) == 0x0056, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBINDX ) == 0x0058, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBLENG ) == 0x005A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCFG ) == 0x005C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPMAXP ) == 0x005E, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCTR ) == 0x0060, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPESEL ) == 0x0064, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPECFG ) == 0x0068, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEBUF ) == 0x006A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEMAXP ) == 0x006C, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEPERI ) == 0x006E, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_CTR ) == 0x0070, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_TR ) == 0x0090, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBBCCTRL0 ) == 0x00B0, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UCKSEL ) == 0x00C4, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBMC ) == 0x00CC, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DEVADD ) == 0x00D0, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSLEW ) == 0x00F0, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPCTRL ) == 0x0100, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPSTS ) == 0x0102, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BCCTRL ) == 0x0140, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL1 ) == 0x0144, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL2 ) == 0x0146, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL1 ) == 0x0148, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL2 ) == 0x014A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM1 ) == 0x0150, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM2 ) == 0x0152, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R ) == 0x0160, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R ) == 0x0164, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR2R ) == 0x0168, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSRCR ) == 0x016A, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R_FS ) == 0x0400, "incorrect offset"); TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R_FS ) == 0x0404, "incorrect offset"); #ifdef __cplusplus } #endif #endif /* TUSB_RUSB2_TYPE_H_ */ ================================================ FILE: src/portable/sony/cxd56/dcd_cxd56.c ================================================ /* * The MIT License (MIT) * * Copyright 2019 Sony Semiconductor Solutions Corporation * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_CXD56 #include #include #include #include "device/dcd.h" #include "device/usbd_pvt.h" #define CXD56_EPNUM (7) #define CXD56_SETUP_QUEUE_DEPTH (4) #define CXD56_MAX_DATA_OUT_SIZE (64) OSAL_QUEUE_DEF(usbd_int_set, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); struct usbdcd_driver_s { struct usbdevclass_driver_s usbdevclass_driver; FAR struct usbdev_ep_s *ep[CXD56_EPNUM]; FAR struct usbdev_req_s *req[CXD56_EPNUM]; osal_queue_t setup_queue; bool setup_processed; FAR uint8_t dataout[CXD56_MAX_DATA_OUT_SIZE]; size_t outlen; }; static struct usbdcd_driver_s usbdcd_driver; static struct usbdev_s *usbdev; static int _dcd_bind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static void _dcd_unbind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static int _dcd_setup (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen); static void _dcd_disconnect (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static void _dcd_suspend (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static void _dcd_resume (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static const struct usbdevclass_driverops_s g_driverops = { _dcd_bind, /* bind */ _dcd_unbind, /* unbind */ _dcd_setup, /* setup */ _dcd_disconnect, /* disconnect */ _dcd_suspend, /* suspend */ _dcd_resume, /* resume */ }; static void usbdcd_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) { (void) ep; uint8_t ep_addr = (uint32_t)req->priv; if (req->result || req->xfrd != req->len) { if (req->len) { dcd_event_xfer_complete(0, ep_addr, req->xfrd, XFER_RESULT_SUCCESS, true); } } else { if (req->xfrd) { dcd_event_xfer_complete(0, ep_addr, req->xfrd, XFER_RESULT_SUCCESS, true); } } } static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; usbdev = dev; usbdcd_driver.ep[0] = dev->ep0; #ifdef EP_ALLOCREQ // SDK v2 usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]); if (usbdcd_driver.req[0] != NULL) { usbdcd_driver.req[0]->len = 64; usbdcd_driver.req[0]->buf = EP_ALLOCBUFFER(usbdcd_driver.ep[0], 64); if (!usbdcd_driver.req[0]->buf) { EP_FREEREQ(usbdcd_driver.ep[0], usbdcd_driver.req[0]); usbdcd_driver.req[0] = NULL; return ENOMEM; } } #else // SDK v3 usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0], 64); if (usbdcd_driver.req[0] == NULL) { return ENOMEM; } #endif usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete; DEV_CONNECT(dev); return 0; } static void _dcd_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev; } static int _dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen) { (void) driver; (void) dev; if (usbdcd_driver.setup_processed) { usbdcd_driver.setup_processed = false; dcd_event_setup_received(0, (uint8_t const *) ctrl, true); } else { osal_queue_send(usbdcd_driver.setup_queue, ctrl, true); } if (outlen > 0 && outlen <= CXD56_MAX_DATA_OUT_SIZE) { memcpy(usbdcd_driver.dataout, dataout, outlen); usbdcd_driver.outlen = outlen; } return 0; } static void _dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; tusb_speed_t speed; switch (dev->speed) { case USB_SPEED_LOW: speed = TUSB_SPEED_LOW; break; case USB_SPEED_FULL: speed = TUSB_SPEED_FULL; break; case USB_SPEED_HIGH: speed = TUSB_SPEED_HIGH; break; default: speed = TUSB_SPEED_HIGH; break; } dcd_event_bus_reset(0, speed, true); DEV_CONNECT(dev); } static void _dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; usbdcd_driver.usbdevclass_driver.speed = USB_SPEED_HIGH; usbdcd_driver.usbdevclass_driver.ops = &g_driverops; usbdcd_driver.setup_processed = true; usbdcd_driver.setup_queue = osal_queue_create(&_setup_queue_def); usbdev_register(&usbdcd_driver.usbdevclass_driver); return true; } // Enable device interrupt void dcd_int_enable(uint8_t rhport) { (void) rhport; up_enable_irq(CXD56_IRQ_USB_INT); } // Disable device interrupt void dcd_int_disable(uint8_t rhport) { (void) rhport; up_disable_irq(CXD56_IRQ_USB_INT); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; DEV_WAKEUP(usbdev); } void dcd_connect(uint8_t rhport) { (void) rhport; DEV_CONNECT(usbdev); } void dcd_disconnect(uint8_t rhport) { (void) rhport; DEV_DISCONNECT(usbdev); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) { (void) rhport; uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); uint8_t xfrtype = 0; uint16_t const ep_mps = tu_edpt_packet_size(p_endpoint_desc); struct usb_epdesc_s epdesc; if (epnum >= CXD56_EPNUM) { return false; } switch (p_endpoint_desc->bmAttributes.xfer) { case 1: xfrtype = USB_EP_ATTR_XFER_ISOC; break; case 2: xfrtype = USB_EP_ATTR_XFER_BULK; break; case 3: xfrtype = USB_EP_ATTR_XFER_INT; break; } usbdcd_driver.ep[epnum] = DEV_ALLOCEP(usbdev, epnum, dir == TUSB_DIR_IN, xfrtype); if (usbdcd_driver.ep[epnum] == NULL) { return false; } usbdcd_driver.req[epnum] = NULL; #ifdef EP_ALLOCREQ // sdk v2 usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]); if (usbdcd_driver.req[epnum] != NULL) { usbdcd_driver.req[epnum]->len = ep_mps; } #else // sdk v3 usbdcd_driver.req[epnum] = usbdev_allocreq(usbdcd_driver.ep[epnum], ep_mps); #endif if(usbdcd_driver.req[epnum] == NULL) { return false; } usbdcd_driver.req[epnum]->callback = usbdcd_ep0incomplete; epdesc.len = p_endpoint_desc->bLength; epdesc.type = p_endpoint_desc->bDescriptorType; epdesc.addr = p_endpoint_desc->bEndpointAddress; epdesc.attr = xfrtype; epdesc.mxpacketsize[0] = LSBYTE(ep_mps); epdesc.mxpacketsize[1] = MSBYTE(ep_mps); epdesc.interval = p_endpoint_desc->bInterval; if (EP_CONFIGURE(usbdcd_driver.ep[epnum], &epdesc, false) < 0) { return false; } return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; // TODO not implemented yet } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void) rhport; (void) desc_ep; return false; // TODO not implemented yet } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; bool ret = true; uint8_t epnum = tu_edpt_number(ep_addr); if (epnum >= CXD56_EPNUM) { return false; } if (epnum == 0) { if (total_bytes == 0) { usbdcd_driver.setup_processed = true; dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, false); } else if (ep_addr == 0x00 && total_bytes == usbdcd_driver.outlen) { memcpy(buffer, usbdcd_driver.dataout, usbdcd_driver.outlen); dcd_event_xfer_complete(0, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); usbdcd_driver.outlen = 0; } else { usbdcd_driver.req[epnum]->len = total_bytes; usbdcd_driver.req[epnum]->priv = (void *)((uint32_t)ep_addr); usbdcd_driver.req[epnum]->flags = total_bytes < usbdcd_driver.ep[epnum]->maxpacket ? USBDEV_REQFLAGS_NULLPKT : 0; usbdcd_driver.req[epnum]->buf = buffer; if (EP_SUBMIT(usbdcd_driver.ep[epnum], usbdcd_driver.req[epnum]) < 0) { ret = false; } } struct usb_ctrlreq_s ctrl; if (usbdcd_driver.setup_processed) { if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl, 100)) { usbdcd_driver.setup_processed = false; dcd_event_setup_received(0, (uint8_t *)&ctrl, false); } } } else { usbdcd_driver.req[epnum]->len = total_bytes; usbdcd_driver.req[epnum]->priv = (void *)((uint32_t)ep_addr); usbdcd_driver.req[epnum]->flags = total_bytes < usbdcd_driver.ep[epnum]->maxpacket ? USBDEV_REQFLAGS_NULLPKT : 0; usbdcd_driver.req[epnum]->buf = buffer; if (EP_SUBMIT(usbdcd_driver.ep[epnum], usbdcd_driver.req[epnum]) < 0) { ret = false; } } return ret; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t epnum = tu_edpt_number(ep_addr); if (epnum >= CXD56_EPNUM) { return; } EP_STALL(usbdcd_driver.ep[epnum]); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t epnum = tu_edpt_number(ep_addr); if (epnum >= CXD56_EPNUM) { return; } EP_RESUME(usbdcd_driver.ep[epnum]); } #endif ================================================ FILE: src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Nathan Conrad * * Portions: * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2022 Simon Küppers (skuep) * Copyright (c) 2022 HiFiPhile * * 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. * * This file is part of the TinyUSB stack. */ /********************************************** * This driver has been tested with the following MCUs: * - F070, F072, L053, F042F6 * * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This * covers: * * F04x, F072, F078, F070x6/B 1024 byte buffer * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up * C0 2048 byte buffer; 32-bit bus; host mode * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer * H5 2048 byte buffer; 32-bit bus; host mode * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer * L5 1024 byte buffer * U0 1024 byte buffer; 32-bit bus * U535, U545 2048 byte buffer; 32-bit bus; host mode * WB35, WB55 1024 byte buffer * * To use this driver, you must: * - If you are using a device with crystal-less USB, set up the clock recovery system (CRS) * - Remap pins to be D+/D- on devices that they are shared (for example: F042Fx) * - This is different to the normal "alternate function" GPIO interface, needs to go through SYSCFG->CFGRx register * - Enable USB clock; Perhaps use __HAL_RCC_USB_CLK_ENABLE(); * - (Optionally configure GPIO HAL to tell it the USB driver is using the USB pins) * - call tusb_init(); * * Assumptions of the driver: * - You are not using CAN (it must share the packet buffer) * - APB clock is >= 10 MHz * - On some boards, series resistors are required, but not on others. * - On some boards, D+ pull up resistor (1.5kohm) is required, but not on others. * - You don't have long-running interrupts; some USB packets must be quickly responded to. * - You have the ST CMSIS library linked into the project. HAL is not used. * * Current driver limitations (i.e., a list of features for you to add): * - STALL handled, but not tested. * - Does it work? No clue. * - All EP BTABLE buffers are created based on max packet size of first EP opened with that address. * - Packet buffer memory is copied in the interrupt. * - This is better for performance, but means interrupts are disabled for longer * - DMA may be the best choice, but it could also be pushed to the USBD task. * - No double-buffering * - No DMA * - Minimal error handling * - Perhaps error interrupts should be reported to the stack, or cause a device reset? * - Assumes a single USB peripheral; I think that no hardware has multiple so this is fine. * - Add a callback for enabling/disabling the D+ PU on devices without an internal PU. * - F3 models use three separate interrupts. I think we could only use the LP interrupt for * everything? However, the interrupts are configurable so the DisableInt and EnableInt * below functions could be adjusting the wrong interrupts (if they had been reconfigured) * - LPM is not used correctly, or at all? * * Notes: * - The buffer table is allocated as endpoints are opened. The allocation is only * cleared when the device is reset. This may be bad if the USB device needs * to be reconfigured. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0) #include "device/dcd.h" #include "fsdev_common.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // One of these for every EP IN & OUT, uses a bit of RAM.... typedef struct { uint8_t *buffer; tu_fifo_t *ff; uint16_t total_len; uint16_t queued_len; uint16_t max_packet_size; uint8_t ep_idx; // index for USB_EPnR register bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask } xfer_ctl_t; // EP allocator typedef struct { uint8_t ep_num; uint8_t ep_type; bool allocated[2]; } ep_alloc_t; static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ // Prototypes //--------------------------------------------------------------------+ // into the stack. static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); static void edpt0_open(uint8_t rhport); TU_ATTR_ALWAYS_INLINE static inline void edpt0_prepare_setup(void) { btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8); } //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint8_t dir) { return &xfer_status[epnum][dir]; } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void)rh_init; fsdev_core_reset(); FSDEV_REG->CNTR = 0; // Enable USB #if !defined( CFG_TUSB_FSDEV_32BIT) // BTABLE register does not exist any more on 32-bit bus devices FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE; #endif // Enable interrupts for device mode FSDEV_REG->CNTR |= U_CNTR_RESETM | U_CNTR_ESOFM | U_CNTR_CTRM | U_CNTR_SUSPM | U_CNTR_WKUPM | U_CNTR_PMAOVRM; handle_bus_reset(rhport); // Enable pull-up if supported dcd_connect(rhport); return true; } bool dcd_deinit(uint8_t rhport) { (void)rhport; fsdev_deinit(); return true; } void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; if (en) { FSDEV_REG->CNTR |= U_CNTR_SOFM; } else { FSDEV_REG->CNTR &= ~U_CNTR_SOFM; } } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; // Respond with status dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK | 0x00, NULL, 0, false); // DCD can only set address after status for this request is complete. // do it at dcd_edpt0_status_complete() } void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; FSDEV_REG->CNTR |= U_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } static void handle_bus_reset(uint8_t rhport) { FSDEV_REG->DADDR = 0u; // disable USB Function for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; ep_alloc_status[i].allocated[0] = false; ep_alloc_status[i].allocated[1] = false; } // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; edpt0_open(rhport); // open control endpoint (both IN & OUT) FSDEV_REG->DADDR = U_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | U_EP_CTR_TX | U_EP_CTR_RX; const uint8_t ep_num = ep_reg & U_EPADDR_FIELD; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { // Ignore spurious interrupts that we don't schedule // host can send IN token while there is no data to send, since ISO does not have NAK // this will result to zero length packet --> trigger interrupt (which cannot be masked) if (!xfer->iso_in_sending) { return; } xfer->iso_in_sending = false; #if FSDEV_USE_SBUF_ISO == 0 uint8_t buf_id = (ep_reg & U_EP_DTOG_TX) ? 0 : 1; #else uint8_t buf_id = BTABLE_BUF_TX; #endif btable_set_count(ep_id, buf_id, 0); } if (xfer->total_len != xfer->queued_len) { dcd_transmit_packet(xfer, ep_id); } else { dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); } } static void handle_ctr_setup(uint32_t ep_id) { uint16_t rx_count = btable_get_count(ep_id, BTABLE_BUF_RX); uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); tu_hwfifo_read(PMA_BUF_AT(rx_addr), setup_packet, rx_count, NULL); // Clear CTR RX if another setup packet arrived before this, it will be discarded ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); // Setup packet should always be 8 bytes. If not, we probably missed the packet if (rx_count == 8) { dcd_event_setup_received(0, (uint8_t *)setup_packet, true); // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 } else { // Missed setup packet !!! TU_BREAKPOINT(); edpt0_prepare_setup(); } } // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | U_EP_CTR_TX | U_EP_CTR_RX; const uint8_t ep_num = ep_reg & U_EPADDR_FIELD; const bool is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); uint8_t buf_id; #if FSDEV_USE_SBUF_ISO == 0 bool const dbl_buf = is_iso; #else bool const dbl_buf = false; #endif if (dbl_buf) { buf_id = (ep_reg & U_EP_DTOG_RX) ? 0 : 1; } else { buf_id = BTABLE_BUF_RX; } const uint16_t rx_count = btable_get_count(ep_id, buf_id); uint16_t pma_addr = (uint16_t)btable_get_addr(ep_id, buf_id); fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(pma_addr); if (xfer->ff) { tu_hwfifo_read_to_fifo(pma_buf, xfer->ff, rx_count, NULL); } else { tu_hwfifo_read(pma_buf, xfer->buffer + xfer->queued_len, rx_count, NULL); } xfer->queued_len += rx_count; if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet // For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10) btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); // ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous // transfer. So reset total_len and queued_len to 0. xfer->total_len = xfer->queued_len = 0; } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { const uint16_t cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } ep_reg &= U_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } } void dcd_int_handler(uint8_t rhport) { uint32_t int_status = FSDEV_REG->ISTR; /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & U_ISTR_SOF) { FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SOF; dcd_event_sof(0, FSDEV_REG->FNR & U_FNR_FN, true); } if (int_status & U_ISTR_RESET) { // USBRST is start of reset. FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_RESET; handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } if (int_status & U_ISTR_WKUP) { FSDEV_REG->CNTR &= ~U_CNTR_LPMODE; FSDEV_REG->CNTR &= ~U_CNTR_FSUSP; FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_WKUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } if (int_status & U_ISTR_SUSP) { /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, * these events cannot be differentiated, so we only trigger suspend. */ /* Force low-power mode in the macrocell */ FSDEV_REG->CNTR |= U_CNTR_FSUSP; FSDEV_REG->CNTR |= U_CNTR_LPMODE; /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SUSP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (int_status & U_ISTR_ESOF) { if (remoteWakeCountdown == 1u) { FSDEV_REG->CNTR &= ~U_CNTR_RESUME; } if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_ESOF; } // loop to handle all pending CTR interrupts while (FSDEV_REG->ISTR & U_ISTR_CTR) { // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt const uint32_t ep_id = FSDEV_REG->ISTR & U_ISTR_EP_ID; const uint32_t ep_reg = ep_read(ep_id); if (ep_reg & U_EP_CTR_RX) { #ifdef CFG_TUSB_FSDEV_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers * Description: * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM * accesses have completed. If the software responds quickly to the interrupt, the full buffer contents may not be * correct. Workaround: * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code * also takes time, so we'll wait 60 cycles (count = 20). * - Since Low Speed mode is not supported/popular, we will ignore it for now. * * Note: this errata may also apply to G0, U5, H5 etc. */ volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver while (cycle_count > 0U) { cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) } #endif if (ep_reg & U_EP_SETUP) { handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet } else { ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); handle_ctr_rx(ep_id); } } if (ep_reg & U_EP_CTR_TX) { ep_write_clear_ctr(ep_id, TUSB_DIR_IN); handle_ctr_tx(ep_id); } } if (int_status & U_ISTR_PMAOVR) { TU_BREAKPOINT(); FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_PMAOVR; } } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *request) { (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { const uint8_t dev_addr = (uint8_t)request->wValue; FSDEV_REG->DADDR = (U_DADDR_EF | dev_addr); } edpt0_prepare_setup(); } /*** * Allocate a section of PMA * In case of double buffering, high 16bit is the address of 2nd buffer * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. */ static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf) { uint8_t blsize, num_block; uint16_t aligned_len = pma_align_buffer_size(len, &blsize, &num_block); (void)blsize; (void)num_block; uint32_t addr = ep_buf_ptr; ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer if (dbuf) { addr |= ((uint32_t)ep_buf_ptr) << 16; ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer } // Verify packet buffer is not overflowed TU_ASSERT(ep_buf_ptr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF); return addr; } /*** * Allocate hardware endpoint */ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) { const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { // Check if already allocated if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type && ep_alloc_status[i].ep_num == epnum) { return i; } #if FSDEV_USE_SBUF_ISO == 0 bool const dbl_buf = ep_type == TUSB_XFER_ISOCHRONOUS; #else bool const dbl_buf = false; #endif // If EP of current direction is not allocated // For double-buffered mode both directions needs to be free if (!ep_alloc_status[i].allocated[dir] && (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) { // Check if EP number is the same if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) { // One EP pair has to be the same type if (ep_alloc_status[i].ep_type == 0xFF || ep_alloc_status[i].ep_type == ep_type) { ep_alloc_status[i].ep_num = epnum; ep_alloc_status[i].ep_type = ep_type; ep_alloc_status[i].allocated[dir] = true; return i; } } } } // Allocation failed TU_ASSERT(0); } void edpt0_open(uint8_t rhport) { (void)rhport; dcd_ep_alloc(0x0, TUSB_XFER_CONTROL); dcd_ep_alloc(0x80, TUSB_XFER_CONTROL); xfer_status[0][0].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; xfer_status[0][0].ep_idx = 0; xfer_status[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; xfer_status[0][1].ep_idx = 0; uint16_t pma_addr0 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); uint16_t pma_addr1 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); uint32_t ep_reg = ep_read(0) & ~U_EPREG_MASK; // only get toggle bits ep_reg |= U_EP_CONTROL; ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit edpt0_prepare_setup(); // prepare for setup packet ep_write(0, ep_reg, false); } bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; const uint8_t ep_addr = desc_ep->bEndpointAddress; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint8_t ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); uint32_t ep_reg = ep_read(ep_idx) & ~U_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | U_EP_CTR_TX | U_EP_CTR_RX; // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_BULK: ep_reg |= U_EP_BULK; break; case TUSB_XFER_INTERRUPT: ep_reg |= U_EP_INTERRUPT; break; default: // Note: ISO endpoint should use alloc / active functions TU_ASSERT(false); } /* Create a packet memory buffer area. */ uint16_t pma_addr = dcd_pma_alloc(packet_size, false); btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->max_packet_size = packet_size; xfer->ep_idx = ep_idx; ep_change_status(&ep_reg, dir, EP_STAT_NAK); ep_change_dtog(&ep_reg, dir, 0); // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { ep_reg &= ~(U_EPRX_STAT | U_EP_DTOG_RX); } else { ep_reg &= ~(U_EPTX_STAT | U_EP_DTOG_TX); } ep_write(ep_idx, ep_reg, true); return true; } void dcd_edpt_close_all(uint8_t rhport) { dcd_int_disable(rhport); for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint ep_write(i, 0, false); // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; ep_alloc_status[i].allocated[0] = false; ep_alloc_status[i].allocated[1] = false; } dcd_int_enable(rhport); // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); const uint8_t ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); #if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0 uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false); uint16_t pma_addr2 = pma_addr; #endif #if FSDEV_USE_SBUF_ISO == 0 btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); #else btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); (void)pma_addr2; #endif xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->ep_idx = ep_idx; return true; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; const uint8_t ep_addr = desc_ep->bEndpointAddress; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; xfer->max_packet_size = tu_edpt_packet_size(desc_ep); uint32_t ep_reg = ep_read(ep_idx) & ~U_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | U_EP_ISOCHRONOUS | U_EP_CTR_TX | U_EP_CTR_RX; #if FSDEV_USE_SBUF_ISO != 0 ep_reg |= U_EP_KIND; ep_change_status(&ep_reg, dir, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); if (dir == TUSB_DIR_IN) { ep_reg &= ~(U_EPRX_STAT | U_EP_DTOG_RX); } else { ep_reg &= ~(U_EPTX_STAT | U_EP_DTOG_TX); } #else ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1); #endif ep_write(ep_idx, ep_reg, true); return true; } // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); uint32_t ep_reg = ep_read(ep_ix) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR const bool is_iso = ep_is_iso(ep_reg); uint8_t buf_id; #if FSDEV_USE_SBUF_ISO == 0 bool const dbl_buf = is_iso; #else bool const dbl_buf = false; #endif if (dbl_buf) { buf_id = (ep_reg & U_EP_DTOG_TX) ? 1 : 0; } else { buf_id = BTABLE_BUF_TX; } uint16_t addr_ptr = (uint16_t)btable_get_addr(ep_ix, buf_id); fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(addr_ptr); if (xfer->ff) { tu_hwfifo_write_from_fifo(pma_buf, xfer->ff, len, NULL); } else { tu_hwfifo_write(pma_buf, &(xfer->buffer[xfer->queued_len]), len, NULL); } xfer->queued_len += len; btable_set_count(ep_ix, buf_id, len); ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); if (is_iso) { xfer->iso_in_sending = true; } ep_reg &= U_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits ep_write(ep_ix, ep_reg, true); } static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) { (void)rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir); uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); #if FSDEV_USE_SBUF_ISO == 0 bool const dbl_buf = ep_is_iso(ep_reg); #else bool const dbl_buf = false; #endif if (dbl_buf) { btable_set_rx_bufsize(ep_idx, 0, cnt); btable_set_rx_bufsize(ep_idx, 1, cnt); } else { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } ep_change_status(&ep_reg, dir, EP_STAT_VALID); ep_write(ep_idx, ep_reg, true); } return true; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { (void)is_isr; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; xfer->queued_len = 0; return edpt_xfer(rhport, ep_num, dir); } bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) { (void)is_isr; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; return edpt_xfer(rhport, ep_num, dir); } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR bits ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir); ep_change_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg, true); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); const uint8_t ep_idx = xfer->ep_idx; uint32_t ep_reg = ep_read(ep_idx) | U_EP_CTR_TX | U_EP_CTR_RX; // reserve CTR bits ep_reg &= U_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { ep_change_status(&ep_reg, dir, EP_STAT_NAK); } ep_change_dtog(&ep_reg, dir, 0); // Reset to DATA0 ep_write(ep_idx, ep_reg, true); } void dcd_int_enable(uint8_t rhport) { fsdev_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { fsdev_int_disable(rhport); } #if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU) || defined(EXTEN_USBD_PU_EN) void dcd_connect(uint8_t rhport) { fsdev_connect(rhport); } void dcd_disconnect(uint8_t rhport) { fsdev_disconnect(rhport); } #endif #endif ================================================ FILE: src/portable/st/stm32_fsdev/fsdev_at32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, hathach (tinyusb.org) * * 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. * */ #ifndef TUSB_FSDEV_AT32_H #define TUSB_FSDEV_AT32_H #include "common/tusb_compiler.h" #if CFG_TUSB_MCU == OPT_MCU_AT32F403A_407 #include "at32f403a_407.h" #elif CFG_TUSB_MCU == OPT_MCU_AT32F413 #include "at32f413.h" #endif #define FSDEV_USE_SBUF_ISO 0 #define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) #define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) #ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413) static const IRQn_Type fsdev_irq[] = { USBFS_H_CAN1_TX_IRQn, USBFS_L_CAN1_RX0_IRQn, USBFSWakeUp_IRQn }; enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; #else #error "Unsupported MCU" #endif TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) { (void)rhport; #if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413) // AT32F403A/407 devices allow to remap the USB interrupt vectors from // shared USB/CAN IRQs to separate CAN and USB IRQs. // This dynamically checks if this remap is active to enable the right IRQs. if (CRM->intmap_bit.usbintmap) { NVIC_EnableIRQ(USBFS_MAPH_IRQn); NVIC_EnableIRQ(USBFS_MAPL_IRQn); NVIC_EnableIRQ(USBFSWakeUp_IRQn); } else #endif { for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { NVIC_EnableIRQ(fsdev_irq[i]); } } } TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { (void)rhport; #if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413) // AT32F403A/407 devices allow to remap the USB interrupt vectors from // shared USB/CAN IRQs to separate CAN and USB IRQs. // This dynamically checks if this remap is active to enable the right IRQs. if (CRM->intmap_bit.usbintmap) { NVIC_DisableIRQ(USBFS_MAPH_IRQn); NVIC_DisableIRQ(USBFS_MAPL_IRQn); NVIC_DisableIRQ(USBFSWakeUp_IRQn); } else #endif { for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { NVIC_DisableIRQ(fsdev_irq[i]); } } } TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void) rhport; /* disable usb phy */ *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= U_CNTR_PDWN; /* D+ 1.5k pull-up disable, USB->cfg_bit.puo = TRUE; */ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1); } TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void) rhport; /* enable usb phy */ *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~U_CNTR_PDWN; /* Dp 1.5k pull-up enable, USB->cfg_bit.puo = 0; */ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) &= ~(1u<<1); } #endif ================================================ FILE: src/portable/st/stm32_fsdev/fsdev_ch32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, hathach (tinyusb.org) * * 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. * */ /**

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause */ #ifndef TUSB_FSDEV_CH32_H #define TUSB_FSDEV_CH32_H #include "common/tusb_compiler.h" // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #if CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #elif CFG_TUSB_MCU == OPT_MCU_CH32V20X #include #endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #define FSDEV_USE_SBUF_ISO 0 #define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) #define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) #ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_CH32V20X static const IRQn_Type fsdev_irq[] = { USB_HP_CAN1_TX_IRQn, USB_LP_CAN1_RX0_IRQn, USBWakeUp_IRQn }; enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; #else #error "Unsupported MCU" #endif TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) { (void)rhport; for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { NVIC_EnableIRQ(fsdev_irq[i]); } } TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { (void)rhport; for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { NVIC_DisableIRQ(fsdev_irq[i]); } } TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void) rhport; EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN; } TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void) rhport; EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN; } #endif ================================================ FILE: src/portable/st/stm32_fsdev/fsdev_common.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Ha Thach (tinyusb.org) * Copyright (c) 2025, HiFiPhile (Zixun LI) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if defined(TUP_USBIP_FSDEV) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED) #include "fsdev_common.h" //--------------------------------------------------------------------+ // Global //--------------------------------------------------------------------+ // Reset the USB Core void fsdev_core_reset(void) { // Perform USB peripheral reset FSDEV_REG->CNTR = U_CNTR_FRES | U_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } FSDEV_REG->CNTR &= ~U_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } // Clear pending interrupts FSDEV_REG->ISTR = 0; } // De-initialize the USB Core void fsdev_deinit(void) { // Disable all interrupts and force USB reset FSDEV_REG->CNTR = U_CNTR_FRES; // Clear pending interrupts FSDEV_REG->ISTR = 0; // Put USB peripheral in power down mode FSDEV_REG->CNTR = U_CNTR_FRES | U_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } } //--------------------------------------------------------------------+ // BTable Helper //--------------------------------------------------------------------+ // Aligned buffer size according to hardware uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { /* The STM32 full speed USB peripheral supports only a limited set of * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ uint16_t block_in_bytes; if (size > 62) { block_in_bytes = 32; *blsize = 1; *num_block = tu_div_ceil(size, 32); } else { block_in_bytes = 2; *blsize = 0; *num_block = tu_div_ceil(size, 2); } return (*num_block) * block_in_bytes; } // Set RX buffer size void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) { uint8_t blsize, num_block; (void) pma_align_buffer_size(wCount, &blsize, &num_block); /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); if (bl_nb == 0) { // zlp but 0 is invalid value, set blsize to 1 (32 bytes) // Note: lower value can cause PMAOVR on setup with ch32v203 bl_nb = 1 << 15; } #ifdef CFG_TUSB_FSDEV_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; #endif } #endif ================================================ FILE: src/portable/st/stm32_fsdev/fsdev_common.h ================================================ /* * The MIT License (MIT) * * Copyright (c) N Conrad * Copyright (c) 2024, hathach (tinyusb.org) * Copyright (c) 2025, HiFiPhile (Zixun LI) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_FSDEV_COMMON_H #define TUSB_FSDEV_COMMON_H #ifdef __cplusplus extern "C" { #endif #include "common/tusb_common.h" #if CFG_TUD_ENABLED #include "device/dcd.h" #endif #if CFG_TUH_ENABLED #include "host/hcd.h" #endif //--------------------------------------------------------------------+ // FSDEV Register Bit Definitions // Vendor-independent definitions with U_ prefix to avoid conflicts. // Based on the common USB FSDEV IP block register layout. // Lower 16 bits are shared across all variants (STM32, CH32, AT32). // Upper 16 bits (DRD extensions) only exist on 32-bit DRD MCUs. //--------------------------------------------------------------------+ // EPnR / CHEPnR - Endpoint/Channel Register // DTOG and STAT bits are toggle-on-write-1. CTR bits are clear-on-write-0. // // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // CTR_RX DTOG_RX STAT_RX[1:0] SETUP EP_TYPE[1:0] KIND CTR_TX DTOG_TX STAT_TX[1:0] EA[3:0] // // DRD 32-bit only (C0, G0, H5, U0, U5): // 31:27 26 25 24 23 22 21 20 19 18 17 16 // Rsvd ERR_RX ERR_TX LSEP NAK DEVADDR[6:0] #define U_EP_CTR_RX 0x8000u #define U_EP_DTOG_RX 0x4000u #define U_EPRX_STAT 0x3000u #define U_EP_SETUP 0x0800u #define U_EP_T_FIELD 0x0600u #define U_EP_KIND 0x0100u #define U_EP_CTR_TX 0x0080u #define U_EP_DTOG_TX 0x0040u #define U_EPTX_STAT 0x0030u #define U_EPADDR_FIELD 0x000Fu // DRD 32-bit upper bits #define U_EP_ERRRX 0x04000000u #define U_EP_ERRTX 0x02000000u #define U_EP_LSEP 0x01000000u #define U_EP_NAK 0x00800000u #define U_EP_DEVADDR 0x007F0000u #define U_EP_DEVADDR_Pos 16u // Endpoint types (EP_TYPE field values) #define U_EP_BULK 0x0000u #define U_EP_CONTROL 0x0200u #define U_EP_ISOCHRONOUS 0x0400u #define U_EP_INTERRUPT 0x0600u #define U_EP_TYPE_MASK (U_EP_T_FIELD) // EP register mask components (non-toggle bits preserved during read-modify-write) // Excludes DTOG_RX, STAT_RX, DTOG_TX, STAT_TX (toggle-on-write-1) #define U_EPREG_MASK_16 (U_EP_CTR_RX | U_EP_SETUP | U_EP_T_FIELD | U_EP_KIND | U_EP_CTR_TX | U_EPADDR_FIELD) #define U_EPREG_MASK_32 (U_EP_ERRRX | U_EP_ERRTX | U_EP_LSEP | U_EP_NAK | U_EP_DEVADDR | U_EPREG_MASK_16) // EP register mask selection based on bus width #ifdef CFG_TUSB_FSDEV_32BIT #define U_EPREG_MASK U_EPREG_MASK_32 #else #define U_EPREG_MASK U_EPREG_MASK_16 #endif #define U_EPKIND_MASK ((uint32_t)(~U_EP_KIND) & U_EPREG_MASK) #define U_EPTX_DTOGMASK (U_EPTX_STAT | U_EPREG_MASK) #define U_EPRX_DTOGMASK (U_EPRX_STAT | U_EPREG_MASK) // Bit positions #define U_EPTX_STAT_Pos 4u #define U_EP_DTOG_TX_Pos 6u #define U_EP_CTR_TX_Pos 7u // Data toggle helpers #define U_EPTX_DTOG1 0x0010u #define U_EPTX_DTOG2 0x0020u #define U_EPRX_DTOG1 0x1000u #define U_EPRX_DTOG2 0x2000u // CNTR - Control Register // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // CTRM PMAOVRM ERRM WKUPM SUSPM RESETM SOFM ESOFM Rsvd Rsvd Rsvd RESUME FSUSP LPMODE PDWN FRES // // DRD 32-bit only: // 31 30:16 // HOST Rsvd #define U_CNTR_CTRM 0x8000u #define U_CNTR_PMAOVRM 0x4000u #define U_CNTR_ERRM 0x2000u #define U_CNTR_WKUPM 0x1000u #define U_CNTR_SUSPM 0x0800u #define U_CNTR_RESETM 0x0400u #define U_CNTR_SOFM 0x0200u #define U_CNTR_ESOFM 0x0100u #define U_CNTR_RESUME 0x0010u #define U_CNTR_FSUSP 0x0008u #define U_CNTR_LPMODE 0x0004u #define U_CNTR_PDWN 0x0002u #define U_CNTR_FRES 0x0001u #define U_CNTR_HOST 0x80000000u // DRD: enable host mode #define U_CNTR_DCON 0x0400u // DRD host: same bit as RESETM // ISTR - Interrupt Status Register // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // CTR PMAOVR ERR WKUP SUSP RESET SOF ESOF Rsvd Rsvd Rsvd DIR EP_ID[3:0] // // DRD 32-bit only: // 31 30 29 28:16 // Rsvd LS_DCONN DCON_STAT Rsvd #define U_ISTR_CTR 0x8000u #define U_ISTR_PMAOVR 0x4000u #define U_ISTR_ERR 0x2000u #define U_ISTR_WKUP 0x1000u #define U_ISTR_SUSP 0x0800u #define U_ISTR_RESET 0x0400u #define U_ISTR_SOF 0x0200u #define U_ISTR_ESOF 0x0100u #define U_ISTR_DIR 0x0010u #define U_ISTR_EP_ID 0x000Fu #define U_ISTR_LS_DCONN 0x40000000u // DRD: low-speed device connected #define U_ISTR_DCON_STAT 0x20000000u // DRD: device connection status #define U_ISTR_DCON 0x0400u // DRD host: same bit as RESET // FNR - Frame Number Register (read-only) // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // RXDP RXDM LCK[2:0] FN[10:0] #define U_FNR_RXDP 0x8000u #define U_FNR_RXDM 0x4000u #define U_FNR_FN 0x07FFu // DADDR - Device Address Register // 15:8 7 6 5 4 3 2 1 0 // Rsvd EF ADD[6:0] #define U_DADDR_EF 0x80u // LPMCSR - LPM Control and Status Register // Supported: STM32 F0, L0, L4, G0, G4, C0, H5, U0, WB. Not on: F1, F3, AT32, CH32. // 15:8 7 6 5 4 3 2 1 0 // Rsvd BESL[3:0] Rsvd REMWAKE Rsvd LPMACK LMPEN #define U_LPMCSR_LMPEN 0x0001u #define U_LPMCSR_LPMACK 0x0002u #define U_LPMCSR_REMWAKE 0x0008u #define U_LPMCSR_BESL 0x00F0u // BCDR - Battery Charging Detector Register // Supported: STM32 F0, L0, L4, G0, G4, C0, H5, U0, WB. Not on: F1, F3, AT32, CH32. // 15 14:8 7 6 5 4 3 2 1 0 // DPPU Rsvd PS2DET SDET PDET DCDET SDEN PDEN DCDEN BCDEN #define U_BCDR_BCDEN 0x0001u #define U_BCDR_DCDEN 0x0002u #define U_BCDR_PDEN 0x0004u #define U_BCDR_SDEN 0x0008u #define U_BCDR_DCDET 0x0010u #define U_BCDR_PDET 0x0020u #define U_BCDR_SDET 0x0040u #define U_BCDR_PS2DET 0x0080u #define U_BCDR_DPPU 0x8000u // Channel status (DRD host mode, reuses STAT_TX/STAT_RX bit positions) #define U_CH_TX_STTX 0x0030u #define U_CH_TX_ACK_SBUF 0x0000u #define U_CH_TX_STALL 0x0010u #define U_CH_TX_NAK 0x0020u #define U_CH_RX_STRX 0x3000u #define U_CH_RX_ACK_SBUF 0x0000u #define U_CH_RX_STALL 0x1000u #define U_CH_RX_NAK 0x2000u #define U_CH_RX_VALID 0x3000u //--------------------------------------------------------------------+ // Registers Typedef //--------------------------------------------------------------------+ // hardware limit endpoint #define FSDEV_EP_COUNT 8 // The fsdev_bus_t type can be used for both register and PMA access necessities #ifdef CFG_TUSB_FSDEV_32BIT typedef uint32_t fsdev_bus_t; #else typedef uint16_t fsdev_bus_t; #endif // volatile 32-bit aligned #define _va32 volatile TU_ATTR_ALIGNED(4) typedef struct { struct { _va32 fsdev_bus_t reg; } ep[FSDEV_EP_COUNT]; _va32 uint32_t RESERVED7[8]; // Reserved _va32 fsdev_bus_t CNTR; // 40: Control register _va32 fsdev_bus_t ISTR; // 44: Interrupt status register _va32 fsdev_bus_t FNR; // 48: Frame number register _va32 fsdev_bus_t DADDR; // 4C: Device address register _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status (not on F1, F3, AT32, CH32) _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector (not on F1, F3, AT32, CH32) } fsdev_regs_t; TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define FSDEV_REG ((fsdev_regs_t *)FSDEV_REG_BASE) //--------------------------------------------------------------------+ // BTable and PMA Access //--------------------------------------------------------------------+ // If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it // Both of these MUST be a multiple of 2, and are in byte units. #ifndef FSDEV_BTABLE_BASE #define FSDEV_BTABLE_BASE 0U #endif TU_VERIFY_STATIC((FSDEV_BTABLE_BASE & 0x7) == 0, "BTABLE base must be aligned to 8 bytes"); #define FSDEV_ADDR_DATA_RATIO (CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE/CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE) // Need alignment when access address is 32 bit but data is only 16-bit #if FSDEV_ADDR_DATA_RATIO == 2 #define fsdev_addr_data_align TU_ATTR_ALIGNED(4) #else #define fsdev_addr_data_align #endif enum { BTABLE_BUF_TX = 0, BTABLE_BUF_RX = 1 }; // Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either // 16-bit or 32-bit depending on CFG_TUSB_FSDEV_32BIT. // 0: TX (IN), 1: RX (OUT) typedef union { // data is strictly 16-bit access (address could be 32-bit aligned) struct { volatile fsdev_addr_data_align uint16_t addr; volatile fsdev_addr_data_align uint16_t count; } ep16[FSDEV_EP_COUNT][2]; // strictly 32-bit access struct { volatile uint32_t count_addr; } ep32[FSDEV_EP_COUNT][2]; } fsdev_btable_t; TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT * 8 * FSDEV_ADDR_DATA_RATIO, "size is not correct"); TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT * 8 <= CFG_TUSB_FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); #define FSDEV_BTABLE ((volatile fsdev_btable_t *)(FSDEV_PMA_BASE + FSDEV_ADDR_DATA_RATIO * FSDEV_BTABLE_BASE)) typedef struct { volatile fsdev_addr_data_align fsdev_bus_t value; } fsdev_pma_buf_t; #define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t *)(FSDEV_PMA_BASE + FSDEV_ADDR_DATA_RATIO * (_addr))) //--------------------------------------------------------------------+ // Vendor-specific includes //--------------------------------------------------------------------+ #if defined(TUP_USBIP_FSDEV_STM32) #include "fsdev_stm32.h" #elif defined(TUP_USBIP_FSDEV_CH32) #include "fsdev_ch32.h" #elif defined(TUP_USBIP_FSDEV_AT32) #include "fsdev_at32.h" #else #error "Unknown USB IP" #endif //--------------------------------------------------------------------+ // Endpoint Helper // - CTR is write 0 to clear // - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, EP_STAT_NAK = 2, EP_STAT_VALID = 3 } ep_stat_t; #define EP_STAT_MASK(_dir) (3u << (U_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) #define EP_DTOG_MASK(_dir) (1u << (U_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) #define CH_STAT_MASK(_dir) (3u << (U_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) #define CH_DTOG_MASK(_dir) (1u << (U_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0))) TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; } TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) { if (need_exclusive) { fsdev_int_disable(0); } FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t)value; if (need_exclusive) { fsdev_int_enable(0); } } TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb_dir_t dir) { uint32_t reg = FSDEV_REG->ep[ep_id].reg; reg |= U_EP_CTR_TX | U_EP_CTR_RX; reg &= U_EPREG_MASK; reg &= ~(1 << (U_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); ep_write(ep_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (U_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) { *reg ^= (state << (U_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { return (reg & U_EP_TYPE_MASK) == U_EP_ISOCHRONOUS; } //--------------------------------------------------------------------+ // Channel Helper // - Direction is opposite to endpoint direction //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t ch_read(uint32_t ch_id) { return ep_read(ch_id); } TU_ATTR_ALWAYS_INLINE static inline void ch_write(uint32_t ch_id, uint32_t value, bool need_exclusive) { ep_write(ch_id, value, need_exclusive); } TU_ATTR_ALWAYS_INLINE static inline void ch_write_clear_ctr(uint32_t ch_id, tusb_dir_t dir) { uint32_t reg = FSDEV_REG->ep[ch_id].reg; reg |= U_EP_CTR_TX | U_EP_CTR_RX; reg &= U_EPREG_MASK; reg &= ~(1 << (U_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); ep_write(ch_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline void ch_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (U_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); } TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) { *reg ^= (state << (U_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0))); } //--------------------------------------------------------------------+ // BTable Helper //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { #ifdef CFG_TUSB_FSDEV_32BIT return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; #else return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { #ifdef CFG_TUSB_FSDEV_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; #ifdef CFG_TUSB_FSDEV_32BIT count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); #else count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; #endif return count & 0x3FFU; } TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { #ifdef CFG_TUSB_FSDEV_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; #endif } // Reset the USB Core void fsdev_core_reset(void); // De-initialize the USB Core void fsdev_deinit(void); // Aligned buffer size according to hardware uint16_t pma_align_buffer_size(uint16_t size, uint8_t *blsize, uint8_t *num_block); // Set RX buffer size void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount); #ifdef __cplusplus } #endif #endif /* TUSB_FSDEV_COMMON_H */ ================================================ FILE: src/portable/st/stm32_fsdev/fsdev_stm32.h ================================================ /* * The MIT License (MIT) * * Copyright(c) N Conrad * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 TinyUSB stack. */ #ifndef TUSB_FSDEV_STM32_H #define TUSB_FSDEV_STM32_H #if CFG_TUSB_MCU == OPT_MCU_STM32C0 #include "stm32c0xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" #define FSDEV_HAS_SBUF_ISO 0 // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support // PMA dedicated to USB (no sharing with CAN) #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" #define FSDEV_HAS_SBUF_ISO 0 // NO internal Pull-ups // *B, and *C: 2 x 16 bits/word #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 #include "stm32f3xx.h" #define FSDEV_HAS_SBUF_ISO 0 // NO internal Pull-ups. PMA dedicated to USB (no sharing with CAN) // xB, and xC: 512 bytes // x6, x8, xD, and xE: 1024 bytes + LPM Support. When CAN clock is enabled, USB can use the first 768 bytes ONLY. #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #include "stm32g0xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32G4 #include "stm32g4xx.h" #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 #include "stm32h5xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32L0 #include "stm32l0xx.h" #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32L1 #include "stm32l1xx.h" #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 #include "stm32l5xx.h" #define FSDEV_HAS_SBUF_ISO 0 #ifndef USB_PMAADDR #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 #include "stm32u0xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32U3 #include "stm32u3xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" #define FSDEV_HAS_SBUF_ISO 1 #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" #define FSDEV_HAS_SBUF_ISO 0 #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. #endif //--------------------------------------------------------------------+ // Register and PMA Base Address //--------------------------------------------------------------------+ #ifndef FSDEV_REG_BASE #if defined(USB_BASE) #define FSDEV_REG_BASE USB_BASE #elif defined(USB_DRD_BASE) #define FSDEV_REG_BASE USB_DRD_BASE #elif defined(USB_DRD_FS_BASE) #define FSDEV_REG_BASE USB_DRD_FS_BASE #else #error "FSDEV_REG_BASE not defined" #endif #endif #ifndef FSDEV_PMA_BASE #if defined(USB_PMAADDR) #define FSDEV_PMA_BASE USB_PMAADDR #elif defined(USB_DRD_PMAADDR) #define FSDEV_PMA_BASE USB_DRD_PMAADDR #else #error "FSDEV_PMA_BASE not defined" #endif #endif #ifndef FSDEV_HAS_SBUF_ISO #error "FSDEV_HAS_SBUF_ISO not defined" #endif #ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP // Default configuration for double-buffered isochronous endpoints: // - Enable double buffering on devices with >1KB Packet Memory Area (PMA) // to improve isochronous transfer reliability and performance // - Disable on devices with limited PMA to conserve memory space #if CFG_TUSB_FSDEV_PMA_SIZE > 1024u #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1 #else #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 #endif #endif #if FSDEV_HAS_SBUF_ISO != 0 && CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP == 0 // SBUF_ISO configuration: // - Some STM32 devices have special hardware support for single-buffered isochronous endpoints // - When SBUF_ISO bit is available and double buffering is disabled: // Enable SBUF_ISO to optimize endpoint register usage (one half of endpoint pair register) #define FSDEV_USE_SBUF_ISO 1 #else // When either: // - Hardware doesn't support SBUF_ISO feature, or // - Double buffering is enabled for isochronous endpoints // We must use the entire endpoint pair register #define FSDEV_USE_SBUF_ISO 0 #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_STM32L1) && !defined(USBWakeUp_IRQn) #define USBWakeUp_IRQn USB_FS_WKUP_IRQn #endif static const IRQn_Type fsdev_irq[] = { #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4, OPT_MCU_STM32U5) USB_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32L5, OPT_MCU_STM32U3) USB_FS_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32H5, OPT_MCU_STM32U0) USB_DRD_FS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #ifdef STM32G0B0xx USB_IRQn, #else USB_UCPD1_2_IRQn, #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 USB_HP_CAN1_TX_IRQn, USB_LP_CAN1_RX0_IRQn, USBWakeUp_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 USB_HP_CAN_TX_IRQn, USB_LP_CAN_RX0_IRQn, USBWakeUp_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1) USB_HP_IRQn, USB_LP_IRQn, USBWakeUp_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, #else #error Unknown arch in USB driver #endif }; enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) { (void)rhport; // forces write to RAM before allowing ISR to execute __DSB(); __ISB(); #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from // shared USB/CAN IRQs to separate CAN and USB IRQs. // This dynamically checks if this remap is active to enable the right IRQs. if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_EnableIRQ(USB_HP_IRQn); NVIC_EnableIRQ(USB_LP_IRQn); NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); } else #endif { for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { NVIC_EnableIRQ(fsdev_irq[i]); } } } TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { (void)rhport; #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from // shared USB/CAN IRQs to separate CAN and USB IRQs. // This dynamically checks if this remap is active to enable the right IRQs. if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_DisableIRQ(USB_HP_IRQn); NVIC_DisableIRQ(USB_LP_IRQn); NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); } else #endif { for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { NVIC_DisableIRQ(fsdev_irq[i]); } } // CMSIS has a membar after disabling interrupts } //--------------------------------------------------------------------+ // Connect / Disconnect //--------------------------------------------------------------------+ #if defined(USB_BCDR_DPPU) TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void)rhport; FSDEV_REG->BCDR &= ~U_BCDR_DPPU; } TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void)rhport; FSDEV_REG->BCDR |= U_BCDR_DPPU; } #elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) { (void)rhport; SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); } TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) { (void)rhport; SYSCFG->PMC |= SYSCFG_PMC_USB_PU; } #endif #endif /* TUSB_FSDEV_STM32_H */ ================================================ FILE: src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 HiFiPhile (Zixun LI) * * 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. * * This file is part of the TinyUSB stack. */ /********************************************** * This driver provides USB Host controller support for STM32 MCUs with "USB A"/"PCD"/"HCD" peripheral. * This covers these MCU families: * * C0 2048 byte buffer; 32-bit bus; host mode * G0 2048 byte buffer; 32-bit bus; host mode * U3 2048 byte buffer; 32-bit bus; host mode * H5 2048 byte buffer; 32-bit bus; host mode * U535, U545 2048 byte buffer; 32-bit bus; host mode * */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && defined(TUP_USBIP_FSDEV_DRD) #include "host/hcd.h" #include "host/usbh.h" #include "fsdev_common.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ // Debug level for FSDEV #define FSDEV_DEBUG 3 // Max number of endpoints application can open, can be larger than FSDEV_EP_COUNT #ifndef CFG_TUH_FSDEV_ENDPOINT_MAX #define CFG_TUH_FSDEV_ENDPOINT_MAX 16u #endif TU_VERIFY_STATIC(CFG_TUH_FSDEV_ENDPOINT_MAX <= 255, "currently only use 8-bit for index"); #if CFG_TUSB_MCU == OPT_MCU_STM32H5 #define CPU_FREQUENCY_MHZ 250U #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #define CPU_FREQUENCY_MHZ 160U #elif CFG_TUSB_MCU == OPT_MCU_STM32U3 #define CPU_FREQUENCY_MHZ 96U #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #define CPU_FREQUENCY_MHZ 64U #elif CFG_TUSB_MCU == OPT_MCU_STM32C0 #define CPU_FREQUENCY_MHZ 48U #else #error "CPU_FREQUENCY_MHZ not defined for this STM32 MCU" #endif enum { HCD_XFER_ERROR_MAX = 3, HCD_XFER_NAK_MAX = 15, HCD_XFER_NAK_DEFAULT = 3, }; // Host driver struct for each opened endpoint typedef struct { uint8_t *buffer; uint16_t buflen; uint16_t queued_len; uint16_t max_packet_size; uint8_t dev_addr; uint8_t ep_addr; uint8_t ep_type; uint8_t interval; struct TU_ATTR_PACKED { uint8_t ls_pre : 1; uint8_t allocated : 1; uint8_t next_setup : 1; uint8_t pid : 1; }; } hcd_endpoint_t; // Channel direction state typedef struct { hcd_endpoint_t* edpt; struct TU_ATTR_PACKED { uint8_t allocated : 1; uint8_t retry : 3; uint8_t nak : 4; // Max NAK count in current frame }; } hcd_channel_dir_t; // Additional info for each channel when it is active typedef struct { uint8_t dev_addr; uint8_t ep_num; uint8_t ep_type; hcd_channel_dir_t out, in; } hcd_channel_t; static struct { hcd_channel_t channel[FSDEV_EP_COUNT]; hcd_endpoint_t edpt[CFG_TUH_FSDEV_ENDPOINT_MAX]; bool connected; } _hcd_data; static tuh_configure_fsdev_t _tuh_cfg = { .max_nak = HCD_XFER_NAK_DEFAULT, }; //--------------------------------------------------------------------+ // Prototypes //--------------------------------------------------------------------+ static uint8_t endpoint_alloc(void); static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr); static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len); static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type); static bool edpt_xfer_kickoff(uint8_t ep_id); static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir); static void edpoint_close(uint8_t ep_id); static void port_status_handler(uint8_t rhport, bool in_isr); static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir); static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir); static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir); static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir); //--------------------------------------------------------------------+ // Inline Functions //--------------------------------------------------------------------+ static inline void endpoint_dealloc(hcd_endpoint_t* edpt) { edpt->allocated = 0; } static inline void channel_dealloc(hcd_channel_t* ch, tusb_dir_t dir) { if (dir == TUSB_DIR_OUT) { ch->out.allocated = 0; } else { ch->in.allocated = 0; } } // Write channel state in specified direction static inline void channel_write_status(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir, ep_stat_t state, bool need_exclusive) { ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir); ch_change_status(&ch_reg, dir, state); ch_write(ch_id, ch_reg, need_exclusive); } static inline uint16_t channel_get_rx_count(uint8_t ch_id) { /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers * Description: * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. * Workaround: * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode * * Note: this errata may also apply to G0, U5, H5 etc. * * We choose the delay count based on max CPU frequency (in MHz) to ensure the delay is at least the required time. */ uint32_t ch_reg = ch_read(ch_id); if (FSDEV_REG->ISTR & U_ISTR_LS_DCONN || ch_reg & U_EP_LSEP) { // Low speed mode: 6.4 us delay -> about 2 cycles per MHz volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ * 2U; while (cycle_count > 0U) { cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) } } else { // Full speed mode: 800 ns delay -> about 0.25 cycles per MHz volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ / 4U; while (cycle_count > 0U) { cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) } } return btable_get_count(ch_id, BTABLE_BUF_RX); } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // Optional HCD configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUH_CFGID_FSDEV && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _tuh_cfg.max_nak = tu_min8(cfg->fsdev.max_nak, HCD_XFER_NAK_MAX); return true; } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; fsdev_core_reset(); FSDEV_REG->CNTR = U_CNTR_HOST; // Enable USB in Host mode tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Clear pending interrupts // Normally no interrupts should be pending here since we just reset the core, // but device mode suspend needs to cleared by WKUP flag FSDEV_REG->ISTR = 0; // Enable interrupts for host mode FSDEV_REG->CNTR |= U_CNTR_DCON | U_CNTR_CTRM | U_CNTR_SOFM | U_CNTR_ERRM | U_CNTR_PMAOVRM; // Initialize port state _hcd_data.connected = false; fsdev_connect(rhport); // If DCON_STAT is already set, the controller sometimes misses the initial connection interrupt if (FSDEV_REG->ISTR & U_ISTR_DCON_STAT) { // Wait DP/DM stabilize time volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ / 4U; while (cycle_count > 0U) { cycle_count--; } port_status_handler(rhport, false); } return true; } bool hcd_deinit(uint8_t rhport) { (void)rhport; fsdev_disconnect(rhport); fsdev_deinit(); return true; } //--------------------------------------------------------------------+ // Interrupt Helper Functions //--------------------------------------------------------------------+ static inline void sof_handler(void) { // Reset NAK counters for all active channels for (uint8_t ch_id = 0; ch_id < FSDEV_EP_COUNT; ch_id++) { hcd_channel_t* channel = &_hcd_data.channel[ch_id]; if (channel->out.allocated) { channel->out.nak = 0; } if (channel->in.allocated) { channel->in.nak = 0; } } } static void port_status_handler(uint8_t rhport, bool in_isr) { uint32_t const fnr_reg = FSDEV_REG->FNR; uint32_t const istr_reg = FSDEV_REG->ISTR; // SE0 detected USB Disconnected state if ((fnr_reg & (U_FNR_RXDP | U_FNR_RXDM)) == 0U) { _hcd_data.connected = false; hcd_event_device_remove(rhport, in_isr); return; } if (!_hcd_data.connected) { // J-state or K-state detected & LastState=Disconnected if (((fnr_reg & U_FNR_RXDP) != 0U) || ((istr_reg & U_ISTR_LS_DCONN) != 0U)) { _hcd_data.connected = true; hcd_event_device_attach(rhport, in_isr); } } else { // J-state or K-state detected & lastState=Connected: a Missed disconnection is detected if (((fnr_reg & U_FNR_RXDP) != 0U) || ((istr_reg & U_ISTR_LS_DCONN) != 0U)) { _hcd_data.connected = false; hcd_event_device_remove(rhport, in_isr); } } } // Handle ACK response static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) { return; } hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; hcd_channel_t *channel = &_hcd_data.channel[ch_id]; if (dir == TUSB_DIR_OUT) { // OUT/TX direction if (edpt->buflen != edpt->queued_len) { // More data to send uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size); uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_TX); tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL); btable_set_count(ch_id, BTABLE_BUF_TX, len); edpt->queued_len += len; channel_write_status(ch_id, ch_reg, TUSB_DIR_OUT, EP_STAT_VALID, false); channel->out.nak = 0; } else { // Transfer complete channel_dealloc(channel, TUSB_DIR_OUT); edpt->pid = (ch_reg & U_EP_DTOG_TX) ? 1 : 0; hcd_event_xfer_complete(daddr, ep_num, edpt->queued_len, XFER_RESULT_SUCCESS, true); } } else { // IN/RX direction uint16_t const rx_count = channel_get_rx_count(ch_id); uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_RX); tu_hwfifo_read(PMA_BUF_AT(pma_addr), edpt->buffer + edpt->queued_len, rx_count, NULL); edpt->queued_len += rx_count; if ((rx_count < edpt->max_packet_size) || (edpt->queued_len >= edpt->buflen)) { // Transfer complete (short packet or all bytes received) channel_dealloc(channel, TUSB_DIR_IN); edpt->pid = (ch_reg & U_EP_DTOG_RX) ? 1 : 0; hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, edpt->queued_len, XFER_RESULT_SUCCESS, true); } else { // More data expected uint16_t const cnt = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size); btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, cnt); channel_write_status(ch_id, ch_reg, TUSB_DIR_IN, EP_STAT_VALID, false); channel->in.nak = 0; } } } // Handle NAK response static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; // Retry non-periodic transfer immediately if NAK count not exceeded // Periodic transfer will be retried by next frame automatically if (edpt->ep_type == TUSB_XFER_CONTROL || edpt->ep_type == TUSB_XFER_BULK) { hcd_channel_dir_t* channel_dir = (dir == TUSB_DIR_OUT) ? &(_hcd_data.channel[ch_id].out) : &(_hcd_data.channel[ch_id].in); if (channel_dir->nak < HCD_XFER_NAK_MAX) { channel_dir->nak++; } if (channel_dir->nak < _tuh_cfg.max_nak || _tuh_cfg.max_nak == 0) { channel_write_status(ch_id, ch_reg, dir, EP_STAT_VALID, false); } } } // Handle STALL response static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; channel_dealloc(channel, dir); channel_write_status(ch_id, ch_reg, dir, EP_STAT_DISABLED, false); hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0), edpt->queued_len, XFER_RESULT_STALLED, true); } // Handle error response static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) { uint8_t const ep_num = ch_reg & U_EPADDR_FIELD; uint8_t const daddr = (ch_reg & U_EP_DEVADDR) >> U_EP_DEVADDR_Pos; uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0)); if (ep_id == TUSB_INDEX_INVALID_8) return; hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir); ch_reg &= ~(dir == TUSB_DIR_OUT ? U_EP_ERRTX : U_EP_ERRRX); hcd_channel_dir_t* channel_dir = (dir == TUSB_DIR_OUT) ? &(_hcd_data.channel[ch_id].out) : &(_hcd_data.channel[ch_id].in); if (channel_dir->retry < HCD_XFER_ERROR_MAX) { // Retry channel_dir->retry++; ch_change_status(&ch_reg, dir, EP_STAT_VALID); } else { // Failed after retries channel_dealloc(channel, dir); ch_change_status(&ch_reg, dir, EP_STAT_DISABLED); hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0), edpt->queued_len, XFER_RESULT_FAILED, true); } ch_write(ch_id, ch_reg, false); } // Handle CTR interrupt for the TX/OUT direction static inline void handle_ctr_tx(uint32_t ch_id) { uint32_t ch_reg = ch_read(ch_id) | U_EP_CTR_TX | U_EP_CTR_RX; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; TU_VERIFY(channel->out.allocated == 1,); if ((ch_reg & U_EP_ERRTX) == 0U) { // No error if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_ACK_SBUF) { ch_handle_ack(ch_id, ch_reg, TUSB_DIR_OUT); } else if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_NAK) { ch_handle_nak(ch_id, ch_reg, TUSB_DIR_OUT); } else if ((ch_reg & U_CH_TX_STTX) == U_CH_TX_STALL) { ch_handle_stall(ch_id, ch_reg, TUSB_DIR_OUT); } } else { ch_handle_error(ch_id, ch_reg, TUSB_DIR_OUT); } } // Handle CTR interrupt for the RX/IN direction static inline void handle_ctr_rx(uint32_t ch_id) { uint32_t ch_reg = ch_read(ch_id) | U_EP_CTR_TX | U_EP_CTR_RX; hcd_channel_t* channel = &_hcd_data.channel[ch_id]; TU_VERIFY(channel->in.allocated == 1,); if ((ch_reg & U_EP_ERRRX) == 0U) { // No error if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_ACK_SBUF) { ch_handle_ack(ch_id, ch_reg, TUSB_DIR_IN); } else if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_NAK) { ch_handle_nak(ch_id, ch_reg, TUSB_DIR_IN); } else if ((ch_reg & U_CH_RX_STRX) == U_CH_RX_STALL){ ch_handle_stall(ch_id, ch_reg, TUSB_DIR_IN); } } else { ch_handle_error(ch_id, ch_reg, TUSB_DIR_IN); } } // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr) { uint32_t int_status = FSDEV_REG->ISTR; // Start of Frame if (int_status & U_ISTR_SOF) { FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_SOF; sof_handler(); } // Port Change Detected (Connection/Disconnection) if (int_status & U_ISTR_DCON) { FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_DCON; port_status_handler(rhport, in_isr); } // Handle transfer complete (CTR) while (FSDEV_REG->ISTR & U_ISTR_CTR) { uint32_t const ch_id = FSDEV_REG->ISTR & U_ISTR_EP_ID; uint32_t const ch_reg = ch_read(ch_id); if (ch_reg & U_EP_CTR_RX) { ch_write_clear_ctr(ch_id, TUSB_DIR_IN); handle_ctr_rx(ch_id); } if (ch_reg & U_EP_CTR_TX) { ch_write_clear_ctr(ch_id, TUSB_DIR_OUT); handle_ctr_tx(ch_id); } } if (int_status & U_ISTR_ERR) { FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_ERR; // TODO: Handle error } if (int_status & U_ISTR_PMAOVR) { TU_BREAKPOINT(); FSDEV_REG->ISTR = (fsdev_bus_t)~U_ISTR_PMAOVR; } } // Enable USB interrupt void hcd_int_enable(uint8_t rhport) { fsdev_int_enable(rhport); } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { fsdev_int_disable(rhport); } // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return FSDEV_REG->FNR & U_FNR_FN; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; return _hcd_data.connected; } // Reset USB bus on the port void hcd_port_reset(uint8_t rhport) { (void) rhport; FSDEV_REG->CNTR |= U_CNTR_FRES; } // Complete bus reset sequence void hcd_port_reset_end(uint8_t rhport) { (void) rhport; FSDEV_REG->CNTR &= ~U_CNTR_FRES; } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; if ((FSDEV_REG->ISTR & U_ISTR_LS_DCONN) != 0U) { return TUSB_SPEED_LOW; } else { return TUSB_SPEED_FULL; } } // HCD closes all opened endpoints belonging to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void) rhport; // Close all endpoints for this device for(uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) { hcd_endpoint_t* edpt = &_hcd_data.edpt[i]; if (edpt->allocated == 1 && edpt->dev_addr == dev_addr) { edpoint_close(i); } } } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) { (void) rhport; uint8_t const ep_addr = ep_desc->bEndpointAddress; uint16_t const packet_size = tu_edpt_packet_size(ep_desc); uint8_t const ep_type = ep_desc->bmAttributes.xfer; uint8_t const ep_id = endpoint_alloc(); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; edpt->dev_addr = dev_addr; edpt->ep_addr = ep_addr; edpt->ep_type = ep_type; edpt->max_packet_size = packet_size; edpt->interval = ep_desc->bInterval; edpt->pid = 0; edpt->ls_pre = (hcd_port_speed_get(rhport) == TUSB_SPEED_FULL && tuh_speed_get(dev_addr) == TUSB_SPEED_LOW) ? 1 : 0; return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); edpoint_close(ep_id); return true; } // Submit a transfer bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void) rhport; TU_LOG(FSDEV_DEBUG, "hcd_edpt_xfer addr=%u ep=0x%02X len=%u\r\n", dev_addr, ep_addr, buflen); uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; edpt->buffer = buffer; edpt->buflen = buflen; edpt->queued_len = 0; uint8_t const ep_num = tu_edpt_number(ep_addr); if (ep_num == 0) { // update ep_dir since control endpoint can switch direction edpt->ep_addr = ep_addr; } return edpt_xfer_kickoff(ep_id); } // Abort a queued transfer bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); tusb_dir_t const dir = tu_edpt_dir(ep_addr); for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { hcd_channel_t* channel = &_hcd_data.channel[i]; uint8_t const allocated = (dir == TUSB_DIR_OUT) ? channel->out.allocated : channel->in.allocated; if (allocated == 1 && channel->dev_addr == dev_addr && channel->ep_num == tu_edpt_number(ep_addr)) { channel_dealloc(channel, dir); uint32_t ch_reg = ch_read(i) | U_EP_CTR_TX | U_EP_CTR_RX; channel_write_status(i, ch_reg, dir, EP_STAT_DISABLED, true); } } return true; } // Submit a special transfer to send 8-byte Setup Packet bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; uint8_t const ep_id = endpoint_find(dev_addr, 0); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; edpt->next_setup = true; edpt->pid = 0; return hcd_edpt_xfer(rhport, dev_addr, 0, (uint8_t*)(uintptr_t) setup_packet, 8); } // Clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; uint8_t const ep_id = endpoint_find(dev_addr, ep_addr); TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; edpt->pid = 0; return true; } //--------------------------------------------------------------------+ // Helper Functions //--------------------------------------------------------------------+ static uint8_t endpoint_alloc(void) { for (uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) { hcd_endpoint_t* edpt = &_hcd_data.edpt[i]; if (edpt->allocated == 0) { edpt->allocated = 1; return i; } } return TUSB_INDEX_INVALID_8; } static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr) { uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr); for (uint32_t i = 0; i < (uint32_t)CFG_TUH_FSDEV_ENDPOINT_MAX; i++) { hcd_endpoint_t* edpt = &_hcd_data.edpt[i]; tusb_dir_t const dir = tu_edpt_dir(edpt->ep_addr); uint8_t const num = tu_edpt_number(edpt->ep_addr); // Match both ep_num and ep_dir, or match ep_num 0 (control endpoint) if (edpt->allocated == 1 && edpt->dev_addr == dev_addr && num == ep_num && (dir == ep_dir || ep_num == 0)) { return i; } } return TUSB_INDEX_INVALID_8; } // close an opened endpoint static void edpoint_close(uint8_t ep_id) { hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; endpoint_dealloc(edpt); // disable active channel belong to this endpoint for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { hcd_channel_t* channel = &_hcd_data.channel[i]; uint32_t ch_reg = ch_read(i) | U_EP_CTR_TX | U_EP_CTR_RX; if (channel->out.allocated == 1 && channel->out.edpt == edpt) { channel_dealloc(channel, TUSB_DIR_OUT); channel_write_status(i, ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED, true); } if (channel->in.allocated == 1 && channel->in.edpt == edpt) { channel_dealloc(channel, TUSB_DIR_IN); channel_write_status(i, ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED, true); } } } // Allocate PMA buffer static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len) { (void) len; // Simple static allocation as we are unlikely to handle ISO endpoints in host mode // We just give each channel two buffers of max packet size (64 bytes) for IN and OUT uint16_t addr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; addr += channel * TUSB_EPSIZE_BULK_FS * 2 + (dir == TUSB_DIR_IN ? TUSB_EPSIZE_BULK_FS : 0); TU_ASSERT(addr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF); return addr; } // Allocate hardware channel static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type) { uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); // Find channel allocate for same ep_num but other direction tusb_dir_t const other_dir = (dir == TUSB_DIR_IN) ? TUSB_DIR_OUT : TUSB_DIR_IN; for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { uint8_t const allocated_dir = (dir == TUSB_DIR_OUT) ? _hcd_data.channel[i].out.allocated : _hcd_data.channel[i].in.allocated; uint8_t const allocated_other = (other_dir == TUSB_DIR_OUT) ? _hcd_data.channel[i].out.allocated : _hcd_data.channel[i].in.allocated; if (allocated_dir == 0 && allocated_other == 1 && _hcd_data.channel[i].dev_addr == dev_addr && _hcd_data.channel[i].ep_num == ep_num && _hcd_data.channel[i].ep_type == ep_type) { if (dir == TUSB_DIR_OUT) { _hcd_data.channel[i].out.allocated = 1; _hcd_data.channel[i].out.retry = 0; } else { _hcd_data.channel[i].in.allocated = 1; _hcd_data.channel[i].in.retry = 0; } return i; } } // Find free channel for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { if (_hcd_data.channel[i].out.allocated == 0 && _hcd_data.channel[i].in.allocated == 0) { _hcd_data.channel[i].dev_addr = dev_addr; _hcd_data.channel[i].ep_num = ep_num; _hcd_data.channel[i].ep_type = ep_type; if (dir == TUSB_DIR_OUT) { _hcd_data.channel[i].out.allocated = 1; _hcd_data.channel[i].out.retry = 0; } else { _hcd_data.channel[i].in.allocated = 1; _hcd_data.channel[i].in.retry = 0; } return i; } } // Allocation failed return TUSB_INDEX_INVALID_8; } // kick-off transfer with an endpoint static bool edpt_xfer_kickoff(uint8_t ep_id) { hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; uint8_t ch_id = channel_alloc(edpt->dev_addr, edpt->ep_addr, edpt->ep_type); TU_ASSERT(ch_id != TUSB_INDEX_INVALID_8); // all channel are in used tusb_dir_t const dir = tu_edpt_dir(edpt->ep_addr); hcd_channel_t* channel = &_hcd_data.channel[ch_id]; if (dir == TUSB_DIR_OUT) { channel->out.edpt = edpt; } else { channel->in.edpt = edpt; } return channel_xfer_start(ch_id, dir); } static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) { hcd_channel_t* channel = &_hcd_data.channel[ch_id]; hcd_endpoint_t* edpt = (dir == TUSB_DIR_OUT) ? channel->out.edpt : channel->in.edpt; uint32_t ch_reg = ch_read(ch_id) & ~U_EPREG_MASK; ch_reg |= tu_edpt_number(edpt->ep_addr) | edpt->dev_addr << U_EP_DEVADDR_Pos | U_EP_CTR_TX | U_EP_CTR_RX; // Set type switch (edpt->ep_type) { case TUSB_XFER_BULK: ch_reg |= U_EP_BULK; break; case TUSB_XFER_INTERRUPT: ch_reg |= U_EP_INTERRUPT; break; case TUSB_XFER_CONTROL: ch_reg |= U_EP_CONTROL; break; default: // Note: ISO endpoint is unsupported TU_ASSERT(false); } /* Create a packet memory buffer area. */ uint16_t pma_addr = hcd_pma_alloc(ch_id, dir, edpt->max_packet_size); btable_set_addr(ch_id, dir == TUSB_DIR_OUT ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); if (dir == TUSB_DIR_OUT) { uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size); tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL); btable_set_count(ch_id, BTABLE_BUF_TX, len); edpt->queued_len += len; } else { btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, edpt->max_packet_size); } if (edpt->ls_pre == 1) { ch_reg |= U_EP_LSEP; } else { ch_reg &= ~U_EP_LSEP; } // Setup DATA/STATUS phase start with DATA1 if (tu_edpt_number(edpt->ep_addr) == 0) { edpt->pid = 1; } if (edpt->next_setup) { edpt->next_setup = false; ch_reg |= U_EP_SETUP; edpt->pid = 0; } ch_change_status(&ch_reg, dir, EP_STAT_VALID); ch_change_dtog(&ch_reg, dir, edpt->pid); ch_reg &= U_EPREG_MASK | CH_STAT_MASK(dir) | CH_DTOG_MASK(dir); ch_write(ch_id, ch_reg, true); return true; } #endif ================================================ FILE: src/portable/st/typec/typec_stm32.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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 "tusb_option.h" #include "typec/tcd.h" #if CFG_TUC_ENABLED && defined(TUP_USBIP_TYPEC_STM32) #include "common/tusb_common.h" #if CFG_TUSB_MCU == OPT_MCU_STM32G4 #include "stm32g4xx.h" #include "stm32g4xx_ll_dma.h" // for UCPD REQID #else #error "Unsupported STM32 family" #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ enum { IMR_ATTACHED = UCPD_IMR_TXMSGDISCIE | UCPD_IMR_TXMSGSENTIE | UCPD_IMR_TXMSGABTIE | UCPD_IMR_TXUNDIE | UCPD_IMR_RXHRSTDETIE | UCPD_IMR_RXOVRIE | UCPD_IMR_RXMSGENDIE | UCPD_IMR_RXORDDETIE | UCPD_IMR_HRSTDISCIE | UCPD_IMR_HRSTSENTIE | UCPD_IMR_FRSEVTIE }; #define PHY_SYNC1 0x18u #define PHY_SYNC2 0x11u #define PHY_SYNC3 0x06u #define PHY_RST1 0x07u #define PHY_RST2 0x19u #define PHY_EOP 0x0Du #define PHY_ORDERED_SET_SOP (PHY_SYNC1 | (PHY_SYNC1<<5u) | (PHY_SYNC1<<10u) | (PHY_SYNC2<<15u)) // SOP Ordered set coding #define PHY_ORDERED_SET_SOP_P (PHY_SYNC1 | (PHY_SYNC1<<5u) | (PHY_SYNC3<<10u) | (PHY_SYNC3<<15u)) // SOP' Ordered set coding #define PHY_ORDERED_SET_SOP_PP (PHY_SYNC1 | (PHY_SYNC3<<5u) | (PHY_SYNC1<<10u) | (PHY_SYNC3<<15u)) // SOP'' Ordered set coding #define PHY_ORDERED_SET_HARD_RESET (PHY_RST1 | (PHY_RST1<<5u) | (PHY_RST1<<10u) | (PHY_RST2<<15u )) // Hard Reset Ordered set coding #define PHY_ORDERED_SET_CABLE_RESET (PHY_RST1 | (PHY_SYNC1<<5u) | (PHY_RST1<<10u) | (PHY_SYNC3<<15u)) // Cable Reset Ordered set coding #define PHY_ORDERED_SET_SOP_P_DEBUG (PHY_SYNC1 | (PHY_RST2<<5u) | (PHY_RST2<<10u) | (PHY_SYNC3<<15u)) // SOP' Debug Ordered set coding #define PHY_ORDERED_SET_SOP_PP_DEBUG (PHY_SYNC1 | (PHY_RST2<<5u) | (PHY_SYNC3<<10u) | (PHY_SYNC2<<15u)) // SOP'' Debug Ordered set coding static uint8_t const* _rx_buf; static uint8_t const* _tx_pending_buf; static uint16_t _tx_pending_bytes; static uint16_t _tx_xferring_bytes; static pd_header_t _good_crc = { .msg_type = PD_CTRL_GOOD_CRC, .data_role = 0, // UFP .specs_rev = PD_REV_20, .power_role = 0, // Sink .msg_id = 0, .n_data_obj = 0, .extended = 0 }; // address of DMA channel rx, tx for each port #define CFG_TUC_STM32_DMA { { DMA1_Channel1_BASE, DMA1_Channel2_BASE } } //--------------------------------------------------------------------+ // DMA //--------------------------------------------------------------------+ static const uint32_t _dma_addr_arr[TUP_TYPEC_RHPORTS_NUM][2] = CFG_TUC_STM32_DMA; TU_ATTR_ALWAYS_INLINE static inline uint32_t dma_get_addr(uint8_t rhport, bool is_rx) { return _dma_addr_arr[rhport][is_rx ? 0 : 1]; } static void dma_init(uint8_t rhport, bool is_rx) { uint32_t dma_addr = dma_get_addr(rhport, is_rx); DMA_Channel_TypeDef* dma_ch = (DMA_Channel_TypeDef*) dma_addr; uint32_t req_id; if (is_rx) { // Peripheral -> Memory, Memory inc, 8-bit, High priority dma_ch->CCR = DMA_CCR_MINC | DMA_CCR_PL_1; dma_ch->CPAR = (uint32_t) &UCPD1->RXDR; req_id = LL_DMAMUX_REQ_UCPD1_RX; } else { // Memory -> Peripheral, Memory inc, 8-bit, High priority dma_ch->CCR = DMA_CCR_MINC | DMA_CCR_PL_1 | DMA_CCR_DIR; dma_ch->CPAR = (uint32_t) &UCPD1->TXDR; req_id = LL_DMAMUX_REQ_UCPD1_TX; } // find and set up mux channel TODO support mcu with multiple DMAMUXs enum { CH_DIFF = DMA1_Channel2_BASE - DMA1_Channel1_BASE }; uint32_t mux_ch_num; #ifdef DMA2_BASE if (dma_addr > DMA2_BASE) { mux_ch_num = 8 * ((dma_addr - DMA2_Channel1_BASE) / CH_DIFF); } else #endif { mux_ch_num = (dma_addr - DMA1_Channel1_BASE) / CH_DIFF; } DMAMUX_Channel_TypeDef* mux_ch = DMAMUX1_Channel0 + mux_ch_num; uint32_t mux_ccr = mux_ch->CCR & ~(DMAMUX_CxCR_DMAREQ_ID); mux_ccr |= req_id; mux_ch->CCR = mux_ccr; } TU_ATTR_ALWAYS_INLINE static inline void dma_start(uint8_t rhport, bool is_rx, void const* buf, uint16_t len) { DMA_Channel_TypeDef* dma_ch = (DMA_Channel_TypeDef*) dma_get_addr(rhport, is_rx); dma_ch->CMAR = (uint32_t) buf; dma_ch->CNDTR = len; dma_ch->CCR |= DMA_CCR_EN; } TU_ATTR_ALWAYS_INLINE static inline void dma_stop(uint8_t rhport, bool is_rx) { DMA_Channel_TypeDef* dma_ch = (DMA_Channel_TypeDef*) dma_get_addr(rhport, is_rx); dma_ch->CCR &= ~DMA_CCR_EN; } TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(uint8_t rhport, bool is_rx) { DMA_Channel_TypeDef* dma_ch = (DMA_Channel_TypeDef*) dma_get_addr(rhport, is_rx); return dma_ch->CCR & DMA_CCR_EN; } TU_ATTR_ALWAYS_INLINE static inline void dma_tx_start(uint8_t rhport, void const* buf, uint16_t len) { UCPD1->TX_ORDSET = PHY_ORDERED_SET_SOP; UCPD1->TX_PAYSZ = len; dma_start(rhport, false, buf, len); UCPD1->CR |= UCPD_CR_TXSEND; } TU_ATTR_ALWAYS_INLINE static inline void dma_tx_stop(uint8_t rhport) { dma_stop(rhport, false); } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool tcd_init(uint8_t rhport, uint32_t port_type) { (void) rhport; // Init DMA for RX, TX dma_init(rhport, true); dma_init(rhport, false); // Initialization phase: CFG1, detect all SOPs UCPD1->CFG1 = (0x0d << UCPD_CFG1_HBITCLKDIV_Pos) | (0x10 << UCPD_CFG1_IFRGAP_Pos) | (0x07 << UCPD_CFG1_TRANSWIN_Pos) | (0x01 << UCPD_CFG1_PSC_UCPDCLK_Pos) | (0x1f << UCPD_CFG1_RXORDSETEN_Pos); UCPD1->CFG1 |= UCPD_CFG1_UCPDEN; // General programming sequence (with UCPD configured then enabled) if (port_type == TUSB_TYPEC_PORT_SNK) { // Set analog mode enable both CC Phy UCPD1->CR = (0x01 << UCPD_CR_ANAMODE_Pos) | (UCPD_CR_CCENABLE_0 | UCPD_CR_CCENABLE_1); // Read Voltage State on CC1 & CC2 fore initial state uint32_t v_cc[2]; (void) v_cc; v_cc[0] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC1_Pos) & 0x03; v_cc[1] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC2_Pos) & 0x03; TU_LOG1("Initial VState CC1 = %lu, CC2 = %lu\r\n", v_cc[0], v_cc[1]); // Enable CC1 & CC2 Interrupt UCPD1->IMR = UCPD_IMR_TYPECEVT1IE | UCPD_IMR_TYPECEVT2IE; } // Disable dead battery in PWR's CR3 PWR->CR3 |= PWR_CR3_UCPD_DBDIS; return true; } // Enable interrupt void tcd_int_enable (uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(UCPD1_IRQn); } // Disable interrupt void tcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(UCPD1_IRQn); } bool tcd_msg_receive(uint8_t rhport, uint8_t* buffer, uint16_t total_bytes) { _rx_buf = buffer; dma_start(rhport, true, buffer, total_bytes); return true; } bool tcd_msg_send(uint8_t rhport, uint8_t const* buffer, uint16_t total_bytes) { (void) rhport; if (dma_enabled(rhport, false)) { // DMA is busy, probably sending GoodCRC, save as pending TX _tx_pending_buf = buffer; _tx_pending_bytes = total_bytes; }else { // DMA is free, start sending _tx_pending_buf = NULL; _tx_pending_bytes = 0; _tx_xferring_bytes = total_bytes; dma_tx_start(rhport, buffer, total_bytes); } return true; } void tcd_int_handler(uint8_t rhport) { (void) rhport; uint32_t sr = UCPD1->SR; sr &= UCPD1->IMR; if (sr & (UCPD_SR_TYPECEVT1 | UCPD_SR_TYPECEVT2)) { uint32_t v_cc[2]; v_cc[0] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC1_Pos) & 0x03; v_cc[1] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC2_Pos) & 0x03; TU_LOG3("VState CC1 = %lu, CC2 = %lu\r\n", v_cc[0], v_cc[1]); uint32_t cr = UCPD1->CR; // TODO only support SNK for now, required highest voltage for now // Enable PHY on active CC and disable Rd on other CC // FIXME somehow CC2 is vstate is not correct, always 1 even not attached. // on DPOW1 board, it is connected to PA10 (USBPD_DBCC2), we probably miss something. if ((sr & UCPD_SR_TYPECEVT1) && (v_cc[0] == 3)) { TU_LOG3("Attach CC1\r\n"); cr &= ~(UCPD_CR_PHYCCSEL | UCPD_CR_CCENABLE); cr |= UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_0; } else if ((sr & UCPD_SR_TYPECEVT2) && (v_cc[1] == 3)) { TU_LOG3("Attach CC2\r\n"); cr &= ~UCPD_CR_CCENABLE; cr |= (UCPD_CR_PHYCCSEL | UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_1); } else { TU_LOG3("Detach\r\n"); cr &= ~UCPD_CR_PHYRXEN; cr |= UCPD_CR_CCENABLE_0 | UCPD_CR_CCENABLE_1; } if (cr & UCPD_CR_PHYRXEN) { // Attached UCPD1->IMR |= IMR_ATTACHED; UCPD1->CFG1 |= UCPD_CFG1_RXDMAEN | UCPD_CFG1_TXDMAEN; }else { // Detached UCPD1->CFG1 &= ~(UCPD_CFG1_RXDMAEN | UCPD_CFG1_TXDMAEN); UCPD1->IMR &= ~IMR_ATTACHED; } // notify stack tcd_event_cc_changed(rhport, v_cc[0], v_cc[1], true); UCPD1->CR = cr; // ack UCPD1->ICR = UCPD_ICR_TYPECEVT1CF | UCPD_ICR_TYPECEVT2CF; } //------------- RX -------------// if (sr & UCPD_SR_RXORDDET) { // SOP: Start of Packet. TU_LOG3("SOP\r\n"); // UCPD1->RX_ORDSET & UCPD_RX_ORDSET_RXORDSET_Msk; // ack UCPD1->ICR = UCPD_ICR_RXORDDETCF; } // Received full message if (sr & UCPD_SR_RXMSGEND) { TU_LOG3("RX MSG END\r\n"); // stop TX dma_stop(rhport, true); uint8_t result; if (!(sr & UCPD_SR_RXERR)) { // response with good crc // TODO move this to usbc stack if (_rx_buf) { _good_crc.msg_id = ((pd_header_t const *) _rx_buf)->msg_id; dma_tx_start(rhport, &_good_crc, 2); } result = XFER_RESULT_SUCCESS; }else { // CRC failed result = XFER_RESULT_FAILED; } // notify stack tcd_event_rx_complete(rhport, UCPD1->RX_PAYSZ, result, true); // ack UCPD1->ICR = UCPD_ICR_RXMSGENDCF; } if (sr & UCPD_SR_RXOVR) { TU_LOG3("RXOVR\r\n"); // ack UCPD1->ICR = UCPD_ICR_RXOVRCF; } //------------- TX -------------// // All tx events: complete and error if (sr & (UCPD_SR_TXMSGSENT | (UCPD_SR_TXMSGDISC | UCPD_SR_TXMSGABT | UCPD_SR_TXUND))) { // force TX stop dma_tx_stop(rhport); uint16_t const xferred_bytes = _tx_xferring_bytes - UCPD1->TX_PAYSZ; uint8_t result; if ( sr & UCPD_SR_TXMSGSENT ) { TU_LOG3("TX MSG SENT\r\n"); result = XFER_RESULT_SUCCESS; // ack UCPD1->ICR = UCPD_ICR_TXMSGSENTCF; }else { TU_LOG3("TX Error\r\n"); result = XFER_RESULT_FAILED; // ack UCPD1->ICR = UCPD_SR_TXMSGDISC | UCPD_SR_TXMSGABT | UCPD_SR_TXUND; } // start pending TX if any if (_tx_pending_buf && _tx_pending_bytes ) { // Start the pending TX dma_tx_start(rhport, _tx_pending_buf, _tx_pending_bytes); // clear pending _tx_pending_buf = NULL; _tx_pending_bytes = 0; } // notify stack tcd_event_tx_complete(rhport, xferred_bytes, result, true); } } #endif ================================================ FILE: src/portable/sunxi/dcd_sunxi_musb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2021 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_F1C100S #include "osal/osal.h" #include #include #include "musb_def.h" typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; #define REQUEST_TYPE_INVALID (0xFFu) typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ } free_block_t; typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ } pipe_state_t; typedef struct { CFG_TUD_MEM_ALIGN tusb_control_request_t setup_packet; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; /*------------------------------------------------------------------ * SUNXI FUNCTION *------------------------------------------------------------------*/ static void usb_phy_write(int addr, int data, int len) { int j = 0, usbc_bit = 0; void *dest = (void *)USBC_REG_CSR(USBC0_BASE); usbc_bit = 1 << (0 * 2); for (j = 0; j < len; j++) { /* set the bit address to be written */ USBC_ClrBit_Mask_l(dest, 0xff << 8); USBC_SetBit_Mask_l(dest, (addr + j) << 8); USBC_ClrBit_Mask_l(dest, usbc_bit); /* set data bit */ if (data & 0x1) USBC_SetBit_Mask_l(dest, 1 << 7); else USBC_ClrBit_Mask_l(dest, 1 << 7); USBC_SetBit_Mask_l(dest, usbc_bit); USBC_ClrBit_Mask_l(dest, usbc_bit); data >>= 1; } } static void USBC_HardwareReset(void) { // Reset phy and controller USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); tusb_time_delay_ms_api(2); USBC_REG_set_bit_l(USBPHY_CLK_GAT_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(BUS_CLK_USB_BIT, BUS_CLK_GATE0_REG); USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); } static void USBC_PhyConfig(void) { /* Regulation 45 ohms */ usb_phy_write(0x0c, 0x01, 1); /* adjust PHY's magnitude and rate */ usb_phy_write(0x20, 0x14, 5); /* threshold adjustment disconnect */ usb_phy_write(0x2a, 3, 2); return; } static void USBC_ConfigFIFO_Base(void) { u32 reg_value; /* config usb fifo, 8kb mode */ reg_value = USBC_Readl(SUNXI_SRAMC_BASE + 0x04); reg_value &= ~(0x03 << 0); reg_value |= (1 << 0); USBC_Writel(reg_value, SUNXI_SRAMC_BASE + 0x04); } static unsigned int USBC_WakeUp_ClearChangeDetect(unsigned int reg_val) { unsigned int temp = reg_val; /* vbus, id, dpdm, these bit is set 1 to clear, so we clear these bit when operate other bits */ temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT); temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT); temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT); return temp; } static void USBC_EnableDpDmPullUp(void) { u32 reg_val = USBC_Readl(USBC_REG_ISCR(USBC0_BASE)); reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN); reg_val |= 3<beg) || (cur->end <= addr)); ++cur) ; return cur; } static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { free_block_t *p = find_containing_block(blks, blks + num, addr); TU_ASSERT(p != blks + num, -2); if (p->beg == addr) { /* Shrink block */ p->beg = addr + size; if (p->beg != p->end) return 0; /* remove block */ free_block_t *end = blks + num; while (p + 1 < end) { *p = *(p + 1); ++p; } return -1; } else { /* Split into 2 blocks */ free_block_t tmp = { .beg = addr + size, .end = p->end }; p->end = addr; if (p->beg == p->end) { if (tmp.beg != tmp.end) { *p = tmp; return 0; } /* remove block */ free_block_t *end = blks + num; while (p + 1 < end) { *p = *(p + 1); ++p; } return -1; } if (tmp.beg == tmp.end) return 0; blks[num] = tmp; return 1; } } static inline unsigned free_block_size(free_block_t const *blk) { return blk->end - blk->beg; } #if 0 static inline void print_block_list(free_block_t const *blk, unsigned num) { TU_LOG1("*************\r\n"); for (unsigned i = 0; i < num; ++i) { TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); ++blk; } } #else #define print_block_list(a,b) #endif #if CFG_TUSB_MCU == OPT_MCU_F1C100S #define USB_FIFO_SIZE_KB 4 #else #error "Unsupported MCU" #endif static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) { free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; unsigned num_blocks = 1; /* Backup current EP to restore later */ u8 backup_ep = USBC_GetActiveEp(); /* Initialize free memory block list */ free_blocks[0].beg = 64 / 8; free_blocks[0].end = (USB_FIFO_SIZE_KB << 10) / 8; /* 2KiB / 8 bytes */ for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { uint_fast16_t addr; int num; USBC_SelectActiveEp(i); addr = USBC_Readw(USBC_REG_TXFIFOAD(USBC0_BASE)); if (addr) { unsigned sz = USBC_Readb(USBC_REG_TXFIFOSZ(USBC0_BASE)); unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); TU_ASSERT(-2 < num, 0); num_blocks += num; print_block_list(free_blocks, num_blocks); } addr = USBC_Readw(USBC_REG_RXFIFOAD(USBC0_BASE)); if (addr) { unsigned sz = USBC_Readb(USBC_REG_RXFIFOSZ(USBC0_BASE)); unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); TU_ASSERT(-2 < num, 0); num_blocks += num; print_block_list(free_blocks, num_blocks); } } print_block_list(free_blocks, num_blocks); USBC_SelectActiveEp(backup_ep); /* Find the best fit memory block */ uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; free_block_t const *min = NULL; uint_fast16_t min_sz = 0xFFFFu; free_block_t const *end = &free_blocks[num_blocks]; for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { uint_fast16_t sz = free_block_size(cur); if (sz < size_in_8byte_unit) continue; if (size_in_8byte_unit == sz) return cur->beg; if (sz < min_sz) min = cur; } TU_ASSERT(min, 0); return min->beg; } static void pipe_write_packet(void *buff, volatile void *fifo, unsigned cnt) { u32 len = 0; u32 i32 = 0; u32 i8 = 0; u8 *buf8 = 0; u32 *buf32 = 0; //--<1>-- adjust data buf32 = buff; len = cnt; i32 = len >> 2; i8 = len & 0x03; //--<2>-- deal with 4byte part while (i32--) { USBC_Writel(*buf32++, fifo); } //--<3>-- deal with no 4byte part buf8 = (u8 *)buf32; while (i8--) { USBC_Writeb(*buf8++, fifo); } } static void pipe_read_packet(void *buff, volatile void *fifo, unsigned cnt) { u32 len = 0; u32 i32 = 0; u32 i8 = 0; u8 *buf8 = 0; u32 *buf32 = 0; //--<1>-- adjust data buf32 = buff; len = cnt; i32 = len >> 2; i8 = len & 0x03; //--<2>-- deal with 4byte part while (i32--) { *buf32++ = USBC_Readl(fifo); } //--<3>-- deal with no 4byte part buf8 = (u8 *)buf32; while (i8--) { *buf8++ = USBC_Readb(fifo); } } static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) { static const struct { void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); } ops[] = { /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, }; tu_fifo_buffer_info_t info; ops[dir].tu_fifo_get_info(f, &info); unsigned total_len = len; len = TU_MIN(total_len, info.linear.len); ops[dir].pipe_read_write(info.linear.ptr, fifo, len); unsigned rem = total_len - len; if (rem) { len = TU_MIN(rem, info.wrapped.len); ops[dir].pipe_read_write(info.wrapped.ptr, fifo, len); rem -= len; } ops[dir].tu_fifo_advance(f, total_len - rem); } /*------------------------------------------------------------------ * TRANSFER FUNCTION DECLARATION *------------------------------------------------------------------*/ static void process_setup_packet(uint8_t rhport) { uint32_t *p = (uint32_t*)(uintptr_t) &_dcd.setup_packet; p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); const unsigned len = _dcd.setup_packet.wLength; _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) __USBC_Dev_ep0_ReadDataHalf(); } static bool handle_xfer_in(uint_fast8_t ep_addr) { unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; if (!rem) { pipe->buf = NULL; return true; } const unsigned mps = USBC_Readw(USBC_REG_TXMAXP(USBC0_BASE)); const unsigned len = TU_MIN(mps, rem); uint8_t *buf = pipe->buf; // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t) buf, addr, len, TUSB_DIR_IN); } else { pipe_write_packet(buf, addr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; } __USBC_Dev_Tx_WriteDataComplete(); // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); return false; } static bool handle_xfer_out(uint_fast8_t ep_addr) { unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(__USBC_Dev_Rx_IsReadDataReady()); const unsigned mps = USBC_Readw(USBC_REG_RXMAXP(USBC0_BASE)); const unsigned rem = pipe->remaining; const unsigned vld = USBC_Readw(USBC_REG_RXCOUNT(USBC0_BASE)); const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); uint8_t *buf = pipe->buf; if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t )buf, addr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, addr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; } if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } __USBC_Dev_Rx_ReadDataComplete(); return false; } static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { (void)rhport; unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; pipe->buf = buffer; pipe->length = total_bytes; pipe->remaining = total_bytes; USBC_SelectActiveEp(tu_edpt_number(ep_addr)); if (dir_in) { handle_xfer_in(ep_addr); } else { if (__USBC_Dev_Rx_IsReadDataReady()) __USBC_Dev_Rx_ReadDataComplete(); } return true; } static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); USBC_SelectActiveEp(0); if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { /* STATUS OUT stage. * MUSB controller automatically handles STATUS OUT packets without * software helps. We do not have to do anything. And STATUS stage * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ // TU_LOG1(" STATUS OUT CSRL0 = %x\r\n", CSRL0); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); } else { /* The next setup packet has already been received, it aborts * invoking callback function to avoid confusing TUSB stack. */ TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); } return true; } const unsigned dir_in = tu_edpt_dir(ep_addr); if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); if (dir_in) { pipe_write_packet(buffer, (volatile void*) USBC_REG_EPFIFO0(USBC0_BASE), len); _dcd.pipe0.buf = buffer + len; _dcd.pipe0.length = len; _dcd.pipe0.remaining = 0; _dcd.remaining_ctrl = rem - len; if ((len < 64) || (rem == len)) { _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ __USBC_Dev_ep0_WriteDataComplete(); } else { __USBC_Dev_ep0_WriteDataHalf(); } // TU_LOG1(" IN CSRL0 = %x\r\n", CSRL0); } else { // TU_LOG1(" OUT CSRL0 = %x\r\n", CSRL0); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; __USBC_Dev_ep0_ReadDataHalf(); } } else if (dir_in) { // TU_LOG1(" STATUS IN CSRL0 = %x\r\n", CSRL0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ __USBC_Dev_ep0_ReadDataComplete(); } return true; } static void process_ep0(uint8_t rhport) { USBC_SelectActiveEp(0); uint_fast8_t csrl = USBC_Readw(USBC_REG_CSR0(USBC0_BASE)); // TU_LOG1(" EP0 CSRL0 = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ __USBC_Dev_ep0_ClearStall(); return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { // TU_LOG1(" ABORT by the next packets\r\n"); USBC_Dev_Ctrl_ClearSetupEnd(); if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, req & TUSB_DIR_IN_MASK, _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } req = REQUEST_TYPE_INVALID; if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ } if (csrl & USB_CSRL0_RXRDY) { /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ TU_ASSERT(sizeof(tusb_control_request_t) == USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)),); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ const unsigned vld = USBC_Readw(USBC_REG_COUNT0(USBC0_BASE)); const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); pipe_read_packet(_dcd.pipe0.buf, (volatile void*)USBC_REG_EPFIFO0(USBC0_BASE), len); _dcd.pipe0.remaining = rem - len; _dcd.remaining_ctrl -= len; _dcd.pipe0.buf = NULL; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } return; } /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ USBC_Dev_SetAddress((uint8_t)_dcd.setup_packet.wValue); } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); return; } if (_dcd.pipe0.buf) { /* DATA IN */ _dcd.pipe0.buf = NULL; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), _dcd.pipe0.length - _dcd.pipe0.remaining, XFER_RESULT_SUCCESS, true); } } static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned epn = tu_edpt_number(ep_addr); USBC_SelectActiveEp(epn); if (dir_in) { // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL); if (__USBC_Dev_Tx_IsEpStall()) { __USBC_Dev_Tx_ClearStall(); return; } completed = handle_xfer_in(ep_addr); } else { // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL); if (__USBC_Dev_Rx_IsEpStall()) { __USBC_Dev_Rx_ClearStall(); return; } completed = handle_xfer_out(ep_addr); } if (completed) { pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; dcd_event_xfer_complete(rhport, ep_addr, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); } } static void process_bus_reset(uint8_t rhport) { /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); dcd_event_bus_reset(rhport, USBC_Dev_QueryTransferMode(), true); } /*------------------------------------------------------------------ * Device API *------------------------------------------------------------------*/ static void usb_isr_handler(void) { dcd_int_handler(0); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; dcd_disconnect(rhport); USBC_HardwareReset(); USBC_PhyConfig(); USBC_ConfigFIFO_Base(); USBC_EnableDpDmPullUp(); USBC_ForceIdToHigh(); // Force device mode USBC_ForceVbusValidToHigh(); USBC_SelectBus(USBC_IO_TYPE_PIO, 0, 0); dcd_edpt_close_all(rhport); #if TUD_OPT_HIGH_SPEED USBC_REG_set_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); #else USBC_REG_clear_bit_b(USBC_BP_POWER_D_HIGH_SPEED_EN, USBC_REG_PCTL(USBC0_BASE)); #endif USBC_Writeb((1 << USBC_BP_INTUSBE_EN_SUSPEND) | (1 << USBC_BP_INTUSBE_EN_RESUME) | (1 << USBC_BP_INTUSBE_EN_RESET) | (1 << USBC_BP_INTUSBE_EN_SOF) | (1 << USBC_BP_INTUSBE_EN_DISCONNECT) , USBC_REG_INTUSBE(USBC0_BASE)); f1c100s_intc_clear_pend(F1C100S_IRQ_USBOTG); f1c100s_intc_set_isr(F1C100S_IRQ_USBOTG, usb_isr_handler); dcd_connect(rhport); return true; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void)rhport; USBC_REG_set_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void)rhport; USBC_REG_clear_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE)); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } void dcd_int_enable(uint8_t rhport) { (void)rhport; f1c100s_intc_enable_irq(F1C100S_IRQ_USBOTG); } static void musb_int_mask(void) { f1c100s_intc_mask_irq(F1C100S_IRQ_USBOTG); } void dcd_int_disable(uint8_t rhport) { (void)rhport; f1c100s_intc_disable_irq(F1C100S_IRQ_USBOTG); } static void musb_int_unmask(void) { f1c100s_intc_unmask_irq(F1C100S_IRQ_USBOTG); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)rhport; (void)dev_addr; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ USBC_SelectActiveEp(0); __USBC_Dev_ep0_ReadDataComplete(); } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; USBC_REG_set_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); tusb_time_delay_ms_api(10); USBC_REG_clear_bit_b(USBC_BP_POWER_D_RESUME, USBC_REG_PCTL(USBC0_BASE)); } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ #ifndef __ARMCC_VERSION #define __clz __builtin_clz #endif // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; uint16_t reg_val; const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; pipe->length = 0; pipe->remaining = 0; musb_int_mask(); // volatile hw_endpoint_t *regs = edpt_regs(epn - 1); USBC_SelectActiveEp(epn); if (dir_in) { USBC_Writew(mps, USBC_REG_TXMAXP(USBC0_BASE)); reg_val = (1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE); if (xfer == TUSB_XFER_ISOCHRONOUS) reg_val |= (1 << USBC_BP_TXCSR_D_ISO); USBC_Writew(reg_val, USBC_REG_TXCSR(USBC0_BASE)); USBC_INT_EnableTxEp(epn); } else { USBC_Writew(mps, USBC_REG_RXMAXP(USBC0_BASE)); reg_val = (1 << USBC_BP_RXCSR_D_FLUSH_FIFO) | (1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE); if (xfer == TUSB_XFER_ISOCHRONOUS) reg_val |= (1 << USBC_BP_RXCSR_D_ISO); USBC_Writew(reg_val, USBC_REG_RXCSR(USBC0_BASE)); USBC_INT_EnableRxEp(epn); } /* Setup FIFO */ int size_in_log2_minus3 = 28 - TU_MIN(28, __clz((uint32_t)mps)); if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; unsigned addr = find_free_memory(size_in_log2_minus3); TU_ASSERT(addr); if (dir_in) { USBC_Writew(addr, USBC_REG_TXFIFOAD(USBC0_BASE)); USBC_Writeb(size_in_log2_minus3, USBC_REG_TXFIFOSZ(USBC0_BASE)); } else { USBC_Writew(addr, USBC_REG_RXFIFOAD(USBC0_BASE)); USBC_Writeb(size_in_log2_minus3, USBC_REG_RXFIFOSZ(USBC0_BASE)); } musb_int_unmask(); return true; } void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; musb_int_mask(); USBC_Writew(1, USBC_REG_INTTxE(USBC0_BASE)); /* Enable only EP0 */ USBC_Writew(0, USBC_REG_INTRxE(USBC0_BASE)); for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { USBC_SelectActiveEp(i); USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), USBC_REG_TXCSR(USBC0_BASE)); USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), USBC_REG_RXCSR(USBC0_BASE)); USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); } musb_int_unmask(); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); musb_int_mask(); USBC_SelectActiveEp(epn); if (dir_in) { USBC_INT_DisableTxEp(epn); USBC_Writew(0, USBC_REG_TXMAXP(USBC0_BASE)); USBC_Writew((1 << USBC_BP_TXCSR_D_MODE) | (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_D_FLUSH_FIFO), USBC_REG_TXCSR(USBC0_BASE)); USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE)); USBC_Writeb(0, USBC_REG_TXFIFOSZ(USBC0_BASE)); } else { USBC_INT_DisableRxEp(epn); USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE)); USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO), USBC_REG_RXCSR(USBC0_BASE)); USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE)); USBC_Writeb(0, USBC_REG_RXFIFOSZ(USBC0_BASE)); } musb_int_unmask(); } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } #endif // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; bool ret; // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); musb_int_mask(); if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); } musb_int_unmask(); return ret; } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; bool ret; // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); musb_int_mask(); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); musb_int_unmask(); return ret; } // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); musb_int_mask(); USBC_SelectActiveEp(epn); if (0 == epn) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; __USBC_Dev_ep0_SendStall(); } } else { if (tu_edpt_dir(ep_addr)) { /* IN */ __USBC_Dev_Tx_SendStall(); } else { /* OUT */ TU_ASSERT(!__USBC_Dev_Rx_IsReadDataReady(),); __USBC_Dev_Rx_SendStall(); } } musb_int_unmask(); } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); musb_int_mask(); USBC_SelectActiveEp(epn); if (0 != epn) { if (tu_edpt_dir(ep_addr)) { /* IN */ __USBC_Dev_Tx_ClearStall(); } else { /* OUT */ __USBC_Dev_Rx_ClearStall(); } } musb_int_unmask(); } void dcd_int_handler(uint8_t rhport) { uint8_t is; uint16_t txis, rxis; is = USBC_Readb(USBC_REG_INTUSB(USBC0_BASE)); /* read interrupt status */ txis = USBC_Readw(USBC_REG_INTTx(USBC0_BASE)); /* read interrupt status */ rxis = USBC_Readw(USBC_REG_INTRx(USBC0_BASE)); /* read interrupt status */ is &= USBC_Readb(USBC_REG_INTUSBE(USBC0_BASE)); /* ignore disabled interrupts */ USBC_Writeb(is, USBC_REG_INTUSB(USBC0_BASE)); /* sunxi musb requires a write to interrupt register to clear */ if (is & USBC_INTUSB_DISCONNECT) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } if (is & USBC_INTUSB_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } if (is & USBC_INTUSB_RESET) { /* ep0 FADDR must be 0 when (re)entering peripheral mode */ USBC_SelectActiveEp(0); USBC_Dev_SetAddress(0); process_bus_reset(rhport); } if (is & USBC_INTUSB_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } if (is & USBC_INTUSB_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } txis &= USBC_Readw(USBC_REG_INTTxE(USBC0_BASE)); USBC_Writew(txis, USBC_REG_INTTx(USBC0_BASE)); if (txis & USBC_INTTx_FLAG_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); } while (txis) { unsigned const num = __builtin_ctz(txis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); txis &= ~TU_BIT(num); } rxis &= USBC_Readw(USBC_REG_INTRxE(USBC0_BASE)); USBC_Writew(rxis, USBC_REG_INTRx(USBC0_BASE)); while (rxis) { unsigned const num = __builtin_ctz(rxis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); rxis &= ~TU_BIT(num); } } #endif ================================================ FILE: src/portable/sunxi/musb_def.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA * Copyright (c) 2021 Tian Yunhao (t123yh) * Copyright (c) 2021 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_MUSB_DEF #define TUSB_MUSB_DEF #define USBC_Readb(reg) (*(volatile unsigned char *)(reg)) #define USBC_Readw(reg) (*(volatile unsigned short *)(reg)) #define USBC_Readl(reg) (*(volatile unsigned long *)(reg)) #define USBC_Writeb(value, reg) (*(volatile unsigned char *)(reg) = (value)) #define USBC_Writew(value, reg) (*(volatile unsigned short *)(reg) = (value)) #define USBC_Writel(value, reg) (*(volatile unsigned long *)(reg) = (value)) #define USBC_SetBit_Mask_b(reg,mask) do { \ unsigned char _r = USBC_Readb(reg); \ _r |= (unsigned char)(mask); \ USBC_Writeb(_r,reg); \ }while(0) #define USBC_SetBit_Mask_w(reg,mask) do { \ unsigned short _r = USBC_Readw(reg); \ _r |= (unsigned short)(mask); \ USBC_Writew(_r,reg); \ }while(0) #define USBC_SetBit_Mask_l(reg,mask) do { \ unsigned int _r = USBC_Readl(reg); \ _r |= (unsigned int)(mask); \ USBC_Writel(_r,reg); \ }while(0) #define USBC_ClrBit_Mask_b(reg,mask) do { \ unsigned char _r = USBC_Readb(reg); \ _r &= (~(unsigned char)(mask)); \ USBC_Writeb(_r,reg); \ }while(0); #define USBC_ClrBit_Mask_w(reg,mask) do { \ unsigned short _r = USBC_Readw(reg); \ _r &= (~(unsigned short)(mask)); \ USBC_Writew(_r,reg); \ }while(0) #define USBC_ClrBit_Mask_l(reg,mask) do { \ unsigned int _r = USBC_Readl(reg); \ _r &= (~(unsigned int)(mask)); \ USBC_Writel(_r,reg); \ }while(0) #define USBC_REG_test_bit_b(bp, reg) (USBC_Readb(reg) & (1 << (bp))) #define USBC_REG_test_bit_w(bp, reg) (USBC_Readw(reg) & (1 << (bp))) #define USBC_REG_test_bit_l(bp, reg) (USBC_Readl(reg) & (1 << (bp))) #define USBC_REG_set_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) | (1 << (bp))) , (reg))) #define USBC_REG_set_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) | (1 << (bp))) , (reg))) #define USBC_REG_set_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) | (1 << (bp))) , (reg))) #define USBC_REG_clear_bit_b(bp, reg) (USBC_Writeb((USBC_Readb(reg) & (~ (1 << (bp)))) , (reg))) #define USBC_REG_clear_bit_w(bp, reg) (USBC_Writew((USBC_Readw(reg) & (~ (1 << (bp)))) , (reg))) #define USBC_REG_clear_bit_l(bp, reg) (USBC_Writel((USBC_Readl(reg) & (~ (1 << (bp)))) , (reg))) #define SW_UDC_EPNUMS 3 #define SUNXI_SRAMC_BASE 0x01c00000 //--------------------------------------------------------------- // reg base //--------------------------------------------------------------- #define USBC0_BASE 0x01c13000 #define USBC1_BASE 0x01c14000 #define USBC2_BASE 0x01c1E000 //Some reg within musb #define USBPHY_CLK_REG 0x01c200CC #define USBPHY_CLK_RST_BIT 0 #define USBPHY_CLK_GAT_BIT 1 #define BUS_CLK_RST_REG 0x01c202c0 //Bus Clock Reset Register Bit24 : USB CLK RST #define BUS_RST_USB_BIT 24 #define BUS_CLK_GATE0_REG 0x01c20060 //Bus Clock Gating Register Bit24 : USB CLK GATE 0: Mask 1 : Pass #define BUS_CLK_USB_BIT 24 //#define USB_INTR #define NDMA_CFG_REG //----------------------------------------------------------------------- // musb reg offset //----------------------------------------------------------------------- #define USBC_REG_o_FADDR 0x0098 #define USBC_REG_o_PCTL 0x0040 #define USBC_REG_o_INTTx 0x0044 #define USBC_REG_o_INTRx 0x0046 #define USBC_REG_o_INTTxE 0x0048 #define USBC_REG_o_INTRxE 0x004A #define USBC_REG_o_INTUSB 0x004C #define USBC_REG_o_INTUSBE 0x0050 #define USBC_REG_o_FRNUM 0x0054 #define USBC_REG_o_EPIND 0x0042 #define USBC_REG_o_TMCTL 0x007C #define USBC_REG_o_TXMAXP 0x0080 #define USBC_REG_o_CSR0 0x0082 #define USBC_REG_o_TXCSR 0x0082 #define USBC_REG_o_RXMAXP 0x0084 #define USBC_REG_o_RXCSR 0x0086 #define USBC_REG_o_COUNT0 0x0088 #define USBC_REG_o_RXCOUNT 0x0088 #define USBC_REG_o_EP0TYPE 0x008C #define USBC_REG_o_TXTYPE 0x008C #define USBC_REG_o_NAKLIMIT0 0x008D #define USBC_REG_o_TXINTERVAL 0x008D #define USBC_REG_o_RXTYPE 0x008E #define USBC_REG_o_RXINTERVAL 0x008F //#define USBC_REG_o_CONFIGDATA 0x001F // #define USBC_REG_o_EPFIFO0 0x0000 #define USBC_REG_o_EPFIFO1 0x0004 #define USBC_REG_o_EPFIFO2 0x0008 #define USBC_REG_o_EPFIFO3 0x000C #define USBC_REG_o_EPFIFO4 0x0010 #define USBC_REG_o_EPFIFO5 0x0014 #define USBC_REG_o_EPFIFOx(n) (0x0000 + (n<<2)) #define USBC_REG_o_DEVCTL 0x0041 #define USBC_REG_o_TXFIFOSZ 0x0090 #define USBC_REG_o_RXFIFOSZ 0x0094 #define USBC_REG_o_TXFIFOAD 0x0092 #define USBC_REG_o_RXFIFOAD 0x0096 #define USBC_REG_o_VEND0 0x0043 #define USBC_REG_o_VEND1 0x007D #define USBC_REG_o_VEND3 0x007E //#define USBC_REG_o_PHYCTL 0x006C #define USBC_REG_o_EPINFO 0x0078 #define USBC_REG_o_RAMINFO 0x0079 #define USBC_REG_o_LINKINFO 0x007A #define USBC_REG_o_VPLEN 0x007B #define USBC_REG_o_HSEOF 0x007C #define USBC_REG_o_FSEOF 0x007D #define USBC_REG_o_LSEOF 0x007E //new #define USBC_REG_o_FADDR0 0x0098 #define USBC_REG_o_HADDR0 0x009A #define USBC_REG_o_HPORT0 0x009B #define USBC_REG_o_TXFADDRx 0x0098 #define USBC_REG_o_TXHADDRx 0x009A #define USBC_REG_o_TXHPORTx 0x009B #define USBC_REG_o_RXFADDRx 0x009C #define USBC_REG_o_RXHADDRx 0x009E #define USBC_REG_o_RXHPORTx 0x009F #define USBC_REG_o_RPCOUNT 0x008A //new #define USBC_REG_o_ISCR 0x0400 #define USBC_REG_o_PHYCTL 0x0404 #define USBC_REG_o_PHYBIST 0x0408 #define USBC_REG_o_PHYTUNE 0x040c #define USBC_REG_o_CSR 0x0410 #define USBC_REG_o_PMU_IRQ 0x0800 //----------------------------------------------------------------------- // registers //----------------------------------------------------------------------- #define USBC_REG_FADDR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR ) #define USBC_REG_PCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PCTL ) #define USBC_REG_INTTx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTx ) #define USBC_REG_INTRx(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRx ) #define USBC_REG_INTTxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTTxE ) #define USBC_REG_INTRxE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTRxE ) #define USBC_REG_INTUSB(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSB ) #define USBC_REG_INTUSBE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_INTUSBE ) #define USBC_REG_FRNUM(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FRNUM ) #define USBC_REG_EPIND(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPIND ) #define USBC_REG_TMCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TMCTL ) #define USBC_REG_TXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXMAXP ) #define USBC_REG_CSR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR0 ) #define USBC_REG_TXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXCSR ) #define USBC_REG_RXMAXP(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXMAXP ) #define USBC_REG_RXCSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCSR ) #define USBC_REG_COUNT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_COUNT0 ) #define USBC_REG_RXCOUNT(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXCOUNT ) #define USBC_REG_EP0TYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EP0TYPE ) #define USBC_REG_TXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXTYPE ) #define USBC_REG_NAKLIMIT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_NAKLIMIT0 ) #define USBC_REG_TXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXINTERVAL ) #define USBC_REG_RXTYPE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXTYPE ) #define USBC_REG_RXINTERVAL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXINTERVAL ) //#define USBC_REG_CONFIGDATA(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CONFIGDATA ) #define USBC_REG_EPFIFO0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO0 ) #define USBC_REG_EPFIFO1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO1 ) #define USBC_REG_EPFIFO2(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO2 ) #define USBC_REG_EPFIFO3(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO3 ) #define USBC_REG_EPFIFO4(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO4 ) #define USBC_REG_EPFIFO5(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPFIFO5 ) #define USBC_REG_EPFIFOx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_EPFIFOx(n) ) #define USBC_REG_DEVCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_DEVCTL ) #define USBC_REG_TXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOSZ ) #define USBC_REG_RXFIFOSZ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOSZ ) #define USBC_REG_TXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_TXFIFOAD ) #define USBC_REG_RXFIFOAD(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RXFIFOAD ) #define USBC_REG_VEND0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND0 ) #define USBC_REG_VEND1(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VEND1 ) #define USBC_REG_EPINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_EPINFO ) #define USBC_REG_RAMINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_RAMINFO ) #define USBC_REG_LINKINFO(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LINKINFO ) #define USBC_REG_VPLEN(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_VPLEN ) #define USBC_REG_HSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HSEOF ) #define USBC_REG_FSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FSEOF ) #define USBC_REG_LSEOF(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_LSEOF ) #define USBC_REG_FADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_FADDR0 ) #define USBC_REG_HADDR0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HADDR0 ) #define USBC_REG_HPORT0(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_HPORT0 ) #define USBC_REG_TXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXFADDRx ) #define USBC_REG_TXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHADDRx ) #define USBC_REG_TXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_TXHPORTx ) #define USBC_REG_RXFADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXFADDRx ) #define USBC_REG_RXHADDRx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHADDRx ) #define USBC_REG_RXHPORTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RXHPORTx ) #define USBC_REG_RPCOUNTx(usbc_base_addr, n) ((usbc_base_addr) + USBC_REG_o_RPCOUNT ) #define USBC_REG_ISCR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_ISCR ) #define USBC_REG_PHYCTL(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYCTL ) #define USBC_REG_PHYBIST(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYBIST ) #define USBC_REG_PHYTUNE(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PHYTUNE ) #define USBC_REG_PMU_IRQ(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_PMU_IRQ ) #define USBC_REG_CSR(usbc_base_addr) ((usbc_base_addr) + USBC_REG_o_CSR) //----------------------------------------------------------------------- // bit position //----------------------------------------------------------------------- /* USB Power Control for Host only */ #define USBC_BP_POWER_H_HIGH_SPEED_EN 5 #define USBC_BP_POWER_H_HIGH_SPEED_FLAG 4 #define USBC_BP_POWER_H_RESET 3 #define USBC_BP_POWER_H_RESUME 2 #define USBC_BP_POWER_H_SUSPEND 1 #define USBC_BP_POWER_H_SUEPEND_EN 0 /* USB Power Control for device only */ #define USBC_BP_POWER_D_ISO_UPDATE_EN 7 #define USBC_BP_POWER_D_SOFT_CONNECT 6 #define USBC_BP_POWER_D_HIGH_SPEED_EN 5 #define USBC_BP_POWER_D_HIGH_SPEED_FLAG 4 #define USBC_BP_POWER_D_RESET_FLAG 3 #define USBC_BP_POWER_D_RESUME 2 #define USBC_BP_POWER_D_SUSPEND 1 #define USBC_BP_POWER_D_ENABLE_SUSPENDM 0 /* interrupt flags for ep0 and the Tx ep1~4 */ #define USBC_BP_INTTx_FLAG_EP5 5 #define USBC_BP_INTTx_FLAG_EP4 4 #define USBC_BP_INTTx_FLAG_EP3 3 #define USBC_BP_INTTx_FLAG_EP2 2 #define USBC_BP_INTTx_FLAG_EP1 1 #define USBC_BP_INTTx_FLAG_EP0 0 /* interrupt flags for Rx ep1~4 */ #define USBC_BP_INTRx_FLAG_EP5 5 #define USBC_BP_INTRx_FLAG_EP4 4 #define USBC_BP_INTRx_FLAG_EP3 3 #define USBC_BP_INTRx_FLAG_EP2 2 #define USBC_BP_INTRx_FLAG_EP1 1 /* interrupt enable for Tx ep0~4 */ #define USBC_BP_INTTxE_EN_EP5 5 #define USBC_BP_INTTxE_EN_EP4 4 #define USBC_BP_INTTxE_EN_EP3 3 #define USBC_BP_INTTxE_EN_EP2 2 #define USBC_BP_INTTxE_EN_EP1 1 #define USBC_BP_INTTxE_EN_EP0 0 /* interrupt enable for Rx ep1~4 */ #define USBC_BP_INTRxE_EN_EP5 5 #define USBC_BP_INTRxE_EN_EP4 4 #define USBC_BP_INTRxE_EN_EP3 3 #define USBC_BP_INTRxE_EN_EP2 2 #define USBC_BP_INTRxE_EN_EP1 1 /* USB interrupt */ #define USBC_BP_INTUSB_VBUS_ERROR 7 #define USBC_BP_INTUSB_SESSION_REQ 6 #define USBC_BP_INTUSB_DISCONNECT 5 #define USBC_BP_INTUSB_CONNECT 4 #define USBC_BP_INTUSB_SOF 3 #define USBC_BP_INTUSB_RESET 2 #define USBC_BP_INTUSB_RESUME 1 #define USBC_BP_INTUSB_SUSPEND 0 /* USB interrupt enable */ #define USBC_BP_INTUSBE_EN_VBUS_ERROR 7 #define USBC_BP_INTUSBE_EN_SESSION_REQ 6 #define USBC_BP_INTUSBE_EN_DISCONNECT 5 #define USBC_BP_INTUSBE_EN_CONNECT 4 #define USBC_BP_INTUSBE_EN_SOF 3 #define USBC_BP_INTUSBE_EN_RESET 2 #define USBC_BP_INTUSBE_EN_RESUME 1 #define USBC_BP_INTUSBE_EN_SUSPEND 0 /* Test Mode Control */ #define USBC_BP_TMCTL_FORCE_HOST 7 #define USBC_BP_TMCTL_FIFO_ACCESS 6 #define USBC_BP_TMCTL_FORCE_FS 5 #define USBC_BP_TMCTL_FORCE_HS 4 #define USBC_BP_TMCTL_TEST_PACKET 3 #define USBC_BP_TMCTL_TEST_K 2 #define USBC_BP_TMCTL_TEST_J 1 #define USBC_BP_TMCTL_TEST_SE0_NAK 0 /* Tx Max packet */ #define USBC_BP_TXMAXP_PACKET_COUNT 11 #define USBC_BP_TXMAXP_MAXIMUM_PAYLOAD 0 /* Control and Status Register for ep0 for Host only */ #define USBC_BP_CSR0_H_DisPing 11 #define USBC_BP_CSR0_H_FlushFIFO 8 #define USBC_BP_CSR0_H_NAK_Timeout 7 #define USBC_BP_CSR0_H_StatusPkt 6 #define USBC_BP_CSR0_H_ReqPkt 5 #define USBC_BP_CSR0_H_Error 4 #define USBC_BP_CSR0_H_SetupPkt 3 #define USBC_BP_CSR0_H_RxStall 2 #define USBC_BP_CSR0_H_TxPkRdy 1 #define USBC_BP_CSR0_H_RxPkRdy 0 /* Control and Status Register for ep0 for device only */ #define USBC_BP_CSR0_D_FLUSH_FIFO 8 #define USBC_BP_CSR0_D_SERVICED_SETUP_END 7 #define USBC_BP_CSR0_D_SERVICED_RX_PKT_READY 6 #define USBC_BP_CSR0_D_SEND_STALL 5 #define USBC_BP_CSR0_D_SETUP_END 4 #define USBC_BP_CSR0_D_DATA_END 3 #define USBC_BP_CSR0_D_SENT_STALL 2 #define USBC_BP_CSR0_D_TX_PKT_READY 1 #define USBC_BP_CSR0_D_RX_PKT_READY 0 /* Tx ep Control and Status Register for Host only */ #define USBC_BP_TXCSR_H_AUTOSET 15 #define USBC_BP_TXCSR_H_RESERVED 14 #define USBC_BP_TXCSR_H_MODE 13 #define USBC_BP_TXCSR_H_DMA_REQ_EN 12 #define USBC_BP_TXCSR_H_FORCE_DATA_TOGGLE 11 #define USBC_BP_TXCSR_H_DMA_REQ_MODE 10 #define USBC_BP_TXCSR_H_NAK_TIMEOUT 7 #define USBC_BP_TXCSR_H_CLEAR_DATA_TOGGLE 6 #define USBC_BP_TXCSR_H_TX_STALL 5 #define USBC_BP_TXCSR_H_FLUSH_FIFO 3 #define USBC_BP_TXCSR_H_ERROR 2 #define USBC_BP_TXCSR_H_FIFO_NOT_EMPTY 1 #define USBC_BP_TXCSR_H_TX_READY 0 /* Tx ep Control and Status Register for Device only */ #define USBC_BP_TXCSR_D_AUTOSET 15 #define USBC_BP_TXCSR_D_ISO 14 #define USBC_BP_TXCSR_D_MODE 13 #define USBC_BP_TXCSR_D_DMA_REQ_EN 12 #define USBC_BP_TXCSR_D_FORCE_DATA_TOGGLE 11 #define USBC_BP_TXCSR_D_DMA_REQ_MODE 10 #define USBC_BP_TXCSR_D_INCOMPLETE 7 #define USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE 6 #define USBC_BP_TXCSR_D_SENT_STALL 5 #define USBC_BP_TXCSR_D_SEND_STALL 4 #define USBC_BP_TXCSR_D_FLUSH_FIFO 3 #define USBC_BP_TXCSR_D_UNDER_RUN 2 #define USBC_BP_TXCSR_D_FIFO_NOT_EMPTY 1 #define USBC_BP_TXCSR_D_TX_READY 0 /* Rx Max Packet */ #define USBC_BP_RXMAXP_PACKET_COUNT 11 #define USBC_BP_RXMAXP_MAXIMUM_PAYLOAD 0 /* Rx ep Control and Status Register for Host only */ #define USBC_BP_RXCSR_H_AUTO_CLEAR 15 #define USBC_BP_RXCSR_H_AUTO_REQ 14 #define USBC_BP_RXCSR_H_DMA_REQ_EN 13 #define USBC_BP_RXCSR_H_PID_ERROR 12 #define USBC_BP_RXCSR_H_DMA_REQ_MODE 11 #define USBC_BP_RXCSR_H_INCOMPLETE 8 #define USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE 7 #define USBC_BP_RXCSR_H_RX_STALL 6 #define USBC_BP_RXCSR_H_REQ_PACKET 5 #define USBC_BP_RXCSR_H_FLUSH_FIFO 4 #define USBC_BP_RXCSR_H_NAK_TIMEOUT 3 #define USBC_BP_RXCSR_H_ERROR 2 #define USBC_BP_RXCSR_H_FIFO_FULL 1 #define USBC_BP_RXCSR_H_RX_PKT_READY 0 /* Rx ep Control and Status Register for Device only */ #define USBC_BP_RXCSR_D_AUTO_CLEAR 15 #define USBC_BP_RXCSR_D_ISO 14 #define USBC_BP_RXCSR_D_DMA_REQ_EN 13 #define USBC_BP_RXCSR_D_DISABLE_NYET 12 #define USBC_BP_RXCSR_D_DMA_REQ_MODE 11 #define USBC_BP_RXCSR_D_INCOMPLETE 8 #define USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE 7 #define USBC_BP_RXCSR_D_SENT_STALL 6 #define USBC_BP_RXCSR_D_SEND_STALL 5 #define USBC_BP_RXCSR_D_FLUSH_FIFO 4 #define USBC_BP_RXCSR_D_DATA_ERROR 3 #define USBC_BP_RXCSR_D_OVERRUN 2 #define USBC_BP_RXCSR_D_FIFO_FULL 1 #define USBC_BP_RXCSR_D_RX_PKT_READY 0 /* Tx Type Register for host only */ #define USBC_BP_TXTYPE_SPEED 6 //new #define USBC_BP_TXTYPE_PROROCOL 4 #define USBC_BP_TXTYPE_TARGET_EP_NUM 0 /* Rx Type Register for host only */ #define USBC_BP_RXTYPE_SPEED 6 //new #define USBC_BP_RXTYPE_PROROCOL 4 #define USBC_BP_RXTYPE_TARGET_EP_NUM 0 /* Core Configueation */ #define USBC_BP_CONFIGDATA_MPRXE 7 #define USBC_BP_CONFIGDATA_MPTXE 6 #define USBC_BP_CONFIGDATA_BIGENDIAN 5 #define USBC_BP_CONFIGDATA_HBRXE 4 #define USBC_BP_CONFIGDATA_HBTXE 3 #define USBC_BP_CONFIGDATA_DYNFIFO_SIZING 2 #define USBC_BP_CONFIGDATA_SOFTCONE 1 #define USBC_BP_CONFIGDATA_UTMI_DATAWIDTH 0 /* OTG Device Control */ #define USBC_BP_DEVCTL_B_DEVICE 7 #define USBC_BP_DEVCTL_FS_DEV 6 #define USBC_BP_DEVCTL_LS_DEV 5 #define USBC_BP_DEVCTL_VBUS 3 #define USBC_BP_DEVCTL_HOST_MODE 2 #define USBC_BP_DEVCTL_HOST_REQ 1 #define USBC_BP_DEVCTL_SESSION 0 /* Tx EP FIFO size control */ #define USBC_BP_TXFIFOSZ_DPB 4 #define USBC_BP_TXFIFOSZ_SZ 0 /* Rx EP FIFO size control */ #define USBC_BP_RXFIFOSZ_DPB 4 #define USBC_BP_RXFIFOSZ_SZ 0 /* vendor0 */ #define USBC_BP_VEND0_DRQ_SEL 1 #define USBC_BP_VEND0_BUS_SEL 0 /* hub address */ #define USBC_BP_HADDR_MULTI_TT 7 /* Interface Status and Control */ #define USBC_BP_ISCR_VBUS_VALID_FROM_DATA 30 #define USBC_BP_ISCR_VBUS_VALID_FROM_VBUS 29 #define USBC_BP_ISCR_EXT_ID_STATUS 28 #define USBC_BP_ISCR_EXT_DM_STATUS 27 #define USBC_BP_ISCR_EXT_DP_STATUS 26 #define USBC_BP_ISCR_MERGED_VBUS_STATUS 25 #define USBC_BP_ISCR_MERGED_ID_STATUS 24 #define USBC_BP_ISCR_ID_PULLUP_EN 17 #define USBC_BP_ISCR_DPDM_PULLUP_EN 16 #define USBC_BP_ISCR_FORCE_ID 14 #define USBC_BP_ISCR_FORCE_VBUS_VALID 12 #define USBC_BP_ISCR_VBUS_VALID_SRC 10 #define USBC_BP_ISCR_HOSC_EN 7 #define USBC_BP_ISCR_VBUS_CHANGE_DETECT 6 #define USBC_BP_ISCR_ID_CHANGE_DETECT 5 #define USBC_BP_ISCR_DPDM_CHANGE_DETECT 4 #define USBC_BP_ISCR_IRQ_ENABLE 3 #define USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN 2 #define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1 #define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0 #define SUNXI_EHCI_AHB_ICHR8_EN (1 << 10) #define SUNXI_EHCI_AHB_INCR4_BURST_EN (1 << 9) #define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8) #define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0) //----------------------------------------------------------------------- // �Զ��� //----------------------------------------------------------------------- /* usb��Դ���� */ #define USBC_MAX_CTL_NUM 1 #define USBC_MAX_EP_NUM 3 //ep0~2, ep�ĸ��� #define USBC_MAX_FIFO_SIZE (2 * 1024) /* usb OTG mode */ #define USBC_OTG_HOST 0 #define USBC_OTG_DEVICE 1 /* usb device type */ #define USBC_DEVICE_HSDEV 0 #define USBC_DEVICE_FSDEV 1 #define USBC_DEVICE_LSDEV 2 /* usb transfer type */ #define USBC_TS_TYPE_IDLE 0 #define USBC_TS_TYPE_CTRL 1 #define USBC_TS_TYPE_ISO 2 #define USBC_TS_TYPE_INT 3 #define USBC_TS_TYPE_BULK 4 /* usb transfer mode */ #define USBC_TS_MODE_UNKOWN 0 #define USBC_TS_MODE_LS 1 #define USBC_TS_MODE_FS 2 #define USBC_TS_MODE_HS 3 /* usb Vbus status */ #define USBC_VBUS_STATUS_BELOW_SESSIONEND 0 #define USBC_VBUS_STATUS_ABOVE_SESSIONEND_BELOW_AVALID 1 #define USBC_VBUS_STATUS_ABOVE_AVALID_BELOW_VBUSVALID 2 #define USBC_VBUS_STATUS_ABOVE_VBUSVALID 3 /* usb io type */ #define USBC_IO_TYPE_PIO 0 #define USBC_IO_TYPE_DMA 1 /* usb ep type */ #define USBC_EP_TYPE_IDLE 0 #define USBC_EP_TYPE_EP0 1 #define USBC_EP_TYPE_TX 2 #define USBC_EP_TYPE_RX 3 /* usb id type */ #define USBC_ID_TYPE_DISABLE 0 #define USBC_ID_TYPE_HOST 1 #define USBC_ID_TYPE_DEVICE 2 /* usb vbus valid type */ #define USBC_VBUS_TYPE_DISABLE 0 #define USBC_VBUS_TYPE_LOW 1 #define USBC_VBUS_TYPE_HIGH 2 /* usb a valid source */ #define USBC_A_VALID_SOURCE_UTMI_AVALID 0 #define USBC_A_VALID_SOURCE_UTMI_VBUS 1 /* usb device switch */ #define USBC_DEVICE_SWITCH_OFF 0 #define USBC_DEVICE_SWITCH_ON 1 /* usb fifo config mode */ #define USBC_FIFO_MODE_4K 0 #define USBC_FIFO_MODE_8K 1 /* ************************************************** * usb interrupt mask * ************************************************** */ /* interrupt flags for ep0 and the Tx ep1~4 */ #define USBC_INTTx_FLAG_EP5 (1 << USBC_BP_INTTx_FLAG_EP5) #define USBC_INTTx_FLAG_EP4 (1 << USBC_BP_INTTx_FLAG_EP4) #define USBC_INTTx_FLAG_EP3 (1 << USBC_BP_INTTx_FLAG_EP3) #define USBC_INTTx_FLAG_EP2 (1 << USBC_BP_INTTx_FLAG_EP2) #define USBC_INTTx_FLAG_EP1 (1 << USBC_BP_INTTx_FLAG_EP1) #define USBC_INTTx_FLAG_EP0 (1 << USBC_BP_INTTx_FLAG_EP0) /* interrupt flags for Rx ep1~4 */ #define USBC_INTRx_FLAG_EP5 (1 << USBC_BP_INTRx_FLAG_EP5) #define USBC_INTRx_FLAG_EP4 (1 << USBC_BP_INTRx_FLAG_EP4) #define USBC_INTRx_FLAG_EP3 (1 << USBC_BP_INTRx_FLAG_EP3) #define USBC_INTRx_FLAG_EP2 (1 << USBC_BP_INTRx_FLAG_EP2) #define USBC_INTRx_FLAG_EP1 (1 << USBC_BP_INTRx_FLAG_EP1) /* USB interrupt */ #define USBC_INTUSB_VBUS_ERROR (1 << USBC_BP_INTUSB_VBUS_ERROR) #define USBC_INTUSB_SESSION_REQ (1 << USBC_BP_INTUSB_SESSION_REQ) #define USBC_INTUSB_DISCONNECT (1 << USBC_BP_INTUSB_DISCONNECT) #define USBC_INTUSB_CONNECT (1 << USBC_BP_INTUSB_CONNECT) #define USBC_INTUSB_SOF (1 << USBC_BP_INTUSB_SOF) #define USBC_INTUSB_RESET (1 << USBC_BP_INTUSB_RESET) #define USBC_INTUSB_RESUME (1 << USBC_BP_INTUSB_RESUME) #define USBC_INTUSB_SUSPEND (1 << USBC_BP_INTUSB_SUSPEND) #define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout #define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear #define USB_CSRL0_STATUS 0x00000040 // STATUS Packet #define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear #define USB_CSRL0_REQPKT 0x00000020 // Request Packet #define USB_CSRL0_STALL 0x00000020 // Send Stall #define USB_CSRL0_SETEND 0x00000010 // Setup End #define USB_CSRL0_ERROR 0x00000010 // Error #define USB_CSRL0_DATAEND 0x00000008 // Data End #define USB_CSRL0_SETUP 0x00000008 // Setup Packet #define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled #define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready #define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready #define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support #define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size #define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support #define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size #endif ================================================ FILE: src/portable/synopsys/dwc2/dcd_dwc2.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 William D. Jones * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2020 Jan Duempelmann * Copyright (c) 2020 Reinhard Panhuber * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) #if !(CFG_TUD_DWC2_SLAVE_ENABLE || CFG_TUD_DWC2_DMA_ENABLE) #error DWC2 require either CFG_TUD_DWC2_SLAVE_ENABLE or CFG_TUD_DWC2_DMA_ENABLE to be enabled #endif // Debug level for DWC2 #define DWC2_DEBUG 2 #include "device/dcd.h" #include "device/usbd.h" #include "device/usbd_pvt.h" #include "dwc2_common.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ typedef struct { uint8_t* buffer; tu_fifo_t* ff; uint16_t total_len; uint16_t max_size; uint8_t interval; uint8_t iso_retry; // ISO retry counter } xfer_ctl_t; // This variable is modified from ISR context, so it must be protected by critical section static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) typedef struct { // EP0 transfers are limited to 1 packet - larger sizes has to be split uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type uint16_t dfifo_top; // top free location in DFIFO in words // Number of IN endpoints active uint8_t allocated_epin_count; // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by bool sof_en; } dcd_data_t; static dcd_data_t _dcd_data; CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(setup_packet, 8); } _dcd_usbbuf; static tud_configure_dwc2_t _tud_cfg = CFG_TUD_CONFIGURE_DWC2_DEFAULT; TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) { #if TU_CHECK_MCU(OPT_MCU_GD32VF103) (void) dwc2; return DWC2_EP_MAX; #else const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; return ghwcfg2.num_dev_ep + 1; #endif } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline bool edpt_is_enabled(dwc2_dep_t* dep) { return (dep->ctl & EPCTL_EPENA) != 0; } #if CFG_TUD_DWC2_SLAVE_ENABLE static uint16_t epin_write_tx_fifo(dwc2_regs_t *dwc2, uint8_t epnum); #endif //-------------------------------------------------------------------- // DMA //-------------------------------------------------------------------- #if CFG_TUD_MEM_DCACHE_ENABLE bool dcd_dcache_clean(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_clean(addr, data_size); } bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_invalidate(addr, data_size); } bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_clean_invalidate(addr, data_size); } #endif TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) { (void) dwc2; // Internal DMA only const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; return CFG_TUD_DWC2_DMA_ENABLE && ghwcfg2.arch == GHWCFG2_ARCH_INTERNAL_DMA; } static void dma_setup_prepare(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { if(edpt_is_enabled(&dwc2->epout[0])) { return; } } // Receive only 1 packet dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); dwc2->epout[0].doepdma = (uintptr_t) _dcd_usbbuf.setup_packet; dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; } //--------------------------------------------------------------------+ // Data FIFO //--------------------------------------------------------------------+ /* Device Data FIFO scheme The FIFO is split up into - EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called EP_LOC_CNT = ep_fifo_size - ghwcfg3.dfifo_depth. For value less than EP_LOC_CNT, gdfifocfg must be configured before gahbcfg.dmaen is set - Buffer mode: 1 word per endpoint direction - Scatter/Gather DMA: 4 words per endpoint direction - TX FIFO: one fifo for each IN endpoint. Size is dynamic depending on packet size, starting from top with EP0 IN. - Shared RX FIFO: a shared fifo for all OUT endpoints. Typically, can hold up to 2 packets of the largest EP size. We allocated TX FIFO from top to bottom (using top pointer), this to allow the RX FIFO to grow dynamically which is possible since the free space is located between the RX and TX FIFOs. ---------------- ep_fifo_size | DxEPIDMAn | |-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) | IN FIFO 0 | control EP |-------------| | IN FIFO 1 | |-------------| | . . . . | |-------------| | IN FIFO n | |-------------| | FREE | |-------------|-- GRXFSIZ (expandable) | OUT FIFO | | ( Shared ) | --------------- 0 According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - Each EP IN needs at least max packet size - All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula): - 13 for setup packets + control words (up to 3 setup packets). - 1 for global NAK (not required/used here). - Largest-EPsize/4 + 1. (FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4 + 1)" - 2 for each used OUT endpoint Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum */ TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { return 13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count; } static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size, bool is_bulk) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; const uint8_t ep_count = dwc2_controller->ep_count; const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ep_count); uint16_t fifo_size = tu_div_ceil(packet_size, 4); if (dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO const uint16_t new_sz = calc_device_grxfsiz(4 * fifo_size, ep_count); // If size_rx needs to be extended check if there is enough free space if (dwc2->grxfsiz < new_sz) { TU_ASSERT(new_sz <= _dcd_data.dfifo_top); dwc2->grxfsiz = new_sz; // Enlarge RX FIFO } } else { // Check IN endpoints concurrently active limit if(0 != dwc2_controller->ep_in_count) { TU_ASSERT(_dcd_data.allocated_epin_count < dwc2_controller->ep_in_count); _dcd_data.allocated_epin_count++; } // Enable double buffering if configured, only effective for non-periodic endpoints // Since we queue only 1 control transfer at a time, it's only applicable for bulk IN endpoints if (((_tud_cfg.bm_double_buffered & (1 << epnum)) != 0) && epnum > 0 && is_bulk) { fifo_size *= 2; } // Check if free space is available TU_ASSERT(_dcd_data.dfifo_top >= fifo_size + dwc2->grxfsiz); _dcd_data.dfifo_top -= fifo_size; // TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, dfifo_top); // Both TXFD and TXSA are in unit of 32-bit words. if (epnum == 0) { dwc2->dieptxf0 = ((uint32_t) fifo_size << DIEPTXF0_TX0FD_Pos) | _dcd_data.dfifo_top; } else { // DIEPTXF starts at FIFO #1. dwc2->dieptxf[epnum - 1] = ((uint32_t) fifo_size << DIEPTXF_INEPTXFD_Pos) | _dcd_data.dfifo_top; } } return true; } static void dfifo_device_init(uint8_t rhport) { const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->grxfsiz = calc_device_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction const bool is_dma = dma_device_enabled(dwc2); _dcd_data.dfifo_top = dwc2_controller->ep_fifo_size/4; if (is_dma) { _dcd_data.dfifo_top -= 2 * dwc2_controller->ep_count; } dwc2->gdfifocfg = ((uint32_t) _dcd_data.dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT) | _dcd_data.dfifo_top; // Allocate FIFO for EP0 IN (void) dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE, false); } //-------------------------------------------------------------------- // Endpoint //-------------------------------------------------------------------- static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); const uint8_t dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); const dwc2_dsts_t dsts = {.value = dwc2->dsts}; if (dsts.enum_speed == DCFG_SPEED_HIGH) { xfer->interval = 1 << (p_endpoint_desc->bInterval - 1); } else { xfer->interval = p_endpoint_desc->bInterval; } // Endpoint control dwc2_depctl_t depctl = {.value = 0}; depctl.mps = xfer->max_size; depctl.active = 1; depctl.type = p_endpoint_desc->bmAttributes.xfer; if (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) { depctl.set_data0_iso_even = 1; } if (dir == TUSB_DIR_IN) { depctl.tx_fifo_num = epnum; } dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; dep->ctl = depctl.value; dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir)); } static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr); dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; const uint32_t stall_mask = (stall ? EPCTL_STALL : 0); if (dir == TUSB_DIR_IN) { if (!edpt_is_enabled(dep)) { dep->diepctl |= DIEPCTL_SNAK | stall_mask; } else { // Stop transmitting packets and NAK IN xfers. dep->diepctl |= DIEPCTL_SNAK; while ((dep->diepint & DIEPINT_INEPNE) == 0) {} // Disable the endpoint. dep->diepctl |= DIEPCTL_EPDIS | stall_mask; while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {} dep->diepint = DIEPINT_EPDISD; } // Flush the FIFO, and wait until we have confirmed it cleared. dfifo_flush_tx(dwc2, epnum); } else { if (!edpt_is_enabled(dep) || epnum == 0) { // non-control not-enabled: stall if set // For EP0 Out, keep it enabled to receive SETUP packets dep->doepctl |= stall_mask; } else { // Asserting GONAK is required to STALL an OUT endpoint. // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt // anyway, and it can't be cleared by user code. If this while loop never // finishes, we have bigger problems than just the stack. dwc2->dctl |= DCTL_SGONAK; while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} // Ditto here disable the endpoint. dep->doepctl |= DOEPCTL_EPDIS | stall_mask; while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {} dep->doepint = DOEPINT_EPDISD; // Allow other OUT endpoints to keep receiving. dwc2->dctl |= DCTL_CGONAK; } } } // Since this function returns void, it is not possible to return a boolean success message // We must make sure that this function is not called when the EP is disabled // Must be called from critical section static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uint8_t dir) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; uint16_t num_packets; uint16_t total_bytes; // EP0 is limited to one packet per xfer if (epnum == 0) { total_bytes = tu_min16(_dcd_data.ep0_pending[dir], CFG_TUD_ENDPOINT0_SIZE); _dcd_data.ep0_pending[dir] -= total_bytes; num_packets = 1; } else { total_bytes = xfer->total_len; num_packets = tu_div_ceil(total_bytes, xfer->max_size); if (num_packets == 0) { num_packets = 1; // zero length packet still count as 1 } } // transfer size: A full OUT transfer (multiple packets, possibly) triggers XFRC. dwc2_ep_tsize_t deptsiz = {.value = 0}; deptsiz.xfer_size = total_bytes; deptsiz.packet_count = num_packets; dep->tsiz = deptsiz.value; // control dwc2_depctl_t depctl = {.value = dep->ctl}; depctl.clear_nak = 1; depctl.enable = 1; if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS) { const dwc2_dsts_t dsts = {.value = dwc2->dsts}; const uint32_t odd_now = dsts.frame_number & 1u; if (odd_now != 0) { depctl.set_data0_iso_even = 1; } else { depctl.set_data1_iso_odd = 1; } } #if CFG_TUD_DWC2_DMA_ENABLE const bool is_dma = dma_device_enabled(dwc2); if(is_dma) { if (dir == TUSB_DIR_IN && total_bytes != 0) { dcd_dcache_clean(xfer->buffer, total_bytes); } dep->diepdma = (uintptr_t) xfer->buffer; dep->diepctl = depctl.value; // enable endpoint // Advance buffer pointer for EP0 if (epnum == 0) { xfer->buffer += total_bytes; } } else #endif { #if CFG_TUD_DWC2_SLAVE_ENABLE dep->diepctl = depctl.value; // enable endpoint if (dir == TUSB_DIR_IN && total_bytes != 0) { const uint16_t xferred_bytes = epin_write_tx_fifo(dwc2, epnum); // Enable TXFE interrupt if there are still data to be sent // EP0 only sends one packet at a time, so no need to check for EP0 if ((epnum != 0) && (xfer->total_len - xferred_bytes > 0)) { dwc2->diepempmsk |= (1u << epnum); } } #endif } } //-------------------------------------------------------------------- // Controller API //-------------------------------------------------------------------- // optional dcd configuration, called by tud_configure() bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUD_CFGID_DWC2 && cfg_param != NULL); const tud_configure_param_t* const cfg = (const tud_configure_param_t*) cfg_param; _tud_cfg = cfg->dwc2; return true; } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; dwc2_regs_t* dwc2 = DWC2_REG(rhport); tu_memclr(&_dcd_data, sizeof(_dcd_data)); // Core Initialization const bool is_hs_phy = dwc2_core_is_highspeed_phy(dwc2, TUD_OPT_HIGH_SPEED); const bool is_dma = dma_device_enabled(dwc2); TU_ASSERT(dwc2_core_init(rhport, is_hs_phy, is_dma)); //------------- 7.1 Device Initialization -------------// // Set device max speed uint32_t dcfg = dwc2->dcfg & ~DCFG_DSPD_Msk; if (is_hs_phy) { // dcfg Highspeed's mask is 0 // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; if (ghwcfg2.hs_phy_type == GHWCFG2_HSPHY_ULPI) { dcfg |= DCFG_XCVRDLY; } } else { dcfg |= DCFG_DSPD_FS << DCFG_DSPD_Pos; } dcfg |= DCFG_NZLSOHSK; // send STALL back and discard if host send non-zlp during control status dwc2->dcfg = dcfg; dcd_disconnect(rhport); // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; // OTG Ctrl uint32_t gotgctl = dwc2->gotgctl & ~GOTGCTL_AVALOEN; // Clear A-override if (!_tud_cfg.vbus_sensing) { gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; // force B Valid if not sensing VBus } dwc2->gotgctl = gotgctl; #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, _tud_cfg.vbus_sensing, false); #endif // Enable required interrupts dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; uint32_t gahbcfg = dwc2->gahbcfg; gahbcfg |= GAHBCFG_GINT; // Enable global interrupt dwc2->gahbcfg = gahbcfg; dcd_connect(rhport); return true; } bool dcd_deinit(uint8_t rhport) { dcd_disconnect(rhport); dwc2_core_deinit(rhport); return true; } void dcd_int_enable(uint8_t rhport) { dwc2_dcd_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { dwc2_dcd_int_disable(rhport); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->dcfg = (dwc2->dcfg & ~DCFG_DAD_Msk) | (dev_addr << DCFG_DAD_Pos); // Response with status after changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); // set remote wakeup dwc2->dctl |= DCTL_RWUSIG; // enable SOF to detect bus resume dwc2->gintsts = GINTSTS_SOF; dwc2->gintmsk |= GINTMSK_SOFM; // Per specs: remote wakeup signal bit must be clear within 1-15ms dwc2_remote_wakeup_delay(); dwc2->dctl &= ~DCTL_RWUSIG; } void dcd_connect(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); #ifdef TUP_USBIP_DWC2_ESP32 // On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY if (rhport == 0) { usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; conf.pad_pull_override = 0; conf.dp_pullup = 0; conf.dp_pulldown = 0; conf.dm_pullup = 0; conf.dm_pulldown = 0; USB_WRAP.otg_conf = conf; } #endif dwc2->dctl &= ~DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); #ifdef TUP_USBIP_DWC2_ESP32 // On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY if (rhport == 0) { usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; conf.pad_pull_override = 1; conf.dp_pullup = 0; conf.dp_pulldown = 1; conf.dm_pullup = 0; conf.dm_pulldown = 1; USB_WRAP.otg_conf = conf; } #endif dwc2->dctl |= DCTL_SDIS; } // Be advised: audio, video and possibly other iso-ep classes use dcd_sof_enable() to enable/disable its corresponding ISR on purpose! void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); _dcd_data.sof_en = en; if (en) { dwc2->gintsts = GINTSTS_SOF; dwc2->gintmsk |= GINTMSK_SOFM; } else { dwc2->gintmsk &= ~GINTMSK_SOFM; } } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { TU_ASSERT(dfifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer == TUSB_XFER_BULK)); edpt_activate(rhport, desc_edpt); return true; } // Close all non-control endpoints, cancel all pending transfers if any. void dcd_edpt_close_all(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; usbd_spin_lock(false); _dcd_data.allocated_epin_count = 0; // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); for (uint8_t n = 1; n < ep_count; n++) { for (uint8_t d = 0; d < 2; d++) { dwc2_dep_t* dep = &dwc2->ep[d][n]; if (edpt_is_enabled(dep)) { dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS; } xfer_status[n][1-d].max_size = 0; } } dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); dfifo_device_init(rhport); // re-init dfifo usbd_spin_unlock(false); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { TU_ASSERT(dfifo_alloc(rhport, ep_addr, largest_packet_size, false)); return true; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { // Disable EP to clear potential incomplete transfers edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); edpt_activate(rhport, p_endpoint_desc); return true; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); bool ret; usbd_spin_lock(is_isr); if (xfer->max_size == 0) { ret = false; // Endpoint is closed } else { xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; xfer->iso_retry = xfer->interval; // Reset ISO retry counter to interval value // EP0 can only handle one packet if (epnum == 0) { _dcd_data.ep0_pending[dir] = total_bytes; } // Schedule packets to be sent within interrupt edpt_schedule_packets(rhport, epnum, dir); ret = true; } usbd_spin_unlock(is_isr); return ret; } // The number of bytes has to be given explicitly to allow more flexible control of how many // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); bool ret; usbd_spin_lock(is_isr); if (xfer->max_size == 0) { ret = false; // Endpoint is closed } else { xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->iso_retry = xfer->interval; // Reset ISO retry counter to interval value // Schedule packets to be sent within interrupt // TODO xfer fifo may only available for slave mode edpt_schedule_packets(rhport, epnum, dir); ret = true; } usbd_spin_unlock(is_isr); return ret; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); edpt_disable(rhport, ep_addr, true); // For control endpoint, prepare to receive SETUP packet if (tu_edpt_number(ep_addr) == 0) { if (dma_device_enabled(dwc2)) { dma_setup_prepare(rhport); } } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; // Clear stall and reset data toggle dep->ctl &= ~EPCTL_STALL;; dep->ctl |= EPCTL_SD0PID_SEVNFRM; } //-------------------------------------------------------------------- // Interrupt Handler //-------------------------------------------------------------------- // 7.4.1 Initialization on USB Reset // Must be called from critical section static void handle_bus_reset(uint8_t rhport) { dwc2_regs_t *dwc2 = DWC2_REG(rhport); const uint8_t ep_count = dwc2_ep_count(dwc2); tu_memclr(xfer_status, sizeof(xfer_status)); _dcd_data.sof_en = false; _dcd_data.allocated_epin_count = 0; // 1. NAK for all OUT endpoints for (uint8_t n = 0; n < ep_count; n++) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } // Disable all IN endpoints for (uint8_t n = 0; n < ep_count; n++) { dwc2_dep_t* dep = &dwc2->epin[n]; if (edpt_is_enabled(dep)) { dep->diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; } } // 2. Set up interrupt mask for EP0 dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; // 4. Set up DFIFO dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); dfifo_device_init(rhport); // 5. Reset device address dwc2_dcfg_t dcfg = {.value = dwc2->dcfg}; dcfg.address = 0; dwc2->dcfg = dcfg.value; // 6. Configure maximum packet size for EP0 uint8_t mps = 0; switch (CFG_TUD_ENDPOINT0_SIZE) { case 8: mps = 3; break; case 16: mps = 2; break; case 32: mps = 1; break; case 64: mps = 0; break; default: mps = 0; break; } dwc2->epin[0].ctl &= ~DIEPCTL0_MPSIZ_Msk; dwc2->epout[0].ctl &= ~DOEPCTL0_MPSIZ_Msk; dwc2->epin[0].ctl |= mps << DIEPCTL0_MPSIZ_Pos; dwc2->epout[0].ctl |= mps << DOEPCTL0_MPSIZ_Pos; xfer_status[0][TUSB_DIR_OUT].max_size = CFG_TUD_ENDPOINT0_SIZE; xfer_status[0][TUSB_DIR_IN].max_size = CFG_TUD_ENDPOINT0_SIZE; if(dma_device_enabled(dwc2)) { dma_setup_prepare(rhport); } else { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); } dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_OEPINT | GINTMSK_IEPINT | GINTMSK_IISOIXFRM; } static void handle_enum_done(uint8_t rhport) { dwc2_regs_t *dwc2 = DWC2_REG(rhport); const dwc2_dsts_t dsts = {.value = dwc2->dsts}; tusb_speed_t speed; switch (dsts.enum_speed) { case DCFG_SPEED_HIGH: speed = TUSB_SPEED_HIGH; break; case DCFG_SPEED_LOW: speed = TUSB_SPEED_LOW; break; case DCFG_SPEED_FULL_30_60MHZ: case DCFG_SPEED_FULL_48MHZ: default: speed = TUSB_SPEED_FULL; break; } // TODO must update GUSBCFG_TRDT according to link speed dcd_event_bus_reset(rhport, speed, true); } #if 0 TU_ATTR_ALWAYS_INLINE static inline void print_doepint(uint32_t doepint) { const char* str[] = { "XFRC", "DIS", "AHBERR", "SETUP_DONE", "ORXED", "STATUS_RX", "SETUP_B2B", "RSV7", "OPERR", "BNA", "RSV10", "ISODROP", "BBLERR", "NAK", "NYET", "SETUP_RX" }; for(uint32_t i=0; iep[0][epnum]; xfer_ctl_t *const xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); dwc2_ep_tsize_t tsiz = {.value = epin->tsiz}; const uint16_t remain_packets = tsiz.packet_count; uint16_t total_bytes_written = 0; // Process every single packet (only whole packets can be written to fifo) for (uint16_t i = 0; i < remain_packets; i++) { tsiz.value = epin->tsiz; const uint16_t remain_bytes = (uint16_t)tsiz.xfer_size; const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size); // Check if dtxfsts has enough space available if (xact_bytes > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) { break; } // Push packet to Tx-FIFO volatile uint32_t *tx_fifo = dwc2->fifo[epnum]; if (xfer->ff) { tu_hwfifo_write_from_fifo(tx_fifo, xfer->ff, xact_bytes, NULL); total_bytes_written += xact_bytes; } else { tu_hwfifo_write(tx_fifo, xfer->buffer, xact_bytes, NULL); xfer->buffer += xact_bytes; total_bytes_written += xact_bytes; } } return total_bytes_written; } // Process shared receive FIFO, this interrupt is only used in Slave mode static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const volatile uint32_t* rx_fifo = dwc2->fifo[0]; // Pop control word off FIFO const dwc2_grxstsp_t grxstsp = {.value = dwc2->grxstsp}; const uint8_t epnum = grxstsp.ep_ch_num; dwc2_dep_t* epout = &dwc2->epout[epnum]; switch (grxstsp.packet_status) { case GRXSTS_PKTSTS_GLOBAL_OUT_NAK: // Global OUT NAK: do nothing break; case GRXSTS_PKTSTS_SETUP_RX: { // Setup packet received uint32_t* setup = (uint32_t*)(uintptr_t) _dcd_usbbuf.setup_packet; // We can receive up to three setup packets in succession, but only the last one is valid. setup[0] = (*rx_fifo); setup[1] = (*rx_fifo); break; } case GRXSTS_PKTSTS_SETUP_DONE: // Setup packet done: // After popping this out, dwc2 asserts a DOEPINT_SETUP interrupt which is handled by handle_epout_irq() epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); break; case GRXSTS_PKTSTS_RX_DATA: { // Out packet received const uint16_t byte_count = grxstsp.byte_count; xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); if (byte_count != 0) { // Read packet off RxFIFO if (xfer->ff != NULL) { tu_hwfifo_read_to_fifo(rx_fifo, xfer->ff, byte_count, NULL); } else { tu_hwfifo_read(rx_fifo, xfer->buffer, byte_count, NULL); xfer->buffer += byte_count; } } // short packet (including ZLP when byte_count == 0), minus remaining bytes (xfer_size) if (byte_count < xfer->max_size) { const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz}; xfer->total_len -= tsiz.xfer_size; if (epnum == 0) { _dcd_data.ep0_pending[TUSB_DIR_OUT] = 0; } } break; } case GRXSTS_PKTSTS_RX_COMPLETE: // Out packet done // After this entry is popped from the receive FIFO, dwc2 asserts a Transfer Completed interrupt on // the specified OUT endpoint which will be handled by handle_epout_irq() break; default: break; // nothing to do } } static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) { if (doepint_bm.setup_phase_done) { // Cleanup previous pending EP0 IN transfer if any dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0]; if (edpt_is_enabled(epin0)) { edpt_disable(rhport, 0x80, false); } dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); return; } // Normal OUT transfer complete if (doepint_bm.xfer_complete) { // only handle data skip if it is setup or status related // Note: even though (xfer_complete + status_phase_rx) is for buffered DMA only, for STM32L47x (dwc2 v3.00a) they // can is set when GRXSTS_PKTSTS_SETUP_RX is popped therefore they can bet set before/together with setup_phase_done if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) { xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) { // EP0 can only handle one packet, Schedule another packet to be received. edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT); } else { dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepint_bm) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2_dep_t* epin = &dwc2->epin[epnum]; xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); if (diepint_bm.xfer_complete) { if ((epnum == 0) && (0 != _dcd_data.ep0_pending[TUSB_DIR_IN])) { // EP0 can only handle one packet. Schedule another packet to be transmitted. edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN); } else { dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } // TX FIFO empty bit is read-only. It will only be cleared by hardware when written bytes is more than // - 64 bytes or // - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL) if (diepint_bm.txfifo_empty && tu_bit_test(dwc2->diepempmsk, epnum)) { epin_write_tx_fifo(dwc2, epnum); // Turn off TXFE if all bytes are written. dwc2_ep_tsize_t tsiz = {.value = epin->tsiz}; if (tsiz.xfer_size == 0) { dwc2->diepempmsk &= ~(1u << epnum); } } } #endif #if CFG_TUD_DWC2_DMA_ENABLE static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); if (doepint_bm.setup_phase_done) { // Cleanup previous pending EP0 IN transfer if any dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0]; if (edpt_is_enabled(epin0)) { edpt_disable(rhport, 0x80, false); } dma_setup_prepare(rhport); dcd_dcache_invalidate(_dcd_usbbuf.setup_packet, 8); dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); return; } // OUT XFER complete if (doepint_bm.xfer_complete) { // only handle data skip if it is setup or status related // Normal OUT transfer complete if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) { if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) { // EP0 can only handle one packet Schedule another packet to be received. edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT); } else { dwc2_dep_t* epout = &dwc2->epout[epnum]; xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); // determine actual received bytes const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz}; const uint16_t remain = tsiz.xfer_size; xfer->total_len -= remain; // this is ZLP, so prepare EP0 for next setup // TODO use status phase rx if(epnum == 0 && xfer->total_len == 0) { dma_setup_prepare(rhport); } dcd_dcache_invalidate(xfer->buffer, xfer->total_len); dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } static void handle_epin_dma(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepint_bm) { xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); if (diepint_bm.xfer_complete) { if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_IN]) { // EP0 can only handle one packet. Schedule another packet to be transmitted. edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN); } else { if(epnum == 0) { dma_setup_prepare(rhport); } dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } #endif static void handle_ep_irq(uint8_t rhport, uint8_t dir) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const bool is_dma = dma_device_enabled(dwc2); const uint8_t ep_count = dwc2_ep_count(dwc2); const uint8_t daint_offset = (dir == TUSB_DIR_IN) ? DAINT_IEPINT_Pos : DAINT_OEPINT_Pos; dwc2_dep_t* ep_base = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][0]; // DAINT for a given EP clears when DEPINTx is cleared. // EPINT will be cleared when DAINT bits are cleared. for (uint8_t epnum = 0; epnum < ep_count; epnum++) { if (tu_bit_test(dwc2->daint,daint_offset + epnum)) { dwc2_dep_t* epout = &ep_base[epnum]; union { uint32_t value; dwc2_diepint_t diepint_bm; dwc2_doepint_t doepint_bm; } intr; intr.value = epout->intr; epout->intr = intr.value; // Clear interrupt //-V::2584::{otg_int} if (is_dma) { #if CFG_TUD_DWC2_DMA_ENABLE if (dir == TUSB_DIR_IN) { handle_epin_dma(rhport, epnum, intr.diepint_bm); } else { handle_epout_dma(rhport, epnum, intr.doepint_bm); } #endif } else { #if CFG_TUD_DWC2_SLAVE_ENABLE if (dir == TUSB_DIR_IN) { handle_epin_slave(rhport, epnum, intr.diepint_bm); } else { handle_epout_slave(rhport, epnum, intr.doepint_bm); } #endif } } } } static void handle_incomplete_iso_in(uint8_t rhport) { dwc2_regs_t *dwc2 = DWC2_REG(rhport); const dwc2_dsts_t dsts = {.value = dwc2->dsts}; const uint32_t odd_now = dsts.frame_number & 1u; // Loop over all IN endpoints const uint8_t ep_count = dwc2_ep_count(dwc2); for (uint8_t epnum = 0; epnum < ep_count; epnum++) { dwc2_dep_t *epin = &dwc2->epin[epnum]; dwc2_depctl_t depctl = {.value = epin->diepctl}; // Read DSTS and DIEPCTLn for all isochronous endpoints. If the current EP is enabled and the read value of // DSTS.SOFFN is the targeted uframe number for this EP, then this EP has an incomplete transfer. if (depctl.enable && depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS && depctl.dpid_iso_odd == odd_now) { xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); if (xfer->iso_retry > 0) { xfer->iso_retry--; // Restart ISO transfe: re-write TSIZ and CTL dwc2_ep_tsize_t deptsiz = {.value = 0}; deptsiz.xfer_size = xfer->total_len; deptsiz.packet_count = tu_div_ceil(xfer->total_len, xfer->max_size); epin->tsiz = deptsiz.value; if (odd_now) { depctl.set_data0_iso_even = 1; } else { depctl.set_data1_iso_odd = 1; } epin->diepctl = depctl.value; } else { // too many retries, give up edpt_disable(rhport, epnum | TUSB_DIR_IN_MASK, false); dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, 0, XFER_RESULT_FAILED, true); } } } } /* Interrupt Hierarchy DIEPINT DIEPINT \ / \ / DAINT / \ / \ GINTSTS: OEPInt IEPInt | USBReset | EnumDone | USBSusp | WkUpInt | OTGInt | SOF | RXFLVL Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk are combined to generate dedicated interrupt line for each endpoint. */ void dcd_int_handler(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint32_t gintmask = dwc2->gintmsk; const uint32_t gintsts = dwc2->gintsts & gintmask; if (gintsts & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; usbd_spin_lock(true); handle_bus_reset(rhport); usbd_spin_unlock(true); } if (gintsts & GINTSTS_ENUMDNE) { // ENUMDNE is the end of reset where speed of the link is detected dwc2->gintsts = GINTSTS_ENUMDNE; // There may be a pending suspend event, so we clear it first dwc2->gintsts = GINTSTS_USBSUSP; dwc2->gintmsk |= GINTMSK_USBSUSPM; handle_enum_done(rhport); } if (gintsts & GINTSTS_USBSUSP) { dwc2->gintsts = GINTSTS_USBSUSP; dwc2->gintmsk &= ~GINTMSK_USBSUSPM; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } if (gintsts & GINTSTS_WKUINT) { dwc2->gintsts = GINTSTS_WKUINT; dwc2->gintmsk |= GINTMSK_USBSUSPM; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } // TODO check GINTSTS_DISCINT for disconnect detection // if(int_status & GINTSTS_DISCINT) if (gintsts & GINTSTS_OTGINT) { // OTG INT bit is read-only const uint32_t otg_int = dwc2->gotgint; if (otg_int & GOTGINT_SEDET) { dwc2->gintmsk &= ~GINTMSK_OTGINT; dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } dwc2->gotgint = otg_int; } if(gintsts & GINTSTS_SOF) { dwc2->gintsts = GINTSTS_SOF; dwc2->gintmsk |= GINTMSK_USBSUSPM; const uint32_t frame = (dwc2->dsts & DSTS_FNSOF) >> DSTS_FNSOF_Pos; // Disable SOF interrupt if SOF was not explicitly enabled since SOF was used for remote wakeup detection if (!_dcd_data.sof_en) { dwc2->gintmsk &= ~GINTMSK_SOFM; } dcd_event_sof(rhport, frame, true); } #if CFG_TUD_DWC2_SLAVE_ENABLE // RxFIFO non-empty interrupt handling. if (gintsts & GINTSTS_RXFLVL) { // RXFLVL bit is read-only dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // disable RXFLVL interrupt while reading do { handle_rxflvl_irq(rhport); // read all packets } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTMSK_RXFLVLM; } #endif // OUT endpoint interrupt handling. if (gintsts & GINTSTS_OEPINT) { // OEPINT is read-only, clear using DOEPINTn handle_ep_irq(rhport, TUSB_DIR_OUT); } // IN endpoint interrupt handling. if (gintsts & GINTSTS_IEPINT) { // IEPINT bit read-only, clear using DIEPINTn handle_ep_irq(rhport, TUSB_DIR_IN); } // Incomplete isochronous IN transfer interrupt handling. if (gintsts & GINTSTS_IISOIXFR) { dwc2->gintsts = GINTSTS_IISOIXFR; handle_incomplete_iso_in(rhport); } } #if CFG_TUD_TEST_MODE void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Enable the test mode dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos); } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_at32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef DWC2_AT32_H_ #define DWC2_AT32_H_ #define DWC2_EP_MAX TUP_DCD_ENDPOINT_MAX #if CFG_TUSB_MCU == OPT_MCU_AT32F415 #include #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #elif CFG_TUSB_MCU == OPT_MCU_AT32F435_437 #include #define OTG1_FIFO_SIZE 1280 #define OTG2_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define OTG2_IRQn OTGFS2_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #define DWC2_OTG2_REG_BASE 0x40040000UL #elif CFG_TUSB_MCU == OPT_MCU_AT32F423 #include #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #elif CFG_TUSB_MCU == OPT_MCU_AT32F402_405 #include #define OTG1_FIFO_SIZE 1280 #define OTG2_FIFO_SIZE 4096 #define OTG1_IRQn OTGFS1_IRQn #define OTG2_IRQn OTGHS_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #define DWC2_OTG2_REG_BASE 0x40040000UL //OTGHS #elif CFG_TUSB_MCU == OPT_MCU_AT32F425 #include #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #elif CFG_TUSB_MCU == OPT_MCU_AT32F45X #include #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL #endif #ifdef __cplusplus extern "C" { #endif static const dwc2_controller_t _dwc2_controller[] = { {.reg_base = DWC2_OTG1_REG_BASE, .irqnum = OTG1_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = OTG1_FIFO_SIZE}, #if defined DWC2_OTG2_REG_BASE {.reg_base = DWC2_OTG2_REG_BASE, .irqnum = OTG2_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = OTG2_FIFO_SIZE} #endif }; TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) { (void) role; const IRQn_Type irqn = (IRQn_Type) _dwc2_controller[rhport].irqnum; if (enabled) { NVIC_EnableIRQ(irqn); } else { NVIC_DisableIRQ(irqn); } } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms uint32_t count = system_core_clock / 1000; while (count--) __asm volatile("nop"); } // MCU specific PHY init, called BEFORE core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { (void) dwc2; // Enable on-chip HS PHY if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) { } else if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { } } // MCU specific PHY deinit, disable PHY power TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { (void) hs_phy_type; dwc2->stm32_gccfg &= ~(STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN); } // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t *dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN | STM32_GCCFG_DCDEN | STM32_GCCFG_PDEN; } #ifdef __cplusplus } #endif #endif /* DWC2_AT32_H_ */ ================================================ FILE: src/portable/synopsys/dwc2/dwc2_bcm.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DWC2_BCM_H_ #define TUSB_DWC2_BCM_H_ #ifdef __cplusplus extern "C" { #endif #include "broadcom/defines.h" #include "broadcom/interrupts.h" #include "broadcom/caches.h" #define DWC2_EP_MAX 8 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 16384 } }; #define dcache_clean(_addr, _size) data_clean(_addr, _size) #define dcache_invalidate(_addr, _size) data_invalidate(_addr, _size) #define dcache_clean_invalidate(_addr, _size) data_clean_and_invalidate(_addr, _size) TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { BP_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { BP_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms // TODO implement later } // MCU specific PHY init, called BEFORE core reset static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } // MCU specific PHY deinit, disable PHY power static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_common.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024-2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #define DWC2_COMMON_DEBUG 2 #if defined(TUP_USBIP_DWC2) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED) #include "dwc2_common.h" //-------------------------------------------------------------------- // //-------------------------------------------------------------------- static void reset_core(dwc2_regs_t* dwc2) { // The software must check that bit 31 in this register is set to 1 (AHB Master is Idle) before starting any operation while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) { } const uint32_t gsnpsid = dwc2->gsnpsid; // preload gsnpsid which is not readable while resetting dwc2->grstctl |= GRSTCTL_CSRST; // reset core if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { // prior v4.20a: CSRST is self-clearing, and the core clears this bit after all the necessary logic is reset in // the core, which can take several clocks, depending on the current state of the core. Once this bit has been // cleared, the software must wait at least 3 PHY clocks before accessing the PHY domain (synchronization delay). while (dwc2->grstctl & GRSTCTL_CSRST) {} } else { // From v4.20a: CSRST bit is write only. The application must clear this bit after checking the bit 29 of this // register i.e Core Soft Reset Done CSRT_DONE (w1c) while (!(dwc2->grstctl & GRSTCTL_CSRST_DONE)) {} dwc2->grstctl = (dwc2->grstctl & ~GRSTCTL_CSRST) | GRSTCTL_CSRST_DONE; } while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) {} // wait for AHB master IDLE } // Dedicated FS PHY is internal with a clock 48Mhz. static void phy_fs_init(dwc2_regs_t* dwc2) { TU_LOG(DWC2_COMMON_DEBUG, "Fullspeed PHY init\r\n"); uint32_t gusbcfg = dwc2->gusbcfg; // Select FS PHY gusbcfg |= GUSBCFG_PHYSEL; dwc2->gusbcfg = gusbcfg; // MCU specific PHY init before reset dwc2_phy_init(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // Reset core after selecting PHY reset_core(dwc2); // USB turnaround time is critical for certification where long cables and 5-Hubs are used. // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, // these bits can be programmed to a larger value. Default is 5 gusbcfg &= ~GUSBCFG_TRDT_Msk; gusbcfg |= 5u << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); } /* dwc2 has 2 highspeed PHYs options * - UTMI+ is internal highspeed PHY, can be clocked at 30 Mhz (8-bit) or 60 Mhz (16-bit). * - ULPI is external highspeed PHY, clocked at 60Mhz with 8-bit interface. * * In addition, UTMI+/ULPI can be shared to run at fullspeed mode with 48Mhz */ static void phy_hs_init(dwc2_regs_t* dwc2) { uint32_t gusbcfg = dwc2->gusbcfg; const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const dwc2_ghwcfg4_t ghwcfg4 = {.value = dwc2->ghwcfg4}; uint8_t phy_width; if (CFG_TUSB_MCU != OPT_MCU_AT32F402_405 && // at32f402_405 does not support 16-bit ghwcfg4.phy_data_width) { phy_width = 16; // 16-bit PHY interface if supported } else { phy_width = 8; // 8-bit PHY interface } // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; if (ghwcfg2.hs_phy_type == GHWCFG2_HSPHY_ULPI) { TU_LOG(DWC2_COMMON_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI PHY (external) gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; // ULPI is always 8-bit interface gusbcfg &= ~GUSBCFG_PHYIF16; // ULPI select single data rate gusbcfg &= ~GUSBCFG_DDRSEL; // default internal VBUS Indicator and Drive gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI); // Disable FS/LS ULPI gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); } else { TU_LOG(DWC2_COMMON_DEBUG, "Highspeed UTMI+ PHY init\r\n"); // Select UTMI+ PHY (internal) gusbcfg &= ~GUSBCFG_ULPI_UTMI_SEL; // Set 16-bit interface if supported if (phy_width == 16) { gusbcfg |= GUSBCFG_PHYIF16; } else { gusbcfg &= ~GUSBCFG_PHYIF16; } } // Apply config dwc2->gusbcfg = gusbcfg; // mcu specific phy init dwc2_phy_init(dwc2, ghwcfg2.hs_phy_type); // Reset core after selecting PHY reset_core(dwc2); // Set turn-around, must after core reset otherwise it will be clear // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; gusbcfg |= (phy_width == 16 ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset dwc2_phy_update(dwc2, ghwcfg2.hs_phy_type); } static bool check_dwc2(dwc2_regs_t* dwc2) { #if CFG_TUSB_DEBUG >= DWC2_COMMON_DEBUG // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 // Run 'python dwc2_info.py' and check dwc2_info.md for bit-field value and comparison with other ports volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); for (size_t i = 0; i < 5; i++) { TU_LOG1("0x%08" PRIX32 ", ", p[i]); } TU_LOG1("0x%08" PRIX32 "\r\n", p[5]); #endif // For some reason: GD32VF103 gsnpsid and all hwcfg register are always zero (skip it) (void)dwc2; #if !TU_CHECK_MCU(OPT_MCU_GD32VF103) enum { GSNPSID_ID_MASK = TU_GENMASK(31, 16) }; const uint32_t gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); #endif return true; } //-------------------------------------------------------------------- // //-------------------------------------------------------------------- bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy) { const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const bool has_hs_phy = (ghwcfg2.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED); if (prefer_hs_phy) { return has_hs_phy; } else { const bool has_fs_phy = (ghwcfg2.fs_phy_type != GHWCFG2_FSPHY_NOT_SUPPORTED); // false if has fs phy, otherwise true since hs phy is the only available phy return !has_fs_phy && has_hs_phy; } } bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled TU_ASSERT(check_dwc2(dwc2)); // disable global interrupt dwc2->gahbcfg &= ~GAHBCFG_GINT; if (is_hs_phy) { phy_hs_init(dwc2); } else { phy_fs_init(dwc2); } /* Set HS/FS Timeout Calibration to 7 (max available value). * The number of PHY clocks that the application programs in * this field is added to the high/full speed interpacket timeout * duration in the core to account for any additional delays * introduced by the PHY. This can be required, because the delay * introduced by the PHY in generating the linestate condition * can vary from one PHY to another. */ dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); // Enable PHY clock TODO stop/gate clock when suspended mode dwc2->pcgcctl &= ~(PCGCCTL_STOPPCLK | PCGCCTL_GATEHCLK | PCGCCTL_PWRCLMP | PCGCCTL_RSTPDWNMODULE); dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); // Clear pending and disable all interrupts dwc2->gintsts = 0xFFFFFFFFU; dwc2->gotgint = 0xFFFFFFFFU; dwc2->gintmsk = 0; TU_LOG(DWC2_COMMON_DEBUG, "DMA = %u\r\n", is_dma); if (is_dma) { // DMA seems to be only settable after a core reset, and not possible to switch on-the-fly dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; } else { dwc2->gintmsk |= GINTSTS_RXFLVL; } return true; } void dwc2_core_deinit(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Disable global interrupt dwc2->gahbcfg &= ~GAHBCFG_GINT; // Reset core: this also flushes FIFOs and clears all interrupt registers reset_core(dwc2); // Stop PHY clock and gate HCLK for power saving (per databook chapter 14) dwc2->pcgcctl |= PCGCCTL_STOPPCLK | PCGCCTL_GATEHCLK; // MCU-specific PHY deinit (disable PHY power) const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const uint8_t hs_phy_type = (dwc2->gusbcfg & GUSBCFG_PHYSEL) ? GHWCFG2_HSPHY_NOT_SUPPORTED : ghwcfg2.hs_phy_type; dwc2_phy_deinit(dwc2, hs_phy_type); } // void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) { // (void) in_isr; // dwc2_regs_t * const dwc2 = DWC2_REG(rhport); // const uint32_t int_mask = dwc2->gintmsk; // const uint32_t int_status = dwc2->gintsts & int_mask; // // // Device disconnect // if (int_status & GINTSTS_DISCINT) { // dwc2->gintsts = GINTSTS_DISCINT; // } // // } #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_common.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DWC2_COMMON_H #define TUSB_DWC2_COMMON_H #include "common/tusb_common.h" #include "dwc2_type.h" #if CFG_TUD_ENABLED #include "device/dcd.h" #endif #if CFG_TUH_ENABLED #include "host/hcd.h" #endif // Following symbols must be defined by port header // - _dwc2_controller[]: array of controllers // - DWC2_EP_MAX: largest EP counts of all controllers // - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset // - dwc2_phy_deinit(dwc2, hs_phy_type): phy deinit to disable PHY power, only deinit the phy used by core // - dwc2_dcd_int_enable/dwc2_dcd_int_disable // - dwc2_remote_wakeup_delay #if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" #elif defined(TUP_USBIP_DWC2_ESP32) #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #include "dwc2_bcm.h" #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #include "dwc2_efm32.h" #elif TU_CHECK_MCU(OPT_MCU_XMC4000) #include "dwc2_xmc.h" #elif defined(TUP_USBIP_DWC2_AT32) #include "dwc2_at32.h" #elif defined(TUP_USBIP_DWC2_NRF) #include "dwc2_nrf.h" #else #error "Unsupported MCUs" #endif enum { DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) }; enum { OTG_INT_COMMON = 0 // GINTSTS_DISCINT | GINTSTS_CONIDSTSCHNG }; //--------------------------------------------------------------------+ // Core/Controller //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { if (rhport >= DWC2_CONTROLLER_COUNT) { // user mis-configured, ignore and use first controller rhport = 0; } return (dwc2_regs_t*)_dwc2_controller[rhport].reg_base; } // check if highspeed phy should be used bool dwc2_core_is_highspeed_phy(dwc2_regs_t* dwc2, bool prefer_hs_phy); bool dwc2_core_init(uint8_t rhport, bool is_hs_phy, bool is_dma); void dwc2_core_deinit(uint8_t rhport); void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr); //--------------------------------------------------------------------+ // DFIFO //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx(dwc2_regs_t* dwc2, uint8_t fnum) { // flush TX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_TXFFLSH | (fnum << GRSTCTL_TXFNUM_Pos); while (0 != (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk)) {} } TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { // flush RX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_RXFFLSH; while (0 != (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk)) {} } void dfifo_read_packet(dwc2_regs_t* dwc2, uint8_t* dst, uint16_t len); void dfifo_write_packet(dwc2_regs_t* dwc2, uint8_t fifo_num, uint8_t const* src, uint16_t len); //--------------------------------------------------------------------+ // DMA //--------------------------------------------------------------------+ #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_efm32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Rafael Silva (@perigoso) * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _DWC2_EFM32_H_ #define _DWC2_EFM32_H_ #ifdef __cplusplus extern "C" { #endif #include "em_device.h" // EFM32 has custom control register before DWC registers #define DWC2_REG_BASE (USB_BASE + offsetof(USB_TypeDef, GOTGCTL)) #define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_REG_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 2048 } }; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms // uint32_t count = SystemCoreClock / 1000; // while ( count-- ) __NOP(); } // MCU specific PHY init, called BEFORE core reset static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // Enable PHY USB->ROUTE = USB_ROUTE_PHYPEN; } // MCU specific PHY deinit, disable PHY power static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // Disable PHY pin USB->ROUTE = 0; } // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // EFM32 Manual: turn around must be 5 (reset & default value) // dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_esp32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DWC2_ESP32_H_ #define TUSB_DWC2_ESP32_H_ #ifdef __cplusplus extern "C" { #endif #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_intr_alloc.h" #include "soc/periph_defs.h" #include "soc/usb_wrap_struct.h" #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define DWC2_FS_REG_BASE 0x60080000UL #define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; #elif TU_CHECK_MCU(OPT_MCU_ESP32H4) // H4's USB_WRAP register block uses "wrap_*" field names. Map them to the // names used by TinyUSB's DWC2 port to keep the source unchanged. #define otg_conf wrap_otg_conf #define pad_pull_override wrap_pad_pull_override #define dp_pullup wrap_dp_pullup #define dp_pulldown wrap_dp_pulldown #define dm_pullup wrap_dm_pullup #define dm_pulldown wrap_dm_pulldown #define DWC2_FS_REG_BASE 0x60040000UL #define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define DWC2_FS_REG_BASE 0x50040000UL #define DWC2_HS_REG_BASE 0x50000000UL #define DWC2_EP_MAX 16 // On ESP32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 }, { .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, .ep_fifo_size = 4096 } }; #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ static intr_handle_t usb_ih[TU_ARRAY_SIZE(_dwc2_controller)]; static void dwc2_int_handler_wrap(void* arg) { const uint8_t rhport = tu_u16_low((uint16_t)(uintptr_t)arg); const tusb_role_t role = (tusb_role_t) tu_u16_high((uint16_t)(uintptr_t)arg); #if CFG_TUD_ENABLED if (role == TUSB_ROLE_DEVICE) { dcd_int_handler(rhport); } #endif #if CFG_TUH_ENABLED && !CFG_TUH_MAX3421 if (role == TUSB_ROLE_HOST) { hcd_int_handler(rhport, true); } #endif } TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) { if (enabled) { esp_intr_alloc(_dwc2_controller[rhport].irqnum, ESP_INTR_FLAG_LOWMED, dwc2_int_handler_wrap, (void*)(uintptr_t)tu_u16(role, rhport), &usb_ih[rhport]); } else { esp_intr_free(usb_ih[rhport]); } } #define dwc2_dcd_int_enable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, true) #define dwc2_dcd_int_disable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, false) TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { vTaskDelay(pdMS_TO_TICKS(1)); } // MCU specific PHY init, called BEFORE core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; // maybe usb_utmi_hal_init() } // MCU specific PHY deinit, disable PHY power TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; // PHY managed by ESP-IDF } // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; // maybe usb_utmi_hal_disable() } //--------------------------------------------------------------------+ // Data Cache //--------------------------------------------------------------------+ #if CFG_TUD_DWC2_DMA_ENABLE || CFG_TUH_DWC2_DMA_ENABLE #if defined(SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE) && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_cache.h" #if CFG_TUD_MEM_DCACHE_LINE_SIZE != CONFIG_CACHE_L1_CACHE_LINE_SIZE || \ CFG_TUH_MEM_DCACHE_LINE_SIZE != CONFIG_CACHE_L1_CACHE_LINE_SIZE #error "CFG_TUD/TUH_MEM_DCACHE_LINE_SIZE must match CONFIG_CACHE_L1_CACHE_LINE_SIZE" #endif TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) { if (size & (CONFIG_CACHE_L1_CACHE_LINE_SIZE-1)) { size = (size & ~(CONFIG_CACHE_L1_CACHE_LINE_SIZE-1)) + CONFIG_CACHE_L1_CACHE_LINE_SIZE; } return size; } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean(const void* addr, uint32_t data_size) { const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M; data_size = round_up_to_cache_line_size(data_size); return ESP_OK == esp_cache_msync((void*)addr, data_size, flag); } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_invalidate(const void* addr, uint32_t data_size) { const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_M2C; data_size = round_up_to_cache_line_size(data_size); return ESP_OK == esp_cache_msync((void*)addr, data_size, flag); } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean_invalidate(const void* addr, uint32_t data_size) { const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_DIR_M2C; data_size = round_up_to_cache_line_size(data_size); return ESP_OK == esp_cache_msync((void*)addr, data_size, flag); } #endif #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_gd32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef DWC2_GD32_H_ #define DWC2_GD32_H_ #ifdef __cplusplus extern "C" { #endif #define DWC2_REG_BASE 0x50000000UL #define DWC2_EP_MAX 4 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_REG_BASE, .irqnum = 86, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1280 } }; extern uint32_t SystemCoreClock; // The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local // Interrupt Controller by Nuclei. It is nearly API compatible to the // NVIC used by ARM MCUs. #define ECLIC_INTERRUPT_ENABLE_BASE 0xD2001001UL TU_ATTR_ALWAYS_INLINE static inline void __eclic_enable_interrupt (uint32_t irq) { *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 1; } TU_ATTR_ALWAYS_INLINE static inline void __eclic_disable_interrupt (uint32_t irq){ *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 0; } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { __eclic_enable_interrupt(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { __eclic_disable_interrupt(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms uint32_t count = SystemCoreClock / 1000; while ( count-- ) __asm volatile ("nop"); } // MCU specific PHY init, called BEFORE core reset static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } // MCU specific PHY deinit, disable PHY power static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } #ifdef __cplusplus } #endif #endif /* DWC2_GD32_H_ */ ================================================ FILE: src/portable/synopsys/dwc2/dwc2_info.md ================================================ | | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | nRF54 | ST F407/429 HS | ST F207/F407/411/429 FS | ST L476 FS | ST F412/76x FS | ST F76x HS | ST H743/H750 | ST F723/L4P5 FS | ST F723 HS | ST H7RS FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | |:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:-------------|:-----------------|:--------------------------|:-------------|:-----------------|:-------------|:---------------|:------------------|:-------------|:-------------|:---------------------|:-------------|:------------| | GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001100 | 0x00001200 | 0x00002000 | 0x00002000 | 0x00002100 | 0x00002300 | 0x00003000 | 0x00003100 | 0x00004000 | 0x00005000 | 0x00AEC000 | 0x00001000 | | GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54430A | 0x4F54281A | 0x4F54281A | 0x4F54310A | 0x4F54320A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54411A | 0x4F54411A | 0x4F54292A | 0x00000000 | | - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 4.30a | 2.81a | 2.81a | 3.10a | 3.20a | 3.20a | 3.30a | 3.30a | 3.30a | 4.11a | 4.11a | 2.92a | 0.00W | | GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0xAA555000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | | GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x228BFC72 | 0x229ED590 | 0x229DCD20 | 0x229ED520 | 0x229ED520 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x229FE1D0 | 0x229ED522 | 0x228FE052 | 0x228F5930 | 0x00000000 | | - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | noHNP noSRP | HNP SRP | HNP SRP | | - arch | Slave only | DMA internal | Slave only | DMA internal | DMA internal | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | Slave only | Slave only | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | DMA internal | Slave only | | - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | n/a | hub | hub | n/a | hub | n/a | hub | n/a | hub | | - hs_phy_type | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | UTMI+/ULPI | UTMI+ | ULPI | n/a | n/a | n/a | ULPI | ULPI | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | | - fs_phy_type | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Shared ULPI | n/a | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | | - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 15 | 5 | 3 | 5 | 5 | 8 | 8 | 5 | 8 | 5 | 8 | 6 | 0 | | - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 15 | 11 | 7 | 11 | 11 | 15 | 15 | 11 | 15 | 11 | 15 | 13 | 0 | | - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - mul_proc_intrpt | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | | - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | | - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | | - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | | - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x0BEAC0E8 | 0x03F403E8 | 0x020001E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03EED2E8 | 0x020081E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | | - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | | - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | | - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | | - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | | - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | | - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | | - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | | - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 3050 | 1012 | 512 | 512 | 512 | 1006 | 952 | 512 | 1006 | 512 | 952 | 634 | 0 | | GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x1E10AA60 | 0x17F00030 | 0x0FF08030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0x23F00030 | 0x1610B230 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | | - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | | - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | | - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | | - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | | - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | | - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | | - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | | - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | | - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | | - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | | - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | | - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 7 | 5 | 3 | 5 | 5 | 8 | 8 | 5 | 8 | 5 | 8 | 6 | 0 | | - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | | - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | ================================================ FILE: src/portable/synopsys/dwc2/dwc2_info.py ================================================ #!/usr/bin/env python3 import ctypes import argparse import pandas as pd # hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 # Note: FS is FullSpeed, HS is HighSpeed dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'AT32 F405 FS': [0x00002000, 0x4F54400A, 0x00000000, 0x228FDD00, 0x020004E8, 0x1FF0A020], 'AT32 F405 HS': [0x00000000, 0x4F54400A, 0x00000000, 0x229FDDD0, 0x03F006E8, 0x1FF0A020], 'AT32 F415': [0x00001000, 0x4F54400A, 0x00000000, 0x228DCD00, 0x020004E8, 0x0F], 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], 'nRF54': [0, 0x4F54430A, 0xAA555000, 0x228BFC72, 0x0BEAC0E8, 0x1E10AA60], # ST sort by GUID 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030], 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST F412/76x FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST F76x HS': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030], 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030], 'ST H7RS FS': [0x4000, 0x4F54411A, 0, 0x229ED522, 0x20081E8, 0x1610B230], 'ST U5A5/H7RS/N6 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030], 'GD32VF103': [0x1000, 0, 0, 0, 0, 0], } # Combine dwc2_info with dwc2_reg_list # dwc2_info = { # 'BCM2711 (Pi4)': { # 'GUID': 0x2708A000, # 'GSNPSID': 0x4F54280A, # 'GHWCFG1': 0, # 'GHWCFG2': 0x228DDD50, # 'GHWCFG3': 0xFF000E8, # 'GHWCFG4': 0x1FF00020 # }, dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()} class GHWCFG2(ctypes.LittleEndianStructure): _fields_ = [ ("op_mode", ctypes.c_uint32, 3), ("arch", ctypes.c_uint32, 2), ("single_point", ctypes.c_uint32, 1), ("hs_phy_type", ctypes.c_uint32, 2), ("fs_phy_type", ctypes.c_uint32, 2), ("num_dev_ep", ctypes.c_uint32, 4), ("num_host_ch", ctypes.c_uint32, 4), ("period_channel_support", ctypes.c_uint32, 1), ("enable_dynamic_fifo", ctypes.c_uint32, 1), ("mul_proc_intrpt", ctypes.c_uint32, 1), ("reserved21", ctypes.c_uint32, 1), ("nptx_q_depth", ctypes.c_uint32, 2), ("ptx_q_depth", ctypes.c_uint32, 2), ("token_q_depth", ctypes.c_uint32, 5), ("otg_enable_ic_usb", ctypes.c_uint32, 1) ] class GHWCFG3(ctypes.LittleEndianStructure): _fields_ = [ ("xfer_size_width", ctypes.c_uint32, 4), ("packet_size_width", ctypes.c_uint32, 3), ("otg_enable", ctypes.c_uint32, 1), ("i2c_enable", ctypes.c_uint32, 1), ("vendor_ctrl_itf", ctypes.c_uint32, 1), ("optional_feature_removed", ctypes.c_uint32, 1), ("synch_reset", ctypes.c_uint32, 1), ("otg_adp_support", ctypes.c_uint32, 1), ("otg_enable_hsic", ctypes.c_uint32, 1), ("battery_charger_support", ctypes.c_uint32, 1), ("lpm_mode", ctypes.c_uint32, 1), ("dfifo_depth", ctypes.c_uint32, 16) ] class GHWCFG4(ctypes.LittleEndianStructure): _fields_ = [ ("num_dev_period_in_ep", ctypes.c_uint32, 4), ("partial_powerdown", ctypes.c_uint32, 1), ("ahb_freq_min", ctypes.c_uint32, 1), ("hibernation", ctypes.c_uint32, 1), ("extended_hibernation", ctypes.c_uint32, 1), ("reserved8", ctypes.c_uint32, 1), ("enhanced_lpm_support1", ctypes.c_uint32, 1), ("service_interval_flow", ctypes.c_uint32, 1), ("ipg_isoc_support", ctypes.c_uint32, 1), ("acg_support", ctypes.c_uint32, 1), ("enhanced_lpm_support", ctypes.c_uint32, 1), ("phy_data_width", ctypes.c_uint32, 2), ("ctrl_ep_num", ctypes.c_uint32, 4), ("iddg_filter", ctypes.c_uint32, 1), ("vbus_valid_filter", ctypes.c_uint32, 1), ("a_valid_filter", ctypes.c_uint32, 1), ("b_valid_filter", ctypes.c_uint32, 1), ("session_end_filter", ctypes.c_uint32, 1), ("dedicated_fifos", ctypes.c_uint32, 1), ("num_dev_in_eps", ctypes.c_uint32, 4), ("dma_desc_enable", ctypes.c_uint32, 1), ("dma_desc_dynamic", ctypes.c_uint32, 1) ] # mapping for specific fields in GHWCFG2 GHWCFG2_field = { 'op_mode': { 0: "HNP SRP", 1: "SRP", 2: "noHNP noSRP", 3: "SRP Device", 4: "noOTG Device", 5: "SRP Host", 6: "noOTG Host" }, 'arch': { 0: "Slave only", 1: "DMA external", 2: "DMA internal" }, 'single_point': { 0: "hub", 1: "n/a" }, 'hs_phy_type': { 0: "n/a", 1: "UTMI+", 2: "ULPI", 3: "UTMI+/ULPI" }, 'fs_phy_type': { 0: "n/a", 1: "Dedicated", 2: "Shared UTMI+", 3: "Shared ULPI" }, 'nptx_q_depth': { 0: "2", 1: "4", 2: "8", }, 'ptx_q_depth': { 0: "2", 1: "4", 2: "8", 3: "16" }, } # mapping for specific fields in GHWCFG4 GHWCFG4_field = { 'phy_data_width': { 0: "8 bit", 1: "16 bit", 2: "8/16 bit", 3: "Reserved" }, } def main(): """Render dwc2_info to Markdown table""" parser = argparse.ArgumentParser() args = parser.parse_args() # Create an empty list to hold the dictionaries md_table = [] # Iterate over the dwc2_info dictionary and extract fields for device, reg_values in dwc2_info.items(): md_item = {"Device": device} for r_name, r_value in reg_values.items(): md_item[r_name] = f"0x{r_value:08X}" if r_name == 'GSNPSID': # Get dwc2 specs version major = ((r_value >> 8) >> 4) & 0x0F minor = (r_value >> 4) & 0xFF patch = chr((r_value & 0x0F) + ord('a') - 0xA) md_item[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" elif r_name in globals(): # Get bit-field values which exist as ctypes structures class_hdl = globals()[r_name] ghwcfg = class_hdl.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) for field_name, field_type, _ in class_hdl._fields_: field_value = getattr(ghwcfg, field_name) if class_hdl == GHWCFG2 and field_name in GHWCFG2_field: field_value = GHWCFG2_field[field_name].get(field_value, f"Unknown ({field_value})") if class_hdl == GHWCFG4 and field_name in GHWCFG4_field: field_value = GHWCFG4_field[field_name].get(field_value, f"Unknown ({field_value})") md_item[f' - {field_name}'] = field_value md_table.append(md_item) # Create a Pandas DataFrame from the list of dictionaries df = pd.DataFrame(md_table).set_index('Device') # Transpose the DataFrame to switch rows and columns df = df.T #print(df) # Write the Markdown table to a file with open('dwc2_info.md', 'w') as md_file: md_file.write(df.to_markdown()) md_file.write('\n') if __name__ == '__main__': main() ================================================ FILE: src/portable/synopsys/dwc2/dwc2_nrf.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DWC2_NRF_H #define TUSB_DWC2_NRF_H #include "nrf.h" #define DWC2_EP_MAX 16 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = NRF_USBHSCORE0_NS_BASE, .irqnum = USBHS_IRQn, .ep_count = 16, .ep_fifo_size = 12288 }, }; TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) { (void) rhport; (void) role; (void) enabled; } #define dwc2_dcd_int_enable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, true) #define dwc2_dcd_int_disable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, false) TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { } // MCU specific PHY init, called BEFORE core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; } // MCU specific PHY deinit, disable PHY power TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; } // MCU specific PHY update, it is called AFTER init() and core reset TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; } #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_stm32.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef DWC2_STM32_H_ #define DWC2_STM32_H_ #ifdef __cplusplus extern "C" { #endif // EP_MAX : Max number of bi-directional endpoints including EP0 // EP_FIFO_SIZE : Size of dedicated USB SRAM #if CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" #define EP_MAX_FS 4 #define EP_FIFO_SIZE_FS 1280 #elif CFG_TUSB_MCU == OPT_MCU_STM32F2 #include "stm32f2xx.h" #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE #elif CFG_TUSB_MCU == OPT_MCU_STM32F4 #include "stm32f4xx.h" #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE #elif CFG_TUSB_MCU == OPT_MCU_STM32H7 #include "stm32h7xx.h" #define EP_MAX_FS 9 #define EP_FIFO_SIZE_FS 4096 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 // NOTE: H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined #if (! defined USB2_OTG_FS) #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE #define OTG_FS_IRQn OTG_HS_IRQn #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32H7RS #include "stm32h7rsxx.h" #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #elif CFG_TUSB_MCU == OPT_MCU_STM32N6 #include "stm32n6xx.h" #define EP_MAX_FS 9 #define EP_FIFO_SIZE_FS 4096 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_BASE #define OTG_FS_IRQn USB1_OTG_HS_IRQn #define USB_OTG_HS_PERIPH_BASE USB2_OTG_HS_BASE #define OTG_HS_IRQn USB2_OTG_HS_IRQn #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif #elif CFG_TUSB_MCU == OPT_MCU_STM32WBA #if defined(STM32WBA62xx) #include "stm32wba62xx.h" #elif defined(STM32WBA64xx) #include "stm32wba64xx.h" #elif defined(STM32WBA65xx) #include "stm32wba65xx.h" #else #error "The selected STM32WBA series chip does not support OTG USB HS" #endif #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE_NS #define OTG_HS_IRQn USB_OTG_HS_IRQn #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #else #error "Unsupported MCUs" #endif // OTG HS always has higher number of endpoints than FS #ifdef USB_OTG_HS_PERIPH_BASE #define DWC2_EP_MAX EP_MAX_HS #else #define DWC2_EP_MAX EP_MAX_FS #endif // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS }, #endif }; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // SystemCoreClock is already included by family header // extern uint32_t SystemCoreClock; TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) { (void) role; const IRQn_Type irqn = (IRQn_Type) _dwc2_controller[rhport].irqnum; if (enabled) { NVIC_EnableIRQ(irqn); } else { NVIC_DisableIRQ(irqn); } } #define dwc2_dcd_int_enable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, true) #define dwc2_dcd_int_disable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, false) TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms uint32_t count = SystemCoreClock / 1000; while (count--) { __NOP(); } } // MCU specific PHY init, called BEFORE core reset // - dwc2 3.30a (H5) use USB_HS_PHYC // - dwc2 4.11a (U5) use femtoPHY // - dwc2 x.xxx (WBA) use USB_OTG_HS static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Enable on-chip FS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; // https://community.st.com/t5/stm32cubemx-mcus/why-stm32h743-usb-fs-doesn-t-work-if-freertos-tickless-idle/m-p/349480#M18867 // H7 running on full-speed phy need to disable ULPI clock in sleep mode. // Otherwise, USB won't work when mcu executing WFI/WFE instruction i.e tick-less RTOS. // Note: there may be other family that is affected by this, but only H7 and F7 is tested so far #if defined(USB_OTG_FS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB2OTGFSULPILPEN) if ( USB_OTG_FS_PERIPH_BASE == (uint32_t) dwc2 ) { RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB2OTGFSULPILPEN; } #endif #if defined(USB_OTG_HS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB1OTGHSULPILPEN) if ( USB_OTG_HS_PERIPH_BASE == (uint32_t) dwc2 ) { RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB1OTGHSULPILPEN; } #endif #if defined(USB_OTG_HS_PERIPH_BASE) && defined(RCC_AHB1LPENR_OTGHSULPILPEN) if ( USB_OTG_HS_PERIPH_BASE == (uint32_t) dwc2 ) { RCC->AHB1LPENR &= ~RCC_AHB1LPENR_OTGHSULPILPEN; } #endif } else { #if CFG_TUSB_MCU != OPT_MCU_STM32U5 && CFG_TUSB_MCU != OPT_MCU_STM32WBA // Disable FS PHY, TODO on U5A5 (dwc2 4.11a) 16th bit is 'Host CDP behavior enable' dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; #endif // Enable on-chip HS PHY if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) { #ifdef USB_HS_PHYC // Enable UTMI HS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN; // Enable LDO USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; // Wait until LDO ready while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} uint32_t phyc_pll = 0; // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS switch ( HSE_VALUE ) { case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header default: TU_ASSERT(false, ); } USB_HS_PHYC->USB_HS_PHYC_PLL = phyc_pll; // Control the tuning interface of the High Speed PHY // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7 USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U; // Enable PLL internal PHY USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; // Wait ~2ms until the PLL is ready (there's no RDY bit to query) tusb_time_delay_ms_api(2); #else #endif } } } // MCU specific PHY deinit, disable PHY power static inline void dwc2_phy_deinit(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Disable on-chip FS PHY dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; } else { // Disable HS PHY #ifdef USB_HS_PHYC dwc2->stm32_gccfg &= ~STM32_GCCFG_PHYHSEN; // Disable PLL and LDO USB_HS_PHYC->USB_HS_PHYC_PLL &= ~USB_HS_PHYC_PLL_PLLEN; USB_HS_PHYC->USB_HS_PHYC_LDO &= ~USB_HS_PHYC_LDO_ENABLE; #endif } } // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual uint32_t turnaround; if (SystemCoreClock >= 32000000u) { turnaround = 0x6u; } else if (SystemCoreClock >= 27500000u) { turnaround = 0x7u; } else if (SystemCoreClock >= 24000000u) { turnaround = 0x8u; } else if (SystemCoreClock >= 21800000u) { turnaround = 0x9u; } else if (SystemCoreClock >= 20000000u) { turnaround = 0xAu; } else if (SystemCoreClock >= 18500000u) { turnaround = 0xBu; } else if (SystemCoreClock >= 17200000u) { turnaround = 0xCu; } else if (SystemCoreClock >= 16000000u) { turnaround = 0xDu; } else if (SystemCoreClock >= 15000000u) { turnaround = 0xEu; } else { turnaround = 0xFu; } dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos); } } //------------- GCCFG configuration -------------// static inline void dwc2_stm32_gccfg_cfg(dwc2_regs_t* dwc2, bool vbus_sensing, bool is_host) { if (is_host) { vbus_sensing = false; } uint32_t gccfg = dwc2->stm32_gccfg; if (dwc2->guid < 0x2000) { // use VBUSASEN/VBUSBSEN/NOVBUSSENS bits if (is_host) { gccfg &= ~(STM32_GCCFG_NOVBUSSENS | STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); } else { if (vbus_sensing) { gccfg &= ~STM32_GCCFG_NOVBUSSENS; gccfg |= STM32_GCCFG_VBUSBSEN; } else { gccfg |= STM32_GCCFG_NOVBUSSENS; gccfg &= ~(STM32_GCCFG_VBUSBSEN | STM32_GCCFG_VBUSASEN); } } } else if (dwc2->guid < 0x5000) { // the later version uses VBDEN with battery charging detection if (vbus_sensing) { gccfg |= STM32_GCCFG_VBDEN; } else { gccfg &= ~STM32_GCCFG_VBDEN; } } else { // from 0x5000 ST seems to use femtoPHY for UTMI+ HS PHY. Which use VBVALEXTOEN and VBVALOVAL for software override // external VBUS sensing // Note: N6 does not support hardware VBUS sensing, so the software override is always active. Therefore, VBDEN and // VBVALEXTOEN are not available #if CFG_TUSB_MCU == OPT_MCU_STM32N6 if (is_host) { gccfg |= STM32_GCCFG_PULLDOWNEN; gccfg &= ~(STM32_GCCFG_VBVALOVAL); } else { gccfg &= ~STM32_GCCFG_PULLDOWNEN; gccfg |= STM32_GCCFG_VBVALOVAL; } #else if (is_host) { gccfg |= STM32_GCCFG_PULLDOWNEN; gccfg &= ~(STM32_GCCFG_VBDEN | STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); } else { gccfg &= ~STM32_GCCFG_PULLDOWNEN; if (vbus_sensing) { gccfg |= STM32_GCCFG_VBDEN; gccfg &= ~(STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL); } else { gccfg &= ~STM32_GCCFG_VBDEN; gccfg |= STM32_GCCFG_VBVALEXTOEN | STM32_GCCFG_VBVALOVAL; } } #endif } dwc2->stm32_gccfg = gccfg; } //------------- DCache -------------// #if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE typedef struct { uintptr_t start; uintptr_t end; } mem_region_t; // Can be used to define additional uncached regions #ifndef CFG_DWC2_MEM_UNCACHED_REGIONS #define CFG_DWC2_MEM_UNCACHED_REGIONS #endif static mem_region_t uncached_regions[] = { // DTCM (although USB DMA can't transfer to/from DTCM) #if CFG_TUSB_MCU == OPT_MCU_STM32H7 {.start = 0x20000000, .end = 0x2001FFFF}, #elif CFG_TUSB_MCU == OPT_MCU_STM32H7RS // DTCM (although USB DMA can't transfer to/from DTCM) {.start = 0x20000000, .end = 0x2002FFFF}, #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 // DTCM {.start = 0x20000000, .end = 0x2000FFFF}, #elif CFG_TUSB_MCU == OPT_MCU_STM32N6 // DTCM NS {.start = 0x20000000, .end = 0x2003FFFF}, // DTCM S {.start = 0x30000000, .end = 0x3003FFFF}, #else #error "Cache maintenance is not supported yet" #endif CFG_DWC2_MEM_UNCACHED_REGIONS }; TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) { if (size & (CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) { size = (size & ~(CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) + CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT; } return size; } TU_ATTR_ALWAYS_INLINE static inline bool is_cache_mem(uintptr_t addr) { if (0 == (SCB->CCR & SCB_CCR_DC_Msk)) { return false; // D-Cache is disabled } for (unsigned int i = 0; i < TU_ARRAY_SIZE(uncached_regions); i++) { if (uncached_regions[i].start <= addr && addr <= uncached_regions[i].end) { return false; } } return true; } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size); } return true; } TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (is_cache_mem(addr32)) { data_size = round_up_to_cache_line_size(data_size); SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } return true; } #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_type.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024, hathach (tinyusb.org) * * 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. * */ /**

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause */ #ifndef TUSB_DWC2_TYPES_H_ #define TUSB_DWC2_TYPES_H_ #include "stdint.h" #ifdef __cplusplus extern "C" { #endif // Controller typedef struct { uintptr_t reg_base; uint32_t irqnum; uint8_t ep_count; uint8_t ep_in_count; uint32_t ep_fifo_size; }dwc2_controller_t; // DWC OTG HW Release versions #define DWC2_CORE_REV_2_71a 0x4f54271a #define DWC2_CORE_REV_2_72a 0x4f54272a #define DWC2_CORE_REV_2_80a 0x4f54280a #define DWC2_CORE_REV_2_90a 0x4f54290a #define DWC2_CORE_REV_2_91a 0x4f54291a #define DWC2_CORE_REV_2_92a 0x4f54292a #define DWC2_CORE_REV_2_94a 0x4f54294a #define DWC2_CORE_REV_3_00a 0x4f54300a #define DWC2_CORE_REV_3_10a 0x4f54310a #define DWC2_CORE_REV_4_00a 0x4f54400a #define DWC2_CORE_REV_4_11a 0x4f54411a #define DWC2_CORE_REV_4_20a 0x4f54420a #define DWC2_FS_IOT_REV_1_00a 0x5531100a #define DWC2_HS_IOT_REV_1_00a 0x5532100a #define DWC2_CORE_REV_MASK 0x0000ffff // DWC OTG HW Core ID #define DWC2_OTG_ID 0x4f540000 #define DWC2_FS_IOT_ID 0x55310000 #define DWC2_HS_IOT_ID 0x55320000 #if 0 // HS PHY typedef struct { volatile uint32_t HS_PHYC_PLL; // 000h This register is used to control the PLL of the HS PHY. volatile uint32_t Reserved04; // 004h Reserved volatile uint32_t Reserved08; // 008h Reserved volatile uint32_t HS_PHYC_TUNE; // 00Ch This register is used to control the tuning interface of the High Speed PHY. volatile uint32_t Reserved10; // 010h Reserved volatile uint32_t Reserved14; // 014h Reserved volatile uint32_t HS_PHYC_LDO; // 018h This register is used to control the regulator (LDO). } HS_PHYC_GlobalTypeDef; #endif enum { GOTGCTL_OTG_VERSION_1_3 = 0, GOTGCTL_OTG_VERSION_2_0 = 1, }; enum { GUSBCFG_PHYSEL_HIGHSPEED = 0, GUSBCFG_PHYSEL_FULLSPEED = 1, }; enum { GUSBCFG_PHYHS_UTMI = 0, GUSBCFG_PHYHS_ULPI = 1, }; enum { GHWCFG2_OPMODE_HNP_SRP = 0, GHWCFG2_OPMODE_SRP = 1, GHWCFG2_OPMODE_NON_HNP_NON_SRP = 2, GHWCFG2_OPMODE_SRP_DEVICE = 3, GHWCFFG2_OPMODE_NON_OTG_DEVICE = 4, GHWCFG2_OPMODE_SRP_HOST = 5, GHWCFG2_OPMODE_NON_OTG_HOST = 6, }; enum { GHWCFG2_ARCH_SLAVE_ONLY = 0, GHWCFG2_ARCH_EXTERNAL_DMA = 1, GHWCFG2_ARCH_INTERNAL_DMA = 2, }; enum { GHWCFG2_HSPHY_NOT_SUPPORTED = 0, GHWCFG2_HSPHY_UTMI = 1, // internal PHY (mostly) GHWCFG2_HSPHY_ULPI = 2, // external PHY (mostly) GHWCFG2_HSPHY_UTMI_ULPI = 3, // both }; enum { GHWCFG2_FSPHY_NOT_SUPPORTED = 0, GHWCFG2_FSPHY_DEDICATED = 1, // have dedicated FS PHY GHWCFG2_FSPHY_UTMI = 2, // shared with UTMI+ GHWCFG2_FSPHY_ULPI = 3, // shared with ULPI }; enum { GHWCFFG4_PHY_DATA_WIDTH_8 = 0, GHWCFFG4_PHY_DATA_WIDTH_16 = 1, GHWCFFG4_PHY_DATA_WIDTH_8_16 = 2, // software selectable }; enum { HPRT_SPEED_HIGH = 0, HPRT_SPEED_FULL = 1, HPRT_SPEED_LOW = 2 }; enum { GINTSTS_CMODE_DEVICE = 0, GINTSTS_CMODE_HOST = 1, }; enum { HCTSIZ_PID_DATA0 = 0, // 00b HCTSIZ_PID_DATA2 = 1, // 01b HCTSIZ_PID_DATA1 = 2, // 10b HCTSIZ_PID_SETUP = 3, // 11b }; enum { HCTSIZ_PID_MDATA = 3, }; enum { GRXSTS_PKTSTS_GLOBAL_OUT_NAK = 1, GRXSTS_PKTSTS_RX_DATA = 2, GRXSTS_PKTSTS_RX_COMPLETE = 3, GRXSTS_PKTSTS_SETUP_DONE = 4, GRXSTS_PKTSTS_HOST_DATATOGGLE_ERR = 5, GRXSTS_PKTSTS_SETUP_RX = 6, GRXSTS_PKTSTS_HOST_CHANNEL_HALTED = 7 }; // Same as TUSB_XFER_* enum { HCCHAR_EPTYPE_CONTROL = 0, HCCHAR_EPTYPE_ISOCHRONOUS = 1, HCCHAR_EPTYPE_BULK = 2, HCCHAR_EPTYPE_INTERRUPT = 3 }; enum { DCFG_SPEED_HIGH = 0, // Highspeed with 30/60 Mhz DCFG_SPEED_FULL_30_60MHZ = 1, // Fullspeed with UTMI+/ULPI 30/60 Mhz DCFG_SPEED_LOW = 2, // Lowspeed with FS PHY at 6 Mhz DCFG_SPEED_FULL_48MHZ = 3, // Fullspeed with dedicated FS PHY at 48 Mhz }; // Same as TUSB_XFER_* enum { DEPCTL_EPTYPE_CONTROL = 0, DEPCTL_EPTYPE_ISOCHRONOUS = 1, DEPCTL_EPTYPE_BULK = 2, DEPCTL_EPTYPE_INTERRUPT = 3 }; //-------------------------------------------------------------------- // Common Register Bitfield //-------------------------------------------------------------------- typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t ses_req_scs : 1; // 0 Session request success uint32_t ses_req : 1; // 1 Session request uint32_t vbval_ov_en : 1; // 2 VBUS valid override enable uint32_t vbval_ov_val : 1; // 3 VBUS valid override value uint32_t aval_ov_en : 1; // 4 A-peripheral session valid override enable uint32_t aval_ov_al : 1; // 5 A-peripheral session valid override value uint32_t bval_ov_en : 1; // 6 B-peripheral session valid override enable uint32_t bval_ov_val : 1; // 7 B-peripheral session valid override value uint32_t hng_scs : 1; // 8 Host negotiation success uint32_t hnp_rq : 1; // 9 HNP (host negotiation protocol) request uint32_t host_set_hnp_en : 1; // 10 Host set HNP enable uint32_t dev_hnp_en : 1; // 11 Device HNP enabled uint32_t embedded_host_en : 1; // 12 Embedded host enable uint32_t rsv13_14 : 2; // 13.14 Reserved uint32_t dbnc_filter_bypass : 1; // 15 Debounce filter bypass uint32_t cid_status : 1; // 16 Connector ID status uint32_t dbnc_done : 1; // 17 Debounce done uint32_t ases_valid : 1; // 18 A-session valid uint32_t bses_valid : 1; // 19 B-session valid uint32_t otg_ver : 1; // 20 OTG version 0: v1.3, 1: v2.0 uint32_t current_mode : 1; // 21 Current mode of operation. Only from v3.00a uint32_t mult_val_id_bc : 5; // 22..26 Multi-valued input pin ID battery charger uint32_t chirp_en : 1; // 27 Chirp detection enable uint32_t rsv28_30 : 3; // 28.30: Reserved uint32_t test_mode_corr_eusb2 : 1; // 31 Test mode control for eUSB2 PHY }; } dwc2_gotgctl_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgctl_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t rsv0_1 : 2; // 0..1 Reserved uint32_t ses_end_det : 1; // 2 Session end detected uint32_t rsv3_7 : 5; // 3..7 Reserved uint32_t srs_status_change : 1; // 8 Session request success status change uint32_t hns_status_change : 1; // 9 Host negotiation success status change uint32_t rsv10_16 : 7; // 10..16 Reserved uint32_t hng_det : 1; // 17 Host negotiation detected uint32_t adev_timeout_change : 1; // 18 A-device timeout change uint32_t dbnc_done : 1; // 19 Debounce done uint32_t mult_val_lp_change : 1; // 20 Multi-valued input pin change uint32_t rsv21_31 :11; // 21..31 Reserved }; } dwc2_gotgint_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgint_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t gintmask : 1; // 0 Global interrupt mask uint32_t hbst_len : 4; // 1..4 Burst length/type uint32_t dma_en : 1; // 5 DMA enable uint32_t rsv6 : 1; // 6 Reserved uint32_t nptxf_empty_lvl : 1; // 7 Non-periodic Tx FIFO empty level uint32_t ptxf_empty_lvl : 1; // 8 Periodic Tx FIFO empty level uint32_t rsv9_20 : 12; // 9.20: Reserved uint32_t remote_mem_support : 1; // 21 Remote memory support uint32_t notify_all_dma_write : 1; // 22 Notify all DMA writes uint32_t ahb_single : 1; // 23 AHB single uint32_t inv_desc_endian : 1; // 24 Inverse descriptor endian uint32_t rsv25_31 : 7; // 25..31 Reserved }; } dwc2_gahbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gahbcfg_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t timeout_cal : 3; /* 0..2 Timeout calibration. The USB standard timeout value for high-speed operation is 736 to 816 (inclusive) bit times. The USB standard timeout value for full- speed operation is 16 to 18 (inclusive) bit times. The application must program this field based on the speed of enumeration. The number of bit times added per PHY clock are as follows: - High-speed: PHY clock One 30-MHz = 16 bit times, One 60-MHz = 8 bit times - Full-speed: PHY clock One 30-MHz = 0.4 bit times, One 60-MHz = 0.2 bit times, One 48-MHz = 0.25 bit times */ uint32_t phy_if16 : 1; // 3 PHY interface. 0: 8 bits, 1: 16 bits uint32_t ulpi_utmi_sel : 1; // 4 ULPI/UTMI select. 0: UTMI+, 1: ULPI uint32_t fs_intf_sel : 1; // 5 Fullspeed serial interface select. 0: 6-pin, 1: 3-pin uint32_t phy_sel : 1; // 6 HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit uint32_t srp_capable : 1; // 8 SRP-capable uint32_t hnp_capable : 1; // 9 HNP-capable uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ uint32_t rsv14 : 1; // 14 Reserved uint32_t phy_low_power_clk_sel : 1; /* 15 PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. In FS/LS modes, the PHY can usually operate on a 48-MHz clock to save power. This bit is valid only for UTMI+ PHYs. - 0: 480 Mhz internal PLL: the UTMI interface operates at either 60 MHz (8 bit) or 30 MHz (16-bit) - 1 48 Mhz external clock: the UTMI interface operates at 48 MHz in FS mode and at either 48 or 6 MHz in LS mode */ uint32_t otg_i2c_sel : 1; // 16 OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals uint32_t ulpi_fsls : 1; /* 17 ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. valid only when the FS serial transceiver is selected on the ULPI PHY. */ uint32_t ulpi_auto_resume : 1; // 18 ULPI Auto-resume uint32_t ulpi_clk_sus_m : 1; // 19 ULPI Clock SuspendM uint32_t ulpi_ext_vbus_drv : 1; // 20 ULPI External VBUS Drive uint32_t ulpi_int_vbus_indicator : 1; // 21 ULPI Internal VBUS Indicator uint32_t term_sel_dl_pulse : 1; // 22 TermSel DLine pulsing uint32_t indicator_complement : 1; // 23 Indicator complement uint32_t indicator_pass_through : 1; // 24 Indicator pass through uint32_t ulpi_if_protect_disable : 1; // 25 ULPI interface protect disable uint32_t ic_usb_capable : 1; // 26 IC_USB Capable uint32_t ic_usb_traf_ctl : 1; // 27 IC_USB Traffic Control uint32_t tx_end_delay : 1; // 28 TX end delay uint32_t force_host_mode : 1; // 29 Force host mode uint32_t force_dev_mode : 1; // 30 Force device mode uint32_t corrupt_tx_pkt : 1; // 31 Corrupt Tx packet. 0: normal, 1: debug }; } dwc2_gusbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gusbcfg_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t core_soft_rst : 1; // 0 Core Soft Reset uint32_t piufs_soft_rst : 1; // 1 PIU FS Dedicated Controller Soft Reset uint32_t frame_counter_rst : 1; // 2 Frame Counter Reset (host) uint32_t intoken_q_flush : 1; // 3 IN Token Queue Flush uint32_t rx_fifo_flush : 1; // 4 RX FIFO Flush uint32_t tx_fifo_flush : 1; // 5 TX FIFO Flush uint32_t tx_fifo_num : 5; // 6..10 TX FIFO Number uint32_t rsv11_28 :18; // 11..28 Reserved uint32_t core_soft_rst_done : 1; // 29 Core Soft Reset Done, from v4.20a uint32_t dma_req : 1; // 30 DMA Request uint32_t ahb_idle : 1; // 31 AHB Idle }; } dwc2_grstctl_t; TU_VERIFY_STATIC(sizeof(dwc2_grstctl_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t ep_ch_num : 4; // 0..3 Endpoint/Channel Number uint32_t byte_count :11; // 4..14 Byte Count uint32_t dpid : 2; // 15..16 Data PID uint32_t packet_status : 4; // 17..20 Packet Status uint32_t frame_number : 4; // 21..24 Frame Number uint32_t rsv25_31 : 7; // 25..31 Reserved }; } dwc2_grxstsp_t; TU_VERIFY_STATIC(sizeof(dwc2_grxstsp_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0..2 HNP/SRP Host/Device/OTG mode uint32_t arch : 2; // 3..4 Slave/External/Internal DMA uint32_t single_point : 1; // 5 0: support hub and split | 1: no hub, no split uint32_t hs_phy_type : 2; // 6..7 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI uint32_t fs_phy_type : 2; // 8..9 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI uint32_t num_dev_ep : 4; // 10..13 Number of device endpoints (excluding EP0) uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control) uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled uint32_t mul_proc_intrpt : 1; // 20 Multi-Processor Interrupt enabled (OTG_MULTI_PROC_INTRPT) uint32_t reserved21 : 1; // 21 reserved uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 uint32_t token_q_depth : 5; // 26..30 Device IN token sequence learning queue depth: 0-30 uint32_t otg_enable_ic_usb : 1; // 31 IC_USB mode specified for mode of operation }; } dwc2_ghwcfg2_t; TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t xfer_size_width : 4; // 0..3 Transfer size counter in bits = 11 + n (max 19 bits) uint32_t packet_size_width : 3; // 4..6 Packet size counter in bits = 4 + n (max 10 bits) uint32_t otg_enable : 1; // 7 OTG capable uint32_t i2c_enable : 1; // 8 I2C interface is available uint32_t vendor_ctrl_itf : 1; // 9 Vendor control interface is available uint32_t optional_feature_removed : 1; // 10 remove User ID, GPIO, SOF toggle & counter to save gate count uint32_t synch_reset : 1; // 11 0: async reset | 1: synch reset uint32_t otg_adp_support : 1; // 12 ADP logic is present along with HSOTG controller uint32_t otg_enable_hsic : 1; // 13 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC uint32_t battery_charger_support : 1; // s14 upport battery charger uint32_t lpm_mode : 1; // 15 LPM mode uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words }; } dwc2_ghwcfg3_t; TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t num_dev_period_in_ep : 4; // 0..3 Number of Device Periodic IN Endpoints uint32_t partial_powerdown : 1; // 4 Partial Power Down Enabled uint32_t ahb_freq_min : 1; // 5 1: minimum of AHB frequency is less than 60 MHz uint32_t hibernation : 1; // 6 Hibernation feature is enabled uint32_t extended_hibernation : 1; // 7 Extended Hibernation feature is enabled uint32_t reserved8 : 1; // 8 Reserved uint32_t enhanced_lpm_support1 : 1; // 9 Enhanced LPM Support1 uint32_t service_interval_flow : 1; // 10 Service Interval flow is supported uint32_t ipg_isoc_support : 1; // 11 Interpacket GAP ISO OUT worst-case is supported uint32_t acg_support : 1; // 12 Active clock gating is supported uint32_t enhanced_lpm_support : 1; // 13 Enhanced LPM Support uint32_t phy_data_width : 2; // 14..15 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable uint32_t ctrl_ep_num : 4; // 16..19 Number of Device control endpoints in addition to EP0 uint32_t iddg_filter : 1; // 20 IDDG Filter Enabled uint32_t vbus_valid_filter : 1; // 21 VBUS Valid Filter Enabled uint32_t a_valid_filter : 1; // 22 A Valid Filter Enabled uint32_t b_valid_filter : 1; // 23 B Valid Filter Enabled uint32_t session_end_filter : 1; // 24 Session End Filter Enabled uint32_t dedicated_fifos : 1; // 25 Dedicated tx fifo for device IN Endpoint uint32_t num_dev_in_eps : 4; // 26..29 Number of Device IN Endpoints including EP0 uint32_t dma_desc_enabled : 1; // scatter/gather DMA configuration enabled uint32_t dma_desc_dynamic : 1; // Dynamic scatter/gather DMA }; } dwc2_ghwcfg4_t; TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t fifo_available : 16; // 0..15 Number of words available in the Tx FIFO uint32_t req_queue_available : 8; // 16..23 Number of spaces available in the NPT transmit request queue for both IN and OU // 24..31 is top entry in the request queue that is currently being processed by the MAC uint32_t qtop_terminate : 1; // 24 Last entry for selected channel uint32_t qtop_type : 2; // 25..26 Token (0) In/Out (1) ZLP, (2) Ping/cspit, (3) Channel halt command uint32_t qtop_ch_num : 4; // 27..30 Channel number }; } dwc2_hnptxsts_t; TU_VERIFY_STATIC(sizeof(dwc2_hnptxsts_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t fifo_available :16; // 0..15 Number of words available in the Tx FIFO uint32_t req_queue_available : 7; // 16..22 Number of spaces available in the PTX transmit request queue uint32_t qtop_terminate : 1; // 23 Last entry for selected channel uint32_t qtop_last_period : 1; // 24 Last entry for selected channel is a periodic entry uint32_t qtop_type : 2; // 25..26 Token (0) In/Out (1) ZLP, (2) Ping/cspit, (3) Channel halt command uint32_t qtop_ch_num : 4; // 27..30 Channel number uint32_t qtop_odd_frame : 1; // 31 Send in odd frame }; } dwc2_hptxsts_t; TU_VERIFY_STATIC(sizeof(dwc2_hptxsts_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t conn_status : 1; // 0 Port connect status uint32_t conn_detected : 1; // 1 Port connect detected uint32_t enable : 1; // 2 Port enable status uint32_t enable_change : 1; // 3 Port enable change uint32_t over_current_active : 1; // 4 Port Over-current active uint32_t over_current_change : 1; // 5 Port Over-current change uint32_t resume : 1; // 6 Port resume uint32_t suspend : 1; // 7 Port suspend uint32_t reset : 1; // 8 Port reset uint32_t rsv9 : 1; // 9 Reserved uint32_t line_status : 2; // 10..11 Line status uint32_t power : 1; // 12 Port power uint32_t test_control : 4; // 13..16 Port Test control uint32_t speed : 2; // 17..18 Port speed uint32_t rsv19_31 :13; // 19..31 Reserved }; } dwc2_hprt_t; TU_VERIFY_STATIC(sizeof(dwc2_hprt_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t ep_size : 11; // 0..10 Maximum packet size uint32_t ep_num : 4; // 11..14 Endpoint number uint32_t ep_dir : 1; // 15 Endpoint direction uint32_t rsv16 : 1; // 16 Reserved uint32_t low_speed_dev : 1; // 17 Low-speed device uint32_t ep_type : 2; // 18..19 Endpoint type uint32_t err_multi_count : 2; // 20..21 Error (splitEn = 1) / Multi (SplitEn = 0) count uint32_t dev_addr : 7; // 22..28 Device address uint32_t odd_frame : 1; // 29 Odd frame uint32_t disable : 1; // 30 Channel disable uint32_t enable : 1; // 31 Channel enable }; } dwc2_channel_char_t; TU_VERIFY_STATIC(sizeof(dwc2_channel_char_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t hub_port : 7; // 0..6 Hub port number uint32_t hub_addr : 7; // 7..13 Hub address uint32_t xact_pos : 2; // 14..15 Transaction position uint32_t split_compl : 1; // 16 Split completion uint32_t rsv17_30 : 14; // 17..30 Reserved uint32_t split_en : 1; // 31 Split enable }; } dwc2_channel_split_t; TU_VERIFY_STATIC(sizeof(dwc2_channel_split_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t xfer_size : 19; // 0..18 Transfer size in bytes uint32_t packet_count : 10; // 19..28 Number of packets uint32_t pid : 2; // 29..30 Packet ID uint32_t do_ping : 1; // 31 Do PING }; } dwc2_channel_tsize_t; TU_VERIFY_STATIC(sizeof(dwc2_channel_tsize_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t num : 16; // 0..15 Frame number uint32_t remainning : 16; // 16..31 Frame remaining }; } dwc2_hfnum_t; TU_VERIFY_STATIC(sizeof(dwc2_hfnum_t) == 4, "incorrect size"); // Host Channel typedef struct { volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt volatile uint32_t hcintmsk; // 50C + 20*ch Host Channel Interrupt Mask volatile uint32_t hctsiz; // 510 + 20*ch Host Channel Transfer Size volatile uint32_t hcdma; // 514 + 20*ch Host Channel DMA Address uint32_t reserved518; // 518 + 20*ch volatile uint32_t hcdmab; // 51C + 20*ch Host Channel DMA Address } dwc2_channel_t; //-------------------------------------------------------------------- // Device Register Bitfield //-------------------------------------------------------------------- typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t speed : 2; // 0..1 Speed uint32_t nzsts_out_handshake : 1; // 2 Non-zero-length status OUT handshake uint32_t en_32khz_suspsend : 1; // 3 Enable 32-kHz SUSPEND mode uint32_t address : 7; // 4..10 Device address uint32_t period_frame_interval : 2; // 11..12 Periodic frame interval uint32_t en_out_nak : 1; // 13 Enable Device OUT NAK uint32_t xcvr_delay : 1; // 14 Transceiver delay uint32_t erratic_int_mask : 1; // 15 Erratic interrupt mask uint32_t rsv16 : 1; // 16 Reserved uint32_t ipg_iso_support : 1; // 17 Interpacket gap ISO support uint32_t epin_mismatch_count : 5; // 18..22 EP IN mismatch count uint32_t dma_desc : 1; // 23 Enable scatter/gather DMA descriptor uint32_t period_schedule_interval : 2; // 24..25 Periodic schedule interval for scatter/gather DMA uint32_t resume_valid : 6; // 26..31 Resume valid period }; } dwc2_dcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_dcfg_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t remote_wakeup_signal : 1; // 0 Remote wakeup signal uint32_t soft_disconnet : 1; // 1 Soft disconnect uint32_t gnp_in_nak_status : 1; // 2 Global non-periodic NAK IN status uint32_t gout_nak_status : 1; // 3 Global OUT NAK status uint32_t test_control : 3; // 4..6 Test control uint32_t set_gnp_in_nak : 1; // 7 Set global non-periodic IN NAK uint32_t clear_gnp_in_nak : 1; // 8 Clear global non-periodic IN NAK uint32_t set_gout_nak : 1; // 9 Set global OUT NAK uint32_t clear_gout_nak : 1; // 10 Clear global OUT NAK uint32_t poweron_prog_done : 1; // 11 Power-on programming done uint32_t rsv12 : 1; // 12 Reserved uint32_t global_multi_count : 2; // 13..14 Global multi-count uint32_t ignore_frame_number : 1; // 15 Ignore frame number uint32_t nak_on_babble : 1; // 16 NAK on babble uint32_t en_cont_on_bna : 1; // 17 Enable continue on BNA uint32_t deep_sleep_besl_reject : 1; // 18 Deep sleep BESL reject uint32_t service_interval : 1; // 19 Service interval for ISO IN endpoint uint32_t rsv20_31 :12; // 20..31 Reserved }; } dwc2_dctl_t; TU_VERIFY_STATIC(sizeof(dwc2_dctl_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t suspend_status : 1; // 0 Suspend status uint32_t enum_speed : 2; // 1..2 Enumerated speed uint32_t erratic_err : 1; // 3 Erratic error uint32_t rsv4_7 : 4; // 4..7 Reserved uint32_t frame_number :14; // 8..21 Frame/MicroFrame number uint32_t line_status : 2; // 22..23 Line status uint32_t rsv24_31 : 8; // 24..31 Reserved }; } dwc2_dsts_t; TU_VERIFY_STATIC(sizeof(dwc2_dsts_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t xfer_complete : 1; // 0 Transfer complete uint32_t disabled : 1; // 1 Endpoint disabled uint32_t ahb_err : 1; // 2 AHB error uint32_t timeout : 1; // 3 Timeout uint32_t in_rx_txfe : 1; // 4 IN token received when TxFIFO is empty uint32_t in_rx_ep_mismatch : 1; // 5 IN token received with EP mismatch uint32_t in_ep_nak_effective : 1; // 6 IN endpoint NAK effective uint32_t txfifo_empty : 1; // 7 TX FIFO empty uint32_t txfifo_underrun : 1; // 8 Tx FIFO under run uint32_t bna : 1; // 9 Buffer not available uint32_t rsv10 : 1; // 10 Reserved uint32_t iso_packet_drop : 1; // 11 Isochronous OUT packet drop status uint32_t babble_err : 1; // 12 Babble error uint32_t nak : 1; // 13 NAK uint32_t nyet : 1; // 14 NYET uint32_t rsv14_31 :17; // 15..31 Reserved }; } dwc2_diepint_t; TU_VERIFY_STATIC(sizeof(dwc2_diepint_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t mps : 11; // 0..10 Maximum packet size, EP0 only use 2 bits uint32_t next_ep : 4; // 11..14 Next endpoint number uint32_t active : 1; // 15 Active uint32_t dpid_iso_odd : 1; // 16 DATA0/DATA1 for bulk/interrupt, odd frame for isochronous uint32_t nak_status : 1; // 17 NAK status uint32_t type : 2; // 18..19 Endpoint type uint32_t rsv20 : 1; // 20 Reserved uint32_t stall : 1; // 21 Stall uint32_t tx_fifo_num : 4; // 22..25 Tx FIFO number (IN) uint32_t clear_nak : 1; // 26 Clear NAK uint32_t set_nak : 1; // 27 Set NAK uint32_t set_data0_iso_even : 1; // 28 Set DATA0 if bulk/interrupt, even frame for isochronous uint32_t set_data1_iso_odd : 1; // 29 Set DATA1 if bulk/interrupt, odd frame for isochronous uint32_t disable : 1; // 30 Disable uint32_t enable : 1; // 31 Enable }; } dwc2_depctl_t; TU_VERIFY_STATIC(sizeof(dwc2_depctl_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t xfer_complete : 1; // 0 Transfer complete uint32_t disabled : 1; // 1 Endpoint disabled uint32_t ahb_err : 1; // 2 AHB error uint32_t setup_phase_done : 1; // 3 Setup phase done uint32_t out_rx_ep_disabled : 1; // 4 OUT token received when endpoint disabled uint32_t status_phase_rx : 1; // 5 Status phase received uint32_t setup_b2b : 1; // 6 Setup packet back-to-back uint32_t rsv7 : 1; // 7 Reserved uint32_t out_packet_err : 1; // 8 OUT packet error uint32_t bna : 1; // 9 Buffer not available uint32_t rsv10 : 1; // 10 Reserved uint32_t iso_packet_drop : 1; // 11 Isochronous OUT packet drop status uint32_t babble_err : 1; // 12 Babble error uint32_t nak : 1; // 13 NAK uint32_t nyet : 1; // 14 NYET uint32_t setup_packet_rx : 1; // 15 Setup packet received (Buffer DMA Mode only) uint32_t rsv16_31 :16; // 16..31 Reserved }; } dwc2_doepint_t; TU_VERIFY_STATIC(sizeof(dwc2_doepint_t) == 4, "incorrect size"); typedef union { uint32_t value; struct TU_ATTR_PACKED { uint32_t xfer_size : 19; // 0..18 Transfer size in bytes uint32_t packet_count : 10; // 19..28 Number of packets uint32_t mc_pid : 2; // 29..30 IN: Multi Count, OUT: PID }; } dwc2_ep_tsize_t; TU_VERIFY_STATIC(sizeof(dwc2_ep_tsize_t) == 4, "incorrect size"); // Device IN/OUT Endpoint typedef struct { union { volatile uint32_t diepctl; volatile uint32_t doepctl; volatile uint32_t ctl; }; uint32_t rsv04; union { volatile uint32_t intr; volatile uint32_t diepint; volatile uint32_t doepint; }; uint32_t rsv0c; union { volatile uint32_t dieptsiz; volatile uint32_t doeptsiz; volatile uint32_t tsiz; }; union { volatile uint32_t diepdma; volatile uint32_t doepdma; }; volatile uint32_t dtxfsts; uint32_t rsv1c; } dwc2_dep_t; TU_VERIFY_STATIC(sizeof(dwc2_dep_t) == 0x20, "incorrect size"); //-------------------------------------------------------------------- // CSR Register Map //-------------------------------------------------------------------- typedef struct { //------------- Core Global ------------- volatile uint32_t gotgctl; // 000 OTG Control and Status volatile uint32_t gotgint; // 004 OTG Interrupt volatile uint32_t gahbcfg; // 008 AHB Configuration volatile uint32_t gusbcfg; // 00c USB Configuration volatile uint32_t grstctl; // 010 Reset volatile uint32_t gintsts; // 014 Interrupt volatile uint32_t gintmsk; // 018 Interrupt Mask volatile uint32_t grxstsr; // 01c Receive Status Debug Read volatile uint32_t grxstsp; // 020 Receive Status Read/Pop volatile uint32_t grxfsiz; // 024 Receive FIFO Size union { volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size }; union { volatile uint32_t hnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status volatile uint32_t gnptxsts; }; volatile uint32_t gi2cctl; // 030 I2C Address volatile uint32_t gpvndctl; // 034 PHY Vendor Control union { volatile uint32_t ggpio; // 038 General Purpose IO volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration }; volatile uint32_t guid; // 03C User (Application programmable) ID volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 union { volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 volatile dwc2_ghwcfg4_t ghwcfg4_bm; }; volatile uint32_t glpmcfg; // 054 Core LPM Configuration volatile uint32_t gpwrdn; // 058 Power Down volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status uint32_t reserved64[39]; // 064..0FF volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size uint32_t reserved140[176]; // 140..3FF //------------ Host ------------- volatile uint32_t hcfg; // 400 Host Configuration volatile uint32_t hfir; // 404 Host Frame Interval volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining uint32_t reserved40c; // 40C volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status volatile uint32_t haint; // 414 Host All Channels Interrupt volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask volatile uint32_t hflbaddr; // 41C Host Frame List Base Address uint32_t reserved420[8]; // 420..43F volatile uint32_t hprt; // 440 Host Port Control and Status uint32_t reserved444[47]; // 444..4FF //------------- Host Channel -------- dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 uint32_t reserved700[64]; // 700..7FF //------------- Device ----------- volatile uint32_t dcfg; // 800 Device Configuration volatile uint32_t dctl; // 804 Device Control volatile uint32_t dsts; // 808 Device Status (RO) uint32_t reserved80c; // 80C volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask volatile uint32_t daint; // 818 Device All Endpoints Interrupt volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time volatile uint32_t dthrctl; // 830 Device threshold Control volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask // Device Each Endpoint (IN/OUT) Interrupt/Mask for generating dedicated EP interrupt line require // OTG_MULTI_PROC_INTRPT=1 volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt mask volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask uint32_t reserved8c0[16]; // 8C0..8FF //------------- Device Endpoint ----- union { dwc2_dep_t ep[2][16]; // 0: IN, 1 OUT struct { dwc2_dep_t epin[16]; // 900..AFF IN Endpoints dwc2_dep_t epout[16]; // B00..CFF OUT Endpoints }; }; uint32_t reservedd00[64]; // D00..DFF //------------- Power Clock --------- volatile uint32_t pcgcctl; // E00 Power and Clock Gating Characteristic Control volatile uint32_t pcgcctl1; // E04 Power and Clock Gating Characteristic Control 1 uint32_t reservede08[126]; // E08..FFF //------------- FIFOs ------------- // Word-accessed only using first pointer since it auto shift volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO } dwc2_regs_t; TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x0400, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, channel) == 0x0500, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, dcfg ) == 0x0800, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epin ) == 0x0900, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epout ) == 0x0B00, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, pcgcctl) == 0x0E00, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); //--------------------------------------------------------------------+ // Register Bit Definitions //--------------------------------------------------------------------+ /******************** Bit definition for GOTGCTL register ********************/ #define GOTGCTL_SRQSCS_Pos (0U) #define GOTGCTL_SRQSCS_Msk (0x1UL << GOTGCTL_SRQSCS_Pos) // 0x00000001 #define GOTGCTL_SRQSCS GOTGCTL_SRQSCS_Msk // Session request success #define GOTGCTL_SRQ_Pos (1U) #define GOTGCTL_SRQ_Msk (0x1UL << GOTGCTL_SRQ_Pos) // 0x00000002 #define GOTGCTL_SRQ GOTGCTL_SRQ_Msk // Session request #define GOTGCTL_VBVALOEN_Pos (2U) #define GOTGCTL_VBVALOEN_Msk (0x1UL << GOTGCTL_VBVALOEN_Pos) // 0x00000004 #define GOTGCTL_VBVALOEN GOTGCTL_VBVALOEN_Msk // VBUS valid override enable #define GOTGCTL_VBVALOVAL_Pos (3U) #define GOTGCTL_VBVALOVAL_Msk (0x1UL << GOTGCTL_VBVALOVAL_Pos) // 0x00000008 #define GOTGCTL_VBVALOVAL GOTGCTL_VBVALOVAL_Msk // VBUS valid override value #define GOTGCTL_AVALOEN_Pos (4U) #define GOTGCTL_AVALOEN_Msk (0x1UL << GOTGCTL_AVALOEN_Pos) // 0x00000010 #define GOTGCTL_AVALOEN GOTGCTL_AVALOEN_Msk // A-peripheral session valid override enable #define GOTGCTL_AVALOVAL_Pos (5U) #define GOTGCTL_AVALOVAL_Msk (0x1UL << GOTGCTL_AVALOVAL_Pos) // 0x00000020 #define GOTGCTL_AVALOVAL GOTGCTL_AVALOVAL_Msk // A-peripheral session valid override value #define GOTGCTL_BVALOEN_Pos (6U) #define GOTGCTL_BVALOEN_Msk (0x1UL << GOTGCTL_BVALOEN_Pos) // 0x00000040 #define GOTGCTL_BVALOEN GOTGCTL_BVALOEN_Msk // B-peripheral session valid override enable #define GOTGCTL_BVALOVAL_Pos (7U) #define GOTGCTL_BVALOVAL_Msk (0x1UL << GOTGCTL_BVALOVAL_Pos) // 0x00000080 #define GOTGCTL_BVALOVAL GOTGCTL_BVALOVAL_Msk // B-peripheral session valid override value #define GOTGCTL_HNGSCS_Pos (8U) #define GOTGCTL_HNGSCS_Msk (0x1UL << GOTGCTL_HNGSCS_Pos) // 0x00000100 #define GOTGCTL_HNGSCS GOTGCTL_HNGSCS_Msk // Host set HNP enable #define GOTGCTL_HNPRQ_Pos (9U) #define GOTGCTL_HNPRQ_Msk (0x1UL << GOTGCTL_HNPRQ_Pos) // 0x00000200 #define GOTGCTL_HNPRQ GOTGCTL_HNPRQ_Msk // HNP request #define GOTGCTL_HSHNPEN_Pos (10U) #define GOTGCTL_HSHNPEN_Msk (0x1UL << GOTGCTL_HSHNPEN_Pos) // 0x00000400 #define GOTGCTL_HSHNPEN GOTGCTL_HSHNPEN_Msk // Host set HNP enable #define GOTGCTL_DHNPEN_Pos (11U) #define GOTGCTL_DHNPEN_Msk (0x1UL << GOTGCTL_DHNPEN_Pos) // 0x00000800 #define GOTGCTL_DHNPEN GOTGCTL_DHNPEN_Msk // Device HNP enabled #define GOTGCTL_EHEN_Pos (12U) #define GOTGCTL_EHEN_Msk (0x1UL << GOTGCTL_EHEN_Pos) // 0x00001000 #define GOTGCTL_EHEN GOTGCTL_EHEN_Msk // Embedded host enable #define GOTGCTL_CIDSTS_Pos (16U) #define GOTGCTL_CIDSTS_Msk (0x1UL << GOTGCTL_CIDSTS_Pos) // 0x00010000 #define GOTGCTL_CIDSTS GOTGCTL_CIDSTS_Msk // Connector ID status #define GOTGCTL_DBCT_Pos (17U) #define GOTGCTL_DBCT_Msk (0x1UL << GOTGCTL_DBCT_Pos) // 0x00020000 #define GOTGCTL_DBCT GOTGCTL_DBCT_Msk // Long/short debounce time #define GOTGCTL_ASVLD_Pos (18U) #define GOTGCTL_ASVLD_Msk (0x1UL << GOTGCTL_ASVLD_Pos) // 0x00040000 #define GOTGCTL_ASVLD GOTGCTL_ASVLD_Msk // A-session valid #define GOTGCTL_BSESVLD_Pos (19U) #define GOTGCTL_BSESVLD_Msk (0x1UL << GOTGCTL_BSESVLD_Pos) // 0x00080000 #define GOTGCTL_BSESVLD GOTGCTL_BSESVLD_Msk // B-session valid #define GOTGCTL_OTGVER_Pos (20U) #define GOTGCTL_OTGVER_Msk (0x1UL << GOTGCTL_OTGVER_Pos) // 0x00100000 #define GOTGCTL_OTGVER GOTGCTL_OTGVER_Msk // OTG version /******************** Bit definition for HCFG register ********************/ #define HCFG_FSLS_PHYCLK_SEL_Pos (0U) #define HCFG_FSLS_PHYCLK_SEL_Msk (0x3UL << HCFG_FSLS_PHYCLK_SEL_Pos) // 0x00000003 #define HCFG_FSLS_PHYCLK_SEL HCFG_FSLS_PHYCLK_SEL_Msk // FS/LS PHY clock select #define HCFG_FSLS_PHYCLK_SEL_30_60MHZ (0x0UL << HCFG_FSLS_PHYCLK_SEL_Pos) // 0x00000000 #define HCFG_FSLS_PHYCLK_SEL_48MHZ (0x1UL << HCFG_FSLS_PHYCLK_SEL_Pos) // 0x00000001 #define HCFG_FSLS_PHYCLK_SEL_6MHZ (0x2UL << HCFG_FSLS_PHYCLK_SEL_Pos) // 0x00000002 #define HCFG_FSLS_ONLY_Pos (2U) #define HCFG_FSLS_ONLY_Msk (0x1UL << HCFG_FSLS_ONLY_Pos) // 0x00000004 #define HCFG_FSLS_ONLY HCFG_FSLS_ONLY_Msk // FS- and LS-only support /******************** Bit definition for PCGCR register ********************/ #define PCGCR_STPPCLK_Pos (0U) #define PCGCR_STPPCLK_Msk (0x1UL << PCGCR_STPPCLK_Pos) // 0x00000001 #define PCGCR_STPPCLK PCGCR_STPPCLK_Msk // Stop PHY clock #define PCGCR_GATEHCLK_Pos (1U) #define PCGCR_GATEHCLK_Msk (0x1UL << PCGCR_GATEHCLK_Pos) // 0x00000002 #define PCGCR_GATEHCLK PCGCR_GATEHCLK_Msk // Gate HCLK #define PCGCR_PHYSUSP_Pos (4U) #define PCGCR_PHYSUSP_Msk (0x1UL << PCGCR_PHYSUSP_Pos) // 0x00000010 #define PCGCR_PHYSUSP PCGCR_PHYSUSP_Msk // PHY suspended /******************** Bit definition for GOTGINT register ********************/ #define GOTGINT_SEDET_Pos (2U) #define GOTGINT_SEDET_Msk (0x1UL << GOTGINT_SEDET_Pos) // 0x00000004 #define GOTGINT_SEDET GOTGINT_SEDET_Msk // Session end detected #define GOTGINT_SRSSCHG_Pos (8U) #define GOTGINT_SRSSCHG_Msk (0x1UL << GOTGINT_SRSSCHG_Pos) // 0x00000100 #define GOTGINT_SRSSCHG GOTGINT_SRSSCHG_Msk // Session request success status change #define GOTGINT_HNSSCHG_Pos (9U) #define GOTGINT_HNSSCHG_Msk (0x1UL << GOTGINT_HNSSCHG_Pos) // 0x00000200 #define GOTGINT_HNSSCHG GOTGINT_HNSSCHG_Msk // Host negotiation success status change #define GOTGINT_HNGDET_Pos (17U) #define GOTGINT_HNGDET_Msk (0x1UL << GOTGINT_HNGDET_Pos) // 0x00020000 #define GOTGINT_HNGDET GOTGINT_HNGDET_Msk // Host negotiation detected #define GOTGINT_ADTOCHG_Pos (18U) #define GOTGINT_ADTOCHG_Msk (0x1UL << GOTGINT_ADTOCHG_Pos) // 0x00040000 #define GOTGINT_ADTOCHG GOTGINT_ADTOCHG_Msk // A-device timeout change #define GOTGINT_DBCDNE_Pos (19U) #define GOTGINT_DBCDNE_Msk (0x1UL << GOTGINT_DBCDNE_Pos) // 0x00080000 #define GOTGINT_DBCDNE GOTGINT_DBCDNE_Msk // Debounce done #define GOTGINT_IDCHNG_Pos (20U) #define GOTGINT_IDCHNG_Msk (0x1UL << GOTGINT_IDCHNG_Pos) // 0x00100000 #define GOTGINT_IDCHNG GOTGINT_IDCHNG_Msk // Change in ID pin input value /******************** Bit definition for DCFG register ********************/ #define DCFG_DSPD_Pos (0U) #define DCFG_DSPD_Msk (0x3UL << DCFG_DSPD_Pos) // 0x00000003 #define DCFG_DSPD_HS 0 // Highspeed #define DCFG_DSPD_FS_HSPHY 1 // Fullspeed on HS PHY #define DCFG_DSPD_LS 2 // Lowspeed #define DCFG_DSPD_FS 3 // Fullspeed on FS PHY #define DCFG_NZLSOHSK_Pos (2U) #define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 #define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake #define DCFG_DAD_Pos (4U) #define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 #define DCFG_DAD DCFG_DAD_Msk // Device address #define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 #define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 #define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 #define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 #define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 #define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 #define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 #define DCFG_PFIVL_Pos (11U) #define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 #define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval #define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 #define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 #define DCFG_XCVRDLY_Pos (14U) #define DCFG_XCVRDLY_Msk (0x1UL << DCFG_XCVRDLY_Pos) // 0x00004000 #define DCFG_XCVRDLY DCFG_XCVRDLY_Msk // Enables delay between xcvr_sel and txvalid during device chirp #define DCFG_PERSCHIVL_Pos (24U) #define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 #define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval #define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 #define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 /******************** Bit definition for DCTL register ********************/ #define DCTL_RWUSIG_Pos (0U) #define DCTL_RWUSIG_Msk (0x1UL << DCTL_RWUSIG_Pos) // 0x00000001 #define DCTL_RWUSIG DCTL_RWUSIG_Msk // Remote wakeup signaling #define DCTL_SDIS_Pos (1U) #define DCTL_SDIS_Msk (0x1UL << DCTL_SDIS_Pos) // 0x00000002 #define DCTL_SDIS DCTL_SDIS_Msk // Soft disconnect #define DCTL_GINSTS_Pos (2U) #define DCTL_GINSTS_Msk (0x1UL << DCTL_GINSTS_Pos) // 0x00000004 #define DCTL_GINSTS DCTL_GINSTS_Msk // Global IN NAK status #define DCTL_GONSTS_Pos (3U) #define DCTL_GONSTS_Msk (0x1UL << DCTL_GONSTS_Pos) // 0x00000008 #define DCTL_GONSTS DCTL_GONSTS_Msk // Global OUT NAK status #define DCTL_TCTL_Pos (4U) #define DCTL_TCTL_Msk (0x7UL << DCTL_TCTL_Pos) // 0x00000070 #define DCTL_TCTL DCTL_TCTL_Msk // Test control #define DCTL_TCTL_0 (0x1UL << DCTL_TCTL_Pos) // 0x00000010 #define DCTL_TCTL_1 (0x2UL << DCTL_TCTL_Pos) // 0x00000020 #define DCTL_TCTL_2 (0x4UL << DCTL_TCTL_Pos) // 0x00000040 #define DCTL_SGINAK_Pos (7U) #define DCTL_SGINAK_Msk (0x1UL << DCTL_SGINAK_Pos) // 0x00000080 #define DCTL_SGINAK DCTL_SGINAK_Msk // Set global IN NAK #define DCTL_CGINAK_Pos (8U) #define DCTL_CGINAK_Msk (0x1UL << DCTL_CGINAK_Pos) // 0x00000100 #define DCTL_CGINAK DCTL_CGINAK_Msk // Clear global IN NAK #define DCTL_SGONAK_Pos (9U) #define DCTL_SGONAK_Msk (0x1UL << DCTL_SGONAK_Pos) // 0x00000200 #define DCTL_SGONAK DCTL_SGONAK_Msk // Set global OUT NAK #define DCTL_CGONAK_Pos (10U) #define DCTL_CGONAK_Msk (0x1UL << DCTL_CGONAK_Pos) // 0x00000400 #define DCTL_CGONAK DCTL_CGONAK_Msk // Clear global OUT NAK #define DCTL_POPRGDNE_Pos (11U) #define DCTL_POPRGDNE_Msk (0x1UL << DCTL_POPRGDNE_Pos) // 0x00000800 #define DCTL_POPRGDNE DCTL_POPRGDNE_Msk // Power-on programming done /******************** Bit definition for HFIR register ********************/ #define HFIR_FRIVL_Pos (0U) #define HFIR_FRIVL_Msk (0xFFFFUL << HFIR_FRIVL_Pos) // 0x0000FFFF #define HFIR_FRIVL HFIR_FRIVL_Msk // Frame interval #define HFIR_RELOAD_CTRL_Pos (16U) // available since v2.92a #define HFIR_RELOAD_CTRL_Msk (0x1UL << HFIR_RELOAD_CTRL_Pos) #define HFIR_RELOAD_CTRL HFIR_RELOAD_CTRL_Msk /******************** Bit definition for HFNUM register ********************/ #define HFNUM_FRNUM_Pos (0U) #define HFNUM_FRNUM_Msk (0xFFFFUL << HFNUM_FRNUM_Pos) // 0x0000FFFF #define HFNUM_FRNUM HFNUM_FRNUM_Msk // Frame number #define HFNUM_FTREM_Pos (16U) #define HFNUM_FTREM_Msk (0xFFFFUL << HFNUM_FTREM_Pos) // 0xFFFF0000 #define HFNUM_FTREM HFNUM_FTREM_Msk // Frame time remaining /******************** Bit definition for DSTS register ********************/ #define DSTS_SUSPSTS_Pos (0U) #define DSTS_SUSPSTS_Msk (0x1UL << DSTS_SUSPSTS_Pos) // 0x00000001 #define DSTS_SUSPSTS DSTS_SUSPSTS_Msk // Suspend status #define DSTS_ENUMSPD_Pos (1U) #define DSTS_ENUMSPD_Msk (0x3UL << DSTS_ENUMSPD_Pos) // 0x00000006 #define DSTS_ENUMSPD DSTS_ENUMSPD_Msk // Enumerated speed #define DSTS_ENUMSPD_HS 0 // Highspeed #define DSTS_ENUMSPD_FS_HSPHY 1 // Fullspeed on HS PHY #define DSTS_ENUMSPD_LS 2 // Lowspeed #define DSTS_ENUMSPD_FS 3 // Fullspeed on FS PHY #define DSTS_EERR_Pos (3U) #define DSTS_EERR_Msk (0x1UL << DSTS_EERR_Pos) // 0x00000008 #define DSTS_EERR DSTS_EERR_Msk // Erratic error #define DSTS_FNSOF_Pos (8U) #define DSTS_FNSOF_Msk (0x3FFFUL << DSTS_FNSOF_Pos) // 0x003FFF00 #define DSTS_FNSOF DSTS_FNSOF_Msk // Frame number of the received SOF /******************** Bit definition for GAHBCFG register ********************/ #define GAHBCFG_GINT_Pos (0U) #define GAHBCFG_GINT_Msk (0x1UL << GAHBCFG_GINT_Pos) // 0x00000001 #define GAHBCFG_GINT GAHBCFG_GINT_Msk // Global interrupt mask #define GAHBCFG_HBSTLEN_Pos (1U) #define GAHBCFG_HBSTLEN_Msk (0xFUL << GAHBCFG_HBSTLEN_Pos) // 0x0000001E #define GAHBCFG_HBSTLEN GAHBCFG_HBSTLEN_Msk // Burst length/type #define GAHBCFG_HBSTLEN_0 (0x0UL << GAHBCFG_HBSTLEN_Pos) // Single #define GAHBCFG_HBSTLEN_1 (0x1UL << GAHBCFG_HBSTLEN_Pos) // INCR #define GAHBCFG_HBSTLEN_2 (0x3UL << GAHBCFG_HBSTLEN_Pos) // INCR4 #define GAHBCFG_HBSTLEN_3 (0x5UL << GAHBCFG_HBSTLEN_Pos) // INCR8 #define GAHBCFG_HBSTLEN_4 (0x7UL << GAHBCFG_HBSTLEN_Pos) // INCR16 #define GAHBCFG_DMAEN_Pos (5U) #define GAHBCFG_DMAEN_Msk (0x1UL << GAHBCFG_DMAEN_Pos) // 0x00000020 #define GAHBCFG_DMAEN GAHBCFG_DMAEN_Msk // DMA enable #define GAHBCFG_TX_FIFO_EPMTY_LVL_Pos (7U) #define GAHBCFG_TX_FIFO_EPMTY_LVL_Msk (0x1UL << GAHBCFG_TX_FIFO_EPMTY_LVL_Pos) // 0x00000080 #define GAHBCFG_TX_FIFO_EPMTY_LVL GAHBCFG_TX_FIFO_EPMTY_LVL_Msk // TxFIFO empty level #define GAHBCFG_PTX_FIFO_EPMTY_LVL_Pos (8U) #define GAHBCFG_PTX_FIFO_EPMTY_LVL_Msk (0x1UL << GAHBCFG_PTX_FIFO_EPMTY_LVL_Pos) // 0x00000100 #define GAHBCFG_PTX_FIFO_EPMTY_LVL GAHBCFG_PTX_FIFO_EPMTY_LVL_Msk // Periodic TxFIFO empty level /******************** Bit definition for GUSBCFG register ********************/ #define GUSBCFG_TOCAL_Pos (0U) #define GUSBCFG_TOCAL_Msk (0x7UL << GUSBCFG_TOCAL_Pos) // 0x00000007 #define GUSBCFG_TOCAL GUSBCFG_TOCAL_Msk // HS/FS timeout calibration #define GUSBCFG_PHYIF16_Pos (3U) #define GUSBCFG_PHYIF16_Msk (0x1UL << GUSBCFG_PHYIF16_Pos) // 0x00000008 #define GUSBCFG_PHYIF16 GUSBCFG_PHYIF16_Msk // PHY Interface (PHYIf) #define GUSBCFG_ULPI_UTMI_SEL_Pos (4U) #define GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << GUSBCFG_ULPI_UTMI_SEL_Pos) // 0x00000010 #define GUSBCFG_ULPI_UTMI_SEL GUSBCFG_ULPI_UTMI_SEL_Msk // ULPI or UTMI+ Select (ULPI_UTMI_Sel) #define GUSBCFG_PHYSEL_Pos (6U) #define GUSBCFG_PHYSEL_Msk (0x1UL << GUSBCFG_PHYSEL_Pos) // 0x00000040 #define GUSBCFG_PHYSEL GUSBCFG_PHYSEL_Msk // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select #define GUSBCFG_DDRSEL TU_BIT(7) // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface. #define GUSBCFG_SRPCAP_Pos (8U) #define GUSBCFG_SRPCAP_Msk (0x1UL << GUSBCFG_SRPCAP_Pos) // 0x00000100 #define GUSBCFG_SRPCAP GUSBCFG_SRPCAP_Msk // SRP-capable #define GUSBCFG_HNPCAP_Pos (9U) #define GUSBCFG_HNPCAP_Msk (0x1UL << GUSBCFG_HNPCAP_Pos) // 0x00000200 #define GUSBCFG_HNPCAP GUSBCFG_HNPCAP_Msk // HNP-capable #define GUSBCFG_TRDT_Pos (10U) #define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 #define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time #define GUSBCFG_PHYLPCS_Pos (15U) #define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 #define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select #define GUSBCFG_ULPIFSLS_Pos (17U) #define GUSBCFG_ULPIFSLS_Msk (0x1UL << GUSBCFG_ULPIFSLS_Pos) // 0x00020000 #define GUSBCFG_ULPIFSLS GUSBCFG_ULPIFSLS_Msk // ULPI FS/LS select #define GUSBCFG_ULPIAR_Pos (18U) #define GUSBCFG_ULPIAR_Msk (0x1UL << GUSBCFG_ULPIAR_Pos) // 0x00040000 #define GUSBCFG_ULPIAR GUSBCFG_ULPIAR_Msk // ULPI Auto-resume #define GUSBCFG_ULPICSM_Pos (19U) #define GUSBCFG_ULPICSM_Msk (0x1UL << GUSBCFG_ULPICSM_Pos) // 0x00080000 #define GUSBCFG_ULPICSM GUSBCFG_ULPICSM_Msk // ULPI Clock SuspendM #define GUSBCFG_ULPIEVBUSD_Pos (20U) #define GUSBCFG_ULPIEVBUSD_Msk (0x1UL << GUSBCFG_ULPIEVBUSD_Pos) // 0x00100000 #define GUSBCFG_ULPIEVBUSD GUSBCFG_ULPIEVBUSD_Msk // ULPI External VBUS Drive #define GUSBCFG_ULPIEVBUSI_Pos (21U) #define GUSBCFG_ULPIEVBUSI_Msk (0x1UL << GUSBCFG_ULPIEVBUSI_Pos) // 0x00200000 #define GUSBCFG_ULPIEVBUSI GUSBCFG_ULPIEVBUSI_Msk // ULPI external VBUS indicator #define GUSBCFG_TSDPS_Pos (22U) #define GUSBCFG_TSDPS_Msk (0x1UL << GUSBCFG_TSDPS_Pos) // 0x00400000 #define GUSBCFG_TSDPS GUSBCFG_TSDPS_Msk // TermSel DLine pulsing selection #define GUSBCFG_PCCI_Pos (23U) #define GUSBCFG_PCCI_Msk (0x1UL << GUSBCFG_PCCI_Pos) // 0x00800000 #define GUSBCFG_PCCI GUSBCFG_PCCI_Msk // Indicator complement #define GUSBCFG_PTCI_Pos (24U) #define GUSBCFG_PTCI_Msk (0x1UL << GUSBCFG_PTCI_Pos) // 0x01000000 #define GUSBCFG_PTCI GUSBCFG_PTCI_Msk // Indicator pass through #define GUSBCFG_ULPIIPD_Pos (25U) #define GUSBCFG_ULPIIPD_Msk (0x1UL << GUSBCFG_ULPIIPD_Pos) // 0x02000000 #define GUSBCFG_ULPIIPD GUSBCFG_ULPIIPD_Msk // ULPI interface protect disable #define GUSBCFG_FHMOD_Pos (29U) #define GUSBCFG_FHMOD_Msk (0x1UL << GUSBCFG_FHMOD_Pos) // 0x20000000 #define GUSBCFG_FHMOD GUSBCFG_FHMOD_Msk // Forced host mode #define GUSBCFG_FDMOD_Pos (30U) #define GUSBCFG_FDMOD_Msk (0x1UL << GUSBCFG_FDMOD_Pos) // 0x40000000 #define GUSBCFG_FDMOD GUSBCFG_FDMOD_Msk // Forced peripheral mode #define GUSBCFG_CTXPKT_Pos (31U) #define GUSBCFG_CTXPKT_Msk (0x1UL << GUSBCFG_CTXPKT_Pos) // 0x80000000 #define GUSBCFG_CTXPKT GUSBCFG_CTXPKT_Msk // Corrupt Tx packet /******************** Bit definition for GRSTCTL register ********************/ #define GRSTCTL_CSRST_Pos (0U) #define GRSTCTL_CSRST_Msk (0x1UL << GRSTCTL_CSRST_Pos) // 0x00000001 #define GRSTCTL_CSRST GRSTCTL_CSRST_Msk // Core soft reset #define GRSTCTL_HSRST_Pos (1U) #define GRSTCTL_HSRST_Msk (0x1UL << GRSTCTL_HSRST_Pos) // 0x00000002 #define GRSTCTL_HSRST GRSTCTL_HSRST_Msk // HCLK soft reset #define GRSTCTL_FCRST_Pos (2U) #define GRSTCTL_FCRST_Msk (0x1UL << GRSTCTL_FCRST_Pos) // 0x00000004 #define GRSTCTL_FCRST GRSTCTL_FCRST_Msk // Host frame counter reset #define GRSTCTL_RXFFLSH_Pos (4U) #define GRSTCTL_RXFFLSH_Msk (0x1UL << GRSTCTL_RXFFLSH_Pos) // 0x00000010 #define GRSTCTL_RXFFLSH GRSTCTL_RXFFLSH_Msk // RxFIFO flush #define GRSTCTL_TXFFLSH_Pos (5U) #define GRSTCTL_TXFFLSH_Msk (0x1UL << GRSTCTL_TXFFLSH_Pos) // 0x00000020 #define GRSTCTL_TXFFLSH GRSTCTL_TXFFLSH_Msk // TxFIFO flush #define GRSTCTL_TXFNUM_Pos (6U) #define GRSTCTL_TXFNUM_Msk (0x1FUL << GRSTCTL_TXFNUM_Pos) // 0x000007C0 #define GRSTCTL_TXFNUM GRSTCTL_TXFNUM_Msk // TxFIFO number #define GRSTCTL_TXFNUM_0 (0x01UL << GRSTCTL_TXFNUM_Pos) // 0x00000040 #define GRSTCTL_TXFNUM_1 (0x02UL << GRSTCTL_TXFNUM_Pos) // 0x00000080 #define GRSTCTL_TXFNUM_2 (0x04UL << GRSTCTL_TXFNUM_Pos) // 0x00000100 #define GRSTCTL_TXFNUM_3 (0x08UL << GRSTCTL_TXFNUM_Pos) // 0x00000200 #define GRSTCTL_TXFNUM_4 (0x10UL << GRSTCTL_TXFNUM_Pos) // 0x00000400 #define GRSTCTL_CSRST_DONE_Pos (29) #define GRSTCTL_CSRST_DONE (1u << GRSTCTL_CSRST_DONE_Pos) // Reset Done, only available from v4.20a #define GRSTCTL_DMAREQ_Pos (30U) #define GRSTCTL_DMAREQ_Msk (0x1UL << GRSTCTL_DMAREQ_Pos) // 0x40000000 #define GRSTCTL_DMAREQ GRSTCTL_DMAREQ_Msk // DMA request signal #define GRSTCTL_AHBIDL_Pos (31U) #define GRSTCTL_AHBIDL_Msk (0x1UL << GRSTCTL_AHBIDL_Pos) // 0x80000000 #define GRSTCTL_AHBIDL GRSTCTL_AHBIDL_Msk // AHB master idle /******************** Bit definition for DIEPMSK register ********************/ #define DIEPMSK_XFRCM_Pos (0U) #define DIEPMSK_XFRCM_Msk (0x1UL << DIEPMSK_XFRCM_Pos) // 0x00000001 #define DIEPMSK_XFRCM DIEPMSK_XFRCM_Msk // Transfer completed interrupt mask #define DIEPMSK_EPDM_Pos (1U) #define DIEPMSK_EPDM_Msk (0x1UL << DIEPMSK_EPDM_Pos) // 0x00000002 #define DIEPMSK_EPDM DIEPMSK_EPDM_Msk // Endpoint disabled interrupt mask #define DIEPMSK_TOM_Pos (3U) #define DIEPMSK_TOM_Msk (0x1UL << DIEPMSK_TOM_Pos) // 0x00000008 #define DIEPMSK_TOM DIEPMSK_TOM_Msk // Timeout condition mask (nonisochronous endpoints) #define DIEPMSK_ITTXFEMSK_Pos (4U) #define DIEPMSK_ITTXFEMSK_Msk (0x1UL << DIEPMSK_ITTXFEMSK_Pos) // 0x00000010 #define DIEPMSK_ITTXFEMSK DIEPMSK_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DIEPMSK_INEPNMM_Pos (5U) #define DIEPMSK_INEPNMM_Msk (0x1UL << DIEPMSK_INEPNMM_Pos) // 0x00000020 #define DIEPMSK_INEPNMM DIEPMSK_INEPNMM_Msk // IN token received with EP mismatch mask #define DIEPMSK_INEPNEM_Pos (6U) #define DIEPMSK_INEPNEM_Msk (0x1UL << DIEPMSK_INEPNEM_Pos) // 0x00000040 #define DIEPMSK_INEPNEM DIEPMSK_INEPNEM_Msk // IN endpoint NAK effective mask #define DIEPMSK_TXFURM_Pos (8U) #define DIEPMSK_TXFURM_Msk (0x1UL << DIEPMSK_TXFURM_Pos) // 0x00000100 #define DIEPMSK_TXFURM DIEPMSK_TXFURM_Msk // FIFO underrun mask #define DIEPMSK_BIM_Pos (9U) #define DIEPMSK_BIM_Msk (0x1UL << DIEPMSK_BIM_Pos) // 0x00000200 #define DIEPMSK_BIM DIEPMSK_BIM_Msk // BNA interrupt mask /******************** Bit definition for HPTXSTS register ********************/ #define HPTXSTS_PTXFSAVL_Pos (0U) #define HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << HPTXSTS_PTXFSAVL_Pos) // 0x0000FFFF #define HPTXSTS_PTXFSAVL HPTXSTS_PTXFSAVL_Msk // Periodic transmit data FIFO space available #define HPTXSTS_PTXQSAV_Pos (16U) #define HPTXSTS_PTXQSAV_Msk (0xFFUL << HPTXSTS_PTXQSAV_Pos) // 0x00FF0000 #define HPTXSTS_PTXQSAV HPTXSTS_PTXQSAV_Msk // Periodic transmit request queue space available #define HPTXSTS_PTXQSAV_0 (0x01UL << HPTXSTS_PTXQSAV_Pos) // 0x00010000 #define HPTXSTS_PTXQSAV_1 (0x02UL << HPTXSTS_PTXQSAV_Pos) // 0x00020000 #define HPTXSTS_PTXQSAV_2 (0x04UL << HPTXSTS_PTXQSAV_Pos) // 0x00040000 #define HPTXSTS_PTXQSAV_3 (0x08UL << HPTXSTS_PTXQSAV_Pos) // 0x00080000 #define HPTXSTS_PTXQSAV_4 (0x10UL << HPTXSTS_PTXQSAV_Pos) // 0x00100000 #define HPTXSTS_PTXQSAV_5 (0x20UL << HPTXSTS_PTXQSAV_Pos) // 0x00200000 #define HPTXSTS_PTXQSAV_6 (0x40UL << HPTXSTS_PTXQSAV_Pos) // 0x00400000 #define HPTXSTS_PTXQSAV_7 (0x80UL << HPTXSTS_PTXQSAV_Pos) // 0x00800000 #define HPTXSTS_PTXQTOP_Pos (24U) #define HPTXSTS_PTXQTOP_Msk (0xFFUL << HPTXSTS_PTXQTOP_Pos) // 0xFF000000 #define HPTXSTS_PTXQTOP HPTXSTS_PTXQTOP_Msk // Top of the periodic transmit request queue #define HPTXSTS_PTXQTOP_0 (0x01UL << HPTXSTS_PTXQTOP_Pos) // 0x01000000 #define HPTXSTS_PTXQTOP_1 (0x02UL << HPTXSTS_PTXQTOP_Pos) // 0x02000000 #define HPTXSTS_PTXQTOP_2 (0x04UL << HPTXSTS_PTXQTOP_Pos) // 0x04000000 #define HPTXSTS_PTXQTOP_3 (0x08UL << HPTXSTS_PTXQTOP_Pos) // 0x08000000 #define HPTXSTS_PTXQTOP_4 (0x10UL << HPTXSTS_PTXQTOP_Pos) // 0x10000000 #define HPTXSTS_PTXQTOP_5 (0x20UL << HPTXSTS_PTXQTOP_Pos) // 0x20000000 #define HPTXSTS_PTXQTOP_6 (0x40UL << HPTXSTS_PTXQTOP_Pos) // 0x40000000 #define HPTXSTS_PTXQTOP_7 (0x80UL << HPTXSTS_PTXQTOP_Pos) // 0x80000000 /******************** Bit definition for HAINT register ********************/ #define HAINT_HAINT_Pos (0U) #define HAINT_HAINT_Msk (0xFFFFUL << HAINT_HAINT_Pos) // 0x0000FFFF #define HAINT_HAINT HAINT_HAINT_Msk // Channel interrupts /******************** Bit definition for DOEPMSK register ********************/ #define DOEPMSK_XFRCM_Pos (0U) #define DOEPMSK_XFRCM_Msk (0x1UL << DOEPMSK_XFRCM_Pos) // 0x00000001 #define DOEPMSK_XFRCM DOEPMSK_XFRCM_Msk // Transfer completed interrupt mask #define DOEPMSK_EPDM_Pos (1U) #define DOEPMSK_EPDM_Msk (0x1UL << DOEPMSK_EPDM_Pos) // 0x00000002 #define DOEPMSK_EPDM DOEPMSK_EPDM_Msk // Endpoint disabled interrupt mask #define DOEPMSK_AHBERRM_Pos (2U) #define DOEPMSK_AHBERRM_Msk (0x1UL << DOEPMSK_AHBERRM_Pos) // 0x00000004 #define DOEPMSK_AHBERRM DOEPMSK_AHBERRM_Msk // OUT transaction AHB Error interrupt mask #define DOEPMSK_STUPM_Pos (3U) #define DOEPMSK_STUPM_Msk (0x1UL << DOEPMSK_STUPM_Pos) // 0x00000008 #define DOEPMSK_STUPM DOEPMSK_STUPM_Msk // SETUP phase done mask #define DOEPMSK_OTEPDM_Pos (4U) #define DOEPMSK_OTEPDM_Msk (0x1UL << DOEPMSK_OTEPDM_Pos) // 0x00000010 #define DOEPMSK_OTEPDM DOEPMSK_OTEPDM_Msk // OUT token received when endpoint disabled mask #define DOEPMSK_OTEPSPRM_Pos (5U) #define DOEPMSK_OTEPSPRM_Msk (0x1UL << DOEPMSK_OTEPSPRM_Pos) // 0x00000020 #define DOEPMSK_OTEPSPRM DOEPMSK_OTEPSPRM_Msk // Status Phase Received mask #define DOEPMSK_B2BSTUP_Pos (6U) #define DOEPMSK_B2BSTUP_Msk (0x1UL << DOEPMSK_B2BSTUP_Pos) // 0x00000040 #define DOEPMSK_B2BSTUP DOEPMSK_B2BSTUP_Msk // Back-to-back SETUP packets received mask #define DOEPMSK_OPEM_Pos (8U) #define DOEPMSK_OPEM_Msk (0x1UL << DOEPMSK_OPEM_Pos) // 0x00000100 #define DOEPMSK_OPEM DOEPMSK_OPEM_Msk // OUT packet error mask #define DOEPMSK_BOIM_Pos (9U) #define DOEPMSK_BOIM_Msk (0x1UL << DOEPMSK_BOIM_Pos) // 0x00000200 #define DOEPMSK_BOIM DOEPMSK_BOIM_Msk // BNA interrupt mask #define DOEPMSK_BERRM_Pos (12U) #define DOEPMSK_BERRM_Msk (0x1UL << DOEPMSK_BERRM_Pos) // 0x00001000 #define DOEPMSK_BERRM DOEPMSK_BERRM_Msk // Babble error interrupt mask #define DOEPMSK_NAKM_Pos (13U) #define DOEPMSK_NAKM_Msk (0x1UL << DOEPMSK_NAKM_Pos) // 0x00002000 #define DOEPMSK_NAKM DOEPMSK_NAKM_Msk // OUT Packet NAK interrupt mask #define DOEPMSK_NYETM_Pos (14U) #define DOEPMSK_NYETM_Msk (0x1UL << DOEPMSK_NYETM_Pos) // 0x00004000 #define DOEPMSK_NYETM DOEPMSK_NYETM_Msk // NYET interrupt mask /******************** Bit definition for GINTSTS register ********************/ #define GINTSTS_CMOD_Pos (0U) #define GINTSTS_CMOD_Msk (0x1UL << GINTSTS_CMOD_Pos) // 0x00000001 #define GINTSTS_CMOD GINTSTS_CMOD_Msk // Current mode of operation #define GINTSTS_MMIS_Pos (1U) #define GINTSTS_MMIS_Msk (0x1UL << GINTSTS_MMIS_Pos) // 0x00000002 #define GINTSTS_MMIS GINTSTS_MMIS_Msk // Mode mismatch interrupt #define GINTSTS_OTGINT_Pos (2U) #define GINTSTS_OTGINT_Msk (0x1UL << GINTSTS_OTGINT_Pos) // 0x00000004 #define GINTSTS_OTGINT GINTSTS_OTGINT_Msk // OTG interrupt #define GINTSTS_SOF_Pos (3U) #define GINTSTS_SOF_Msk (0x1UL << GINTSTS_SOF_Pos) // 0x00000008 #define GINTSTS_SOF GINTSTS_SOF_Msk // Start of frame #define GINTSTS_RXFLVL_Pos (4U) #define GINTSTS_RXFLVL_Msk (0x1UL << GINTSTS_RXFLVL_Pos) // 0x00000010 #define GINTSTS_RXFLVL GINTSTS_RXFLVL_Msk // RxFIFO nonempty #define GINTSTS_NPTX_FIFO_EMPTY_Pos (5U) #define GINTSTS_NPTX_FIFO_EMPTY_Msk (0x1UL << GINTSTS_NPTX_FIFO_EMPTY_Pos) // 0x00000020 #define GINTSTS_NPTX_FIFO_EMPTY GINTSTS_NPTX_FIFO_EMPTY_Msk // Nonperiodic TxFIFO empty #define GINTSTS_GINAKEFF_Pos (6U) #define GINTSTS_GINAKEFF_Msk (0x1UL << GINTSTS_GINAKEFF_Pos) // 0x00000040 #define GINTSTS_GINAKEFF GINTSTS_GINAKEFF_Msk // Global IN nonperiodic NAK effective #define GINTSTS_BOUTNAKEFF_Pos (7U) #define GINTSTS_BOUTNAKEFF_Msk (0x1UL << GINTSTS_BOUTNAKEFF_Pos) // 0x00000080 #define GINTSTS_BOUTNAKEFF GINTSTS_BOUTNAKEFF_Msk // Global OUT NAK effective #define GINTSTS_ESUSP_Pos (10U) #define GINTSTS_ESUSP_Msk (0x1UL << GINTSTS_ESUSP_Pos) // 0x00000400 #define GINTSTS_ESUSP GINTSTS_ESUSP_Msk // Early suspend #define GINTSTS_USBSUSP_Pos (11U) #define GINTSTS_USBSUSP_Msk (0x1UL << GINTSTS_USBSUSP_Pos) // 0x00000800 #define GINTSTS_USBSUSP GINTSTS_USBSUSP_Msk // USB suspend #define GINTSTS_USBRST_Pos (12U) #define GINTSTS_USBRST_Msk (0x1UL << GINTSTS_USBRST_Pos) // 0x00001000 #define GINTSTS_USBRST GINTSTS_USBRST_Msk // USB reset #define GINTSTS_ENUMDNE_Pos (13U) #define GINTSTS_ENUMDNE_Msk (0x1UL << GINTSTS_ENUMDNE_Pos) // 0x00002000 #define GINTSTS_ENUMDNE GINTSTS_ENUMDNE_Msk // Enumeration done #define GINTSTS_ISOODRP_Pos (14U) #define GINTSTS_ISOODRP_Msk (0x1UL << GINTSTS_ISOODRP_Pos) // 0x00004000 #define GINTSTS_ISOODRP GINTSTS_ISOODRP_Msk // Isochronous OUT packet dropped interrupt #define GINTSTS_EOPF_Pos (15U) #define GINTSTS_EOPF_Msk (0x1UL << GINTSTS_EOPF_Pos) // 0x00008000 #define GINTSTS_EOPF GINTSTS_EOPF_Msk // End of periodic frame interrupt #define GINTSTS_IEPINT_Pos (18U) #define GINTSTS_IEPINT_Msk (0x1UL << GINTSTS_IEPINT_Pos) // 0x00040000 #define GINTSTS_IEPINT GINTSTS_IEPINT_Msk // IN endpoint interrupt #define GINTSTS_OEPINT_Pos (19U) #define GINTSTS_OEPINT_Msk (0x1UL << GINTSTS_OEPINT_Pos) // 0x00080000 #define GINTSTS_OEPINT GINTSTS_OEPINT_Msk // OUT endpoint interrupt #define GINTSTS_IISOIXFR_Pos (20U) #define GINTSTS_IISOIXFR_Msk (0x1UL << GINTSTS_IISOIXFR_Pos) // 0x00100000 #define GINTSTS_IISOIXFR GINTSTS_IISOIXFR_Msk // Incomplete isochronous IN transfer #define GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) #define GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << GINTSTS_PXFR_INCOMPISOOUT_Pos) // 0x00200000 #define GINTSTS_PXFR_INCOMPISOOUT GINTSTS_PXFR_INCOMPISOOUT_Msk // Incomplete periodic transfer #define GINTSTS_DATAFSUSP_Pos (22U) #define GINTSTS_DATAFSUSP_Msk (0x1UL << GINTSTS_DATAFSUSP_Pos) // 0x00400000 #define GINTSTS_DATAFSUSP GINTSTS_DATAFSUSP_Msk // Data fetch suspended #define GINTSTS_RSTDET_Pos (23U) #define GINTSTS_RSTDET_Msk (0x1UL << GINTSTS_RSTDET_Pos) // 0x00800000 #define GINTSTS_RSTDET GINTSTS_RSTDET_Msk // Reset detected interrupt #define GINTSTS_HPRTINT_Pos (24U) #define GINTSTS_HPRTINT_Msk (0x1UL << GINTSTS_HPRTINT_Pos) // 0x01000000 #define GINTSTS_HPRTINT GINTSTS_HPRTINT_Msk // Host port interrupt #define GINTSTS_HCINT_Pos (25U) #define GINTSTS_HCINT_Msk (0x1UL << GINTSTS_HCINT_Pos) // 0x02000000 #define GINTSTS_HCINT GINTSTS_HCINT_Msk // Host channels interrupt #define GINTSTS_PTX_FIFO_EMPTY_Pos (26U) #define GINTSTS_PTX_FIFO_EMPTY_Msk (0x1UL << GINTSTS_PTX_FIFO_EMPTY_Pos) // 0x04000000 #define GINTSTS_PTX_FIFO_EMPTY GINTSTS_PTX_FIFO_EMPTY_Msk // Periodic TxFIFO empty #define GINTSTS_LPMINT_Pos (27U) #define GINTSTS_LPMINT_Msk (0x1UL << GINTSTS_LPMINT_Pos) // 0x08000000 #define GINTSTS_LPMINT GINTSTS_LPMINT_Msk // LPM interrupt #define GINTSTS_CONIDSTSCHNG_Pos (28U) #define GINTSTS_CONIDSTSCHNG_Msk (0x1UL << GINTSTS_CONIDSTSCHNG_Pos) // 0x10000000 #define GINTSTS_CONIDSTSCHNG GINTSTS_CONIDSTSCHNG_Msk // Connector ID status change #define GINTSTS_DISCINT_Pos (29U) #define GINTSTS_DISCINT_Msk (0x1UL << GINTSTS_DISCINT_Pos) // 0x20000000 #define GINTSTS_DISCINT GINTSTS_DISCINT_Msk // Disconnect detected interrupt #define GINTSTS_SRQINT_Pos (30U) #define GINTSTS_SRQINT_Msk (0x1UL << GINTSTS_SRQINT_Pos) // 0x40000000 #define GINTSTS_SRQINT GINTSTS_SRQINT_Msk // Session request/new session detected interrupt #define GINTSTS_WKUINT_Pos (31U) #define GINTSTS_WKUINT_Msk (0x1UL << GINTSTS_WKUINT_Pos) // 0x80000000 #define GINTSTS_WKUINT GINTSTS_WKUINT_Msk // Resume/remote wakeup detected interrupt /******************** Bit definition for GINTMSK register ********************/ #define GINTMSK_MMISM_Pos (1U) #define GINTMSK_MMISM_Msk (0x1UL << GINTMSK_MMISM_Pos) // 0x00000002 #define GINTMSK_MMISM GINTMSK_MMISM_Msk // Mode mismatch interrupt mask #define GINTMSK_OTGINT_Pos (2U) #define GINTMSK_OTGINT_Msk (0x1UL << GINTMSK_OTGINT_Pos) // 0x00000004 #define GINTMSK_OTGINT GINTMSK_OTGINT_Msk // OTG interrupt mask #define GINTMSK_SOFM_Pos (3U) #define GINTMSK_SOFM_Msk (0x1UL << GINTMSK_SOFM_Pos) // 0x00000008 #define GINTMSK_SOFM GINTMSK_SOFM_Msk // Start of frame mask #define GINTMSK_RXFLVLM_Pos (4U) #define GINTMSK_RXFLVLM_Msk (0x1UL << GINTMSK_RXFLVLM_Pos) // 0x00000010 #define GINTMSK_RXFLVLM GINTMSK_RXFLVLM_Msk // Receive FIFO nonempty mask #define GINTMSK_NPTXFEM_Pos (5U) #define GINTMSK_NPTXFEM_Msk (0x1UL << GINTMSK_NPTXFEM_Pos) // 0x00000020 #define GINTMSK_NPTXFEM GINTMSK_NPTXFEM_Msk // Nonperiodic TxFIFO empty mask #define GINTMSK_GINAKEFFM_Pos (6U) #define GINTMSK_GINAKEFFM_Msk (0x1UL << GINTMSK_GINAKEFFM_Pos) // 0x00000040 #define GINTMSK_GINAKEFFM GINTMSK_GINAKEFFM_Msk // Global nonperiodic IN NAK effective mask #define GINTMSK_GONAKEFFM_Pos (7U) #define GINTMSK_GONAKEFFM_Msk (0x1UL << GINTMSK_GONAKEFFM_Pos) // 0x00000080 #define GINTMSK_GONAKEFFM GINTMSK_GONAKEFFM_Msk // Global OUT NAK effective mask #define GINTMSK_ESUSPM_Pos (10U) #define GINTMSK_ESUSPM_Msk (0x1UL << GINTMSK_ESUSPM_Pos) // 0x00000400 #define GINTMSK_ESUSPM GINTMSK_ESUSPM_Msk // Early suspend mask #define GINTMSK_USBSUSPM_Pos (11U) #define GINTMSK_USBSUSPM_Msk (0x1UL << GINTMSK_USBSUSPM_Pos) // 0x00000800 #define GINTMSK_USBSUSPM GINTMSK_USBSUSPM_Msk // USB suspend mask #define GINTMSK_USBRST_Pos (12U) #define GINTMSK_USBRST_Msk (0x1UL << GINTMSK_USBRST_Pos) // 0x00001000 #define GINTMSK_USBRST GINTMSK_USBRST_Msk // USB reset mask #define GINTMSK_ENUMDNEM_Pos (13U) #define GINTMSK_ENUMDNEM_Msk (0x1UL << GINTMSK_ENUMDNEM_Pos) // 0x00002000 #define GINTMSK_ENUMDNEM GINTMSK_ENUMDNEM_Msk // Enumeration done mask #define GINTMSK_ISOODRPM_Pos (14U) #define GINTMSK_ISOODRPM_Msk (0x1UL << GINTMSK_ISOODRPM_Pos) // 0x00004000 #define GINTMSK_ISOODRPM GINTMSK_ISOODRPM_Msk // Isochronous OUT packet dropped interrupt mask #define GINTMSK_EOPFM_Pos (15U) #define GINTMSK_EOPFM_Msk (0x1UL << GINTMSK_EOPFM_Pos) // 0x00008000 #define GINTMSK_EOPFM GINTMSK_EOPFM_Msk // End of periodic frame interrupt mask #define GINTMSK_EPMISM_Pos (17U) #define GINTMSK_EPMISM_Msk (0x1UL << GINTMSK_EPMISM_Pos) // 0x00020000 #define GINTMSK_EPMISM GINTMSK_EPMISM_Msk // Endpoint mismatch interrupt mask #define GINTMSK_IEPINT_Pos (18U) #define GINTMSK_IEPINT_Msk (0x1UL << GINTMSK_IEPINT_Pos) // 0x00040000 #define GINTMSK_IEPINT GINTMSK_IEPINT_Msk // IN endpoints interrupt mask #define GINTMSK_OEPINT_Pos (19U) #define GINTMSK_OEPINT_Msk (0x1UL << GINTMSK_OEPINT_Pos) // 0x00080000 #define GINTMSK_OEPINT GINTMSK_OEPINT_Msk // OUT endpoints interrupt mask #define GINTMSK_IISOIXFRM_Pos (20U) #define GINTMSK_IISOIXFRM_Msk (0x1UL << GINTMSK_IISOIXFRM_Pos) // 0x00100000 #define GINTMSK_IISOIXFRM GINTMSK_IISOIXFRM_Msk // Incomplete isochronous IN transfer mask #define GINTMSK_PXFRM_IISOOXFRM_Pos (21U) #define GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << GINTMSK_PXFRM_IISOOXFRM_Pos) // 0x00200000 #define GINTMSK_PXFRM_IISOOXFRM GINTMSK_PXFRM_IISOOXFRM_Msk // Incomplete periodic transfer mask #define GINTMSK_FSUSPM_Pos (22U) #define GINTMSK_FSUSPM_Msk (0x1UL << GINTMSK_FSUSPM_Pos) // 0x00400000 #define GINTMSK_FSUSPM GINTMSK_FSUSPM_Msk // Data fetch suspended mask #define GINTMSK_RSTDEM_Pos (23U) #define GINTMSK_RSTDEM_Msk (0x1UL << GINTMSK_RSTDEM_Pos) // 0x00800000 #define GINTMSK_RSTDEM GINTMSK_RSTDEM_Msk // Reset detected interrupt mask #define GINTMSK_PRTIM_Pos (24U) #define GINTMSK_PRTIM_Msk (0x1UL << GINTMSK_PRTIM_Pos) // 0x01000000 #define GINTMSK_PRTIM GINTMSK_PRTIM_Msk // Host port interrupt mask #define GINTMSK_HCIM_Pos (25U) #define GINTMSK_HCIM_Msk (0x1UL << GINTMSK_HCIM_Pos) // 0x02000000 #define GINTMSK_HCIM GINTMSK_HCIM_Msk // Host channels interrupt mask #define GINTMSK_PTXFEM_Pos (26U) #define GINTMSK_PTXFEM_Msk (0x1UL << GINTMSK_PTXFEM_Pos) // 0x04000000 #define GINTMSK_PTXFEM GINTMSK_PTXFEM_Msk // Periodic TxFIFO empty mask #define GINTMSK_LPMINTM_Pos (27U) #define GINTMSK_LPMINTM_Msk (0x1UL << GINTMSK_LPMINTM_Pos) // 0x08000000 #define GINTMSK_LPMINTM GINTMSK_LPMINTM_Msk // LPM interrupt Mask #define GINTMSK_CONIDSTSCHNGM_Pos (28U) #define GINTMSK_CONIDSTSCHNGM_Msk (0x1UL << GINTMSK_CONIDSTSCHNGM_Pos) // 0x10000000 #define GINTMSK_CONIDSTSCHNGM GINTMSK_CONIDSTSCHNGM_Msk // Connector ID status change mask #define GINTMSK_DISCINT_Pos (29U) #define GINTMSK_DISCINT_Msk (0x1UL << GINTMSK_DISCINT_Pos) // 0x20000000 #define GINTMSK_DISCINT GINTMSK_DISCINT_Msk // Disconnect detected interrupt mask #define GINTMSK_SRQIM_Pos (30U) #define GINTMSK_SRQIM_Msk (0x1UL << GINTMSK_SRQIM_Pos) // 0x40000000 #define GINTMSK_SRQIM GINTMSK_SRQIM_Msk // Session request/new session detected interrupt mask #define GINTMSK_WUIM_Pos (31U) #define GINTMSK_WUIM_Msk (0x1UL << GINTMSK_WUIM_Pos) // 0x80000000 #define GINTMSK_WUIM GINTMSK_WUIM_Msk // Resume/remote wakeup detected interrupt mask /******************** Bit definition for DAINT register ********************/ #define DAINT_IEPINT_Pos (0U) #define DAINT_IEPINT_Msk (0xFFFFUL << DAINT_IEPINT_Pos) // 0x0000FFFF #define DAINT_IEPINT DAINT_IEPINT_Msk // IN endpoint interrupt bits #define DAINT_OEPINT_Pos (16U) #define DAINT_OEPINT_Msk (0xFFFFUL << DAINT_OEPINT_Pos) // 0xFFFF0000 #define DAINT_OEPINT DAINT_OEPINT_Msk // OUT endpoint interrupt bits /******************** Bit definition for HAINTMSK register ********************/ #define HAINTMSK_HAINTM_Pos (0U) #define HAINTMSK_HAINTM_Msk (0xFFFFUL << HAINTMSK_HAINTM_Pos) // 0x0000FFFF #define HAINTMSK_HAINTM HAINTMSK_HAINTM_Msk // Channel interrupt mask /******************** Bit definition for GRXSTSP register ********************/ #define GRXSTSP_EPNUM_Pos (0U) #define GRXSTSP_EPNUM_Msk (0xFUL << GRXSTSP_EPNUM_Pos) // 0x0000000F #define GRXSTSP_EPNUM GRXSTSP_EPNUM_Msk // IN EP interrupt mask bits #define GRXSTSP_BCNT_Pos (4U) #define GRXSTSP_BCNT_Msk (0x7FFUL << GRXSTSP_BCNT_Pos) // 0x00007FF0 #define GRXSTSP_BCNT GRXSTSP_BCNT_Msk // OUT EP interrupt mask bits #define GRXSTSP_DPID_Pos (15U) #define GRXSTSP_DPID_Msk (0x3UL << GRXSTSP_DPID_Pos) // 0x00018000 #define GRXSTSP_DPID GRXSTSP_DPID_Msk // OUT EP interrupt mask bits #define GRXSTSP_PKTSTS_Pos (17U) #define GRXSTSP_PKTSTS_Msk (0xFUL << GRXSTSP_PKTSTS_Pos) // 0x001E0000 #define GRXSTSP_PKTSTS GRXSTSP_PKTSTS_Msk // OUT EP interrupt mask bits /******************** Bit definition for DAINTMSK register ********************/ #define DAINTMSK_IEPM_Pos (0U) #define DAINTMSK_IEPM_Msk (0xFFFFUL << DAINTMSK_IEPM_Pos) // 0x0000FFFF #define DAINTMSK_IEPM DAINTMSK_IEPM_Msk // IN EP interrupt mask bits #define DAINTMSK_OEPM_Pos (16U) #define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 #define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits #define DAINT_SHIFT(_dir) (((_dir) == TUSB_DIR_IN) ? 0 : 16) #if 0 /******************** Bit definition for OTG register ********************/ #define CHNUM_Pos (0U) #define CHNUM_Msk (0xFUL << CHNUM_Pos) // 0x0000000F #define CHNUM CHNUM_Msk // Channel number #define CHNUM_0 (0x1UL << CHNUM_Pos) // 0x00000001 #define CHNUM_1 (0x2UL << CHNUM_Pos) // 0x00000002 #define CHNUM_2 (0x4UL << CHNUM_Pos) // 0x00000004 #define CHNUM_3 (0x8UL << CHNUM_Pos) // 0x00000008 #define BCNT_Pos (4U) #define BCNT_Msk (0x7FFUL << BCNT_Pos) // 0x00007FF0 #define BCNT BCNT_Msk // Byte count #define DPID_Pos (15U) #define DPID_Msk (0x3UL << DPID_Pos) // 0x00018000 #define DPID DPID_Msk // Data PID #define DPID_0 (0x1UL << DPID_Pos) // 0x00008000 #define DPID_1 (0x2UL << DPID_Pos) // 0x00010000 #define PKTSTS_Pos (17U) #define PKTSTS_Msk (0xFUL << PKTSTS_Pos) // 0x001E0000 #define PKTSTS PKTSTS_Msk // Packet status #define PKTSTS_0 (0x1UL << PKTSTS_Pos) // 0x00020000 #define PKTSTS_1 (0x2UL << PKTSTS_Pos) // 0x00040000 #define PKTSTS_2 (0x4UL << PKTSTS_Pos) // 0x00080000 #define PKTSTS_3 (0x8UL << PKTSTS_Pos) // 0x00100000 #define EPNUM_Pos (0U) #define EPNUM_Msk (0xFUL << EPNUM_Pos) // 0x0000000F #define EPNUM EPNUM_Msk // Endpoint number #define EPNUM_0 (0x1UL << EPNUM_Pos) // 0x00000001 #define EPNUM_1 (0x2UL << EPNUM_Pos) // 0x00000002 #define EPNUM_2 (0x4UL << EPNUM_Pos) // 0x00000004 #define EPNUM_3 (0x8UL << EPNUM_Pos) // 0x00000008 #define FRMNUM_Pos (21U) #define FRMNUM_Msk (0xFUL << FRMNUM_Pos) // 0x01E00000 #define FRMNUM FRMNUM_Msk // Frame number #define FRMNUM_0 (0x1UL << FRMNUM_Pos) // 0x00200000 #define FRMNUM_1 (0x2UL << FRMNUM_Pos) // 0x00400000 #define FRMNUM_2 (0x4UL << FRMNUM_Pos) // 0x00800000 #define FRMNUM_3 (0x8UL << FRMNUM_Pos) // 0x01000000 #endif /******************** Bit definition for GRXFSIZ register ********************/ #define GRXFSIZ_RXFD_Pos (0U) #define GRXFSIZ_RXFD_Msk (0xFFFFUL << GRXFSIZ_RXFD_Pos) // 0x0000FFFF #define GRXFSIZ_RXFD GRXFSIZ_RXFD_Msk // RxFIFO depth /******************** Bit definition for DVBUSDIS register ********************/ #define DVBUSDIS_VBUSDT_Pos (0U) #define DVBUSDIS_VBUSDT_Msk (0xFFFFUL << DVBUSDIS_VBUSDT_Pos) // 0x0000FFFF #define DVBUSDIS_VBUSDT DVBUSDIS_VBUSDT_Msk // Device VBUS discharge time /******************** Bit definition for OTG register ********************/ #define GNPTXFSIZ_NPTXFSA_Pos (0U) #define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF #define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address #define GNPTXFSIZ_NPTXFD_Pos (16U) #define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 #define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth #define DIEPTXF0_TX0FSA_Pos (0U) #define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF #define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address #define DIEPTXF0_TX0FD_Pos (16U) #define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 #define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth /******************** Bit definition for DVBUSPULSE register ********************/ #define DVBUSPULSE_DVBUSP_Pos (0U) #define DVBUSPULSE_DVBUSP_Msk (0xFFFUL << DVBUSPULSE_DVBUSP_Pos) // 0x00000FFF #define DVBUSPULSE_DVBUSP DVBUSPULSE_DVBUSP_Msk // Device VBUS pulsing time /******************** Bit definition for GNPTXSTS register ********************/ #define GNPTXSTS_NPTXFSAV_Pos (0U) #define GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << GNPTXSTS_NPTXFSAV_Pos) // 0x0000FFFF #define GNPTXSTS_NPTXFSAV GNPTXSTS_NPTXFSAV_Msk // Nonperiodic TxFIFO space available #define GNPTXSTS_NPTQXSAV_Pos (16U) #define GNPTXSTS_NPTQXSAV_Msk (0xFFUL << GNPTXSTS_NPTQXSAV_Pos) // 0x00FF0000 #define GNPTXSTS_NPTQXSAV GNPTXSTS_NPTQXSAV_Msk // Nonperiodic transmit request queue space available #define GNPTXSTS_NPTQXSAV_0 (0x01UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00010000 #define GNPTXSTS_NPTQXSAV_1 (0x02UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00020000 #define GNPTXSTS_NPTQXSAV_2 (0x04UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00040000 #define GNPTXSTS_NPTQXSAV_3 (0x08UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00080000 #define GNPTXSTS_NPTQXSAV_4 (0x10UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00100000 #define GNPTXSTS_NPTQXSAV_5 (0x20UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00200000 #define GNPTXSTS_NPTQXSAV_6 (0x40UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00400000 #define GNPTXSTS_NPTQXSAV_7 (0x80UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00800000 #define GNPTXSTS_NPTXQTOP_Pos (24U) #define GNPTXSTS_NPTXQTOP_Msk (0x7FUL << GNPTXSTS_NPTXQTOP_Pos) // 0x7F000000 #define GNPTXSTS_NPTXQTOP GNPTXSTS_NPTXQTOP_Msk // Top of the nonperiodic transmit request queue #define GNPTXSTS_NPTXQTOP_0 (0x01UL << GNPTXSTS_NPTXQTOP_Pos) // 0x01000000 #define GNPTXSTS_NPTXQTOP_1 (0x02UL << GNPTXSTS_NPTXQTOP_Pos) // 0x02000000 #define GNPTXSTS_NPTXQTOP_2 (0x04UL << GNPTXSTS_NPTXQTOP_Pos) // 0x04000000 #define GNPTXSTS_NPTXQTOP_3 (0x08UL << GNPTXSTS_NPTXQTOP_Pos) // 0x08000000 #define GNPTXSTS_NPTXQTOP_4 (0x10UL << GNPTXSTS_NPTXQTOP_Pos) // 0x10000000 #define GNPTXSTS_NPTXQTOP_5 (0x20UL << GNPTXSTS_NPTXQTOP_Pos) // 0x20000000 #define GNPTXSTS_NPTXQTOP_6 (0x40UL << GNPTXSTS_NPTXQTOP_Pos) // 0x40000000 /******************** Bit definition for DTHRCTL register ********************/ #define DTHRCTL_NONISOTHREN_Pos (0U) #define DTHRCTL_NONISOTHREN_Msk (0x1UL << DTHRCTL_NONISOTHREN_Pos) // 0x00000001 #define DTHRCTL_NONISOTHREN DTHRCTL_NONISOTHREN_Msk // Nonisochronous IN endpoints threshold enable #define DTHRCTL_ISOTHREN_Pos (1U) #define DTHRCTL_ISOTHREN_Msk (0x1UL << DTHRCTL_ISOTHREN_Pos) // 0x00000002 #define DTHRCTL_ISOTHREN DTHRCTL_ISOTHREN_Msk // ISO IN endpoint threshold enable #define DTHRCTL_TXTHRLEN_Pos (2U) #define DTHRCTL_TXTHRLEN_Msk (0x1FFUL << DTHRCTL_TXTHRLEN_Pos) // 0x000007FC #define DTHRCTL_TXTHRLEN DTHRCTL_TXTHRLEN_Msk // Transmit threshold length #define DTHRCTL_TXTHRLEN_0 (0x001UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000004 #define DTHRCTL_TXTHRLEN_1 (0x002UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000008 #define DTHRCTL_TXTHRLEN_2 (0x004UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000010 #define DTHRCTL_TXTHRLEN_3 (0x008UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000020 #define DTHRCTL_TXTHRLEN_4 (0x010UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000040 #define DTHRCTL_TXTHRLEN_5 (0x020UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000080 #define DTHRCTL_TXTHRLEN_6 (0x040UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000100 #define DTHRCTL_TXTHRLEN_7 (0x080UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000200 #define DTHRCTL_TXTHRLEN_8 (0x100UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000400 #define DTHRCTL_RXTHREN_Pos (16U) #define DTHRCTL_RXTHREN_Msk (0x1UL << DTHRCTL_RXTHREN_Pos) // 0x00010000 #define DTHRCTL_RXTHREN DTHRCTL_RXTHREN_Msk // Receive threshold enable #define DTHRCTL_RXTHRLEN_Pos (17U) #define DTHRCTL_RXTHRLEN_Msk (0x1FFUL << DTHRCTL_RXTHRLEN_Pos) // 0x03FE0000 #define DTHRCTL_RXTHRLEN DTHRCTL_RXTHRLEN_Msk // Receive threshold length #define DTHRCTL_RXTHRLEN_0 (0x001UL << DTHRCTL_RXTHRLEN_Pos) // 0x00020000 #define DTHRCTL_RXTHRLEN_1 (0x002UL << DTHRCTL_RXTHRLEN_Pos) // 0x00040000 #define DTHRCTL_RXTHRLEN_2 (0x004UL << DTHRCTL_RXTHRLEN_Pos) // 0x00080000 #define DTHRCTL_RXTHRLEN_3 (0x008UL << DTHRCTL_RXTHRLEN_Pos) // 0x00100000 #define DTHRCTL_RXTHRLEN_4 (0x010UL << DTHRCTL_RXTHRLEN_Pos) // 0x00200000 #define DTHRCTL_RXTHRLEN_5 (0x020UL << DTHRCTL_RXTHRLEN_Pos) // 0x00400000 #define DTHRCTL_RXTHRLEN_6 (0x040UL << DTHRCTL_RXTHRLEN_Pos) // 0x00800000 #define DTHRCTL_RXTHRLEN_7 (0x080UL << DTHRCTL_RXTHRLEN_Pos) // 0x01000000 #define DTHRCTL_RXTHRLEN_8 (0x100UL << DTHRCTL_RXTHRLEN_Pos) // 0x02000000 #define DTHRCTL_ARPEN_Pos (27U) #define DTHRCTL_ARPEN_Msk (0x1UL << DTHRCTL_ARPEN_Pos) // 0x08000000 #define DTHRCTL_ARPEN DTHRCTL_ARPEN_Msk // Arbiter parking enable /******************** Bit definition for DIEPEMPMSK register ********************/ #define DIEPEMPMSK_INEPTXFEM_Pos (0U) #define DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << DIEPEMPMSK_INEPTXFEM_Pos) // 0x0000FFFF #define DIEPEMPMSK_INEPTXFEM DIEPEMPMSK_INEPTXFEM_Msk // IN EP Tx FIFO empty interrupt mask bits /******************** Bit definition for DEACHINT register ********************/ #define DEACHINT_IEP1INT_Pos (1U) #define DEACHINT_IEP1INT_Msk (0x1UL << DEACHINT_IEP1INT_Pos) // 0x00000002 #define DEACHINT_IEP1INT DEACHINT_IEP1INT_Msk // IN endpoint 1interrupt bit #define DEACHINT_OEP1INT_Pos (17U) #define DEACHINT_OEP1INT_Msk (0x1UL << DEACHINT_OEP1INT_Pos) // 0x00020000 #define DEACHINT_OEP1INT DEACHINT_OEP1INT_Msk // OUT endpoint 1 interrupt bit /******************** Bit definition for GCCFG register ********************/ #define STM32_GCCFG_DCDET_Pos (0U) #define STM32_GCCFG_DCDET_Msk (0x1UL << STM32_GCCFG_DCDET_Pos) // 0x00000001 #define STM32_GCCFG_DCDET STM32_GCCFG_DCDET_Msk // Data contact detection (DCD) status #define STM32_GCCFG_PDET_Pos (1U) #define STM32_GCCFG_PDET_Msk (0x1UL << STM32_GCCFG_PDET_Pos) // 0x00000002 #define STM32_GCCFG_PDET STM32_GCCFG_PDET_Msk // Primary detection (PD) status #define STM32_GCCFG_SDET_Pos (2U) #define STM32_GCCFG_SDET_Msk (0x1UL << STM32_GCCFG_SDET_Pos) // 0x00000004 #define STM32_GCCFG_SDET STM32_GCCFG_SDET_Msk // Secondary detection (SD) status #define STM32_GCCFG_PS2DET_Pos (3U) #define STM32_GCCFG_PS2DET_Msk (0x1UL << STM32_GCCFG_PS2DET_Pos) // 0x00000008 #define STM32_GCCFG_PS2DET STM32_GCCFG_PS2DET_Msk // DM pull-up detection status #define STM32_GCCFG_PWRDWN_Pos (16U) #define STM32_GCCFG_PWRDWN_Msk (0x1UL << STM32_GCCFG_PWRDWN_Pos) // 0x00010000 #define STM32_GCCFG_PWRDWN STM32_GCCFG_PWRDWN_Msk // Power down #define STM32_GCCFG_BCDEN_Pos (17U) #define STM32_GCCFG_BCDEN_Msk (0x1UL << STM32_GCCFG_BCDEN_Pos) // 0x00020000 #define STM32_GCCFG_BCDEN STM32_GCCFG_BCDEN_Msk // Battery charging detector (BCD) enable #define STM32_GCCFG_DCDEN_Pos (18U) #define STM32_GCCFG_DCDEN_Msk (0x1UL << STM32_GCCFG_DCDEN_Pos) // 0x00040000 #define STM32_GCCFG_DCDEN STM32_GCCFG_DCDEN_Msk // Data contact detection (DCD) mode enable*/ #define STM32_GCCFG_PDEN_Pos (19U) #define STM32_GCCFG_PDEN_Msk (0x1UL << STM32_GCCFG_PDEN_Pos) // 0x00080000 #define STM32_GCCFG_PDEN STM32_GCCFG_PDEN_Msk // Primary detection (PD) mode enable*/ #define STM32_GCCFG_SDEN_Pos (20U) #define STM32_GCCFG_SDEN_Msk (0x1UL << STM32_GCCFG_SDEN_Pos) // 0x00100000 #define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (SD) mode enable #define STM32_GCCFG_VBDEN_Pos (21U) #define STM32_GCCFG_VBDEN_Msk (0x1UL << STM32_GCCFG_VBDEN_Pos) // 0x00200000 #define STM32_GCCFG_VBDEN STM32_GCCFG_VBDEN_Msk // VBUS mode enable #define STM32_GCCFG_OTGIDEN_Pos (22U) #define STM32_GCCFG_OTGIDEN_Msk (0x1UL << STM32_GCCFG_OTGIDEN_Pos) // 0x00400000 #define STM32_GCCFG_OTGIDEN STM32_GCCFG_OTGIDEN_Msk // OTG Id enable #define STM32_GCCFG_PHYHSEN_Pos (23U) #define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 #define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable // GUID < 0x2000: VBUSASEN, VBUSBSEN, NOVBUSSENS bits #define STM32_GCCFG_VBUSASEN_Pos (18U) #define STM32_GCCFG_VBUSASEN_Msk (0x1UL << STM32_GCCFG_VBUSASEN_Pos) // 0x00040000 #define STM32_GCCFG_VBUSASEN STM32_GCCFG_VBUSASEN_Msk // Enable A-device (host) VBUS sensing #define STM32_GCCFG_VBUSBSEN_Pos (19U) #define STM32_GCCFG_VBUSBSEN_Msk (0x1UL << STM32_GCCFG_VBUSBSEN_Pos) // 0x00080000 #define STM32_GCCFG_VBUSBSEN STM32_GCCFG_VBUSBSEN_Msk // Enable B-device (peripheral) VBUS sensing #define STM32_GCCFG_NOVBUSSENS_Pos (21U) #define STM32_GCCFG_NOVBUSSENS_Msk (0x1UL << STM32_GCCFG_NOVBUSSENS_Pos) // 0x00200000 #define STM32_GCCFG_NOVBUSSENS STM32_GCCFG_NOVBUSSENS_Msk // VBUS sensing disable option // GUID < 0x2000: end // TODO: stm32u5a5 SDEN is 22nd bit, conflict with 20th bit above // #define STM32_GCCFG_SDEN_Pos (22U) // #define STM32_GCCFG_SDEN_Msk (0x1U << STM32_GCCFG_SDEN_Pos) // 0x00400000 // #define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (PD) mode enable // GUID >= 0x5000 use femtoPHY: VBVALOVA, VBVALEXTOEN, PULLDOWNEN #define STM32_GCCFG_VBVALOVAL_Pos (23U) #define STM32_GCCFG_VBVALOVAL_Msk (0x1U << STM32_GCCFG_VBVALOVAL_Pos) // 0x00800000 #define STM32_GCCFG_VBVALOVAL STM32_GCCFG_VBVALOVAL_Msk // Value of VBUSVLDEXT0 femtoPHY input #define STM32_GCCFG_VBVALEXTOEN_Pos (24U) #define STM32_GCCFG_VBVALEXTOEN_Msk (0x1U << STM32_GCCFG_VBVALEXTOEN_Pos) // 0x01000000 #define STM32_GCCFG_VBVALEXTOEN STM32_GCCFG_VBVALEXTOEN_Msk // Enables of VBUSVLDEXT0 femtoPHY input override #define STM32_GCCFG_PULLDOWNEN_Pos (25U) #define STM32_GCCFG_PULLDOWNEN_Msk (0x1U << STM32_GCCFG_PULLDOWNEN_Pos) // 0x02000000 #define STM32_GCCFG_PULLDOWNEN STM32_GCCFG_PULLDOWNEN_Msk // Enables of femtoPHY pulldown resistors, used when ID PAD is disabled // GUID >= 0x5000: end /******************** Bit definition for DEACHINTMSK register ********************/ #define DEACHINTMSK_IEP1INTM_Pos (1U) #define DEACHINTMSK_IEP1INTM_Msk (0x1UL << DEACHINTMSK_IEP1INTM_Pos) // 0x00000002 #define DEACHINTMSK_IEP1INTM DEACHINTMSK_IEP1INTM_Msk // IN Endpoint 1 interrupt mask bit #define DEACHINTMSK_OEP1INTM_Pos (17U) #define DEACHINTMSK_OEP1INTM_Msk (0x1UL << DEACHINTMSK_OEP1INTM_Pos) // 0x00020000 #define DEACHINTMSK_OEP1INTM DEACHINTMSK_OEP1INTM_Msk // OUT Endpoint 1 interrupt mask bit /******************** Bit definition for CID register ********************/ #define CID_PRODUCT_ID_Pos (0U) #define CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << CID_PRODUCT_ID_Pos) // 0xFFFFFFFF #define CID_PRODUCT_ID CID_PRODUCT_ID_Msk // Product ID field /******************** Bit definition for GLPMCFG register ********************/ #define GLPMCFG_LPMEN_Pos (0U) #define GLPMCFG_LPMEN_Msk (0x1UL << GLPMCFG_LPMEN_Pos) // 0x00000001 #define GLPMCFG_LPMEN GLPMCFG_LPMEN_Msk // LPM support enable #define GLPMCFG_LPMACK_Pos (1U) #define GLPMCFG_LPMACK_Msk (0x1UL << GLPMCFG_LPMACK_Pos) // 0x00000002 #define GLPMCFG_LPMACK GLPMCFG_LPMACK_Msk // LPM Token acknowledge enable #define GLPMCFG_BESL_Pos (2U) #define GLPMCFG_BESL_Msk (0xFUL << GLPMCFG_BESL_Pos) // 0x0000003C #define GLPMCFG_BESL GLPMCFG_BESL_Msk // BESL value received with last ACKed LPM Token #define GLPMCFG_REMWAKE_Pos (6U) #define GLPMCFG_REMWAKE_Msk (0x1UL << GLPMCFG_REMWAKE_Pos) // 0x00000040 #define GLPMCFG_REMWAKE GLPMCFG_REMWAKE_Msk // bRemoteWake value received with last ACKed LPM Token #define GLPMCFG_L1SSEN_Pos (7U) #define GLPMCFG_L1SSEN_Msk (0x1UL << GLPMCFG_L1SSEN_Pos) // 0x00000080 #define GLPMCFG_L1SSEN GLPMCFG_L1SSEN_Msk // L1 shallow sleep enable #define GLPMCFG_BESLTHRS_Pos (8U) #define GLPMCFG_BESLTHRS_Msk (0xFUL << GLPMCFG_BESLTHRS_Pos) // 0x00000F00 #define GLPMCFG_BESLTHRS GLPMCFG_BESLTHRS_Msk // BESL threshold #define GLPMCFG_L1DSEN_Pos (12U) #define GLPMCFG_L1DSEN_Msk (0x1UL << GLPMCFG_L1DSEN_Pos) // 0x00001000 #define GLPMCFG_L1DSEN GLPMCFG_L1DSEN_Msk // L1 deep sleep enable #define GLPMCFG_LPMRSP_Pos (13U) #define GLPMCFG_LPMRSP_Msk (0x3UL << GLPMCFG_LPMRSP_Pos) // 0x00006000 #define GLPMCFG_LPMRSP GLPMCFG_LPMRSP_Msk // LPM response #define GLPMCFG_SLPSTS_Pos (15U) #define GLPMCFG_SLPSTS_Msk (0x1UL << GLPMCFG_SLPSTS_Pos) // 0x00008000 #define GLPMCFG_SLPSTS GLPMCFG_SLPSTS_Msk // Port sleep status #define GLPMCFG_L1RSMOK_Pos (16U) #define GLPMCFG_L1RSMOK_Msk (0x1UL << GLPMCFG_L1RSMOK_Pos) // 0x00010000 #define GLPMCFG_L1RSMOK GLPMCFG_L1RSMOK_Msk // Sleep State Resume OK #define GLPMCFG_LPMCHIDX_Pos (17U) #define GLPMCFG_LPMCHIDX_Msk (0xFUL << GLPMCFG_LPMCHIDX_Pos) // 0x001E0000 #define GLPMCFG_LPMCHIDX GLPMCFG_LPMCHIDX_Msk // LPM Channel Index #define GLPMCFG_LPMRCNT_Pos (21U) #define GLPMCFG_LPMRCNT_Msk (0x7UL << GLPMCFG_LPMRCNT_Pos) // 0x00E00000 #define GLPMCFG_LPMRCNT GLPMCFG_LPMRCNT_Msk // LPM retry count #define GLPMCFG_SNDLPM_Pos (24U) #define GLPMCFG_SNDLPM_Msk (0x1UL << GLPMCFG_SNDLPM_Pos) // 0x01000000 #define GLPMCFG_SNDLPM GLPMCFG_SNDLPM_Msk // Send LPM transaction #define GLPMCFG_LPMRCNTSTS_Pos (25U) #define GLPMCFG_LPMRCNTSTS_Msk (0x7UL << GLPMCFG_LPMRCNTSTS_Pos) // 0x0E000000 #define GLPMCFG_LPMRCNTSTS GLPMCFG_LPMRCNTSTS_Msk // LPM retry count status #define GLPMCFG_ENBESL_Pos (28U) #define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 #define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency // GDFIFOCFG #define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) #define GDFIFOCFG_EPINFOBASE_SHIFT 16 #define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) #define GDFIFOCFG_GDFIFOCFG_SHIFT 0 /******************** Bit definition for DIEPEACHMSK1 register ********************/ #define DIEPEACHMSK1_XFRCM_Pos (0U) #define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 #define DIEPEACHMSK1_XFRCM DIEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask #define DIEPEACHMSK1_EPDM_Pos (1U) #define DIEPEACHMSK1_EPDM_Msk (0x1UL << DIEPEACHMSK1_EPDM_Pos) // 0x00000002 #define DIEPEACHMSK1_EPDM DIEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask #define DIEPEACHMSK1_TOM_Pos (3U) #define DIEPEACHMSK1_TOM_Msk (0x1UL << DIEPEACHMSK1_TOM_Pos) // 0x00000008 #define DIEPEACHMSK1_TOM DIEPEACHMSK1_TOM_Msk // Timeout condition mask (nonisochronous endpoints) #define DIEPEACHMSK1_ITTXFEMSK_Pos (4U) #define DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DIEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 #define DIEPEACHMSK1_ITTXFEMSK DIEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DIEPEACHMSK1_INEPNMM_Pos (5U) #define DIEPEACHMSK1_INEPNMM_Msk (0x1UL << DIEPEACHMSK1_INEPNMM_Pos) // 0x00000020 #define DIEPEACHMSK1_INEPNMM DIEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask #define DIEPEACHMSK1_INEPNEM_Pos (6U) #define DIEPEACHMSK1_INEPNEM_Msk (0x1UL << DIEPEACHMSK1_INEPNEM_Pos) // 0x00000040 #define DIEPEACHMSK1_INEPNEM DIEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask #define DIEPEACHMSK1_TXFURM_Pos (8U) #define DIEPEACHMSK1_TXFURM_Msk (0x1UL << DIEPEACHMSK1_TXFURM_Pos) // 0x00000100 #define DIEPEACHMSK1_TXFURM DIEPEACHMSK1_TXFURM_Msk // FIFO underrun mask #define DIEPEACHMSK1_BIM_Pos (9U) #define DIEPEACHMSK1_BIM_Msk (0x1UL << DIEPEACHMSK1_BIM_Pos) // 0x00000200 #define DIEPEACHMSK1_BIM DIEPEACHMSK1_BIM_Msk // BNA interrupt mask #define DIEPEACHMSK1_NAKM_Pos (13U) #define DIEPEACHMSK1_NAKM_Msk (0x1UL << DIEPEACHMSK1_NAKM_Pos) // 0x00002000 #define DIEPEACHMSK1_NAKM DIEPEACHMSK1_NAKM_Msk // NAK interrupt mask /******************** Bit definition for HPRT register ********************/ #define HPRT_CONN_STATUS_Pos (0U) #define HPRT_CONN_STATUS_Msk (0x1UL << HPRT_CONN_STATUS_Pos) // 0x00000001 #define HPRT_CONN_STATUS HPRT_CONN_STATUS_Msk // Port connect status #define HPRT_CONN_DETECT_Pos (1U) #define HPRT_CONN_DETECT_Msk (0x1UL << HPRT_CONN_DETECT_Pos) // 0x00000002 #define HPRT_CONN_DETECT HPRT_CONN_DETECT_Msk // Port connect detected #define HPRT_ENABLE_Pos (2U) #define HPRT_ENABLE_Msk (0x1UL << HPRT_ENABLE_Pos) // 0x00000004 #define HPRT_ENABLE HPRT_ENABLE_Msk // Port enable #define HPRT_ENABLE_CHANGE_Pos (3U) #define HPRT_ENABLE_CHANGE_Msk (0x1UL << HPRT_ENABLE_CHANGE_Pos) // 0x00000008 #define HPRT_ENABLE_CHANGE HPRT_ENABLE_CHANGE_Msk // Port enable/disable change #define HPRT_OVER_CURRENT_ACTIVE_Pos (4U) #define HPRT_OVER_CURRENT_ACTIVE_Msk (0x1UL << HPRT_OVER_CURRENT_ACTIVE_Pos) // 0x00000010 #define HPRT_OVER_CURRENT_ACTIVE HPRT_OVER_CURRENT_ACTIVE_Msk // Port overcurrent active #define HPRT_OVER_CURRENT_CHANGE_Pos (5U) #define HPRT_OVER_CURRENT_CHANGE_Msk (0x1UL << HPRT_OVER_CURRENT_CHANGE_Pos) // 0x00000020 #define HPRT_OVER_CURRENT_CHANGE HPRT_OVER_CURRENT_CHANGE_Msk // Port overcurrent change #define HPRT_RESUME_Pos (6U) #define HPRT_RESUME_Msk (0x1UL << HPRT_RESUME_Pos) // 0x00000040 #define HPRT_RESUME HPRT_RESUME_Msk // Port resume #define HPRT_SUSPEND_Pos (7U) #define HPRT_SUSPEND_Msk (0x1UL << HPRT_SUSPEND_Pos) // 0x00000080 #define HPRT_SUSPEND HPRT_SUSPEND_Msk // Port suspend #define HPRT_RESET_Pos (8U) #define HPRT_RESET_Msk (0x1UL << HPRT_RESET_Pos) // 0x00000100 #define HPRT_RESET HPRT_RESET_Msk // Port reset #define HPRT_LINE_STATUS_Pos (10U) #define HPRT_LINE_STATUS_Msk (0x3UL << HPRT_LINE_STATUS_Pos) // 0x00000C00 #define HPRT_LINE_STATUS HPRT_LINE_STATUS_Msk // Port line status #define HPRT_LINE_STATUS_0 (0x1UL << HPRT_LINE_STATUS_Pos) // 0x00000400 #define HPRT_LINE_STATUS_1 (0x2UL << HPRT_LINE_STATUS_Pos) // 0x00000800 #define HPRT_POWER_Pos (12U) #define HPRT_POWER_Msk (0x1UL << HPRT_POWER_Pos) // 0x00001000 #define HPRT_POWER HPRT_POWER_Msk // Port power #define HPRT_TEST_CONTROL_Pos (13U) #define HPRT_TEST_CONTROL_Msk (0xFUL << HPRT_TEST_CONTROL_Pos) // 0x0001E000 #define HPRT_TEST_CONTROL HPRT_TEST_CONTROL_Msk // Port test control #define HPRT_TEST_CONTROL_0 (0x1UL << HPRT_TEST_CONTROL_Pos) // 0x00002000 #define HPRT_TEST_CONTROL_1 (0x2UL << HPRT_TEST_CONTROL_Pos) // 0x00004000 #define HPRT_TEST_CONTROL_2 (0x4UL << HPRT_TEST_CONTROL_Pos) // 0x00008000 #define HPRT_TEST_CONTROL_3 (0x8UL << HPRT_TEST_CONTROL_Pos) // 0x00010000 #define HPRT_SPEED_Pos (17U) #define HPRT_SPEED_Msk (0x3UL << HPRT_SPEED_Pos) // 0x00060000 #define HPRT_SPEED HPRT_SPEED_Msk // Port speed #define HPRT_SPEED_0 (0x1UL << HPRT_SPEED_Pos) // 0x00020000 #define HPRT_SPEED_1 (0x2UL << HPRT_SPEED_Pos) // 0x00040000 /******************** Bit definition for DOEPEACHMSK1 register ********************/ #define DOEPEACHMSK1_XFRCM_Pos (0U) #define DOEPEACHMSK1_XFRCM_Msk (0x1UL << DOEPEACHMSK1_XFRCM_Pos) // 0x00000001 #define DOEPEACHMSK1_XFRCM DOEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask #define DOEPEACHMSK1_EPDM_Pos (1U) #define DOEPEACHMSK1_EPDM_Msk (0x1UL << DOEPEACHMSK1_EPDM_Pos) // 0x00000002 #define DOEPEACHMSK1_EPDM DOEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask #define DOEPEACHMSK1_TOM_Pos (3U) #define DOEPEACHMSK1_TOM_Msk (0x1UL << DOEPEACHMSK1_TOM_Pos) // 0x00000008 #define DOEPEACHMSK1_TOM DOEPEACHMSK1_TOM_Msk // Timeout condition mask #define DOEPEACHMSK1_ITTXFEMSK_Pos (4U) #define DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DOEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 #define DOEPEACHMSK1_ITTXFEMSK DOEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DOEPEACHMSK1_INEPNMM_Pos (5U) #define DOEPEACHMSK1_INEPNMM_Msk (0x1UL << DOEPEACHMSK1_INEPNMM_Pos) // 0x00000020 #define DOEPEACHMSK1_INEPNMM DOEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask #define DOEPEACHMSK1_INEPNEM_Pos (6U) #define DOEPEACHMSK1_INEPNEM_Msk (0x1UL << DOEPEACHMSK1_INEPNEM_Pos) // 0x00000040 #define DOEPEACHMSK1_INEPNEM DOEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask #define DOEPEACHMSK1_TXFURM_Pos (8U) #define DOEPEACHMSK1_TXFURM_Msk (0x1UL << DOEPEACHMSK1_TXFURM_Pos) // 0x00000100 #define DOEPEACHMSK1_TXFURM DOEPEACHMSK1_TXFURM_Msk // OUT packet error mask #define DOEPEACHMSK1_BIM_Pos (9U) #define DOEPEACHMSK1_BIM_Msk (0x1UL << DOEPEACHMSK1_BIM_Pos) // 0x00000200 #define DOEPEACHMSK1_BIM DOEPEACHMSK1_BIM_Msk // BNA interrupt mask #define DOEPEACHMSK1_BERRM_Pos (12U) #define DOEPEACHMSK1_BERRM_Msk (0x1UL << DOEPEACHMSK1_BERRM_Pos) // 0x00001000 #define DOEPEACHMSK1_BERRM DOEPEACHMSK1_BERRM_Msk // Bubble error interrupt mask #define DOEPEACHMSK1_NAKM_Pos (13U) #define DOEPEACHMSK1_NAKM_Msk (0x1UL << DOEPEACHMSK1_NAKM_Pos) // 0x00002000 #define DOEPEACHMSK1_NAKM DOEPEACHMSK1_NAKM_Msk // NAK interrupt mask #define DOEPEACHMSK1_NYETM_Pos (14U) #define DOEPEACHMSK1_NYETM_Msk (0x1UL << DOEPEACHMSK1_NYETM_Pos) // 0x00004000 #define DOEPEACHMSK1_NYETM DOEPEACHMSK1_NYETM_Msk // NYET interrupt mask /******************** Bit definition for HPTXFSIZ register ********************/ #define HPTXFSIZ_PTXSA_Pos (0U) #define HPTXFSIZ_PTXSA_Msk (0xFFFFUL << HPTXFSIZ_PTXSA_Pos) // 0x0000FFFF #define HPTXFSIZ_PTXSA HPTXFSIZ_PTXSA_Msk // Host periodic TxFIFO start address #define HPTXFSIZ_PTXFD_Pos (16U) #define HPTXFSIZ_PTXFD_Msk (0xFFFFUL << HPTXFSIZ_PTXFD_Pos) // 0xFFFF0000 #define HPTXFSIZ_PTXFD HPTXFSIZ_PTXFD_Msk // Host periodic TxFIFO depth /******************** Bit definition for DIEPCTL register ********************/ #define DIEPCTL0_MPSIZ_Pos (0U) #define DIEPCTL0_MPSIZ_Msk (0x3UL << DIEPCTL0_MPSIZ_Pos) // 0x00000003 #define DIEPCTL0_MPSIZ DIEPCTL0_MPSIZ_Msk // Maximum packet size(endpoint 0) #define DIEPCTL_MPSIZ_Pos (0U) #define DIEPCTL_MPSIZ_Msk (0x7FFUL << DIEPCTL_MPSIZ_Pos) // 0x000007FF #define DIEPCTL_MPSIZ DIEPCTL_MPSIZ_Msk // Maximum packet size #define DIEPCTL_USBAEP_Pos (15U) #define DIEPCTL_USBAEP_Msk (0x1UL << DIEPCTL_USBAEP_Pos) // 0x00008000 #define DIEPCTL_USBAEP DIEPCTL_USBAEP_Msk // USB active endpoint #define DIEPCTL_EONUM_DPID_Pos (16U) #define DIEPCTL_EONUM_DPID_Msk (0x1UL << DIEPCTL_EONUM_DPID_Pos) // 0x00010000 #define DIEPCTL_EONUM_DPID DIEPCTL_EONUM_DPID_Msk // Even/odd frame #define DIEPCTL_NAKSTS_Pos (17U) #define DIEPCTL_NAKSTS_Msk (0x1UL << DIEPCTL_NAKSTS_Pos) // 0x00020000 #define DIEPCTL_NAKSTS DIEPCTL_NAKSTS_Msk // NAK status #define DIEPCTL_EPTYP_Pos (18U) #define DIEPCTL_EPTYP_Msk (0x3UL << DIEPCTL_EPTYP_Pos) // 0x000C0000 #define DIEPCTL_EPTYP DIEPCTL_EPTYP_Msk // Endpoint type #define DIEPCTL_EPTYP_0 (0x1UL << DIEPCTL_EPTYP_Pos) // 0x00040000 #define DIEPCTL_EPTYP_1 (0x2UL << DIEPCTL_EPTYP_Pos) // 0x00080000 #define DIEPCTL_STALL_Pos (21U) #define DIEPCTL_STALL_Msk (0x1UL << DIEPCTL_STALL_Pos) // 0x00200000 #define DIEPCTL_STALL DIEPCTL_STALL_Msk // STALL handshake #define DIEPCTL_TXFNUM_Pos (22U) #define DIEPCTL_TXFNUM_Msk (0xFUL << DIEPCTL_TXFNUM_Pos) // 0x03C00000 #define DIEPCTL_TXFNUM DIEPCTL_TXFNUM_Msk // TxFIFO number #define DIEPCTL_TXFNUM_0 (0x1UL << DIEPCTL_TXFNUM_Pos) // 0x00400000 #define DIEPCTL_TXFNUM_1 (0x2UL << DIEPCTL_TXFNUM_Pos) // 0x00800000 #define DIEPCTL_TXFNUM_2 (0x4UL << DIEPCTL_TXFNUM_Pos) // 0x01000000 #define DIEPCTL_TXFNUM_3 (0x8UL << DIEPCTL_TXFNUM_Pos) // 0x02000000 #define DIEPCTL_CNAK_Pos (26U) #define DIEPCTL_CNAK_Msk (0x1UL << DIEPCTL_CNAK_Pos) // 0x04000000 #define DIEPCTL_CNAK DIEPCTL_CNAK_Msk // Clear NAK #define DIEPCTL_SNAK_Pos (27U) #define DIEPCTL_SNAK_Msk (0x1UL << DIEPCTL_SNAK_Pos) // 0x08000000 #define DIEPCTL_SNAK DIEPCTL_SNAK_Msk // Set NAK #define DIEPCTL_SD0PID_SEVNFRM_Pos (28U) #define DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DIEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 #define DIEPCTL_SD0PID_SEVNFRM DIEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID #define DIEPCTL_SODDFRM_Pos (29U) #define DIEPCTL_SODDFRM_Msk (0x1UL << DIEPCTL_SODDFRM_Pos) // 0x20000000 #define DIEPCTL_SODDFRM DIEPCTL_SODDFRM_Msk // Set odd frame #define DIEPCTL_EPDIS_Pos (30U) #define DIEPCTL_EPDIS_Msk (0x1UL << DIEPCTL_EPDIS_Pos) // 0x40000000 #define DIEPCTL_EPDIS DIEPCTL_EPDIS_Msk // Endpoint disable #define DIEPCTL_EPENA_Pos (31U) #define DIEPCTL_EPENA_Msk (0x1UL << DIEPCTL_EPENA_Pos) // 0x80000000 #define DIEPCTL_EPENA DIEPCTL_EPENA_Msk // Endpoint enable /******************** Bit definition for HCCHAR register ********************/ #define HCCHAR_MPSIZ_Pos (0U) #define HCCHAR_MPSIZ_Msk (0x7FFUL << HCCHAR_MPSIZ_Pos) // 0x000007FF #define HCCHAR_MPSIZ HCCHAR_MPSIZ_Msk // Maximum packet size #define HCCHAR_EPNUM_Pos (11U) #define HCCHAR_EPNUM_Msk (0xFUL << HCCHAR_EPNUM_Pos) // 0x00007800 #define HCCHAR_EPNUM HCCHAR_EPNUM_Msk // Endpoint number #define HCCHAR_EPNUM_0 (0x1UL << HCCHAR_EPNUM_Pos) // 0x00000800 #define HCCHAR_EPNUM_1 (0x2UL << HCCHAR_EPNUM_Pos) // 0x00001000 #define HCCHAR_EPNUM_2 (0x4UL << HCCHAR_EPNUM_Pos) // 0x00002000 #define HCCHAR_EPNUM_3 (0x8UL << HCCHAR_EPNUM_Pos) // 0x00004000 #define HCCHAR_EPDIR_Pos (15U) #define HCCHAR_EPDIR_Msk (0x1UL << HCCHAR_EPDIR_Pos) // 0x00008000 #define HCCHAR_EPDIR HCCHAR_EPDIR_Msk // Endpoint direction #define HCCHAR_LSDEV_Pos (17U) #define HCCHAR_LSDEV_Msk (0x1UL << HCCHAR_LSDEV_Pos) // 0x00020000 #define HCCHAR_LSDEV HCCHAR_LSDEV_Msk // Low-speed device #define HCCHAR_EPTYP_Pos (18U) #define HCCHAR_EPTYP_Msk (0x3UL << HCCHAR_EPTYP_Pos) // 0x000C0000 #define HCCHAR_EPTYP HCCHAR_EPTYP_Msk // Endpoint type #define HCCHAR_EPTYP_0 (0x1UL << HCCHAR_EPTYP_Pos) // 0x00040000 #define HCCHAR_EPTYP_1 (0x2UL << HCCHAR_EPTYP_Pos) // 0x00080000 #define HCCHAR_MC_Pos (20U) #define HCCHAR_MC_Msk (0x3UL << HCCHAR_MC_Pos) // 0x00300000 #define HCCHAR_MC HCCHAR_MC_Msk // Multi Count (MC) / Error Count (EC) #define HCCHAR_MC_0 (0x1UL << HCCHAR_MC_Pos) // 0x00100000 #define HCCHAR_MC_1 (0x2UL << HCCHAR_MC_Pos) // 0x00200000 #define HCCHAR_DAD_Pos (22U) #define HCCHAR_DAD_Msk (0x7FUL << HCCHAR_DAD_Pos) // 0x1FC00000 #define HCCHAR_DAD HCCHAR_DAD_Msk // Device address #define HCCHAR_DAD_0 (0x01UL << HCCHAR_DAD_Pos) // 0x00400000 #define HCCHAR_DAD_1 (0x02UL << HCCHAR_DAD_Pos) // 0x00800000 #define HCCHAR_DAD_2 (0x04UL << HCCHAR_DAD_Pos) // 0x01000000 #define HCCHAR_DAD_3 (0x08UL << HCCHAR_DAD_Pos) // 0x02000000 #define HCCHAR_DAD_4 (0x10UL << HCCHAR_DAD_Pos) // 0x04000000 #define HCCHAR_DAD_5 (0x20UL << HCCHAR_DAD_Pos) // 0x08000000 #define HCCHAR_DAD_6 (0x40UL << HCCHAR_DAD_Pos) // 0x10000000 #define HCCHAR_ODDFRM_Pos (29U) #define HCCHAR_ODDFRM_Msk (0x1UL << HCCHAR_ODDFRM_Pos) // 0x20000000 #define HCCHAR_ODDFRM HCCHAR_ODDFRM_Msk // Odd frame #define HCCHAR_CHDIS_Pos (30U) #define HCCHAR_CHDIS_Msk (0x1UL << HCCHAR_CHDIS_Pos) // 0x40000000 #define HCCHAR_CHDIS HCCHAR_CHDIS_Msk // Channel disable #define HCCHAR_CHENA_Pos (31U) #define HCCHAR_CHENA_Msk (0x1UL << HCCHAR_CHENA_Pos) // 0x80000000 #define HCCHAR_CHENA HCCHAR_CHENA_Msk // Channel enable /******************** Bit definition for HCSPLT register ********************/ #define HCSPLT_PRTADDR_Pos (0U) #define HCSPLT_PRTADDR_Msk (0x7FUL << HCSPLT_PRTADDR_Pos) // 0x0000007F #define HCSPLT_PRTADDR HCSPLT_PRTADDR_Msk // Port address #define HCSPLT_PRTADDR_0 (0x01UL << HCSPLT_PRTADDR_Pos) // 0x00000001 #define HCSPLT_PRTADDR_1 (0x02UL << HCSPLT_PRTADDR_Pos) // 0x00000002 #define HCSPLT_PRTADDR_2 (0x04UL << HCSPLT_PRTADDR_Pos) // 0x00000004 #define HCSPLT_PRTADDR_3 (0x08UL << HCSPLT_PRTADDR_Pos) // 0x00000008 #define HCSPLT_PRTADDR_4 (0x10UL << HCSPLT_PRTADDR_Pos) // 0x00000010 #define HCSPLT_PRTADDR_5 (0x20UL << HCSPLT_PRTADDR_Pos) // 0x00000020 #define HCSPLT_PRTADDR_6 (0x40UL << HCSPLT_PRTADDR_Pos) // 0x00000040 #define HCSPLT_HUBADDR_Pos (7U) #define HCSPLT_HUBADDR_Msk (0x7FUL << HCSPLT_HUBADDR_Pos) // 0x00003F80 #define HCSPLT_HUBADDR HCSPLT_HUBADDR_Msk // Hub address #define HCSPLT_HUBADDR_0 (0x01UL << HCSPLT_HUBADDR_Pos) // 0x00000080 #define HCSPLT_HUBADDR_1 (0x02UL << HCSPLT_HUBADDR_Pos) // 0x00000100 #define HCSPLT_HUBADDR_2 (0x04UL << HCSPLT_HUBADDR_Pos) // 0x00000200 #define HCSPLT_HUBADDR_3 (0x08UL << HCSPLT_HUBADDR_Pos) // 0x00000400 #define HCSPLT_HUBADDR_4 (0x10UL << HCSPLT_HUBADDR_Pos) // 0x00000800 #define HCSPLT_HUBADDR_5 (0x20UL << HCSPLT_HUBADDR_Pos) // 0x00001000 #define HCSPLT_HUBADDR_6 (0x40UL << HCSPLT_HUBADDR_Pos) // 0x00002000 #define HCSPLT_XACTPOS_Pos (14U) #define HCSPLT_XACTPOS_Msk (0x3UL << HCSPLT_XACTPOS_Pos) // 0x0000C000 #define HCSPLT_XACTPOS HCSPLT_XACTPOS_Msk // XACTPOS #define HCSPLT_XACTPOS_0 (0x1UL << HCSPLT_XACTPOS_Pos) // 0x00004000 #define HCSPLT_XACTPOS_1 (0x2UL << HCSPLT_XACTPOS_Pos) // 0x00008000 #define HCSPLT_COMPLSPLT_Pos (16U) #define HCSPLT_COMPLSPLT_Msk (0x1UL << HCSPLT_COMPLSPLT_Pos) // 0x00010000 #define HCSPLT_COMPLSPLT HCSPLT_COMPLSPLT_Msk // Do complete split #define HCSPLT_SPLITEN_Pos (31U) #define HCSPLT_SPLITEN_Msk (0x1UL << HCSPLT_SPLITEN_Pos) // 0x80000000 #define HCSPLT_SPLITEN HCSPLT_SPLITEN_Msk // Split enable /******************** Bit definition for HCINT register ********************/ #define HCINT_XFER_COMPLETE_Pos (0U) #define HCINT_XFER_COMPLETE_Msk (0x1UL << HCINT_XFER_COMPLETE_Pos) // 0x00000001 #define HCINT_XFER_COMPLETE HCINT_XFER_COMPLETE_Msk // Transfer completed #define HCINT_HALTED_Pos (1U) #define HCINT_HALTED_Msk (0x1UL << HCINT_HALTED_Pos) // 0x00000002 #define HCINT_HALTED HCINT_HALTED_Msk // Channel halted #define HCINT_AHB_ERR_Pos (2U) #define HCINT_AHB_ERR_Msk (0x1UL << HCINT_AHB_ERR_Pos) // 0x00000004 #define HCINT_AHB_ERR HCINT_AHB_ERR_Msk // AHB error #define HCINT_STALL_Pos (3U) #define HCINT_STALL_Msk (0x1UL << HCINT_STALL_Pos) // 0x00000008 #define HCINT_STALL HCINT_STALL_Msk // STALL response received interrupt #define HCINT_NAK_Pos (4U) #define HCINT_NAK_Msk (0x1UL << HCINT_NAK_Pos) // 0x00000010 #define HCINT_NAK HCINT_NAK_Msk // NAK response received interrupt #define HCINT_ACK_Pos (5U) #define HCINT_ACK_Msk (0x1UL << HCINT_ACK_Pos) // 0x00000020 #define HCINT_ACK HCINT_ACK_Msk // ACK response received/transmitted interrupt #define HCINT_NYET_Pos (6U) #define HCINT_NYET_Msk (0x1UL << HCINT_NYET_Pos) // 0x00000040 #define HCINT_NYET HCINT_NYET_Msk // Response received interrupt #define HCINT_XACT_ERR_Pos (7U) #define HCINT_XACT_ERR_Msk (0x1UL << HCINT_XACT_ERR_Pos) // 0x00000080 #define HCINT_XACT_ERR HCINT_XACT_ERR_Msk // Transaction error #define HCINT_BABBLE_ERR_Pos (8U) #define HCINT_BABBLE_ERR_Msk (0x1UL << HCINT_BABBLE_ERR_Pos) // 0x00000100 #define HCINT_BABBLE_ERR HCINT_BABBLE_ERR_Msk // Babble error #define HCINT_FARME_OVERRUN_Pos (9U) #define HCINT_FARME_OVERRUN_Msk (0x1UL << HCINT_FARME_OVERRUN_Pos) // 0x00000200 #define HCINT_FARME_OVERRUN HCINT_FARME_OVERRUN_Msk // Frame overrun #define HCINT_DATATOGGLE_ERR_Pos (10U) #define HCINT_DATATOGGLE_ERR_Msk (0x1UL << HCINT_DATATOGGLE_ERR_Pos) // 0x00000400 #define HCINT_DATATOGGLE_ERR HCINT_DATATOGGLE_ERR_Msk // Data toggle error #define HCINT_BUFFER_NA_Pos (11U) #define HCINT_BUFFER_NA_Msk (0x1UL << HCINT_BUFFER_NA_Pos) // 0x00000800 #define HCINT_BUFFER_NA HCINT_BUFFER_NA_Msk // Buffer not available interrupt #define HCINT_XCS_XACT_ERR_Pos (12U) #define HCINT_XCS_XACT_ERR_Msk (0x1UL << HCINT_XCS_XACT_ERR_Pos) // 0x00001000 #define HCINT_XCS_XACT_ERR HCINT_XCS_XACT_ERR_Msk // Excessive transaction error #define HCINT_DESC_ROLLOVER_Pos (13U) #define HCINT_DESC_ROLLOVER_Msk (0x1UL << HCINT_DESC_ROLLOVER_Pos) // 0x00002000 #define HCINT_DESC_ROLLOVER HCINT_DESC_ROLLOVER_Msk // Descriptor rollover /******************** Bit definition for DIEPINT register ********************/ #define DIEPINT_XFRC_Pos (0U) #define DIEPINT_XFRC_Msk (0x1UL << DIEPINT_XFRC_Pos) // 0x00000001 #define DIEPINT_XFRC DIEPINT_XFRC_Msk // Transfer completed interrupt #define DIEPINT_EPDISD_Pos (1U) #define DIEPINT_EPDISD_Msk (0x1UL << DIEPINT_EPDISD_Pos) // 0x00000002 #define DIEPINT_EPDISD DIEPINT_EPDISD_Msk // Endpoint disabled interrupt #define DIEPINT_AHBERR_Pos (2U) #define DIEPINT_AHBERR_Msk (0x1UL << DIEPINT_AHBERR_Pos) // 0x00000004 #define DIEPINT_AHBERR DIEPINT_AHBERR_Msk // AHB Error (AHBErr) during an IN transaction #define DIEPINT_TOC_Pos (3U) #define DIEPINT_TOC_Msk (0x1UL << DIEPINT_TOC_Pos) // 0x00000008 #define DIEPINT_TOC DIEPINT_TOC_Msk // Timeout condition #define DIEPINT_ITTXFE_Pos (4U) #define DIEPINT_ITTXFE_Msk (0x1UL << DIEPINT_ITTXFE_Pos) // 0x00000010 #define DIEPINT_ITTXFE DIEPINT_ITTXFE_Msk // IN token received when TxFIFO is empty #define DIEPINT_INEPNM_Pos (5U) #define DIEPINT_INEPNM_Msk (0x1UL << DIEPINT_INEPNM_Pos) // 0x00000020 #define DIEPINT_INEPNM DIEPINT_INEPNM_Msk // IN token received with EP mismatch #define DIEPINT_INEPNE_Pos (6U) #define DIEPINT_INEPNE_Msk (0x1UL << DIEPINT_INEPNE_Pos) // 0x00000040 #define DIEPINT_INEPNE DIEPINT_INEPNE_Msk // IN endpoint NAK effective #define DIEPINT_TXFE_Pos (7U) #define DIEPINT_TXFE_Msk (0x1UL << DIEPINT_TXFE_Pos) // 0x00000080 #define DIEPINT_TXFE DIEPINT_TXFE_Msk // Transmit FIFO empty #define DIEPINT_TXFIFOUDRN_Pos (8U) #define DIEPINT_TXFIFOUDRN_Msk (0x1UL << DIEPINT_TXFIFOUDRN_Pos) // 0x00000100 #define DIEPINT_TXFIFOUDRN DIEPINT_TXFIFOUDRN_Msk // Transmit Fifo Underrun #define DIEPINT_BNA_Pos (9U) #define DIEPINT_BNA_Msk (0x1UL << DIEPINT_BNA_Pos) // 0x00000200 #define DIEPINT_BNA DIEPINT_BNA_Msk // Buffer not available interrupt #define DIEPINT_PKTDRPSTS_Pos (11U) #define DIEPINT_PKTDRPSTS_Msk (0x1UL << DIEPINT_PKTDRPSTS_Pos) // 0x00000800 #define DIEPINT_PKTDRPSTS DIEPINT_PKTDRPSTS_Msk // Packet dropped status #define DIEPINT_BERR_Pos (12U) #define DIEPINT_BERR_Msk (0x1UL << DIEPINT_BERR_Pos) // 0x00001000 #define DIEPINT_BERR DIEPINT_BERR_Msk // Babble error interrupt #define DIEPINT_NAK_Pos (13U) #define DIEPINT_NAK_Msk (0x1UL << DIEPINT_NAK_Pos) // 0x00002000 #define DIEPINT_NAK DIEPINT_NAK_Msk // NAK interrupt /******************** Bit definition for DIEPTSIZ register ********************/ #define DIEPTSIZ_XFRSIZ_Pos (0U) #define DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DIEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF #define DIEPTSIZ_XFRSIZ DIEPTSIZ_XFRSIZ_Msk // Transfer size #define DIEPTSIZ_PKTCNT_Pos (19U) #define DIEPTSIZ_PKTCNT_Msk (0x3FFUL << DIEPTSIZ_PKTCNT_Pos) // 0x1FF80000 #define DIEPTSIZ_PKTCNT DIEPTSIZ_PKTCNT_Msk // Packet count #define DIEPTSIZ_MULCNT_Pos (29U) #define DIEPTSIZ_MULCNT_Msk (0x3UL << DIEPTSIZ_MULCNT_Pos) // 0x60000000 #define DIEPTSIZ_MULCNT DIEPTSIZ_MULCNT_Msk // Packet count /******************** Bit definition for HCTSIZ register ********************/ #define HCTSIZ_XFRSIZ_Pos (0U) #define HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << HCTSIZ_XFRSIZ_Pos) // 0x0007FFFF #define HCTSIZ_XFRSIZ HCTSIZ_XFRSIZ_Msk // Transfer size #define HCTSIZ_PKTCNT_Pos (19U) #define HCTSIZ_PKTCNT_Msk (0x3FFUL << HCTSIZ_PKTCNT_Pos) // 0x1FF80000 #define HCTSIZ_PKTCNT HCTSIZ_PKTCNT_Msk // Packet count #define HCTSIZ_DOPING_Pos (31U) #define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000 #define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING #define HCTSIZ_PID_Pos (29U) #define HCTSIZ_PID_Msk (0x3UL << HCTSIZ_PID_Pos) // 0x60000000 #define HCTSIZ_PID HCTSIZ_PID_Msk // Data PID /******************** Bit definition for DIEPDMA register ********************/ #define DIEPDMA_DMAADDR_Pos (0U) #define DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << DIEPDMA_DMAADDR_Pos) // 0xFFFFFFFF #define DIEPDMA_DMAADDR DIEPDMA_DMAADDR_Msk // DMA address /******************** Bit definition for HCDMA register ********************/ #define HCDMA_DMAADDR_Pos (0U) #define HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << HCDMA_DMAADDR_Pos) // 0xFFFFFFFF #define HCDMA_DMAADDR HCDMA_DMAADDR_Msk // DMA address /******************** Bit definition for DTXFSTS register ********************/ #define DTXFSTS_INEPTFSAV_Pos (0U) #define DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << DTXFSTS_INEPTFSAV_Pos) // 0x0000FFFF #define DTXFSTS_INEPTFSAV DTXFSTS_INEPTFSAV_Msk // IN endpoint TxFIFO space available /******************** Bit definition for DIEPTXF register ********************/ #define DIEPTXF_INEPTXSA_Pos (0U) #define DIEPTXF_INEPTXSA_Msk (0xFFFFUL << DIEPTXF_INEPTXSA_Pos) // 0x0000FFFF #define DIEPTXF_INEPTXSA DIEPTXF_INEPTXSA_Msk // IN endpoint FIFOx transmit RAM start address #define DIEPTXF_INEPTXFD_Pos (16U) #define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 #define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth /******************** Bit definition for Common EPCTL register ********************/ #define EPCTL_MPSIZ_Pos (0U) #define EPCTL_MPSIZ_Msk (0x7FFUL << EPCTL_MPSIZ_Pos) // 0x000007FF #define EPCTL_MPSIZ EPCTL_MPSIZ_Msk // Maximum packet size //Bit 1 #define EPCTL_USBAEP_Pos (15U) #define EPCTL_USBAEP_Msk (0x1UL << EPCTL_USBAEP_Pos) // 0x00008000 #define EPCTL_USBAEP EPCTL_USBAEP_Msk // USB active endpoint #define EPCTL_NAKSTS_Pos (17U) #define EPCTL_NAKSTS_Msk (0x1UL << EPCTL_NAKSTS_Pos) // 0x00020000 #define EPCTL_NAKSTS EPCTL_NAKSTS_Msk // NAK status #define EPCTL_EPTYP_Pos (18U) #define EPCTL_EPTYP_Msk (0x3UL << EPCTL_EPTYP_Pos) // 0x000C0000 #define EPCTL_EPTYP EPCTL_EPTYP_Msk // Endpoint type #define EPCTL_EPTYP_0 (0x1UL << EPCTL_EPTYP_Pos) // 0x00040000 #define EPCTL_EPTYP_1 (0x2UL << EPCTL_EPTYP_Pos) // 0x00080000 #define EPCTL_SNPM EPCTL_SNPM_Msk // Snoop mode #define EPCTL_STALL_Pos (21U) #define EPCTL_STALL_Msk (0x1UL << EPCTL_STALL_Pos) // 0x00200000 #define EPCTL_STALL EPCTL_STALL_Msk // STALL handshake #define EPCTL_CNAK_Pos (26U) #define EPCTL_CNAK_Msk (0x1UL << EPCTL_CNAK_Pos) // 0x04000000 #define EPCTL_CNAK EPCTL_CNAK_Msk // Clear NAK #define EPCTL_SNAK_Pos (27U) #define EPCTL_SNAK_Msk (0x1UL << EPCTL_SNAK_Pos) // 0x08000000 #define EPCTL_SNAK EPCTL_SNAK_Msk // Set NAK #define EPCTL_SD0PID_SEVNFRM_Pos (28U) #define EPCTL_SD0PID_SEVNFRM_Msk (0x1UL << EPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 #define EPCTL_SD0PID_SEVNFRM EPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID #define EPCTL_SODDFRM_Pos (29U) #define EPCTL_SODDFRM_Msk (0x1UL << EPCTL_SODDFRM_Pos) // 0x20000000 #define EPCTL_SODDFRM EPCTL_SODDFRM_Msk // Set odd frame #define EPCTL_EPDIS_Pos (30U) #define EPCTL_EPDIS_Msk (0x1UL << EPCTL_EPDIS_Pos) // 0x40000000 #define EPCTL_EPDIS EPCTL_EPDIS_Msk // Endpoint disable #define EPCTL_EPENA_Pos (31U) #define EPCTL_EPENA_Msk (0x1UL << EPCTL_EPENA_Pos) // 0x80000000 #define EPCTL_EPENA EPCTL_EPENA_Msk // Endpoint enable /******************** Bit definition for DOEPCTL register ********************/ #define DOEPCTL0_MPSIZ_Pos (0U) #define DOEPCTL0_MPSIZ_Msk (0x3UL << DOEPCTL0_MPSIZ_Pos) // 0x00000003 #define DOEPCTL0_MPSIZ DOEPCTL0_MPSIZ_Msk // Maximum packet size(endpoint 0) #define DOEPCTL_MPSIZ_Pos (0U) #define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF #define DOEPCTL_MPSIZ DOEPCTL_MPSIZ_Msk // Maximum packet size //Bit 1 #define DOEPCTL_USBAEP_Pos (15U) #define DOEPCTL_USBAEP_Msk (0x1UL << DOEPCTL_USBAEP_Pos) // 0x00008000 #define DOEPCTL_USBAEP DOEPCTL_USBAEP_Msk // USB active endpoint #define DOEPCTL_NAKSTS_Pos (17U) #define DOEPCTL_NAKSTS_Msk (0x1UL << DOEPCTL_NAKSTS_Pos) // 0x00020000 #define DOEPCTL_NAKSTS DOEPCTL_NAKSTS_Msk // NAK status #define DOEPCTL_SD0PID_SEVNFRM_Pos (28U) #define DOEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DOEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 #define DOEPCTL_SD0PID_SEVNFRM DOEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID #define DOEPCTL_SODDFRM_Pos (29U) #define DOEPCTL_SODDFRM_Msk (0x1UL << DOEPCTL_SODDFRM_Pos) // 0x20000000 #define DOEPCTL_SODDFRM DOEPCTL_SODDFRM_Msk // Set odd frame #define DOEPCTL_EPTYP_Pos (18U) #define DOEPCTL_EPTYP_Msk (0x3UL << DOEPCTL_EPTYP_Pos) // 0x000C0000 #define DOEPCTL_EPTYP DOEPCTL_EPTYP_Msk // Endpoint type #define DOEPCTL_EPTYP_0 (0x1UL << DOEPCTL_EPTYP_Pos) // 0x00040000 #define DOEPCTL_EPTYP_1 (0x2UL << DOEPCTL_EPTYP_Pos) // 0x00080000 #define DOEPCTL_SNPM_Pos (20U) #define DOEPCTL_SNPM_Msk (0x1UL << DOEPCTL_SNPM_Pos) // 0x00100000 #define DOEPCTL_SNPM DOEPCTL_SNPM_Msk // Snoop mode #define DOEPCTL_STALL_Pos (21U) #define DOEPCTL_STALL_Msk (0x1UL << DOEPCTL_STALL_Pos) // 0x00200000 #define DOEPCTL_STALL DOEPCTL_STALL_Msk // STALL handshake #define DOEPCTL_CNAK_Pos (26U) #define DOEPCTL_CNAK_Msk (0x1UL << DOEPCTL_CNAK_Pos) // 0x04000000 #define DOEPCTL_CNAK DOEPCTL_CNAK_Msk // Clear NAK #define DOEPCTL_SNAK_Pos (27U) #define DOEPCTL_SNAK_Msk (0x1UL << DOEPCTL_SNAK_Pos) // 0x08000000 #define DOEPCTL_SNAK DOEPCTL_SNAK_Msk // Set NAK #define DOEPCTL_EPDIS_Pos (30U) #define DOEPCTL_EPDIS_Msk (0x1UL << DOEPCTL_EPDIS_Pos) // 0x40000000 #define DOEPCTL_EPDIS DOEPCTL_EPDIS_Msk // Endpoint disable #define DOEPCTL_EPENA_Pos (31U) #define DOEPCTL_EPENA_Msk (0x1UL << DOEPCTL_EPENA_Pos) // 0x80000000 #define DOEPCTL_EPENA DOEPCTL_EPENA_Msk // Endpoint enable /******************** Bit definition for DOEPINT register ********************/ #define DOEPINT_XFRC_Pos (0U) #define DOEPINT_XFRC_Msk (0x1UL << DOEPINT_XFRC_Pos) // 0x00000001 #define DOEPINT_XFRC DOEPINT_XFRC_Msk // Transfer completed interrupt #define DOEPINT_EPDISD_Pos (1U) #define DOEPINT_EPDISD_Msk (0x1UL << DOEPINT_EPDISD_Pos) // 0x00000002 #define DOEPINT_EPDISD DOEPINT_EPDISD_Msk // Endpoint disabled interrupt #define DOEPINT_AHBERR_Pos (2U) #define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 #define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction #define DOEPINT_SETUP_Pos (3U) #define DOEPINT_SETUP_Msk (0x1UL << DOEPINT_SETUP_Pos) // 0x00000008 #define DOEPINT_SETUP DOEPINT_SETUP_Msk // SETUP phase done #define DOEPINT_OTEPDIS_Pos (4U) #define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 #define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled #define DOEPINT_STSPHSRX_Pos (5U) #define DOEPINT_STSPHSRX_Msk (0x1UL << DOEPINT_STSPHSRX_Pos) // 0x00000020 #define DOEPINT_STSPHSRX DOEPINT_STSPHSRX_Msk // Status Phase Received For Control Write #define DOEPINT_B2BSTUP_Pos (6U) #define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 #define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received #define DOEPINT_OUTPKTERR_Pos (8U) #define DOEPINT_OUTPKTERR_Msk (0x1UL << DOEPINT_OUTPKTERR_Pos) // 0x00000100 #define DOEPINT_OUTPKTERR DOEPINT_OUTPKTERR_Msk // OUT packet error #define DOEPINT_NAK_Pos (13U) #define DOEPINT_NAK_Msk (0x1UL << DOEPINT_NAK_Pos) // 0x00002000 #define DOEPINT_NAK DOEPINT_NAK_Msk // NAK Packet is transmitted by the device #define DOEPINT_NYET_Pos (14U) #define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 #define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt #define DOEPINT_STPKTRX_Pos (15U) #define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 #define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) #define DOEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DOEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF #define DOEPTSIZ_XFRSIZ DOEPTSIZ_XFRSIZ_Msk // Transfer size #define DOEPTSIZ_PKTCNT_Pos (19U) #define DOEPTSIZ_PKTCNT_Msk (0x3FFUL << DOEPTSIZ_PKTCNT_Pos) // 0x1FF80000 #define DOEPTSIZ_PKTCNT DOEPTSIZ_PKTCNT_Msk // Packet count #define DOEPTSIZ_STUPCNT_Pos (29U) #define DOEPTSIZ_STUPCNT_Msk (0x3UL << DOEPTSIZ_STUPCNT_Pos) // 0x60000000 #define DOEPTSIZ_STUPCNT DOEPTSIZ_STUPCNT_Msk // SETUP packet count #define DOEPTSIZ_STUPCNT_0 (0x1UL << DOEPTSIZ_STUPCNT_Pos) // 0x20000000 #define DOEPTSIZ_STUPCNT_1 (0x2UL << DOEPTSIZ_STUPCNT_Pos) // 0x40000000 /******************** Bit definition for PCGCTL register ********************/ #define PCGCCTL_IF_DEV_MODE TU_BIT(31) #define PCGCCTL_P2HD_PRT_SPD_MASK (0x3ul << 29) #define PCGCCTL_P2HD_PRT_SPD_SHIFT 29 #define PCGCCTL_P2HD_DEV_ENUM_SPD_MASK (0x3ul << 27) #define PCGCCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 #define PCGCCTL_MAC_DEV_ADDR_MASK (0x7ful << 20) #define PCGCCTL_MAC_DEV_ADDR_SHIFT 20 #define PCGCCTL_MAX_TERMSEL TU_BIT(19) #define PCGCCTL_MAX_XCVRSELECT_MASK (0x3ul << 17) #define PCGCCTL_MAX_XCVRSELECT_SHIFT 17 #define PCGCCTL_PORT_POWER TU_BIT(16) #define PCGCCTL_PRT_CLK_SEL_MASK (0x3ul << 14) #define PCGCCTL_PRT_CLK_SEL_SHIFT 14 #define PCGCCTL_ESS_REG_RESTORED TU_BIT(13) #define PCGCCTL_EXTND_HIBER_SWITCH TU_BIT(12) #define PCGCCTL_EXTND_HIBER_PWRCLMP TU_BIT(11) #define PCGCCTL_ENBL_EXTND_HIBER TU_BIT(10) #define PCGCCTL_RESTOREMODE TU_BIT(9) #define PCGCCTL_RESETAFTSUSP TU_BIT(8) #define PCGCCTL_DEEP_SLEEP TU_BIT(7) #define PCGCCTL_PHY_IN_SLEEP TU_BIT(6) #define PCGCCTL_ENBL_SLEEP_GATING TU_BIT(5) #define PCGCCTL_RSTPDWNMODULE TU_BIT(3) #define PCGCCTL_PWRCLMP TU_BIT(2) #define PCGCCTL_GATEHCLK TU_BIT(1) #define PCGCCTL_STOPPCLK TU_BIT(0) #define PCGCTL1_TIMER (0x3ul << 1) #define PCGCTL1_GATEEN TU_BIT(0) #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/dwc2_xmc.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2021 Rafael Silva (@perigoso) * Copyright (c) 2021, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef _DWC2_XMC_H_ #define _DWC2_XMC_H_ #ifdef __cplusplus extern "C" { #endif #include "xmc_device.h" #define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { // Note: XMC has some custom control registers before DWC registers { .reg_base = USB0_BASE, .irqnum = USB0_0_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 2048 } }; TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(_dwc2_controller[rhport].irqnum); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable (uint8_t rhport) { NVIC_DisableIRQ(_dwc2_controller[rhport].irqnum); } static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms // uint32_t count = SystemCoreClock / 1000; // while ( count-- ) __NOP(); } // MCU specific PHY init, called BEFORE core reset static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // Enable PHY //USB->ROUTE = USB_ROUTE_PHYPEN; } // MCU specific PHY deinit, disable PHY power static inline void dwc2_phy_deinit(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // nothing to do } // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) { (void) dwc2; (void) hs_phy_type; // XMC Manual: turn around must be 5 (reset & default value) // dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/portable/synopsys/dwc2/hcd_dwc2.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_DWC2) && !CFG_TUH_MAX3421 #if !(CFG_TUH_DWC2_SLAVE_ENABLE || CFG_TUH_DWC2_DMA_ENABLE) #error DWC2 require either CFG_TUH_DWC2_SLAVE_ENABLE or CFG_TUH_DWC2_DMA_ENABLE to be enabled #endif #include "host/hcd.h" #include "host/usbh.h" #include "dwc2_common.h" // Debug level for DWC2 #define DWC2_DEBUG 2 // Max number of endpoints application can open, can be larger than DWC2_CHANNEL_COUNT_MAX #ifndef CFG_TUH_DWC2_ENDPOINT_MAX #define CFG_TUH_DWC2_ENDPOINT_MAX 16u #endif #define DWC2_CHANNEL_COUNT_MAX 16u // absolute max channel count TU_VERIFY_STATIC(CFG_TUH_DWC2_ENDPOINT_MAX <= 255, "currently only use 8-bit for index"); enum { HPRT_W1_MASK = HPRT_CONN_DETECT | HPRT_ENABLE | HPRT_ENABLE_CHANGE | HPRT_OVER_CURRENT_CHANGE | HPRT_SUSPEND }; enum { HCD_XFER_ERROR_MAX = 3 }; enum { HCD_XFER_PERIOD_SPLIT_NYET_MAX = 3 }; //-------------------------------------------------------------------- // //-------------------------------------------------------------------- // Host driver struct for each opened endpoint typedef struct { union { uint32_t hcchar; dwc2_channel_char_t hcchar_bm; }; union { uint32_t hcsplt; dwc2_channel_split_t hcsplt_bm; }; struct TU_ATTR_PACKED { uint32_t uframe_interval : 18; // micro-frame interval uint32_t speed : 2; uint32_t next_pid : 2; // PID for next transfer uint32_t next_do_ping : 1; // Do PING for next transfer if possible (highspeed OUT) uint32_t closing : 1; // endpoint is closing // uint32_t : 8; }; uint32_t uframe_countdown; // micro-frame count down to transfer for periodic, only need 18-bit uint8_t* buffer; uint16_t buflen; } hcd_endpoint_t; // Additional info for each channel when it is active typedef struct { volatile bool allocated; uint8_t ep_id; struct TU_ATTR_PACKED { uint8_t err_count : 3; uint8_t period_split_nyet_count : 3; uint8_t halted_nyet : 1; uint8_t closing : 1; // closing channel }; uint8_t result; uint16_t xferred_bytes; // bytes that accumulate transferred though USB bus for the whole hcd_edpt_xfer(), which can // be composed of multiple channel_xfer_start() (retry with NAK/NYET) uint16_t fifo_bytes; // bytes written/read from/to FIFO (may not be transferred on USB bus). } hcd_xfer_t; typedef struct { hcd_xfer_t xfer[DWC2_CHANNEL_COUNT_MAX]; hcd_endpoint_t edpt[CFG_TUH_DWC2_ENDPOINT_MAX]; } hcd_data_t; static hcd_data_t _hcd_data; static tuh_configure_dwc2_t _tuh_cfg = {.use_hs_phy = TUH_OPT_HIGH_SPEED}; //-------------------------------------------------------------------- // //-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_channel_count(const dwc2_regs_t* dwc2) { const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; return tu_min8(ghwcfg2.num_host_ch + 1, DWC2_CHANNEL_COUNT_MAX); } TU_ATTR_ALWAYS_INLINE static inline tusb_speed_t hprt_speed_get(dwc2_regs_t* dwc2) { tusb_speed_t speed; const dwc2_hprt_t hprt = {.value = dwc2->hprt}; switch(hprt.speed) { case HPRT_SPEED_HIGH: speed = TUSB_SPEED_HIGH; break; case HPRT_SPEED_FULL: speed = TUSB_SPEED_FULL; break; case HPRT_SPEED_LOW : speed = TUSB_SPEED_LOW ; break; default: speed = TUSB_SPEED_INVALID; TU_BREAKPOINT(); break; } return speed; } TU_ATTR_ALWAYS_INLINE static inline bool dma_host_enabled(const dwc2_regs_t* dwc2) { (void) dwc2; // Internal DMA only const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; return CFG_TUH_DWC2_DMA_ENABLE && ghwcfg2.arch == GHWCFG2_ARCH_INTERNAL_DMA; } #if CFG_TUH_MEM_DCACHE_ENABLE bool hcd_dcache_clean(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_clean(addr, data_size); } bool hcd_dcache_invalidate(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_invalidate(addr, data_size); } bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { TU_VERIFY(addr && data_size); return dwc2_dcache_clean_invalidate(addr, data_size); } #endif // Allocate a channel for new transfer TU_ATTR_ALWAYS_INLINE static inline uint8_t channel_alloc(dwc2_regs_t* dwc2) { const uint8_t max_channel = dwc2_channel_count(dwc2); for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; if (!xfer->allocated) { tu_memclr(xfer, sizeof(hcd_xfer_t)); xfer->allocated = true; return ch_id; } } return TUSB_INDEX_INVALID_8; } // Check if is periodic (interrupt/isochronous) TU_ATTR_ALWAYS_INLINE static inline bool channel_is_periodic(uint32_t hcchar) { const dwc2_channel_char_t hcchar_bm = {.value = hcchar}; return hcchar_bm.ep_type == HCCHAR_EPTYPE_INTERRUPT || hcchar_bm.ep_type == HCCHAR_EPTYPE_ISOCHRONOUS; } TU_ATTR_ALWAYS_INLINE static inline uint8_t req_queue_avail(const dwc2_regs_t* dwc2, bool is_period) { if (is_period) { const dwc2_hptxsts_t hptxsts = {.value = dwc2->hptxsts}; return hptxsts.req_queue_available; } else { const dwc2_hnptxsts_t hnptxsts = {.value = dwc2->hnptxsts}; return hnptxsts.req_queue_available; } } TU_ATTR_ALWAYS_INLINE static inline void channel_dealloc(dwc2_regs_t* dwc2, uint8_t ch_id) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; xfer->allocated = false; dwc2->haintmsk &= ~TU_BIT(ch_id); } TU_ATTR_ALWAYS_INLINE static inline bool channel_disable(const dwc2_regs_t* dwc2, dwc2_channel_t* channel) { const bool is_period = channel_is_periodic(channel->hcchar); if (dma_host_enabled(dwc2)) { // In buffer DMA or external DMA mode: // - Channel disable must not be programmed for non-split periodic channels. At the end of the next uframe/frame (in // the worst case), the controller generates a channel halted and disables the channel automatically. // - For split enabled channels (both non-periodic and periodic), channel disable must not be programmed randomly. // However, channel disable can be programmed for specific scenarios such as NAK and FrmOvrn. if (is_period && (channel->hcsplt & HCSPLT_SPLITEN)) { return true; } } else { while (0 == req_queue_avail(dwc2, is_period)) { // blocking wait for request queue available } } channel->hcintmsk |= HCINT_HALTED; channel->hcchar |= HCCHAR_CHDIS | HCCHAR_CHENA; // must set both CHDIS and CHENA return true; } // attempt to send IN token to receive data TU_ATTR_ALWAYS_INLINE static inline bool channel_send_in_token(const dwc2_regs_t* dwc2, dwc2_channel_t* channel) { while (0 == req_queue_avail(dwc2, channel_is_periodic(channel->hcchar))) { // blocking wait for request queue available } channel->hcchar |= HCCHAR_CHENA; return true; } // Find currently enabled channel. Note: EP0 is bidirectional TU_ATTR_ALWAYS_INLINE static inline uint8_t channel_find_enabled(dwc2_regs_t* dwc2, uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir) { const uint8_t max_channel = dwc2_channel_count(dwc2); for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) { if (_hcd_data.xfer[ch_id].allocated) { const dwc2_channel_char_t hcchar = {.value = dwc2->channel[ch_id].hcchar}; if (hcchar.dev_addr == dev_addr && hcchar.ep_num == ep_num && (ep_num == 0 || hcchar.ep_dir == ep_dir)) { return ch_id; } } } return TUSB_INDEX_INVALID_8; } // Allocate a new endpoint TU_ATTR_ALWAYS_INLINE static inline uint8_t edpt_alloc(void) { for (uint32_t i = 0; i < CFG_TUH_DWC2_ENDPOINT_MAX; i++) { hcd_endpoint_t* edpt = &_hcd_data.edpt[i]; if (edpt->hcchar_bm.enable == 0) { tu_memclr(edpt, sizeof(hcd_endpoint_t)); edpt->hcchar_bm.enable = 1; return i; } } return TUSB_INDEX_INVALID_8; } TU_ATTR_ALWAYS_INLINE static inline void edpt_dealloc(hcd_endpoint_t *edpt) { edpt->hcchar_bm.enable = 0; } // close an opened endpoint static void edpt_close(dwc2_regs_t *dwc2, uint8_t ep_id) { hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; edpt->closing = 1; // mark endpoint as closing // disable active channel belong to this endpoint for (uint8_t ch_id = 0; ch_id < DWC2_CHANNEL_COUNT_MAX; ch_id++) { hcd_xfer_t *xfer = &_hcd_data.xfer[ch_id]; if (xfer->allocated && xfer->ep_id == ep_id) { dwc2_channel_t *channel = &dwc2->channel[ch_id]; xfer->closing = 1; channel_disable(dwc2, channel); return; // only 1 active channel per endpoint } } edpt_dealloc(edpt); // no active channel, safe to de-alloc now } // Find an endpoint that is opened previously with hcd_edpt_open() // Note: EP0 is bidirectional TU_ATTR_ALWAYS_INLINE static inline uint8_t edpt_find_opened(uint8_t dev_addr, uint8_t ep_num, uint8_t ep_dir) { for (uint8_t i = 0; i < (uint8_t)CFG_TUH_DWC2_ENDPOINT_MAX; i++) { const hcd_endpoint_t *edpt = &_hcd_data.edpt[i]; const dwc2_channel_char_t hcchar_bm = edpt->hcchar_bm; if (hcchar_bm.enable && hcchar_bm.dev_addr == dev_addr && hcchar_bm.ep_num == ep_num && (ep_num == 0 || hcchar_bm.ep_dir == ep_dir)) { return i; } } return TUSB_INDEX_INVALID_8; } TU_ATTR_ALWAYS_INLINE static inline uint16_t cal_packet_count(uint16_t len, uint16_t ep_size) { if (len == 0) { return 1; } else { return tu_div_ceil(len, ep_size); } } TU_ATTR_ALWAYS_INLINE static inline uint8_t cal_next_pid(uint8_t pid, uint8_t packet_count) { if (packet_count & 0x01u) { return pid ^ 0x02u; // toggle DATA0 and DATA1 } else { return pid; } } //-------------------------------------------------------------------- // //-------------------------------------------------------------------- /* USB Data FIFO Layout The FIFO is split up into - EPInfo: for storing DMA metadata (check dcd_dwc2.c for more details) - 1 RX FIFO: for receiving data - 1 TX FIFO for non-periodic (NPTX) - 1 TX FIFO for periodic (PTX) We allocated TX FIFO from top to bottom (using top pointer), this to allow the RX FIFO to grow dynamically which is possible since the free space is located between the RX and TX FIFOs. ----------------- ep_fifo_size | HCDMAn | |--------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) | Non-Periodic | | TX FIFO | |--------------|--- GNPTXFSIZ.addr (fixed size) | Periodic | | TX FIFO | |--------------|--- HPTXFSIZ.addr (expandable downward) | FREE | | | |--------------|-- GRXFSIZ (expandable upward) | RX FIFO | ---------------- 0 */ /* Programming Guide 2.1.2 FIFO RAM allocation * RX * - Largest-EPsize/4 + 2 (status info). recommended x2 if high bandwidth or multiple ISO are used. * - 2 for transfer complete and channel halted status * - 1 for each Control/Bulk out endpoint to Handle NAK/NYET (i.e max is number of host channel) * * TX non-periodic (NPTX) * - At least largest-EPsize/4, recommended x2 * * TX periodic (PTX) * - At least largest-EPsize*MulCount/4 (MulCount up to 3 for high-bandwidth ISO/interrupt) */ static void dfifo_host_init(uint8_t rhport, bool is_hs_phy) { const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per channel const bool is_dma = dma_host_enabled(dwc2); uint16_t dfifo_top = dwc2_controller->ep_fifo_size/4; if (is_dma) { dfifo_top -= ghwcfg2.num_host_ch; } // fixed allocation for now, improve later: // - ptx_largest is limited to 256 for FS since most FS core only has 1024 bytes total uint32_t nptx_largest = is_hs_phy ? TUSB_EPSIZE_BULK_HS / 4 : TUSB_EPSIZE_BULK_FS / 4; uint32_t ptx_largest = is_hs_phy ? TUSB_EPSIZE_ISO_HS_MAX / 4 : 256 / 4; uint16_t nptxfsiz = 2 * nptx_largest; uint16_t rxfsiz = 2 * (ptx_largest + 2) + ghwcfg2.num_host_ch; TU_ASSERT(dfifo_top >= (nptxfsiz + rxfsiz),); uint16_t ptxfsiz = dfifo_top - (nptxfsiz + rxfsiz); dwc2->gdfifocfg = (dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT) | dfifo_top; dfifo_top -= rxfsiz; dwc2->grxfsiz = rxfsiz; dfifo_top -= nptxfsiz; dwc2->gnptxfsiz = tu_u32_from_u16(nptxfsiz, dfifo_top); dfifo_top -= ptxfsiz; dwc2->hptxfsiz = tu_u32_from_u16(ptxfsiz, dfifo_top); } //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; TU_VERIFY(cfg_id == TUH_CFGID_DWC2 && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _tuh_cfg = cfg->dwc2; return true; } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); tu_memclr(&_hcd_data, sizeof(_hcd_data)); // Core Initialization const bool is_hs_phy = dwc2_core_is_highspeed_phy(dwc2, _tuh_cfg.use_hs_phy); const bool is_dma = dma_host_enabled(dwc2); TU_ASSERT(dwc2_core_init(rhport, is_hs_phy, is_dma)); //------------- 3.1 Host Initialization -------------// // Enable HFIR reload if (dwc2->gsnpsid >= DWC2_CORE_REV_2_92a) { dwc2->hfir |= HFIR_RELOAD_CTRL; } // force host mode and wait for mode switch dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FDMOD) | GUSBCFG_FHMOD; while ((dwc2->gintsts & GINTSTS_CMOD) != GINTSTS_CMODE_HOST) {} #ifdef TUP_USBIP_DWC2_STM32 dwc2_stm32_gccfg_cfg(dwc2, false, true); #endif if (is_hs_phy && (rh_init->speed == TUSB_SPEED_HIGH || rh_init->speed == TUSB_SPEED_AUTO)) { dwc2->hcfg &= ~HCFG_FSLS_ONLY; // max speed } else { dwc2->hcfg |= HCFG_FSLS_ONLY; // disable high speed mode } // configure a fixed-allocated fifo scheme dfifo_host_init(rhport, is_hs_phy); dwc2->hprt = HPRT_W1_MASK; // clear all write-1-clear bits dwc2->hprt = HPRT_POWER; // turn on VBUS // Enable required interrupts dwc2->gintmsk |= GINTSTS_OTGINT | GINTSTS_HPRTINT | GINTSTS_HCINT | GINTSTS_DISCINT; // NPTX can hold at least 2 packet, change interrupt level to half-empty uint32_t gahbcfg = dwc2->gahbcfg & ~GAHBCFG_TX_FIFO_EPMTY_LVL; gahbcfg |= GAHBCFG_GINT; // Enable global interrupt dwc2->gahbcfg = gahbcfg; return true; } bool hcd_deinit(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Turn off VBUS dwc2->hprt = HPRT_W1_MASK; // clear w1c bits without side effects // HPRT_POWER is not set -> VBUS off dwc2_core_deinit(rhport); return true; } // Enable USB interrupt void hcd_int_enable (uint8_t rhport) { dwc2_int_set(rhport, TUSB_ROLE_HOST, true); } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { dwc2_int_set(rhport, TUSB_ROLE_HOST, false); } // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); return dwc2->hfnum & HFNUM_FRNUM_Msk; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); return dwc2->hprt & HPRT_CONN_STATUS; } // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint32_t hprt = dwc2->hprt & ~HPRT_W1_MASK; hprt |= HPRT_RESET; dwc2->hprt = hprt; } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint32_t hprt = dwc2->hprt & ~HPRT_W1_MASK; // skip w1c bits hprt &= ~HPRT_RESET; dwc2->hprt = hprt; } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const tusb_speed_t speed = hprt_speed_get(dwc2); return speed; } // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); for (uint8_t ep_id = 0; ep_id < CFG_TUH_DWC2_ENDPOINT_MAX; ep_id++) { const hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; if (edpt->hcchar_bm.enable && edpt->hcchar_bm.dev_addr == dev_addr) { edpt_close(dwc2, ep_id); } } } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t* desc_ep) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const tusb_speed_t rh_speed = hprt_speed_get(dwc2); tuh_bus_info_t bus_info; tuh_bus_info_get(dev_addr, &bus_info); // find a free endpoint const uint8_t ep_id = edpt_alloc(); TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; dwc2_channel_char_t* hcchar_bm = &edpt->hcchar_bm; hcchar_bm->ep_size = tu_edpt_packet_size(desc_ep); hcchar_bm->ep_num = tu_edpt_number(desc_ep->bEndpointAddress); hcchar_bm->ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); hcchar_bm->low_speed_dev = (bus_info.speed == TUSB_SPEED_LOW) ? 1 : 0; hcchar_bm->ep_type = desc_ep->bmAttributes.xfer; // ep_type matches TUSB_XFER_* hcchar_bm->err_multi_count = 0; hcchar_bm->dev_addr = dev_addr; hcchar_bm->odd_frame = 0; hcchar_bm->disable = 0; hcchar_bm->enable = 1; dwc2_channel_split_t* hcsplt_bm = &edpt->hcsplt_bm; hcsplt_bm->hub_port = bus_info.hub_port; hcsplt_bm->hub_addr = bus_info.hub_addr; hcsplt_bm->xact_pos = 0; hcsplt_bm->split_compl = 0; hcsplt_bm->split_en = (rh_speed == TUSB_SPEED_HIGH && bus_info.speed != TUSB_SPEED_HIGH) ? 1 : 0; edpt->speed = bus_info.speed; edpt->next_pid = HCTSIZ_PID_DATA0; switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_ISOCHRONOUS: edpt->uframe_interval = 1 << (desc_ep->bInterval - 1); if (bus_info.speed == TUSB_SPEED_FULL) { edpt->uframe_interval <<= 3; } break; case TUSB_XFER_INTERRUPT: if (bus_info.speed == TUSB_SPEED_HIGH) { edpt->uframe_interval = 1 << (desc_ep->bInterval - 1); } else { edpt->uframe_interval = desc_ep->bInterval << 3; } break; default: break; } return true; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { dwc2_regs_t *dwc2 = DWC2_REG(rhport); const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); const uint8_t ep_id = edpt_find_opened(daddr, ep_num, ep_dir); TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); edpt_close(dwc2, ep_id); return true; } // clean up channel after part of transfer is done but the whole urb is not complete static void channel_xfer_out_wrapup(dwc2_regs_t* dwc2, uint8_t ch_id) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; const dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; edpt->next_pid = hctsiz.pid; // save PID /* Since hctsiz.xfersize field reflects the number of bytes transferred via the AHB, not the USB) * For IN: we can use hctsiz.xfersize as remaining bytes. * For OUT: Must use the hctsiz.pktcnt field to determine how much data has been transferred. This field reflects the * number of packets that have been transferred via the USB. This is always an integral number of packets if the * transfer was halted before its normal completion. */ const uint16_t remain_packets = hctsiz.packet_count; const dwc2_channel_char_t hcchar = {.value = channel->hcchar}; const uint16_t total_packets = cal_packet_count(edpt->buflen, hcchar.ep_size); const uint16_t actual_bytes = (total_packets - remain_packets) * hcchar.ep_size; xfer->fifo_bytes = 0; xfer->xferred_bytes += actual_bytes; edpt->buffer += actual_bytes; edpt->buflen -= actual_bytes; } static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_char_t* hcchar_bm = &edpt->hcchar_bm; dwc2_channel_t* channel = &dwc2->channel[ch_id]; bool const is_period = channel_is_periodic(edpt->hcchar); // clear previous state xfer->fifo_bytes = 0; // hchar: restore but don't enable yet if (is_period) { hcchar_bm->odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame } channel->hcchar = (edpt->hcchar & ~HCCHAR_CHENA); // hctsiz: zero length packet still count as 1 const uint16_t packet_count = cal_packet_count(edpt->buflen, hcchar_bm->ep_size); dwc2_channel_tsize_t hctsiz = {.value = 0}; hctsiz.pid = edpt->next_pid; // next PID is set in transfer complete interrupt hctsiz.packet_count = packet_count; hctsiz.xfer_size = edpt->buflen; if (edpt->next_do_ping && edpt->speed == TUSB_SPEED_HIGH && edpt->next_pid != HCTSIZ_PID_SETUP && hcchar_bm->ep_dir == TUSB_DIR_OUT) { hctsiz.do_ping = 1; } channel->hctsiz = hctsiz.value; edpt->next_do_ping = 0; // pre-calculate next PID based on packet count, adjusted in transfer complete interrupt if short packet if (hcchar_bm->ep_num == 0) { edpt->next_pid = HCTSIZ_PID_DATA1; // control data and status stage always start with DATA1 } else { edpt->next_pid = cal_next_pid(edpt->next_pid, packet_count); } channel->hcsplt = edpt->hcsplt; channel->hcint = 0xFFFFFFFFU; // clear all channel interrupts if (dma_host_enabled(dwc2)) { channel->hcintmsk = HCINT_HALTED; dwc2->haintmsk |= TU_BIT(ch_id); channel->hcdma = (uint32_t) edpt->buffer; if (hcchar_bm->ep_dir == TUSB_DIR_IN) { channel_send_in_token(dwc2, channel); } else { hcd_dcache_clean(edpt->buffer, edpt->buflen); channel->hcchar |= HCCHAR_CHENA; } } else { uint32_t hcintmsk = HCINT_NAK | HCINT_XACT_ERR | HCINT_STALL | HCINT_XFER_COMPLETE | HCINT_DATATOGGLE_ERR; if (hcchar_bm->ep_dir == TUSB_DIR_IN) { hcintmsk |= HCINT_BABBLE_ERR | HCINT_DATATOGGLE_ERR | HCINT_ACK; } else { hcintmsk |= HCINT_NYET; if (edpt->hcsplt_bm.split_en || hctsiz.do_ping) { hcintmsk |= HCINT_ACK; } } channel->hcintmsk = hcintmsk; dwc2->haintmsk |= TU_BIT(ch_id); // enable channel for slave mode: // - OUT: it will enable corresponding FIFO channel // - IN : it will write an IN request to the Non-periodic Request Queue, this will have dwc2 trying to send // IN Token. If we got NAK, we have to re-enable the channel again in the interrupt. Due to the way usbh stack only // call hcd_edpt_xfer() once, we will need to manage de-allocate/re-allocate IN channel dynamically. if (hcchar_bm->ep_dir == TUSB_DIR_IN) { channel_send_in_token(dwc2, channel); } else { channel->hcchar |= HCCHAR_CHENA; if (edpt->buflen > 0) { // To prevent conflict with other channel, we will enable periodic/non-periodic FIFO empty interrupt accordingly // And write packet in the interrupt handler dwc2->gintmsk |= (is_period ? GINTSTS_PTX_FIFO_EMPTY : GINTSTS_NPTX_FIFO_EMPTY); } } } return true; } // kick-off transfer with an endpoint static bool edpt_xfer_kickoff(dwc2_regs_t* dwc2, uint8_t ep_id) { uint8_t ch_id = channel_alloc(dwc2); TU_ASSERT(ch_id < 16); // all channel are in used hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; xfer->ep_id = ep_id; xfer->result = XFER_RESULT_INVALID; return channel_xfer_start(dwc2, ch_id); } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); uint8_t ep_id = edpt_find_opened(dev_addr, ep_num, ep_dir); TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; TU_VERIFY(edpt->closing == 0); // skip if endpoint is closing edpt->buffer = buffer; edpt->buflen = buflen; if (ep_num == 0) { // update ep_dir since control endpoint can switch direction edpt->hcchar_bm.ep_dir = ep_dir; } return edpt_xfer_kickoff(dwc2, ep_id); } // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); const uint8_t ep_id = edpt_find_opened(dev_addr, ep_num, ep_dir); TU_VERIFY(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); // hcd_int_disable(rhport); // Find enabled channeled and disable it, channel will be de-allocated in the interrupt handler const uint8_t ch_id = channel_find_enabled(dwc2, dev_addr, ep_num, ep_dir); if (ch_id < 16) { dwc2_channel_t* channel = &dwc2->channel[ch_id]; channel_disable(dwc2, channel); } // hcd_int_enable(rhport); return true; } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, const uint8_t setup_packet[8]) { uint8_t ep_id = edpt_find_opened(dev_addr, 0, TUSB_DIR_OUT); TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); // no opened endpoint hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; edpt->next_pid = HCTSIZ_PID_SETUP; return hcd_edpt_xfer(rhport, dev_addr, 0, (uint8_t*)(uintptr_t) setup_packet, 8); } // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); const uint8_t ep_id = edpt_find_opened(dev_addr, ep_num, ep_dir); TU_VERIFY(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id]; edpt->next_pid = HCTSIZ_PID_DATA0; return true; } //-------------------------------------------------------------------- // HCD Event Handler //-------------------------------------------------------------------- // retry an IN transfer, channel must be halted static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_t* channel = &dwc2->channel[ch_id]; dwc2_channel_char_t hcchar = {.value = channel->hcchar}; if (channel_is_periodic(hcchar.value)){ const dwc2_channel_split_t hcsplt = {.value = channel->hcsplt}; // retry immediately for periodic split NYET if we haven't reach max retry if (hcsplt.split_en && hcsplt.split_compl && (hcint & HCINT_NYET || xfer->halted_nyet)) { xfer->period_split_nyet_count++; xfer->halted_nyet = 0; if (xfer->period_split_nyet_count < HCD_XFER_PERIOD_SPLIT_NYET_MAX) { hcchar.odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame channel->hcchar = hcchar.value; channel_send_in_token(dwc2, channel); return; } else { // too many NYET, de-allocate channel with below code xfer->period_split_nyet_count = 0; } } const uint32_t ucount = (hprt_speed_get(dwc2) == TUSB_SPEED_HIGH ? 1 : 8); if (edpt->uframe_interval == ucount) { // retry on next frame if bInterval is 1 hcchar.odd_frame = 1 - (dwc2->hfnum & 1); channel->hcchar = hcchar.value; channel_send_in_token(dwc2, channel); } else { // otherwise, de-allocate channel, enable SOF set frame counter for later transfer const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; edpt->next_pid = hctsiz.pid; // save PID edpt->uframe_countdown = edpt->uframe_interval - ucount; // enable SOF interrupt if not already enabled if (0 == (dwc2->gintmsk & GINTMSK_SOFM)) { dwc2->gintsts = GINTSTS_SOF; dwc2->gintmsk |= GINTMSK_SOFM; } // already halted, de-allocate channel (called from DMA isr) channel_dealloc(dwc2, ch_id); } } else { // for control/bulk: retry immediately channel_send_in_token(dwc2, channel); } } #if CFG_TUSB_DEBUG && 0 TU_ATTR_ALWAYS_INLINE static inline void print_hcint(uint32_t hcint) { const char* str[] = { "XFRC", "HALTED", "AHBERR", "STALL", "NAK", "ACK", "NYET", "XERR", "BBLERR", "FRMOR", "DTERR", "BNA", "XCSERR", "DESC_LST" }; for(uint32_t i=0; i<14; i++) { if (hcint & TU_BIT(i)) { TU_LOG1("%s ", str[i]); } } TU_LOG1("\r\n"); } #endif #if CFG_TUH_DWC2_SLAVE_ENABLE static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Pop control word off FIFO const dwc2_grxstsp_t grxstsp = {.value= dwc2->grxstsp}; const uint8_t ch_id = grxstsp.ep_ch_num; switch (grxstsp.packet_status) { case GRXSTS_PKTSTS_RX_DATA: { // In packet received, pop this entry --> ACK interrupt const uint16_t byte_count = grxstsp.byte_count; hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; TU_ASSERT(xfer->ep_id < CFG_TUH_DWC2_ENDPOINT_MAX,); hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; if (byte_count > 0) { tu_hwfifo_read(dwc2->fifo[0], edpt->buffer + xfer->xferred_bytes, byte_count, NULL); xfer->xferred_bytes += byte_count; xfer->fifo_bytes = byte_count; } break; } case GRXSTS_PKTSTS_RX_COMPLETE: // In transfer complete: After this entry is popped from the rx FIFO, dwc2 asserts a Transfer Completed // interrupt --> handle_channel_irq() break; case GRXSTS_PKTSTS_HOST_DATATOGGLE_ERR: // handle in channel interrupt break; case GRXSTS_PKTSTS_HOST_CHANNEL_HALTED: // triggered when channel.hcchar_bm.disable is set // TODO handle later break; default: break; // ignore other status } } // return true if there is still pending data and need more ISR static bool handle_txfifo_empty(dwc2_regs_t* dwc2, bool is_periodic) { // Use period txsts for both p/np to get request queue space available (1-bit difference, it is small enough) const dwc2_hptxsts_t txsts = {.value = (is_periodic ? dwc2->hptxsts : dwc2->hnptxsts)}; const uint8_t max_channel = dwc2_channel_count(dwc2); for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) { dwc2_channel_t* channel = &dwc2->channel[ch_id]; const dwc2_channel_char_t hcchar = {.value = channel->hcchar}; // skip writing to FIFO if channel is expecting halted. if (0 == (channel->hcintmsk & HCINT_HALTED) && (hcchar.ep_dir == TUSB_DIR_OUT)) { hcd_xfer_t *xfer = &_hcd_data.xfer[ch_id]; TU_ASSERT(xfer->ep_id < CFG_TUH_DWC2_ENDPOINT_MAX); hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; const uint16_t remain_packets = hctsiz.packet_count; for (uint16_t i = 0; i < remain_packets; i++) { const uint16_t remain_bytes = edpt->buflen - xfer->fifo_bytes; const uint16_t xact_bytes = tu_min16(remain_bytes, hcchar.ep_size); // skip if there is not enough space in FIFO and RequestQueue. // Packet's last word written to FIFO will trigger a request queue if ((xact_bytes > (txsts.fifo_available << 2)) || (txsts.req_queue_available == 0)) { return true; } tu_hwfifo_write(dwc2->fifo[ch_id], edpt->buffer + xfer->fifo_bytes, xact_bytes, NULL); xfer->fifo_bytes += xact_bytes; } } } return false; // no channel has pending data } static bool handle_channel_in_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_split_t hcsplt = {.value = channel->hcsplt}; const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; bool is_done = false; // if (hcsplt.split_en) { // if (edpt->hcchar_bm.ep_num == 1) { // TU_LOG1("Frame %u, ch %u: ep %u, hcint 0x%04lX ", dwc2->hfnum_bm.num, ch_id, hcsplt.ep_num, hcint); // print_hcint(hcint); // } if (hcint & HCINT_XFER_COMPLETE) { if (edpt->hcchar_bm.ep_num != 0) { edpt->next_pid = hctsiz.pid; // save pid (already toggled) } const uint16_t remain_packets = hctsiz.packet_count; if (hcsplt.split_en && remain_packets && xfer->fifo_bytes == edpt->hcchar_bm.ep_size) { // Split can only complete 1 transaction (up to 1 packet) at a time, schedule more hcsplt.split_compl = 0; channel->hcsplt = hcsplt.value; } else { xfer->result = XFER_RESULT_SUCCESS; } channel_disable(dwc2, channel); } else if (hcint & (HCINT_XACT_ERR | HCINT_BABBLE_ERR | HCINT_STALL)) { if (hcint & HCINT_STALL) { xfer->result = XFER_RESULT_STALLED; } else if (hcint & HCINT_BABBLE_ERR) { xfer->result = XFER_RESULT_FAILED; } else if (hcint & HCINT_XACT_ERR) { xfer->err_count++; channel->hcintmsk |= HCINT_ACK; } else { // nothing to do } channel_disable(dwc2, channel); } else if (hcint & HCINT_NYET) { // restart complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; xfer->halted_nyet = 1; channel_disable(dwc2, channel); } else if (hcint & HCINT_NAK) { // NAK received, disable channel to flush all posted request and try again if (hcsplt.split_en == 1u) { hcsplt.split_compl = 0; // restart with start-split channel->hcsplt = hcsplt.value; } channel_disable(dwc2, channel); } else if (hcint & HCINT_ACK) { xfer->err_count = 0; if (hcsplt.split_en == 1u) { if (hcsplt.split_compl == 0) { // start split is ACK --> do complete split channel->hcintmsk |= HCINT_NYET; hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel_send_in_token(dwc2, channel); } else { // do nothing for complete split with DATA, this will trigger XferComplete and handled there } } else { // ACK with data const uint16_t remain_packets = hctsiz.packet_count; if (remain_packets > 0) { // still more packet to receive, also reset to start split hcsplt.split_compl = 0; channel->hcsplt = hcsplt.value; channel_send_in_token(dwc2, channel); } } } else if (hcint & HCINT_HALTED) { channel->hcintmsk &= ~HCINT_HALTED; if (xfer->result != XFER_RESULT_INVALID) { is_done = true; } else if (xfer->err_count == HCD_XFER_ERROR_MAX) { xfer->result = XFER_RESULT_FAILED; is_done = true; } else if (xfer->closing == 1) { is_done = true; } else { // got here due to NAK or NYET channel_xfer_in_retry(dwc2, ch_id, hcint); } } else if (hcint & HCINT_DATATOGGLE_ERR) { channel->hcintmsk &= ~HCINT_DATATOGGLE_ERR; xfer->err_count = 0; hcsplt.split_compl = 0; // restart with start-split channel->hcsplt = hcsplt.value; channel_disable(dwc2, channel); } else { // nothing to do } return is_done; } static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_split_t hcsplt = {.value = channel->hcsplt}; bool is_done = false; if (hcint & HCINT_XFER_COMPLETE) { is_done = true; xfer->result = XFER_RESULT_SUCCESS; channel->hcintmsk &= ~HCINT_ACK; if (hcint & HCINT_NYET) { // complete transfer with NYET, do ping next time edpt->next_do_ping = 1; } } else if (hcint & HCINT_STALL) { xfer->result = XFER_RESULT_STALLED; channel_disable(dwc2, channel); } else if (hcint & HCINT_NYET) { xfer->err_count = 0; if (hcsplt.split_en == 1u) { // retry complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel->hcchar |= HCCHAR_CHENA; } else { edpt->next_do_ping = 1; channel_xfer_out_wrapup(dwc2, ch_id); channel_disable(dwc2, channel); } } else if (hcint & (HCINT_NAK | HCINT_XACT_ERR)) { // clean up transfer so far, disable and start again later channel_xfer_out_wrapup(dwc2, ch_id); channel_disable(dwc2, channel); if (hcint & HCINT_XACT_ERR) { xfer->err_count++; channel->hcintmsk |= HCINT_ACK; } else { // NAK disable channel to flush all posted request and try again edpt->next_do_ping = 1; xfer->err_count = 0; } } else if (hcint & HCINT_HALTED) { channel->hcintmsk &= ~HCINT_HALTED; if (xfer->result != XFER_RESULT_INVALID) { is_done = true; } else if (xfer->err_count == HCD_XFER_ERROR_MAX) { xfer->result = XFER_RESULT_FAILED; is_done = true; } else if (xfer->closing == 1) { is_done = true; } else { // Got here due to NAK or NYET TU_ASSERT(channel_xfer_start(dwc2, ch_id)); } } else if (hcint & HCINT_ACK) { xfer->err_count = 0; channel->hcintmsk &= ~HCINT_ACK; if (hcsplt.split_en == 1u) { if (hcsplt.split_compl == 0) { // ACK for start split --> do complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel->hcchar |= HCCHAR_CHENA; } } else { // ACK interrupt is only enabled for Split and PING // ACK for PING, which mean device is ready to receive data channel->hctsiz &= ~HCTSIZ_DOPING; // HC already cleared PING bit, but we clear anyway channel->hcchar |= HCCHAR_CHENA; } } else { // nothing to do } if (is_done) { xfer->xferred_bytes += xfer->fifo_bytes; xfer->fifo_bytes = 0; } return is_done; } #endif #if CFG_TUH_DWC2_DMA_ENABLE static bool handle_channel_in_dma(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_char_t hcchar = {.value = channel->hcchar}; dwc2_channel_split_t hcsplt = {.value = channel->hcsplt}; const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; bool is_done = false; // TU_LOG1("in hcint = %02lX\r\n", hcint); if (hcint & HCINT_HALTED) { if (hcint & (HCINT_XFER_COMPLETE | HCINT_STALL | HCINT_BABBLE_ERR)) { const uint16_t remain_bytes = (uint16_t) hctsiz.xfer_size; const uint16_t remain_packets = hctsiz.packet_count; const uint16_t actual_len = edpt->buflen - remain_bytes; xfer->xferred_bytes += actual_len; is_done = true; if (hcint & HCINT_STALL) { xfer->result = XFER_RESULT_STALLED; } else if (hcint & HCINT_BABBLE_ERR) { xfer->result = XFER_RESULT_FAILED; } else if (hcsplt.split_en && remain_packets && actual_len == hcchar.ep_size) { // Split can only complete 1 transaction (up to 1 packet) at a time, schedule more is_done = false; edpt->buffer += actual_len; edpt->buflen -= actual_len; hcsplt.split_compl = 0; channel->hcsplt = hcsplt.value; channel_xfer_in_retry(dwc2, ch_id, hcint); } else { xfer->result = XFER_RESULT_SUCCESS; } xfer->err_count = 0; channel->hcintmsk &= ~HCINT_ACK; } else if (hcint & HCINT_XACT_ERR) { xfer->err_count++; if (xfer->err_count >= HCD_XFER_ERROR_MAX) { is_done = true; xfer->result = XFER_RESULT_FAILED; } else { channel->hcintmsk |= HCINT_ACK | HCINT_NAK | HCINT_DATATOGGLE_ERR; hcsplt.split_compl = 0; channel->hcsplt = hcsplt.value; channel_xfer_in_retry(dwc2, ch_id, hcint); } } else if (hcint & HCINT_NYET) { // Must handle nyet before nak or ack. Could get a nyet at the same time as either of those on a BULK/CONTROL // OUT that started with a PING. The nyet takes precedence. if (hcsplt.split_en) { // split not yet mean hub has no data, retry complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel_xfer_in_retry(dwc2, ch_id, hcint); } } else if (hcint & HCINT_ACK) { xfer->err_count = 0; channel->hcintmsk &= ~HCINT_ACK; if (hcsplt.split_en) { // start split is ACK --> do complete split // TODO: for ISO must use xact_pos to plan complete split based on microframe (up to 187.5 bytes/uframe) hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; if (channel_is_periodic(channel->hcchar)) { hcchar.odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame channel->hcchar = hcchar.value; } channel_send_in_token(dwc2, channel); } } else if (hcint & (HCINT_NAK | HCINT_DATATOGGLE_ERR)) { xfer->err_count = 0; channel->hcintmsk &= ~(HCINT_NAK | HCINT_DATATOGGLE_ERR); hcsplt.split_compl = 0; // restart with start-split channel->hcsplt = hcsplt.value; channel_xfer_in_retry(dwc2, ch_id, hcint); } else if (hcint & HCINT_FARME_OVERRUN) { // retry start-split in next binterval channel_xfer_in_retry(dwc2, ch_id, hcint); } if (xfer->closing == 1) { is_done = true; } } return is_done; } static bool handle_channel_out_dma(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) { hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id]; dwc2_channel_split_t hcsplt = {.value = channel->hcsplt}; bool is_done = false; // TU_LOG1("out hcint = %02lX\r\n", hcint); if (hcint & HCINT_HALTED) { if (hcint & (HCINT_XFER_COMPLETE | HCINT_STALL)) { is_done = true; xfer->err_count = 0; if (hcint & HCINT_XFER_COMPLETE) { xfer->result = XFER_RESULT_SUCCESS; xfer->xferred_bytes += edpt->buflen; } else { xfer->result = XFER_RESULT_STALLED; channel_xfer_out_wrapup(dwc2, ch_id); } channel->hcintmsk &= ~HCINT_ACK; } else if (hcint & HCINT_XACT_ERR) { if (hcint & (HCINT_NAK | HCINT_NYET | HCINT_ACK)) { xfer->err_count = 0; // clean up transfer so far and start again channel_xfer_out_wrapup(dwc2, ch_id); channel_xfer_start(dwc2, ch_id); } else { xfer->err_count++; if (xfer->err_count >= HCD_XFER_ERROR_MAX) { xfer->result = XFER_RESULT_FAILED; is_done = true; } else { // clean up transfer so far and start again channel_xfer_out_wrapup(dwc2, ch_id); channel_xfer_start(dwc2, ch_id); } } } else if (hcint & HCINT_NYET) { if (hcsplt.split_en && hcsplt.split_compl) { // split not yet mean hub has no data, retry complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel->hcchar |= HCCHAR_CHENA; } } else if (hcint & HCINT_ACK) { xfer->err_count = 0; if (hcsplt.split_en && !hcsplt.split_compl) { // start split is ACK --> do complete split hcsplt.split_compl = 1; channel->hcsplt = hcsplt.value; channel->hcchar |= HCCHAR_CHENA; } } if (xfer->closing == 1) { is_done = true; } } else if (hcint & HCINT_ACK) { xfer->err_count = 0; channel->hcintmsk &= ~HCINT_ACK; } return is_done; } #endif static void handle_channel_irq(uint8_t rhport, bool in_isr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const bool is_dma = dma_host_enabled(dwc2); const uint8_t max_channel = dwc2_channel_count(dwc2); for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) { if (tu_bit_test(dwc2->haint, ch_id)) { dwc2_channel_t* channel = &dwc2->channel[ch_id]; hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id]; TU_ASSERT(xfer->ep_id < CFG_TUH_DWC2_ENDPOINT_MAX,); dwc2_channel_char_t hcchar = {.value = channel->hcchar}; const uint32_t hcint = channel->hcint; channel->hcint = hcint; // clear interrupt bool is_done = false; if (is_dma) { #if CFG_TUH_DWC2_DMA_ENABLE if (hcchar.ep_dir == TUSB_DIR_OUT) { is_done = handle_channel_out_dma(dwc2, ch_id, hcint); } else { is_done = handle_channel_in_dma(dwc2, ch_id, hcint); if (is_done && (channel->hcdma > xfer->xferred_bytes)) { // hcdma is increased by word --> need to align4 hcd_dcache_invalidate((void*) tu_align4(channel->hcdma - xfer->xferred_bytes), xfer->xferred_bytes); } } #endif } else { #if CFG_TUH_DWC2_SLAVE_ENABLE if (hcchar.ep_dir == TUSB_DIR_OUT) { is_done = handle_channel_out_slave(dwc2, ch_id, hcint); } else { is_done = handle_channel_in_slave(dwc2, ch_id, hcint); } #endif } if (is_done) { if (xfer->closing == 1) { hcd_endpoint_t *edpt = &_hcd_data.edpt[xfer->ep_id]; edpt_dealloc(edpt); } else { const uint8_t ep_addr = tu_edpt_addr(hcchar.ep_num, hcchar.ep_dir); hcd_event_xfer_complete(hcchar.dev_addr, ep_addr, xfer->xferred_bytes, (xfer_result_t)xfer->result, in_isr); } channel_dealloc(dwc2, ch_id); } } } } // SOF is enabled for scheduled periodic transfer static bool handle_sof_irq(uint8_t rhport, bool in_isr) { (void) in_isr; dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->gintsts = GINTSTS_SOF; // Clear the SOF interrupt flag bool more_isr = false; // If highspeed then SOF is 125us, else 1ms const uint32_t ucount = (hprt_speed_get(dwc2) == TUSB_SPEED_HIGH ? 1 : 8); for(uint8_t ep_id = 0; ep_id < CFG_TUH_DWC2_ENDPOINT_MAX; ep_id++) { hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id]; if (edpt->closing == 0) { if (edpt->hcchar_bm.enable && channel_is_periodic(edpt->hcchar) && edpt->uframe_countdown > 0) { edpt->uframe_countdown -= tu_min32(ucount, edpt->uframe_countdown); if (edpt->uframe_countdown == 0) { if (!edpt_xfer_kickoff(dwc2, ep_id)) { edpt->uframe_countdown = ucount; // failed to start, try again next frame } } more_isr = true; } } } return more_isr; } // Config HCFG FS/LS clock and HFIR for SOF interval according to link speed (value is in PHY clock unit) // Databook Table 2-2: System Clock Speeds // +-----------+------------------+----------+-----------+-------------------+ // | PHY | PHY Clock (MHz) | Width | HCFG.Sel | HFIR (clk cycles) | // +-----------+------------------+----------+-----------+-------------------+ // | HS UTMI+ | 30 | 16-bit | 30_60 | HS:3749 FS:29999 | // | HS UTMI+ | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | // | HS ULPI | 60 | 8-bit | 30_60 | HS:7499 FS:59999 | // | FS (dead.) | 48 | internal | 48 | FS:47999 | // | LS via FS | 48 (6 effective) | internal | 6 | LS:47999 | // +-----------+------------------+----------+-----------+-------------------+ // HFIR = (interval_us * phy_clock) - 1, where interval is 125us (HS) or 1000us (FS/LS) static void port0_enable(dwc2_regs_t* dwc2, tusb_speed_t speed) { uint32_t hcfg = dwc2->hcfg & ~HCFG_FSLS_PHYCLK_SEL; const dwc2_gusbcfg_t gusbcfg = {.value = dwc2->gusbcfg}; uint32_t phy_clock; if (gusbcfg.phy_sel == GUSBCFG_PHYSEL_FULLSPEED) { phy_clock = 48; // dedicated FS is 48Mhz if (speed == TUSB_SPEED_LOW) { hcfg |= HCFG_FSLS_PHYCLK_SEL_6MHZ; } else { hcfg |= HCFG_FSLS_PHYCLK_SEL_48MHZ; } } else { if (gusbcfg.ulpi_utmi_sel == GUSBCFG_PHYHS_ULPI) { phy_clock = 60; // ULPI 8-bit is 60Mhz } else { // UTMI+ 16-bit is 30Mhz, 8-bit is 60Mhz phy_clock = gusbcfg.phy_if16 ? 30 : 60; // Enable UTMI+ low power mode 48Mhz external clock if not highspeed if (speed == TUSB_SPEED_HIGH) { dwc2->gusbcfg &= ~GUSBCFG_PHYLPCS; } else { dwc2->gusbcfg |= GUSBCFG_PHYLPCS; // may need to reset port } } hcfg |= HCFG_FSLS_PHYCLK_SEL_30_60MHZ; } dwc2->hcfg = hcfg; uint32_t hfir = dwc2->hfir & ~HFIR_FRIVL_Msk; if (speed == TUSB_SPEED_HIGH) { hfir |= 125*phy_clock - 1; // The "- 1" is the correct value. The Synopsys databook was corrected in 3.30a } else { hfir |= 1000*phy_clock - 1; } dwc2->hfir = hfir; } /* Handle Host Port interrupt, possible source are: - Connection Detection - Enable Change - Over Current Change */ static void handle_hprt_irq(uint8_t rhport, bool in_isr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_hprt_t hprt_bm = {.value = dwc2->hprt}; uint32_t hprt = hprt_bm.value & ~HPRT_W1_MASK; if (hprt_bm.conn_detected == 1u) { // Port Connect Detect hprt |= HPRT_CONN_DETECT; if (hprt_bm.conn_status == 1u) { hcd_event_device_attach(rhport, in_isr); } } if (hprt_bm.enable_change == 1u) { // Port enable change hprt |= HPRT_ENABLE_CHANGE; if (hprt_bm.enable == 1u) { // Port enable const tusb_speed_t speed = hprt_speed_get(dwc2); port0_enable(dwc2, speed); } else { // TU_ASSERT(false, ); } } dwc2->hprt = hprt; // clear interrupt } /* Interrupt Hierarchy HCINTn HPRT | | HAINT.CHn | | | GINTSTS : HCInt | PrtInt | NPTxFEmp | PTxFEmpp | RXFLVL | SOF */ void hcd_int_handler(uint8_t rhport, bool in_isr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const uint32_t gintmsk = dwc2->gintmsk; const uint32_t gintsts = dwc2->gintsts & gintmsk; // TU_LOG1_HEX(gintsts); if (gintsts & GINTSTS_SOF) { const bool more_sof = handle_sof_irq(rhport, in_isr); if (!more_sof) { dwc2->gintmsk &= ~GINTSTS_SOF; } } if (gintsts & GINTSTS_HPRTINT) { // Host port interrupt: source is cleared in HPRT register // TU_LOG1_HEX(dwc2->hprt); handle_hprt_irq(rhport, in_isr); } if (gintsts & GINTSTS_HCINT) { // Host Channel interrupt: source is cleared in HCINT register // must be handled after TX FIFO empty handle_channel_irq(rhport, in_isr); } if (gintsts & GINTSTS_DISCINT) { // Device disconnected dwc2->gintsts = GINTSTS_DISCINT; if (0 == (dwc2->hprt & HPRT_CONN_STATUS)) { hcd_event_device_remove(rhport, in_isr); } } #if CFG_TUH_DWC2_SLAVE_ENABLE // RxFIFO non-empty interrupt handling if (gintsts & GINTSTS_RXFLVL) { // RXFLVL bit is read-only dwc2->gintmsk &= ~GINTSTS_RXFLVL; // disable RXFLVL interrupt while reading do { handle_rxflvl_irq(rhport); // read all packets } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTSTS_RXFLVL; } if (gintsts & GINTSTS_NPTX_FIFO_EMPTY) { // NPTX FIFO empty interrupt, this is read-only and cleared by hardware when FIFO is written const bool more_nptxfe = handle_txfifo_empty(dwc2, false); if (!more_nptxfe) { // no more pending packet, disable interrupt dwc2->gintmsk &= ~GINTSTS_NPTX_FIFO_EMPTY; } } if (gintsts & GINTSTS_PTX_FIFO_EMPTY) { // PTX FIFO empty interrupt, this is read-only and cleared by hardware when FIFO is written const bool more_ptxfe = handle_txfifo_empty(dwc2, true); if (!more_ptxfe) { // no more pending packet, disable interrupt dwc2->gintmsk &= ~GINTSTS_PTX_FIFO_EMPTY; } } #endif } #endif ================================================ FILE: src/portable/template/dcd_template.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2018, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE #include "device/dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ // Initialize controller to device mode bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; return true; } // Enable device interrupt void dcd_int_enable (uint8_t rhport) { (void) rhport; } // Disable device interrupt void dcd_int_disable (uint8_t rhport) { (void) rhport; } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } // Wake up host void dcd_remote_wakeup (uint8_t rhport) { (void) rhport; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { (void) rhport; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void) rhport; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; (void) ep_desc; return false; } // Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; } // Configure and enable an ISO endpoint according to descriptor bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { (void) rhport; (void) desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; (void) ep_addr; (void) buffer; (void) total_bytes; return false; } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; (void) ep_addr; (void) ff; (void) total_bytes; return false; } // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; (void) ep_addr; } // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; (void) ep_addr; } #endif ================================================ FILE: src/portable/template/hcd_template.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE #include "host/hcd.h" #include "host/usbh.h" //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; (void) cfg_id; (void) cfg_param; return false; } // Initialize controller to host mode bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; return false; } // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; (void) in_isr; } // Enable USB interrupt void hcd_int_enable (uint8_t rhport) { (void) rhport; } // Disable USB interrupt void hcd_int_disable(uint8_t rhport) { (void) rhport; } // Get frame number (1ms) uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return 0; } //--------------------------------------------------------------------+ // Port API //--------------------------------------------------------------------+ // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; return false; } // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport) { (void) rhport; } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } // Get port link speed tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; return TUSB_SPEED_FULL; } // HCD closes all opened endpoints belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } //--------------------------------------------------------------------+ // Endpoints API //--------------------------------------------------------------------+ // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; (void) dev_addr; (void) ep_desc; // NOTE: ep_desc is allocated on the stack when called from usbh_edpt_control_open() // You need to copy the data into a local variable who maintains the state of the endpoint and transfer. // Check _hcd_data in hcd_dwc2.c for example. return false; } bool hcd_edpt_close(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { (void) rhport; (void) daddr; (void) ep_addr; return false; // TODO not implemented yet } // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void) rhport; (void) dev_addr; (void) ep_addr; (void) buffer; (void) buflen; return false; } // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; return false; } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; (void) dev_addr; (void) setup_packet; return false; } // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; return false; } #endif ================================================ FILE: src/portable/ti/msp430x5xx/dcd_msp430x5xx.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019-2020 William D. Jones * Copyright (c) 2019-2020 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx ) #include "msp430.h" #include "device/dcd.h" /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ // usbpllir_mirror and usbmaintl_mirror can be added later if needed. static volatile uint16_t usbiepie_mirror = 0; static volatile uint16_t usboepie_mirror = 0; static volatile uint8_t usbie_mirror = 0; static volatile uint16_t usbpwrctl_mirror = 0; static bool in_isr = false; uint8_t _setup_packet[8]; // Xfer control typedef struct { uint8_t * buffer; // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API uint16_t total_len; uint16_t queued_len; uint16_t max_size; bool short_packet; } xfer_ctl_t; xfer_ctl_t xfer_status[8][2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] // Accessing endpoint regs typedef volatile uint8_t * ep_regs_t; typedef enum { CNF = 0, BBAX = 1, BCTX = 2, BBAY = 5, BCTY = 6, SIZXY = 7 } ep_regs_index_t; #define EP_REGS(epnum, dir) ((ep_regs_t) ((uintptr_t)&USBOEPCNF_1 + 64*dir + 8*(epnum - 1))) static void bus_reset(void) { // Hardcoded into the USB core. xfer_status[0][TUSB_DIR_OUT].max_size = 8; xfer_status[0][TUSB_DIR_IN].max_size = 8; USBKEYPID = USBKEY; // Enable the control EP 0. Also enable Indication Enable- a guard flag // separate from the Interrupt Enable mask. USBOEPCNF_0 |= (UBME | USBIIE); USBIEPCNF_0 |= (UBME | USBIIE); // Enable interrupts for this endpoint. USBOEPIE |= BIT0; USBIEPIE |= BIT0; // Clear NAK until a setup packet is received. USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; // Enable responding to packets. USBCTL |= FEN; // Dedicated buffers in hardware for SETUP and EP0, no setup needed. // Now safe to respond to SETUP packets. USBIE |= SETUPIE; USBKEYPID = 0; } // Controls reset behavior of the USB module on receipt of a bus reset event. // - enable: When true, bus reset events will cause a reset the USB module. static void enable_functional_reset(const bool enable) { // Check whether or not the USB configuration registers were // locked prior to this function being called so that, if // necessary, the lock state can be restored on exit. bool unlocked = (USBKEYPID == 0xA528) ? true : false; if(!unlocked) USBKEYPID = USBKEY; if(enable) { USBCTL |= FRSTE; } else { USBCTL &= ~FRSTE; } if(!unlocked) USBKEYPID = 0; } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; USBKEYPID = USBKEY; // Enable the module (required to write config regs)! USBCNF |= USB_EN; // Reset used interrupts USBOEPIE = 0; USBIEPIE = 0; USBIE = 0; USBOEPIFG = 0; USBIEPIFG = 0; USBIFG = 0; USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE | VUOVLIFG | VBONIFG | VBOFFIFG); usboepie_mirror = 0; usbiepie_mirror = 0; usbie_mirror = 0; usbpwrctl_mirror = 0; USBVECINT = 0; if(USBPWRCTL & USBBGVBV) {// Bus power detected? USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBIE |= RSTRIE; // Enable reset and wait for it before continuing. USBCNF |= PUR_EN; // Enable pullup. } else { USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. } USBKEYPID = 0; return true; } // There is no "USB peripheral interrupt disable" bit on MSP430, so we have // to save the relevant registers individually. // WARNING: Unlike the ARM/NVIC routines, these functions are _not_ idempotent // if you modified the registers saved in between calls so they don't match // the mirrors; mirrors will be updated to reflect most recent register // contents. void dcd_int_enable (uint8_t rhport) { (void) rhport; __bic_SR_register(GIE); // Unlikely to be called in ISR, but let's be safe. // Also, this cleanly disables all USB interrupts // atomically from application's POV. // This guard is required because tinyusb can enable interrupts without // having disabled them first. if(in_isr) { USBOEPIE = usboepie_mirror; USBIEPIE = usbiepie_mirror; USBIE = usbie_mirror; USBPWRCTL |= usbpwrctl_mirror; } in_isr = false; __bis_SR_register(GIE); } void dcd_int_disable (uint8_t rhport) { (void) rhport; __bic_SR_register(GIE); usboepie_mirror = USBOEPIE; usbiepie_mirror = USBIEPIE; usbie_mirror = USBIE; usbpwrctl_mirror = (USBPWRCTL & (VUOVLIE | VBONIE | VBOFFIE)); USBOEPIE = 0; USBIEPIE = 0; USBIE = 0; USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE); in_isr = true; __bis_SR_register(GIE); } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) rhport; USBFUNADR = dev_addr; // Response with status after changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; } void dcd_connect(uint8_t rhport) { dcd_int_disable(rhport); USBKEYPID = USBKEY; USBCNF |= PUR_EN; // Enable pullup. USBKEYPID = 0; dcd_int_enable(rhport); } void dcd_disconnect(uint8_t rhport) { dcd_int_disable(rhport); USBKEYPID = USBKEY; USBCNF &= ~PUR_EN; // Disable pullup. USBKEYPID = 0; dcd_int_enable(rhport); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void) rhport; uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); // Unsupported endpoint numbers or type (Iso not supported. Control // not supported on nonzero endpoints). if( (epnum > 7) || \ (desc_edpt->bmAttributes.xfer == 0) || \ (desc_edpt->bmAttributes.xfer == 1)) { return false; } xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); // Buffer allocation scheme: // For simplicity, only single buffer for now, since tinyusb currently waits // for an xfer to complete before scheduling another one. This means only // the X buffer is used. // // 1904 bytes are available, the max endpoint size supported on msp430 is // 64 bytes. This is enough RAM for all 14 endpoints enabled _with_ double // bufferring (64*14*2 = 1792 bytes). Extra RAM exists for triple and higher // order bufferring, which must be maintained in software. // // For simplicity, each endpoint gets a hardcoded 64 byte chunk (regardless // of actual wMaxPacketSize) whose start address is the following: // addr = 128 * (epnum - 1) + 64 * dir. // // Double buffering equation: // x_addr = 256 * (epnum - 1) + 128 * dir // y_addr = x_addr + 64 // Address is right-shifted by 3 to fit into 8 bits. uint8_t buf_base = (128 * (epnum - 1) + 64 * dir) >> 3; // IN and OUT EP registers have the same structure. ep_regs_t ep_regs = EP_REGS(epnum, dir); // FIXME: I was able to get into a situation where OUT EP 3 would stall // while debugging, despite stall code never being called. It appears // these registers don't get cleared on reset, being part of RAM. // Investigate and see if I can duplicate. // Also, DBUF got set on OUT EP 2 while debugging. Only OUT EPs seem to be // affected at this time. USB RAM directly precedes main RAM; perhaps I'm // overwriting registers via buffer overflow w/ my debugging code? ep_regs[SIZXY] = tu_edpt_packet_size(desc_edpt); ep_regs[BCTX] |= NAK; ep_regs[BBAX] = buf_base; ep_regs[CNF] &= ~(TOGGLE | STALL | DBUF); // ISO xfers not supported on // MSP430, so no need to gate DATA0/1 and frame // behavior. Clear stall and double buffer bit as // well- see above comment. ep_regs[CNF] |= (UBME | USBIIE); USBKEYPID = USBKEY; if(dir == TUSB_DIR_OUT) { USBOEPIE |= (1 << epnum); } else { USBIEPIE |= (1 << epnum); } USBKEYPID = 0; return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->buffer = buffer; // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->short_packet = false; if(epnum == 0) { if(dir == TUSB_DIR_OUT) { // Interrupt will notify us when data was received. USBCTL &= ~DIR; USBOEPCNT_0 &= ~NAK; } else { // Kickstart the IN packet handler by queuing initial data and calling // the ISR to transmit the first packet. // Interrupt only fires on completed xfer. USBCTL |= DIR; USBIEPIFG |= BIT0; } } else { ep_regs_t ep_regs = EP_REGS(epnum, dir); if(dir == TUSB_DIR_OUT) { ep_regs[BCTX] &= ~NAK; } else { USBIEPIFG |= (1 << epnum); } } return true; } #if 0 // TODO support dcd_edpt_xfer_fifo API bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->short_packet = false; ep_regs_t ep_regs = EP_REGS(epnum, dir); if(dir == TUSB_DIR_OUT) { ep_regs[BCTX] &= ~NAK; } else { USBIEPIFG |= (1 << epnum); } return true; } #endif void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); if(epnum == 0) { if(dir == TUSB_DIR_OUT) { USBOEPCNT_0 |= NAK; USBOEPCNF_0 |= STALL; } else { USBIEPCNT_0 |= NAK; USBIEPCNF_0 |= STALL; } } else { ep_regs_t ep_regs = EP_REGS(epnum, dir); ep_regs[CNF] |= STALL; } } void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); if(epnum == 0) { if(dir == TUSB_DIR_OUT) { USBOEPCNF_0 &= ~STALL; } else { USBIEPCNF_0 &= ~STALL; } } else { ep_regs_t ep_regs = EP_REGS(epnum, dir); // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt // and bulk endpoints. ep_regs[CNF] &= ~(STALL + TOGGLE); } } void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; (void) request; // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the // Status Phase of a control xfer is done, in preparation of another possible // SETUP packet. However, from my own testing, SETUP packets _are_ correctly // handled by the USB core without clearing the NAKs. // // Right now, clearing NAKs in this callbacks causes a direction mismatch // between host and device on EP0. Figure out why and come back to this. // USBOEPCNT_0 &= ~NAK; // USBIEPCNT_0 &= ~NAK; } /*------------------------------------------------------------------*/ static void receive_packet(uint8_t ep_num) { xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_OUT); ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_OUT); uint8_t xfer_size; if(ep_num == 0) { xfer_size = USBOEPCNT_0 & 0x0F; } else { xfer_size = ep_regs[BCTX] & 0x7F; } uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t to_recv_size; if(remaining <= xfer->max_size) { // Avoid buffer overflow. to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; } else { // Room for full packet, choose recv_size based on what the microcontroller // claims. to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; } #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { volatile uint8_t * ep_buf = (ep_num == 0) ? &USBOEP0BUF : (&USBSTABUFF + (ep_regs[BBAX] << 3)); tu_fifo_write_n(xfer->ff, (const void *) ep_buf, to_recv_size); } else #endif { uint8_t * base = (xfer->buffer + xfer->queued_len); if(ep_num == 0) { volatile uint8_t * ep0out_buf = &USBOEP0BUF; for(uint16_t i = 0; i < to_recv_size; i++) { base[i] = ep0out_buf[i]; } } else { volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); for(uint16_t i = 0; i < to_recv_size ; i++) { base[i] = ep_buf[i]; } } } xfer->queued_len += xfer_size; xfer->short_packet = (xfer_size < xfer->max_size); if((xfer->total_len == xfer->queued_len) || xfer->short_packet) { dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Schedule to receive another packet. if(ep_num == 0) { USBOEPCNT_0 &= ~NAK; } else { ep_regs[BCTX] &= ~NAK; } } } static void transmit_packet(uint8_t ep_num) { xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_IN); // First, determine whether we should even send a packet or finish // up the xfer. bool zlp = (xfer->total_len == 0); // By necessity, xfer->total_len will // equal xfer->queued_len for ZLPs. // Of course a ZLP is a short packet. if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) { dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); return; } // Then actually commit to transmit a packet. uint8_t * base = (xfer->buffer + xfer->queued_len); uint16_t remaining = xfer->total_len - xfer->queued_len; uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; xfer->queued_len += xfer_size; if(xfer_size < xfer->max_size) { // Next "xfer complete interrupt", the transfer will end. xfer->short_packet = true; } if(ep_num == 0) { volatile uint8_t * ep0in_buf = &USBIEP0BUF; for(uint16_t i = 0; i < xfer_size; i++) { ep0in_buf[i] = base[i]; } USBIEPCNT_0 = (USBIEPCNT_0 & 0xF0) + xfer_size; USBIEPCNT_0 &= ~NAK; } else { ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_IN); volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); #if 0 // TODO support dcd_edpt_xfer_fifo API if (xfer->ff) { tu_fifo_read_n(xfer->ff, (void *) ep_buf, xfer_size); } else #endif { for(int i = 0; i < xfer_size; i++) { ep_buf[i] = base[i]; } } ep_regs[BCTX] = (ep_regs[BCTX] & 0x80) + (xfer_size & 0x7F); ep_regs[BCTX] &= ~NAK; } } static void handle_setup_packet(void) { volatile uint8_t * setup_buf = &USBSUBLK; for(int i = 0; i < 8; i++) { _setup_packet[i] = setup_buf[i]; } // Force NAKs until tinyusb can handle the SETUP packet and prepare for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; // Clear SETUPIFG to avoid handling in the USBVECINT switch statement. // When handled there the NAKs applied to the endpoints above are // cleared by hardware and the host will receive stale/duplicate data. // // Excerpt from MSP430x5xx and MSP430x6xx Family User's Guide: // // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on // input endpoint 0 and output endpoint 0 is also cleared." USBIEPCNF_0 &= ~UBME; // Errata USB10 workaround. USBOEPCNF_0 &= ~UBME; // Errata USB10 workaround. USBIFG &= ~SETUPIFG; USBIEPCNF_0 |= UBME; // Errata USB10 workaround. USBOEPCNF_0 |= UBME; // Errata USB10 workaround. dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } static void handle_bus_power_event(void *param) { (void) param; tusb_time_delay_ms_api(5); // Bus power settling delay. USBKEYPID = USBKEY; if(USBPWRCTL & USBBGVBV) { // Event caused by application of bus power. USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider // register is re-written. The assumption here is that this // register was already properly configured during board-level // initialization. USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. uint16_t attempts = 0; do { // Poll the PLL, checking for a successful lock. USBPLLIR = 0; tusb_time_delay_ms_api(1); attempts++; } while ((attempts < 10) && (USBPLLIR != 0)); // A successful lock is indicated by all PLL-related interrupt flags being cleared. if(!USBPLLIR) { const tusb_rhport_init_t rhport_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_FULL }; dcd_init(0, &rhport_init); // Re-initialize the USB module. } } else { // Event caused by removal of bus power. USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. USBCNF = 0; // Disable the USB module. dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); } USBKEYPID = 0; } void dcd_int_handler(uint8_t rhport) { (void) rhport; // Setup is special- reading USBVECINT to handle setup packets is done to // stop hardware-generated NAKs on EP0. uint8_t setup_status = USBIFG & SETUPIFG; if(setup_status) { enable_functional_reset(true); handle_setup_packet(); } // Workaround possible bug in MSP430 GCC 9.3.0 where volatile variable // USBVECINT is read from twice when only once is intended. The second // (garbage) read seems to be triggered by certain switch statement // configurations. uint16_t curr_vector; #if __GNUC__ > 9 || (__GNUC__ == 9 && __GNUC_MINOR__ > 2) asm volatile ("mov %1, %0" : "=r" (curr_vector) : "m" (USBVECINT)); #else curr_vector = USBVECINT; #endif switch(curr_vector) { case USBVECINT_NONE: break; case USBVECINT_RSTR: enable_functional_reset(false); // Errata USB4 workaround. bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; case USBVECINT_PWR_VBUSOn: case USBVECINT_PWR_VBUSOff: { USBKEYPID = USBKEY; // Prevent (possibly) unstable power from generating spurious interrupts. USBPWRCTL &= ~(VBONIE | VBOFFIE); USBKEYPID = 0; dcd_event_t event; event.rhport = 0; event.event_id = USBD_EVENT_FUNC_CALL; event.func_call.func = handle_bus_power_event; dcd_event_handler(&event, true); } break; // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet // is received. At this point, even though the hardware is no longer // forcing NAKs, the EP0 NAK bits should still be set to avoid // sending/receiving data before tinyusb is ready. // // Furthermore, it's possible for the hardware to STALL in the middle of // a control xfer if the EP0 NAK bits aren't set properly. // See: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/845259 // From my testing, if all of the following hold: // * OUT EP0 NAK is cleared. // * IN EP0 NAK is set. // * DIR bit in USBCTL is clear. // and an IN packet is received on EP0, the USB core will STALL. Setting // both EP0 NAKs manually when a SETUP packet is received, as is done // in handle_setup_packet(), avoids meeting STALL conditions. // // TODO: Figure out/explain why the STALL condition can be reached in the // first place. When I first noticed the STALL, the only two places I // touched the NAK bits were in dcd_edpt_xfer() and to _set_ (sic) them in // bus_reset(). SETUP packet handling should've been unaffected. case USBVECINT_SETUP_PACKET_RECEIVED: break; case USBVECINT_INPUT_ENDPOINT0: enable_functional_reset(true); transmit_packet(0); break; case USBVECINT_OUTPUT_ENDPOINT0: enable_functional_reset(true); receive_packet(0); break; case USBVECINT_INPUT_ENDPOINT1: case USBVECINT_INPUT_ENDPOINT2: case USBVECINT_INPUT_ENDPOINT3: case USBVECINT_INPUT_ENDPOINT4: case USBVECINT_INPUT_ENDPOINT5: case USBVECINT_INPUT_ENDPOINT6: case USBVECINT_INPUT_ENDPOINT7: { uint8_t ep = ((curr_vector - USBVECINT_INPUT_ENDPOINT1) >> 1) + 1; transmit_packet(ep); } break; case USBVECINT_OUTPUT_ENDPOINT1: case USBVECINT_OUTPUT_ENDPOINT2: case USBVECINT_OUTPUT_ENDPOINT3: case USBVECINT_OUTPUT_ENDPOINT4: case USBVECINT_OUTPUT_ENDPOINT5: case USBVECINT_OUTPUT_ENDPOINT6: case USBVECINT_OUTPUT_ENDPOINT7: { uint8_t ep = ((curr_vector - USBVECINT_OUTPUT_ENDPOINT1) >> 1) + 1; receive_packet(ep); } break; default: while(true); } } #endif ================================================ FILE: src/portable/valentyusb/eptri/dcd_eptri.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) #ifndef DEBUG #define DEBUG 0 #endif #ifndef LOG_USB #define LOG_USB 0 #endif #include "device/dcd.h" #include "dcd_eptri.h" #include "csr.h" #include "irq.h" void fomu_error(uint32_t line); #if LOG_USB struct usb_log { uint8_t ep_num; uint8_t size; uint8_t data[66]; }; __attribute__((used)) struct usb_log usb_log[128]; __attribute__((used)) uint8_t usb_log_offset; struct xfer_log { uint8_t ep_num; uint16_t size; }; __attribute__((used)) struct xfer_log xfer_log[64]; __attribute__((used)) uint8_t xfer_log_offset; __attribute__((used)) struct xfer_log queue_log[64]; __attribute__((used)) uint8_t queue_log_offset; #endif //--------------------------------------------------------------------+ // SIE Command //--------------------------------------------------------------------+ #define EP_SIZE 64 uint16_t volatile rx_buffer_offset[16]; uint8_t* volatile rx_buffer[16]; uint16_t volatile rx_buffer_max[16]; volatile uint8_t tx_ep; volatile bool tx_active; volatile uint16_t tx_buffer_offset[16]; uint8_t* volatile tx_buffer[16]; volatile uint16_t tx_buffer_max[16]; volatile uint8_t reset_count; #if DEBUG __attribute__((used)) uint8_t volatile * last_tx_buffer; __attribute__((used)) volatile uint8_t last_tx_ep; uint8_t setup_packet_bfr[10]; #endif //--------------------------------------------------------------------+ // PIPE HELPER //--------------------------------------------------------------------+ static bool advance_tx_ep(void) { // Move on to the next transmit buffer in a round-robin manner uint8_t prev_tx_ep = tx_ep; for (tx_ep = (tx_ep + 1) & 0xf; tx_ep != prev_tx_ep; tx_ep = ((tx_ep + 1) & 0xf)) { if (tx_buffer[tx_ep]) return true; } if (!tx_buffer[tx_ep]) return false; return true; } #if LOG_USB void xfer_log_append(uint8_t ep_num, uint16_t sz) { xfer_log[xfer_log_offset].ep_num = ep_num; xfer_log[xfer_log_offset].size = sz; xfer_log_offset++; if (xfer_log_offset >= sizeof(xfer_log)/sizeof(*xfer_log)) xfer_log_offset = 0; } void queue_log_append(uint8_t ep_num, uint16_t sz) { queue_log[queue_log_offset].ep_num = ep_num; queue_log[queue_log_offset].size = sz; queue_log_offset++; if (queue_log_offset >= sizeof(queue_log)/sizeof(*queue_log)) queue_log_offset = 0; } #endif static void tx_more_data(void) { // Send more data uint8_t added_bytes; for (added_bytes = 0; (added_bytes < EP_SIZE) && (tx_buffer_offset[tx_ep] < tx_buffer_max[tx_ep]); added_bytes++) { #if LOG_USB usb_log[usb_log_offset].data[added_bytes] = tx_buffer[tx_ep][tx_buffer_offset[tx_ep]]; #endif usb_in_data_write(tx_buffer[tx_ep][tx_buffer_offset[tx_ep]++]); } #if LOG_USB usb_log[usb_log_offset].ep_num = tu_edpt_addr(tx_ep, TUSB_DIR_IN); usb_log[usb_log_offset].size = added_bytes; usb_log_offset++; if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) usb_log_offset = 0; #endif // Updating the epno queues the data usb_in_ctrl_write(tx_ep & 0xf); } static void process_tx(void) { #if DEBUG // If the system isn't idle, then something is very wrong. uint8_t in_status = usb_in_status_read(); if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))) fomu_error(__LINE__); #endif // If the buffer is now empty, search for the next buffer to fill. if (!tx_buffer[tx_ep]) { if (advance_tx_ep()) tx_more_data(); else tx_active = false; return; } if (tx_buffer_offset[tx_ep] >= tx_buffer_max[tx_ep]) { #if DEBUG last_tx_buffer = tx_buffer[tx_ep]; last_tx_ep = tx_ep; #endif tx_buffer[tx_ep] = NULL; uint16_t xferred_bytes = tx_buffer_max[tx_ep]; uint8_t xferred_ep = tx_ep; if (!advance_tx_ep()) tx_active = false; #if LOG_USB xfer_log_append(tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes); #endif dcd_event_xfer_complete(0, tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes, XFER_RESULT_SUCCESS, true); if (!tx_active) return; } tx_more_data(); return; } static void process_rx(void) { uint8_t out_status = usb_out_status_read(); #if DEBUG // If the OUT handler is still waiting to send, don't do anything. if (!(out_status & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET))) fomu_error(__LINE__); // return; #endif uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf; // If the destination buffer doesn't exist, don't drain the hardware // fifo. Note that this can cause deadlocks if the host is waiting // on some other endpoint's data! #if DEBUG if (rx_buffer[rx_ep] == NULL) { fomu_error(__LINE__); return; } #endif // Drain the FIFO into the destination buffer uint32_t total_read = 0; uint32_t current_offset = rx_buffer_offset[rx_ep]; #if DEBUG uint8_t test_buffer[256]; memset(test_buffer, 0, sizeof(test_buffer)); if (current_offset > rx_buffer_max[rx_ep]) fomu_error(__LINE__); #endif #if LOG_USB usb_log[usb_log_offset].ep_num = tu_edpt_addr(rx_ep, TUSB_DIR_OUT); usb_log[usb_log_offset].size = 0; #endif while (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)) { uint8_t c = usb_out_data_read(); #if DEBUG test_buffer[total_read] = c; #endif total_read++; if (current_offset < rx_buffer_max[rx_ep]) { #if LOG_USB usb_log[usb_log_offset].data[usb_log[usb_log_offset].size++] = c; #endif if (rx_buffer[rx_ep] != (volatile uint8_t *)0xffffffff) rx_buffer[rx_ep][current_offset++] = c; } } #if LOG_USB usb_log_offset++; if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) usb_log_offset = 0; #endif #if DEBUG if (total_read > 66) fomu_error(__LINE__); if (total_read < 2) total_read = 2; // fomu_error(__LINE__); #endif // Strip off the CRC16 rx_buffer_offset[rx_ep] += (total_read - 2); if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep]) rx_buffer_offset[rx_ep] = rx_buffer_max[rx_ep]; // If there's no more data, complete the transfer to tinyusb if ((rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep]) // ZLP with less than the total amount of data || ((total_read == 2) && ((rx_buffer_offset[rx_ep] & 63) == 0)) // Short read, but not a full packet || (((rx_buffer_offset[rx_ep] & 63) != 0) && (total_read < 66))) { #if DEBUG if (rx_buffer[rx_ep] == NULL) fomu_error(__LINE__); #endif // Free up this buffer. rx_buffer[rx_ep] = NULL; uint16_t len = rx_buffer_offset[rx_ep]; #if DEBUG // Validate that all enabled endpoints have buffers, // and no disabled endpoints have buffers. uint16_t ep_en_mask = usb_out_enable_status_read(); int i; for (i = 0; i < 16; i++) { if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { uint8_t new_status = usb_out_status_read(); // Another IRQ came in while we were processing, so ignore this endpoint. if ((new_status & 0x20) && ((new_status & 0xf) == i)) continue; fomu_error(__LINE__); } } #endif #if LOG_USB xfer_log_append(tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len); #endif dcd_event_xfer_complete(0, tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len, XFER_RESULT_SUCCESS, true); } else { // If there's more data, re-enable data reception on this endpoint usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | rx_ep); } // Now that the buffer is drained, clear the pending IRQ. usb_out_ev_pending_write(usb_out_ev_pending_read()); } //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ static void dcd_reset(void) { reset_count++; usb_setup_ev_enable_write(0); usb_in_ev_enable_write(0); usb_out_ev_enable_write(0); usb_address_write(0); // Reset all three FIFO handlers usb_setup_ctrl_write(1 << CSR_USB_SETUP_CTRL_RESET_OFFSET); usb_in_ctrl_write(1 << CSR_USB_IN_CTRL_RESET_OFFSET); usb_out_ctrl_write(1 << CSR_USB_OUT_CTRL_RESET_OFFSET); memset((void *)(uintptr_t) rx_buffer, 0, sizeof(rx_buffer)); memset((void *)(uintptr_t) rx_buffer_max, 0, sizeof(rx_buffer_max)); memset((void *)(uintptr_t) rx_buffer_offset, 0, sizeof(rx_buffer_offset)); memset((void *)(uintptr_t) tx_buffer, 0, sizeof(tx_buffer)); memset((void *)(uintptr_t) tx_buffer_max, 0, sizeof(tx_buffer_max)); memset((void *)(uintptr_t) tx_buffer_offset, 0, sizeof(tx_buffer_offset)); tx_ep = 0; tx_active = false; // Enable all event handlers and clear their contents usb_setup_ev_pending_write(0xff); usb_in_ev_pending_write(0xff); usb_out_ev_pending_write(0xff); usb_in_ev_enable_write(1); usb_out_ev_enable_write(1); usb_setup_ev_enable_write(3); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); } // Initializes the USB peripheral for device mode and enables it. bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; usb_pullup_out_write(0); // Enable all event handlers and clear their contents usb_setup_ev_pending_write(usb_setup_ev_pending_read()); usb_in_ev_pending_write(usb_in_ev_pending_read()); usb_out_ev_pending_write(usb_out_ev_pending_read()); usb_in_ev_enable_write(1); usb_out_ev_enable_write(1); usb_setup_ev_enable_write(3); // Turn on the external pullup usb_pullup_out_write(1); return true; } // Enables or disables the USB device interrupt(s). May be used to // prevent concurrency issues when mutating data structures shared // between main code and the interrupt handler. void dcd_int_enable(uint8_t rhport) { (void) rhport; irq_setmask(irq_getmask() | (1 << USB_INTERRUPT)); } void dcd_int_disable(uint8_t rhport) { (void) rhport; irq_setmask(irq_getmask() & ~(1 << USB_INTERRUPT)); } // Called when the device is given a new bus address. void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { // Respond with ACK status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); // Wait for the response packet to get sent while (tx_active) ; // Activate the new address usb_address_write(dev_addr); } // Called to remote wake up host when suspended (e.g hid keyboard) void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; } void dcd_connect(uint8_t rhport) { (void) rhport; usb_pullup_out_write(1); } void dcd_disconnect(uint8_t rhport) { (void) rhport; usb_pullup_out_write(0); } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { (void) rhport; uint8_t ep_num = tu_edpt_number(p_endpoint_desc->bEndpointAddress); uint8_t ep_dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) return false; // Not supported if (ep_dir == TUSB_DIR_OUT) { rx_buffer_offset[ep_num] = 0; rx_buffer_max[ep_num] = 0; rx_buffer[ep_num] = NULL; } else if (ep_dir == TUSB_DIR_IN) { tx_buffer_offset[ep_num] = 0; tx_buffer_max[ep_num] = 0; tx_buffer[ep_num] = NULL; } return true; } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; (void)ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; // TODO implement dcd_edpt_close_all() } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { uint8_t enable = 0; if (rx_buffer[ep_addr]) enable = 1; usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); } else usb_in_ctrl_write((1 << CSR_USB_IN_CTRL_STALL_OFFSET) | tu_edpt_number(ep_addr)); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { uint8_t enable = 0; if (rx_buffer[ep_addr]) enable = 1; usb_out_ctrl_write((0 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); } // IN endpoints will get un-stalled when more data is written. } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void)rhport; uint8_t ep_num = tu_edpt_number(ep_addr); uint8_t ep_dir = tu_edpt_dir(ep_addr); TU_ASSERT(ep_num < 16); // Give a nonzero buffer when we transmit 0 bytes, so that the // system doesn't think the endpoint is idle. if ((buffer == NULL) && (total_bytes == 0)) { buffer = (uint8_t *)0xffffffff; } TU_ASSERT(buffer != NULL); if (ep_dir == TUSB_DIR_IN) { // Wait for the tx pipe to free up uint8_t previous_reset_count = reset_count; // Continue until the buffer is empty, the system is idle, and the fifo is empty. while (tx_buffer[ep_num] != NULL) ; dcd_int_disable(0); #if LOG_USB queue_log_append(ep_addr, total_bytes); #endif // If a reset happens while we're waiting, abort the transfer if (previous_reset_count != reset_count) return true; TU_ASSERT(tx_buffer[ep_num] == NULL); tx_buffer_offset[ep_num] = 0; tx_buffer_max[ep_num] = total_bytes; tx_buffer[ep_num] = buffer; // If the current buffer is NULL, then that means the tx logic is idle. // Update the tx_ep to point to our endpoint number and queue the data. // Otherwise, let it be and it'll get picked up after the next transfer // finishes. if (!tx_active) { tx_ep = ep_num; tx_active = true; tx_more_data(); } dcd_int_enable(0); } else if (ep_dir == TUSB_DIR_OUT) { while (rx_buffer[ep_num] != NULL) ; TU_ASSERT(rx_buffer[ep_num] == NULL); dcd_int_disable(0); #if LOG_USB queue_log_append(ep_addr, total_bytes); #endif rx_buffer[ep_num] = buffer; rx_buffer_offset[ep_num] = 0; rx_buffer_max[ep_num] = total_bytes; // Enable receiving on this particular endpoint usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | ep_num); #if DEBUG uint16_t ep_en_mask = usb_out_enable_status_read(); int i; for (i = 0; i < 16; i++) { if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { if (rx_buffer[i] && usb_out_ev_pending_read() && (usb_out_status_read() & 0xf) == i) continue; fomu_error(__LINE__); } } #endif dcd_int_enable(0); } return true; } //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ static void handle_out(void) { // An "OUT" transaction just completed so we have new data. // (But only if we can accept the data) #if DEBUG if (!usb_out_ev_pending_read()) fomu_error(__LINE__); if (!usb_out_ev_enable_read()) fomu_error(__LINE__); #endif process_rx(); } static void handle_in(void) { #if DEBUG if (!usb_in_ev_pending_read()) fomu_error(__LINE__); if (!usb_in_ev_enable_read()) fomu_error(__LINE__); #endif usb_in_ev_pending_write(usb_in_ev_pending_read()); process_tx(); } static void handle_reset(void) { #if DEBUG uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); if (!(setup_pending & 2)) fomu_error(__LINE__); #endif usb_setup_ev_pending_write(2); // This event means a bus reset occurred. Reset everything, and // abandon any further processing. dcd_reset(); } static void handle_setup(void) { #if !DEBUG uint8_t setup_packet_bfr[10]; #endif #if DEBUG uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); if (!(setup_pending & 1)) fomu_error(__LINE__); #endif // We got a SETUP packet. Copy it to the setup buffer and clear // the "pending" bit. // Setup packets are always 8 bytes, plus two bytes of crc16. uint32_t setup_length = 0; #if DEBUG if (!(usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET))) fomu_error(__LINE__); #endif while (usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET)) { uint8_t c = usb_setup_data_read(); if (setup_length < sizeof(setup_packet_bfr)) setup_packet_bfr[setup_length] = c; setup_length++; } // If we have 10 bytes, that's a full SETUP packet plus CRC16. // Otherwise, it was an RX error. if (setup_length == 10) { dcd_event_setup_received(0, setup_packet_bfr, true); } #if DEBUG else { fomu_error(__LINE__); } #endif usb_setup_ev_pending_write(1); } void dcd_int_handler(uint8_t rhport) { (void)rhport; uint8_t next_ev; while ((next_ev = usb_next_ev_read())) { switch (next_ev) { case 1 << CSR_USB_NEXT_EV_IN_OFFSET: handle_in(); break; case 1 << CSR_USB_NEXT_EV_OUT_OFFSET: handle_out(); break; case 1 << CSR_USB_NEXT_EV_SETUP_OFFSET: handle_setup(); break; case 1 << CSR_USB_NEXT_EV_RESET_OFFSET: handle_reset(); break; } } } #endif ================================================ FILE: src/portable/valentyusb/eptri/dcd_eptri.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_DCD_VALENTYUSB_EPTRI_H_ #define TUSB_DCD_VALENTYUSB_EPTRI_H_ #include "common/tusb_common.h" #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* TUSB_DCD_VALENTYUSB_EPTRI_H_ */ ================================================ FILE: src/portable/wch/ch32_usbfs_reg.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Matthew Tran * Copyright (c) 2024 hathach * * 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. * * This file is part of the TinyUSB stack. */ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #if CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #elif CFG_TUSB_MCU == OPT_MCU_CH32V103 #include typedef struct { __IO uint8_t BASE_CTRL; __IO uint8_t UDEV_CTRL; __IO uint8_t INT_EN; __IO uint8_t DEV_ADDR; __IO uint8_t Reserve0; __IO uint8_t MIS_ST; __IO uint8_t INT_FG; __IO uint8_t INT_ST; __IO uint32_t RX_LEN; __IO uint8_t UEP4_1_MOD; __IO uint8_t UEP2_3_MOD; __IO uint8_t UEP5_6_MOD; __IO uint8_t UEP7_MOD; __IO uint32_t UEP0_DMA; __IO uint32_t UEP1_DMA; __IO uint32_t UEP2_DMA; __IO uint32_t UEP3_DMA; __IO uint32_t UEP4_DMA; __IO uint32_t UEP5_DMA; __IO uint32_t UEP6_DMA; __IO uint32_t UEP7_DMA; __IO uint16_t UEP0_TX_LEN; __IO uint8_t UEP0_TX_CTRL; __IO uint8_t UEP0_RX_CTRL; __IO uint16_t UEP1_TX_LEN; __IO uint8_t UEP1_TX_CTRL; __IO uint8_t UEP1_RX_CTRL; __IO uint16_t UEP2_TX_LEN; __IO uint8_t UEP2_TX_CTRL; __IO uint8_t UEP2_RX_CTRL; __IO uint16_t UEP3_TX_LEN; __IO uint8_t UEP3_TX_CTRL; __IO uint8_t UEP3_RX_CTRL; __IO uint16_t UEP4_TX_LEN; __IO uint8_t UEP4_TX_CTRL; __IO uint8_t UEP4_RX_CTRL; __IO uint16_t UEP5_TX_LEN; __IO uint8_t UEP5_TX_CTRL; __IO uint8_t UEP5_RX_CTRL; __IO uint16_t UEP6_TX_LEN; __IO uint8_t UEP6_TX_CTRL; __IO uint8_t UEP6_RX_CTRL; __IO uint16_t UEP7_TX_LEN; __IO uint8_t UEP7_TX_CTRL; __IO uint8_t UEP7_RX_CTRL; __IO uint32_t Reserve1; __IO uint32_t OTG_CR; __IO uint32_t OTG_SR; } USBOTG_FS_TypeDef; #define USBOTG_FS ((USBOTG_FS_TypeDef *) 0x40023400) #elif CFG_TUSB_MCU == OPT_MCU_CH32V20X #include #elif CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn #endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // CTRL #define USBFS_CTRL_DMA_EN (1 << 0) #define USBFS_CTRL_CLR_ALL (1 << 1) #define USBFS_CTRL_RESET_SIE (1 << 2) #define USBFS_CTRL_INT_BUSY (1 << 3) #define USBFS_CTRL_SYS_CTRL (1 << 4) #define USBFS_CTRL_DEV_PUEN (1 << 5) #define USBFS_CTRL_LOW_SPEED (1 << 6) #define USBFS_CTRL_HOST_MODE (1 << 7) // INT_EN #define USBFS_INT_EN_BUS_RST (1 << 0) #define USBFS_INT_EN_DETECT (1 << 0) #define USBFS_INT_EN_TRANSFER (1 << 1) #define USBFS_INT_EN_SUSPEND (1 << 2) #define USBFS_INT_EN_HST_SOF (1 << 3) #define USBFS_INT_EN_FIFO_OV (1 << 4) #define USBFS_INT_EN_DEV_NAK (1 << 6) #define USBFS_INT_EN_DEV_SOF (1 << 7) // INT_FG #define USBFS_INT_FG_BUS_RST (1 << 0) #define USBFS_INT_FG_DETECT (1 << 0) #define USBFS_INT_FG_TRANSFER (1 << 1) #define USBFS_INT_FG_SUSPEND (1 << 2) #define USBFS_INT_FG_HST_SOF (1 << 3) #define USBFS_INT_FG_FIFO_OV (1 << 4) #define USBFS_INT_FG_SIE_FREE (1 << 5) #define USBFS_INT_FG_TOG_OK (1 << 6) #define USBFS_INT_FG_IS_NAK (1 << 7) // INT_ST #define USBFS_INT_ST_MASK_UIS_ENDP(x) (((x) >> 0) & 0x0F) #define USBFS_INT_ST_MASK_UIS_TOKEN(x) (((x) >> 4) & 0x03) // UDEV_CTRL #define USBFS_UDEV_CTRL_PORT_EN (1 << 0) #define USBFS_UDEV_CTRL_GP_BIT (1 << 1) #define USBFS_UDEV_CTRL_LOW_SPEED (1 << 2) #define USBFS_UDEV_CTRL_DM_PIN (1 << 4) #define USBFS_UDEV_CTRL_DP_PIN (1 << 5) #define USBFS_UDEV_CTRL_PD_DIS (1 << 7) // TX_CTRL #define USBFS_EP_T_RES_MASK (3 << 0) #define USBFS_EP_T_TOG (1 << 2) #define USBFS_EP_T_AUTO_TOG (1 << 3) #define USBFS_EP_T_RES_ACK (0 << 0) #define USBFS_EP_T_RES_NYET (1 << 0) #define USBFS_EP_T_RES_NAK (2 << 0) #define USBFS_EP_T_RES_STALL (3 << 0) // RX_CTRL #define USBFS_EP_R_RES_MASK (3 << 0) #define USBFS_EP_R_TOG (1 << 2) #define USBFS_EP_R_AUTO_TOG (1 << 3) #define USBFS_EP_R_RES_ACK (0 << 0) #define USBFS_EP_R_RES_NYET (1 << 0) #define USBFS_EP_R_RES_NAK (2 << 0) #define USBFS_EP_R_RES_STALL (3 << 0) // token PID #define PID_OUT 0 #define PID_SOF 1 #define PID_IN 2 #define PID_SETUP 3 #endif // USB_CH32_USBFS_REG_H ================================================ FILE: src/portable/wch/ch32_usbhs_reg.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Matthew Tran * Copyright (c) 2024 hathach * * 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. * * This file is part of the TinyUSB stack. */ #ifndef USB_CH32_USBHS_REG_H #define USB_CH32_USBHS_REG_H // https://github.com/openwch/ch32v307/pull/90 // https://github.com/openwch/ch32v20x/pull/12 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif #ifdef __GNUC__ #pragma GCC diagnostic pop #endif /******************* GLOBAL ******************/ // USB CONTROL #define USBHS_CONTROL_OFFSET 0x00 #define USBHS_DMA_EN (1 << 0) #define USBHS_ALL_CLR (1 << 1) #define USBHS_FORCE_RST (1 << 2) #define USBHS_INT_BUSY_EN (1 << 3) #define USBHS_DEV_PU_EN (1 << 4) #define USBHS_SPEED_MASK (3 << 5) #define USBHS_FULL_SPEED (0 << 5) #define USBHS_HIGH_SPEED (1 << 5) #define USBHS_LOW_SPEED (2 << 5) #define USBHS_HOST_MODE (1 << 7) // USB_INT_EN #define USBHS_INT_EN_OFFSET 0x02 #define USBHS_BUS_RST_EN (1 << 0) #define USBHS_DETECT_EN (1 << 0) #define USBHS_TRANSFER_EN (1 << 1) #define USBHS_SUSPEND_EN (1 << 2) #define USBHS_SOF_ACT_EN (1 << 3) #define USBHS_FIFO_OV_EN (1 << 4) #define USBHS_SETUP_ACT_EN (1 << 5) #define USBHS_ISO_ACT_EN (1 << 6) #define USBHS_DEV_NAK_EN (1 << 7) // USB DEV AD #define USBHS_DEV_AD_OFFSET 0x03 // USB FRAME_NO #define USBHS_FRAME_NO_OFFSET 0x04 #define USBHS_FRAME_NO_NUM_MASK (0x7FF) #define USBHS_FRAME_NO_MICROFRAME_SHIFT (11) #define USBHS_FRAME_NO_MICROFRAME_MASK (0x7 << USBHS_FRAME_NO_MICROFRAME_SHIFT) // USB SUSPEND #define USBHS_SUSPEND_OFFSET 0x06 #define USBHS_DEV_REMOTE_WAKEUP (1 << 2) #define USBHS_LINESTATE_MASK (2 << 4) /* Read Only */ // RESERVED0 // USB SPEED TYPE #define USBHS_SPEED_TYPE_OFFSET 0x08 #define USBHS_SPEED_TYPE_MASK 0x03 #define USBHS_SPEED_TYPE_FULL 0 #define USBHS_SPEED_TYPE_HIGH 1 #define USBHS_SPEED_TYPE_LOW 2 // USB_MIS_ST #define USBHS_MIS_ST_OFFSET 0x09 #define USBHS_SPLIT_CAN (1 << 0) #define USBHS_ATTACH (1 << 1) #define USBHS_SUSPEND (1 << 2) #define USBHS_BUS_RESET (1 << 3) #define USBHS_R_FIFO_RDY (1 << 4) #define USBHS_SIE_FREE (1 << 5) #define USBHS_SOF_ACT (1 << 6) #define USBHS_SOF_PRES (1 << 7) // INT_FLAG #define USBHS_INT_FLAG_OFFSET 0x0A #define USBHS_BUS_RST_FLAG (1 << 0) #define USBHS_DETECT_FLAG (1 << 0) #define USBHS_TRANSFER_FLAG (1 << 1) #define USBHS_SUSPEND_FLAG (1 << 2) #define USBHS_HST_SOF_FLAG (1 << 3) #define USBHS_FIFO_OV_FLAG (1 << 4) #define USBHS_SETUP_FLAG (1 << 5) #define USBHS_ISO_ACT_FLAG (1 << 6) // INT_ST #define USBHS_INT_ST_OFFSET 0x0B #define USBHS_DEV_UIS_IS_NAK (1 << 7) #define USBHS_DEV_UIS_TOG_OK (1 << 6) #define MASK_UIS_TOKEN (3 << 4) #define USBHS_TOKEN_PID_OUT (0 << 4) #define USBHS_TOKEN_PID_SOF (1 << 4) #define USBHS_TOKEN_PID_IN (2 << 4) #define USBHS_TOKEN_PID_SETUP (3 << 4) #define MASK_UIS_ENDP (0x0F) #define MASK_UIS_H_RES (0x0F) #define USBHS_TOGGLE_OK (0x40) #define USBHS_HOST_RES (0x0f) //USB_RX_LEN #define USBHS_RX_LEN_OFFSET 0x0C /******************* DEVICE ******************/ //UEP_CONFIG #define USBHS_UEP_CONFIG_OFFSET 0x10 #define USBHS_EP0_T_EN (1 << 0) #define USBHS_EP0_R_EN (1 << 16) #define USBHS_EP1_T_EN (1 << 1) #define USBHS_EP1_R_EN (1 << 17) #define USBHS_EP2_T_EN (1 << 2) #define USBHS_EP2_R_EN (1 << 18) #define USBHS_EP3_T_EN (1 << 3) #define USBHS_EP3_R_EN (1 << 19) #define USBHS_EP4_T_EN (1 << 4) #define USBHS_EP4_R_EN (1 << 20) #define USBHS_EP5_T_EN (1 << 5) #define USBHS_EP5_R_EN (1 << 21) #define USBHS_EP6_T_EN (1 << 6) #define USBHS_EP6_R_EN (1 << 22) #define USBHS_EP7_T_EN (1 << 7) #define USBHS_EP7_R_EN (1 << 23) #define USBHS_EP8_T_EN (1 << 8) #define USBHS_EP8_R_EN (1 << 24) #define USBHS_EP9_T_EN (1 << 9) #define USBHS_EP9_R_EN (1 << 25) #define USBHS_EP10_T_EN (1 << 10) #define USBHS_EP10_R_EN (1 << 26) #define USBHS_EP11_T_EN (1 << 11) #define USBHS_EP11_R_EN (1 << 27) #define USBHS_EP12_T_EN (1 << 12) #define USBHS_EP12_R_EN (1 << 28) #define USBHS_EP13_T_EN (1 << 13) #define USBHS_EP13_R_EN (1 << 29) #define USBHS_EP14_T_EN (1 << 14) #define USBHS_EP14_R_EN (1 << 30) #define USBHS_EP15_T_EN (1 << 15) #define USBHS_EP15_R_EN (1 << 31) //UEP_TYPE #define USBHS_UEP_TYPE_OFFSET 0x14 #define USBHS_EP0_T_TYP (1 << 0) #define USBHS_EP0_R_TYP (1 << 16) #define USBHS_EP1_T_TYP (1 << 1) #define USBHS_EP1_R_TYP (1 << 17) #define USBHS_EP2_T_TYP (1 << 2) #define USBHS_EP2_R_TYP (1 << 18) #define USBHS_EP3_T_TYP (1 << 3) #define USBHS_EP3_R_TYP (1 << 19) #define USBHS_EP4_T_TYP (1 << 4) #define USBHS_EP4_R_TYP (1 << 20) #define USBHS_EP5_T_TYP (1 << 5) #define USBHS_EP5_R_TYP (1 << 21) #define USBHS_EP6_T_TYP (1 << 6) #define USBHS_EP6_R_TYP (1 << 22) #define USBHS_EP7_T_TYP (1 << 7) #define USBHS_EP7_R_TYP (1 << 23) #define USBHS_EP8_T_TYP (1 << 8) #define USBHS_EP8_R_TYP (1 << 24) #define USBHS_EP9_T_TYP (1 << 8) #define USBHS_EP9_R_TYP (1 << 25) #define USBHS_EP10_T_TYP (1 << 10) #define USBHS_EP10_R_TYP (1 << 26) #define USBHS_EP11_T_TYP (1 << 11) #define USBHS_EP11_R_TYP (1 << 27) #define USBHS_EP12_T_TYP (1 << 12) #define USBHS_EP12_R_TYP (1 << 28) #define USBHS_EP13_T_TYP (1 << 13) #define USBHS_EP13_R_TYP (1 << 29) #define USBHS_EP14_T_TYP (1 << 14) #define USBHS_EP14_R_TYP (1 << 30) #define USBHS_EP15_T_TYP (1 << 15) #define USBHS_EP15_R_TYP (1 << 31) /* BUF_MOD UEP1~15 */ #define USBHS_BUF_MOD_OFFSET 0x18 #define USBHS_EP0_BUF_MOD (1 << 0) #define USBHS_EP0_ISO_BUF_MOD (1 << 16) #define USBHS_EP1_BUF_MOD (1 << 1) #define USBHS_EP1_ISO_BUF_MOD (1 << 17) #define USBHS_EP2_BUF_MOD (1 << 2) #define USBHS_EP2_ISO_BUF_MOD (1 << 18) #define USBHS_EP3_BUF_MOD (1 << 3) #define USBHS_EP3_ISO_BUF_MOD (1 << 19) #define USBHS_EP4_BUF_MOD (1 << 4) #define USBHS_EP4_ISO_BUF_MOD (1 << 20) #define USBHS_EP5_BUF_MOD (1 << 5) #define USBHS_EP5_ISO_BUF_MOD (1 << 21) #define USBHS_EP6_BUF_MOD (1 << 6) #define USBHS_EP6_ISO_BUF_MOD (1 << 22) #define USBHS_EP7_BUF_MOD (1 << 7) #define USBHS_EP7_ISO_BUF_MOD (1 << 23) #define USBHS_EP8_BUF_MOD (1 << 8) #define USBHS_EP8_ISO_BUF_MOD (1 << 24) #define USBHS_EP9_BUF_MOD (1 << 9) #define USBHS_EP9_ISO_BUF_MOD (1 << 25) #define USBHS_EP10_BUF_MOD (1 << 10) #define USBHS_EP10_ISO_BUF_MOD (1 << 26) #define USBHS_EP11_BUF_MOD (1 << 11) #define USBHS_EP11_ISO_BUF_MOD (1 << 27) #define USBHS_EP12_BUF_MOD (1 << 12) #define USBHS_EP12_ISO_BUF_MOD (1 << 28) #define USBHS_EP13_BUF_MOD (1 << 13) #define USBHS_EP13_ISO_BUF_MOD (1 << 29) #define USBHS_EP14_BUF_MOD (1 << 14) #define USBHS_EP14_ISO_BUF_MOD (1 << 30) #define USBHS_EP15_BUF_MOD (1 << 15) #define USBHS_EP15_ISO_BUF_MOD (1 << 31) //USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD Description: Arrange from low to high with UEPn_DMA as the starting address // 0 0 x The endpoint is disabled and the UEPn_*_DMA buffers are not used. // 1 0 0 The first address of the receive (OUT) buffer is UEPn_RX_DMA // 1 0 1 RB_UEPn_RX_TOG[0]=0, use buffer UEPn_RX_DMA RB_UEPn_RX_TOG[0]=1, use buffer UEPn_TX_DMA // 0 1 0 The first address of the transmit (IN) buffer is UEPn_TX_DMA. // 0 1 1 RB_UEPn_TX_TOG[0]=0, use buffer UEPn_TX_DMA RB_UEPn_TX_TOG[0]=1, use buffer UEPn_RX_DMA /* USB0_DMA */ #define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address /* USBX_RX_DMA */ #define USBHS_UEPx_RX_DMA_OFFSET(n) (0x1C + 4 * (n)) // endpoint x DMA buffer address #define USBHS_UEPx_TX_DMA_OFFSET(n) (0x58 + 4 * (n)) // endpoint x DMA buffer address #define USBHS_UEPx_MAX_LEN_OFFSET(n) (0x98 + 4 * (n)) // endpoint x DMA buffer address #define USBHS_UEPx_T_LEN_OFFSET(n) (0xD8 + 4 * (n)) // endpoint x DMA buffer address #define USBHS_UEPx_TX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 2) // endpoint x DMA buffer address #define USBHS_UEPx_RX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 3) // endpoint x DMA buffer address // UEPn_T_LEN #define USBHS_EP_T_LEN_MASK (0x7FF) //UEPn_TX_CTRL #define USBHS_EP_T_RES_MASK (3 << 0) #define USBHS_EP_T_RES_ACK (0 << 0) #define USBHS_EP_T_RES_NYET (1 << 0) #define USBHS_EP_T_RES_NAK (2 << 0) #define USBHS_EP_T_RES_STALL (3 << 0) #define USBHS_EP_T_TOG_MASK (3 << 3) #define USBHS_EP_T_TOG_0 (0 << 3) #define USBHS_EP_T_TOG_1 (1 << 3) #define USBHS_EP_T_TOG_2 (2 << 3) #define USBHS_EP_T_TOG_M (3 << 3) #define USBHS_EP_T_AUTOTOG (1 << 5) //UEPn_RX_CTRL #define USBHS_EP_R_RES_MASK (3 << 0) #define USBHS_EP_R_RES_ACK (0 << 0) #define USBHS_EP_R_RES_NYET (1 << 0) #define USBHS_EP_R_RES_NAK (2 << 0) #define USBHS_EP_R_RES_STALL (3 << 0) #define USBHS_EP_R_TOG_MASK (3 << 3) #define USBHS_EP_R_TOG_0 (0 << 3) #define USBHS_EP_R_TOG_1 (1 << 3) #define USBHS_EP_R_TOG_2 (2 << 3) #define USBHS_EP_R_TOG_M (3 << 3) #define USBHS_EP_R_AUTOTOG (1 << 5) #define USBHS_TOG_MATCH (1 << 6) /******************* HOST ******************/ // USB HOST_CTRL #define USBHS_SEND_BUS_RESET (1 << 0) #define USBHS_SEND_BUS_SUSPEND (1 << 1) #define USBHS_SEND_BUS_RESUME (1 << 2) #define USBHS_REMOTE_WAKE (1 << 3) #define USBHS_PHY_SUSPENDM (1 << 4) #define USBHS_UH_SOFT_FREE (1 << 6) #define USBHS_SEND_SOF_EN (1 << 7) //UH_CONFIG #define USBHS_HOST_TX_EN (1 << 3) #define USBHS_HOST_RX_EN (1 << 18) // HOST_EP_TYPE #define USBHS_ENDP_TX_ISO (1 << 3) #define USBHS_ENDP_RX_ISO (1 << (16 + 2)) // R32_UH_EP_PID #define USBHS_HOST_MASK_TOKEN (0x0f) #define USBHS_HOST_MASK_ENDP (0x0f << 4) //R8_UH_RX_CTRL #define USBHS_EP_R_RES_MASK (3 << 0) #define USBHS_EP_R_RES_ACK (0 << 0) #define USBHS_EP_R_RES_NYET (1 << 0) #define USBHS_EP_R_RES_NAK (2 << 0) #define USBHS_EP_R_RES_STALL (3 << 0) #define USBHS_UH_R_RES_NO (1 << 2) #define USBHS_UH_R_TOG_1 (1 << 3) #define USBHS_UH_R_TOG_2 (2 << 3) #define USBHS_UH_R_TOG_3 (3 << 3) #define USBHS_UH_R_TOG_AUTO (1 << 5) #define USBHS_UH_R_DATA_NO (1 << 6) //R8_UH_TX_CTRL #define USBHS_UH_T_RES_MASK (3 << 0) #define USBHS_UH_T_RES_ACK (0 << 0) #define USBHS_UH_T_RES_NYET (1 << 0) #define USBHS_UH_T_RES_NAK (2 << 0) #define USBHS_UH_T_RES_STALL (3 << 0) #define USBHS_UH_T_RES_NO (1 << 2) #define USBHS_UH_T_TOG_1 (1 << 3) #define USBHS_UH_T_TOG_2 (2 << 3) #define USBHS_UH_T_TOG_3 (3 << 3) #define USBHS_UH_T_TOG_AUTO (1 << 5) #define USBHS_UH_T_DATA_NO (1 << 6) #endif ================================================ FILE: src/portable/wch/dcd_ch32_usbfs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Matthew Tran * Copyright (c) 2024 hathach * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && CFG_TUD_WCH_USBIP_USBFS #include "device/dcd.h" #include "ch32_usbfs_reg.h" /* private defines */ #define EP_MAX (8) #define EP_DMA(ep) ((&USBOTG_FS->UEP0_DMA)[ep]) #define EP_TX_LEN(ep) ((&USBOTG_FS->UEP0_TX_LEN)[2 * ep]) #define EP_TX_CTRL(ep) ((&USBOTG_FS->UEP0_TX_CTRL)[4 * ep]) #define EP_RX_CTRL(ep) ((&USBOTG_FS->UEP0_RX_CTRL)[4 * ep]) /* private data */ struct usb_xfer { bool valid; uint8_t* buffer; size_t len; size_t processed_len; size_t max_size; }; static struct { bool ep0_tog; bool isochronous[EP_MAX]; struct usb_xfer xfer[EP_MAX][2]; TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; TU_ATTR_ALIGNED(4) struct { // OUT transfers >64 bytes will overwrite queued IN data! uint8_t out[64]; uint8_t in[1023]; uint8_t pad; } ep3_buffer; } data; /* private helpers */ static void update_in(uint8_t rhport, uint8_t ep, bool force) { struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_IN]; if (xfer->valid) { if (force || xfer->len) { size_t len = TU_MIN(xfer->max_size, xfer->len); if (ep == 0) { memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk } else if (ep == 3) { memcpy(data.ep3_buffer.in, xfer->buffer, len); } else { memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); } xfer->buffer += len; xfer->len -= len; xfer->processed_len += len; EP_TX_LEN(ep) = len; if (ep == 0) { EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); data.ep0_tog = !data.ep0_tog; } else if (data.isochronous[ep]) { EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; } else { EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; } } else { xfer->valid = false; EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; dcd_event_xfer_complete( rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, XFER_RESULT_SUCCESS, true); } } } static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_OUT]; if (xfer->valid) { size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); if (ep == 3) { memcpy(xfer->buffer, data.ep3_buffer.out, len); } else { memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); } xfer->buffer += len; xfer->len -= len; xfer->processed_len += len; if (xfer->len == 0 || len < xfer->max_size) { xfer->valid = false; dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); } if (ep == 0) { EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } } } /* public functions */ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; // init registers USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; USBOTG_FS->DEV_ADDR = 0x00; USBOTG_FS->INT_FG = 0xFF; USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; // setup endpoint 0 EP_DMA(0) = (uint32_t) &data.buffer[0][0]; EP_TX_LEN(0) = 0; EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; // enable other endpoints but NAK everything USBOTG_FS->UEP4_1_MOD = 0xCC; USBOTG_FS->UEP2_3_MOD = 0xCC; USBOTG_FS->UEP5_6_MOD = 0xCC; USBOTG_FS->UEP7_MOD = 0x0C; for (uint8_t ep = 1; ep < EP_MAX; ep++) { EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; } EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; dcd_connect(rhport); return true; } void dcd_int_handler(uint8_t rhport) { (void) rhport; uint8_t status = USBOTG_FS->INT_FG; if (status & USBFS_INT_FG_TRANSFER) { uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); switch (token) { case PID_OUT: { uint16_t rx_len = USBOTG_FS->RX_LEN; update_out(rhport, ep, rx_len); break; } case PID_IN: update_in(rhport, ep, false); break; case PID_SETUP: // setup clears stall EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; data.ep0_tog = true; dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); break; } USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; } else if (status & USBFS_INT_FG_BUS_RST) { data.ep0_tog = true; data.xfer[0][TUSB_DIR_OUT].max_size = 64; data.xfer[0][TUSB_DIR_IN].max_size = 64; //dcd_event_bus_reset(rhport, (USBOTG_FS->BASE_CTRL & USBFS_CTRL_LOW_SPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL, true); dcd_event_bus_reset(rhport, (USBOTG_FS->UDEV_CTRL & USBFS_UDEV_CTRL_LOW_SPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL, true); USBOTG_FS->DEV_ADDR = 0x00; EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; } else if (status & USBFS_INT_FG_SUSPEND) { dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; dcd_event_handler(&event, true); USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; } } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBHD_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBHD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) dev_addr; dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); // zlp status response } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; // TODO optional } void dcd_connect(uint8_t rhport) { (void) rhport; USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; } void dcd_disconnect(uint8_t rhport) { (void) rhport; USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; } EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { (void) rhport; uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); TU_ASSERT(ep < EP_MAX); data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); if (ep != 0) { if (dir == TUSB_DIR_OUT) { if (data.isochronous[ep]) { EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; } else { EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; } } else { EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; } } return true; } void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; // TODO optional } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void)largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; return false; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t ep = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); struct usb_xfer* xfer = &data.xfer[ep][dir]; dcd_int_disable(rhport); xfer->valid = true; xfer->buffer = buffer; xfer->len = total_bytes; xfer->processed_len = 0; dcd_int_enable(rhport); if (dir == TUSB_DIR_IN) { update_in(rhport, ep, true); } return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t ep = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); if (ep == 0) { if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; } else { EP_TX_LEN(0) = 0; EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; } } else { if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; } else { EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; } } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t ep = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); if (ep == 0) { if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } } else { if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; } else { EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; } } } #endif ================================================ FILE: src/portable/wch/dcd_ch32_usbhs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill * Copyright (c) 2023 Denis Krasutski * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && defined(CFG_TUD_WCH_USBIP_USBHS) && \ (CFG_TUD_WCH_USBIP_USBHS == 1) #include "ch32_usbhs_reg.h" #include "device/dcd.h" // Max number of bi-directional endpoints including EP0 #define EP_MAX 16 typedef struct { uint8_t* buffer; uint16_t total_len; uint16_t queued_len; uint16_t max_size; bool is_last_packet; bool is_iso; } xfer_ctl_t; typedef enum { EP_RESPONSE_ACK, EP_RESPONSE_NAK, } ep_response_list_t; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] static xfer_ctl_t xfer_status[EP_MAX][2]; #define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep) * 2) #define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep) * 4) #define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep) * 4) #define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep) * 2) #define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE]; static void ep_set_response_and_toggle(uint8_t ep_num, tusb_dir_t ep_dir, ep_response_list_t response_type) { if (ep_dir == TUSB_DIR_IN) { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; if (ep_num == 0) { if (response_type == EP_RESPONSE_ACK) { if (EP_TX_LEN(ep_num) == 0) { EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; } else { EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; } } } if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; } else { EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; } } else { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; if (ep_num == 0) { if (response_type == EP_RESPONSE_ACK) { if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; } } else { EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; } } EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; } } static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer) { if (ep_dir == TUSB_DIR_IN) { uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); if (ep_num == 0) { memcpy(ep0_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); } else { EP_TX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; } EP_TX_LEN(ep_num) = next_tx_size; xfer->queued_len += next_tx_size; if (xfer->queued_len == xfer->total_len) { xfer->is_last_packet = true; } if (xfer->is_iso == true) { /* Enable EP to generate ISA_ACT interrupt */ USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } } else { /* TUSB_DIR_OUT */ uint16_t left_to_receive = xfer->total_len - xfer->queued_len; uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); if (max_possible_rx_size == left_to_receive) { xfer->is_last_packet = true; } if (ep_num > 0) { EP_RX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; } } ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; memset(&xfer_status, 0, sizeof(xfer_status)); USBHSD->HOST_CTRL = 0x00; USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; USBHSD->CONTROL = 0; #if TUD_OPT_HIGH_SPEED USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else #error OPT_MODE_FULL_SPEED not currently supported on CH32 USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; #endif USBHSD->INT_EN = 0; USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_BUS_RST_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; USBHSD->BUF_MODE = 0x00; for (int ep = 0; ep < EP_MAX; ep++) { EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; EP_RX_MAX_LEN(ep) = 0; } USBHSD->UEP0_DMA = (uint32_t) ep0_buffer; USBHSD->UEP0_MAX_LEN = CFG_TUD_ENDPOINT0_SIZE; xfer_status[0][TUSB_DIR_OUT].max_size = CFG_TUD_ENDPOINT0_SIZE; xfer_status[0][TUSB_DIR_IN].max_size = CFG_TUD_ENDPOINT0_SIZE; USBHSD->DEV_AD = 0; USBHSD->CONTROL |= USBHS_DEV_PU_EN; return true; } void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBHS_IRQn); } void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBHS_IRQn); } void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; for (size_t ep = 1; ep < EP_MAX; ep++) { EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; EP_RX_MAX_LEN(ep) = 0; } USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) dev_addr; // Response with zlp status dcd_edpt_xfer(rhport, 0x80, NULL, 0, false); } void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; } void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; if (en) { USBHSD->INT_EN |= USBHS_SOF_ACT_EN; } else { USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); } } void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { USBHSD->DEV_AD = (uint8_t) request->wValue; } EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); TU_ASSERT(ep_num < EP_MAX); if (ep_num == 0) { return true; } xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); if (dir == TUSB_DIR_OUT) { USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); } EP_RX_MAX_LEN(ep_num) = xfer->max_size; } else { if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); } else { /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } EP_TX_LEN(ep_num) = 0; EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; } return true; } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; EP_RX_MAX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); } else { // TUSB_DIR_IN EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; EP_TX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); } } #if 0 bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; (void) largest_packet_size; return false; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { (void) rhport; (void) desc_ep; return false; } #endif void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; } else { EP_TX_LEN(0) = 0; EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_OUT) { EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; } else { EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; } } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) { (void) is_isr; (void) rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); xfer->buffer = buffer; xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->is_last_packet = false; xfer_data_packet(ep_num, dir, xfer); return true; } void dcd_int_handler(uint8_t rhport) { (void) rhport; uint8_t int_flag = USBHSD->INT_FG; uint8_t int_status = USBHSD->INT_ST; if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) { uint8_t const token = int_status & MASK_UIS_TOKEN; if (token == USBHS_TOKEN_PID_SOF) { uint32_t frame_count = USBHSD->FRAME_NO & USBHS_FRAME_NO_NUM_MASK; dcd_event_sof(rhport, frame_count, true); }else { uint8_t const ep_num = int_status & MASK_UIS_ENDP; tusb_dir_t const ep_dir = (token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); if (token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; if (ep_num == 0) { memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); } xfer->queued_len += rx_len; if (rx_len < xfer->max_size) { xfer->is_last_packet = true; } } else if (token == USBHS_TOKEN_PID_IN) { if (xfer->is_iso && xfer->is_last_packet) { /* Disable EP to avoid ISO_ACT interrupt generation */ USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); } else { // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet } } if (xfer->is_last_packet == true) { ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { /* prepare next part of packet to xref */ xfer_data_packet(ep_num, ep_dir, xfer); } } USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)); /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { ep_set_response_and_toggle(0, TUSB_DIR_IN, EP_RESPONSE_NAK); ep_set_response_and_toggle(0, TUSB_DIR_OUT, EP_RESPONSE_NAK); dcd_event_setup_received(0, ep0_buffer, true); USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ } else if (int_flag & USBHS_BUS_RST_FLAG) { // TODO CH32 does not detect actual speed at this time (should be known at end of reset) // This interrupt probably triggered at start of bus reset // tusb_speed_t actual_speed; // switch(USBHSD->SPEED_TYPE & USBHS_SPEED_TYPE_MASK){ // case USBHS_SPEED_TYPE_HIGH: // actual_speed = TUSB_SPEED_HIGH; // break; // case USBHS_SPEED_TYPE_FULL: // actual_speed = TUSB_SPEED_FULL; // break; // case USBHS_SPEED_TYPE_LOW: // actual_speed = TUSB_SPEED_LOW; // break; // default: // TU_ASSERT(0,); // break; // } // dcd_event_bus_reset(0, actual_speed, true); dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); USBHSD->DEV_AD = 0; EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; USBHSD->INT_FG = USBHS_BUS_RST_FLAG; /* Clear flag */ } else if (int_flag & USBHS_SUSPEND_FLAG) { dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; dcd_event_handler(&event, true); USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ } } #endif ================================================ FILE: src/portable/wch/hcd_ch32_usbfs.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2024 Mitsumine Suzu (verylowfreq) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED && defined(TUP_USBIP_WCH_USBFS) && defined(CFG_TUH_WCH_USBIP_USBFS) && CFG_TUH_WCH_USBIP_USBFS #include #include "host/hcd.h" #include "host/usbh.h" #include "host/usbh_pvt.h" #include "bsp/board_api.h" #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif #include "ch32v20x.h" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "ch32v20x_usb.h" #define USBFS_RX_BUF_LEN 64 #define USBFS_TX_BUF_LEN 64 TU_ATTR_ALIGNED(4) static uint8_t USBFS_RX_Buf[USBFS_RX_BUF_LEN]; TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN]; #define USB_XFER_TIMEOUT_MILLIS 100 // #define USB_INTERRUPT_XFER_TIMEOUT_MILLIS 1 #define PANIC(...) \ do { \ printf("%s() L%d: ", __func__, __LINE__); \ printf("\r\n[PANIC] " __VA_ARGS__); \ while (true) {} \ } while (false) #define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__) // Busywait for delay microseconds/nanoseconds TU_ATTR_ALWAYS_INLINE static inline void loopdelay(uint32_t count) { volatile uint32_t c = count / 3; if (c == 0) { return; } // while (c-- != 0); asm volatile( "1: \n" // loop label " addi %0, %0, -1 \n" // c-- " bne %0, zero, 1b \n" // if (c != 0) goto loop : "+r"(c) // c is input/output operand ); } // Endpoint status typedef struct usb_edpt { // Is this a valid struct bool configured; uint8_t dev_addr; uint8_t ep_addr; uint8_t max_packet_size; uint8_t xfer_type; // Data toggle (0 or not 0) for DATA0/1 uint8_t data_toggle; bool is_nak_pending; uint16_t buflen; uint8_t* buf; } usb_edpt_t; static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {}; typedef struct usb_current_xfer_st { bool is_busy; uint8_t dev_addr; uint8_t ep_addr; // Xfer started time in millis for timeout uint32_t start_ms; uint8_t *buffer; uint16_t bufferlen; uint16_t xferred_len; bool nak_pending; } usb_current_xfer_t; static volatile usb_current_xfer_t usb_current_xfer_info = {}; static usb_edpt_t *get_edpt_record(uint8_t dev_addr, uint8_t ep_addr) { for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) { usb_edpt_t *cur = &usb_edpt_list[i]; if (cur->configured && cur->dev_addr == dev_addr && cur->ep_addr == ep_addr) { return cur; } } return NULL; } static usb_edpt_t *get_empty_record_slot(void) { for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) { if (!usb_edpt_list[i].configured) { return &usb_edpt_list[i]; } } return NULL; } static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) { usb_edpt_t *slot = get_empty_record_slot(); TU_ASSERT(slot != NULL, NULL); slot->dev_addr = dev_addr; slot->ep_addr = ep_addr; slot->max_packet_size = max_packet_size; slot->xfer_type = xfer_type; slot->data_toggle = 0; slot->is_nak_pending = false; slot->buflen = 0; slot->buf = NULL; slot->configured = true; return slot; } static usb_edpt_t *get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) { usb_edpt_t *ret = get_edpt_record(dev_addr, ep_addr); if (ret != NULL) { return ret; } else { return add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type); } } static void remove_edpt_record_for_device(uint8_t dev_addr) { for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) { if (usb_edpt_list[i].configured && usb_edpt_list[i].dev_addr == dev_addr) { usb_edpt_list[i].configured = false; } } } // static void dump_edpt_record_list() { // for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) { // usb_edpt_t* cur = &usb_edpt_list[i]; // if (cur->configured) { // printf("[%2d] Device 0x%02x Endpoint 0x%02x\r\n", i, cur->dev_addr, cur->ep_addr); // } else { // printf("[%2d] not configured\r\n", i); // } // } // } static bool interrupt_enabled = false; /** Enable or disable USBFS Host function */ static void hardware_init_host(bool enabled) { // Reset USBOTG module USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; tusb_time_delay_ms_api(1); USBOTG_H_FS->BASE_CTRL = 0; if (!enabled) { // Disable all feature USBOTG_H_FS->BASE_CTRL = 0; } else { // Enable USB Host features // NVIC_DisableIRQ(USBFS_IRQn); hcd_int_disable(0); USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN; USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN; USBOTG_H_FS->HOST_RX_DMA = (uint32_t) USBFS_RX_Buf; USBOTG_H_FS->HOST_TX_DMA = (uint32_t) USBFS_TX_Buf; // USBOTG_H_FS->INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT; USBOTG_H_FS->INT_EN = USBFS_UIE_DETECT; } } static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggle) { LOG_CH32_USBFSH("hardware_start_xfer(pid=%s(0x%02x), ep_addr=0x%02x, toggle=%d)\r\n", pid == USB_PID_IN ? "IN" : pid == USB_PID_OUT ? "OUT" : pid == USB_PID_SETUP ? "SETUP" : "(other)", pid, ep_addr, data_toggle); //WORKAROUND: For LowSpeed device, insert small delay bool is_lowspeed_device = tuh_speed_get(usb_current_xfer_info.dev_addr) == TUSB_SPEED_LOW; if (is_lowspeed_device) { //NOTE: worked -> SystemCoreClock / 1000000 * 50, 25 // NOT worked -> 20 and less (at 144MHz internal clock) loopdelay(SystemCoreClock / 1000000 * 40); } uint8_t pid_edpt = (pid << 4) | (tu_edpt_number(ep_addr) & 0x0f); USBOTG_H_FS->HOST_TX_CTRL = (data_toggle != 0) ? USBFS_UH_T_TOG : 0; USBOTG_H_FS->HOST_RX_CTRL = (data_toggle != 0) ? USBFS_UH_R_TOG : 0; USBOTG_H_FS->HOST_EP_PID = pid_edpt; USBOTG_H_FS->INT_EN |= USBFS_UIE_TRANSFER; USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; return true; } /** Set device address to communicate */ static void hardware_update_device_address(uint8_t dev_addr) { // Keep the bit of GP_BIT. Other 7bits are actual device address. USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK); } /** Set port speed */ static void hardware_update_port_speed(tusb_speed_t speed) { LOG_CH32_USBFSH("hardware_update_port_speed(%s)\r\n", speed == TUSB_SPEED_FULL ? "Full" : speed == TUSB_SPEED_LOW ? "Low" : "(invalid)"); switch (speed) { case TUSB_SPEED_LOW: USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED; USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED; USBOTG_H_FS->HOST_SETUP |= USBFS_UH_PRE_PID_EN; return; case TUSB_SPEED_FULL: USBOTG_H_FS->BASE_CTRL &= ~USBFS_UC_LOW_SPEED; USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED; USBOTG_H_FS->HOST_SETUP &= ~USBFS_UH_PRE_PID_EN; return; default: PANIC("hardware_update_port_speed(%d)\r\n", speed); } } static void hardware_set_port_address_speed(uint8_t dev_addr) { hardware_update_device_address(dev_addr); tusb_speed_t rhport_speed = hcd_port_speed_get(0); tusb_speed_t dev_speed = tuh_speed_get(dev_addr); hardware_update_port_speed(dev_speed); if (rhport_speed == TUSB_SPEED_FULL && dev_speed == TUSB_SPEED_LOW) { USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED; } } static bool hardware_device_attached(void) { return USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH; } //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { (void) rhport; (void) rh_init; hardware_init_host(true); return true; } bool hcd_deinit(uint8_t rhport) { (void) rhport; hardware_init_host(false); return true; } static bool int_state_for_portreset = false; void hcd_port_reset(uint8_t rhport) { (void) rhport; LOG_CH32_USBFSH("hcd_port_reset()\r\n"); int_state_for_portreset = interrupt_enabled; // NVIC_DisableIRQ(USBFS_IRQn); hcd_int_disable(rhport); hardware_update_device_address(0x00); // USBOTG_H_FS->HOST_SETUP = 0x00; USBOTG_H_FS->HOST_CTRL |= USBFS_UH_BUS_RESET; return; } void hcd_port_reset_end(uint8_t rhport) { (void) rhport; LOG_CH32_USBFSH("hcd_port_reset_end()\r\n"); USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET; tusb_time_delay_ms_api(2); if ((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0) { if (hcd_port_speed_get(0) == TUSB_SPEED_LOW) { hardware_update_port_speed(TUSB_SPEED_LOW); } } USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN; USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN; // Suppress the attached event USBOTG_H_FS->INT_FG |= USBFS_UIF_DETECT; if (int_state_for_portreset) { hcd_int_enable(rhport); } } bool hcd_port_connect_status(uint8_t rhport) { (void) rhport; return hardware_device_attached(); } tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void) rhport; if (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL) { return TUSB_SPEED_LOW; } else { return TUSB_SPEED_FULL; } } // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { (void) rhport; LOG_CH32_USBFSH("hcd_device_close(%d, 0x%02x)\r\n", rhport, dev_addr); remove_edpt_record_for_device(dev_addr); } uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; return tusb_time_millis_api(); } void hcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBFS_IRQn); interrupt_enabled = true; } void hcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBFS_IRQn); interrupt_enabled = false; } static void xfer_retry(void* _params) { LOG_CH32_USBFSH("xfer_retry()\r\n"); usb_edpt_t* edpt_info = (usb_edpt_t*)_params; if (usb_current_xfer_info.nak_pending) { usb_current_xfer_info.nak_pending = false; edpt_info->is_nak_pending = false; uint8_t dev_addr = edpt_info->dev_addr; uint8_t ep_addr = edpt_info->ep_addr; uint16_t buflen = edpt_info->buflen; uint8_t* buf = edpt_info->buf; // Check connectivity usb_edpt_t* edpt_info_current = get_edpt_record(dev_addr, ep_addr); if (edpt_info_current) { hcd_edpt_xfer(0, dev_addr, ep_addr, buf, buflen); } } } void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; (void) in_isr; if (USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT) { // Clear the flag USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT; // Read the detection state bool attached = hardware_device_attached(); LOG_CH32_USBFSH("hcd_int_handler() attached = %d\r\n", attached ? 1 : 0); if (attached) { hcd_event_device_attach(rhport, true); } else { hcd_event_device_remove(rhport, true); } return; } if (USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) { // Disable transfer interrupt USBOTG_H_FS->INT_EN &= ~USBFS_UIE_TRANSFER; // Clear the flag // USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; // Copy PID and Endpoint uint8_t pid_edpt = USBOTG_H_FS->HOST_EP_PID; uint8_t status = USBOTG_H_FS->INT_ST; uint8_t dev_addr = USBOTG_H_FS->DEV_ADDR & USBFS_USB_ADDR_MASK; // Clear register to stop transfer // USBOTG_H_FS->HOST_EP_PID = 0x00; LOG_CH32_USBFSH("hcd_int_handler() pid_edpt=0x%02x\r\n", pid_edpt); uint8_t request_pid = pid_edpt >> 4; uint8_t response_pid = status & USBFS_UIS_H_RES_MASK; uint8_t ep_addr = pid_edpt & 0x0f; if (request_pid == USB_PID_IN) { ep_addr |= 0x80; } usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr); if (edpt_info == NULL) { PANIC("\r\nget_edpt_record(0x%02x, 0x%02x) returned NULL in USBHD_IRQHandler\r\n", dev_addr, ep_addr); } if (status & USBFS_UIS_TOG_OK) { edpt_info->data_toggle ^= 0x01; switch (request_pid) { case USB_PID_SETUP: case USB_PID_OUT: { uint16_t tx_len = USBOTG_H_FS->HOST_TX_LEN; usb_current_xfer_info.bufferlen -= tx_len; usb_current_xfer_info.xferred_len += tx_len; if (usb_current_xfer_info.bufferlen == 0) { LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n"); usb_current_xfer_info.buffer += tx_len; uint16_t copylen = TU_MIN(edpt_info->max_packet_size, usb_current_xfer_info.bufferlen); memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen); hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); return; } } case USB_PID_IN: { uint16_t received_len = USBOTG_H_FS->RX_LEN; usb_current_xfer_info.xferred_len += received_len; uint16_t xferred_len = usb_current_xfer_info.xferred_len; LOG_CH32_USBFSH("Read %d bytes\r\n", received_len); // if (received_len > 0 && (usb_current_xfer_info.buffer == NULL || usb_current_xfer_info.bufferlen == 0)) { // PANIC("Data received but buffer not set\r\n"); // } memcpy(usb_current_xfer_info.buffer, USBFS_RX_Buf, received_len); usb_current_xfer_info.buffer += received_len; if ((received_len < edpt_info->max_packet_size) || (xferred_len == usb_current_xfer_info.bufferlen)) { // USB device sent all data. LOG_CH32_USBFSH("USB_PID_IN completed\r\n"); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { // USB device may send more data. LOG_CH32_USBFSH("Read more data\r\n"); hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle); return; } } default: { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } } else { if (response_pid == USB_PID_STALL) { LOG_CH32_USBFSH("STALL response\r\n"); hcd_edpt_clear_stall(0, dev_addr, ep_addr); edpt_info->data_toggle = 0; hardware_start_xfer(request_pid, ep_addr, 0); return; } else if (response_pid == USB_PID_NAK) { LOG_CH32_USBFSH("NAK reposense\r\n"); uint32_t elapsed_time = tusb_time_millis_api() - usb_current_xfer_info.start_ms; (void)elapsed_time; if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) { usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, in_isr); } else { usb_current_xfer_info.is_busy = false; usb_current_xfer_info.nak_pending = true; edpt_info->is_nak_pending = true; edpt_info->buflen = usb_current_xfer_info.bufferlen; edpt_info->buf = usb_current_xfer_info.buffer; hcd_event_t event = { .rhport = rhport, .dev_addr = dev_addr, .event_id = USBH_EVENT_FUNC_CALL, .func_call = { .func = xfer_retry, .param = edpt_info } }; hcd_event_handler(&event, in_isr); } return; } else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1) { LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } else { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } } } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) { (void) rhport; uint8_t ep_addr = ep_desc->bEndpointAddress; uint8_t ep_num = tu_edpt_number(ep_addr); uint16_t max_packet_size = ep_desc->wMaxPacketSize; uint8_t xfer_type = ep_desc->bmAttributes.xfer; LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type); while (usb_current_xfer_info.is_busy) { } if (ep_num == 0x00) { TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false); TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false); } else { TU_ASSERT(get_or_add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type) != NULL, false); } USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN; USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN; hardware_set_port_address_speed(dev_addr); return true; } bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) { (void) rhport; LOG_CH32_USBFSH("hcd_edpt_xfer(%d, 0x%02x, 0x%02x, ...)\r\n", rhport, dev_addr, ep_addr); while (usb_current_xfer_info.is_busy) {} usb_current_xfer_info.is_busy = true; usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr); TU_ASSERT(edpt_info != NULL); hardware_set_port_address_speed(dev_addr); usb_current_xfer_info.dev_addr = dev_addr; usb_current_xfer_info.ep_addr = ep_addr; usb_current_xfer_info.buffer = buffer; usb_current_xfer_info.bufferlen = buflen; usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.xferred_len = 0; usb_current_xfer_info.nak_pending = false; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle); } else { LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); uint16_t copylen = TU_MIN(edpt_info->max_packet_size, buflen); USBOTG_H_FS->HOST_TX_LEN = copylen; memcpy(USBFS_TX_Buf, buffer, copylen); return hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); } } bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; (void) ep_addr; return false; } bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { (void) rhport; while (usb_current_xfer_info.is_busy) {} usb_current_xfer_info.is_busy = true; LOG_CH32_USBFSH("hcd_setup_send(rhport=%d, dev_addr=0x%02x, %p)\r\n", rhport, dev_addr, setup_packet); hardware_set_port_address_speed(dev_addr); usb_edpt_t *edpt_info_tx = get_edpt_record(dev_addr, 0x00); usb_edpt_t *edpt_info_rx = get_edpt_record(dev_addr, 0x80); TU_ASSERT(edpt_info_tx != NULL, false); TU_ASSERT(edpt_info_rx != NULL, false); // Initialize data toggle (SETUP always starts with DATA0) // Data toggle for OUT is toggled in hcd_int_handler() edpt_info_tx->data_toggle = 0; // Data toggle for IN must be set 0x01 manually. edpt_info_rx->data_toggle = 0x01; const uint16_t setup_packet_datalen = 8; memcpy(USBFS_TX_Buf, setup_packet, setup_packet_datalen); USBOTG_H_FS->HOST_TX_LEN = setup_packet_datalen; uint8_t ep_addr = (setup_packet[0] & 0x80) ? 0x80 : 0x00; usb_current_xfer_info.dev_addr = dev_addr; usb_current_xfer_info.ep_addr = ep_addr; usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.buffer = USBFS_TX_Buf; usb_current_xfer_info.bufferlen = setup_packet_datalen; usb_current_xfer_info.xferred_len = 0; usb_current_xfer_info.nak_pending = false; hardware_start_xfer(USB_PID_SETUP, 0, 0); return true; } bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr); uint8_t edpt_num = tu_edpt_number(ep_addr); uint8_t setup_request_clear_stall[8] = { 0x02, 0x01, 0x00, 0x00, edpt_num, 0x00, 0x00, 0x00 }; memcpy(USBFS_TX_Buf, setup_request_clear_stall, 8); USBOTG_H_FS->HOST_TX_LEN = 8; bool prev_int_state = interrupt_enabled; hcd_int_disable(0); USBOTG_H_FS->HOST_EP_PID = (USB_PID_SETUP << 4) | 0x00; USBOTG_H_FS->INT_FG |= USBFS_UIF_TRANSFER; while ((USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) == 0) {} USBOTG_H_FS->HOST_EP_PID = 0; uint8_t response_pid = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK; (void) response_pid; LOG_CH32_USBFSH("hcd_edpt_clear_stall() response pid=0x%02x\r\n", response_pid); if (prev_int_state) { hcd_int_enable(0); } return true; } #endif ================================================ FILE: src/tinyusb.mk ================================================ # C source files TINYUSB_SRC_C += \ src/tusb.c \ src/common/tusb_fifo.c \ src/device/usbd.c \ src/device/usbd_control.c \ src/typec/usbc.c \ src/class/audio/audio_device.c \ src/class/cdc/cdc_device.c \ src/class/dfu/dfu_device.c \ src/class/dfu/dfu_rt_device.c \ src/class/hid/hid_device.c \ src/class/midi/midi_device.c \ src/class/msc/msc_device.c \ src/class/mtp/mtp_device.c \ src/class/net/ecm_rndis_device.c \ src/class/net/ncm_device.c \ src/class/printer/printer_device.c \ src/class/usbtmc/usbtmc_device.c \ src/class/video/video_device.c \ src/class/vendor/vendor_device.c \ src/host/usbh.c \ src/host/hub.c \ src/class/cdc/cdc_host.c \ src/class/hid/hid_host.c \ src/class/midi/midi_host.c \ src/class/msc/msc_host.c \ src/class/vendor/vendor_host.c \ src/typec/usbc.c \ ================================================ FILE: src/tusb.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUH_ENABLED || CFG_TUD_ENABLED #include "tusb.h" #include "common/tusb_private.h" #if CFG_TUD_ENABLED #include "device/usbd_pvt.h" #endif #if CFG_TUH_ENABLED #include "host/usbh_pvt.h" #endif // Suppress IAR warning // Warning[Pe111]: statement is unreachable #if defined(__ICCARM__) #pragma diag_suppress = Pe111 #endif tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID }; //-------------------------------------------------------------------- // Weak/Default API, can be overwritten by Application //-------------------------------------------------------------------- #if CFG_TUSB_OS != OPT_OS_NONE TU_ATTR_WEAK uint32_t tusb_time_millis_api(void) { return osal_time_millis(); } TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { osal_task_delay(ms); } #else // tusb_time_millis_api() must be implemented by user application. TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { // delay using millis() const uint32_t time_ms = tusb_time_millis_api(); while ((tusb_time_millis_api() - time_ms) < ms) {} } #endif TU_ATTR_WEAK void *tusb_app_virt_to_phys(void *virt_addr) { return virt_addr; } TU_ATTR_WEAK void* tusb_app_phys_to_virt(void *phys_addr) { return phys_addr; } //--------------------------------------------------------------------+ // Public API //--------------------------------------------------------------------+ bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // backward compatible called with tusb_init(void) #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) if (rh_init == NULL) { #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) // init device stack CFG_TUSB_RHPORTx_MODE must be defined const tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; TU_ASSERT ( tud_rhport_init(TUD_OPT_RHPORT, &dev_init) ); _tusb_rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_DEVICE; #endif #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) // init host stack CFG_TUSB_RHPORTx_MODE must be defined const tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; TU_ASSERT( tuh_rhport_init(TUH_OPT_RHPORT, &host_init) ); _tusb_rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_HOST; #endif return true; } #endif // new API with explicit rhport and role TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM && rh_init->role != TUSB_ROLE_INVALID); _tusb_rhport_role[rhport] = rh_init->role; #if CFG_TUD_ENABLED if (rh_init->role == TUSB_ROLE_DEVICE) { TU_ASSERT(tud_rhport_init(rhport, rh_init)); } #endif #if CFG_TUH_ENABLED if (rh_init->role == TUSB_ROLE_HOST) { TU_ASSERT(tuh_rhport_init(rhport, rh_init)); } #endif return true; } bool tusb_inited(void) { bool ret = false; #if CFG_TUD_ENABLED if (tud_inited()) { ret = true; } #endif #if CFG_TUH_ENABLED if (tuh_inited()) { ret = true; } #endif return ret; } void tusb_int_handler(uint8_t rhport, bool in_isr) { TU_VERIFY(rhport < TUP_USBIP_CONTROLLER_NUM,); #if CFG_TUD_ENABLED if (_tusb_rhport_role[rhport] == TUSB_ROLE_DEVICE) { (void) in_isr; dcd_int_handler(rhport); } #endif #if CFG_TUH_ENABLED if (_tusb_rhport_role[rhport] == TUSB_ROLE_HOST) { hcd_int_handler(rhport, in_isr); } #endif } bool tusb_deinit(uint8_t rhport) { TU_VERIFY(rhport < TUP_USBIP_CONTROLLER_NUM); bool ret = false; #if CFG_TUD_ENABLED if (_tusb_rhport_role[rhport] == TUSB_ROLE_DEVICE) { TU_ASSERT(tud_deinit(rhport)); _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; ret = true; } #endif #if CFG_TUH_ENABLED if (_tusb_rhport_role[rhport] == TUSB_ROLE_HOST) { TU_ASSERT(tuh_deinit(rhport)); _tusb_rhport_role[rhport] = TUSB_ROLE_INVALID; ret = true; } #endif return ret; } //--------------------------------------------------------------------+ // Descriptor helper //--------------------------------------------------------------------+ uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) { while (desc + 1 < end) { if (desc[1] == byte1) { return desc; } desc += desc[DESC_OFFSET_LEN]; } return NULL; } uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) { while (desc + 2 < end) { if (desc[1] == byte1 && desc[2] == byte2) { return desc; } desc += desc[DESC_OFFSET_LEN]; } return NULL; } uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) { while (desc + 3 < end) { if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) { return desc; } desc += desc[DESC_OFFSET_LEN]; } return NULL; } //--------------------------------------------------------------------+ // Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; // pre-check to help reducing mutex lock TU_VERIFY(ep_state->busy == 0); TU_VERIFY(ep_state->claimed == 0); (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only claim the endpoint if it is not busy and not claimed yet. bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); if (available) { ep_state->claimed = 1; } (void) osal_mutex_unlock(mutex); return available; } bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); if (ret) { ep_state->claimed = 0; } (void) osal_mutex_unlock(mutex); return ret; } #if CFG_TUSB_DEBUG bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { const uint16_t max_packet_size = tu_edpt_packet_size(desc_ep); TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); TU_ASSERT(max_packet_size > 0); switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_ISOCHRONOUS: { const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023); TU_ASSERT(max_packet_size <= spec_size); break; } case TUSB_XFER_BULK: if (speed == TUSB_SPEED_HIGH) { // Bulk highspeed must be EXACTLY 512 TU_ASSERT(max_packet_size == 512); } else { // Bulk fullspeed can only be 8, 16, 32, 64 TU_ASSERT(max_packet_size == 8 || max_packet_size == 16 || max_packet_size == 32 || max_packet_size == 64); } break; case TUSB_XFER_INTERRUPT: { const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); TU_ASSERT(max_packet_size <= spec_size); break; } default: return false; } return true; } #endif bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max, const uint8_t *p_desc, uint16_t desc_len) { const uint8_t *desc_end = p_desc + desc_len; while (tu_desc_in_bounds(p_desc, desc_end)) { const uint8_t desc_type = tu_desc_type(p_desc); if (desc_type == TUSB_DESC_ENDPOINT) { const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); ep2drv[ep_num][ep_dir] = driver_id; } else if (desc_type == TUSB_DESC_INTERFACE) { const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc; if (desc_itf->bAlternateSetting == 0) { TU_ASSERT(desc_itf->bInterfaceNumber < itf_max); itf2drv[desc_itf->bInterfaceNumber] = driver_id; } } p_desc = tu_desc_next(p_desc); } return true; } //--------------------------------------------------------------------+ // Endpoint Stream Helper for both Host and Device stack //--------------------------------------------------------------------+ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, uint16_t ff_bufsize, uint8_t *ep_buf) { (void) is_tx; if (ff_buf == NULL || ff_bufsize == 0) { return false; } s->is_host = is_host; tu_fifo_config(&s->ff, ff_buf, ff_bufsize, overwritable); #if OSAL_MUTEX_REQUIRED if (ff_buf != NULL && ff_bufsize > 0) { osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); } #endif s->ep_buf = ep_buf; return true; } static bool stream_claim(tu_edpt_stream_t *s) { TU_VERIFY(s->ep_addr != 0); // must be opened if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_claim(s->hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED return usbd_edpt_claim(s->hwid, s->ep_addr); #endif } return false; } static bool stream_xfer(tu_edpt_stream_t *s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } else { #if CFG_TUD_ENABLED if (s->ep_buf == NULL) { return usbd_edpt_xfer_fifo(s->hwid, s->ep_addr, &s->ff, count, false); } else { return usbd_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); } #endif } return false; } static bool stream_release(tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_release(s->hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED return usbd_edpt_release(s->hwid, s->ep_addr); #endif } return false; } //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (s->mps - 1)))); TU_VERIFY(stream_claim(s)); TU_ASSERT(stream_xfer(s, 0)); return true; } uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { const uint16_t ff_count = tu_fifo_count(&s->ff); TU_VERIFY(ff_count > 0, 0); // skip if no data TU_VERIFY(stream_claim(s), 0); // Pull data from FIFO -> EP buf uint16_t count; if (s->ep_buf == NULL) { count = tu_fifo_count(&s->ff); // re-get count since fifo can be changed } else { count = tu_fifo_read_n(&s->ff, s->ep_buf, s->xfer_len); } if (count > 0) { TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected stream_release(s); return 0; } } uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { TU_VERIFY(bufsize > 0); const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) { tu_edpt_stream_write_xfer(s); } return ret; } uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { return (uint32_t)tu_fifo_remaining(&s->ff); } //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { uint16_t available = tu_fifo_remaining(&s->ff); // Prepare for incoming data but only allow what we can store in the ring buffer. // TODO Actually we can still carry out the transfer, keeping count of received bytes // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming TU_VERIFY(available >= s->mps); TU_VERIFY(stream_claim(s), 0); available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed if (available >= s->mps) { // multiple of packet size limit by ep bufsize uint16_t count = (uint16_t) (available & ~(s->mps - 1)); count = tu_min16(count, s->xfer_len); TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer stream_release(s); return 0; } } uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize) { const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); tu_edpt_stream_read_xfer(s); return num_read; } //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG #include #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* const tu_str_speed[] = {"Full", "Low", "High"}; char const* const tu_str_std_request[] = { "Get Status", "Clear Feature", "Reserved", "Set Feature", "Reserved", "Set Address", "Get Descriptor", "Set Descriptor", "Get Configuration", "Set Configuration", "Get Interface", "Set Interface", "Synch Frame" }; char const* const tu_str_xfer_result[] = { "OK", "FAILED", "STALLED", "TIMEOUT" }; #endif static void dump_str_line(uint8_t const* buf, uint16_t count) { tu_printf(" |"); // each line is 16 bytes for (uint16_t i = 0; i < count; i++) { int ch = buf[i]; tu_printf("%c", isprint(ch) ? ch : '.'); } tu_printf("|\r\n"); } /* Print out memory contents * - buf : buffer * - count : number of item * - indent: prefix spaces on every line */ void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) { uint8_t const size = 1; // fixed 1 byte for now if (!buf || !count) { tu_printf("NULL\r\n"); return; } uint8_t const* buf8 = (uint8_t const*) buf; char format[] = "%00X"; format[2] += (uint8_t) (2 * size); // 1 byte = 2 hex digits const uint8_t item_per_line = 16 / size; for (unsigned int i = 0; i < count; i++) { unsigned int value = 0; if (i % item_per_line == 0) { // Print Ascii if (i != 0) { dump_str_line(buf8 - 16, 16); } for (uint8_t s = 0; s < indent; s++) { tu_printf(" "); } // print offset or absolute address tu_printf("%04X: ", 16 * i / item_per_line); } tu_memcpy_s(&value, sizeof(value), buf8, size); buf8 += size; tu_printf(" "); tu_printf(format, value); } // fill up last row to 16 for printing ascii const uint32_t remain = count % 16; uint8_t nback = (uint8_t) (remain ? remain : 16); if (remain > 0) { for (uint32_t i = 0; i < 16 - remain; i++) { tu_printf(" "); for (int j = 0; j < 2 * size; j++) { tu_printf(" "); } } } dump_str_line(buf8 - nback, nback); } #endif #endif // host or device enabled ================================================ FILE: src/tusb.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_H_ #define TUSB_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ #include "common/tusb_common.h" #include "osal/osal.h" #include "common/tusb_fifo.h" //------------- TypeC -------------// #if CFG_TUC_ENABLED #include "typec/usbc.h" #endif //------------- HOST -------------// #if CFG_TUH_ENABLED #include "host/usbh.h" #if CFG_TUH_HID #include "class/hid/hid_host.h" #endif #if CFG_TUH_MSC #include "class/msc/msc_host.h" #endif #if CFG_TUH_CDC #include "class/cdc/cdc_host.h" #endif #if CFG_TUH_MIDI #include "class/midi/midi_host.h" #endif #if CFG_TUH_VENDOR #include "class/vendor/vendor_host.h" #endif #else #ifndef tuh_int_handler #define tuh_int_handler(...) #endif #endif //------------- DEVICE -------------// #if CFG_TUD_ENABLED #include "device/usbd.h" #if CFG_TUD_HID #include "class/hid/hid_device.h" #endif #if CFG_TUD_CDC #include "class/cdc/cdc_device.h" #endif #if CFG_TUD_MSC #include "class/msc/msc_device.h" #endif #if CFG_TUD_PRINTER #include "class/printer/printer_device.h" #endif #if CFG_TUD_MTP #include "class/mtp/mtp_device.h" #endif #if CFG_TUD_AUDIO #include "class/audio/audio_device.h" #endif #if CFG_TUD_VIDEO #include "class/video/video_device.h" #endif #if CFG_TUD_MIDI #include "class/midi/midi_device.h" #endif #if CFG_TUD_VENDOR #include "class/vendor/vendor_device.h" #endif #if CFG_TUD_USBTMC #include "class/usbtmc/usbtmc_device.h" #endif #if CFG_TUD_DFU_RUNTIME #include "class/dfu/dfu_rt_device.h" #endif #if CFG_TUD_DFU #include "class/dfu/dfu_device.h" #endif #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM #include "class/net/net_device.h" #endif #if CFG_TUD_BTH #include "class/bth/bth_device.h" #endif #else #ifndef tud_int_handler #define tud_int_handler(...) #endif #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED || CFG_TUD_ENABLED // Internal helper for backward compatible with tusb_init(void) bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Initialize roothub port with device/host role // Note: when using with RTOS, this should be called after scheduler/kernel is started. // Since USB IRQ handler does use RTOS queue API. // Note2: defined as macro for backward compatible with tusb_init(void), can be changed to function in the future. #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) #define _tusb_init_arg0() tusb_rhport_init(0, NULL) #else #define _tusb_init_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined") #endif #define _tusb_init_arg1(_rhport) _tusb_init_arg0() #define _tusb_init_arg2(_rhport, _rh_init) tusb_rhport_init(_rhport, _rh_init) #define tusb_init(...) TU_FUNC_OPTIONAL_ARG(_tusb_init, __VA_ARGS__) // Check if stack is initialized bool tusb_inited(void); // Called to handle usb interrupt/event. tusb_init(rhport, role) must be called before void tusb_int_handler(uint8_t rhport, bool in_isr); // Deinit usb stack on roothub port bool tusb_deinit(uint8_t rhport); #else #define tusb_init(...) (false) #define tusb_int_handler(...) do {}while(0) #define tusb_inited() (false) #define tusb_deinit(...) (false) #endif #ifdef __cplusplus } #endif #endif /* TUSB_H_ */ ================================================ FILE: src/tusb_option.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #pragma once #include "common/tusb_compiler.h" // Version is release as major.minor.revision eg 1.0.0 #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 20 #define TUSB_VERSION_REVISION 1 #define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR * 10000 + TUSB_VERSION_MINOR * 100 + TUSB_VERSION_REVISION) #define TUSB_VERSION_STRING TU_XSTRING(TUSB_VERSION_MAJOR) "." TU_XSTRING(TUSB_VERSION_MINOR) "." TU_XSTRING(TUSB_VERSION_REVISION) //--------------------------------------------------------------------+ // Supported MCUs // CFG_TUSB_MCU must be defined to one of following value //--------------------------------------------------------------------+ #define OPT_MCU_NONE 0 // LPC #define OPT_MCU_LPC11UXX 1 ///< NXP LPC11Uxx #define OPT_MCU_LPC13XX 2 ///< NXP LPC13xx #define OPT_MCU_LPC15XX 3 ///< NXP LPC15xx #define OPT_MCU_LPC175X_6X 4 ///< NXP LPC175x, LPC176x #define OPT_MCU_LPC177X_8X 5 ///< NXP LPC177x, LPC178x #define OPT_MCU_LPC18XX 6 ///< NXP LPC18xx #define OPT_MCU_LPC40XX 7 ///< NXP LPC40xx #define OPT_MCU_LPC43XX 8 ///< NXP LPC43xx #define OPT_MCU_LPC51 9 ///< NXP LPC51 #define OPT_MCU_LPC51UXX OPT_MCU_LPC51 ///< NXP LPC51 #define OPT_MCU_LPC54 10 ///< NXP LPC54 #define OPT_MCU_LPC55 11 ///< NXP LPC55 // legacy naming #define OPT_MCU_LPC54XXX OPT_MCU_LPC54 #define OPT_MCU_LPC55XX OPT_MCU_LPC55 // NRF #define OPT_MCU_NRF5X 100 ///< Nordic nRF 52,53 series #define OPT_MCU_NRF54 101 ///< Nordic nRF54 series // SAM #define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 #define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 #define OPT_MCU_SAMG 202 ///< MicroChip SAMDG series #define OPT_MCU_SAME5X 203 ///< MicroChip SAM E5x #define OPT_MCU_SAMD11 204 ///< MicroChip SAMD11 #define OPT_MCU_SAML2X 205 ///< MicroChip SAML2x #define OPT_MCU_SAML21 OPT_MCU_SAML2X ///< SAML21 backward compatibility #define OPT_MCU_SAML22 OPT_MCU_SAML2X ///< SAML22 backward compatibility #define OPT_MCU_SAMX7X 207 ///< MicroChip SAME70, S70, V70, V71 family // STM32 #define OPT_MCU_STM32F0 300 ///< ST F0 #define OPT_MCU_STM32F1 301 ///< ST F1 #define OPT_MCU_STM32F2 302 ///< ST F2 #define OPT_MCU_STM32F3 303 ///< ST F3 #define OPT_MCU_STM32F4 304 ///< ST F4 #define OPT_MCU_STM32F7 305 ///< ST F7 #define OPT_MCU_STM32H7 306 ///< ST H7 #define OPT_MCU_STM32L1 308 ///< ST L1 #define OPT_MCU_STM32L0 307 ///< ST L0 #define OPT_MCU_STM32L4 309 ///< ST L4 #define OPT_MCU_STM32G0 310 ///< ST G0 #define OPT_MCU_STM32G4 311 ///< ST G4 #define OPT_MCU_STM32WB 312 ///< ST WB #define OPT_MCU_STM32U5 313 ///< ST U5 #define OPT_MCU_STM32L5 314 ///< ST L5 #define OPT_MCU_STM32H5 315 ///< ST H5 #define OPT_MCU_STM32U0 316 ///< ST U0 #define OPT_MCU_STM32H7RS 317 ///< ST F7RS #define OPT_MCU_STM32C0 318 ///< ST C0 #define OPT_MCU_STM32N6 319 ///< ST N6 #define OPT_MCU_STM32WBA 320 ///< ST WBA #define OPT_MCU_STM32U3 321 ///< ST U3 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 // TI #define OPT_MCU_MSP430x5xx 500 ///< TI MSP430x5xx #define OPT_MCU_MSP432E4 510 ///< TI MSP432E4xx #define OPT_MCU_TM4C123 511 ///< TI Tiva-C 123x #define OPT_MCU_TM4C129 512 ///< TI Tiva-C 129x // ValentyUSB eptri #define OPT_MCU_VALENTYUSB_EPTRI 600 ///< Fomu eptri config // NXP iMX RT #define OPT_MCU_MIMXRT1XXX 700 ///< NXP iMX RT1xxx Series #define OPT_MCU_MIMXRT10XX OPT_MCU_MIMXRT1XXX ///< RT10xx #define OPT_MCU_MIMXRT11XX OPT_MCU_MIMXRT1XXX ///< RT11xx // Nuvoton #define OPT_MCU_NUC121 800 #define OPT_MCU_NUC126 801 #define OPT_MCU_NUC120 802 #define OPT_MCU_NUC505 803 // Espressif #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3 #define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) #define OPT_MCU_ESP32C3 903 ///< Espressif ESP32-C3 #define OPT_MCU_ESP32C6 904 ///< Espressif ESP32-C6 #define OPT_MCU_ESP32C2 905 ///< Espressif ESP32-C2 #define OPT_MCU_ESP32H2 906 ///< Espressif ESP32-H2 #define OPT_MCU_ESP32P4 907 ///< Espressif ESP32-P4 #define OPT_MCU_ESP32C5 908 ///< Espressif ESP32-C5 #define OPT_MCU_ESP32C61 909 ///< Espressif ESP32-C61 #define OPT_MCU_ESP32H4 910 ///< Espressif ESP32-H4 // Dialog #define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x // Raspberry Pi #define OPT_MCU_RP2040 1100 ///< Raspberry Pi RP2040 // NXP Kinetis #define OPT_MCU_KINETIS_KL 1200 ///< NXP KL series #define OPT_MCU_KINETIS_K32L 1201 ///< NXP K32L series #define OPT_MCU_KINETIS_K32 1201 ///< Alias to K32L #define OPT_MCU_KINETIS_K 1202 ///< NXP K series #define OPT_MCU_MKL25ZXX 1200 ///< Alias to KL (obsolete) #define OPT_MCU_K32L2BXX 1201 ///< Alias to K32 (obsolete) // Silabs #define OPT_MCU_EFM32GG 1300 ///< Silabs EFM32GG // Renesas RX #define OPT_MCU_RX63X 1400 ///< Renesas RX63N/631 #define OPT_MCU_RX65X 1401 ///< Renesas RX65N/RX651 #define OPT_MCU_RX72N 1402 ///< Renesas RX72N #define OPT_MCU_RAXXX 1403 ///< Renesas RA generic // Mind Motion #define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327 // GigaDevice #define OPT_MCU_GD32VF103 1600 ///< GigaDevice GD32VF103 // Broadcom #define OPT_MCU_BCM2711 1700 ///< Broadcom BCM2711 #define OPT_MCU_BCM2835 1701 ///< Broadcom BCM2835 #define OPT_MCU_BCM2837 1702 ///< Broadcom BCM2837 // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 // PIC #define OPT_MCU_PIC32MZ 1900 ///< MicroChip PIC32MZ family #define OPT_MCU_PIC32MM 1901 ///< MicroChip PIC32MM family #define OPT_MCU_PIC32MX 1902 ///< MicroChip PIC32MX family #define OPT_MCU_PIC32MK 1903 ///< MicroChip PIC32MK family #define OPT_MCU_PIC24 1910 ///< MicroChip PIC24 family #define OPT_MCU_DSPIC33 1911 ///< MicroChip DSPIC33 family // BridgeTek #define OPT_MCU_FT90X 2000 ///< BridgeTek FT90x #define OPT_MCU_FT93X 2001 ///< BridgeTek FT93x // Allwinner #define OPT_MCU_F1C100S 2100 ///< Allwinner F1C100s family // WCH #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X #define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series #define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series #define OPT_MCU_RW61X 2302 ///< NXP RW61x Series // Analog Devices #define OPT_MCU_MAX32690 2400 ///< ADI MAX32690 #define OPT_MCU_MAX32665 2401 ///< ADI MAX32666/5 #define OPT_MCU_MAX32666 2401 ///< ADI MAX32666/5 #define OPT_MCU_MAX32650 2402 ///< ADI MAX32650/1/2 #define OPT_MCU_MAX78002 2403 ///< ADI MAX78002 // ArteryTek #define OPT_MCU_AT32F403A_407 2500 ///< ArteryTek AT32F403A_AT32F407 #define OPT_MCU_AT32F415 2501 ///< ArteryTek AT32F415 #define OPT_MCU_AT32F435_437 2502 ///< ArteryTek AT32F435_AT32F437 #define OPT_MCU_AT32F423 2503 ///< ArteryTek AT32F423 #define OPT_MCU_AT32F402_405 2504 ///< ArteryTek AT32F402_405 #define OPT_MCU_AT32F425 2505 ///< ArteryTek AT32F425 #define OPT_MCU_AT32F413 2506 ///< ArteryTek AT32F413 #define OPT_MCU_AT32F45X 2507 ///< ArteryTek AT32F45x // HPMicro #define OPT_MCU_HPM 2600 ///< HPMicro // Check if configured MCU is one of listed // Apply TU_MCU_IS_EQUAL with || as separator to list of input #define TU_MCU_IS_EQUAL(_m) (CFG_TUSB_MCU == (_m)) #define TU_CHECK_MCU(...) (TU_ARGS_APPLY(TU_MCU_IS_EQUAL, ||, __VA_ARGS__)) //--------------------------------------------------------------------+ // Supported OS //--------------------------------------------------------------------+ #define OPT_OS_NONE 1 ///< No RTOS #define OPT_OS_FREERTOS 2 ///< FreeRTOS #define OPT_OS_MYNEWT 3 ///< Mynewt OS #define OPT_OS_CUSTOM 4 ///< Custom OS is implemented by application #define OPT_OS_PICO 5 ///< Raspberry Pi Pico SDK #define OPT_OS_RTTHREAD 6 ///< RT-Thread #define OPT_OS_RTX4 7 ///< Keil RTX 4 #define OPT_OS_ZEPHYR 8 ///< Zephyr #define OPT_OS_THREADX 9 ///< ThreadX //--------------------------------------------------------------------+ // Mode and Speed //--------------------------------------------------------------------+ // Low byte is operational mode #define OPT_MODE_NONE 0x0000 ///< Disabled #define OPT_MODE_DEVICE 0x0001 ///< Device Mode #define OPT_MODE_HOST 0x0002 ///< Host Mode // High byte is max operational speed (corresponding to tusb_speed_t) #define OPT_MODE_DEFAULT_SPEED 0x0000u ///< Default (max) speed supported by MCU #define OPT_MODE_LOW_SPEED 0x0100u ///< Low Speed #define OPT_MODE_FULL_SPEED 0x0200u ///< Full Speed #define OPT_MODE_HIGH_SPEED 0x0400u ///< High Speed #define OPT_MODE_SPEED_MASK 0xff00u //--------------------------------------------------------------------+ // Include tusb_config.h //--------------------------------------------------------------------+ // Allow to use command line to change the config name/location #ifdef CFG_TUSB_CONFIG_FILE #include CFG_TUSB_CONFIG_FILE #else #include "tusb_config.h" #endif #include "common/tusb_mcu.h" //--------------------------------------------------------------------+ // USBIP //--------------------------------------------------------------------+ //------------- ChipIdea -------------// // Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is // insufficient). #ifndef CFG_TUD_CI_HS_VBUS_CHARGE #ifndef CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT #define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0 #endif #define CFG_TUD_CI_HS_VBUS_CHARGE CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT #endif // CI_HS support FIFO transfer if endpoint buffer is 4k aligned and size is multiple of 4k, also DCACHE is disabled #ifndef CFG_TUD_CI_HS_EPBUF_4K_ALIGNED #define CFG_TUD_CI_HS_EPBUF_4K_ALIGNED 0 #endif #if CFG_TUD_CI_HS_EPBUF_4K_ALIGNED && !CFG_TUD_MEM_DCACHE_ENABLE #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #endif //------------- DWC2 -------------// // DMA mode for device #ifndef CFG_TUD_DWC2_DMA_ENABLE #ifndef CFG_TUD_DWC2_DMA_ENABLE_DEFAULT #define CFG_TUD_DWC2_DMA_ENABLE_DEFAULT 0 #endif #define CFG_TUD_DWC2_DMA_ENABLE CFG_TUD_DWC2_DMA_ENABLE_DEFAULT #endif // Slave mode for device #ifndef CFG_TUD_DWC2_SLAVE_ENABLE #ifndef CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE // disabled if DMA is enabled #endif #define CFG_TUD_DWC2_SLAVE_ENABLE CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT #endif // DMA mode for host #ifndef CFG_TUH_DWC2_DMA_ENABLE #ifndef CFG_TUH_DWC2_DMA_ENABLE_DEFAULT #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 #endif #define CFG_TUH_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE_DEFAULT #endif // Slave mode for host #ifndef CFG_TUH_DWC2_SLAVE_ENABLE #ifndef CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE // disabled if DMA is enabled #endif #define CFG_TUH_DWC2_SLAVE_ENABLE CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT #endif #if defined(TUP_USBIP_DWC2) #define CFG_TUD_EDPT_DEDICATED_HWFIFO CFG_TUD_DWC2_SLAVE_ENABLE #define CFG_TUH_EDPT_DEDICATED_HWFIFO CFG_TUH_DWC2_SLAVE_ENABLE #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32bit access #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo address #endif //------------ FSDEV --------------// #if defined(TUP_USBIP_FSDEV) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #if CFG_TUSB_FSDEV_PMA_SIZE == 2048 || TU_CHECK_MCU(OPT_MCU_STM32U0) // 32-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase #define CFG_TUSB_FSDEV_32BIT #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024 // 2 x 16-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase #elif CFG_TUSB_FSDEV_PMA_SIZE == 512 // 1 x 16-bit access scheme #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase #endif #endif //------------ MAX3421 -------------// // Enable MAX3421 USB host controller #ifndef CFG_TUH_MAX3421 #define CFG_TUH_MAX3421 0 #endif //------------ MUSB --------------// #if defined(TUP_USBIP_MUSB) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32 bit data #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // allow odd 16bit access #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // allow odd 8bit access #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo #endif //------------- Raspberry Pi -------------// // Enable PIO-USB software host controller #ifndef CFG_TUH_RPI_PIO_USB #define CFG_TUH_RPI_PIO_USB 0 #endif #ifndef CFG_TUD_RPI_PIO_USB #define CFG_TUD_RPI_PIO_USB 0 #endif #if (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 1 #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 1 #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ #endif //------------ RUSB2 --------------// #if defined(TUP_USBIP_RUSB2) #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (2 | (TUD_OPT_HIGH_SPEED ? 4 : 0)) // 16 bit and 32 bit if highspeed #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE // custom write since rusb2 can change access width 32 -> 16 and can write // odd byte with byte access #endif //------- Microchip SAMX7X -------// // DMA mode for device #ifndef CFG_TUD_SAMX7X_DMA_ENABLE #ifndef CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT #define CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT 0 #endif #define CFG_TUD_SAMX7X_DMA_ENABLE CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT #endif #if (CFG_TUSB_MCU == OPT_MCU_SAMX7X) #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #endif //-------------------------------------------------------------------- // RootHub Mode detection //-------------------------------------------------------------------- //------------- Root hub as Device -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUD_OPT_RHPORT 0 #elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUD_OPT_RHPORT 1 #else #define TUD_RHPORT_MODE OPT_MODE_NONE #endif #ifndef CFG_TUD_ENABLED // fallback to use CFG_TUSB_RHPORTx_MODE #define CFG_TUD_ENABLED (TUD_RHPORT_MODE & OPT_MODE_DEVICE) #endif #ifndef CFG_TUD_MAX_SPEED // fallback to use CFG_TUSB_RHPORTx_MODE #define CFG_TUD_MAX_SPEED (TUD_RHPORT_MODE & OPT_MODE_SPEED_MASK) #endif // For backward compatible #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED // highspeed support indicator #define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? (CFG_TUD_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) //------------- Root hub as Host -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) #define TUH_OPT_RHPORT 0 #elif defined(CFG_TUSB_RHPORT1_MODE) && ((CFG_TUSB_RHPORT1_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT1_MODE) #define TUH_OPT_RHPORT 1 #else #define TUH_RHPORT_MODE OPT_MODE_NONE #endif #ifndef CFG_TUH_ENABLED // fallback to use CFG_TUSB_RHPORTx_MODE #define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST) #endif #ifndef CFG_TUH_MAX_SPEED // fallback to use CFG_TUSB_RHPORTx_MODE #define CFG_TUH_MAX_SPEED (TUH_RHPORT_MODE & OPT_MODE_SPEED_MASK) #endif // For backward compatible #define TUSB_OPT_HOST_ENABLED CFG_TUH_ENABLED // highspeed support indicator #define TUH_OPT_HIGH_SPEED (CFG_TUH_MAX_SPEED ? (CFG_TUH_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) //--------------------------------------------------------------------+ // TODO move later //--------------------------------------------------------------------+ // TUP_MCU_STRICT_ALIGN will overwrite TUP_ARCH_STRICT_ALIGN. // In case TUP_MCU_STRICT_ALIGN = 1 and TUP_ARCH_STRICT_ALIGN =0, we will not reply on compiler // to generate unaligned access code. // LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM #if TUD_OPT_HIGH_SPEED && TU_CHECK_MCU(OPT_MCU_LPC54XXX, OPT_MCU_LPC55XX) #define TUP_MCU_STRICT_ALIGN 1 #else #define TUP_MCU_STRICT_ALIGN 0 #endif //--------------------------------------------------------------------+ // Common Options (Default) //--------------------------------------------------------------------+ // Debug enable to print out error message #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Level where CFG_TUSB_DEBUG must be at least for USBH is logged #ifndef CFG_TUH_LOG_LEVEL #define CFG_TUH_LOG_LEVEL 2 #endif // Level where CFG_TUSB_DEBUG must be at least for USBD is logged #ifndef CFG_TUD_LOG_LEVEL #define CFG_TUD_LOG_LEVEL 2 #endif // Memory section for placing buffer used for usb transferring. If MEM_SECTION is different for // host and device use: CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION instead #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif // Alignment requirement of buffer used for usb transferring. if MEM_ALIGN is different for // host and device controller use: CFG_TUD_MEM_ALIGN, CFG_TUH_MEM_ALIGN instead #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) #endif #ifndef CFG_TUSB_MEM_DCACHE_LINE_SIZE #ifndef CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 1 #endif #define CFG_TUSB_MEM_DCACHE_LINE_SIZE CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT #endif // OS selection #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_OS_HAS_SCHEDULER #define CFG_TUSB_OS_HAS_SCHEDULER (CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO) #endif #ifndef CFG_TUSB_OS_INC_PATH #ifndef CFG_TUSB_OS_INC_PATH_DEFAULT #define CFG_TUSB_OS_INC_PATH_DEFAULT #endif #define CFG_TUSB_OS_INC_PATH CFG_TUSB_OS_INC_PATH_DEFAULT #endif //-------------------------------------------------------------------- // Device Options (Default) //-------------------------------------------------------------------- // Attribute to place data in accessible RAM for device controller (default: CFG_TUSB_MEM_SECTION) #ifndef CFG_TUD_MEM_SECTION #define CFG_TUD_MEM_SECTION CFG_TUSB_MEM_SECTION #endif // Attribute to align memory for device controller (default: CFG_TUSB_MEM_ALIGN) #ifndef CFG_TUD_MEM_ALIGN #define CFG_TUD_MEM_ALIGN CFG_TUSB_MEM_ALIGN #endif #ifndef CFG_TUD_MEM_DCACHE_ENABLE #ifndef CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT 0 #endif #define CFG_TUD_MEM_DCACHE_ENABLE CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT #endif #ifndef CFG_TUD_MEM_DCACHE_LINE_SIZE #define CFG_TUD_MEM_DCACHE_LINE_SIZE CFG_TUSB_MEM_DCACHE_LINE_SIZE #endif #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif #ifndef CFG_TUD_ENDPOINT0_BUFSIZE #define CFG_TUD_ENDPOINT0_BUFSIZE CFG_TUD_ENDPOINT0_SIZE #endif #ifndef CFG_TUD_INTERFACE_MAX #define CFG_TUD_INTERFACE_MAX 16 #endif // max events processed in one tud_task_ext() call, 0 for unlimited #ifndef CFG_TUD_TASK_EVENTS_PER_RUN #define CFG_TUD_TASK_EVENTS_PER_RUN 16 #endif // default to max hardware endpoint, but can be smaller to save RAM #ifndef CFG_TUD_ENDPPOINT_MAX #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX #endif #if CFG_TUD_ENDPPOINT_MAX > TUP_DCD_ENDPOINT_MAX #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" #endif // USB 2.0 7.1.20: compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 #endif #ifndef CFG_TUD_VBUS_DETECT_HW_DEFAULT #define CFG_TUD_VBUS_DETECT_HW_DEFAULT 0 #endif // Enable VBUS Detect hardware, usually via functional GPIO #ifndef CFG_TUD_VBUS_DETECT_HW #define CFG_TUD_VBUS_DETECT_HW CFG_TUD_VBUS_DETECT_HW_DEFAULT #endif //------------- Device Class Driver -------------// #ifndef CFG_TUD_BTH #define CFG_TUD_BTH 0 #endif #if CFG_TUD_BTH && !defined(CFG_TUD_BTH_ISO_ALT_COUNT) #error CFG_TUD_BTH_ISO_ALT_COUNT must be defined to tell Bluetooth driver the number of ISO endpoints to use #endif #ifndef CFG_TUD_CDC #define CFG_TUD_CDC 0 #endif #ifndef CFG_TUD_MSC #define CFG_TUD_MSC 0 #endif #ifndef CFG_TUD_MTP #define CFG_TUD_MTP 0 #endif #ifndef CFG_TUD_HID #define CFG_TUD_HID 0 #endif #ifndef CFG_TUD_AUDIO #define CFG_TUD_AUDIO 0 #endif #ifndef CFG_TUD_VIDEO #define CFG_TUD_VIDEO 0 #endif #ifndef CFG_TUD_MIDI #define CFG_TUD_MIDI 0 #endif #ifndef CFG_TUD_VENDOR #define CFG_TUD_VENDOR 0 #endif #ifndef CFG_TUD_USBTMC #define CFG_TUD_USBTMC 0 #endif #ifndef CFG_TUD_DFU_RUNTIME #define CFG_TUD_DFU_RUNTIME 0 #endif #ifndef CFG_TUD_DFU #define CFG_TUD_DFU 0 #endif #ifndef CFG_TUD_ECM_RNDIS #ifdef CFG_TUD_NET #warning "CFG_TUD_NET is renamed to CFG_TUD_ECM_RNDIS" #define CFG_TUD_ECM_RNDIS CFG_TUD_NET #else #define CFG_TUD_ECM_RNDIS 0 #endif #endif #ifndef CFG_TUD_NCM #define CFG_TUD_NCM 0 #endif #ifndef CFG_TUD_PRINTER #define CFG_TUD_PRINTER 0 #endif #ifndef CFG_TUD_EDPT_DEDICATED_HWFIFO #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 #endif //-------------------------------------------------------------------- // Host Options (Default) //-------------------------------------------------------------------- #if CFG_TUH_ENABLED #ifndef CFG_TUH_DEVICE_MAX #define CFG_TUH_DEVICE_MAX 1 #endif #ifndef CFG_TUH_ENUMERATION_BUFSIZE #define CFG_TUH_ENUMERATION_BUFSIZE 256 #endif #endif // CFG_TUH_ENABLED // Attribute to place data in accessible RAM for host controller (default: CFG_TUSB_MEM_SECTION) #ifndef CFG_TUH_MEM_SECTION #define CFG_TUH_MEM_SECTION CFG_TUSB_MEM_SECTION #endif // Attribute to align memory for host controller #ifndef CFG_TUH_MEM_ALIGN #define CFG_TUH_MEM_ALIGN CFG_TUSB_MEM_ALIGN #endif #ifndef CFG_TUH_MEM_DCACHE_ENABLE #ifndef CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT 0 #endif #define CFG_TUH_MEM_DCACHE_ENABLE CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT #endif #ifndef CFG_TUH_MEM_DCACHE_LINE_SIZE #define CFG_TUH_MEM_DCACHE_LINE_SIZE CFG_TUSB_MEM_DCACHE_LINE_SIZE #endif // max events processed in one tuh_task_ext() call, 0 for unlimited #ifndef CFG_TUH_TASK_EVENTS_PER_RUN #define CFG_TUH_TASK_EVENTS_PER_RUN 16 #endif //------------- CLASS -------------// #ifndef CFG_TUH_HUB #define CFG_TUH_HUB 0 #endif #ifndef CFG_TUH_CDC #define CFG_TUH_CDC 0 #endif // FTDI is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_FTDI #define CFG_TUH_CDC_FTDI 0 #endif // List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID #ifndef CFG_TUH_CDC_FTDI_VID_PID_LIST #define CFG_TUH_CDC_FTDI_VID_PID_LIST \ {0x0403, 0x6001}, /* Similar device to SIO above */ \ {0x0403, 0x6006}, /* FTDI's alternate PID for above */ \ {0x0403, 0x6010}, /* Dual channel device */ \ {0x0403, 0x6011}, /* Quad channel hi-speed device */ \ {0x0403, 0x6014}, /* Single channel hi-speed device */ \ {0x0403, 0x6015}, /* FT-X series (FT201X, FT230X, FT231X, etc) */ \ {0x0403, 0x6040}, /* Dual channel hi-speed device with PD */ \ {0x0403, 0x6041}, /* Quad channel hi-speed device with PD */ \ {0x0403, 0x6042}, /* Dual channel hi-speed device with PD */ \ {0x0403, 0x6043}, /* Quad channel hi-speed device with PD */ \ {0x0403, 0x6044}, /* Dual channel hi-speed device with PD */ \ {0x0403, 0x6045}, /* Dual channel hi-speed device with PD */ \ {0x0403, 0x6048}, /* Quad channel automotive grade hi-speed device */ \ {0x0403, 0x8372}, /* Product Id SIO application of 8U100AX */ \ {0x0403, 0xFBFA}, /* Product ID for FT232RL */ \ {0x0403, 0xCD18}, /* ??? */ #endif // CP210X is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_CP210X #define CFG_TUH_CDC_CP210X 0 #endif // List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID #ifndef CFG_TUH_CDC_CP210X_VID_PID_LIST #define CFG_TUH_CDC_CP210X_VID_PID_LIST \ { 0x10C4, 0xEA60 }, /* Silicon Labs factory default */ \ { 0x10C4, 0xEA61 }, /* Silicon Labs factory default */ \ { 0x10C4, 0xEA70 } /* Silicon Labs Dual Port factory default */ #endif #ifndef CFG_TUH_CDC_CH34X // CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 0 #endif // List of product IDs that can use the CH34X CDC driver #ifndef CFG_TUH_CDC_CH34X_VID_PID_LIST #define CFG_TUH_CDC_CH34X_VID_PID_LIST \ { 0x1a86, 0x5523 }, /* ch341 chip */ \ { 0x1a86, 0x7522 }, /* ch340k chip */ \ { 0x1a86, 0x7523 }, /* ch340 chip */ \ { 0x1a86, 0xe523 }, /* ch330 chip */ \ { 0x4348, 0x5523 }, /* ch340 custom chip */ \ { 0x2184, 0x0057 }, /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ \ { 0x9986, 0x7523 } /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ #endif #ifndef CFG_TUH_CDC_PL2303 // PL2303 is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_PL2303 0 #endif #ifndef CFG_TUH_CDC_PL2303_VID_PID_LIST // List of product IDs that can use the PL2303 CDC driver #define CFG_TUH_CDC_PL2303_VID_PID_LIST \ { 0x067b, 0x2303 }, /* initial 2303 */ \ { 0x067b, 0x2304 }, /* TB */ \ { 0x067b, 0x23a3 }, /* GC */ \ { 0x067b, 0x23b3 }, /* GB */ \ { 0x067b, 0x23c3 }, /* GT */ \ { 0x067b, 0x23d3 }, /* GL */ \ { 0x067b, 0x23e3 }, /* GE */ \ { 0x067b, 0x23f3 } /* GS */ #endif #ifndef CFG_TUH_HID #define CFG_TUH_HID 0 #endif #ifndef CFG_TUH_MIDI #define CFG_TUH_MIDI 0 #endif #ifndef CFG_TUH_MSC #define CFG_TUH_MSC 0 #endif #ifndef CFG_TUH_VENDOR #define CFG_TUH_VENDOR 0 #endif #ifndef CFG_TUH_API_EDPT_XFER #define CFG_TUH_API_EDPT_XFER 0 #endif #ifndef CFG_TUH_EDPT_DEDICATED_HWFIFO #define CFG_TUH_EDPT_DEDICATED_HWFIFO 0 #endif //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ #ifndef CFG_TUC_ENABLED #define CFG_TUC_ENABLED 0 #define tuc_int_handler(_p) #endif //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ #if CFG_TUD_ENDPOINT0_SIZE > 64 #error Control Endpoint Max Packet Size cannot be larger than 64 #endif // To avoid GCC compiler warnings when -pedantic option is used (strict ISO C) typedef int make_iso_compilers_happy; ================================================ FILE: src/typec/pd_types.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_PD_TYPES_H_ #define TUSB_PD_TYPES_H_ #ifdef __cplusplus extern "C" { #endif #include #include #include "common/tusb_compiler.h" // Start of all packed definitions for compiler without per-type packed TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN //--------------------------------------------------------------------+ // TYPE-C //--------------------------------------------------------------------+ typedef enum { TUSB_TYPEC_PORT_SRC, TUSB_TYPEC_PORT_SNK, TUSB_TYPEC_PORT_DRP } tusb_typec_port_type_t; enum { PD_CTRL_RESERVED = 0, // 0b00000: 0 PD_CTRL_GOOD_CRC, // 0b00001: 1 PD_CTRL_GO_TO_MIN, // 0b00010: 2 PD_CTRL_ACCEPT, // 0b00011: 3 PD_CTRL_REJECT, // 0b00100: 4 PD_CTRL_PING, // 0b00101: 5 PD_CTRL_PS_READY, // 0b00110: 6 PD_CTRL_GET_SOURCE_CAP, // 0b00111: 7 PD_CTRL_GET_SINK_CAP, // 0b01000: 8 PD_CTRL_DR_SWAP, // 0b01001: 9 PD_CTRL_PR_SWAP, // 0b01010: 10 PD_CTRL_VCONN_SWAP, // 0b01011: 11 PD_CTRL_WAIT, // 0b01100: 12 PD_CTRL_SOFT_RESET, // 0b01101: 13 PD_CTRL_DATA_RESET, // 0b01110: 14 PD_CTRL_DATA_RESET_COMPLETE, // 0b01111: 15 PD_CTRL_NOT_SUPPORTED, // 0b10000: 16 PD_CTRL_GET_SOURCE_CAP_EXTENDED, // 0b10001: 17 PD_CTRL_GET_STATUS, // 0b10010: 18 PD_CTRL_FR_SWAP, // 0b10011: 19 PD_CTRL_GET_PPS_STATUS, // 0b10100: 20 PD_CTRL_GET_COUNTRY_CODES, // 0b10101: 21 PD_CTRL_GET_SINK_CAP_EXTENDED, // 0b10110: 22 PD_CTRL_GET_SOURCE_INFO, // 0b10111: 23 PD_CTRL_REVISION, // 0b11000: 24 }; enum { PD_DATA_RESERVED = 0, // 0b00000: 0 PD_DATA_SOURCE_CAP, // 0b00001: 1 PD_DATA_REQUEST, // 0b00010: 2 PD_DATA_BIST, // 0b00011: 3 PD_DATA_SINK_CAP, // 0b00100: 4 PD_DATA_BATTERY_STATUS, // 0b00101: 5 PD_DATA_ALERT, // 0b00110: 6 PD_DATA_GET_COUNTRY_INFO, // 0b00111: 7 PD_DATA_ENTER_USB, // 0b01000: 8 PD_DATA_EPR_REQUEST, // 0b01001: 9 PD_DATA_EPR_MODE, // 0b01010: 10 PD_DATA_SRC_INFO, // 0b01011: 11 PD_DATA_REVISION, // 0b01100: 12 PD_DATA_RESERVED_13, // 0b01101: 13 PD_DATA_RESERVED_14, // 0b01110: 14 PD_DATA_VENDOR_DEFINED, // 0b01111: 15 }; enum { PD_REV_10 = 0x0, PD_REV_20 = 0x1, PD_REV_30 = 0x2, }; enum { PD_DATA_ROLE_UFP = 0x0, PD_DATA_ROLE_DFP = 0x1, }; enum { PD_POWER_ROLE_SINK = 0x0, PD_POWER_ROLE_SOURCE = 0x1, }; typedef struct TU_ATTR_PACKED { uint16_t msg_type : 5; // [0:4] uint16_t data_role : 1; // [5] SOP only: 0 UFP, 1 DFP uint16_t specs_rev : 2; // [6:7] uint16_t power_role : 1; // [8] SOP only: 0 Sink, 1 Source uint16_t msg_id : 3; // [9:11] uint16_t n_data_obj : 3; // [12:14] uint16_t extended : 1; // [15] } pd_header_t; TU_VERIFY_STATIC(sizeof(pd_header_t) == 2, "size is not correct"); typedef struct TU_ATTR_PACKED { uint16_t data_size : 9; // [0:8] uint16_t reserved : 1; // [9] uint16_t request_chunk : 1; // [10] uint16_t chunk_number : 4; // [11:14] uint16_t chunked : 1; // [15] } pd_header_extended_t; TU_VERIFY_STATIC(sizeof(pd_header_extended_t) == 2, "size is not correct"); //--------------------------------------------------------------------+ // Source Capability //--------------------------------------------------------------------+ // All table references are from USBPD Specification rev3.1 version 1.8 enum { PD_PDO_TYPE_FIXED = 0, // Vmin = Vmax PD_PDO_TYPE_BATTERY, PD_PDO_TYPE_VARIABLE, // non-battery PD_PDO_TYPE_APDO, // Augmented Power Data Object }; // Fixed Power Data Object (PDO) table 6-9 typedef struct TU_ATTR_PACKED { uint32_t current_max_10ma : 10; // [9..0] Max current in 10mA unit uint32_t voltage_50mv : 10; // [19..10] Voltage in 50mV unit uint32_t current_peak : 2; // [21..20] Peak current uint32_t reserved : 1; // [22] Reserved uint32_t epr_mode_capable : 1; // [23] epr_mode_capable uint32_t unchunked_ext_msg_support : 1; // [24] UnChunked Extended Message Supported uint32_t dual_role_data : 1; // [25] Dual Role Data uint32_t usb_comm_capable : 1; // [26] USB Communications Capable uint32_t unconstrained_power : 1; // [27] Unconstrained Power uint32_t usb_suspend_supported : 1; // [28] USB Suspend Supported uint32_t dual_role_power : 1; // [29] Dual Role Power uint32_t type : 2; // [30] Fixed Supply type = PD_PDO_TYPE_FIXED } pd_pdo_fixed_t; TU_VERIFY_STATIC(sizeof(pd_pdo_fixed_t) == 4, "Invalid size"); // Battery Power Data Object (PDO) table 6-12 typedef struct TU_ATTR_PACKED { uint32_t power_max_250mw : 10; // [9..0] Max allowable power in 250mW unit uint32_t voltage_min_50mv : 10; // [19..10] Minimum voltage in 50mV unit uint32_t voltage_max_50mv : 10; // [29..20] Maximum voltage in 50mV unit uint32_t type : 2; // [31..30] Battery type = PD_PDO_TYPE_BATTERY } pd_pdo_battery_t; TU_VERIFY_STATIC(sizeof(pd_pdo_battery_t) == 4, "Invalid size"); // Variable Power Data Object (PDO) table 6-11 typedef struct TU_ATTR_PACKED { uint32_t current_max_10ma : 10; // [9..0] Max current in 10mA unit uint32_t voltage_min_50mv : 10; // [19..10] Minimum voltage in 50mV unit uint32_t voltage_max_50mv : 10; // [29..20] Maximum voltage in 50mV unit uint32_t type : 2; // [31..30] Variable Supply type = PD_PDO_TYPE_VARIABLE } pd_pdo_variable_t; TU_VERIFY_STATIC(sizeof(pd_pdo_variable_t) == 4, "Invalid size"); // Augmented Power Data Object (PDO) table 6-13 typedef struct TU_ATTR_PACKED { uint32_t current_max_50ma : 7; // [6..0] Max current in 50mA unit uint32_t reserved1 : 1; // [7] Reserved uint32_t voltage_min_100mv : 8; // [15..8] Minimum Voltage in 100mV unit uint32_t reserved2 : 1; // [16] Reserved uint32_t voltage_max_100mv : 8; // [24..17] Maximum Voltage in 100mV unit uint32_t reserved3 : 2; // [26..25] Reserved uint32_t pps_power_limited : 1; // [27] PPS Power Limited uint32_t spr_programmable : 2; // [29..28] SPR Programmable Power Supply uint32_t type : 2; // [31..30] Augmented Power Data Object = PD_PDO_TYPE_APDO } pd_pdo_apdo_t; TU_VERIFY_STATIC(sizeof(pd_pdo_apdo_t) == 4, "Invalid size"); //--------------------------------------------------------------------+ // Request //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { uint32_t current_extremum_10ma : 10; // [9..0] Max (give back = 0) or Min (give back = 1) current in 10mA unit uint32_t current_operate_10ma : 10; // [19..10] Operating current in 10mA unit uint32_t reserved : 2; // [21..20] Reserved uint32_t epr_mode_capable : 1; // [22] EPR mode capable uint32_t unchunked_ext_msg_support : 1; // [23] UnChunked Extended Message Supported uint32_t no_usb_suspend : 1; // [24] No USB Suspend uint32_t usb_comm_capable : 1; // [25] USB Communications Capable uint32_t capability_mismatch : 1; // [26] Capability Mismatch uint32_t give_back_flag : 1; // [27] GiveBack Flag: 0 = Max, 1 = Min uint32_t object_position : 4; // [31..28] Object Position } pd_rdo_fixed_variable_t; TU_VERIFY_STATIC(sizeof(pd_rdo_fixed_variable_t) == 4, "Invalid size"); typedef struct TU_ATTR_PACKED { uint32_t power_extremum_250mw : 10; // [9..0] Max (give back = 0) or Min (give back = 1) operating power in 250mW unit uint32_t power_operate_250mw : 10; // [19..10] Operating power in 250mW unit uint32_t reserved : 2; // [21..20] Reserved uint32_t epr_mode_capable : 1; // [22] EPR mode capable uint32_t unchunked_ext_msg_support : 1; // [23] UnChunked Extended Message Supported uint32_t no_usb_suspend : 1; // [24] No USB Suspend uint32_t usb_comm_capable : 1; // [25] USB Communications Capable uint32_t capability_mismatch : 1; // [26] Capability Mismatch uint32_t give_back_flag : 1; // [27] GiveBack Flag: 0 = Max, 1 = Min uint32_t object_position : 4; // [31..28] Object Position } pd_rdo_battery_t; TU_VERIFY_STATIC(sizeof(pd_rdo_battery_t) == 4, "Invalid size"); TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END #ifdef __cplusplus } #endif #endif ================================================ FILE: src/typec/tcd.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) for Adafruit Industries * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_TCD_H_ #define TUSB_TCD_H_ #include "common/tusb_common.h" #include "pd_types.h" #include "osal/osal.h" #include "common/tusb_fifo.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ enum { TCD_EVENT_INVALID = 0, TCD_EVENT_CC_CHANGED, TCD_EVENT_RX_COMPLETE, TCD_EVENT_TX_COMPLETE, }; typedef struct TU_ATTR_PACKED { uint8_t rhport; uint8_t event_id; union { struct { uint8_t cc_state[2]; } cc_changed; struct TU_ATTR_PACKED { uint16_t result : 2; uint16_t xferred_bytes : 14; } xfer_complete; }; } tcd_event_t; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Initialize controller bool tcd_init(uint8_t rhport, uint32_t port_type); // Enable interrupt void tcd_int_enable (uint8_t rhport); // Disable interrupt void tcd_int_disable(uint8_t rhport); // Interrupt Handler void tcd_int_handler(uint8_t rhport); //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool tcd_msg_receive(uint8_t rhport, uint8_t* buffer, uint16_t total_bytes); bool tcd_msg_send(uint8_t rhport, uint8_t const* buffer, uint16_t total_bytes); //--------------------------------------------------------------------+ // Event API (implemented by stack) // Called by TCD to notify stack //--------------------------------------------------------------------+ extern void tcd_event_handler(tcd_event_t const * event, bool in_isr); TU_ATTR_ALWAYS_INLINE static inline void tcd_event_cc_changed(uint8_t rhport, uint8_t cc1, uint8_t cc2, bool in_isr) { tcd_event_t event = { .rhport = rhport, .event_id = TCD_EVENT_CC_CHANGED, .cc_changed = { .cc_state = {cc1, cc2 } } }; tcd_event_handler(&event, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void tcd_event_rx_complete(uint8_t rhport, uint16_t xferred_bytes, uint8_t result, bool in_isr) { tcd_event_t event = { .rhport = rhport, .event_id = TCD_EVENT_RX_COMPLETE, .xfer_complete = { .xferred_bytes = xferred_bytes, .result = result } }; tcd_event_handler(&event, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void tcd_event_tx_complete(uint8_t rhport, uint16_t xferred_bytes, uint8_t result, bool in_isr) { tcd_event_t event = { .rhport = rhport, .event_id = TCD_EVENT_TX_COMPLETE, .xfer_complete = { .xferred_bytes = xferred_bytes, .result = result } }; tcd_event_handler(&event, in_isr); } #ifdef __cplusplus } #endif #endif ================================================ FILE: src/typec/usbc.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (thach@tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "tusb_option.h" #if CFG_TUC_ENABLED #include "tcd.h" #include "usbc.h" //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ // Debug level of USBD #define USBC_DEBUG 2 #define TU_LOG_USBC(...) TU_LOG(USBC_DEBUG, __VA_ARGS__) // Event queue // usbc_int_set() is used as mutex in OS NONE config void usbc_int_set(bool enabled); OSAL_QUEUE_DEF(usbc_int_set, _usbc_qdef, CFG_TUC_TASK_QUEUE_SZ, tcd_event_t); tu_static osal_queue_t _usbc_q; // if stack is initialized static bool _usbc_inited = false; // if port is initialized static bool _port_inited[TUP_TYPEC_RHPORTS_NUM]; // Max possible PD size is 262 bytes static uint8_t _rx_buf[64] TU_ATTR_ALIGNED(4); static uint8_t _tx_buf[64] TU_ATTR_ALIGNED(4); bool usbc_msg_send(uint8_t rhport, pd_header_t const* header, void const* data); bool parse_msg_data(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end); bool parse_msg_control(uint8_t rhport, pd_header_t const* header); //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end) { (void) rhport; (void) header; (void) dobj; (void) p_end; return false; } TU_ATTR_WEAK bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header) { (void) rhport; (void) header; return false; } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool tuc_inited(uint8_t rhport) { return _usbc_inited && _port_inited[rhport]; } bool tuc_init(uint8_t rhport, uint32_t port_type) { // Initialize stack if (!_usbc_inited) { tu_memclr(_port_inited, sizeof(_port_inited)); _usbc_q = osal_queue_create(&_usbc_qdef); TU_ASSERT(_usbc_q != NULL); _usbc_inited = true; } // skip if port already initialized if ( _port_inited[rhport] ) { return true; } TU_LOG_USBC("USBC init on port %u\r\n", rhport); TU_LOG_INT(USBC_DEBUG, sizeof(tcd_event_t)); TU_ASSERT(tcd_init(rhport, port_type)); tcd_int_enable(rhport); _port_inited[rhport] = true; return true; } void tuc_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized if (!_usbc_inited) return; // Loop until there is no more events in the queue while (1) { tcd_event_t event; if (!osal_queue_receive(_usbc_q, &event, timeout_ms)) return; switch (event.event_id) { case TCD_EVENT_CC_CHANGED: break; case TCD_EVENT_RX_COMPLETE: // TODO process message here in ISR, move to thread later if (event.xfer_complete.result == XFER_RESULT_SUCCESS) { pd_header_t const* header = (pd_header_t const*) _rx_buf; if (header->n_data_obj == 0) { parse_msg_control(event.rhport, header); }else { uint8_t const* p_end = _rx_buf + event.xfer_complete.xferred_bytes; uint8_t const * dobj = _rx_buf + sizeof(pd_header_t); parse_msg_data(event.rhport, header, dobj, p_end); } } // prepare for next message tcd_msg_receive(event.rhport, _rx_buf, sizeof(_rx_buf)); break; case TCD_EVENT_TX_COMPLETE: break; default: break; } } } bool parse_msg_data(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end) { tuc_pd_data_received_cb(rhport, header, dobj, p_end); return true; } bool parse_msg_control(uint8_t rhport, pd_header_t const* header) { tuc_pd_control_received_cb(rhport, header); return true; } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool usbc_msg_send(uint8_t rhport, pd_header_t const* header, void const* data) { // copy header memcpy(_tx_buf, header, sizeof(pd_header_t)); // copy data objcet if available uint16_t const n_data_obj = header->n_data_obj; if (n_data_obj > 0) { memcpy(_tx_buf + sizeof(pd_header_t), data, n_data_obj * 4); } return tcd_msg_send(rhport, _tx_buf, sizeof(pd_header_t) + n_data_obj * 4); } bool tuc_msg_request(uint8_t rhport, void const* rdo) { pd_header_t const header = { .msg_type = PD_DATA_REQUEST, .data_role = PD_DATA_ROLE_UFP, .specs_rev = PD_REV_30, .power_role = PD_POWER_ROLE_SINK, .msg_id = 0, .n_data_obj = 1, .extended = 0, }; return usbc_msg_send(rhport, &header, rdo); } void tcd_event_handler(tcd_event_t const * event, bool in_isr) { (void) in_isr; switch(event->event_id) { case TCD_EVENT_CC_CHANGED: if (event->cc_changed.cc_state[0] || event->cc_changed.cc_state[1]) { // Attach, start receiving tcd_msg_receive(event->rhport, _rx_buf, sizeof(_rx_buf)); }else { // Detach } break; default: break; } osal_queue_send(_usbc_q, event, in_isr); } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void usbc_int_set(bool enabled) { // Disable all controllers since they shared the same event queue for (uint8_t p = 0; p < TUP_TYPEC_RHPORTS_NUM; p++) { if ( _port_inited[p] ) { if (enabled) { tcd_int_enable(p); }else { tcd_int_disable(p); } } } } #endif ================================================ FILE: src/typec/usbc.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #ifndef TUSB_UTCD_H_ #define TUSB_UTCD_H_ #include "common/tusb_common.h" #include "pd_types.h" #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // TypeC Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUC_TASK_QUEUE_SZ #define CFG_TUC_TASK_QUEUE_SZ 8 #endif //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Init typec stack on a port bool tuc_init(uint8_t rhport, uint32_t port_type); // Check if typec port is initialized bool tuc_inited(uint8_t rhport); // Task function should be called in main/rtos loop, extended version of tud_task() // - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever // - in_isr: if function is called in ISR void tuc_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline void tuc_task (void) { tuc_task_ext(UINT32_MAX, false); } #ifndef TUSB_TCD_H_ extern void tcd_int_handler(uint8_t rhport); #endif // Interrupt handler, name alias to TCD #define tuc_int_handler tcd_int_handler //--------------------------------------------------------------------+ // Callbacks //--------------------------------------------------------------------+ bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end); bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header); //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ bool tuc_msg_request(uint8_t rhport, void const* rdo); #ifdef __cplusplus } #endif #endif ================================================ FILE: test/fuzz/dcd_fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "device/dcd.h" #include "fuzz/fuzz_private.h" #include #include #include #define UNUSED(x) (void)(x) //--------------------------------------------------------------------+ // State tracker //--------------------------------------------------------------------+ struct State { bool interrupts_enabled; bool sof_enabled; uint8_t address; }; tu_static State state = {false, 0, 0}; //--------------------------------------------------------------------+ // Controller API // All no-ops as we are fuzzing. //--------------------------------------------------------------------+ extern "C" { bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { UNUSED(rhport); UNUSED(rh_init); return true; } void dcd_int_handler(uint8_t rhport) { assert(_fuzz_data_provider.has_value()); if (!state.interrupts_enabled) { return; } // Choose if we want to generate a signal based on the fuzzed data. if (_fuzz_data_provider->ConsumeBool()) { dcd_event_bus_signal( rhport, // Choose a random event based on the fuzz data. (dcd_eventid_t)_fuzz_data_provider->ConsumeIntegralInRange( DCD_EVENT_INVALID + 1, DCD_EVENT_COUNT - 1), // Identify trigger as either an interrupt or a syncrhonous call // depending on fuzz data. _fuzz_data_provider->ConsumeBool()); } if (_fuzz_data_provider->ConsumeBool()) { constexpr size_t kSetupFrameLength = 8; std::vector setup = _fuzz_data_provider->ConsumeBytes(kSetupFrameLength); // Fuzz consumer may return less than requested. If this is the case // we want to make sure that at least that length is allocated and available // to the signal handler. if (setup.size() != kSetupFrameLength) { setup.resize(kSetupFrameLength); } dcd_event_setup_received(rhport, setup.data(), // Identify trigger as either an interrupt or a // syncrhonous call depending on fuzz data. _fuzz_data_provider->ConsumeBool()); } } void dcd_int_enable(uint8_t rhport) { state.interrupts_enabled = true; UNUSED(rhport); return; } void dcd_int_disable(uint8_t rhport) { state.interrupts_enabled = false; UNUSED(rhport); return; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { UNUSED(rhport); state.address = dev_addr; // Respond with status. dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); return; } void dcd_remote_wakeup(uint8_t rhport) { UNUSED(rhport); return; } void dcd_connect(uint8_t rhport) { UNUSED(rhport); return; } void dcd_disconnect(uint8_t rhport) { UNUSED(rhport); return; } void dcd_sof_enable(uint8_t rhport, bool en) { state.sof_enabled = en; UNUSED(rhport); return; } //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { UNUSED(rhport); UNUSED(desc_ep); return _fuzz_data_provider->ConsumeBool(); } // Close all non-control endpoints, cancel all pending transfers if any. // Invoked when switching from a non-zero Configuration by SET_CONFIGURE // therefore required for multiple configuration support. void dcd_edpt_close_all(uint8_t rhport) { UNUSED(rhport); return; } // Close an endpoint. // Since it is weak, caller must TU_ASSERT this function's existence before // calling it. void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { UNUSED(rhport); UNUSED(ep_addr); return; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to // notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) { UNUSED(rhport); UNUSED(buffer); UNUSED(total_bytes); UNUSED(is_isr); uint8_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_IN) { std::vector temp = _fuzz_data_provider->ConsumeBytes(total_bytes); std::copy(temp.begin(), temp.end(), buffer); } // Ignore output data as it's not useful for fuzzing without a more // complex fuzzed backend. But we need to make sure it's not // optimised out. volatile uint8_t *dont_optimise0 = buffer; volatile uint16_t dont_optimise1 = total_bytes; UNUSED(dont_optimise0); UNUSED(dont_optimise1); return _fuzz_data_provider->ConsumeBool(); } /* TODO: implement a fuzzed version of this. bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) {} */ // Stall endpoint, any queuing transfer should be removed from endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { UNUSED(rhport); UNUSED(ep_addr); return; } // clear stall, data toggle is also reset to DATA0 // This API never calls with control endpoints, since it is auto cleared when // receiving setup packet void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { UNUSED(rhport); UNUSED(ep_addr); return; } } ================================================ FILE: test/fuzz/device/cdc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.5) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(cdc) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: test/fuzz/device/cdc/Makefile ================================================ include ../../make.mk INC += \ src \ # Example source SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.c)) SRC_CXX += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.cc)) include ../../rules.mk ================================================ FILE: test/fuzz/device/cdc/src/fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 #include #include #include #include #include "class/cdc/cdc_device.h" #include "fuzz/fuzz.h" #include "tusb.h" #include #include #include extern "C" { #define FUZZ_ITERATIONS 500 //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void cdc_task(FuzzedDataProvider *provider); extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { FuzzedDataProvider provider(Data, Size); std::vector callback_data = provider.ConsumeBytes( provider.ConsumeIntegralInRange(0, Size)); fuzz_init(callback_data.data(), callback_data.size()); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); for (int i = 0; i < FUZZ_ITERATIONS; i++) { if (provider.remaining_bytes() == 0) { return 0; } tud_int_handler(provider.ConsumeIntegral()); tud_task(); // tinyusb device task cdc_task(&provider); } return 0; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ enum CdcApiFuncs { kCdcNConnected, kCdcNGetLineState, kCdcNGetLineCoding, kCdcNSetWantedChar, kCdcNAvailable, kCdcNRead, kCdcNReadChar, kCdcNReadFlush, kCdcNPeek, kCdcNWrite, kCdcNWriteChar, kCdcNWriteStr, kCdcNWriteFlush, kCdcNWriteAvailable, kCdcNWriteClear, // We don't need to fuzz tud_cdc_* as they are just wrappers // calling with n==0. kMaxValue, }; void cdc_task(FuzzedDataProvider *provider) { assert(provider != NULL); const int kMaxBufferSize = 4096; switch (provider->ConsumeEnum()) { case kCdcNConnected: // TODO: Fuzz interface number (void)tud_cdc_n_connected(0); break; case kCdcNGetLineState: // TODO: Fuzz interface number (void)tud_cdc_n_get_line_state(0); break; case kCdcNGetLineCoding: { cdc_line_coding_t coding; // TODO: Fuzz interface number (void)tud_cdc_n_get_line_coding(0, &coding); } break; case kCdcNSetWantedChar: // TODO: Fuzz interface number (void)tud_cdc_n_set_wanted_char(0, provider->ConsumeIntegral()); break; case kCdcNAvailable: // TODO: Fuzz interface number (void)tud_cdc_n_available(0); break; case kCdcNRead: { std::vector buffer; buffer.resize(provider->ConsumeIntegralInRange(0, kMaxBufferSize)); // TODO: Fuzz interface number (void)tud_cdc_n_read(0, buffer.data(), buffer.size()); break; } case kCdcNReadChar: // TODO: Fuzz interface number tud_cdc_n_read_char(0); break; case kCdcNReadFlush: // TODO: Fuzz interface number tud_cdc_n_read_flush(0); break; case kCdcNPeek: { uint8_t peak = 0; tud_cdc_n_peek(0, &peak); break; } case kCdcNWrite: { std::vector buffer = provider->ConsumeBytes( provider->ConsumeIntegralInRange(0, kMaxBufferSize)); // TODO: Fuzz interface number (void)tud_cdc_n_write(0, buffer.data(), buffer.size()); } break; case kCdcNWriteChar: // TODO: Fuzz interface number (void)tud_cdc_n_write_char(0, provider->ConsumeIntegral()); break; case kCdcNWriteStr: { std::string str = provider->ConsumeRandomLengthString(kMaxBufferSize); // TODO: Fuzz interface number (void)tud_cdc_n_write_str(0, str.c_str()); break; } case kCdcNWriteFlush: // TODO: Fuzz interface number (void)tud_cdc_n_write_flush(0); break; case kCdcNWriteAvailable: // TODO: Fuzz interface number (void)tud_cdc_n_write_available(0); break; case kCdcNWriteClear: // TODO: Fuzz interface number (void)tud_cdc_n_write_clear(0); break; case kMaxValue: // Noop. break; } } } ================================================ FILE: test/fuzz/device/cdc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: test/fuzz/device/cdc/src/usb_descriptors.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save * device driver after the first plug. * Auto ProductID layout's Bitmap: * [MSB] HID | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ (0x4000 | PID_MAP(CDC, 0) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | \ PID_MAP(VENDOR, 4)) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and // protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01}; return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data // address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and // other_speed_configuration // high speed configuration uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data // address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), }; // other speed configuration uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change // configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00}; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete. device_qualifier descriptor describes // information about a high-speed capable device that would change if the device // were operating at the other speed. If not highspeed capable stall this // request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *)&desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete Configuration descriptor in the other speed // e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void)index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // array of pointer to string descriptors char const *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456789012", // 3: Serials, should use chip ID "TinyUSB CDC", // 4: CDC Interface }; static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; uint8_t chr_count; if (index == 0) { memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; } else { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = (uint8_t)strlen(str); if (chr_count > 31) chr_count = 31; // Convert ASCII string into UTF-16 for (uint8_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: test/fuzz/device/msc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.5) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(msc) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: test/fuzz/device/msc/Makefile ================================================ include ../../make.mk INC += \ src \ # Example source SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.c)) SRC_CXX += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.cc)) include ../../rules.mk ================================================ FILE: test/fuzz/device/msc/src/fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 #include #include #include #include #include "class/cdc/cdc_device.h" #include "fuzz/fuzz.h" #include "tusb.h" #include #include #include //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ #define FUZZ_ITERATIONS 500 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { FuzzedDataProvider provider(Data, Size); std::vector callback_data = provider.ConsumeBytes( provider.ConsumeIntegralInRange(0, Size)); fuzz_init(callback_data.data(), callback_data.size()); tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); for (int i = 0; i < FUZZ_ITERATIONS; i++) { if (provider.remaining_bytes() == 0) { return 0; } tud_int_handler(provider.ConsumeIntegral()); tud_task(); // tinyusb device task } return 0; } ================================================ FILE: test/fuzz/device/msc/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 0 #define CFG_TUD_MSC 1 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: test/fuzz/device/msc/src/usb_descriptors.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save * device driver after the first plug. * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ (0x4000 | PID_MAP(MSC, 0) | PID_MAP(HID, 1) | PID_MAP(MIDI, 2) | \ PID_MAP(VENDOR, 3)) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { tu_static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and // protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01}; return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_MSC = 0, ITF_NUM_TOTAL }; #define EPNUM_MSC_OUT 0x05 #define EPNUM_MSC_IN 0x85 #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) // full speed configuration uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 4, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and // other_speed_configuration // high speed configuration uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 4, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512), }; // other speed configuration uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change // configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00}; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete. device_qualifier descriptor describes // information about a high-speed capable device that would change if the device // were operating at the other speed. If not highspeed capable stall this // request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *)&desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete Configuration descriptor in the other speed // e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void)index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // array of pointer to string descriptors char const *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456789012", // 3: Serials, should use chip ID "TinyUSB MSC", // 4: MSC Interface }; tu_static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; uint8_t chr_count; if (index == 0) { memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; } else { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = (uint8_t)strlen(str); if (chr_count > 31) chr_count = 31; // Convert ASCII string into UTF-16 for (uint8_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: test/fuzz/device/net/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.5) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) project(net) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) add_executable(${PROJECT_NAME}) # Example source target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c ) # Example include target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT_NAME} noos) ================================================ FILE: test/fuzz/device/net/Makefile ================================================ include ../../make.mk # suppress warning caused by lwip CFLAGS += \ -Wno-error=null-dereference \ -Wno-error=unused-parameter \ -Wno-error=unused-variable INC += \ src \ $(TOP)/lib/lwip/src/include \ $(TOP)/lib/lwip/src/include/ipv4 \ $(TOP)/lib/lwip/src/include/lwip/apps \ $(TOP)/lib/networking # Example source SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.c)) SRC_CXX += $(addprefix $(EXAMPLE_PATH)/, $(wildcard src/*.cc)) # lwip sources SRC_C += \ lib/lwip/src/core/altcp.c \ lib/lwip/src/core/altcp_alloc.c \ lib/lwip/src/core/altcp_tcp.c \ lib/lwip/src/core/def.c \ lib/lwip/src/core/dns.c \ lib/lwip/src/core/inet_chksum.c \ lib/lwip/src/core/init.c \ lib/lwip/src/core/ip.c \ lib/lwip/src/core/mem.c \ lib/lwip/src/core/memp.c \ lib/lwip/src/core/netif.c \ lib/lwip/src/core/pbuf.c \ lib/lwip/src/core/raw.c \ lib/lwip/src/core/stats.c \ lib/lwip/src/core/sys.c \ lib/lwip/src/core/tcp.c \ lib/lwip/src/core/tcp_in.c \ lib/lwip/src/core/tcp_out.c \ lib/lwip/src/core/timeouts.c \ lib/lwip/src/core/udp.c \ lib/lwip/src/core/ipv4/autoip.c \ lib/lwip/src/core/ipv4/dhcp.c \ lib/lwip/src/core/ipv4/etharp.c \ lib/lwip/src/core/ipv4/icmp.c \ lib/lwip/src/core/ipv4/igmp.c \ lib/lwip/src/core/ipv4/ip4.c \ lib/lwip/src/core/ipv4/ip4_addr.c \ lib/lwip/src/core/ipv4/ip4_frag.c \ lib/lwip/src/core/ipv6/dhcp6.c \ lib/lwip/src/core/ipv6/ethip6.c \ lib/lwip/src/core/ipv6/icmp6.c \ lib/lwip/src/core/ipv6/inet6.c \ lib/lwip/src/core/ipv6/ip6.c \ lib/lwip/src/core/ipv6/ip6_addr.c \ lib/lwip/src/core/ipv6/ip6_frag.c \ lib/lwip/src/core/ipv6/mld6.c \ lib/lwip/src/core/ipv6/nd6.c \ lib/lwip/src/netif/ethernet.c \ lib/lwip/src/netif/slipif.c \ lib/lwip/src/apps/http/httpd.c \ lib/lwip/src/apps/http/fs.c \ lib/networking/dhserver.c \ lib/networking/dnserver.c \ lib/networking/rndis_reports.c include ../../rules.mk ================================================ FILE: test/fuzz/device/net/src/arch/cc.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels * */ #ifndef __CC_H__ #define __CC_H__ //#include "cpu.h" typedef int sys_prot_t; /* define compiler specific symbols */ #if defined (__ICCARM__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_USE_INCLUDES #elif defined (__CC_ARM) #define PACK_STRUCT_BEGIN __packed #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #elif defined (__GNUC__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #elif defined (__TASKING__) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x #endif #define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) #endif /* __CC_H__ */ ================================================ FILE: test/fuzz/device/net/src/fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 #include #include #include #include #include "class/cdc/cdc_device.h" #include "class/net/net_device.h" #include "fuzz/fuzz.h" #include "tusb.h" #include #include #include extern "C" { #define FUZZ_ITERATIONS 500 //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void net_task(FuzzedDataProvider *provider); extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { FuzzedDataProvider provider(Data, Size); std::vector callback_data = provider.ConsumeBytes( provider.ConsumeIntegralInRange(0, Size)); fuzz_init(callback_data.data(), callback_data.size()); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); for (int i = 0; i < FUZZ_ITERATIONS; i++) { if (provider.remaining_bytes() == 0) { return 0; } tud_int_handler(provider.ConsumeIntegral()); tud_task(); // tinyusb device task net_task(&provider); } return 0; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ enum NetApiFuncs { kNetworkRecvRenew, kNetworkCanXmit, kNetworkXmit, kMaxValue, }; void net_task(FuzzedDataProvider *provider) { assert(provider != NULL); switch (provider->ConsumeEnum()) { case kNetworkRecvRenew: tud_network_recv_renew(); break; case kNetworkCanXmit: (void)tud_network_can_xmit(provider->ConsumeIntegral()); case kNetworkXmit: // TODO: Actually pass real values here later. tud_network_xmit(NULL, 0); case kMaxValue: // Noop. break; } } } ================================================ FILE: test/fuzz/device/net/src/lwipopts.h ================================================ /* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Simon Goldschmidt * */ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ /* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ #define NO_SYS 1 #define MEM_ALIGNMENT 4 #define LWIP_RAW 0 #define LWIP_NETCONN 0 #define LWIP_SOCKET 0 #define LWIP_DHCP 0 #define LWIP_ICMP 1 #define LWIP_UDP 1 #define LWIP_TCP 1 #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 TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) #define TCP_SND_BUF (2 * TCP_MSS) #define TCP_WND (TCP_MSS) #define ETHARP_SUPPORT_STATIC_ENTRIES 1 #define LWIP_HTTPD_CGI 0 #define LWIP_HTTPD_SSI 0 #define LWIP_HTTPD_SSI_INCLUDE_TAG 0 #define LWIP_SINGLE_NETIF 1 #define PBUF_POOL_SIZE 2 #define HTTPD_USE_CUSTOM_FSDATA 0 #define LWIP_MULTICAST_PING 1 #define LWIP_BROADCAST_PING 1 #define LWIP_IPV6_MLD 0 #define LWIP_IPV6_SEND_ROUTER_SOLICIT 0 #endif /* __LWIPOPTS_H__ */ ================================================ FILE: test/fuzz/device/net/src/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- // Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack #define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled #define CFG_TUD_ECM_RNDIS 1 #define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. // Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: test/fuzz/device/net/src/usb_descriptors.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Ha Thach (tinyusb.org) * * 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 "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save * device driver after the first plug. * Auto ProductID layout's Bitmap: * [MSB] HID | CDC [LSB] */ #define PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) #define USB_PID \ (0x4000 | PID_MAP(CDC, 0) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | \ PID_MAP(VENDOR, 4)) #define USB_VID 0xCafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const *tud_descriptor_device_cb(void) { tu_static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and // protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01}; return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration uint8_t const desc_fs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data // address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and // other_speed_configuration // high speed configuration uint8_t const desc_hs_configuration[] = { // Config number, interface count, string index, total length, attribute, // power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP notification address and size, EP data // address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), }; // other speed configuration uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; // device qualifier is mostly similar to device descriptor since we don't change // configuration based on speed tusb_desc_device_qualifier_t const desc_device_qualifier = { .bLength = sizeof(tusb_desc_device_qualifier_t), .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, .bcdUSB = USB_BCD, .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bNumConfigurations = 0x01, .bReserved = 0x00}; // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete. device_qualifier descriptor describes // information about a high-speed capable device that would change if the device // were operating at the other speed. If not highspeed capable stall this // request. uint8_t const *tud_descriptor_device_qualifier_cb(void) { return (uint8_t const *)&desc_device_qualifier; } // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete Configuration descriptor in the other speed // e.g if high speed then this is for full speed and vice versa uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) { (void)index; // for multiple configurations // if link speed is high return fullspeed config, and vice versa // Note: the descriptor type is OTHER_SPEED_CONFIG instead of CONFIG memcpy(desc_other_speed_config, (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration, CONFIG_TOTAL_LEN); desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG; return desc_other_speed_config; } #endif // highspeed // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { (void)index; // for multiple configurations #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration; #else return desc_fs_configuration; #endif } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ // array of pointer to string descriptors char const *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456789012", // 3: Serials, should use chip ID "TinyUSB CDC", // 4: CDC Interface }; tu_static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long // enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void)langid; uint8_t chr_count; if (index == 0) { memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; } else { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; const char *str = string_desc_arr[index]; // Cap at max char chr_count = (uint8_t)strlen(str); if (chr_count > 31) chr_count = 31; // Convert ASCII string into UTF-16 for (uint8_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } } // first byte is length (including header), second byte is string type _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } ================================================ FILE: test/fuzz/dicts/cdc.dict ================================================ # List of supported OIDs RNDIS_OID_GEN_SUPPORTED_LIST="\x00\x01\x01\x01" # Hardware status RNDIS_OID_GEN_HARDWARE_STATUS="\x00\x01\x01\x02" # Media types supported (encoded) RNDIS_OID_GEN_MEDIA_SUPPORTED="\x00\x01\x01\x03" # Media types in use (encoded) RNDIS_OID_GEN_MEDIA_IN_USE="\x00\x01\x01\x04" RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD="\x00\x01\x01\x05" # Maximum frame size in bytes RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE="\x00\x01\x01\x06" # Link speed in units of 100 bps RNDIS_OID_GEN_LINK_SPEED="\x00\x01\x01\x07" # Transmit buffer space RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE="\x00\x01\x01\x08" # Receive buffer space RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE="\x00\x01\x01\x09" # NDIS version number used by the driver RNDIS_OID_GEN_DRIVER_VERSION="\x00\x01\x01\x10" # Maximum total packet length in bytes RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE="\x00\x01\x01\x11" # Optional protocol flags (encoded) RNDIS_OID_GEN_PROTOCOL_OPTIONS="\x00\x01\x01\x12" # Optional NIC flags (encoded) RNDIS_OID_GEN_MAC_OPTIONS="\x00\x01\x01\x13" # Whether the NIC is connected to the network RNDIS_OID_GEN_MEDIA_CONNECT_STATUS="\x00\x01\x01\x14" # The maximum number of send packets the driver can accept per call to its MiniportSendPacketsfunction RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS="\x00\x01\x01\x15" # Vendor-assigned version number of the driver RNDIS_OID_GEN_VENDOR_DRIVER_VERSION="\x00\x01\x01\x16" # The custom GUIDs (Globally Unique Identifier) supported by the miniport driver RNDIS_OID_GEN_SUPPORTED_GUIDS="\x00\x01\x01\x17" # List of network-layer addresses associated with the binding between a transport and the driver RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES="\x00\x01\x01\x18" # Size of packets' additional headers RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET="\x00\x01\x01\x19" RNDIS_OID_GEN_MEDIA_CAPABILITIES="\x00\x01\x02\x01" # Physical media supported by the miniport driver (encoded) RNDIS_OID_GEN_PHYSICAL_MEDIUM="\x00\x01\x02\x02" # Permanent station address RNDIS_OID_802_3_PERMANENT_ADDRESS="\x01\x01\x01\x01" # Current station address RNDIS_OID_802_3_CURRENT_ADDRESS="\x01\x01\x01\x02" # Current multicast address list RNDIS_OID_802_3_MULTICAST_LIST="\x01\x01\x01\x03" # Maximum size of multicast address list RNDIS_OID_802_3_MAXIMUM_LIST_SIZE="\x01\x01\x01\x04" # Directed packets. Directed packets contain a destination address equal to the station address of the NIC. RNDIS_PACKET_TYPE_DIRECTED="\x00\x00\x00\x01" # Multicast address packets sent to addresses in the multicast address list. RNDIS_PACKET_TYPE_MULTICAST="\x00\x00\x00\x02" # All multicast address packets, not just the ones enumerated in the multicast address list. RNDIS_PACKET_TYPE_ALL_MULTICAST="\x00\x00\x00\x04" # Broadcast packets. RNDIS_PACKET_TYPE_BROADCAST="\x00\x00\x00\x08" # All source routing packets. If the protocol driver sets this bit, the NDIS library attempts to act as a source routing bridge. RNDIS_PACKET_TYPE_SOURCE_ROUTING="\x00\x00\x00\x10" # Specifies all packets regardless of whether VLAN filtering is enabled or not and whether the VLAN identifier matches or not. RNDIS_PACKET_TYPE_PROMISCUOUS="\x00\x00\x00\x20" # SMT packets that an FDDI NIC receives. RNDIS_PACKET_TYPE_SMT="\x00\x00\x00\x40" # All packets sent by installed protocols and all packets indicated by the NIC that is identified by a given NdisBindingHandle. RNDIS_PACKET_TYPE_ALL_LOCAL="\x00\x00\x00\x80" # Packets sent to the current group address. RNDIS_PACKET_TYPE_GROUP="\x00\x00\x10\x00" # All functional address packets, not just the ones in the current functional address. RNDIS_PACKET_TYPE_ALL_FUNCTIONAL="\x00\x00\x20\x00" # Functional address packets sent to addresses included in the current functional address. RNDIS_PACKET_TYPE_FUNCTIONAL="\x00\x00\x40\x00" # NIC driver frames that a Token Ring NIC receives. RNDIS_PACKET_TYPE_MAC_FRAME="\x00\x00\x80\x00" RNDIS_PACKET_TYPE_NO_LOCAL="\x00\x01\x00\x00" ================================================ FILE: test/fuzz/fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "fuzzer/FuzzedDataProvider.h" #include std::optional _fuzz_data_provider; extern "C" int fuzz_init(const uint8_t *data, size_t size) { _fuzz_data_provider.emplace(data, size); return 0; } ================================================ FILE: test/fuzz/fuzz.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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. * */ #pragma once #include #ifdef __cplusplus extern "C" { #endif int fuzz_init(const uint8_t *data, size_t size); #ifdef __cplusplus } #endif ================================================ FILE: test/fuzz/fuzz_private.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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. * */ #pragma once #include "fuzzer/FuzzedDataProvider.h" #include extern std::optional _fuzz_data_provider; ================================================ FILE: test/fuzz/make.mk ================================================ # --------------------------------------- # Common make definition for all examples # --------------------------------------- #-------------- TOP and EXAMPLE_PATH ------------ # Set TOP to be the path to get from the current directory (where make was # invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns # the name of this makefile relative to where make was invoked. THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) # strip off /tools/top.mk to get for example ../../.. # and Set TOP to an absolute path TOP = $(abspath $(subst make.mk,../..,$(THIS_MAKEFILE))) # Set EXAMPLE_PATH to the relative path from TOP to the current directory, ie examples/device/cdc_msc_freertos EXAMPLE_PATH = $(subst $(TOP)/,,$(abspath .)) # Detect whether shell style is windows or not # https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069 ifeq '$(findstring ;,$(PATH))' ';' # PATH contains semicolon - so we're definitely on Windows. CMDEXE := 1 # makefile shell commands should use syntax for DOS CMD, not unix sh # Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax. # We can't just use sh, because while sh and/or bash shell may be available, # many Windows environments won't have utilities like realpath used below, so... # Force DOS command shell on Windows. SHELL := cmd.exe endif # Build directory BUILD := _build PROJECT := $(notdir $(CURDIR)) # Handy check parameter function check_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2))))) __check_defined = \ $(if $(value $1),, \ $(error Undefined make flag: $1$(if $2, ($2)))) #-------------- Fuzz harness compiler ------------ CC ?= clang CXX ?= clang++ GDB ?= gdb OBJCOPY = objcopy SIZE = size MKDIR = mkdir ifeq ($(CMDEXE),1) CP = copy RM = del PYTHON = python else SED = sed CP = cp RM = rm PYTHON = python3 endif #-------------- Fuzz harness flags ------------ COVERAGE_FLAGS ?= -fsanitize-coverage=trace-pc-guard SANITIZER_FLAGS ?= -fsanitize=fuzzer \ -fsanitize=address CFLAGS += $(COVERAGE_FLAGS) $(SANITIZER_FLAGS) #-------------- Source files and compiler flags -------------- INC += $(TOP)/test # Compiler Flags CFLAGS += \ -ggdb \ -fdata-sections \ -ffunction-sections \ -fno-strict-aliasing \ -Wall \ -Wextra \ -Werror \ -Wfatal-errors \ -Wdouble-promotion \ -Wstrict-prototypes \ -Wstrict-overflow \ -Werror-implicit-function-declaration \ -Wfloat-equal \ -Wundef \ -Wshadow \ -Wwrite-strings \ -Wsign-compare \ -Wmissing-format-attribute \ -Wunreachable-code \ -Wcast-align \ -Wcast-qual \ -Wnull-dereference \ -Wuninitialized \ -Wunused \ -Wredundant-decls \ -O1 CFLAGS += \ -Wno-error=unreachable-code \ -DOPT_MCU_FUZZ=1 \ -DCFG_TUSB_MCU=OPT_MCU_FUZZ \ -D_FUZZ CXXFLAGS += \ -xc++ \ -Wno-c++11-narrowing \ -fno-implicit-templates # conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion # -Wconversion # Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -Og else CFLAGS += $(CFLAGS_OPTIMIZED) endif # Log level is mapped to TUSB DEBUG option ifneq ($(LOG),) CFLAGS += -DCFG_TUSB_DEBUG=$(LOG) endif ================================================ FILE: test/fuzz/msc_fuzz.cc ================================================ #include "fuzz/fuzz_private.h" #include "tusb.h" #include #include #include #if CFG_TUD_MSC==1 // Whether host does safe eject. // tud_msc_get_maxlun_cb returns a uint8_t so the max logical units that are // allowed is 255, so we need to keep track of 255 fuzzed logical units. static std::array::max()> ejected = {false}; extern "C" { // Invoked when received SCSI_CMD_INQUIRY // Application fill vendor id, product id and revision with string up to 8, 16, // 4 characters respectively void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { (void)lun; assert(_fuzz_data_provider.has_value()); std::string vid = _fuzz_data_provider->ConsumeBytesAsString(8); std::string pid = _fuzz_data_provider->ConsumeBytesAsString(16); std::string rev = _fuzz_data_provider->ConsumeBytesAsString(4); memcpy(vendor_id, vid.c_str(), strlen(vid.c_str())); memcpy(product_id, pid.c_str(), strlen(pid.c_str())); memcpy(product_rev, rev.c_str(), strlen(rev.c_str())); } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { // RAM disk is ready until ejected if (ejected[lun]) { // Additional Sense 3A-00 is NOT_FOUND tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); return false; } return _fuzz_data_provider->ConsumeBool(); } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and // SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size Application update // block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { (void)lun; *block_count = _fuzz_data_provider->ConsumeIntegral(); *block_size = _fuzz_data_provider->ConsumeIntegral(); } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void)power_condition; assert(_fuzz_data_provider.has_value()); if (load_eject) { if (start) { // load disk storage } else { // unload disk storage ejected[lun] = true; } } return _fuzz_data_provider->ConsumeBool(); } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { assert(_fuzz_data_provider.has_value()); (void)lun; (void)lba; (void)offset; std::vector consumed_buffer = _fuzz_data_provider->ConsumeBytes( _fuzz_data_provider->ConsumeIntegralInRange(0, bufsize)); memcpy(buffer, consumed_buffer.data(), consumed_buffer.size()); // Sometimes return an error code; if (_fuzz_data_provider->ConsumeBool()) { return _fuzz_data_provider->ConsumeIntegralInRange( std::numeric_limits::min(), -1); } return consumed_buffer.size(); } bool tud_msc_is_writable_cb(uint8_t lun) { assert(_fuzz_data_provider.has_value()); (void)lun; return _fuzz_data_provider->ConsumeBool(); } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) { // Ignore these as they are outputs and don't affect the return value. (void)lun; (void)lba; (void)offset; (void)buffer; assert(_fuzz_data_provider.has_value()); // -ve error codes -> bufsize. return _fuzz_data_provider->ConsumeIntegralInRange( std::numeric_limits::min(), bufsize); } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { (void)buffer; (void)bufsize; assert(_fuzz_data_provider.has_value()); switch (scsi_cmd[0]) { case SCSI_CMD_TEST_UNIT_READY: break; case SCSI_CMD_INQUIRY: break; case SCSI_CMD_MODE_SELECT_6: break; case SCSI_CMD_MODE_SENSE_6: break; case SCSI_CMD_START_STOP_UNIT: break; case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: break; case SCSI_CMD_READ_CAPACITY_10: break; case SCSI_CMD_REQUEST_SENSE: break; case SCSI_CMD_READ_FORMAT_CAPACITY: break; case SCSI_CMD_READ_10: break; case SCSI_CMD_WRITE_10: break; default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); return _fuzz_data_provider->ConsumeIntegralInRange( std::numeric_limits::min(), -1); } return 0; } } #endif ================================================ FILE: test/fuzz/net_fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "tusb_config.h" #if defined(CFG_TUD_ECM_RNDIS) || defined(CFG_TUD_NCM) #include "class/net/net_device.h" #include "fuzz_private.h" #include #include #include #include "lwip/sys.h" extern "C" { bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { assert(_fuzz_data_provider.has_value()); (void)src; (void)size; return _fuzz_data_provider->ConsumeBool(); } // client must provide this: copy from network stack packet pointer to dst uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { (void)ref; (void)arg; assert(_fuzz_data_provider.has_value()); uint16_t size = _fuzz_data_provider->ConsumeIntegral(); std::vector temp = _fuzz_data_provider->ConsumeBytes(size); memcpy(dst, temp.data(), temp.size()); return size; } /* lwip has provision for using a mutex, when applicable */ sys_prot_t sys_arch_protect(void) { return 0; } void sys_arch_unprotect(sys_prot_t pval) { (void)pval; } //------------- ECM/RNDIS -------------// // client must provide this: initialize any network state back to the beginning void tud_network_init_cb(void) { // NoOp. } // client must provide this: 48-bit MAC address // TODO removed later since it is not part of tinyusb stack uint8_t tud_network_mac_address[6] = {0}; } // extern "C" #endif ================================================ FILE: test/fuzz/rules.mk ================================================ # --------------------------------------- # Common make rules for all examples # --------------------------------------- # Set all as default goal .DEFAULT_GOAL := all # --------------------------------------- # Compiler Flags # --------------------------------------- LIBS_GCC ?= -lm # libc LIBS += $(LIBS_GCC) ifneq ($(BOARD), spresense) LIBS += -lc -Wl,-Bstatic -lc++ -Wl,-Bdynamic endif # TinyUSB Stack source SRC_C += \ src/tusb.c \ src/common/tusb_fifo.c \ src/device/usbd.c \ src/device/usbd_control.c \ src/class/audio/audio_device.c \ src/class/cdc/cdc_device.c \ src/class/dfu/dfu_device.c \ src/class/dfu/dfu_rt_device.c \ src/class/hid/hid_device.c \ src/class/midi/midi_device.c \ src/class/msc/msc_device.c \ src/class/mtp/mtp_device.c \ src/class/printer/printer_device.c \ src/class/net/ecm_rndis_device.c \ src/class/net/ncm_device.c \ src/class/usbtmc/usbtmc_device.c \ src/class/video/video_device.c \ src/class/vendor/vendor_device.c # Fuzzers are c++ SRC_CXX += \ test/fuzz/dcd_fuzz.cc \ test/fuzz/fuzz.cc \ test/fuzz/msc_fuzz.cc \ test/fuzz/net_fuzz.cc \ test/fuzz/usbd_fuzz.cc # TinyUSB stack include INC += $(TOP)/src CFLAGS += $(addprefix -I,$(INC)) CXXFLAGS += -std=c++17 # LTO makes it difficult to analyze map file for optimizing size purpose # We will run this option in ci ifeq ($(NO_LTO),1) CFLAGS := $(filter-out -flto,$(CFLAGS)) endif ifneq ($(LD_FILE),) LDFLAGS_LD_FILE ?= -Wl,-T,$(TOP)/$(LD_FILE) endif LDFLAGS += $(CFLAGS) $(LDFLAGS_LD_FILE) -fuse-ld=lld -Wl,-Map=$@.map -Wl,--cref -Wl,-gc-sections ifneq ($(SKIP_NANOLIB), 1) endif ASFLAGS += $(CFLAGS) # Assembly files can be name with upper case .S, convert it to .s SRC_S := $(SRC_S:.S=.s) # Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 # assembly file should be placed first in linking order # '_asm' suffix is added to object of assembly file OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=_asm.o)) OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/obj/, $(SRC_CXX:.cc=_cxx.o)) # Verbose mode ifeq ("$(V)","1") $(info CFLAGS $(CFLAGS) ) $(info ) $(info LDFLAGS $(LDFLAGS)) $(info ) $(info ASFLAGS $(ASFLAGS)) $(info ) endif # --------------------------------------- # Rules # --------------------------------------- all: $(BUILD)/$(PROJECT) OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) $(OBJ_DIRS): ifeq ($(CMDEXE),1) @$(MKDIR) $(subst /,\,$@) else @$(MKDIR) -p $@ endif $(BUILD)/$(PROJECT): $(OBJ) @echo LINK $@ @ $(CXX) -o $@ $(LIB_FUZZING_ENGINE) $^ $(LIBS) $(LDFLAGS) # We set vpath to point to the top of the tree so that the source files # can be located. By following this scheme, it allows a single build rule # to be used to compile all .c files. vpath %.c . $(TOP) $(BUILD)/obj/%.o: %.c @echo CC $(notdir $@) @$(CC) $(CFLAGS) -c -MD -o $@ $< # All cpp srcs vpath %.cc . $(TOP) $(BUILD)/obj/%_cxx.o: %.cc @echo CXX $(notdir $@) @$(CXX) $(CFLAGS) $(CXXFLAGS) -c -MD -o $@ $< # ASM sources lower case .s vpath %.s . $(TOP) $(BUILD)/obj/%_asm.o: %.s @echo AS $(notdir $@) @$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< # ASM sources upper case .S vpath %.S . $(TOP) $(BUILD)/obj/%_asm.o: %.S @echo AS $(notdir $@) @$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< .PHONY: clean clean: ifeq ($(CMDEXE),1) rd /S /Q $(subst /,\,$(BUILD)) else $(RM) -rf $(BUILD) endif # ---------------- GNU Make End ----------------------- # get depenecies .PHONY: get-deps get-deps: $(PYTHON) $(TOP)/tools/get_deps.py $(FAMILY) size: $(BUILD)/$(PROJECT) -@echo '' @$(SIZE) $< -@echo '' # linkermap must be install previously at https://github.com/hathach/linkermap linkermap: $(BUILD)/$(PROJECT) @linkermap -v $<.map # Print out the value of a make variable. # https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile print-%: @echo $* = $($*) ================================================ FILE: test/fuzz/usbd_fuzz.cc ================================================ /* * The MIT License (MIT) * * Copyright (c) 2022 Nathaniel Brough * * 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 "fuzz/fuzz_private.h" #include "tusb.h" // #include "usb_descriptors.h" #ifndef CFG_FUZZ_MAX_STRING_LEN #define CFG_FUZZ_MAX_STRING_LEN 1000 #endif extern "C" { /* TODO: Implement a fuzzed version of this. uint8_t const *tud_descriptor_bos_cb(void) { } */ /* TODO: Implement a fuzzed version of this. uint8_t const *tud_descriptor_device_qualifier_cb(void) {} */ /* TODO: Implement a fuzzed version of this. uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {} */ void tud_mount_cb(void) { // NOOP } void tud_umount_cb(void) { // NOOP } void tud_suspend_cb(bool remote_wakeup_en) { (void)remote_wakeup_en; // NOOP } void tud_resume_cb(void) { // NOOP } /* TODO: Implement a fuzzed version of this. bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) {} */ /* TODO: Implement a fuzzed version of this. uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {} */ } ================================================ FILE: test/hil/hfp.json ================================================ { "boards": [ { "name": "stm32l412nucleo", "uid": "41003B000E504E5457323020", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "774470029", "args": "-device STM32L412KB" } }, { "name": "stm32f746disco", "uid": "210041000C51343237303334", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "770935966", "args": "-device STM32F746NG" } }, { "name": "lpcxpresso43s67", "uid": "08F000044528BAAA8D858F58C50700F5", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "728973776", "args": "-device LPC43S67_M4" } } ] } ================================================ FILE: test/hil/hil_ci_set_matrix.py ================================================ import argparse import json import os def main(): parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') args = parser.parse_args() config_file = args.config_file # if config file is not found, try to find it in the same directory as this script if not os.path.exists(config_file): config_file = os.path.join(os.path.dirname(__file__), config_file) with open(config_file) as f: config = json.load(f) matrix = { 'arm-gcc': [], 'esp-idf': [] } for board in config['boards']: name = board['name'] flasher = board['flasher'] if flasher['name'] == 'esptool': toolchain = 'esp-idf' else: toolchain = 'arm-gcc' build_board = f'-b {name}' if 'build' in board: if 'args' in board['build']: build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) if 'flags_on' in board['build']: for f in board['build']['flags_on']: if f == '': matrix[toolchain].append(build_board) else: matrix[toolchain].append(f'{build_board} -f1 {f.replace(" ", " -f1 ")}') else: matrix[toolchain].append(build_board) else: matrix[toolchain].append(build_board) print(json.dumps(matrix)) if __name__ == '__main__': main() ================================================ FILE: test/hil/hil_test.py ================================================ #!/usr/bin/env python3 # # The MIT License (MIT) # # Copyright (c) 2023 HiFiPhile # # 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. # udev rules : # ACTION=="add", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", SYMLINK+="ttyUSB_%c.%s{bInterfaceNumber}" # ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ENV{ID_FS_USAGE}=="filesystem", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/blkUSB_%c.%s{bInterfaceNumber}" import argparse import os import random import re import sys import time import warnings # Suppress pkg_resources deprecation warning from fs module warnings.filterwarnings("ignore", message="pkg_resources is deprecated") # Suppress pyfatfs unclean unmount warning warnings.filterwarnings("ignore", message="Filesystem was not cleanly unmounted") import serial import subprocess import json import glob from multiprocessing import Pool import fs import hashlib import ctypes from pymtp import MTP import string ENUM_TIMEOUT = 30 STATUS_OK = "\033[32mOK\033[0m" STATUS_FAILED = "\033[31mFailed\033[0m" STATUS_SKIPPED = "\033[33mSkipped\033[0m" verbose = False test_only = [] build_dir = 'cmake-build' WCH_RISCV_CONTENT = """ adapter driver wlinke adapter speed 6000 transport select sdi wlink_set_address 0x00000000 set _CHIPNAME wch_riscv sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME $_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 echo "Ready for Remote Connections" """ MSC_README_TXT = \ b"This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ issue at github.com/hathach/tinyusb" # ------------------------------------------------------------- # Path # ------------------------------------------------------------- OPENCOD_ADI_PATH = f'{os.getenv("HOME")}/app/openocd_adi' TINYUSB_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # get usb serial by id def get_serial_dev(id, vendor_str, product_str, ifnum): if vendor_str and product_str: # known vendor and product vendor_str = vendor_str.replace(' ', '_') product_str = product_str.replace(' ', '_') return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}' else: # just use id: mostly for cp210x/ftdi flasher pattern = f'/dev/serial/by-id/usb-*_{id}-if*' port_list = glob.glob(pattern) return port_list[0] # get usb disk by id def get_disk_dev(id, vendor_str, lun): return f'/dev/disk/by-id/usb-{vendor_str}_Mass_Storage_{id}-0:{lun}' def get_hid_dev(id, vendor_str, product_str, event): return f'/dev/input/by-id/usb-{vendor_str}_{product_str}_{id}-{event}' def open_serial_dev(port): timeout = ENUM_TIMEOUT ser = None while timeout > 0: if os.path.exists(port): try: ser = serial.Serial(port, baudrate=115200, timeout=5) break except serial.SerialException: print(f'serial {port} not reaady {timeout} sec') pass time.sleep(0.1) timeout -= 0.1 assert timeout > 0, f'Cannot open port f{port}' if os.path.exists(port) else f'Port {port} not existed' return ser def read_disk_file(uid, lun, fname): # open_fs("fat://{dev}) require 'pip install pyfatfs' dev = get_disk_dev(uid, 'TinyUSB', lun) timeout = ENUM_TIMEOUT while timeout > 0: if os.path.exists(dev): fat = fs.open_fs(f'fat://{dev}?read_only=true') try: with fat.open(fname, 'rb') as f: data = f.read() finally: fat.close() assert data, f'Cannot read file {fname} from {dev}' return data time.sleep(1) timeout -= 1 assert timeout > 0, f'Storage {dev} not existed' return None def open_mtp_dev(uid): mtp = MTP() # MTP seems to take a while to enumerate timeout = 2 * ENUM_TIMEOUT while timeout > 0: # unmount gio/gvfs MTP mount which blocks libmtp from accessing the device subprocess.run(f"gio mount -u mtp://TinyUsb_TinyUsb_Device_{uid}/", shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) for raw in mtp.detect_devices(): mtp.device = mtp.mtp.LIBMTP_Open_Raw_Device(ctypes.byref(raw)) if mtp.device: sn = mtp.get_serialnumber().decode('utf-8') if sn == uid: return mtp mtp.disconnect() time.sleep(1) timeout -= 1 return None def get_printer_dev(id, vendor_str, product_str, ifnum): """Find /dev/usb/lpX by matching USB serial, vendor, product, and interface number via sysfs""" vendor_str = vendor_str.replace(' ', '_') if vendor_str else '' product_str = product_str.replace(' ', '_') if product_str else '' for lp in glob.glob('/sys/class/usbmisc/lp*'): try: sn = open(f'{lp}/device/../serial').read().strip() if sn == id: return f'/dev/usb/{os.path.basename(lp)}' except (FileNotFoundError, PermissionError, ValueError): pass return None def open_printer_dev(id, vendor_str, product_str, ifnum): """Wait for printer device to enumerate and return its path""" timeout = ENUM_TIMEOUT while timeout > 0: lp_dev = get_printer_dev(id, vendor_str, product_str, ifnum) if lp_dev and os.path.exists(lp_dev): return lp_dev time.sleep(1) timeout -= 1 assert False, f'Printer device not found for {id} if{ifnum:02d}' # ------------------------------------------------------------- # Flashing firmware # ------------------------------------------------------------- def run_cmd(cmd, cwd=None): r = subprocess.run(cmd, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: title = f'COMMAND FAILED: {cmd}' print() if os.getenv('CI'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) print(f"::endgroup::") else: print(title) print(r.stdout.decode("utf-8")) elif verbose: print(cmd) print(r.stdout.decode("utf-8")) return r def flash_jlink(board, firmware): flasher = board['flasher'] script = ['halt', 'r', f'loadfile {firmware}.elf', 'r', 'go', 'exit'] f_jlink = f'{board["name"]}_{os.path.basename(firmware)}.jlink' with open(f_jlink, 'w') as f: f.writelines(f'{s}\n' for s in script) ret = run_cmd(f'JLinkExe -USB {flasher["uid"]} {flasher["args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile {f_jlink}') os.remove(f_jlink) return ret def reset_jlink(board): flasher = board['flasher'] script = ['halt', 'r', 'go', 'exit'] f_jlink = f'{board["name"]}_reset.jlink' if not os.path.exists(f_jlink): with open(f_jlink, 'w') as f: f.writelines(f'{s}\n' for s in script) ret = run_cmd(f'JLinkExe -USB {flasher["uid"]} {flasher["args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile {f_jlink}') return ret def flash_stlink(board, firmware): flasher = board['flasher'] return run_cmd(f'STM32_Programmer_CLI --connect port=swd sn={flasher["uid"]} --write {firmware}.elf --go') def reset_stlink(board): flasher = board['flasher'] return run_cmd(f'STM32_Programmer_CLI --connect port=swd sn={flasher["uid"]} --rst --go') def flash_stflash(board, firmware): flasher = board['flasher'] ret = run_cmd(f'st-flash --serial {flasher["uid"]} write {firmware}.bin 0x8000000') return ret def reset_stflash(board): flasher = board['flasher'] return subprocess.CompletedProcess(args=['dummy'], returncode=0) def flash_openocd(board, firmware): flasher = board['flasher'] ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" ' f'{flasher["args"]} -c "init; halt; program {firmware}.elf verify; reset; exit"') return ret def reset_openocd(board): flasher = board['flasher'] ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" ' f'{flasher["args"]} -c "init; reset run; exit"') return ret def flash_openocd_wch(board, firmware): flasher = board['flasher'] f_wch = f"wch-riscv_{board['uid']}.cfg" if not os.path.exists(f_wch): with open(f_wch, 'w') as file: file.write(WCH_RISCV_CONTENT) ret = run_cmd(f'openocd_wch -c "adapter serial {flasher["uid"]}" -f {f_wch} ' f'-c "program {firmware}.elf reset exit"') return ret def reset_openocd_wch(board): flasher = board['flasher'] f_wch = f"wch-riscv_{board['uid']}.cfg" if not os.path.exists(f_wch): with open(f_wch, 'w') as file: file.write(WCH_RISCV_CONTENT) ret = run_cmd(f'openocd_wch -c "adapter serial {flasher["uid"]}" -f {f_wch} -c "program reset exit"') return ret def flash_openocd_adi(board, firmware): flasher = board['flasher'] ret = run_cmd(f'{OPENCOD_ADI_PATH}/src/openocd -c "adapter serial {flasher["uid"]}" -s {OPENCOD_ADI_PATH}/tcl ' f'{flasher["args"]} -c "program {firmware}.elf reset exit"') return ret def reset_openocd_adi(board): flasher = board['flasher'] ret = run_cmd(f'{OPENCOD_ADI_PATH}/src/openocd -c "adapter serial {flasher["uid"]}" -s {OPENCOD_ADI_PATH}/tcl ' f'{flasher["args"]} -c "program reset exit"') return ret def flash_wlink_rs(board, firmware): flasher = board['flasher'] # wlink use index for probe selection and lacking usb serial support ret = run_cmd(f'wlink flash {firmware}.elf') return ret def reset_wlink_rs(board): flasher = board['flasher'] # wlink use index for probe selection and lacking usb serial support ret = run_cmd(f'wlink reset') return ret def flash_esptool(board, firmware): flasher = board['flasher'] port = get_serial_dev(flasher["uid"], None, None, 0) fw_dir = os.path.dirname(f'{firmware}.bin') with open(f'{fw_dir}/config.env') as f: idf_target = json.load(f)['IDF_TARGET'] with open(f'{fw_dir}/flash_args') as f: flash_args = f.read().strip().replace('\n', ' ') command = (f'esptool --chip {idf_target} -p {port} {flasher["args"]} ' f'--before=default_reset --after=hard_reset write_flash {flash_args}') ret = run_cmd(command, cwd=fw_dir) return ret def reset_esptool(board): flasher = board['flasher'] return subprocess.CompletedProcess(args=['dummy'], returncode=0) def flash_uniflash(board, firmware): flasher = board['flasher'] ret = run_cmd(f'dslite.sh {flasher["args"]} -f {firmware}.hex') return ret def reset_uniflash(board): flasher = board['flasher'] return subprocess.CompletedProcess(args=['dummy'], returncode=0) # ------------------------------------------------------------- # Tests: dual # ------------------------------------------------------------- def test_dual_host_info_to_device_cdc(board): uid = board['uid'] declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']] port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) ser = open_serial_dev(port) ser.timeout = 0.1 # read until all expected devices are enumerated data = b'' timeout = ENUM_TIMEOUT while timeout > 0: new_data = ser.read(ser.in_waiting or 1) if new_data: data += new_data # check if all devices found enum_dev_sn = [] for l in data.decode('utf-8', errors='ignore').splitlines(): vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) if vid_pid_sn: enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') if set(declared_devs).issubset(set(enum_dev_sn)): break time.sleep(0.1) timeout -= 0.1 ser.close() if len(data) == 0: assert False, 'No data from device' lines = data.decode('utf-8', errors='ignore').splitlines() enum_dev_sn = [] for l in lines: vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) if vid_pid_sn: print(f'\r\n {l} ', end='') enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') if set(declared_devs) != set(enum_dev_sn): failed_msg = f'Expected {declared_devs}, Enumerated {enum_dev_sn}' print('\n'.join(lines)) assert False, failed_msg return 0 # ------------------------------------------------------------- # Tests: host # ------------------------------------------------------------- def test_host_device_info(board): flasher = board['flasher'] declared_devs = [f'{d["vid_pid"]}_{d["serial"]}' for d in board['tests']['dev_attached']] port = get_serial_dev(flasher["uid"], None, None, 0) ser = open_serial_dev(port) ser.timeout = 0.1 # reset device since we can miss the first line ret = globals()[f'reset_{flasher["name"].lower()}'](board) assert ret.returncode == 0, 'Failed to reset device' # read until all expected devices are enumerated data = b'' timeout = ENUM_TIMEOUT while timeout > 0: new_data = ser.read(ser.in_waiting or 1) if new_data: data += new_data # check if all devices found enum_dev_sn = [] for l in data.decode('utf-8', errors='ignore').splitlines(): vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) if vid_pid_sn: enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') if set(declared_devs).issubset(set(enum_dev_sn)): break time.sleep(0.1) timeout -= 0.1 ser.close() if len(data) == 0: assert False, 'No data from device' lines = data.decode('utf-8', errors='ignore').splitlines() enum_dev_sn = [] for l in lines: vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l) if vid_pid_sn: print(f'\r\n {l} ', end='') enum_dev_sn.append(f'{vid_pid_sn.group(1)}_{vid_pid_sn.group(2)}_{vid_pid_sn.group(3)}') if set(declared_devs) != set(enum_dev_sn): failed_msg = f'Expected {declared_devs}, Enumerated {enum_dev_sn}' print('\n'.join(lines)) assert False, failed_msg return 0 def print_msc_info(lines): """Print MSC inquiry and disk size on a single line""" inquiry = '' disk_size = '' for l in lines: if re.match(r'^[A-Za-z].*\s+rev\s+', l): inquiry = l.strip() if 'Disk Size' in l: disk_size = l.strip() if inquiry or disk_size: print(f'\r\n {inquiry} {disk_size} ', end='') def test_host_cdc_msc_hid(board): flasher = board['flasher'] dev_attached = board['tests'].get('dev_attached', []) cdc_devs = [d for d in dev_attached if d.get('is_cdc')] msc_devs = [d for d in dev_attached if d.get('is_msc')] if not cdc_devs and not msc_devs: return port = get_serial_dev(flasher["uid"], None, None, 0) ser = open_serial_dev(port) ser.timeout = 0.1 # reset device to catch mount messages ret = globals()[f'reset_{flasher["name"].lower()}'](board) assert ret.returncode == 0, 'Failed to reset device' # Wait for all expected mount messages data = b'' timeout = ENUM_TIMEOUT wait_cdc = len(cdc_devs) > 0 wait_msc = len(msc_devs) > 0 while timeout > 0: new_data = ser.read(ser.in_waiting or 1) if new_data: data += new_data cdc_ok = (not wait_cdc) or (b'CDC Interface is mounted' in data) msc_ok = (not wait_msc) or (b'Disk Size' in data) if cdc_ok and msc_ok: break time.sleep(0.1) timeout -= 0.1 # Lookup serial chip name from vid_pid vid_pid_name = { '0403_6001': 'FTDI', '0403_6010': 'FTDI', '0403_6011': 'FTDI', '0403_6014': 'FTDI', '10c4_ea60': 'CP210x', '10c4_ea70': 'CP210x', '067b_2303': 'PL2303', '067b_23a3': 'PL2303', '1a86_7523': 'CH340', '1a86_7522': 'CH340', '1a86_55d3': 'CH9102', '1a86_55d4': 'CH9102', } lines = data.decode('utf-8', errors='ignore').splitlines() # Verify and print CDC mount if cdc_devs: assert b'CDC Interface is mounted' in data, 'CDC device not mounted on host' dev = cdc_devs[0] chip_name = vid_pid_name.get(dev['vid_pid'], dev['vid_pid']) for l in lines: if 'CDC Interface is mounted' in l: print(f'\r\n {chip_name}: {l} ', end='') # Verify and print MSC mount (inquiry + disk size) if msc_devs: assert b'MassStorage device is mounted' in data, 'MSC device not mounted on host' assert b'Disk Size' in data, 'MSC Disk Size not reported' print_msc_info(lines) # CDC echo test via flasher serial if not cdc_devs: ser.close() return time.sleep(2) ser.reset_input_buffer() def rand_ascii(length): return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii") sizes = [8, 32, 64, 128] for size in sizes: test_data = rand_ascii(size) ser.reset_input_buffer() # Write byte-by-byte with delay to avoid UART overrun for b in test_data: ser.write(bytes([b])) ser.flush() time.sleep(0.001) # Read echo back with timeout echo = b'' t = 5.0 while t > 0 and len(echo) < size: rd = ser.read(max(1, ser.in_waiting)) if rd: echo += rd time.sleep(0.05) t -= 0.05 assert echo == test_data, (f'CDC echo wrong data ({size} bytes):\n' f' expected: {test_data}\n received: {echo}') ser.close() def test_host_msc_file_explorer(board): flasher = board['flasher'] msc_devs = [d for d in board['tests'].get('dev_attached', []) if d.get('is_msc')] if not msc_devs: return port = get_serial_dev(flasher["uid"], None, None, 0) ser = open_serial_dev(port) ser.timeout = 0.1 # reset device to catch mount messages ret = globals()[f'reset_{flasher["name"].lower()}'](board) assert ret.returncode == 0, 'Failed to reset device' # Wait for MSC mount (Disk Size message) data = b'' timeout = ENUM_TIMEOUT while timeout > 0: new_data = ser.read(ser.in_waiting or 1) if new_data: data += new_data if b'Disk Size' in data: break time.sleep(0.1) timeout -= 0.1 assert b'Disk Size' in data, 'MSC device not mounted' lines = data.decode('utf-8', errors='ignore').splitlines() print_msc_info(lines) # Send "cat README.TXT" and read response time.sleep(1) ser.reset_input_buffer() for ch in 'cat README.TXT\r': ser.write(ch.encode()) ser.flush() time.sleep(0.002) # Read response resp = b'' t = 10.0 while t > 0: rd = ser.read(max(1, ser.in_waiting)) if rd: resp += rd # wait for prompt after command output if b'>' in resp and resp.rstrip().endswith(b'>'): break time.sleep(0.05) t -= 0.05 # Verify response contains README content resp_text = resp.decode('utf-8', errors='ignore') assert MSC_README_TXT.decode() in resp_text, (f'MSC README.TXT not found in response:\n' f' received: {resp_text}') print('README.TXT matched ', end='') ser.close() # ------------------------------------------------------------- # Tests: device # ------------------------------------------------------------- def test_device_board_test(board): # Dummy test pass def test_device_cdc_dual_ports(board): uid = board['uid'] port = [ get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0), get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 2) ] ser = [open_serial_dev(p) for p in port] def rand_ascii(length): return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii") sizes = [32, 64, 128, 256, 512, random.randint(2000, 5000)] def write_and_check(writer, payload): payload_len = len(payload) for s in ser: s.reset_input_buffer() rd0 = b'' rd1 = b'' offset = 0 # Write in chunks of random 1-64 bytes (device has 64-byte buffer) while offset < payload_len: chunk_size = min(random.randint(1, 64), payload_len - offset) ser[writer].write(payload[offset:offset + chunk_size]) ser[writer].flush() rd0 += ser[0].read(chunk_size) rd1 += ser[1].read(chunk_size) offset += chunk_size assert rd0 == payload.lower(), f'Port0 wrong data ({payload_len}): expected {payload.lower()}... was {rd0}' assert rd1 == payload.upper(), f'Port1 wrong data ({payload_len}): expected {payload.upper()}... was {rd1}' for size in sizes: payload0 = rand_ascii(size) write_and_check(0, payload0) payload1 = rand_ascii(size) write_and_check(1, payload1) ser[0].close() ser[1].close() def test_device_cdc_msc(board): uid = board['uid'] # CDC Echo test port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) ser = open_serial_dev(port) def rand_ascii(length): return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii") sizes = [32, 64, 128, 256, 512, random.randint(2000, 5000)] for size in sizes: test_str = rand_ascii(size) rd_str = b'' offset = 0 # Write in chunks of random 1-64 bytes (device has 64-byte buffer) while offset < size: chunk_size = min(random.randint(1, 64), size - offset) ser.write(test_str[offset:offset + chunk_size]) ser.flush() rd_str += ser.read(chunk_size) offset += chunk_size assert rd_str == test_str, f'CDC wrong data ({size} bytes):\n expected: {test_str}\n received: {rd_str}' ser.close() # MSC Block test data = read_disk_file(uid, 0, 'README.TXT') assert data == MSC_README_TXT, f'MSC wrong data in README.TXT\n expected: {MSC_README_TXT.decode()}\n received: {data.decode()}' def test_device_cdc_msc_freertos(board): test_device_cdc_msc(board) def test_device_dfu(board): uid = board['uid'] # Wait device enum timeout = ENUM_TIMEOUT while timeout > 0: ret = run_cmd(f'dfu-util -l') stdout = ret.stdout.decode() if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 assert timeout > 0, 'Device not available' f_dfu0 = f'dfu0_{uid}' f_dfu1 = f'dfu1_{uid}' # Test upload try: os.remove(f_dfu0) os.remove(f_dfu1) except OSError: pass ret = run_cmd(f'dfu-util -S {uid} -a 0 -U {f_dfu0}') assert ret.returncode == 0, 'Upload failed' ret = run_cmd(f'dfu-util -S {uid} -a 1 -U {f_dfu1}') assert ret.returncode == 0, 'Upload failed' with open(f_dfu0) as f: assert 'Hello world from TinyUSB DFU! - Partition 0' in f.read(), 'Wrong uploaded data' with open(f_dfu1) as f: assert 'Hello world from TinyUSB DFU! - Partition 1' in f.read(), 'Wrong uploaded data' os.remove(f_dfu0) os.remove(f_dfu1) def test_device_dfu_runtime(board): uid = board['uid'] # Wait device enum timeout = ENUM_TIMEOUT while timeout > 0: ret = run_cmd(f'dfu-util -l') stdout = ret.stdout.decode() if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 assert timeout > 0, 'Device not available' def test_device_hid_boot_interface(board): uid = board['uid'] kbd = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') mouse1 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') mouse2 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') # Wait device enum timeout = ENUM_TIMEOUT while timeout > 0: if os.path.exists(kbd) and os.path.exists(mouse1) and os.path.exists(mouse2): break time.sleep(1) timeout = timeout - 1 assert timeout > 0, 'HID device not available' def test_device_hid_composite_freertos(id): # TODO implement later pass def test_device_printer_to_cdc(board): import threading uid = board['uid'] # Wait for CDC port and printer device cdc_port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) ser = open_serial_dev(cdc_port) lp_dev = open_printer_dev(uid, 'TinyUSB', 'TinyUSB_Device', 2) # Test 0: Verify IEEE 1284 Device ID from sysfs expected_id = 'MFG:TinyUSB;MDL:Printer to CDC;CMD:PS;CLS:PRINTER;' lp_name = os.path.basename(lp_dev) sysfs_id_path = f'/sys/class/usbmisc/{lp_name}/device/ieee1284_id' if os.path.exists(sysfs_id_path): with open(sysfs_id_path) as f: ieee1284_id = f.read().strip() if ieee1284_id: assert ieee1284_id == expected_id, (f'IEEE 1284 ID mismatch:\n' f' expected: {expected_id}\n got: {ieee1284_id}') def rand_ascii(length): return "".join(random.choices(string.ascii_letters + string.digits, k=length)).encode("ascii") sizes = [32, 64, 128, 256, 512, random.randint(2000, 5000)] # flush any stale data ser.reset_input_buffer() # Test 1: Printer -> CDC with multiple sizes, write in random 1-64 byte chunks for size in sizes: test_data = rand_ascii(size) ser.reset_input_buffer() rd = b'' offset = 0 with open(lp_dev, 'wb') as lp: while offset < size: chunk_size = min(random.randint(1, 64), size - offset) lp.write(test_data[offset:offset + chunk_size]) lp.flush() rd += ser.read(chunk_size) offset += chunk_size # read any remaining bytes (fullspeed devices may need extra time) while len(rd) < size: remaining = ser.read(size - len(rd)) if not remaining: break rd += remaining assert rd == test_data, (f'Printer->CDC wrong data ({size} bytes):\n' f' expected: {test_data[:64]}\n received: {rd[:64]}') # Test 2: CDC -> Printer with multiple sizes, write in random 1-64 byte chunks # Use a thread to read from printer since /dev/usb/lp read blocks ser.reset_input_buffer() time.sleep(0.5) for size in sizes: test_data = rand_ascii(size) rd_result = [b'', None] # [data, error] reader_ready = threading.Event() def lp_reader(): try: rd = b'' fd = os.open(lp_dev, os.O_RDONLY) reader_ready.set() try: while len(rd) < size: chunk = os.read(fd, min(64, size - len(rd))) if not chunk: break rd += chunk finally: os.close(fd) rd_result[0] = rd except Exception as e: rd_result[1] = e reader_ready.set() reader = threading.Thread(target=lp_reader, daemon=True) reader.start() # wait for reader to open lp device before writing reader_ready.wait(timeout=5) time.sleep(0.1) # Write to CDC in small chunks with flush to avoid overflowing device FIFO offset = 0 while offset < size: chunk_size = min(random.randint(1, 64), size - offset) ser.write(test_data[offset:offset + chunk_size]) ser.flush() time.sleep(0.01) offset += chunk_size reader.join(timeout=10) assert not reader.is_alive(), f'CDC->Printer timeout ({size} bytes)' assert rd_result[1] is None, f'CDC->Printer read error: {rd_result[1]}' assert rd_result[0] == test_data, (f'CDC->Printer wrong data ({size} bytes):\n' f' expected: {test_data[:64]}\n received: {rd_result[0][:64]}') time.sleep(0.2) ser.close() def test_device_mtp(board): uid = board['uid'] # --- BEFORE: mute C-level stderr for libmtp vid/pid warnings --- fd = sys.stderr.fileno() _saved = os.dup(fd) _null = os.open(os.devnull, os.O_WRONLY) os.dup2(_null, fd) mtp = open_mtp_dev(uid) # --- AFTER: restore stderr --- os.dup2(_saved, fd) os.close(_null) os.close(_saved) if mtp is None or mtp.device is None: assert False, 'MTP device not found' try: assert b"TinyUSB" == mtp.get_manufacturer(), 'MTP wrong manufacturer' assert b"MTP Example" == mtp.get_modelname(), 'MTP wrong model' assert b'1.0' == mtp.get_deviceversion(), 'MTP wrong version' assert b'TinyUSB MTP' == mtp.get_devicename(), 'MTP wrong device name' # read and compare readme.txt and logo.png f1_expect = b'TinyUSB MTP Filesystem example' f2_md5_expect = '40ef23fc2891018d41a05d4a0d5f822f' # md5sum of logo.png f1 = uid.encode("utf-8") + b'_file1' f2 = uid.encode("utf-8") + b'_file2' f3 = uid.encode("utf-8") + b'_file3' mtp.get_file_to_file(1, f1) with open(f1, 'rb') as file: f1_data = file.read() os.remove(f1) assert f1_data == f1_expect, 'MTP file1 wrong data' mtp.get_file_to_file(2, f2) with open(f2, 'rb') as file: f2_data = file.read() os.remove(f2) assert f2_md5_expect == hashlib.md5(f2_data).hexdigest(), 'MTP file2 wrong data' # test send file with open(f3, "wb") as file: f3_data = os.urandom(random.randint(1024, 3*1024)) file.write(f3_data) file.close() fid = mtp.send_file_from_file(f3, b'file3') f3_readback = f3 + b'_readback' mtp.get_file_to_file(fid, f3_readback) with open(f3_readback, 'rb') as f: f3_rb_data = f.read() os.remove(f3_readback) assert f3_rb_data == f3_data, 'MTP file3 wrong data' os.remove(f3) mtp.delete_object(fid) finally: mtp.disconnect() def test_device_msc_dual_lun(board): uid = board['uid'] # Read README from LUN 0 data0 = read_disk_file(uid, 0, 'README0.TXT') readme0 = b"LUN0: " + MSC_README_TXT assert data0 == readme0, f'MSC LUN0 wrong data in README0.TXT\n expected: {readme0}\n received: {data0}' # Read README from LUN 1 data1 = read_disk_file(uid, 1, 'README1.TXT') readme1 = b"LUN1: " + MSC_README_TXT assert data1 == readme1, f'MSC LUN1 wrong data in README1.TXT\n expected: {readme1}\n received: {data1}' def test_device_midi_test(board): uid = board['uid'] # Find MIDI device via /dev/snd/by-id using board UID timeout = ENUM_TIMEOUT midi_port = None while timeout > 0: pattern = f'/dev/snd/by-id/usb-*_{uid}-*' devs = glob.glob(pattern) if devs: # by-id entry points to controlCX, derive card number for midiCXD0 link = os.path.basename(os.readlink(devs[0])) # e.g. "controlC2" card_num = link.replace('controlC', '') midi_path = f'/dev/snd/midiC{card_num}D0' if os.path.exists(midi_path): midi_port = midi_path break time.sleep(1) timeout -= 1 assert midi_port is not None, f'MIDI device not found for {uid}' # Read MIDI messages and verify note on/off import select with open(midi_port, 'rb') as f: notes = [] # Read for up to 3 seconds to capture a few notes (286ms interval) end_time = time.time() + 3 while time.time() < end_time: ready, _, _ = select.select([f], [], [], 0.5) if ready: data = f.read(64) if data: # Parse MIDI bytes: note_on = 0x90, note_off = 0x80 i = 0 while i + 2 < len(data): status = data[i] if (status & 0xF0) == 0x90: # Note On notes.append(data[i + 1]) i += 3 elif (status & 0xF0) == 0x80: # Note Off i += 3 else: i += 1 assert len(notes) >= 2, f'Expected at least 2 MIDI notes, got {len(notes)}' # Verify notes are from the expected sequence note_sequence = [ 74, 78, 81, 86, 90, 93, 98, 102, 57, 61, 66, 69, 73, 78, 81, 85, 88, 92, 97, 100, 97, 92, 88, 85, 81, 78, 74, 69, 66, 62, 57, 62, 66, 69, 74, 78, 81, 86, 90, 93, 97, 102, 97, 93, 90, 85, 81, 78, 73, 68, 64, 61, 56, 61, 64, 68, 74, 78, 81, 86, 90, 93, 98, 102 ] for n in notes: assert n in note_sequence, f'Unexpected MIDI note {n}' def test_device_hid_generic_inout(board): uid = board['uid'] import hid # Find HID device by UID (VID=0xCafe) timeout = ENUM_TIMEOUT dev = None while timeout > 0: for d in hid.enumerate(0xCafe): if d['serial_number'] == uid: dev = d break if dev: break time.sleep(1) timeout -= 1 assert dev is not None, f'HID device not found for {uid}' h = hid.Device(vid=dev['vendor_id'], pid=dev['product_id'], serial=uid) # Echo test: send random data and verify echo for size in [8, 32, 63]: # Report ID (0) + payload, padded to 64 bytes payload = bytes([random.randint(1, 255) for _ in range(size)]) report = bytes([0]) + payload + bytes(64 - size) h.write(report) echo = h.read(64, timeout=2000) assert echo is not None and len(echo) >= size, ( f'HID echo timeout or short read ({size} bytes)') assert bytes(echo[:size]) == payload, ( f'HID echo wrong data ({size} bytes):\n' f' expected: {payload.hex()}\n received: {bytes(echo[:size]).hex()}') h.close() # ------------------------------------------------------------- # Main # ------------------------------------------------------------- # device tests # note don't test 2 examples with cdc or 2 msc next to each other device_tests = [ 'device/cdc_dual_ports', 'device/dfu', 'device/cdc_msc', 'device/dfu_runtime', 'device/cdc_msc_freertos', 'device/hid_boot_interface', 'device/msc_dual_lun', 'device/hid_generic_inout', 'device/printer_to_cdc', 'device/midi_test', 'device/mtp' ] dual_tests = [ 'dual/host_info_to_device_cdc', ] host_test = [ 'host/cdc_msc_hid', 'host/msc_file_explorer', 'host/device_info', ] def test_example(board, f1, example): """ Test example firmware :param board: board dict :param f1: flags on :param example: example name :return: 0 if success/skip, 1 if failed """ name = board['name'] err_count = 0 f1_str = "" if f1 != "": f1_str = '-f1_' + f1.replace(' ', '_') fw_dir = f'{TINYUSB_ROOT}/{build_dir}/cmake-build-{name}{f1_str}/{example}' fw_name = f'{fw_dir}/{os.path.basename(example)}' print(f'{name+f1_str:40} {example:30} ...', end='') if not os.path.exists(fw_dir) or not (os.path.exists(f'{fw_name}.elf') or os.path.exists(f'{fw_name}.bin')): print('Skip (no binary)') return 0 if verbose: print(f'Flashing {fw_name}.elf') # flash firmware. It may fail randomly, retry a few times max_rety = 3 start_s = time.time() for i in range(max_rety): ret = globals()[f'flash_{board["flasher"]["name"].lower()}'](board, fw_name) if ret.returncode == 0: try: globals()[f'test_{example.replace("/", "_")}'](board) print(' OK', end='') break except Exception as e: if i == max_rety - 1: err_count += 1 print(f'{STATUS_FAILED}: {e}') else: print(f'\n Test failed: {e}, retry {i+2}/{max_rety}', end='') time.sleep(0.5) else: print(f'\n Flash failed, retry {i+2}/{max_rety}', end='') time.sleep(0.5) if ret.returncode != 0: err_count += 1 print(f' Flash {STATUS_FAILED}', end='') print(f' in {time.time() - start_s:.1f}s') return err_count def test_board(board): name = board['name'] flasher = board['flasher'] # default to all tests test_list = [] if len(test_only) > 0: test_list = test_only else: if 'tests' in board: board_tests = board['tests'] if 'device' in board_tests and board_tests['device'] == True: test_list += list(device_tests) if 'dual' in board_tests and board_tests['dual'] == True: test_list += dual_tests if 'host' in board_tests and board_tests['host'] == True: test_list += host_test if 'only' in board_tests: test_list = board_tests['only'] if 'skip' in board_tests: for skip in board_tests['skip']: if skip in test_list: test_list.remove(skip) print(f'{name:25} {skip:30} ... Skip') err_count = 0 flags_on_list = [""] if 'build' in board and 'flags_on' in board['build']: flags_on_list = board['build']['flags_on'] for f1 in flags_on_list: for test in test_list: err_count += test_example(board, f1, test) # flash board_test last to disable board's usb test_example(board, flags_on_list[0], 'device/board_test') return name, err_count def main(): """ Hardware test on specified boards """ global verbose global test_only global build_dir duration = time.time() parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') parser.add_argument('-s', '--skip', action='append', default=[], help='Skip boards from test') parser.add_argument('-t', '--test-only', action='append', default=[], help='Tests to run, all if not specified') parser.add_argument('-B', '--build', default='cmake-build', help='Build folder name (default: cmake-build)') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() config_file = args.config_file boards = args.board skip_boards = args.skip verbose = args.verbose test_only = args.test_only build_dir = args.build # if config file is not found, try to find it in the same directory as this script if not os.path.exists(config_file): config_file = os.path.join(os.path.dirname(__file__), config_file) with open(config_file) as f: config = json.load(f) if len(boards) == 0: config_boards = [e for e in config['boards'] if e['name'] not in skip_boards] else: config_boards = [e for e in config['boards'] if e['name'] in boards] err_count = 0 with Pool(processes=os.cpu_count()) as pool: mret = pool.map(test_board, config_boards) err_count = sum(e[1] for e in mret) # generate skip list for next re-run if failed skip_fname = f'{config_file}.skip' if err_count > 0: skip_boards += [name for name, err in mret if err == 0] with open(skip_fname, 'w') as f: f.write(' '.join(f'-s {i}' for i in skip_boards)) elif os.path.exists(skip_fname): os.remove(skip_fname) duration = time.time() - duration print() print("-" * 30) print(f'Total failed: {err_count} in {duration:.1f}s') print("-" * 30) sys.exit(err_count) if __name__ == '__main__': main() ================================================ FILE: test/hil/pymtp.py ================================================ #!/usr/bin/env python # # A Ctypes wrapper to LibMTP # Developed by: Nick Devito (nick@nick125.com) # (c) 2008 Nick Devito # Released under the GPLv3 or later. # """ PyMTP is a pythonic wrapper around libmtp, making it a bit more friendly to use in python Example Usage (or see examples/): >>> import pymtp >>> mtp = pymtp.MTP() >>> mtp.connect() PTP: Opening session >>> print mtp.get_devicename() Device name >>> mtp.disconnect() PTP: Closing session >>> """ __VERSION__ = "0.0.5" __VERSION_MACRO__ = 5 __VERSION_MINOR__ = 0 __VERSION_MAJOR__ = 0 __VERSION_TUPLE__ = (__VERSION_MAJOR__, __VERSION_MINOR__, __VERSION_MACRO__) __AUTHOR__ = "Nick Devito (nick@nick125.com)" __LICENSE__ = "GPL-3" __DEBUG__ = 1 import os import ctypes import ctypes.util # NOTE: This code *may* work on windows, I don't have a win32 system to test # this on. _module_path = ctypes.util.find_library("mtp") _libmtp = ctypes.CDLL(_module_path) # ---------- # Error Definitions # ---------- class NoDeviceConnected(Exception): """ Raised when there isn't a device connected to the USB bus """ pass class AlreadyConnected(Exception): """ Raised when we're already connected to a device and there is an attempt to connect """ pass class UnsupportedCommand(Exception): """ Raised when the connected device does not support the command issued """ pass class CommandFailed(Exception): """ Raised when the connected device returned an error when trying to execute a command """ pass class NotConnected(Exception): """ Raised when a command is called and the device is not connected """ pass class ObjectNotFound(Exception): """ Raised when a command tries to get an object that doesn't exist """ pass # ---------- # End Error Definitions # ---------- # ---------- # Data Model Definitions # ---------- class LIBMTP_Error(ctypes.Structure): """ LIBMTP_Error Contains the ctypes structure for LIBMTP_error_t """ def __repr__(self): return self.errornumber LIBMTP_Error._fields_ = [("errornumber", ctypes.c_int), ("error_text", ctypes.c_char_p), ("next", ctypes.POINTER(LIBMTP_Error))] class LIBMTP_DeviceStorage(ctypes.Structure): """ LIBMTP_DeviceStorage Contains the ctypes structure for LIBMTP_devicestorage_t """ def __repr__(self): return self.id LIBMTP_DeviceStorage._fields_ = [("id", ctypes.c_uint32), ("StorageType", ctypes.c_uint16), ("FilesystemType", ctypes.c_uint16), ("AccessCapability", ctypes.c_uint16), ("MaxCapacity", ctypes.c_uint64), ("FreeSpaceInBytes", ctypes.c_uint64), ("FreeSpaceInObjects", ctypes.c_uint64), ("StorageDescription", ctypes.c_char_p), ("VolumeIdentifier", ctypes.c_char_p), ("next", ctypes.POINTER(LIBMTP_DeviceStorage)), ("prev", ctypes.POINTER(LIBMTP_DeviceStorage))] class LIBMTP_DeviceEntry(ctypes.Structure): """ LIBMTP_DeviceEntry Contains the ctypes structure for LIBMTP_device_entry_t """ def __repr__(self): return self.vendor LIBMTP_DeviceEntry._fields_ = [("vendor", ctypes.c_char_p), ("vendor_id", ctypes.c_uint16), ("product", ctypes.c_char_p), ("product_id", ctypes.c_uint16), ("device_flags", ctypes.c_uint32)] class LIBMTP_RawDevice(ctypes.Structure): """ LIBMTP_RawDevice Contains the ctypes structure for LIBMTP_raw_device_t """ def __repr__(self): return self.device_entry LIBMTP_RawDevice._fields_ = [("device_entry", LIBMTP_DeviceEntry), ("bus_location", ctypes.c_uint32), ("devnum", ctypes.c_uint8)] class LIBMTP_MTPDevice(ctypes.Structure): """ LIBMTP_MTPDevice Contains the ctypes structure for LIBMTP_mtpdevice_t """ def __repr__(self): return self.interface_number LIBMTP_MTPDevice._fields_ = [("interface_number", ctypes.c_uint8), ("params", ctypes.c_void_p), ("usbinfo", ctypes.c_void_p), ("storage", ctypes.POINTER(LIBMTP_DeviceStorage)), ("errorstack", ctypes.POINTER(LIBMTP_Error)), ("maximum_battery_level", ctypes.c_uint8), ("default_music_folder", ctypes.c_uint32), ("default_playlist_folder", ctypes.c_uint32), ("default_picture_folder", ctypes.c_uint32), ("default_video_folder", ctypes.c_uint32), ("default_organizer_folder", ctypes.c_uint32), ("default_zencast_folder", ctypes.c_uint32), ("default_album_folder", ctypes.c_uint32), ("default_text_folder", ctypes.c_uint32), ("cd", ctypes.c_void_p), ("next", ctypes.POINTER(LIBMTP_MTPDevice))] class LIBMTP_File(ctypes.Structure): """ LIBMTP_File Contains the ctypes structure for LIBMTP_file_t """ def __repr__(self): return "%s (%s)" % (self.filename, self.item_id) LIBMTP_File._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), ("storage_id", ctypes.c_uint32), ("filename", ctypes.c_char_p), ("filesize", ctypes.c_uint64), ("modificationdate", ctypes.c_uint64), ("filetype", ctypes.c_int), # LIBMTP_filetype_t enum ("next", ctypes.POINTER(LIBMTP_File))] class LIBMTP_Track(ctypes.Structure): """ LIBMTP_Track Contains the ctypes structure for LIBMTP_track_t """ def __repr__(self): return "%s - %s (%s)" % (self.artist, self.title, self.item_id) LIBMTP_Track._fields_ = [("item_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), ("storage_id", ctypes.c_uint32), ("title", ctypes.c_char_p), ("artist", ctypes.c_char_p), ("composer", ctypes.c_char_p), ("genre", ctypes.c_char_p), ("album", ctypes.c_char_p), ("date", ctypes.c_char_p), ("filename", ctypes.c_char_p), ("tracknumber", ctypes.c_uint16), ("duration", ctypes.c_uint32), ("samplerate", ctypes.c_uint32), ("nochannels", ctypes.c_uint16), ("wavecodec", ctypes.c_uint32), ("bitrate", ctypes.c_uint32), ("bitratetype", ctypes.c_uint16), ("rating", ctypes.c_uint16), ("usecount", ctypes.c_uint32), ("filesize", ctypes.c_uint64), ("modificationdate", ctypes.c_uint64), ("filetype", ctypes.c_int), # LIBMTP_filetype_t enum ("next", ctypes.POINTER(LIBMTP_Track))] class LIBMTP_Playlist(ctypes.Structure): """ LIBMTP_Playlist Contains the ctypes structure for LIBMTP_playlist_t """ def __init__(self): self.tracks = ctypes.pointer(ctypes.c_uint32(0)) self.no_tracks = ctypes.c_uint32(0) def __repr__(self): return "%s (%s)" % (self.name, self.playlist_id) def __iter__(self): """ This allows the playlist object to act like a list with a generator. """ for track in xrange(self.no_tracks): yield self.tracks[track] def __getitem__(self, key): """ This allows the playlist to return tracks like a list """ if (key > (self.no_tracks - 1)): raise IndexError return self.tracks[key] def __setitem__(self, key, value): """ This allows the user to manipulate the playlist like a list. However, this will only modify existing objects, you can't try to set a key outside of the current size. """ if (key > (self.no_tracks - 1)): raise IndexError self.tracks[key] = value def __delitem__(self, key): """ This allows the user to delete an object from the playlist """ if (key > (self.no_tracks - 1)): raise IndexError for i in range(key, (self.no_tracks - 1)): self.tracks[i] = self.tracks[i + 1] self.no_tracks -= 1 def append(self, value): """ This function appends a track to the end of the tracks list. """ if (self.tracks == None): self.tracks = ctypes.pointer(ctypes.c_uint32(0)) self.no_tracks += 1 self.tracks[(self.no_tracks - 1)] = value def __len__(self): """ This returns the number of tracks in the playlist """ return self.no_tracks LIBMTP_Playlist._fields_ = [("playlist_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("tracks", ctypes.POINTER(ctypes.c_uint32)), ("no_tracks", ctypes.c_uint32), ("next", ctypes.POINTER(LIBMTP_Playlist))] class LIBMTP_Folder(ctypes.Structure): """ LIBMTP_Folder Contains the ctypes structure for LIBMTP_folder_t """ def __repr__(self): return "%s (%s)" % (self.name, self.folder_id) LIBMTP_Folder._fields_ = [("folder_id", ctypes.c_uint32), ("parent_id", ctypes.c_uint32), ("storage_id", ctypes.c_uint32), ("name", ctypes.c_char_p), ("sibling", ctypes.POINTER(LIBMTP_Folder)), ("child", ctypes.POINTER(LIBMTP_Folder))] # Abstracted from libmtp's LIBMTP_filetype_t. This must be kept in sync. # first checked in 0.2.6.1 # last checked in version 1.1.6 LIBMTP_Filetype = { "WAV": ctypes.c_int(0), "MP3": ctypes.c_int(1), "WMA": ctypes.c_int(2), "OGG": ctypes.c_int(3), "AUDIBLE": ctypes.c_int(4), "MP4": ctypes.c_int(5), "UNDEF_AUDIO": ctypes.c_int(6), "WMV": ctypes.c_int(7), "AVI": ctypes.c_int(8), "MPEG": ctypes.c_int(9), "ASF": ctypes.c_int(10), "QT": ctypes.c_int(11), "UNDEF_VIDEO": ctypes.c_int(12), "JPEG": ctypes.c_int(13), "JFIF": ctypes.c_int(14), "TIFF": ctypes.c_int(15), "BMP": ctypes.c_int(16), "GIF": ctypes.c_int(17), "PICT": ctypes.c_int(18), "PNG": ctypes.c_int(19), "VCALENDAR1": ctypes.c_int(20), "VCALENDAR2": ctypes.c_int(21), "VCARD2": ctypes.c_int(22), "VCARD3": ctypes.c_int(23), "WINDOWSIMAGEFORMAT": ctypes.c_int(24), "WINEXEC": ctypes.c_int(25), "TEXT": ctypes.c_int(26), "HTML": ctypes.c_int(27), "FIRMWARE": ctypes.c_int(28), "AAC": ctypes.c_int(29), "MEDIACARD": ctypes.c_int(30), "FLAC": ctypes.c_int(31), "MP2": ctypes.c_int(32), "M4A": ctypes.c_int(33), "DOC": ctypes.c_int(34), "XML": ctypes.c_int(35), "XLS": ctypes.c_int(36), "PPT": ctypes.c_int(37), "MHT": ctypes.c_int(38), "JP2": ctypes.c_int(39), "JPX": ctypes.c_int(40), "ALBUM": ctypes.c_int(41), "PLAYLIST": ctypes.c_int(42), "UNKNOWN": ctypes.c_int(43), } # Synced from libmtp 0.2.6.1's libmtp.h. Must be kept in sync. LIBMTP_Error_Number = { "NONE": ctypes.c_int(0), "GENERAL": ctypes.c_int(1), "PTP_LAYER": ctypes.c_int(2), "USB_LAYER": ctypes.c_int(3), "MEMORY_ALLOCATION": ctypes.c_int(4), "NO_DEVICE_ATTACHED": ctypes.c_int(5), "STORAGE_FULL": ctypes.c_int(6), "CONNECTING": ctypes.c_int(7), "CANCELLED": ctypes.c_int(8), } # ---------- # End Data Model Definitions # ---------- # ---------- # Type Definitions # ---------- _libmtp.LIBMTP_Detect_Raw_Devices.restype = ctypes.c_int # actually LIBMTP_Error_Number enum _libmtp.LIBMTP_Get_Friendlyname.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Serialnumber.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Modelname.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Manufacturername.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Deviceversion.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Filelisting_With_Callback.restype = ctypes.POINTER(LIBMTP_File) _libmtp.LIBMTP_Get_Tracklisting_With_Callback.restype = ctypes.POINTER(LIBMTP_Track) _libmtp.LIBMTP_Get_Filetype_Description.restype = ctypes.c_char_p _libmtp.LIBMTP_Get_Filemetadata.restype = ctypes.POINTER(LIBMTP_File) _libmtp.LIBMTP_Get_Trackmetadata.restype = ctypes.POINTER(LIBMTP_Track) _libmtp.LIBMTP_Get_First_Device.restype = ctypes.POINTER(LIBMTP_MTPDevice) _libmtp.LIBMTP_Get_Playlist_List.restype = ctypes.POINTER(LIBMTP_Playlist) _libmtp.LIBMTP_Get_Playlist.restype = ctypes.POINTER(LIBMTP_Playlist) _libmtp.LIBMTP_Get_Folder_List.restype = ctypes.POINTER(LIBMTP_Folder) _libmtp.LIBMTP_Find_Folder.restype = ctypes.POINTER(LIBMTP_Folder) _libmtp.LIBMTP_Get_Errorstack.restype = ctypes.POINTER(LIBMTP_Error) _libmtp.LIBMTP_Open_Raw_Device.restype = ctypes.POINTER(LIBMTP_MTPDevice) _libmtp.LIBMTP_Open_Raw_Device.argtypes = [ctypes.POINTER(LIBMTP_RawDevice)] # This is for callbacks with the type of LIBMTP_progressfunc_t Progressfunc = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_uint64, ctypes.c_uint64) # ---------- # End Type Definitions # ---------- class MTP: """ The MTP object This is the main wrapper around libmtp """ def __init__(self): """ Initializes the MTP object @rtype: None @return: None """ self.mtp = _libmtp self.mtp.LIBMTP_Init() self.device = None def debug_stack(self): """ Checks if __DEBUG__ is set, if so, prints and clears the errorstack. @rtype: None @return: None """ if __DEBUG__: self.mtp.LIBMTP_Dump_Errorstack() #self.mtp.LIBMTP_Clear_Errorstack() def detect_devices(self): """ Detect if any MTP devices are connected @rtype: None @return: a list of LIBMTP_RawDevice instances for devices found """ devlist = [] device = LIBMTP_RawDevice() devices = ctypes.pointer(device) numdevs = ctypes.c_int(0) err = self.mtp.LIBMTP_Detect_Raw_Devices(ctypes.byref(devices), ctypes.byref(numdevs)) if err == LIBMTP_Error_Number['NO_DEVICE_ATTACHED']: return devlist elif err == LIBMTP_Error_Number['STORAGE_FULL']: # ignore this, we're just trying to detect here, not do anything else pass elif err == LIBMTP_Error_Number['CONNECTING']: raise AlreadyConnected('CONNECTING') elif err == LIBMTP_Error_Number['GENERAL']: raise CommandFailed('GENERAL') elif err == LIBMTP_Error_Number['PTP_LAYER']: raise CommandFailed('PTP_LAYER') elif err == LIBMTP_Error_Number['USB_LAYER']: raise CommandFailed('USB_LAYER') elif err == LIBMTP_Error_Number['MEMORY_ALLOCATION']: raise CommandFailed('MEMORY_ALLOCATION') elif err == LIBMTP_Error_Number['CANCELLED']: raise CommandFailed('CANCELLED') if numdevs.value == 0: return devlist for i in range(numdevs.value): devlist.append(devices[i]) return devlist def connect(self): """ Initializes the MTP connection to the device @rtype: None @return: None """ if (self.device != None): raise AlreadyConnected self.device = self.mtp.LIBMTP_Get_First_Device() if not self.device: self.device = None raise NoDeviceConnected def disconnect(self): """ Disconnects the MTP device and deletes the self.device object @rtype: None @return: None """ if (self.device == None): raise NotConnected self.mtp.LIBMTP_Release_Device(self.device) del self.device self.device = None def get_devicename(self): """ Returns the connected device's 'friendly name' (or known as the owner name) @rtype: string @return: The connected device's 'friendly name' """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Friendlyname(self.device) def set_devicename(self, name): """ Changes the connected device's 'friendly name' to name @type name: string @param name: The name to change the connected device's 'friendly name' to @rtype: None @return: None """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Set_Friendlyname(self.device, name) if (ret != 0): self.debug_stack() raise CommandFailed def get_serialnumber(self): """ Returns the connected device's serial number @rtype: string @return: The connected device's serial number """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Serialnumber(self.device) def get_manufacturer(self): """ Return the connected device's manufacturer @rtype: string @return: The connected device's manufacturer """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Manufacturername(self.device) def get_batterylevel(self): """ Returns the connected device's maximum and current battery levels @rtype: tuple @return: The connected device's maximum and current battery levels ([0] is maximum, [1] is current) """ if (self.device == None): raise NotConnected maximum_level = ctypes.c_uint8() current_level = ctypes.c_uint8() ret = self.mtp.LIBMTP_Get_Batterylevel(self.device, \ ctypes.byref(maximum_level), ctypes.byref(current_level)) if (ret != 0): raise CommandFailed return (maximum_level.value, current_level.value) def get_modelname(self): """ Returns the connected device's model name (such as "Zen V Plus") @rtype: string @return: The connected device's model name """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Modelname(self.device) def get_deviceversion(self): """ Returns the connected device's version (such as firmware/hardware version) @rtype: string @return: Returns the connect device's version information """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Deviceversion(self.device) def get_filelisting(self, callback=None): """ Returns the connected device's file listing as a tuple, containing L{LIBMTP_File} objects. @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback must take two arguments, total and sent (in bytes) @rtype: tuple @return: Returns the connect device file listing tuple """ if (self.device == None): raise NotConnected if (callback != None): callback = Progressfunc(callback) files = self.mtp.LIBMTP_Get_Filelisting_With_Callback(self.device, callback, None) ret = [] next = files while next: ret.append(next.contents) if (next.contents.next == None): break next = next.contents.next return ret def get_filetype_description(self, filetype): """ Returns the description of the filetype @type filetype: int @param filetype: The MTP filetype integer @rtype: string @return: The file type information """ if (self.device == None): raise NotConnected return self.mtp.LIBMTP_Get_Filetype_Description(filetype) def get_file_metadata(self, file_id): """ Returns the file metadata from the connected device As per the libmtp documentation, calling this function repeatedly is not recommended, as it is slow and creates a large amount of USB traffic. @type file_id: int @param file_id: The unique numeric file id @rtype: LIBMTP_File @return: The file metadata """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Get_Filemetadata(self.device, file_id) if (not hasattr(ret, 'contents')): raise ObjectNotFound return ret.contents def get_tracklisting(self, callback=None): """ Returns tracks from the connected device @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback must take two arguments, total and sent (in bytes) @rtype: tuple @return: Returns a tuple full of L{LIBMTP_Track} objects """ if (self.device == None): raise NotConnected if (callback != None): callback = Progressfunc(callback) tracks = self.mtp.LIBMTP_Get_Tracklisting_With_Callback(self.device, callback, None) ret = [] next = tracks while next: ret.append(next.contents) if (next.contents.next == None): break next = next.contents.next return ret def get_track_metadata(self, track_id): """ Returns the track metadata As per the libmtp documentation, calling this function repeatedly is not recommended, as it is slow and creates a large amount of USB traffic. @type track_id: int @param track_id: The unique numeric track id @rtype: L{LIBMTP_Track} @return: The track metadata """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Get_Trackmetadata(self.device, track_id) if (not hasattr(ret, 'contents')): raise ObjectNotFound return ret.contents def get_file_to_file(self, file_id, target, callback=None): """ Downloads the file from the connected device and stores it at the target location @type file_id: int @param file_id: The unique numeric file id @type target: str @param target: The location to place the file @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback must take two arguments, total and sent (in bytes) """ if (self.device == None): raise NotConnected if (callback != None): callback = Progressfunc(callback) ret = self.mtp.LIBMTP_Get_File_To_File(self.device, file_id, target, callback, None) if (ret != 0): self.debug_stack() raise CommandFailed def get_track_to_file(self, track_id, target, callback=None): """ Downloads the track from the connected device and stores it at the target location @type track_id: int @param track_id: The unique numeric track id @type target: str @param target: The location to place the track @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback must take two arguments, total and sent (in bytes) """ if (self.device == None): raise NotConnected if (callback != None): callback = Progressfunc(callback) ret = self.mtp.LIBMTP_Get_Track_To_File(self.device, track_id, target, callback, None) if (ret != 0): self.debug_stack() raise CommandFailed def find_filetype(self, filename): """ Attempts to guess the filetype off the filename. Kind of inaccurate and should be trusted with a grain of salt. It works in most situations, though. @type filename: str @param filename: The filename to attempt to guess from @rtype: int @return: The integer of the Filetype """ fileext = filename.decode('utf-8').lower().split(".")[-1] if (fileext == "wav" or fileext == "wave"): return LIBMTP_Filetype["WAV"] elif (fileext == "mp3"): return LIBMTP_Filetype["MP3"] elif (fileext == "wma"): return LIBMTP_Filetype["WMA"] elif (fileext == "ogg"): return LIBMTP_Filetype["OGG"] elif (fileext == "mp4"): return LIBMTP_Filetype["MP4"] elif (fileext == "wmv"): return LIBMTP_Filetype["WMV"] elif (fileext == "avi"): return LIBMTP_Filetype["AVI"] elif (fileext == "mpeg" or fileext == "mpg"): return LIBMTP_Filetype["MPEG"] elif (fileext == "asf"): return LIBMTP_Filetype["ASF"] elif (fileext == "qt" or fileext == "mov"): return LIBMTP_Filetype["QT"] elif (fileext == "jpeg" or fileext == "jpg"): return LIBMTP_Filetype["JPEG"] elif (fileext == "jfif"): return LIBMTP_Filetype["JFIF"] elif (fileext == "tif" or fileext == "tiff"): return LIBMTP_Filetype["TIFF"] elif (fileext == "bmp"): return LIBMTP_Filetype["BMP"] elif (fileext == "gif"): return LIBMTP_Filetype["GIF"] elif (fileext == "pic" or fileext == "pict"): return LIBMTP_Filetype["PICT"] elif (fileext == "png"): return LIBMTP_Filetype["PNG"] elif (fileext == "wmf"): return LIBMTP_Filetype["WINDOWSIMAGEFORMAT"] elif (fileext == "ics"): return LIBMTP_Filetype["VCALENDAR2"] elif (fileext == "exe" or fileext == "com" or fileext == "bat"\ or fileext == "dll" or fileext == "sys"): return LIBMTP_Filetype["WINEXEC"] elif (fileext == "aac"): return LIBMTP_Filetype["AAC"] elif (fileext == "mp2"): return LIBMTP_Filetype["MP2"] elif (fileext == "flac"): return LIBMTP_Filetype["FLAC"] elif (fileext == "m4a"): return LIBMTP_Filetype["M4A"] elif (fileext == "doc"): return LIBMTP_Filetype["DOC"] elif (fileext == "xml"): return LIBMTP_Filetype["XML"] elif (fileext == "xls"): return LIBMTP_Filetype["XLS"] elif (fileext == "ppt"): return LIBMTP_Filetype["PPT"] elif (fileext == "mht"): return LIBMTP_Filetype["MHT"] elif (fileext == "jp2"): return LIBMTP_Filetype["JP2"] elif (fileext == "jpx"): return LIBMTP_Filetype["JPX"] else: return LIBMTP_Filetype["UNKNOWN"] def send_file_from_file(self, source, target, callback=None): """ Sends a file from the filesystem to the connected device and stores it at the target filename inside the parent. This will attempt to "guess" the filetype with find_filetype() @type source: str @param source: The path on the filesystem where the file resides @type target: str @param target: The target filename on the device @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must take two arguments, sent and total (in bytes) @rtype: int @return: The object ID of the new file """ if (self.device == None): raise NotConnected if (os.path.isfile(source) == False): raise IOError if (callback != None): callback = Progressfunc(callback) metadata = LIBMTP_File(filename=target, \ filetype=self.find_filetype(source), \ filesize=os.stat(source).st_size) ret = self.mtp.LIBMTP_Send_File_From_File(self.device, source, \ ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() raise CommandFailed return metadata.item_id def send_track_from_file(self, source, target, metadata, callback=None): """ Sends a track from the filesystem to the connected device @type source: str @param source: The path where the track resides @type target: str @param target: The target filename on the device @type metadata: LIBMTP_Track @param metadata: The track metadata @type callback: function or None @param callback: The function provided to libmtp to receive callbacks from ptp. Callback function must take two arguments, sent and total (in bytes) @rtype: int @return: The object ID of the new track """ if (self.device == None): raise NotConnected if (os.path.exists(source) == None): raise IOError if callback: callback = Progressfunc(callback) metadata.filename = target metadata.filetype = self.find_filetype(source) metadata.filesize = os.stat(source).st_size ret = self.mtp.LIBMTP_Send_Track_From_File(self.device, source, \ ctypes.pointer(metadata), callback, None) if (ret != 0): self.debug_stack() raise CommandFailed return metadata.item_id def get_freespace(self): """ Returns the amount of free space on the connected device @rtype: long @return: The amount of free storage in bytes """ if (self.device == None): raise NotConnected self.mtp.LIBMTP_Get_Storage(self.device, 0) return self.device.contents.storage.contents.FreeSpaceInBytes def get_totalspace(self): """ Returns the total space on the connected device @rtype: long @return: The amount of total storage in bytes """ if (self.device == None): raise NotConnected self.mtp.LIBMTP_Get_Storage(self.device, 0) return self.device.contents.storage.contents.MaxCapacity def get_usedspace(self): """ Returns the amount of used space on the connected device @rtype: long @return: The amount of used storage in bytes """ if (self.device == None): raise NotConnected self.mtp.LIBMTP_Get_Storage(self.device, 0) storage = self.device.contents.storage.contents return (storage.MaxCapacity - storage.FreeSpaceInBytes) def get_usedspace_percent(self): """ Returns the amount of used space as a percentage @rtype: float @return: The percentage of used storage """ if (self.device == None): raise NotConnected self.mtp.LIBMTP_Get_Storage(self.device, 0) storage = self.device.contents.storage.contents # Why don't we call self.get_totalspace/self.get_usedspace # here? That would require 3 *more* calls to # LIBMTP_Get_Storage usedspace = storage.MaxCapacity - storage.FreeSpaceInBytes return ((float(usedspace) / float(storage.MaxCapacity)) * 100) def delete_object(self, object_id): """ Deletes the object off the connected device. @type object_id: int @param object_id: The unique object identifier """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Delete_Object(self.device, object_id) if (ret != 0): self.debug_stack() raise CommandFailed def get_playlists(self): """ Returns a tuple filled with L{LIBMTP_Playlist} objects from the connected device. The main gotcha of this function is that the tracks variable of LIBMTP_Playlist isn't iterable (without segfaults), so, you have to iterate over the no_tracks (through range or xrange) and access it that way (i.e. tracks[track_id]). Kind of sucks. @rtype: tuple @return: Tuple filled with LIBMTP_Playlist objects """ if (self.device == None): raise NotConnected playlists = self.mtp.LIBMTP_Get_Playlist_List(self.device) ret = [] next = playlists while next: ret.append(next.contents) if (next.contents.next == None): break next = next.contents.next return ret def get_playlist(self, playlist_id): """ Returns a L{LIBMTP_Playlist} object of the requested playlist_id from the connected device @type playlist_id: int @param playlist_id: The unique playlist identifier @rtype: LIBMTP_Playlist @return: The playlist object """ if (self.device == None): raise NotConnected try: ret = self.mtp.LIBMTP_Get_Playlist(self.device, playlist_id).contents except ValueError: raise ObjectNotFound return ret def create_new_playlist(self, metadata): """ Creates a new playlist based on the metadata object passed. @type metadata: LIBMTP_Playlist @param metadata: A LIBMTP_Playlist object describing the playlist @rtype: int @return: The object ID of the new playlist """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Create_New_Playlist(self.device, ctypes.pointer(metadata)) if (ret != 0): self.debug_stack() raise CommandFailed return metadata.playlist_id def update_playlist(self, metadata): """ Updates a playlist based on the supplied metadata. When updating the tracks field in a playlist, this function will replace the playlist's tracks with the tracks supplied in the metadata object. This means that the previous tracks in the playlist will be overwritten. @type metadata: LIBMTP_Playlist @param metadata: A LIBMTP_Playlist object describing the updates to the playlist. """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Update_Playlist(self.device, ctypes.pointer(metadata)) if (ret != 0): self.debug_stack() raise CommandFailed def get_folder_list(self): """ Returns a pythonic dict of the folders on the device. @rtype: dict @return: A dict of the folders on the device where the folder ID is the key. """ if (self.device == None): raise NotConnected folders = self.mtp.LIBMTP_Get_Folder_List(self.device) next = folders # List of folders, key being the folder ID ret = {} # Iterate over the folders to grab the first-level parents while True: next = next.contents scanned = True # Check if this ID exists, if not, add it # and trigger a scan of the children if not (ret.has_key(next.folder_id)): ret[next.folder_id] = next scanned = False if ((scanned == False) and (next.child)): ## Scan the children next = next.child elif (next.sibling): ## Scan the siblings next = next.sibling elif (next.parent_id != 0): ## If we have no children/siblings to visit, ## and we aren't at the parent, go back to ## the parent. next = self.mtp.LIBMTP_Find_Folder(folders, int(next.parent_id)) else: ## We have scanned everything, let's go home. break return ret def get_parent_folders(self): """ Returns a list of only the parent folders. @rtype: list @return: Returns a list of the parent folders """ if (self.device == None): raise NotConnected folders = self.mtp.LIBMTP_Get_Folder_List(self.device) next = folders # A temporary holding space, this makes checking folder # IDs easier tmp = {} while True: next = next.contents ## Check if this folder is in the dict if not (tmp.has_key(next.folder_id)): tmp[next.folder_id] = next # Check for siblings if (next.sibling): ## Scan the sibling next = next.sibling else: ## We're done here. break ## convert the dict into a list ret = [] for key in tmp: ret.append(tmp[key]) return ret def create_folder(self, name, parent=0, storage=0): """ This creates a new folder in the parent. If the parent is 0, it will go in the main directory. @type name: str @param name: The name for the folder @type parent: int @param parent: The parent ID or 0 for main directory @type storage: int @param storage: The storage id or 0 to create the new folder on the primary storage @rtype: int @return: Returns the object ID of the new folder """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Create_Folder(self.device, name, parent, storage) if (ret == 0): self.debug_stack() raise CommandFailed return ret def get_errorstack(self): """ Returns the connected device's errorstack from LIBMTP. @rtype: L{LIBMTP_Error} @return: An array of LIBMTP_Errors. """ if (self.device == None): raise NotConnected ret = self.mtp.LIBMTP_Get_Errorstack(self.device) if (ret != 0): raise CommandFailed return ret ================================================ FILE: test/hil/requirements.txt ================================================ fs hid pyfatfs pyserial ================================================ FILE: test/hil/tinyusb.json ================================================ { "boards": [ { "name": "espressif_p4_function_ev", "uid": "6055F9F98715", "build" : { "flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE"] }, "tests": { "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"], "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002427", "is_cdc": true}] }, "flasher": { "name": "esptool", "uid": "4ea4f48f6bc3ee11bbb9d00f9e1b1c54", "args": "-b 1500000", "comment": "use --force for ESP32-P4 v0.1" }, "comment": "Use TS3USB30 mux to test both device and host" }, { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", "build" : { "flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE"] }, "tests": { "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"], "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2005402", "is_cdc": true}] }, "flasher": { "name": "esptool", "uid": "3ea619acd1cdeb11a0a0b806e93fd3f1", "args": "-b 1500000" }, "comment": "Use TS3USB30 mux to test both device and host" }, { "name": "feather_nrf52840_express", "uid": "1F0479CD0F764471", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000682804350", "args": "-device nrf52840_xxaa" } }, { "name": "max32666fthr", "uid": "0C81464124010B20FF0A08CC2C", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "openocd_adi", "uid": "E6614C311B597D32", "args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" } }, { "name": "metro_m4_express", "uid": "9995AD485337433231202020FF100A34", "build" : { "args": ["MAX3421_HOST=1"] }, "tests": { "device": true, "host": false, "dual": true, "dev_attached": [{"vid_pid": "067b_2303", "serial": "0", "is_cdc": true}], "comment": "pl23x" }, "flasher": { "name": "jlink", "uid": "123456", "args": "-device ATSAMD51J19" } }, { "name": "mimxrt1015_evk", "uid": "DC28F865D2111D228D00B0543A70463C", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000726284213", "args": "-device MIMXRT1015DAF5A" } }, { "name": "mimxrt1064_evk", "uid": "BAE96FB95AFA6DBB8F00005002001200", "tests": { "device": true, "host": true, "dual": true, "dev_attached": [{"vid_pid": "10c4_ea60", "serial": "0001", "is_cdc": true}], "comment": "cp2102" }, "flasher": { "name": "jlink", "uid": "000725299165", "args": "-device MIMXRT1064xxx6A" } }, { "name": "lpcxpresso11u37", "uid": "17121919", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000724441579", "args": "-device LPC11U37/401" } }, { "name": "ra4m1_ek", "uid": "152E163038303131393346E46F26574B", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000831174392", "args": "-device R7FA4M1AB" } }, { "name": "raspberry_pi_pico", "uid": "E6614C311B764A37", "build" : { "flags_on": ["CFG_TUH_RPI_PIO_USB"] }, "tests": { "device": true, "host": true, "dual": true, "dev_attached": [{"vid_pid": "1a86_7523", "serial": "0", "is_cdc": true}], "comment": "ch34x" }, "flasher": { "name": "openocd", "uid": "E6614103E72C1D2F", "args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" } }, { "name": "raspberry_pi_pico_w", "uid": "E6614C311B764A37", "tests": { "device": false, "host": true, "dual": false, "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2023934", "is_cdc": true}] }, "flasher": { "name": "openocd", "uid": "E6633861A3819D38", "args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" }, "comment": "Test native host" }, { "name": "raspberry_pi_pico2", "uid": "560AE75E1C7152C9", "tests": { "device": false, "host": true, "dual": false, "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002694", "is_cdc": true}] }, "flasher": { "name": "openocd", "uid": "E6633861A3978538", "args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"" } }, { "name": "adafruit_fruit_jam", "uid": "2B0DC7A45781189E", "tests": { "device": true, "host": true, "dual": true, "dev_attached": [ {"vid_pid": "0403_6001", "serial": "0", "is_cdc": true}, {"vid_pid": "058f_6387", "serial": "A8BEE062633D", "is_msc": true, "msc_disk_size": 3730, "msc_inquiry": "Generic Flash Disk rev 8.07"} ] }, "flasher": { "name": "openocd", "uid": "E6614103E78E8324", "args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"" } }, { "name": "stm32f072disco", "uid": "3A001A001357364230353532", "flasher": { "name": "jlink", "uid": "779541626", "args": "-device stm32f072rb" }, "comment": "2x16 access scheme with 1KB USB SRAM" }, { "name": "stm32f723disco", "uid": "460029001951373031313335", "build" : { "flags_on": ["", "CFG_TUH_DWC2_DMA_ENABLE"] }, "tests": { "device": true, "host": true, "dual": false, "dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2003414", "is_cdc": true}] }, "flasher": { "name": "jlink", "uid": "000776606156", "args": "-device stm32f723ie" }, "comment": "Device port0 FS (slave only), Host port1 HS with DMA" }, { "name": "stm32h743nucleo", "uid": "110018000951383432343236", "build" : { "flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE"] }, "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "openocd", "uid": "004C00343137510F39383538", "args": "-f interface/stlink.cfg -f target/stm32h7x.cfg" } }, { "name": "stm32g0b1nucleo", "uid": "4D0038000450434E37343120", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "openocd", "uid": "066FFF495087534867063844", "args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" }, "comment": "32-bit scheme, 2KB USB SRAM" } ], "boards-skip": [ { "name": "stm32f769disco", "uid": "21002F000F51363531383437", "build" : { "flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE"] }, "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000778170924", "args": "-device stm32f769ni" } }, { "name": "nanoch32v203", "uid": "CDAB277B0FBC03E339E339E3", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "openocd_wch", "uid": "EBCA8F0670AF", "args": "" } }, { "name": "stm32f407disco", "uid": "30001A000647313332353735", "tests": { "device": true, "host": false, "dual": false }, "flasher": { "name": "jlink", "uid": "000773661813", "args": "-device stm32f407vg" } } ] } ================================================ FILE: test/unit-test/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.20) project(tinyusb_unit_tests LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) # Command to invoke Ceedling. Supports multi-word commands such as "bundle exec ceedling". set(CEEDLING_COMMAND "ceedling" CACHE STRING "Command used to invoke Ceedling (Ruby gem).") separate_arguments(CEEDLING_COMMAND_LIST NATIVE_COMMAND "${CEEDLING_COMMAND}") if (CEEDLING_COMMAND_LIST STREQUAL "") message(FATAL_ERROR "CEEDLING_COMMAND is empty; set it to a valid Ceedling invocation.") endif () list(GET CEEDLING_COMMAND_LIST 0 CEEDLING_LAUNCHER) find_program(CEEDLING_LAUNCHER_PATH NAMES ${CEEDLING_LAUNCHER}) if (NOT CEEDLING_LAUNCHER_PATH) message(FATAL_ERROR "Could not find '${CEEDLING_LAUNCHER}' on PATH; adjust CEEDLING_COMMAND or PATH.") endif () list(REMOVE_AT CEEDLING_COMMAND_LIST 0) list(INSERT CEEDLING_COMMAND_LIST 0 ${CEEDLING_LAUNCHER_PATH}) set(CEEDLING_WORKDIR ${CMAKE_CURRENT_LIST_DIR}) set(CEEDLING_BUILD_DIR ${CEEDLING_WORKDIR}/_build) # Helper to add a Ceedling-backed test target that compiles into a real CMake executable. function(add_ceedling_test TARGET_NAME TEST_SOURCE PRODUCT_SOURCES MOCK_SOURCES) set(runner ${CEEDLING_BUILD_DIR}/test/runners/${TARGET_NAME}_runner.c) add_custom_target(ceedling_gen_${TARGET_NAME} COMMAND ${CEEDLING_COMMAND_LIST} test:${TARGET_NAME} WORKING_DIRECTORY ${CEEDLING_WORKDIR} BYPRODUCTS ${runner} USES_TERMINAL COMMENT "Generate Ceedling runner/mocks for ${TARGET_NAME}" ) add_executable(${TARGET_NAME} ${TEST_SOURCE} ${runner} ${MOCK_SOURCES} ${CEEDLING_BUILD_DIR}/vendor/unity/src/unity.c ${CEEDLING_BUILD_DIR}/vendor/cmock/src/cmock.c ${PRODUCT_SOURCES} ) set_source_files_properties( ${runner} ${MOCK_SOURCES} ${CEEDLING_BUILD_DIR}/vendor/unity/src/unity.c ${CEEDLING_BUILD_DIR}/vendor/cmock/src/cmock.c PROPERTIES GENERATED TRUE ) add_dependencies(${TARGET_NAME} ceedling_gen_${TARGET_NAME}) target_include_directories(${TARGET_NAME} PRIVATE ${CEEDLING_WORKDIR}/test ${CEEDLING_WORKDIR}/test/support ${CEEDLING_BUILD_DIR}/test/runners ${CEEDLING_BUILD_DIR}/test/mocks/${TARGET_NAME} ${CEEDLING_BUILD_DIR}/vendor/unity/src ${CEEDLING_BUILD_DIR}/vendor/cmock/src ${CEEDLING_WORKDIR}/../../src ${CEEDLING_WORKDIR}/../../src/common ${CEEDLING_WORKDIR}/../../src/device ${CEEDLING_WORKDIR}/../../src/class ${CEEDLING_WORKDIR}/../../src/class/msc ${CEEDLING_WORKDIR}/../../src/host ${CEEDLING_WORKDIR}/../../src/typec ${CEEDLING_WORKDIR}/../../src/osal ) target_compile_definitions(${TARGET_NAME} PRIVATE _UNITY_TEST_) target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra) add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) endfunction() # Custom targets to keep plain Ceedling entry-points available. add_custom_target(ceedling_all COMMAND ${CEEDLING_COMMAND_LIST} test:all WORKING_DIRECTORY ${CEEDLING_WORKDIR} USES_TERMINAL COMMENT "Run Ceedling (Unity) unit tests" ) add_custom_target(ceedling_clean COMMAND ${CEEDLING_COMMAND_LIST} clean WORKING_DIRECTORY ${CEEDLING_WORKDIR} USES_TERMINAL COMMENT "Clean Ceedling build outputs" ) add_custom_target(ceedling_clobber COMMAND ${CEEDLING_COMMAND_LIST} clobber WORKING_DIRECTORY ${CEEDLING_WORKDIR} USES_TERMINAL COMMENT "Clobber Ceedling build outputs" ) # Per-test wiring: mocks are generated under _build/test/mocks//. add_ceedling_test( test_common_func ${CEEDLING_WORKDIR}/test/test_common_func.c "" "" ) add_ceedling_test( test_fifo ${CEEDLING_WORKDIR}/test/test_fifo.c ${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c "" ) add_ceedling_test( test_usbd ${CEEDLING_WORKDIR}/test/device/usbd/test_usbd.c "${CEEDLING_WORKDIR}/../../src/tusb.c;${CEEDLING_WORKDIR}/../../src/device/usbd.c;${CEEDLING_WORKDIR}/../../src/device/usbd_control.c;${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c" "${CEEDLING_BUILD_DIR}/test/mocks/test_usbd/mock_dcd.c;${CEEDLING_BUILD_DIR}/test/mocks/test_usbd/mock_msc_device.c" ) add_ceedling_test( test_msc_device ${CEEDLING_WORKDIR}/test/device/msc/test_msc_device.c "${CEEDLING_WORKDIR}/../../src/tusb.c;${CEEDLING_WORKDIR}/../../src/device/usbd.c;${CEEDLING_WORKDIR}/../../src/device/usbd_control.c;${CEEDLING_WORKDIR}/../../src/class/msc/msc_device.c;${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c" "${CEEDLING_BUILD_DIR}/test/mocks/test_msc_device/mock_dcd.c" ) enable_testing() ================================================ FILE: test/unit-test/ceedling ================================================ #!/bin/bash ruby vendor/ceedling/bin/ceedling $* ================================================ FILE: test/unit-test/project.yml ================================================ # ========================================================================= # Ceedling - Test-Centered Build System for C # ThrowTheSwitch.org # Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams # SPDX-License-Identifier: MIT # ========================================================================= --- :project: # how to use ceedling. If you're not sure, leave this as `gem` and `?` :which_ceedling: gem :ceedling_version: 1.0.0 :verbosity: 3 # optional features. If you don't need them, keep them turned off for performance :use_mocks: TRUE :use_test_preprocessor: :mocks # options are :none, :mocks, :tests, or :all :use_deep_dependencies: :all # options are :none, :mocks, :tests, or :all :use_backtrace: :simple # options are :none, :simple, or :gdb :use_decorators: :auto # decorate Ceedling's output text. options are :auto, :all, or :none # tweak the way ceedling handles automatic tasks :build_root: _build :test_file_prefix: test_ :default_tasks: - test:all # performance options. If your tools start giving mysterious errors, consider # dropping this to 1 to force single-tasking :test_threads: 8 :compile_threads: 8 # enable release build (more details in release_build section below) :release_build: FALSE # Specify where to find mixins and any that should be enabled automatically :mixins: :enabled: [] :load_paths: [] # further details to configure the way Ceedling handles test code :test_build: :use_assembly: FALSE :test_runner: # Insert additional #include statements in a generated runner :includes: - osal.h # further details to configure the way Ceedling handles release code :release_build: :output: MyApp.out :use_assembly: FALSE :artifacts: [] # Plugins are optional Ceedling features which can be enabled. Ceedling supports # a variety of plugins which may effect the way things are compiled, reported, # or may provide new command options. Refer to the readme in each plugin for # details on how to use it. :plugins: :load_paths: [] :enabled: #- beep # beeps when finished, so you don't waste time waiting for ceedling - module_generator # handy for quickly creating source, header, and test templates #- gcov # test coverage using gcov. Requires gcc, gcov, and a coverage analyzer like gcovr #- bullseye # test coverage using bullseye. Requires bullseye for your platform #- command_hooks # write custom actions to be called at different points during the build process #- compile_commands_json_db # generate a compile_commands.json file #- dependencies # automatically fetch 3rd party libraries, etc. #- subprojects # managing builds and test for static libraries #- fake_function_framework # use FFF instead of CMock # Report options (You'll want to choose one stdout option, but may choose multiple stored options if desired) #- report_build_warnings_log #- report_tests_gtestlike_stdout #- report_tests_ide_stdout #- report_tests_log_factory - report_tests_pretty_stdout #- report_tests_raw_output_log #- report_tests_teamcity_stdout # Specify which reports you'd like from the log factory :report_tests_log_factory: :reports: - json - junit - cppunit - html # override the default extensions for your system and toolchain :extension: #:header: .h #:source: .c #:assembly: .s #:dependencies: .d #:object: .o :executable: .out #:testpass: .pass #:testfail: .fail #:subprojects: .a # This is where Ceedling should look for your source and test files. # see documentation for the many options for specifying this. :paths: :test: - +:test/** - -:test/support :source: - ../../src/** :include: - ../../src/** :support: - test/support :libraries: [] # You can even specify specific files to add or remove from your test # and release collections. Usually it's better to use paths and let # Ceedling do the work for you! :files: :test: [] :source: [] # Compilation symbols to be injected into builds # See documentation for advanced options: # - Test name matchers for different symbols per test executable build # - Referencing symbols in multiple lists using advanced YAML # - Specifying symbols used during test preprocessing :defines: :test: - _UNITY_TEST_ - CFG_TUD_EDPT_DEDICATED_HWFIFO=1 - CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE=6 - CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE=0 :release: [] # Enable to inject name of a test as a unique compilation symbol into its respective executable build. :use_test_definition: FALSE # Configure additional command line flags provided to tools used in each build step # :flags: # :release: # :compile: # Add '-Wall' and '--02' to compilation of all files in release target # - -Wall # - --O2 # :test: # :compile: # '(_|-)special': # Add '-pedantic' to compilation of all files in all test executables with '_special' or '-special' in their names # - -pedantic # '*': # Add '-foo' to compilation of all files in all test executables # - -foo # Configuration Options specific to CMock. See CMock docs for details :cmock: # Core configuration :plugins: # What plugins should be used by CMock? - :ignore - :ignore_arg - :return_thru_ptr - :callback - :array :verbosity: 2 # the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose :when_no_prototypes: :warn # the options being :ignore, :warn, or :error # File configuration :skeleton_path: '' # Subdirectory to store stubs when generated (default: '') :mock_prefix: 'mock_' # Prefix to append to filenames for mocks :mock_suffix: '' # Suffix to append to filenames for mocks # Parser configuration :strippables: ['(?:__attribute__\s*\([ (]*.*?[ )]*\)+)'] :attributes: - __ramfunc - __irq - __fiq - register - extern :c_calling_conventions: - __stdcall - __cdecl - __fastcall :treat_externs: :exclude # the options being :include or :exclud :treat_inlines: :exclude # the options being :include or :exclud # Type handling configuration #:unity_helper_path: '' # specify a string of where to find a unity_helper.h file to discover custom type assertions :treat_as: # optionally add additional types to map custom types uint8: HEX8 uint16: HEX16 uint32: UINT32 int8: INT8 bool: UINT8 #:treat_as_array: {} # hint to cmock that these types are pointers to something #:treat_as_void: [] # hint to cmock that these types are actually aliases of void :memcmp_if_unknown: true # allow cmock to use the memory comparison assertions for unknown types :when_ptr: :compare_data # hint to cmock how to handle pointers in general, the options being :compare_ptr, :compare_data, or :smart # Mock generation configuration :weak: '' # Symbol to use to declare weak functions :enforce_strict_ordering: true # Do we want cmock to enforce ordering of all function calls? :fail_on_unexpected_calls: true # Do we want cmock to fail when it encounters a function call that wasn't expected? :callback_include_count: true # Do we want cmock to include the number of calls to this callback, when using callbacks? :callback_after_arg_check: false # Do we want cmock to enforce an argument check first when using a callback? #:includes: [] # You can add additional includes here, or specify the location with the options below #:includes_h_pre_orig_header: [] #:includes_h_post_orig_header: [] #:includes_c_pre_header: [] #:includes_c_post_header: [] #:array_size_type: [] # Specify a type or types that should be used for array lengths #:array_size_name: 'size|len' # Specify a name or names that CMock might automatically recognize as the length of an array :exclude_setjmp_h: false # Don't use setjmp when running CMock. Note that this might result in late reporting or out-of-order failures. # Configuration options specific to Unity. :unity: :defines: - UNITY_EXCLUDE_FLOAT # You can optionally have ceedling create environment variables for you before # performing the rest of its tasks. :environment: [] # :environment: # # List enforces order allowing later to reference earlier with inline Ruby substitution # - :var1: value # - :var2: another value # - :path: # Special PATH handling with platform-specific path separators # - #{ENV['PATH']} # Environment variables can use inline Ruby substitution # - /another/path/to/include # LIBRARIES # These libraries are automatically injected into the build process. Those specified as # common will be used in all types of builds. Otherwise, libraries can be injected in just # tests or releases. These options are MERGED with the options in supplemental yaml files. :libraries: :placement: :end :flag: "-l${1}" :path_flag: "-L ${1}" :system: [] # for example, you might list 'm' to grab the math library :test: [] :release: [] ################################################################ # PLUGIN CONFIGURATION ################################################################ # Add -gcov to the plugins list to make sure of the gcov plugin # You will need to have gcov and gcovr both installed to make it work. # For more information on these options, see docs in plugins/gcov :gcov: :summaries: TRUE # Enable simple coverage summaries to console after tests :report_task: FALSE # Disabled dedicated report generation task (this enables automatic report generation) :utilities: - gcovr # Use gcovr to create the specified reports (default). #- ReportGenerator # Use ReportGenerator to create the specified reports. :reports: # Specify one or more reports to generate. # Make an HTML summary report. - HtmlBasic # - HtmlDetailed # - Text # - Cobertura # - SonarQube # - JSON # - HtmlInline # - HtmlInlineAzure # - HtmlInlineAzureDark # - HtmlChart # - MHtml # - Badges # - CsvSummary # - Latex # - LatexSummary # - PngChart # - TeamCitySummary # - lcov # - Xml # - XmlSummary :gcovr: # :html_artifact_filename: TestCoverageReport.html # :html_title: Test Coverage Report :html_medium_threshold: 75 :html_high_threshold: 90 # :html_absolute_paths: TRUE # :html_encoding: UTF-8 # :module_generator: # :project_root: ./ # :source_root: source/ # :inc_root: includes/ # :test_root: tests/ # :naming: :snake #options: :bumpy, :camel, :caps, or :snake # :includes: # :tst: [] # :src: [] # :boilerplates: # :src: "" # :inc: "" # :tst: "" # :dependencies: # :libraries: # - :name: WolfSSL # :source_path: third_party/wolfssl/source # :build_path: third_party/wolfssl/build # :artifact_path: third_party/wolfssl/install # :fetch: # :method: :zip # :source: \\shared_drive\third_party_libs\wolfssl\wolfssl-4.2.0.zip # :environment: # - CFLAGS+=-DWOLFSSL_DTLS_ALLOW_FUTURE # :build: # - "autoreconf -i" # - "./configure --enable-tls13 --enable-singlethreaded" # - make # - make install # :artifacts: # :static_libraries: # - lib/wolfssl.a # :dynamic_libraries: # - lib/wolfssl.so # :includes: # - include/** # :subprojects: # :paths: # - :name: libprojectA # :source: # - ./subprojectA/source # :include: # - ./subprojectA/include # :build_root: ./subprojectA/build # :defines: [] # :command_hooks: # :pre_mock_preprocess: # :post_mock_preprocess: # :pre_test_preprocess: # :post_test_preprocess: # :pre_mock_generate: # :post_mock_generate: # :pre_runner_generate: # :post_runner_generate: # :pre_compile_execute: # :post_compile_execute: # :pre_link_execute: # :post_link_execute: # :pre_test_fixture_execute: # :post_test_fixture_execute: # :pre_test: # :post_test: # :pre_release: # :post_release: # :pre_build: # :post_build: # :post_error: ################################################################ # TOOLCHAIN CONFIGURATION ################################################################ #:tools: # Ceedling defaults to using gcc for compiling, linking, etc. # As [:tools] is blank, gcc will be used (so long as it's in your system path) # See documentation to configure a given toolchain for use #:tools: # :test_compiler: # :executable: gcc # :name: 'gcc compiler' # :arguments: # - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE #expands to -I search paths # - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR #expands to -I search paths # - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR #expands to all -D defined symbols # #- -fsanitize=address # - -c ${1} #source code input file (Ruby method call param list sub) # - -o ${2} #object file output (Ruby method call param list sub) # :test_linker: # :executable: gcc # :name: 'gcc linker' # :arguments: # #- -fsanitize=address # - ${1} #list of object files to link (Ruby method call param list sub) # - -o ${2} #executable file output (Ruby method call param list sub) # :test_compiler: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_linker: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_assembler: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_fixture: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_includes_preprocessor: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_file_preprocessor: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_file_preprocessor_directives: # :executable: # :arguments: [] # :name: # :optional: FALSE # :test_dependencies_generator: # :executable: # :arguments: [] # :name: # :optional: FALSE # :release_compiler: # :executable: # :arguments: [] # :name: # :optional: FALSE # :release_linker: # :executable: # :arguments: [] # :name: # :optional: FALSE # :release_assembler: # :executable: # :arguments: [] # :name: # :optional: FALSE # :release_dependencies_generator: # :executable: # :arguments: [] # :name: # :optional: FALSE ... ================================================ FILE: test/unit-test/test/device/msc/test_msc_device.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, hathach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include "unity.h" // Files to test #include "osal/osal.h" #include "tusb_fifo.h" #include "tusb.h" #include "usbd.h" TEST_SOURCE_FILE("usbd_control.c") TEST_SOURCE_FILE("msc_device.c") // Mock File #include "mock_dcd.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ uint32_t tusb_time_millis_api(void) { return 0; } enum { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80, EDPT_MSC_OUT = 0x01, EDPT_MSC_IN = 0x81, }; uint8_t const rhport = 0; enum { ITF_NUM_MSC, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) uint8_t const data_desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), }; tusb_control_request_t const request_set_configuration = { .bmRequestType = 0x00, .bRequest = TUSB_REQ_SET_CONFIGURATION, .wValue = 1, .wIndex = 0, .wLength = 0 }; uint8_t const* desc_configuration; enum { DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount DISK_BLOCK_SIZE = 512 }; uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE]; // Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response // Some inquiry_resp's fields are already filled with default values, application can update them // Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data. uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp, uint32_t bufsize) { (void) lun; (void) bufsize; const char vid[] = "TinyUSB"; const char pid[] = "Mass Storage"; const char rev[] = "1.0"; memcpy(inquiry_resp->vendor_id, vid, strlen(vid)); memcpy(inquiry_resp->product_id, pid, strlen(pid)); memcpy(inquiry_resp->product_rev, rev, strlen(rev)); return sizeof(scsi_inquiry_resp_t); // 36 bytes } // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { (void) lun; return true; // RAM disk is always ready } // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } // Invoked when received Start Stop Unit command // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { (void) lun; (void) power_condition; return true; } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); return bufsize; } // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { (void) lun; uint8_t* addr = msc_disk[lba] + offset; memcpy(addr, buffer, bufsize); return bufsize; } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { // read10 & write10 has their own callback and MUST not be handled here void const* response = NULL; uint16_t resplen = 0; return resplen; } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ uint8_t const * tud_descriptor_device_cb(void) { return NULL; } uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { return desc_configuration; } uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; return NULL; } void setUp(void) { dcd_int_disable_Ignore(); dcd_int_enable_Ignore(); if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; dcd_init_ExpectAndReturn(0, &dev_init, true); tusb_init(0, &dev_init); } dcd_event_bus_reset(rhport, TUSB_SPEED_HIGH, false); tud_task(); } void tearDown(void) { } //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ void test_msc(void) { // Read 1 LBA = 0, Block count = 1 msc_cbw_t cbw_read10 = { .signature = MSC_CBW_SIGNATURE, .tag = 0xCAFECAFE, .total_bytes = 512, .lun = 0, .dir = TUSB_DIR_IN_MASK, .cmd_len = sizeof(scsi_read10_t) }; scsi_read10_t cmd_read10 = { .cmd_code = SCSI_CMD_READ_10, .lba = tu_htonl(0), .block_count = tu_htons(1) }; memcpy(cbw_read10.command, &cmd_read10, cbw_read10.cmd_len); desc_configuration = data_desc_configuration; uint8_t const* desc_ep = tu_desc_next(tu_desc_next(desc_configuration)); dcd_event_setup_received(rhport, (uint8_t*) &request_set_configuration, false); // open endpoints dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) desc_ep, true); dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep), true); // Prepare SCSI command dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), false, true); dcd_edpt_xfer_IgnoreArg_buffer(); dcd_edpt_xfer_ReturnMemThruPtr_buffer( (uint8_t*) &cbw_read10, sizeof(msc_cbw_t)); // command received dcd_event_xfer_complete(rhport, EDPT_MSC_OUT, sizeof(msc_cbw_t), 0, true); // control status dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_IN, NULL, 0, false, true); // SCSI Data transfer dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 512, false, true); dcd_edpt_xfer_IgnoreArg_buffer(); dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 512, 0, true); // complete // SCSI Status dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 13, false, true); dcd_edpt_xfer_IgnoreArg_buffer(); dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 13, 0, true); // Prepare for next command dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), false, true); dcd_edpt_xfer_IgnoreArg_buffer(); tud_task(); } ================================================ FILE: test/unit-test/test/device/usbd/test_usbd.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019, Ha Thach (tinyusb.org) * * 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 "unity.h" // Files to test #include "osal/osal.h" #include "tusb_fifo.h" #include "tusb.h" #include "usbd.h" TEST_SOURCE_FILE("usbd_control.c") // Mock File #include "mock_dcd.h" #include "mock_msc_device.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ uint32_t tusb_time_millis_api(void) { return 0; } enum { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80 }; uint8_t const rhport = 0; tusb_desc_device_t const data_desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = 0x0200, // Use Interface Association Descriptor (IAD) for CDC // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = 0xCafe, .bcdDevice = 0x0100, .iManufacturer = 0x01, .iProduct = 0x02, .iSerialNumber = 0x03, .bNumConfigurations = 0x01 }; uint8_t const data_desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, 0, 0, TUD_CONFIG_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), }; tusb_control_request_t const req_get_desc_device = { .bmRequestType = 0x80, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = (TUSB_DESC_DEVICE << 8), .wIndex = 0x0000, .wLength = 64 }; tusb_control_request_t const req_get_desc_configuration = { .bmRequestType = 0x80, .bRequest = TUSB_REQ_GET_DESCRIPTOR, .wValue = (TUSB_DESC_CONFIGURATION << 8), .wIndex = 0x0000, .wLength = 256 }; uint8_t const* desc_device; uint8_t const* desc_configuration; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ uint8_t const * tud_descriptor_device_cb(void) { return desc_device; } uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { return desc_configuration; } uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; return NULL; } void setUp(void) { dcd_int_disable_Ignore(); dcd_int_enable_Ignore(); if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; mscd_init_Expect(); dcd_init_ExpectAndReturn(0, &dev_init, true); tusb_init(0, &dev_init); } } void tearDown(void) { } //--------------------------------------------------------------------+ // Get Descriptor //--------------------------------------------------------------------+ //------------- Device -------------// void test_usbd_get_device_descriptor(void) { desc_device = (uint8_t const *) &data_desc_device; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); // data dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*)&data_desc_device, sizeof(tusb_desc_device_t), sizeof(tusb_desc_device_t), false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, sizeof(tusb_desc_device_t), 0, false); // status dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_device, 1); tud_task(); } void test_usbd_get_device_descriptor_null(void) { desc_device = NULL; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); dcd_edpt_stall_Expect(rhport, EDPT_CTRL_OUT); dcd_edpt_stall_Expect(rhport, EDPT_CTRL_IN); tud_task(); } //------------- Configuration -------------// void test_usbd_get_configuration_descriptor(void) { desc_configuration = data_desc_configuration; uint16_t total_len = ((tusb_desc_configuration_t const*) data_desc_configuration)->wTotalLength; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); // data dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*) data_desc_configuration, total_len, total_len, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, total_len, 0, false); // status dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_configuration, 1); tud_task(); } void test_usbd_get_configuration_descriptor_null(void) { desc_configuration = NULL; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); dcd_edpt_stall_Expect(rhport, EDPT_CTRL_OUT); dcd_edpt_stall_Expect(rhport, EDPT_CTRL_IN); tud_task(); } //--------------------------------------------------------------------+ // Control ZLP //--------------------------------------------------------------------+ void test_usbd_control_in_zlp(void) { // 128 byte total len, with EP0 size = 64, and request length = 256 // ZLP must be return uint8_t zlp_desc_configuration[CFG_TUD_ENDPOINT0_SIZE*2] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, 0, 0, CFG_TUD_ENDPOINT0_SIZE*2, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), }; desc_configuration = zlp_desc_configuration; // request, then 1st, 2nd xact + ZLP + status dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); // 1st transaction dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, EDPT_CTRL_IN, zlp_desc_configuration, CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, CFG_TUD_ENDPOINT0_SIZE, 0, false); // 2nd transaction dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, EDPT_CTRL_IN, zlp_desc_configuration + CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, CFG_TUD_ENDPOINT0_SIZE, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, CFG_TUD_ENDPOINT0_SIZE, 0, false); // Expect Zero length Packet dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_IN, NULL, 0, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_IN, 0, 0, false); // Status dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, false, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); dcd_edpt0_status_complete_ExpectWithArray(rhport, &req_get_desc_configuration, 1); tud_task(); } ================================================ FILE: test/unit-test/test/support/tusb_config.h ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * */ #ifndef TUSB_CONFIG_H_ #define TUSB_CONFIG_H_ // testing framework #include "unity.h" #ifdef __cplusplus extern "C" { #endif //-------------------------------------------------------------------- // COMMON CONFIGURATION //-------------------------------------------------------------------- // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU //#error CFG_TUSB_MCU must be defined #define CFG_TUSB_MCU OPT_MCU_NRF5X #endif #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #endif #define CFG_TUSB_OS OPT_OS_NONE // CFG_TUSB_DEBUG is defined by compiler in DEBUG build #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 1 #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. * e.g * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- #define CFG_TUD_TASK_QUEUE_SZ 100 #define CFG_TUD_ENDPOINT0_SIZE 64 //------------- CLASS -------------// //#define CFG_TUD_CDC 0 #define CFG_TUD_MSC 1 //#define CFG_TUD_HID 0 //#define CFG_TUD_MIDI 0 //#define CFG_TUD_VENDOR 0 //------------- CDC -------------// // FIFO size of CDC TX and RX #define CFG_TUD_CDC_RX_BUFSIZE 512 #define CFG_TUD_CDC_TX_BUFSIZE 512 //------------- MSC -------------// // Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 //------------- HID -------------// // Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_EP_BUFSIZE 64 #ifdef __cplusplus } #endif #endif /* TUSB_CONFIG_H_ */ ================================================ FILE: test/unit-test/test/test_common_func.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2023, Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include #include "unity.h" #include "tusb_common.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ //------------- IMPLEMENTATION -------------// void setUp(void) { } void tearDown(void) { } void test_TU_ARGS_NUM(void) { TEST_ASSERT_EQUAL( 0, TU_ARGS_NUM()); TEST_ASSERT_EQUAL( 1, TU_ARGS_NUM(a1)); TEST_ASSERT_EQUAL( 2, TU_ARGS_NUM(a1, a2)); TEST_ASSERT_EQUAL( 3, TU_ARGS_NUM(a1, a2, a3)); TEST_ASSERT_EQUAL( 4, TU_ARGS_NUM(a1, a2, a3, a4)); TEST_ASSERT_EQUAL( 5, TU_ARGS_NUM(a1, a2, a3, a4, a5)); TEST_ASSERT_EQUAL( 6, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6)); TEST_ASSERT_EQUAL( 7, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7)); TEST_ASSERT_EQUAL( 8, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8)); TEST_ASSERT_EQUAL( 9, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9)); TEST_ASSERT_EQUAL(10, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)); TEST_ASSERT_EQUAL(11, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)); TEST_ASSERT_EQUAL(12, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)); TEST_ASSERT_EQUAL(13, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)); TEST_ASSERT_EQUAL(14, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)); TEST_ASSERT_EQUAL(15, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)); TEST_ASSERT_EQUAL(16, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)); TEST_ASSERT_EQUAL(17, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17)); TEST_ASSERT_EQUAL(18, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)); TEST_ASSERT_EQUAL(19, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); TEST_ASSERT_EQUAL(20, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)); TEST_ASSERT_EQUAL(21, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21)); TEST_ASSERT_EQUAL(22, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22)); TEST_ASSERT_EQUAL(23, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23)); TEST_ASSERT_EQUAL(24, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24)); TEST_ASSERT_EQUAL(25, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)); TEST_ASSERT_EQUAL(26, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26)); TEST_ASSERT_EQUAL(27, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27)); TEST_ASSERT_EQUAL(28, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28)); TEST_ASSERT_EQUAL(29, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29)); TEST_ASSERT_EQUAL(30, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30)); TEST_ASSERT_EQUAL(31, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31)); TEST_ASSERT_EQUAL(32, TU_ARGS_NUM(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32)); } void test_tu_scatter_read32(void) { // Test data: 0x04030201 uint8_t buf1[] = {0x01, 0x02, 0x03, 0x04}; uint8_t buf2[] = {0x05, 0x06, 0x07, 0x08}; // len1=1, len2=0: read 1 byte from buf1 TEST_ASSERT_EQUAL_HEX32(0x01, tu_scatter_read32(buf1, 1, buf2, 0)); // len1=1, len2=1: read 1 byte from buf1, 1 byte from buf2 TEST_ASSERT_EQUAL_HEX32(0x0501, tu_scatter_read32(buf1, 1, buf2, 1)); // len1=1, len2=2: read 1 byte from buf1, 2 bytes from buf2 TEST_ASSERT_EQUAL_HEX32(0x060501, tu_scatter_read32(buf1, 1, buf2, 2)); // len1=1, len2=3: read 1 byte from buf1, 3 bytes from buf2 TEST_ASSERT_EQUAL_HEX32(0x07060501, tu_scatter_read32(buf1, 1, buf2, 3)); // len1=2, len2=0: read 2 bytes from buf1 TEST_ASSERT_EQUAL_HEX32(0x0201, tu_scatter_read32(buf1, 2, buf2, 0)); // len1=2, len2=1: read 2 bytes from buf1, 1 byte from buf2 TEST_ASSERT_EQUAL_HEX32(0x050201, tu_scatter_read32(buf1, 2, buf2, 1)); // len1=2, len2=2: read 2 bytes from buf1, 2 bytes from buf2 TEST_ASSERT_EQUAL_HEX32(0x06050201, tu_scatter_read32(buf1, 2, buf2, 2)); // len1=3, len2=0: read 3 bytes from buf1 TEST_ASSERT_EQUAL_HEX32(0x030201, tu_scatter_read32(buf1, 3, buf2, 0)); // len1=3, len2=1: read 3 bytes from buf1, 1 byte from buf2 TEST_ASSERT_EQUAL_HEX32(0x05030201, tu_scatter_read32(buf1, 3, buf2, 1)); } void test_tu_scatter_write32(void) { uint8_t buf1[4]; uint8_t buf2[4]; // len1=1, len2=0: write 1 byte to buf1 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x01, buf1, 1, buf2, 0); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x00, buf2[0]); // len1=1, len2=1: write 1 byte to buf1, 1 byte to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x0201, buf1, 1, buf2, 1); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf2[0]); // len1=1, len2=2: write 1 byte to buf1, 2 bytes to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x030201, buf1, 1, buf2, 2); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf2[0]); TEST_ASSERT_EQUAL_HEX8(0x03, buf2[1]); // len1=1, len2=3: write 1 byte to buf1, 3 bytes to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x04030201, buf1, 1, buf2, 3); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf2[0]); TEST_ASSERT_EQUAL_HEX8(0x03, buf2[1]); TEST_ASSERT_EQUAL_HEX8(0x04, buf2[2]); // len1=2, len2=0: write 2 bytes to buf1 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x0201, buf1, 2, buf2, 0); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf1[1]); // len1=2, len2=1: write 2 bytes to buf1, 1 byte to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x030201, buf1, 2, buf2, 1); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf1[1]); TEST_ASSERT_EQUAL_HEX8(0x03, buf2[0]); // len1=2, len2=2: write 2 bytes to buf1, 2 bytes to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x04030201, buf1, 2, buf2, 2); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf1[1]); TEST_ASSERT_EQUAL_HEX8(0x03, buf2[0]); TEST_ASSERT_EQUAL_HEX8(0x04, buf2[1]); // len1=3, len2=0: write 3 bytes to buf1 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x030201, buf1, 3, buf2, 0); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf1[1]); TEST_ASSERT_EQUAL_HEX8(0x03, buf1[2]); // len1=3, len2=1: write 3 bytes to buf1, 1 byte to buf2 memset(buf1, 0, sizeof(buf1)); memset(buf2, 0, sizeof(buf2)); tu_scatter_write32(0x04030201, buf1, 3, buf2, 1); TEST_ASSERT_EQUAL_HEX8(0x01, buf1[0]); TEST_ASSERT_EQUAL_HEX8(0x02, buf1[1]); TEST_ASSERT_EQUAL_HEX8(0x03, buf1[2]); TEST_ASSERT_EQUAL_HEX8(0x04, buf2[0]); } ================================================ FILE: test/unit-test/test/test_fifo.c ================================================ /* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) * * 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. * * This file is part of the TinyUSB stack. */ #include #include "unity.h" #include "osal/osal.h" #include "tusb_fifo.h" #define FIFO_SIZE 64 uint8_t tu_ff_buf[FIFO_SIZE * sizeof(uint8_t)]; tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, false); tu_fifo_t *ff = &tu_ff; tu_fifo_buffer_info_t info; uint8_t test_data[4096]; uint8_t rd_buf[FIFO_SIZE]; static const tu_hwfifo_access_t hwfifo_access_32 = { .data_stride = 4, .param = 0, }; static const tu_hwfifo_access_t hwfifo_access_16 = { .data_stride = 2, .param = 0, }; void setUp(void) { tu_fifo_clear(ff); memset(&info, 0, sizeof(tu_fifo_buffer_info_t)); for (size_t i = 0; i < sizeof(test_data); i++) { test_data[i] = i; } memset(rd_buf, 0, sizeof(rd_buf)); } void tearDown(void) { } //--------------------------------------------------------------------+ // Tests //--------------------------------------------------------------------+ void test_normal(void) { for (uint8_t i = 0; i < FIFO_SIZE; i++) { tu_fifo_write(ff, &i); } for (uint8_t i = 0; i < FIFO_SIZE; i++) { uint8_t c; tu_fifo_read(ff, &c); TEST_ASSERT_EQUAL(i, c); } } void test_read_n(void) { uint16_t rd_count; // fill up fifo for (uint8_t i = 0; i < FIFO_SIZE; i++) { tu_fifo_write(ff, test_data + i); } // case 1: Read index + count < depth // read 0 -> 4 rd_count = tu_fifo_read_n(ff, rd_buf, 5); TEST_ASSERT_EQUAL(5, rd_count); TEST_ASSERT_EQUAL_MEMORY(test_data, rd_buf, rd_count); // 0 -> 4 // case 2: Read index + count > depth // write 10, 11, 12 tu_fifo_write(ff, test_data + FIFO_SIZE); tu_fifo_write(ff, test_data + FIFO_SIZE + 1); tu_fifo_write(ff, test_data + FIFO_SIZE + 2); rd_count = tu_fifo_read_n(ff, rd_buf, 7); TEST_ASSERT_EQUAL(7, rd_count); TEST_ASSERT_EQUAL_MEMORY(test_data + 5, rd_buf, rd_count); // 5 -> 11 // Should only read until empty TEST_ASSERT_EQUAL(FIFO_SIZE - 5 + 3 - 7, tu_fifo_read_n(ff, rd_buf, 100)); } void test_write_n(void) { // case 1: wr + count < depth tu_fifo_write_n(ff, test_data, 32); // wr = 32, count = 32 uint16_t rd_count; rd_count = tu_fifo_read_n(ff, rd_buf, 16); // wr = 32, count = 16 TEST_ASSERT_EQUAL(16, rd_count); TEST_ASSERT_EQUAL_MEMORY(test_data, rd_buf, rd_count); // case 2: wr + count > depth tu_fifo_write_n(ff, test_data + 32, 40); // wr = 72 -> 8, count = 56 tu_fifo_read_n(ff, rd_buf, 32); // count = 24 TEST_ASSERT_EQUAL_MEMORY(test_data + 16, rd_buf, rd_count); TEST_ASSERT_EQUAL(24, tu_fifo_count(ff)); } void test_write_double_overflowed(void) { tu_fifo_set_overwritable(ff, true); uint8_t rd_buf[FIFO_SIZE] = {0}; uint8_t *buf = test_data; // full buf += tu_fifo_write_n(ff, buf, FIFO_SIZE); TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff)); // write more, should still full buf += tu_fifo_write_n(ff, buf, FIFO_SIZE - 8); TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff)); // double overflowed: in total, write more than > 2*FIFO_SIZE buf += tu_fifo_write_n(ff, buf, 16); TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff)); // reading back should give back data from last FIFO_SIZE write tu_fifo_read_n(ff, rd_buf, FIFO_SIZE); TEST_ASSERT_EQUAL_MEMORY(buf - 16, rd_buf + FIFO_SIZE - 16, 16); // TODO whole buffer should match, but we deliberately not implement it // TEST_ASSERT_EQUAL_MEMORY(buf-FIFO_SIZE, rd_buf, FIFO_SIZE); } static uint16_t help_write(uint16_t total, uint16_t n) { tu_fifo_write_n(ff, test_data, n); total = tu_min16(FIFO_SIZE, total + n); TEST_ASSERT_EQUAL(total, tu_fifo_count(ff)); TEST_ASSERT_EQUAL(FIFO_SIZE - total, tu_fifo_remaining(ff)); return total; } void test_write_overwritable2(void) { tu_fifo_set_overwritable(ff, true); // based on actual crash tests detected by fuzzing uint16_t total = 0; total = help_write(total, 12); total = help_write(total, 55); total = help_write(total, 73); total = help_write(total, 55); total = help_write(total, 75); total = help_write(total, 84); total = help_write(total, 1); total = help_write(total, 10); total = help_write(total, 12); total = help_write(total, 25); total = help_write(total, 192); } void test_peek(void) { uint8_t temp; temp = 10; tu_fifo_write(ff, &temp); temp = 20; tu_fifo_write(ff, &temp); temp = 30; tu_fifo_write(ff, &temp); temp = 0; tu_fifo_peek(ff, &temp); TEST_ASSERT_EQUAL(10, temp); tu_fifo_read(ff, &temp); tu_fifo_read(ff, &temp); tu_fifo_peek(ff, &temp); TEST_ASSERT_EQUAL(30, temp); } void test_get_read_info_when_no_wrap() { uint8_t ch = 1; // write 6 items for (uint8_t i = 0; i < 6; i++) { tu_fifo_write(ff, &ch); } // read 2 items tu_fifo_read(ff, &ch); tu_fifo_read(ff, &ch); tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(4, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); TEST_ASSERT_NULL(info.wrapped.ptr); } void test_get_read_info_when_wrapped() { uint8_t ch = 1; // make fifo full for (uint8_t i = 0; i < FIFO_SIZE; i++) { tu_fifo_write(ff, &ch); } // read 6 items for (uint8_t i = 0; i < 6; i++) { tu_fifo_read(ff, &ch); } // write 2 items tu_fifo_write(ff, &ch); tu_fifo_write(ff, &ch); tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.linear.len); TEST_ASSERT_EQUAL(2, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.linear.ptr); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_get_write_info_when_no_wrap() { uint8_t ch = 1; // write 2 items tu_fifo_write(ff, &ch); tu_fifo_write(ff, &ch); tu_fifo_get_write_info(ff, &info); TEST_ASSERT_EQUAL(FIFO_SIZE - 2, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); // application should check len instead of ptr. // TEST_ASSERT_NULL(info.wrapped.ptr); } void test_get_write_info_when_wrapped() { uint8_t ch = 1; // write 6 items for (uint8_t i = 0; i < 6; i++) { tu_fifo_write(ff, &ch); } // read 2 items tu_fifo_read(ff, &ch); tu_fifo_read(ff, &ch); tu_fifo_get_write_info(ff, &info); TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.linear.len); TEST_ASSERT_EQUAL(2, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.linear.ptr); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_empty(void) { uint8_t temp; TEST_ASSERT_TRUE(tu_fifo_empty(ff)); // read info tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(0, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_NULL(info.linear.ptr); TEST_ASSERT_NULL(info.wrapped.ptr); // write info tu_fifo_get_write_info(ff, &info); TEST_ASSERT_EQUAL(FIFO_SIZE, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.linear.ptr); // application should check len instead of ptr. // TEST_ASSERT_NULL(info.wrapped.ptr); // write 1 then re-check empty tu_fifo_write(ff, &temp); TEST_ASSERT_FALSE(tu_fifo_empty(ff)); } void test_full(void) { TEST_ASSERT_FALSE(tu_fifo_full(ff)); for (uint8_t i = 0; i < FIFO_SIZE; i++) { tu_fifo_write(ff, &i); } TEST_ASSERT_TRUE(tu_fifo_full(ff)); // read info tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(FIFO_SIZE, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.linear.ptr); // skip this, application must check len instead of buffer // TEST_ASSERT_NULL(info.wrapped.ptr); // write info } void test_rd_idx_wrap(void) { tu_fifo_t ff10; uint8_t buf[10]; uint8_t dst[10]; tu_fifo_config(&ff10, buf, 10, 1); uint16_t n; ff10.wr_idx = 6; ff10.rd_idx = 15; n = tu_fifo_read_n(&ff10, dst, 4); TEST_ASSERT_EQUAL(n, 4); TEST_ASSERT_EQUAL(ff10.rd_idx, 0); n = tu_fifo_read_n(&ff10, dst, 4); TEST_ASSERT_EQUAL(n, 4); TEST_ASSERT_EQUAL(ff10.rd_idx, 4); n = tu_fifo_read_n(&ff10, dst, 4); TEST_ASSERT_EQUAL(n, 2); TEST_ASSERT_EQUAL(ff10.rd_idx, 6); } void test_advance_write_pointer_cases(void) { tu_fifo_clear(ff); tu_fifo_advance_write_pointer(ff, 3); TEST_ASSERT_EQUAL(3, ff->wr_idx); TEST_ASSERT_EQUAL(3, tu_fifo_count(ff)); // advance to cross depth but stay within 0..2*depth window ff->wr_idx = FIFO_SIZE - 2; // 62 ff->rd_idx = 0; tu_fifo_advance_write_pointer(ff, 10); // 62 + 10 = 72 within window TEST_ASSERT_EQUAL(72, ff->wr_idx); TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff)); // advance past the unused index space (beyond 2*depth) ff->wr_idx = (uint16_t)(2 * FIFO_SIZE - 3); // 125 ff->rd_idx = 0; tu_fifo_advance_write_pointer(ff, 6); // forces wrap across unused space TEST_ASSERT_EQUAL(3, ff->wr_idx); TEST_ASSERT_EQUAL(3, tu_fifo_count(ff)); } void test_advance_read_pointer_cases(void) { tu_fifo_clear(ff); ff->wr_idx = 6; tu_fifo_advance_read_pointer(ff, 3); TEST_ASSERT_EQUAL(3, ff->rd_idx); TEST_ASSERT_EQUAL(3, tu_fifo_count(ff)); ff->wr_idx = FIFO_SIZE + 10; // 74 ff->rd_idx = FIFO_SIZE - 10; // 54 tu_fifo_advance_read_pointer(ff, 20); // move to match write index within window TEST_ASSERT_EQUAL(74, ff->rd_idx); TEST_ASSERT_EQUAL(0, tu_fifo_count(ff)); ff->wr_idx = 9; ff->rd_idx = (uint16_t)(2 * FIFO_SIZE - 1); // 127 tu_fifo_advance_read_pointer(ff, 6); // crosses unused index space TEST_ASSERT_EQUAL(5, ff->rd_idx); TEST_ASSERT_EQUAL(4, tu_fifo_count(ff)); } void test_write_n_fixed_addr_rw32_nowrap(void) { tu_fifo_clear(ff); volatile uint32_t reg = 0x11223344; uint8_t expected[8] = {0x44, 0x33, 0x22, 0x11, 0x44, 0x33, 0x22, 0x11}; for (uint8_t n = 1; n <= 8; n++) { tu_fifo_clear(ff); uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_32); TEST_ASSERT_EQUAL(n, written); TEST_ASSERT_EQUAL(n, tu_fifo_count(ff)); uint8_t out[8] = {0}; tu_fifo_read_n(ff, out, n); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n); } } void test_write_n_fixed_addr_rw32_wrapped(void) { tu_fifo_clear(ff); volatile uint32_t reg = 0xA1B2C3D4; uint8_t expected[8] = {0xD4, 0xC3, 0xB2, 0xA1, 0xD4, 0xC3, 0xB2, 0xA1}; for (uint8_t n = 1; n <= 8; n++) { tu_fifo_clear(ff); // Position the fifo near the end so writes wrap ff->wr_idx = FIFO_SIZE - 3; ff->rd_idx = FIFO_SIZE - 3; uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_32); TEST_ASSERT_EQUAL(n, written); TEST_ASSERT_EQUAL(n, tu_fifo_count(ff)); uint8_t out[8] = {0}; tu_fifo_read_n(ff, out, n); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n); } } void test_read_n_fixed_addr_rw32_nowrap(void) { uint8_t pattern[8] = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87}; uint32_t reg_expected[8] = { 0x00000010, 0x00002110, 0x00322110, 0x43322110, 0x00000054, 0x00006554, 0x00766554, 0x87766554}; for (uint8_t n = 1; n <= 8; n++) { tu_fifo_clear(ff); tu_fifo_write_n(ff, pattern, 8); uint32_t reg = 0; uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_32); TEST_ASSERT_EQUAL(n, read_cnt); TEST_ASSERT_EQUAL(8 - n, tu_fifo_count(ff)); TEST_ASSERT_EQUAL_HEX32(reg_expected[n - 1], reg); } } void test_read_n_fixed_addr_rw32_wrapped(void) { uint8_t pattern[8] = {0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87}; uint32_t reg_expected[8] = { 0x000000F0, 0x0000E1F0, 0x00D2E1F0, 0xC3D2E1F0, 0x000000B4, 0x0000A5B4, 0x0096A5B4, 0x8796A5B4}; for (uint8_t n = 1; n <= 8; n++) { tu_fifo_clear(ff); ff->rd_idx = FIFO_SIZE - 2; ff->wr_idx = (uint16_t)(ff->rd_idx + n); for (uint8_t i = 0; i < n; i++) { uint8_t idx = (uint8_t)((ff->rd_idx + i) % FIFO_SIZE); ff->buffer[idx] = pattern[i]; } uint32_t reg = 0; uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_32); TEST_ASSERT_EQUAL(n, read_cnt); TEST_ASSERT_EQUAL(0, tu_fifo_count(ff)); TEST_ASSERT_EQUAL_HEX32(reg_expected[n - 1], reg); } } void test_write_n_fixed_addr_rw16_nowrap(void) { tu_fifo_clear(ff); volatile uint16_t reg = 0x1122; uint8_t expected[6] = {0x22, 0x11, 0x22, 0x11, 0x22, 0x11}; for (uint8_t n = 1; n <= 6; n++) { tu_fifo_clear(ff); uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_16); TEST_ASSERT_EQUAL(n, written); TEST_ASSERT_EQUAL(n, tu_fifo_count(ff)); uint8_t out[6] = {0}; tu_fifo_read_n(ff, out, n); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n); } } void test_write_n_fixed_addr_rw16_wrapped(void) { tu_fifo_clear(ff); volatile uint16_t reg = 0xA1B2; uint8_t expected[6] = {0xB2, 0xA1, 0xB2, 0xA1, 0xB2, 0xA1}; for (uint8_t n = 1; n <= 6; n++) { tu_fifo_clear(ff); // Position the fifo near the end so writes wrap ff->wr_idx = FIFO_SIZE - 3; ff->rd_idx = FIFO_SIZE - 3; uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_16); TEST_ASSERT_EQUAL(n, written); TEST_ASSERT_EQUAL(n, tu_fifo_count(ff)); uint8_t out[6] = {0}; tu_fifo_read_n(ff, out, n); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n); } } void test_read_n_fixed_addr_rw16_nowrap(void) { uint8_t pattern[6] = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65}; uint16_t reg_expected[6] = {0x0010, 0x2110, 0x0032, 0x4332, 0x0054, 0x6554}; for (uint8_t n = 1; n <= 6; n++) { tu_fifo_clear(ff); tu_fifo_write_n(ff, pattern, 6); uint16_t reg = 0; uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_16); TEST_ASSERT_EQUAL(n, read_cnt); TEST_ASSERT_EQUAL(6 - n, tu_fifo_count(ff)); TEST_ASSERT_EQUAL_HEX16(reg_expected[n - 1], reg); } } void test_read_n_fixed_addr_rw16_wrapped(void) { uint8_t pattern[6] = {0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5}; uint16_t reg_expected[6] = {0x00F0, 0xE1F0, 0x00D2, 0xC3D2, 0x00B4, 0xA5B4}; for (uint8_t n = 1; n <= 6; n++) { tu_fifo_clear(ff); ff->rd_idx = FIFO_SIZE - 1; ff->wr_idx = (uint16_t)(ff->rd_idx + n); for (uint8_t i = 0; i < n; i++) { uint8_t idx = (uint8_t)((ff->rd_idx + i) % FIFO_SIZE); ff->buffer[idx] = pattern[i]; } uint16_t reg = 0; uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_16); TEST_ASSERT_EQUAL(n, read_cnt); TEST_ASSERT_EQUAL(0, tu_fifo_count(ff)); TEST_ASSERT_EQUAL_HEX16(reg_expected[n - 1], reg); } } void test_get_read_info_advanced_cases(void) { tu_fifo_clear(ff); ff->wr_idx = 20; ff->rd_idx = 2; tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(18, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); TEST_ASSERT_NULL(info.wrapped.ptr); ff->wr_idx = 68; // ptr = 4 ff->rd_idx = 56; // ptr = 56 tu_fifo_get_read_info(ff, &info); TEST_ASSERT_EQUAL(8, info.linear.len); TEST_ASSERT_EQUAL(4, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 56, info.linear.ptr); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_get_write_info_advanced_cases(void) { tu_fifo_clear(ff); ff->wr_idx = 10; ff->rd_idx = 104; // ptr = 40 tu_fifo_get_write_info(ff, &info); TEST_ASSERT_EQUAL(30, info.linear.len); TEST_ASSERT_EQUAL(0, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 10, info.linear.ptr); TEST_ASSERT_NULL(info.wrapped.ptr); ff->wr_idx = 60; ff->rd_idx = 20; tu_fifo_get_write_info(ff, &info); TEST_ASSERT_EQUAL(4, info.linear.len); TEST_ASSERT_EQUAL(20, info.wrapped.len); TEST_ASSERT_EQUAL_PTR(ff->buffer + 60, info.linear.ptr); TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_correct_read_pointer_cases(void) { tu_fifo_clear(ff); // wr beyond depth: rd should be wr - depth ff->wr_idx = FIFO_SIZE + 6; // 70 tu_fifo_correct_read_pointer(ff); TEST_ASSERT_EQUAL(6, ff->rd_idx); // wr exactly at depth: rd should wrap to zero ff->wr_idx = FIFO_SIZE; tu_fifo_correct_read_pointer(ff); TEST_ASSERT_EQUAL(0, ff->rd_idx); // wr below depth: rd should be wr + depth ff->wr_idx = 10; tu_fifo_correct_read_pointer(ff); TEST_ASSERT_EQUAL(FIFO_SIZE + 10, ff->rd_idx); } ================================================ FILE: tools/build.py ================================================ #!/usr/bin/env python3 import argparse import random import os import sys import time import subprocess import shlex from pathlib import Path from multiprocessing import Pool import build_utils STATUS_OK = "\033[32mOK\033[0m" STATUS_FAILED = "\033[31mFailed\033[0m" STATUS_SKIPPED = "\033[33mSkipped\033[0m" RET_OK = 0 RET_FAILED = 1 RET_SKIPPED = 2 build_format = '| {:30} | {:40} | {:16} | {:5} |' build_separator = '-' * 95 build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED] verbose = False parallel_jobs = os.cpu_count() # CI board control lists (used when running under CI) ci_skip_boards = { 'rp2040': [ 'adafruit_feather_rp2040_usb_host', 'adafruit_fruit_jam', 'adafruit_metro_rp2350', 'feather_rp2040_max3421', 'pico_sdk', 'raspberry_pi_pico_w', ], } ci_preferred_boards = { 'samd2x_l2x': ['metro_m0_express'], 'samd5x_e5x': ['metro_m4_express'], 'stm32h7': ['stm32h743eval'] } # ----------------------------- # Helper # ----------------------------- def run_cmd(cmd): if isinstance(cmd, str): raise TypeError("run_cmd expects a list/tuple of args, not a string") args = cmd cmd_display = " ".join(args) r = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) title = f'Command Error: {cmd_display}' if r.returncode != 0: # print build output if failed if os.getenv('GITHUB_ACTIONS'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) print(f"::endgroup::") else: print(title) print(r.stdout.decode("utf-8")) elif verbose: print(cmd_display) print(r.stdout.decode("utf-8")) return r def find_family(board): bsp_dir = Path("hw/bsp") for family_dir in bsp_dir.iterdir(): if family_dir.is_dir(): board_dir = family_dir / 'boards' / board if board_dir.exists(): return family_dir.name return None def get_examples(family): all_examples = [] for d in os.scandir("examples"): if d.is_dir() and 'cmake' not in d.name and 'build_system' not in d.name: for entry in os.scandir(d.path): if entry.is_dir() and 'cmake' not in entry.name: if family != 'espressif' or 'freertos' in entry.name: all_examples.append(d.name + '/' + entry.name) if family == 'espressif': all_examples.append('device/board_test') all_examples.append('device/video_capture') all_examples.append('host/device_info') all_examples.sort() return all_examples def print_build_result(board, build_target, status, duration): if isinstance(duration, (int, float)): duration = "{:.2f}s".format(duration) print(build_format.format(board, build_target, build_status[status], duration)) # ----------------------------- # CMake # ----------------------------- def cmake_board(board, build_args, build_flags_on, build_targets): ret = [0, 0, 0] start_time = time.monotonic() build_dir = f'cmake-build/cmake-build-{board}' build_flags = [] if len(build_flags_on) > 0: cli_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on) build_flags.append(f'-DCFLAGS_CLI={cli_flags}') build_dir += '-f1_' + '_'.join(build_flags_on) family = find_family(board) if family == 'espressif': # for espressif, we have to build example individually all_examples = get_examples(family) for example in all_examples: if build_utils.skip_example(example, board): ret[2] += 1 else: rcmd = run_cmd([ 'idf.py', '-C', f'examples/{example}', '-B', f'{build_dir}/{example}', '-GNinja', f'-DBOARD={board}', *build_flags, 'build' ]) ret[0 if rcmd.returncode == 0 else 1] += 1 else: rcmd = run_cmd(['cmake', 'examples', '-B', build_dir, '-GNinja', f'-DBOARD={board}', '-DCMAKE_BUILD_TYPE=MinSizeRel', '-DLINKERMAP_OPTION=-q -f tinyusb/src', *build_args, *build_flags]) if rcmd.returncode == 0: cmd = ["cmake", "--build", build_dir, '--parallel', str(parallel_jobs)] for target in build_targets: rcmd = run_cmd(cmd + ['--target', target]) if rcmd.returncode != 0: break ret[0 if rcmd.returncode == 0 else 1] += 1 print_build_result(board, ','.join(build_targets), 0 if ret[1] == 0 else 1, time.monotonic() - start_time) return ret # ----------------------------- # Make # ----------------------------- def make_one_example(example, board, make_option, build_targets): # Check if board is skipped if build_utils.skip_example(example, board): print_build_result(board, example, 2, '-') r = 2 else: start_time = time.monotonic() make_cmd = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)] if make_option: make_cmd += shlex.split(make_option) r = 0 for target in build_targets: build_result = run_cmd(make_cmd + [target]) if build_result.returncode != 0: r = 1 break print_build_result(board, example, r, time.monotonic() - start_time) ret = [0, 0, 0] ret[r] = 1 return ret def make_board(board, build_args, build_targets): print(build_separator) family = find_family(board); all_examples = get_examples(family) start_time = time.monotonic() ret = [0, 0, 0] if family == 'espressif' or family == 'rp2040': # espressif and rp2040 do not support make, use cmake instead final_status = 2 else: with Pool(processes=os.cpu_count()) as pool: pool_args = list((map(lambda e, b=board, o=f"{build_args}", t=build_targets: [e, b, o, t], all_examples))) r = pool.starmap(make_one_example, pool_args) # sum all element of same index (column sum) ret = list(map(sum, list(zip(*r)))) final_status = 0 if ret[1] == 0 else 1 print_build_result(board, 'all', final_status, time.monotonic() - start_time) return ret # ----------------------------- # Build Family # ----------------------------- def build_boards_list(boards, build_defines, build_system, build_flags_on, build_targets): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': build_args = [f'-D{d}' for d in build_defines] r = cmake_board(b, build_args, build_flags_on, build_targets) elif build_system == 'make': build_args = ' '.join(f'{d}' for d in build_defines) r = make_board(b, build_args, build_targets) ret[0] += r[0] ret[1] += r[1] ret[2] += r[2] return ret def get_family_boards(family, one_random, one_first): """Get list of boards for a family. Args: family: Family name one_random: If True, return only one random board one_first: If True, return only the first board (alphabetical) Returns: List of board names """ skip_list = [] preferred_list = [] if os.getenv('GITHUB_ACTIONS') or os.getenv('CIRCLECI'): skip_list = ci_skip_boards.get(family, []) preferred_list = ci_preferred_boards.get(family, []) all_boards = [] for entry in os.scandir(f"hw/bsp/{family}/boards"): if entry.is_dir() and entry.name not in skip_list: all_boards.append(entry.name) if not all_boards: print(f"No boards found for family '{family}'") return [] all_boards.sort() # If only-one flags are set, honor select list first, then pick first or random if one_first or one_random: if preferred_list: return [preferred_list[0]] if one_first: return [all_boards[0]] if one_random: return [random.choice(all_boards)] return all_boards # ----------------------------- # Main # ----------------------------- def main(): global verbose global parallel_jobs parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to build') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') parser.add_argument('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system') parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system') parser.add_argument('--one-random', action='store_true', default=False, help='Build only one random board of each specified family') parser.add_argument('--one-first', action='store_true', default=False, help='Build only the first board (alphabetical) of each specified family') parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel') parser.add_argument('-T', '--target', action='append', default=[], help='Build target to use, may be specified multiple times (default: all)') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() families = args.families boards = args.board toolchain = args.toolchain build_system = args.build_system build_defines = args.define_symbol build_flags_on = args.build_flags_on one_random = args.one_random one_first = args.one_first build_targets = args.target if args.target else ['all'] verbose = args.verbose parallel_jobs = args.jobs build_defines.append(f'TOOLCHAIN={toolchain}') if len(families) == 0 and len(boards) == 0: print("Please specify families or board to build") return 1 print(build_separator) print(build_format.format('Board', 'Target', '\033[39mResult\033[0m', 'Time')) total_time = time.monotonic() # get all families all_families = [] if 'all' in families: for entry in os.scandir("hw/bsp"): if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): all_families.append(entry.name) else: all_families = list(families) all_families.sort() # get boards from families and append to boards list all_boards = list(boards) for f in all_families: all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_targets) total_time = time.monotonic() - total_time print(build_separator) print(f"Build Summary: {result[0]} {STATUS_OK}, {result[1]} {STATUS_FAILED} and took {total_time:.2f}s") print(build_separator) return result[1] if __name__ == '__main__': sys.exit(main()) ================================================ FILE: tools/build_utils.py ================================================ #!/usr/bin/env python3 import subprocess import pathlib import re build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" def skip_example(example, board): ex_dir = pathlib.Path('examples/') / example bsp = pathlib.Path("hw/bsp") # board within family board_dir = list(bsp.glob("*/boards/" + board)) if not board_dir: # Skip unknown boards return True board_dir = list(board_dir)[0] family_dir = board_dir.parent.parent family = family_dir.name # family.mk family_mk = family_dir / "family.mk" if not family_mk.exists(): family_mk = family_dir / "family.cmake" mk_contents = family_mk.read_text() # Find the mcu, first in family mk then board mk if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: board_mk = board_dir / "board.mk" if not board_mk.exists(): board_mk = board_dir / "board.cmake" mk_contents = board_mk.read_text() mcu = "NONE" if family == "espressif": for line in mk_contents.splitlines(): match = re.search(r'set\(IDF_TARGET\s+"([^"]+)"\)', line) if match: mcu = match.group(1).upper() break else: for token in mk_contents.split(): if "CFG_TUSB_MCU=OPT_MCU_" in token: # Strip " because cmake files has them. token = token.strip("\"") _, opt_mcu = token.split("=") mcu = opt_mcu[len("OPT_MCU_"):] if mcu != "NONE": break # Skip all OPT_MCU_NONE these are WIP port if mcu == "NONE": return True max3421_enabled = False for line in mk_contents.splitlines(): if "MAX3421_HOST=1" in line or 'MAX3421_HOST 1' in line: max3421_enabled = True break skip_file = ex_dir / "skip.txt" only_file = ex_dir / "only.txt" if skip_file.exists(): skips = skip_file.read_text().split() if ("mcu:" + mcu in skips or "board:" + board in skips or "family:" + family in skips): return True if only_file.exists(): onlys = only_file.read_text().split() if not ("mcu:" + mcu in onlys or ("mcu:MAX3421" in onlys and max3421_enabled) or "board:" + board in onlys or "family:" + family in onlys): return True return False def build_size(make_cmd): size_output = subprocess.run(make_cmd + ' size', shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8").splitlines() for i, l in enumerate(size_output): text_title = 'text data bss dec' if text_title in l: size_list = size_output[i+1].split('\t') flash_size = int(size_list[0]) sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) return (0, 0) ================================================ FILE: tools/codespell/exclude-file.txt ================================================ ================================================ FILE: tools/codespell/ignore-words.txt ================================================ attch busses dout endianess fro hsi inout mot pris ptd ser sie synopsys te thre tre ================================================ FILE: tools/file2carray.py ================================================ #!/usr/bin/env python3 import argparse import random import os import sys import time import subprocess from pathlib import Path from multiprocessing import Pool from weakref import finalize def print_carray(f, payload): while len(payload) > 0: f.write('\n ') f.write(', '.join('0x{:02x}'.format(x) for x in payload[0:16])) f.write(',') payload = payload[16:] f.write('\n') def main(): parser = argparse.ArgumentParser(description='Convert binary files to C array format') parser.add_argument('files', nargs='+', help='Binary files to convert') args = parser.parse_args() files = args.files for fin_name in files: if not os.path.isfile(fin_name): print(f"File {fin_name} does not exist") continue with open(fin_name, 'rb') as fin: contents = fin.read() fout_name = fin_name + '.h' with open(fout_name, 'w') as fout: print(f"Converting {fin_name} to {fout_name}") fout.write(f'enum {{ BINDATA_LEN = {len(contents)} }};\n') fout.write(f'const size_t bindata_len = BINDATA_LEN;\n') fout.write(f'const uint8_t bindata[] __attribute__((aligned(16))) = {{') print_carray(fout, contents) fout.write('};\n') if __name__ == '__main__': sys.exit(main()) ================================================ FILE: tools/gen_doc.py ================================================ #!/usr/bin/env python3 import re import pandas as pd from tabulate import tabulate from pathlib import Path from get_deps import deps_all # TOP is tinyusb root dir TOP = Path(__file__).parent.parent.resolve() # ----------------------------------------- # Dependencies # ----------------------------------------- def gen_deps_doc(): deps_rst = Path(TOP) / "docs/reference/dependencies.rst" df = pd.DataFrame.from_dict(deps_all, orient='index', columns=['Repo', 'Commit', 'Required by']) df = df[['Repo', 'Commit', 'Required by']].sort_index() df = df.rename_axis("Local Path") outstr = f"""\ ************ Dependencies ************ MCU low-level peripheral drivers and external libraries for building TinyUSB examples {tabulate(df, headers="keys", tablefmt='rst')} """ with deps_rst.open('w') as f: f.write(outstr) # ----------------------------------------- # Dependencies # ----------------------------------------- def extract_metadata(file_path): metadata = {} try: with open(file_path, 'r') as file: content = file.read() # Match metadata block match = re.search(r'/\*\s*metadata:(.*?)\*/', content, re.DOTALL) if match: block = match.group(1) # Extract key-value pairs for line in block.splitlines(): key_value = re.match(r'\s*(\w+):\s*(.+)', line) if key_value: key, value = key_value.groups() metadata[key] = value.strip() except FileNotFoundError: pass return metadata def gen_boards_doc(): # 'Manufacturer' : { 'Board' } vendor_data = {} # 'Board' : [ 'Name', 'Family', 'url', 'note' ] all_boards = {} # extract metadata from family.c for family_dir in sorted((Path(TOP) / "hw/bsp").iterdir()): if family_dir.is_dir(): family_c = family_dir / "family.c" if not family_c.exists(): family_c = family_dir / "boards/family.c" f_meta = extract_metadata(family_c) if not f_meta: continue manuf = f_meta.get('manufacturer', '') if manuf not in vendor_data: vendor_data[manuf] = {} # extract metadata from board.h for board_dir in sorted((family_dir / "boards").iterdir()): if board_dir.is_dir(): b_meta = extract_metadata(board_dir / "board.h") if not b_meta: continue b_entry = [ b_meta.get('name', ''), family_dir.name, b_meta.get('url', ''), b_meta.get('note', '') ] vendor_data[manuf][board_dir.name] = b_entry boards_rst = Path(TOP) / "docs/reference/boards.rst" with boards_rst.open('w') as f: title = f"""\ **************** Supported Boards **************** The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. It is responsible for getting the MCU started and the USB peripheral clocked with minimal of on-board devices - One LED : for status - One Button : to get input from user - One UART : needed for logging with LOGGER=uart, maybe required for host/dual examples Following boards are supported""" f.write(title) for manuf, boards in sorted(vendor_data.items()): f.write(f"\n\n{manuf}\n") f.write(f"{'-' * len(manuf)}\n\n") df = pd.DataFrame.from_dict(boards, orient='index', columns=['Name', 'Family', 'URL', 'Note']) df = df.rename_axis("Board") f.write(tabulate(df, headers="keys", tablefmt='rst')) # ----------------------------------------- # Main # ----------------------------------------- if __name__ == "__main__": gen_deps_doc() gen_boards_doc() ================================================ FILE: tools/gen_presets.py ================================================ #!/usr/bin/env python3 import os import json from pathlib import Path def main(): board_list = [] board_list_esp = [] # Find all board.cmake files, exclude espressif for root, dirs, files in os.walk("hw/bsp"): for file in files: if file == "board.cmake" and "espressif" not in root: board_list.append(os.path.basename(root)) # Find all espressif boards for root, dirs, files in os.walk("hw/bsp/espressif"): for file in files: if file == "board.cmake": board_list_esp.append(os.path.basename(root)) print('Generating presets for the following boards:') print(board_list) # Generate the presets presets = {} presets['version'] = 6 # Configure presets presets['configurePresets'] = [ {"name": "default", "hidden": True, "description": r"Configure preset for the ${presetName} board", "generator": "Ninja Multi-Config", "binaryDir": r"${sourceDir}/build/${presetName}", "cacheVariables": { "CMAKE_DEFAULT_BUILD_TYPE": "RelWithDebInfo", "BOARD": r"${presetName}" }}, {"name": "default single config", "hidden": True, "description": r"Configure preset for the ${presetName} board", "generator": "Ninja", "binaryDir": r"${sourceDir}/build/${presetName}", "cacheVariables": { "BOARD": r"${presetName}" }}] # Add non-espressif boards presets['configurePresets'].extend( sorted( [ { 'name': board, 'inherits': 'default' } for board in board_list ], key=lambda x: x['name'] ) ) # Add espressif boards with single config generator presets['configurePresets'].extend( sorted( [ { 'name': board, 'inherits': 'default single config' } for board in board_list_esp ], key=lambda x: x['name'] ) ) # Combine all boards board_list.extend(board_list_esp) # Build presets # no inheritance since 'name' doesn't support macro expansion presets['buildPresets'] = sorted( [ { 'name': board, 'description': "Build preset for the " + board + " board", 'configurePreset': board } for board in board_list ], key=lambda x: x['name'] ) # Workflow presets presets['workflowPresets'] = sorted( [ { "name": board, "steps": [ { "type": "configure", "name": board }, { "type": "build", "name": board } ] } for board in board_list ], key=lambda x: x['name'] ) path_boardpresets = "hw/bsp/BoardPresets.json" with open(path_boardpresets, "w") as f: f.write('{}\n'.format(json.dumps(presets, indent=2))) # Generate presets for examples presets = { "version": 6, "include": [ ] } example_list = [] for root, dirs, files in os.walk("examples"): for file in files: # Filter out ESP-IDF CMakeLists.txt in src folder if file == "CMakeLists.txt" and os.path.basename(root) != 'src': presets['include'] = [os.path.relpath(path_boardpresets, root).replace(os.sep, '/')] with open(os.path.join(root, 'CMakePresets.json'), 'w') as f: f.write('{}\n'.format(json.dumps(presets, indent=2))) example_list.append(os.path.basename(root)) print('Generating presets for the following examples:') print(example_list) if __name__ == "__main__": main() ================================================ FILE: tools/get_deps.py ================================================ #!/usr/bin/env python3 import argparse import sys import subprocess from pathlib import Path from multiprocessing import Pool # Mandatory Dependencies that is always fetched # path, url, commit, family (Alphabet sorted by path) deps_mandatory = { 'lib/FreeRTOS-Kernel': ['https://github.com/FreeRTOS/FreeRTOS-Kernel.git', 'cc0e0707c0c748713485b870bb980852b210877f', 'all'], 'lib/lwip': ['https://github.com/lwip-tcpip/lwip.git', '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'lib/threadx': ['https://github.com/eclipse-threadx/threadx.git', '4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae', 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', '8e1f440fa15c567aceb5aa0d14f6d18c329cc67f', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', 'c594542b2faa01cc33a2b97c9fbebc38549df80a', 'all'], } # Optional Dependencies per MCU # path, url, commit, family (Alphabet sorted by path) deps_optional = { 'hw/mcu/allwinner': ['https://github.com/hathach/allwinner_driver.git', '8e5e89e8e132c0fd90e72d5422e5d3d68232b756', 'fc100s'], 'hw/mcu/analog/msdk' : ['https://github.com/analogdevicesinc/msdk.git', 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', 'maxim'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '03f74eac84645178fdde7f2e5ca9acdcb7bd9dcd', 'ft9xx'], 'hw/mcu/broadcom': ['https://github.com/adafruit/broadcom-peripherals.git', '08370086080759ed54ac1136d62d2ad24c6fa267', 'broadcom_32bit broadcom_64bit'], 'hw/mcu/gd/nuclei-sdk': ['https://github.com/Nuclei-Software/nuclei-sdk.git', '7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7', 'gd32vf103'], 'hw/mcu/infineon/mtb-xmclib-cat3': ['https://github.com/Infineon/mtb-xmclib-cat3.git', 'daf5500d03cba23e68c2f241c30af79cd9d63880', 'xmc4000'], 'hw/mcu/microchip': ['https://github.com/hathach/microchip_driver.git', '9e8b37e307d8404033bb881623a113931e1edf27', 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg'], 'hw/mcu/mindmotion/mm32sdk': ['https://github.com/hathach/mm32sdk.git', 'b93e856211060ae825216c6a1d6aa347ec758843', 'mm32'], 'hw/mcu/nordic/nrfx': ['https://github.com/NordicSemiconductor/nrfx.git', '11f57e578c7feea13f21c79ea0efab2630ac68c7', 'nrf'], 'hw/mcu/nuvoton': ['https://github.com/majbthrd/nuc_driver.git', '2204191ec76283371419fbcec207da02e1bc22fa', 'nuc100_120 nuc121_125 nuc126 nuc505'], 'hw/mcu/nxp/lpcopen': ['https://github.com/hathach/nxp_lpcopen.git', 'b41cf930e65c734d8ec6de04f1d57d46787c76ae', 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcuxsdk-core': ['https://github.com/nxp-mcuxpresso/mcuxsdk-core', '0c5c6b16deb211110e06bde896cdff59ab213e16', 'imxrt kinetis_k32l lpc51 lpc55 mcx'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/nxp-mcuxpresso/mcux-sdk', 'a1bdae309a14ec95a4f64a96d3315a4f89c397c6', 'kinetis_k kinetis_kl lpc54 rw61x'], 'hw/mcu/nxp/mcux-devices-kinetis': ['https://github.com/nxp-mcuxpresso/mcux-devices-kinetis', '98a155e666c54f396e528ec3131f27a5d5b71f76', 'kinetis_k32l'], 'hw/mcu/nxp/mcux-devices-lpc': ['https://github.com/nxp-mcuxpresso/mcux-devices-lpc', '8096b783ec09d0d1c8629025a5f9d8e7df26e520', 'lpc51 lpc55'], 'hw/mcu/nxp/mcux-devices-mcx': ['https://github.com/nxp-mcuxpresso/mcux-devices-mcx', 'ada1c97c761123ec0c179bb9bb9f744bf9a11475', 'mcx'], 'hw/mcu/nxp/mcux-devices-rt': ['https://github.com/nxp-mcuxpresso/mcux-devices-rt', 'dba2b523c9df61f3330bd186242f8210a8e47c45', 'imxrt'], 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', '675543bcc9baa8170f868ab7ba316d418dbcf41f', 'rp2040'], 'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git', 'edcc97d684b6f716728a60d7a6fea049d9870bd6', 'ra'], 'hw/mcu/renesas/rx': ['https://github.com/kkitayam/rx_device.git', '706b4e0cf485605c32351e2f90f5698267996023', 'rx'], 'hw/mcu/silabs/cmsis-dfp-efm32gg12b': ['https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git', 'f1c31b7887669cb230b3ea63f9b56769078960bc', 'efm32'], 'hw/mcu/sony/cxd56/spresense-exported-sdk': ['https://github.com/sonydevworld/spresense-exported-sdk.git', '2ec2a1538362696118dc3fdf56f33dacaf8f4067', 'spresense'], 'hw/mcu/st/cmsis_device_c0': ['https://github.com/STMicroelectronics/cmsis_device_c0.git', '517611273f835ffe95318947647bc1408f69120d', 'stm32c0'], 'hw/mcu/st/cmsis_device_f0': ['https://github.com/STMicroelectronics/cmsis_device_f0.git', 'cbb5da5d48b4b5f2efacdc2f033be30f9d29889f', 'stm32f0'], 'hw/mcu/st/cmsis_device_f1': ['https://github.com/STMicroelectronics/cmsis_device_f1.git', 'c8e9a4a4f16b6d2cb2a2083cbe5161025280fb22', 'stm32f1'], 'hw/mcu/st/cmsis_device_f2': ['https://github.com/STMicroelectronics/cmsis_device_f2.git', '49321f1e4d2bd3e65687b37f2652a28ea7983674', 'stm32f2'], 'hw/mcu/st/cmsis_device_f3': ['https://github.com/STMicroelectronics/cmsis_device_f3.git', '5558e64e3675a1e1fcb1c71f468c7c407c1b1134', 'stm32f3'], 'hw/mcu/st/cmsis_device_f4': ['https://github.com/STMicroelectronics/cmsis_device_f4.git', '3c77349ce04c8af401454cc51f85ea9a50e34fc1', 'stm32f4'], 'hw/mcu/st/cmsis_device_f7': ['https://github.com/STMicroelectronics/cmsis_device_f7.git', '2352e888e821aa0f4fe549bd5ea81d29c67a3222', 'stm32f7'], 'hw/mcu/st/cmsis_device_g0': ['https://github.com/STMicroelectronics/cmsis_device_g0.git', 'f484fe852535f913a02ee79787eafa74dd7f9488', 'stm32g0'], 'hw/mcu/st/cmsis_device_g4': ['https://github.com/STMicroelectronics/cmsis_device_g4.git', '7c39c32593b03764aaa57531588b8bf7cdd443a5', 'stm32g4'], 'hw/mcu/st/cmsis_device_h7': ['https://github.com/STMicroelectronics/cmsis_device_h7.git', '45b818cab6ee2806e3a27c80e330957223424392', 'stm32h7'], 'hw/mcu/st/cmsis_device_h7rs': ['https://github.com/STMicroelectronics/cmsis_device_h7rs.git', '57ea11f70ebf1850e1048989d665c9070f0bb863', 'stm32h7rs'], 'hw/mcu/st/cmsis_device_h5': ['https://github.com/STMicroelectronics/cmsis_device_h5.git', '5273b8f134ba65f5b8174c4141b711b5c0d295b2', 'stm32h5'], 'hw/mcu/st/cmsis_device_l0': ['https://github.com/STMicroelectronics/cmsis_device_l0.git', '7b7ae8cd71437331e1d7824f157d00c7bb4a5044', 'stm32l0'], 'hw/mcu/st/cmsis_device_l1': ['https://github.com/STMicroelectronics/cmsis_device_l1.git', 'a23ade4ccf14012085fedf862e33a536ab7ed8be', 'stm32l1'], 'hw/mcu/st/cmsis_device_l4': ['https://github.com/STMicroelectronics/cmsis_device_l4.git', 'a2530753e86dd326a75467d28feb92e2ba7d0df2', 'stm32l4'], 'hw/mcu/st/cmsis_device_l5': ['https://github.com/STMicroelectronics/cmsis_device_l5.git', '7d9a51481f0e6c376e62c3c849e6caf652c66482', 'stm32l5'], 'hw/mcu/st/cmsis_device_n6': ['https://github.com/STMicroelectronics/cmsis-device-n6.git', '7bcdc944fbf7cf5928d3c1d14054ca13261d33ec', 'stm32n6'], 'hw/mcu/st/cmsis-device-u0': ['https://github.com/STMicroelectronics/cmsis-device-u0.git', 'e3a627c6a5bc4eb2388e1885a95cc155e1672253', 'stm32u0'], 'hw/mcu/st/cmsis_device_u5': ['https://github.com/STMicroelectronics/cmsis_device_u5.git', '6e67187dec98035893692ab2923914cb5f4e0117', 'stm32u5'], 'hw/mcu/st/cmsis_device_wb': ['https://github.com/STMicroelectronics/cmsis_device_wb.git', 'cda2cb9fc4a5232ab18efece0bb06b0b60910083', 'stm32wb'], 'hw/mcu/st/cmsis-device-wba': ['https://github.com/STMicroelectronics/cmsis-device-wba.git', '647d8522e5fd15049e9a1cc30ed19d85e5911eaf', 'stm32wba'], 'hw/mcu/st/stm32-mfxstm32l152': ['https://github.com/STMicroelectronics/stm32-mfxstm32l152.git', '7f4389efee9c6a655b55e5df3fceef5586b35f9b', 'stm32h7'], 'hw/mcu/st/stm32-tcpp0203': ['https://github.com/STMicroelectronics/stm32-tcpp0203.git', '9918655bff176ac3046ccf378b5c7bbbc6a38d15', 'stm32h5 stm32h7rs stm32n6'], 'hw/mcu/st/stm32c0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git', 'c283b143bef6bdaacf64240ee6f15eb61dad6125', 'stm32c0'], 'hw/mcu/st/stm32f0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git', '94399697cb5eeaf8511b81b7f50dc62f0a5a3f6c', 'stm32f0'], 'hw/mcu/st/stm32f1xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git', '18074e3e5ecad0b380a5cf5a9131fe4b5ed1b2b7', 'stm32f1'], 'hw/mcu/st/stm32f2xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f2xx_hal_driver.git', 'ae7b47fe41cf75ccaf65cbf8ee8749b18ba0e0f3', 'stm32f2'], 'hw/mcu/st/stm32f3xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f3xx_hal_driver.git', 'e098c8c8ce6f426bcee7db3a37c0932ea881eb0b', 'stm32f3'], 'hw/mcu/st/stm32f4xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f4xx_hal_driver.git', 'b6f0ed3829f3829eb358a2e7417d80bba1a42db7', 'stm32f4'], 'hw/mcu/st/stm32f7xx_hal_driver': ['https://github.com/STMicroelectronics/stm32f7xx_hal_driver.git', 'e1446fa12ffda80ea1016faf349e45b2047fff12', 'stm32f7'], 'hw/mcu/st/stm32g0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32g0xx_hal_driver.git', 'a248a9e484d58943b46c68f6c49b4b276778bd59', 'stm32g0'], 'hw/mcu/st/stm32g4xx_hal_driver': ['https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git', '10138a41749ea62d53ecab65b2bc2a950acc04d2', 'stm32g4'], 'hw/mcu/st/stm32h7xx_hal_driver': ['https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git', 'dbfb749f229e1aa89e50b54229ca87766e180d2d', 'stm32h7'], 'hw/mcu/st/stm32h7rsxx_hal_driver': ['https://github.com/STMicroelectronics/stm32h7rsxx-hal-driver.git', '9e83b95ae0f70faa067eddce2da617d180937f9b', 'stm32h7rs'], 'hw/mcu/st/stm32h5xx_hal_driver': ['https://github.com/STMicroelectronics/stm32h5xx_hal_driver.git', '3c84eaa6000ab620be01afbcfba2735389afe09b', 'stm32h5'], 'hw/mcu/st/stm32l0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git', '65da4cd8a10ad859ec8d9cd71f3f6c50735bd473', 'stm32l0'], 'hw/mcu/st/stm32l1xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l1xx_hal_driver.git', '54f0b7568ce2acb33d090c70c897ee32229c1d32', 'stm32l1'], 'hw/mcu/st/stm32l4xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git', '3e039bbf62f54bbd834d578185521cff80596efe', 'stm32l4'], 'hw/mcu/st/stm32l5xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git', '3340b9a597bcf75cc173345a90a74aa2a4a37510', 'stm32l5'], 'hw/mcu/st/stm32n6xx_hal_driver': ['https://github.com/STMicroelectronics/stm32n6xx-hal-driver.git', 'bc6c41f8f67d61b47af26695d0bf67762a000666', 'stm32n6'], 'hw/mcu/st/stm32u0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32u0xx-hal-driver.git', 'cbfb5ac654256445237fd32b3587ac6a238d24f1', 'stm32u0'], 'hw/mcu/st/stm32u5xx_hal_driver': ['https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git', '2c5e2568fbdb1900a13ca3b2901fdd302cac3444', 'stm32u5'], 'hw/mcu/st/stm32wbxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git', 'd60dd46996876506f1d2e9abd6b1cc110c8004cd', 'stm32wb'], 'hw/mcu/st/stm32wbaxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git', '9442fbb71f855ff2e64fbf662b7726beba511a24', 'stm32wba'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '083944907e7d08fcb1f614b47598ce45935b8da1', 'msp430 msp432e4 tm4c'], 'hw/mcu/wch/ch32v103': ['https://github.com/openwch/ch32v103.git', '7578cae0b21f86dd053a1f781b2fc6ab99d0ec17', 'ch32v10x'], 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', 'c4c38f507e258a4e69b059ccc2dc27dde33cea1b', 'ch32v20x'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', '184f21b852cb95eed58e86e901837bc9fff68775', 'ch32v30x'], 'hw/mcu/wch/ch32f20x': ['https://github.com/openwch/ch32f20x.git', '77c4095087e5ed2c548ec9058e655d0b8757663b', 'ch32f20x'], 'hw/mcu/artery/at32f403a_407': ['https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git', 'f2cb360c3d28fada76b374308b8c4c61d37a090b', 'at32f403a_407'], 'hw/mcu/artery/at32f415': ['https://github.com/ArteryTek/AT32F415_Firmware_Library.git', '716f545aa1290ff144ccf023a8e797b951e1bc8e', 'at32f415'], 'hw/mcu/artery/at32f435_437': ['https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git', '25439cc6650a8ae0345934e8707a5f38c7ae41f8', 'at32f435_437'], 'hw/mcu/artery/at32f423': ['https://github.com/ArteryTek/AT32F423_Firmware_Library.git', '2afa7f12852e57a9e8aab3a892c641e1a8635a18', 'at32f423'], 'hw/mcu/artery/at32f402_405': ['https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git', '4424515c2663e82438654e0947695295df2abdfe', 'at32f402_405'], 'hw/mcu/artery/at32f425': ['https://github.com/ArteryTek/AT32F425_Firmware_Library.git', '620233e1357d5c1b7e2bde6b9dd5196822b91817', 'at32f425'], 'hw/mcu/artery/at32f413': ['https://github.com/ArteryTek/AT32F413_Firmware_Library.git', 'f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450', 'at32f413'], 'hw/mcu/artery/at32f45x': ['https://github.com/ArteryTek/AT32F45x_Firmware_Library.git', '3d4a1b38be8ebac292e2350ca53bc4bfa4430233', 'at32f45x'], 'hw/mcu/hpmicro/hpm_sdk': ['https://github.com/hpmicro/hpm_sdk', '8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff', 'hpmicro'], 'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git', '2b7495b8535bdcb306dac29b9ded4cfb679d7e5c', 'kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x ' 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' 'sam3x samd11 samd21 samd2x_l2x samd51 samd5x_e5x same5x same7x samg ' 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], } # combined 2 deps deps_all = {**deps_mandatory, **deps_optional} # TOP is tinyusb root dir TOP = Path(__file__).parent.parent.resolve() def run_cmd(cmd): r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) title = f'Command Error: {cmd}' if r.returncode != 0: print(title) print(r.stdout.decode("utf-8")) return r def get_a_dep(d): if d not in deps_all.keys(): print('{} is not found in dependency list') return 1 url = deps_all[d][0] commit = deps_all[d][1] families = deps_all[d][2] print(f'cloning {d} with {url}') p = Path(TOP / d) git_cmd = f"git -C {p}" # Init git deps if not existed if not p.exists(): p.mkdir(parents=True) run_cmd(f"{git_cmd} init") run_cmd(f"{git_cmd} remote add origin {url}") head = None else: # Check if commit is already fetched result = run_cmd(f"{git_cmd} rev-parse HEAD") head = result.stdout.decode("utf-8").splitlines()[0] run_cmd(f"{git_cmd} reset --hard") if commit != head: run_cmd(f"{git_cmd} fetch --depth 1 origin {commit}") run_cmd(f"{git_cmd} checkout FETCH_HEAD") return 0 def find_family(board): bsp_dir = Path(TOP / "hw/bsp") for family_dir in bsp_dir.iterdir(): if family_dir.is_dir(): board_dir = family_dir / 'boards' / board if board_dir.exists(): return family_dir.name return None def main(): parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to fetch') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') parser.add_argument('-D', '--define', action='append', default=[], help='Have no effect') parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Have no effect') args = parser.parse_args() families = args.families boards = args.board status = 0 deps = [] if 'all' in families: deps.extend(deps_optional.keys()) else: families = list(families) if boards is not None: for b in boards: f = find_family(b) if f is not None: families.append(f) for f in families: for d in deps_optional: if d not in deps and f in deps_optional[d][2].split(): deps.append(d) if len(deps) == 0: print('WARN: no additional dependencies found for given boards or families') deps.extend(deps_mandatory.keys()) with Pool() as pool: status = sum(pool.map(get_a_dep, deps)) return status if __name__ == "__main__": sys.exit(main()) ================================================ FILE: tools/iar_gen.py ================================================ #!/usr/bin/env python3 import os import sys import xml.dom.minidom as XML import glob def Main(): # Read base configuration base = "" with open("iar_template.ipcf") as f: base = f.read() # Enumerate all device/host examples dir_1 = os.listdir("../examples") for dir_2 in dir_1: if os.path.isdir("../examples/{}".format(dir_2)): print(dir_2) examples = os.listdir("../examples/{}".format(dir_2)) for example in examples: if os.path.isdir("../examples/{}/{}".format(dir_2, example)): print("../examples/{}/{}".format(dir_2, example)) conf = XML.parseString(base) files = conf.getElementsByTagName("files")[0] inc = conf.getElementsByTagName("includePath")[0] # Add bsp inc path = conf.createElement('path') path_txt = conf.createTextNode("$TUSB_DIR$/hw") path.appendChild(path_txt) inc.appendChild(path) # Add board.c/.h grp = conf.createElement('group') grp.setAttribute("name", "bsp") path = conf.createElement('path') path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c") path.appendChild(path_txt) grp.appendChild(path) files.appendChild(grp) # Add example's .c/.h grp = conf.createElement('group') grp.setAttribute("name", "example") for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)): if file.endswith(".c") or file.endswith(".h"): path = conf.createElement('path') path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file)) path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file)) path.appendChild(path_txt) grp.appendChild(path) files.appendChild(grp) cfg_str = conf.toprettyxml() cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()]) #print(cfg_str) with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f: f.write(cfg_str) def ListPath(path, blacklist=[]): # Get all .c files files = glob.glob(f'../{path}/**/*.c', recursive=True) files.extend(glob.glob(f'../{path}/**/*.h', recursive=True)) # Filter files = [x for x in files if all(y not in x for y in blacklist)] # Get common dir list dirs = [] for file in files: dir = os.path.dirname(file) if dir not in dirs: dirs.append(dir) # Print .c grouped by dir for dir in dirs: print('') for file in files: if os.path.dirname(file) == dir: print(' $TUSB_DIR$/' + file.replace('../','').replace('\\','/')+'') print('') def List(): ListPath('src', [ 'template.c' ]) ListPath('lib/SEGGER_RTT') if __name__ == "__main__": if os.path.dirname(os.getcwd()) != 'tools': os.chdir('tools') if (len(sys.argv) > 1): if (sys.argv[1] == 'l'): List() else: Main() ================================================ FILE: tools/iar_template.ipcf ================================================ $TUSB_DIR$/src $TUSB_DIR$/lib/SEGGER_RTT/RTT $TUSB_DIR$/lib/SEGGER_RTT/Config $PROJ_DIR$ $TUSB_DIR$/src/tusb.c $TUSB_DIR$/src/tusb.h $TUSB_DIR$/src/tusb_option.h $TUSB_DIR$/src/class/audio/audio_device.c $TUSB_DIR$/src/class/audio/audio.h $TUSB_DIR$/src/class/audio/audio_device.h $TUSB_DIR$/src/class/bth/bth_device.c $TUSB_DIR$/src/class/bth/bth_device.h $TUSB_DIR$/src/class/cdc/cdc_device.c $TUSB_DIR$/src/class/cdc/cdc_host.c $TUSB_DIR$/src/class/cdc/cdc_rndis_host.c $TUSB_DIR$/src/class/cdc/cdc.h $TUSB_DIR$/src/class/cdc/cdc_device.h $TUSB_DIR$/src/class/cdc/cdc_host.h $TUSB_DIR$/src/class/cdc/cdc_rndis.h $TUSB_DIR$/src/class/cdc/cdc_rndis_host.h $TUSB_DIR$/src/class/dfu/dfu_device.c $TUSB_DIR$/src/class/dfu/dfu_rt_device.c $TUSB_DIR$/src/class/dfu/dfu.h $TUSB_DIR$/src/class/dfu/dfu_device.h $TUSB_DIR$/src/class/dfu/dfu_rt_device.h $TUSB_DIR$/src/class/hid/hid_device.c $TUSB_DIR$/src/class/hid/hid_host.c $TUSB_DIR$/src/class/hid/hid.h $TUSB_DIR$/src/class/hid/hid_device.h $TUSB_DIR$/src/class/hid/hid_host.h $TUSB_DIR$/src/class/midi/midi_device.c $TUSB_DIR$/src/class/midi/midi.h $TUSB_DIR$/src/class/midi/midi_device.h $TUSB_DIR$/src/class/msc/msc_device.c $TUSB_DIR$/src/class/msc/msc_host.c $TUSB_DIR$/src/class/msc/msc.h $TUSB_DIR$/src/class/msc/msc_device.h $TUSB_DIR$/src/class/msc/msc_host.h $TUSB_DIR$/src/class/mtp/mtp_device.c $TUSB_DIR$/src/class/mtp/mtp.h $TUSB_DIR$/src/class/mtp/mtp_device.h $TUSB_DIR$/src/class/net/ecm_rndis_device.c $TUSB_DIR$/src/class/net/ncm_device.c $TUSB_DIR$/src/class/net/ncm.h $TUSB_DIR$/src/class/net/net_device.h $TUSB_DIR$/src/class/printer/printer_device.c $TUSB_DIR$/src/class/printer/printer.h $TUSB_DIR$/src/class/printer/printer_device.h $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c $TUSB_DIR$/src/class/usbtmc/usbtmc.h $TUSB_DIR$/src/class/usbtmc/usbtmc_device.h $TUSB_DIR$/src/class/vendor/vendor_device.c $TUSB_DIR$/src/class/vendor/vendor_host.c $TUSB_DIR$/src/class/vendor/vendor_device.h $TUSB_DIR$/src/class/vendor/vendor_host.h $TUSB_DIR$/src/class/video/video_device.c $TUSB_DIR$/src/class/video/video.h $TUSB_DIR$/src/class/video/video_device.h $TUSB_DIR$/src/common/tusb_fifo.c $TUSB_DIR$/src/common/tusb_common.h $TUSB_DIR$/src/common/tusb_compiler.h $TUSB_DIR$/src/common/tusb_debug.h $TUSB_DIR$/src/common/tusb_fifo.h $TUSB_DIR$/src/common/tusb_mcu.h $TUSB_DIR$/src/common/tusb_private.h $TUSB_DIR$/src/common/tusb_types.h $TUSB_DIR$/src/common/tusb_verify.h $TUSB_DIR$/src/device/usbd.c $TUSB_DIR$/src/device/usbd_control.c $TUSB_DIR$/src/device/dcd.h $TUSB_DIR$/src/device/usbd.h $TUSB_DIR$/src/device/usbd_pvt.h $TUSB_DIR$/src/host/hub.c $TUSB_DIR$/src/host/usbh.c $TUSB_DIR$/src/host/hcd.h $TUSB_DIR$/src/host/hub.h $TUSB_DIR$/src/host/usbh.h $TUSB_DIR$/src/host/usbh_pvt.h $TUSB_DIR$/src/portable/analog/max3421/hcd_max3421.c $TUSB_DIR$/src/portable/bridgetek/ft9xx/dcd_ft9xx.c $TUSB_DIR$/src/portable/chipidea/ci_fs/dcd_ci_fs.c $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_kinetis.h $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_mcx.h $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_type.h $TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c $TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_imxrt.h $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_mcx.h $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_type.h $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c $TUSB_DIR$/src/portable/ehci/ehci.c $TUSB_DIR$/src/portable/ehci/ehci.h $TUSB_DIR$/src/portable/ehci/ehci_api.h $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c $TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c $TUSB_DIR$/src/portable/mentor/musb/musb_msp432e.h $TUSB_DIR$/src/portable/mentor/musb/musb_tm4c.h $TUSB_DIR$/src/portable/mentor/musb/musb_type.h $TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c $TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c $TUSB_DIR$/src/portable/microchip/pic32mz/usbhs_registers.h $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c $TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c $TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c $TUSB_DIR$/src/portable/microchip/samx7x/common_usb_regs.h $TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c $TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c $TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c $TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c $TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c $TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c $TUSB_DIR$/src/portable/nxp/khci/hcd_khci.c $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c $TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.h $TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c $TUSB_DIR$/src/portable/ohci/ohci.c $TUSB_DIR$/src/portable/ohci/ohci.h $TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c $TUSB_DIR$/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.c $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.h $TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c $TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_common.c $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_ra.h $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_rx.h $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_type.h $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c $TUSB_DIR$/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c $TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.c $TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.h $TUSB_DIR$/src/portable/st/typec/typec_stm32.c $TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c $TUSB_DIR$/src/portable/sunxi/musb_def.h $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_bcm.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_efm32.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_esp32.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_gd32.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_stm32.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_type.h $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_xmc.h $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.h $TUSB_DIR$/src/portable/wch/dcd_ch32_usbfs.c $TUSB_DIR$/src/portable/wch/dcd_ch32_usbhs.c $TUSB_DIR$/src/portable/wch/ch32_usbhs_reg.h $TUSB_DIR$/src/typec/usbc.c $TUSB_DIR$/src/typec/pd_types.h $TUSB_DIR$/src/typec/tcd.h $TUSB_DIR$/src/typec/usbc.h $TUSB_DIR$/src/class/cdc/serial/ch34x.h $TUSB_DIR$/src/class/cdc/serial/cp210x.h $TUSB_DIR$/src/class/cdc/serial/ftdi_sio.h $TUSB_DIR$/src/osal/osal.h $TUSB_DIR$/src/osal/osal_freertos.h $TUSB_DIR$/src/osal/osal_mynewt.h $TUSB_DIR$/src/osal/osal_none.h $TUSB_DIR$/src/osal/osal_pico.h $TUSB_DIR$/src/osal/osal_rtthread.h $TUSB_DIR$/src/osal/osal_rtx4.h $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.h $TUSB_DIR$/lib/SEGGER_RTT/Config/SEGGER_RTT_Conf.h ================================================ FILE: tools/make_release.py ================================================ #!/usr/bin/env python3 import re import gen_doc import gen_presets version = '0.20.0' print('version {}'.format(version)) ver_id = version.split('.') ################### # src/tusb_option.h ################### f_option_h = 'src/tusb_option.h' with open(f_option_h) as f: fdata = f.read() fdata = re.sub(r'(#define TUSB_VERSION_MAJOR *) \d+', r"\1 {}".format(ver_id[0]), fdata) fdata = re.sub(r'(#define TUSB_VERSION_MINOR *) \d+', r"\1 {}".format(ver_id[1]), fdata) fdata = re.sub(r'(#define TUSB_VERSION_REVISION *) \d+', r"\1 {}".format(ver_id[2]), fdata) # Write the file out again with open(f_option_h, 'w') as f: f.write(fdata) ################### # repository.yml ################### f_repository_yml = 'repository.yml' with open(f_repository_yml) as f: fdata = f.read() if fdata.find(version) < 0: fdata = re.sub(r'("0-latest"): "\d+\.\d+\.\d+"', r'"{}": "{}"\r\n \1: "{}"'.format(version, version, version), fdata) with open(f_repository_yml, 'w') as f: f.write(fdata) ################### # library.json ################### f_library_json = 'library.json' with open(f_library_json) as f: fdata = f.read() fdata = re.sub(r'( {4}"version":) "\d+\.\d+\.\d+"', rf'\1 "{version}"', fdata) with open(f_library_json, 'w') as f: f.write(fdata) ################### # sonar-project.properties ################### f_sonar_properties = 'sonar-project.properties' with open(f_sonar_properties) as f: fdata = f.read() fdata = re.sub(r'(sonar\.projectVersion=)\d+\.\d+\.\d+', r'\g<1>{}'.format(version), fdata) with open(f_sonar_properties, 'w') as f: f.write(fdata) # gen docs gen_doc.gen_deps_doc() gen_doc.gen_boards_doc() # gen presets gen_presets.main() ##################(ver# # docs/info/changelog.rst ################### print("Update docs/info/changelog.rst") ================================================ FILE: tools/metrics.py ================================================ #!/usr/bin/env python3 """Calculate average sizes from bloaty CSV or TinyUSB metrics JSON outputs.""" import argparse import csv import glob import io import json import os import sys from collections import defaultdict def expand_files(file_patterns): """Expand file patterns (globs) to list of files. Args: file_patterns: List of file paths or glob patterns Returns: List of expanded file paths """ expanded = [] for pattern in file_patterns: if '*' in pattern or '?' in pattern: expanded.extend(glob.glob(pattern)) else: expanded.append(pattern) return expanded def parse_bloaty_csv(csv_text, filters=None): """Parse bloaty CSV text and return normalized JSON data structure.""" filters = filters or [] reader = csv.DictReader(io.StringIO(csv_text)) size_by_unit = defaultdict(int) symbols_by_unit: dict[str, defaultdict[str, int]] = defaultdict(lambda: defaultdict(int)) sections_by_unit: dict[str, defaultdict[str, int]] = defaultdict(lambda: defaultdict(int)) for row in reader: compile_unit = row.get("compileunits") or row.get("compileunit") or row.get("path") if compile_unit is None: continue if str(compile_unit).upper() == "TOTAL": continue if filters and not any(filt in compile_unit for filt in filters): continue try: vmsize = int(row.get("vmsize", 0)) except ValueError: continue size_by_unit[compile_unit] += vmsize symbol_name = row.get("symbols", "") if symbol_name: symbols_by_unit[compile_unit][symbol_name] += vmsize section_name = row.get("sections") or row.get("section") if section_name and vmsize: sections_by_unit[compile_unit][section_name] += vmsize files = [] for unit_path, total_size in size_by_unit.items(): symbols = [ {"name": sym, "size": sz} for sym, sz in sorted(symbols_by_unit[unit_path].items(), key=lambda x: x[1], reverse=True) ] sections = {sec: sz for sec, sz in sections_by_unit[unit_path].items() if sz} files.append( { "file": os.path.basename(unit_path) or unit_path, "path": unit_path, "size": total_size, "symbols": symbols, "sections": sections, } ) total_all = sum(size_by_unit.values()) return {"files": files, "TOTAL": total_all} def combine_files(input_files, filters=None): """Combine multiple metrics inputs (bloaty CSV or metrics JSON) into a single data set.""" filters = filters or [] all_json_data = {"file_list": [], "data": []} for fin in input_files: if not os.path.exists(fin): print(f"Warning: {fin} not found, skipping", file=sys.stderr) continue try: if fin.endswith(".json"): with open(fin, "r", encoding="utf-8") as f: json_data = json.load(f) if filters: json_data["files"] = [ f for f in json_data.get("files", []) if f.get("path") and any(filt in f["path"] for filt in filters) ] elif fin.endswith(".csv"): with open(fin, "r", encoding="utf-8") as f: csv_text = f.read() json_data = parse_bloaty_csv(csv_text, filters) else: if fin.endswith(".elf"): print(f"Warning: {fin} is an ELF; please run bloaty with --csv output first. Skipping.", file=sys.stderr) else: print(f"Warning: {fin} is not a supported CSV or JSON metrics input. Skipping.", file=sys.stderr) continue # Drop any fake TOTAL entries that slipped in as files json_data["files"] = [ f for f in json_data.get("files", []) if str(f.get("file", "")).upper() != "TOTAL" ] all_json_data["file_list"].append(fin) all_json_data["data"].append(json_data) except Exception as e: # pragma: no cover - defensive print(f"Warning: Failed to analyze {fin}: {e}", file=sys.stderr) continue return all_json_data def compute_avg(all_json_data): """Compute average sizes from combined json_data. Args: all_json_data: Dictionary with file_list and data from combine_files() Returns: json_average: Dictionary with averaged size data """ if not all_json_data["data"]: return None # Merge files with the same 'file' value and compute averages file_accumulator = {} # key: file name, value: {"sizes": [sizes], "symbols": {name: [sizes]}, "sections": {name: [sizes]}} for json_data in all_json_data["data"]: for f in json_data.get("files", []): fname = f["file"] if fname not in file_accumulator: file_accumulator[fname] = { "sizes": [], "path": f.get("path"), "symbols": defaultdict(list), "sections": defaultdict(list), } size_val = f.get("size", 0) file_accumulator[fname]["sizes"].append(size_val) for sym in f.get("symbols", []): name = sym.get("name") if name is None: continue file_accumulator[fname]["symbols"][name].append(sym.get("size", 0)) sections_map = f.get("sections") or {} for sname, ssize in sections_map.items(): file_accumulator[fname]["sections"][sname].append(ssize) # Build json_average with averaged values files_average = [] for fname, data in file_accumulator.items(): avg_size = round(sum(data["sizes"]) / len(data["sizes"])) if data["sizes"] else 0 symbols_avg = [] for sym_name, sizes in data["symbols"].items(): if not sizes: continue symbols_avg.append({"name": sym_name, "size": round(sum(sizes) / len(sizes))}) symbols_avg.sort(key=lambda x: x["size"], reverse=True) sections_avg = { sec_name: round(sum(sizes) / len(sizes)) for sec_name, sizes in data["sections"].items() if sizes } files_average.append( { "file": fname, "path": data["path"], "size": avg_size, "symbols": symbols_avg, "sections": sections_avg, } ) total_size = sum(f["size"] for f in files_average) or 1 for f in files_average: f["percent"] = (f["size"] / total_size) * 100 if total_size else 0 for sym in f["symbols"]: sym["percent"] = (sym["size"] / f["size"]) * 100 if f["size"] else 0 json_average = { "file_list": all_json_data["file_list"], "files": files_average, } return json_average def compare_files(base_file, new_file, filters=None): """Compare two CSV or JSON inputs and generate difference report.""" filters = filters or [] base_avg = compute_avg(combine_files([base_file], filters)) new_avg = compute_avg(combine_files([new_file], filters)) if not base_avg or not new_avg: return None base_files = {f["file"]: f for f in base_avg["files"]} new_files = {f["file"]: f for f in new_avg["files"]} all_file_names = set(base_files.keys()) | set(new_files.keys()) comparison_files = [] for fname in sorted(all_file_names): b = base_files.get(fname, {}) n = new_files.get(fname, {}) b_size = b.get("size", 0) n_size = n.get("size", 0) base_sections = b.get("sections") or {} new_sections = n.get("sections") or {} # Symbol diffs b_syms = {s["name"]: s for s in b.get("symbols", [])} n_syms = {s["name"]: s for s in n.get("symbols", [])} all_syms = set(b_syms.keys()) | set(n_syms.keys()) symbols = [] for sym in all_syms: sb = b_syms.get(sym, {}).get("size", 0) sn = n_syms.get(sym, {}).get("size", 0) symbols.append({"name": sym, "base": sb, "new": sn, "diff": sn - sb}) symbols.sort(key=lambda x: abs(x["diff"]), reverse=True) comparison_files.append({ "file": fname, "size": {"base": b_size, "new": n_size, "diff": n_size - b_size}, "symbols": symbols, "sections": { name: { "base": base_sections.get(name, 0), "new": new_sections.get(name, 0), "diff": new_sections.get(name, 0) - base_sections.get(name, 0), } for name in sorted(set(base_sections) | set(new_sections)) }, }) base_total = sum(f["size"] for f in base_avg["files"]) new_total = sum(f["size"] for f in new_avg["files"]) total = { "base": base_total, "new": new_total, "diff": new_total - base_total, } return { "base_file": base_file, "new_file": new_file, "total": total, "files": comparison_files, } def get_sort_key(sort_order): """Get sort key function based on sort order. Args: sort_order: One of 'size-', 'size+', 'name-', 'name+' Returns: Tuple of (key_func, reverse) """ def _size_val(entry): return entry.get('size', 0) if sort_order == 'size-': return _size_val, True elif sort_order == 'size+': return _size_val, False elif sort_order == 'name-': return lambda x: x.get('file', ''), True else: # name+ return lambda x: x.get('file', ''), False def format_diff(base, new, diff): """Format a diff value with percentage.""" if diff == 0: return f"{new}" if base == 0 or new == 0: return f"{base} ➙ {new}" pct = (diff / base) * 100 sign = "+" if diff > 0 else "" return f"{base} ➙ {new} ({sign}{diff}, {sign}{pct:.1f}%)" def write_json_output(json_data, path): """Write JSON output with indentation.""" with open(path, "w", encoding="utf-8") as outf: json.dump(json_data, outf, indent=2) def render_combine_table(json_data, sort_order='name+'): """Render averaged sizes as markdown table lines (no title).""" files = json_data.get("files", []) if not files: return ["No entries."] key_func, reverse = get_sort_key(sort_order) files_sorted = sorted(files, key=key_func, reverse=reverse) total_size = json_data.get("TOTAL") or sum(f.get("size", 0) for f in files_sorted) pct_strings = [ f"{(f.get('percent') if f.get('percent') is not None else (f.get('size', 0) / total_size * 100 if total_size else 0)):.1f}%" for f in files_sorted] pct_width = 6 size_width = max(len("size"), *(len(str(f.get("size", 0))) for f in files_sorted), len(str(total_size))) file_width = max(len("File"), *(len(f.get("file", "")) for f in files_sorted), len("TOTAL")) # Build section totals on the fly from file data sections_global = defaultdict(int) for f in files_sorted: for name, size in (f.get("sections") or {}).items(): sections_global[name] += size # Display sections in reverse alphabetical order for stable column layout section_names = sorted(sections_global.keys(), reverse=True) section_widths = {} for name in section_names: max_val = max((f.get("sections", {}).get(name, 0) for f in files_sorted), default=0) section_widths[name] = max(len(name), len(str(max_val)), 1) if not section_names: header = f"| {'File':<{file_width}} | {'size':>{size_width}} | {'%':>{pct_width}} |" separator = f"| :{'-' * (file_width - 1)} | {'-' * (size_width - 1)}: | {'-' * (pct_width - 1)}: |" else: header_parts = [f"| {'File':<{file_width}} |"] sep_parts = [f"| :{'-' * (file_width - 1)} |"] for name in section_names: header_parts.append(f" {name:>{section_widths[name]}} |") sep_parts.append(f" {'-' * (section_widths[name] - 1)}: |") header_parts.append(f" {'size':>{size_width}} | {'%':>{pct_width}} |") sep_parts.append(f" {'-' * (size_width - 1)}: | {'-' * (pct_width - 1)}: |") header = "".join(header_parts) separator = "".join(sep_parts) lines = [header, separator] for f, pct_str in zip(files_sorted, pct_strings): size_val = f.get("size", 0) parts = [f"| {f.get('file', ''):<{file_width}} |"] if section_names: sections_map = f.get("sections") or {} for name in section_names: parts.append(f" {sections_map.get(name, 0):>{section_widths[name]}} |") parts.append(f" {size_val:>{size_width}} | {pct_str:>{pct_width}} |") lines.append("".join(parts)) total_parts = [f"| {'TOTAL':<{file_width}} |"] if section_names: for name in section_names: total_parts.append(f" {sections_global.get(name, 0):>{section_widths[name]}} |") total_parts.append(f" {total_size:>{size_width}} | {'100.0%':>{pct_width}} |") lines.append("".join(total_parts)) return lines def write_combine_markdown(json_data, path, sort_order='name+', title="TinyUSB Average Code Size Metrics"): """Write averaged size data to a markdown file.""" md_lines = [f"# {title}", ""] md_lines.extend(render_combine_table(json_data, sort_order)) md_lines.append("") if json_data.get("file_list"): md_lines.extend(["
", "Input files", ""]) md_lines.extend([f"- {mf}" for mf in json_data["file_list"]]) md_lines.extend(["", "
", ""]) with open(path, "w", encoding="utf-8") as f: f.write("\n".join(md_lines)) def write_compare_markdown(comparison, path, sort_order='size'): """Write comparison data to markdown file.""" md_lines = [ "# Size Difference Report", "", "Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.", "", "Note: If there is no change, only one value is shown.", "", ] significant, minor, unchanged = _split_by_significance(comparison["files"], sort_order) def render(title, rows, collapsed=False): if collapsed: md_lines.append(f"
{title}") md_lines.append("") else: md_lines.append(f"## {title}") md_lines.extend(render_compare_table(_build_rows(rows, sort_order), include_sum=True)) md_lines.append("") if collapsed: md_lines.append("
") md_lines.append("") render("Changes >1% in size", significant) render("Changes <1% in size", minor) render("No changes", unchanged, collapsed=True) with open(path, "w", encoding="utf-8") as f: f.write("\n".join(md_lines)) def print_compare_summary(comparison, sort_order='name+'): """Print diff report to stdout in table form.""" files = comparison["files"] rows = _build_rows(files, sort_order) lines = render_compare_table(rows, include_sum=True) for line in lines: print(line) def _build_rows(files, sort_order): """Sort files and prepare printable fields.""" def sort_key(file_row): if sort_order == 'size-': return abs(file_row["size"]["diff"]) if sort_order in ('size', 'size+'): return abs(file_row["size"]["diff"]) if sort_order == 'name-': return file_row['file'] return file_row['file'] reverse = sort_order in ('size-', 'name-') files_sorted = sorted(files, key=sort_key, reverse=reverse) rows = [] for f in files_sorted: sd = f["size"] diff_val = sd['new'] - sd['base'] if sd['base'] == 0: pct_str = "n/a" else: pct_val = (diff_val / sd['base']) * 100 pct_str = f"{pct_val:+.1f}%" rows.append({ "file": f['file'], "base": sd['base'], "new": sd['new'], "diff": diff_val, "pct": pct_str, "sections": f.get("sections", {}), }) return rows def _split_by_significance(files, sort_order): """Split files into >1% changes, <1% changes, and no changes.""" def is_significant(file_row): base = file_row["size"]["base"] diff = abs(file_row["size"]["diff"]) if base == 0: return diff != 0 return (diff / base) * 100 > 1.0 rows_sorted = sorted( files, key=lambda f: abs(f["size"]["diff"]) if sort_order.startswith("size") else f["file"], reverse=sort_order in ('size-', 'name-'), ) significant = [] minor = [] unchanged = [] for f in rows_sorted: if f["size"]["diff"] == 0: unchanged.append(f) else: (significant if is_significant(f) else minor).append(f) return significant, minor, unchanged def render_compare_table(rows, include_sum): """Return markdown table lines for given rows.""" if not rows: return ["No entries.", ""] # collect section columns (reverse alpha) section_names = sorted( {name for r in rows for name in (r.get("sections") or {})}, reverse=True, ) def fmt_abs(val_old, val_new): diff = val_new - val_old if diff == 0: return f"{val_new}" sign = "+" if diff > 0 else "" return f"{val_old} ➙ {val_new} ({sign}{diff})" sum_base = sum(r["base"] for r in rows) sum_new = sum(r["new"] for r in rows) total_diff = sum_new - sum_base total_pct = "n/a" if sum_base == 0 else f"{(total_diff / sum_base) * 100:+.1f}%" file_width = max(len("file"), *(len(r["file"]) for r in rows), len("TOTAL")) size_width = max( len("size"), *(len(fmt_abs(r["base"], r["new"])) for r in rows), len(fmt_abs(sum_base, sum_new)), ) pct_width = max(len("% diff"), *(len(r["pct"]) for r in rows), len(total_pct)) section_widths = {} for name in section_names: max_val_len = 0 for r in rows: sec_entry = (r.get("sections") or {}).get(name, {"base": 0, "new": 0}) max_val_len = max(max_val_len, len(fmt_abs(sec_entry.get("base", 0), sec_entry.get("new", 0)))) section_widths[name] = max(len(name), max_val_len, 1) header_parts = [f"| {'file':<{file_width}} |"] sep_parts = [f"| :{'-' * (file_width - 1)} |"] for name in section_names: header_parts.append(f" {name:>{section_widths[name]}} |") sep_parts.append(f" {'-' * (section_widths[name] - 1)}: |") header_parts.append(f" {'size':>{size_width}} | {'% diff':>{pct_width}} |") sep_parts.append(f" {'-' * (size_width - 1)}: | {'-' * (pct_width - 1)}: |") header = "".join(header_parts) separator = "".join(sep_parts) lines = [header, separator] for r in rows: parts = [f"| {r['file']:<{file_width}} |"] sections_map = r.get("sections") or {} for name in section_names: sec_entry = sections_map.get(name, {"base": 0, "new": 0}) parts.append(f" {fmt_abs(sec_entry.get('base', 0), sec_entry.get('new', 0)):>{section_widths[name]}} |") parts.append(f" {fmt_abs(r['base'], r['new']):>{size_width}} | {r['pct']:>{pct_width}} |") lines.append("".join(parts)) if include_sum: total_parts = [f"| {'TOTAL':<{file_width}} |"] for name in section_names: total_base = sum((r.get("sections") or {}).get(name, {}).get("base", 0) for r in rows) total_new = sum((r.get("sections") or {}).get(name, {}).get("new", 0) for r in rows) total_parts.append(f" {fmt_abs(total_base, total_new):>{section_widths[name]}} |") total_parts.append(f" {fmt_abs(sum_base, sum_new):>{size_width}} | {total_pct:>{pct_width}} |") lines.append("".join(total_parts)) return lines def cmd_combine(args): """Handle combine subcommand.""" input_files = expand_files(args.files) all_json_data = combine_files(input_files, args.filters) json_average = compute_avg(all_json_data) if json_average is None: print("No valid map files found", file=sys.stderr) sys.exit(1) if not args.quiet: for line in render_combine_table(json_average, sort_order=args.sort): print(line) if args.json_out: write_json_output(json_average, args.out + '.json') if args.markdown_out: write_combine_markdown(json_average, args.out + '.md', sort_order=args.sort, title="TinyUSB Average Code Size Metrics") def cmd_compare(args): """Handle compare subcommand.""" comparison = compare_files(args.base, args.new, args.filters) if comparison is None: print("Failed to compare files", file=sys.stderr) sys.exit(1) if not args.quiet: print_compare_summary(comparison, args.sort) if args.markdown_out: write_compare_markdown(comparison, args.out + '.md', args.sort) if not args.quiet: print(f"Comparison written to {args.out}.md") def main(argv=None): parser = argparse.ArgumentParser(description='Code size metrics tool') subparsers = parser.add_subparsers(dest='command', required=True, help='Available commands') # Combine subcommand combine_parser = subparsers.add_parser('combine', help='Combine and average bloaty CSV outputs or metrics JSON files') combine_parser.add_argument('files', nargs='+', help='Path to bloaty CSV output or TinyUSB metrics JSON file(s) (including linkermap-generated) or glob pattern(s)') combine_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], help='Only include compile units whose path contains this substring (can be repeated)') combine_parser.add_argument('-o', '--out', dest='out', default='metrics', help='Output path basename for JSON and Markdown files (default: metrics)') combine_parser.add_argument('-j', '--json', dest='json_out', action='store_true', help='Write JSON output file') combine_parser.add_argument('-m', '--markdown', dest='markdown_out', action='store_true', help='Write Markdown output file') combine_parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', help='Suppress summary output') combine_parser.add_argument('-S', '--sort', dest='sort', default='size-', choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'], help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: size-') # Compare subcommand compare_parser = subparsers.add_parser('compare', help='Compare two metrics inputs (bloaty CSV or metrics JSON)') compare_parser.add_argument('base', help='Base CSV/metrics JSON file') compare_parser.add_argument('new', help='New CSV/metrics JSON file') compare_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], help='Only include compile units whose path contains this substring (can be repeated)') compare_parser.add_argument('-o', '--out', dest='out', default='metrics_compare', help='Output path basename for Markdown/JSON files (default: metrics_compare)') compare_parser.add_argument('-m', '--markdown', dest='markdown_out', action='store_true', help='Write Markdown output file') compare_parser.add_argument('-S', '--sort', dest='sort', default='name+', choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'], help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: name+') compare_parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', help='Suppress stdout summary output') args = parser.parse_args(argv) if args.command == 'combine': cmd_combine(args) elif args.command == 'compare': cmd_compare(args) if __name__ == '__main__': main() ================================================ FILE: tools/mksunxi.py ================================================ #!/usr/bin/env python3 import sys import struct def align(num, alignment): if num % alignment != 0: num += (alignment - num % alignment) return num def process_file(input, output): with open(input, 'rb') as fin: content = bytearray(fin.read()) align_value = 512 padded_length = align(len(content), align_value) # pad file to actual length content += b'\x00' * (padded_length - len(content)) struct_format = '